From 6e7980b0ad162bbb526b3d52acbc1639c2b11760 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Fri, 20 Jul 2012 10:43:41 +0000 Subject: Import, KeyboardNotify: changed folder structure git-svn-id: http://svn.miranda-ng.org/main/trunk@1071 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Import/ICQserver.cpp | 74 - plugins/Import/ICQserver.h | 62 - plugins/Import/docs/import-translation.txt | 164 ++ plugins/Import/import-translation.txt | 164 -- plugins/Import/import.h | 105 -- plugins/Import/import.ico | Bin 5430 -> 0 bytes plugins/Import/import_10.vcxproj | 39 +- plugins/Import/import_10.vcxproj.filters | 27 +- plugins/Import/main.cpp | 543 ------- plugins/Import/mirabilis.cpp | 1493 ------------------- plugins/Import/mirabilis.h | 200 --- plugins/Import/miranda.cpp | 1445 ------------------ plugins/Import/mirandadb0700.h | 142 -- plugins/Import/mirandahistory.cpp | 208 --- plugins/Import/progress.cpp | 100 -- plugins/Import/res/import.ico | Bin 0 -> 5430 bytes plugins/Import/res/resource.rc | 390 +++++ plugins/Import/resource.h | 64 - plugins/Import/resource.rc | 390 ----- plugins/Import/src/ICQserver.cpp | 74 + plugins/Import/src/ICQserver.h | 62 + plugins/Import/src/import.h | 108 ++ plugins/Import/src/main.cpp | 543 +++++++ plugins/Import/src/mirabilis.cpp | 1493 +++++++++++++++++++ plugins/Import/src/mirabilis.h | 200 +++ plugins/Import/src/miranda.cpp | 1445 ++++++++++++++++++ plugins/Import/src/mirandadb0700.h | 142 ++ plugins/Import/src/mirandahistory.cpp | 208 +++ plugins/Import/src/progress.cpp | 100 ++ plugins/Import/src/resource.h | 64 + plugins/Import/src/version.h | 5 + plugins/Import/src/wizard.cpp | 216 +++ plugins/Import/version.h | 5 - plugins/Import/wizard.cpp | 216 --- plugins/KeyboardNotify/AggressiveOptimize.h | 165 --- plugins/KeyboardNotify/EnumProc.cpp | 260 ---- plugins/KeyboardNotify/EnumProc.h | 27 - plugins/KeyboardNotify/KeyboardNotify_10.vcxproj | 54 +- .../KeyboardNotify_10.vcxproj.filters | 42 +- plugins/KeyboardNotify/constants.h | 85 -- .../docs/keyboardnotify-translation.txt | 113 ++ plugins/KeyboardNotify/flash.cpp | 438 ------ plugins/KeyboardNotify/flash.h | 28 - plugins/KeyboardNotify/ignore.cpp | 389 ----- plugins/KeyboardNotify/ignore.h | 20 - plugins/KeyboardNotify/keyboard.cpp | 120 -- plugins/KeyboardNotify/keyboard.h | 21 - .../KeyboardNotify/keyboardnotify-translation.txt | 113 -- plugins/KeyboardNotify/keypresses.cpp | 77 - plugins/KeyboardNotify/keypresses.h | 20 - plugins/KeyboardNotify/main.cpp | 1448 ------------------ plugins/KeyboardNotify/options.cpp | 1565 -------------------- plugins/KeyboardNotify/protolist.h | 34 - plugins/KeyboardNotify/res/resources.rc | 424 ++++++ plugins/KeyboardNotify/resource.h | 120 -- plugins/KeyboardNotify/resources.rc | 424 ------ plugins/KeyboardNotify/src/AggressiveOptimize.h | 165 +++ plugins/KeyboardNotify/src/EnumProc.cpp | 260 ++++ plugins/KeyboardNotify/src/EnumProc.h | 27 + plugins/KeyboardNotify/src/constants.h | 85 ++ plugins/KeyboardNotify/src/flash.cpp | 438 ++++++ plugins/KeyboardNotify/src/flash.h | 28 + plugins/KeyboardNotify/src/ignore.cpp | 389 +++++ plugins/KeyboardNotify/src/ignore.h | 20 + plugins/KeyboardNotify/src/keyboard.cpp | 120 ++ plugins/KeyboardNotify/src/keyboard.h | 21 + plugins/KeyboardNotify/src/keypresses.cpp | 77 + plugins/KeyboardNotify/src/keypresses.h | 20 + plugins/KeyboardNotify/src/main.cpp | 1448 ++++++++++++++++++ plugins/KeyboardNotify/src/options.cpp | 1565 ++++++++++++++++++++ plugins/KeyboardNotify/src/protolist.h | 34 + plugins/KeyboardNotify/src/resource.h | 120 ++ plugins/KeyboardNotify/src/trigger.cpp | 178 +++ plugins/KeyboardNotify/src/trigger.h | 20 + plugins/KeyboardNotify/src/utils.cpp | 52 + plugins/KeyboardNotify/src/utils.h | 20 + plugins/KeyboardNotify/trigger.cpp | 178 --- plugins/KeyboardNotify/trigger.h | 20 - plugins/KeyboardNotify/utils.cpp | 52 - plugins/KeyboardNotify/utils.h | 20 - 80 files changed, 10912 insertions(+), 10923 deletions(-) delete mode 100644 plugins/Import/ICQserver.cpp delete mode 100644 plugins/Import/ICQserver.h create mode 100644 plugins/Import/docs/import-translation.txt delete mode 100644 plugins/Import/import-translation.txt delete mode 100644 plugins/Import/import.h delete mode 100644 plugins/Import/import.ico delete mode 100644 plugins/Import/main.cpp delete mode 100644 plugins/Import/mirabilis.cpp delete mode 100644 plugins/Import/mirabilis.h delete mode 100644 plugins/Import/miranda.cpp delete mode 100644 plugins/Import/mirandadb0700.h delete mode 100644 plugins/Import/mirandahistory.cpp delete mode 100644 plugins/Import/progress.cpp create mode 100644 plugins/Import/res/import.ico create mode 100644 plugins/Import/res/resource.rc delete mode 100644 plugins/Import/resource.h delete mode 100644 plugins/Import/resource.rc create mode 100644 plugins/Import/src/ICQserver.cpp create mode 100644 plugins/Import/src/ICQserver.h create mode 100644 plugins/Import/src/import.h create mode 100644 plugins/Import/src/main.cpp create mode 100644 plugins/Import/src/mirabilis.cpp create mode 100644 plugins/Import/src/mirabilis.h create mode 100644 plugins/Import/src/miranda.cpp create mode 100644 plugins/Import/src/mirandadb0700.h create mode 100644 plugins/Import/src/mirandahistory.cpp create mode 100644 plugins/Import/src/progress.cpp create mode 100644 plugins/Import/src/resource.h create mode 100644 plugins/Import/src/version.h create mode 100644 plugins/Import/src/wizard.cpp delete mode 100644 plugins/Import/version.h delete mode 100644 plugins/Import/wizard.cpp delete mode 100644 plugins/KeyboardNotify/AggressiveOptimize.h delete mode 100644 plugins/KeyboardNotify/EnumProc.cpp delete mode 100644 plugins/KeyboardNotify/EnumProc.h delete mode 100644 plugins/KeyboardNotify/constants.h create mode 100644 plugins/KeyboardNotify/docs/keyboardnotify-translation.txt delete mode 100644 plugins/KeyboardNotify/flash.cpp delete mode 100644 plugins/KeyboardNotify/flash.h delete mode 100644 plugins/KeyboardNotify/ignore.cpp delete mode 100644 plugins/KeyboardNotify/ignore.h delete mode 100644 plugins/KeyboardNotify/keyboard.cpp delete mode 100644 plugins/KeyboardNotify/keyboard.h delete mode 100644 plugins/KeyboardNotify/keyboardnotify-translation.txt delete mode 100644 plugins/KeyboardNotify/keypresses.cpp delete mode 100644 plugins/KeyboardNotify/keypresses.h delete mode 100644 plugins/KeyboardNotify/main.cpp delete mode 100644 plugins/KeyboardNotify/options.cpp delete mode 100644 plugins/KeyboardNotify/protolist.h create mode 100644 plugins/KeyboardNotify/res/resources.rc delete mode 100644 plugins/KeyboardNotify/resource.h delete mode 100644 plugins/KeyboardNotify/resources.rc create mode 100644 plugins/KeyboardNotify/src/AggressiveOptimize.h create mode 100644 plugins/KeyboardNotify/src/EnumProc.cpp create mode 100644 plugins/KeyboardNotify/src/EnumProc.h create mode 100644 plugins/KeyboardNotify/src/constants.h create mode 100644 plugins/KeyboardNotify/src/flash.cpp create mode 100644 plugins/KeyboardNotify/src/flash.h create mode 100644 plugins/KeyboardNotify/src/ignore.cpp create mode 100644 plugins/KeyboardNotify/src/ignore.h create mode 100644 plugins/KeyboardNotify/src/keyboard.cpp create mode 100644 plugins/KeyboardNotify/src/keyboard.h create mode 100644 plugins/KeyboardNotify/src/keypresses.cpp create mode 100644 plugins/KeyboardNotify/src/keypresses.h create mode 100644 plugins/KeyboardNotify/src/main.cpp create mode 100644 plugins/KeyboardNotify/src/options.cpp create mode 100644 plugins/KeyboardNotify/src/protolist.h create mode 100644 plugins/KeyboardNotify/src/resource.h create mode 100644 plugins/KeyboardNotify/src/trigger.cpp create mode 100644 plugins/KeyboardNotify/src/trigger.h create mode 100644 plugins/KeyboardNotify/src/utils.cpp create mode 100644 plugins/KeyboardNotify/src/utils.h delete mode 100644 plugins/KeyboardNotify/trigger.cpp delete mode 100644 plugins/KeyboardNotify/trigger.h delete mode 100644 plugins/KeyboardNotify/utils.cpp delete mode 100644 plugins/KeyboardNotify/utils.h (limited to 'plugins') diff --git a/plugins/Import/ICQserver.cpp b/plugins/Import/ICQserver.cpp deleted file mode 100644 index 372c0cb92c..0000000000 --- a/plugins/Import/ICQserver.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - -Import plugin for Miranda IM - -Copyright (C) 2001-2005 Martin Öberg, Richard Hughes, Roland Rabien & Tristan Van de Vreede - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -// ============== -// == INCLUDES == -// ============== - -#include "import.h" - -#include "ICQserver.h" -#include "resource.h" - -// ==================== -// ==================== -// == IMPLEMENTATION == -// ==================== -// ==================== - -BOOL CALLBACK ICQserverPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam) -{ - switch(message) { - case WM_INITDIALOG: - SendMessage(GetParent(hdlg),WIZM_DISABLEBUTTON,0,0); - SendMessage(GetParent(hdlg),WIZM_ENABLEBUTTON,1,0); - SendMessage(GetParent(hdlg),WIZM_DISABLEBUTTON,2,0); - TranslateDialogDefault(hdlg); - ICQserverImport(); - return TRUE; - - case WM_COMMAND: - switch(LOWORD(wParam)) { - case IDOK: - PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_FINISHED,(LPARAM)FinishedPageProc); - break; - case IDCANCEL: - PostMessage(GetParent(hdlg),WM_CLOSE,0,0); - break; - } - break; - } - return FALSE; -} - -static void ICQserverImport() -{ - // Clear last update stamp - DBDeleteContactSetting(NULL, szICQModuleName[ iICQAccount ], "SrvLastUpdate"); - DBDeleteContactSetting(NULL, szICQModuleName[ iICQAccount ], "SrvRecordCount"); - - // Enable contacts downloading - DBWriteContactSettingByte(NULL, szICQModuleName[ iICQAccount ], "UseServerCList", 1); - DBWriteContactSettingByte(NULL, szICQModuleName[ iICQAccount ], "AddServerNew", 1); - DBWriteContactSettingByte(NULL, szICQModuleName[ iICQAccount ], "UseServerNicks", 1); - DBWriteContactSettingByte(NULL, szICQModuleName[ iICQAccount ], "ServerAddRemove", 1); -} diff --git a/plugins/Import/ICQserver.h b/plugins/Import/ICQserver.h deleted file mode 100644 index 864890a978..0000000000 --- a/plugins/Import/ICQserver.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - -Import plugin for Miranda IM - -Copyright (C) 2001,2002,2003,2004 Martin Öberg, Richard Hughes, Roland Rabien & Tristan Van de Vreede - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - - - -#ifndef ICQSERVER_H -#define ICQSERVER_H - -#include - -// ====================== -// == GLOBAL FUNCTIONS == -// ====================== - -// ===================== -// == LOCAL FUNCTIONS == -// ===================== - -// Main function -static void ICQserverImport(); - -// GUI callbacks -INT_PTR CALLBACK FinishedPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam); - - -// ====================== -// == GLOBAL VARIABLES == -// ====================== - -extern int cICQAccounts; -extern char ** szICQModuleName; -extern TCHAR ** tszICQAccountName; -extern int iICQAccount; - -// ===================== -// == LOCAL VARIABLES == -// ===================== - -// ============= -// == DEFINES == -// ============= - -#endif \ No newline at end of file diff --git a/plugins/Import/docs/import-translation.txt b/plugins/Import/docs/import-translation.txt new file mode 100644 index 0000000000..18838c6ad9 --- /dev/null +++ b/plugins/Import/docs/import-translation.txt @@ -0,0 +1,164 @@ +; Common strings that belong to many files +;[Added %d contacts and %d groups.] +;[All Files] +;[Cancel] +;[Import completed in %d seconds.] +;[Importing groups.] +;[The given file does not exist. Please check that you have entered the name correctly.] + +; ../../plugins/Import/main.cpp +;[&Import...] +;[Added %s contact %s] +;[Added %s contact %s, '%s'] +;[Added contact %u (found in history)] +;[Failed to add %s contact %s] +;[Ignored event from/to self] +;[Skipping duplicate group %s.] + +; ../../plugins/Import/mirabilis.cpp +;[Added %d events and skipped %d duplicates.] +;[All groups may not have not been imported.] +;[Attempting to parse group list, type %d.] +;[Attempting to parse property block at offset %u.] +;[Attempting to parse property block list at offset %u.] +;[Attempting to parse sub list at offset %u.] +;[Attempting to parse wav file list at offset %u.] +;[ERROR: An error occurred while importing groups.] +;[ERROR: Failed to find contact list groups.] +;[ERROR: Failed to find owner information.] +;[Error: Unknown datatype (%u) at offset %u.] +;[Error: Unknown sub list type (%u) at offset %u.] +;[Failed to open database file] +;[Failed to open index file] +;[Failed to read Property block.] +;[Group import was not completed.] +;[ICQ account is not installed.] +;[Ignoring msg from user %d at ofs %d.] +;[Ignoring msg with no text from %d ofs %d.] +;[Import aborted] +;[Importing contacts] +;[Importing history (this may take a while)] +;[Mirabilis ICQ database indexes] +;[Mirabilis Import] +;[No ICQ contacts or history will be imported.] +;[Skipping 'Auth. accepted' msg, ofs %d.] +;[Skipping 'Auth. denied' msg, ofs %d.] +;[Skipping 'Birthday' msg (?), ofs %d.] +;[Skipping 'Chat request' msg, ofs %d.] +;[Skipping 'Contact' msg, ofs %d.] +;[Skipping 'Email Express' msg, ofs %d.] +;[Skipping 'Phonecall' msg (?), ofs %d.] +;[Skipping 'Request for auth.' msg, ofs %d.] +;[Skipping 'SMS' msg (?), ofs %d.] +;[Skipping 'System message', ofs %d.] +;[Skipping 'WWW Pager' msg, ofs %d.] +;[Skipping 'You were added' msg, ofs %d.] +;[Skipping 29 msg, ofs %d.] +;[Skipping 32 msg, ofs %d.] +;[Skipping contact with unsupported version.] +;[Skipping duplicate ICQ contact %u] +;[Skipping duplicate ICQ contact %u, %s] +;[Skipping event with ID < 2001.] +;[Skipping file message offset %d.] +;[Skipping inactive contact.] +;[Skipping message type 0xE3 at offset %d.] +;[Skipping non-ICQ contact %u.] +;[Skipping unknown 0xE0 subtype (%d), ofs %d.] +;[Skipping unknown event type %d at offset %d.] +;[Skipping unrecognizable contact.] +;[This database does not contain any contact groups.] +;[This database is an unknown version.] +;[This looks like a ICQ 2000a database.] +;[This looks like a ICQ 2000b database.] +;[This looks like a ICQ 2001, 2002 or 2003a database.] +;[This looks like a ICQ 99a database.] +;[This looks like a ICQ 99b database.] +;[default] + +; ../../plugins/Import/miranda.cpp +;[Added %d contacts, %d groups and %d events.] +;[Could not open file.] +;[DEBUG: Deleted setting treated as 0-length setting] +;[ERROR: Chain broken, no valid contact at %d] +;[ERROR: Faulty settings chain] +;[Failed to add message] +;[Failed to find module %s] +;[Failed to find setting %s] +;[Found module: %s] +;[Getting type %u value for setting: %s] +;[Group import failed.] +;[Ignoring module: %s] +;[Ignoring setting: %s] +;[Importing contacts.] +;[Importing history.] +;[Importing system history.] +;[Miranda IM database] +;[Miranda Import] +;[Modulename corrupted] +;[No owner found.] +;[Number of contacts in database: %d] +;[Read failure.] +;[Signature mismatch] +;[Skipped %d contacts.] +;[Skipped %d duplicates and %d filtered events.] +;[Skipped %d duplicates.] +;[Skipping %s contact, ID not found] +;[Skipping contact with no protocol] +;[Skipping contact, %s not installed.] +;[Skipping duplicate %s contact %s] +;[Skipping history import.] +;[Skipping new contacts import.] +;[Skipping non-IM contact (%s)] +;[Skipping system history import.] +;[This is not a valid Miranda IM database.] +;[This looks like a Miranda database, version 0.1.0.0 or above.] +;[Unknown error while adding %s contact %s] +;[Version mismatch] +;[Warning: Found module with no name] + +; ../../plugins/Import/resource.rc +;[&Account:] +;[&Filename:] +;[&Next >] +;[&Other Database...] +;[&Other Profile...] +;[< &Back] +;[Choose how you would like to import:] +;[Click \"Next\" to choose the information you wish to import, or click \"Cancel\" to exit the wizard and continue using Miranda.] +;[Custom import] +;[Do not load the import plugin at startup again] +;[File Transfers] +;[From a Mirabilis ICQ (99a - 2003a) database.] +;[From a Miranda IM database.] +;[If at a future date you wish to use the wizard again, you can make it load again by going to the Plugins section of the Options dialog box.] +;[If you want to change the way Miranda handles server-side contacts at a later time, you can do this in the \"ICQ Contacts\" page in the Miranda options.] +;[If you wish to import more information, click \"Next\" to return to the start of the wizard, otherwise click \"Finish\" to start using Miranda.] +;[Import Information Wizard] +;[Import all contacts and all messages] +;[Import completed] +;[Incoming] +;[It is recommended that you create a backup of your current Miranda profile before importing.] +;[Messages] +;[Miranda has found Mirabilis ICQ databases corresponding to the following ICQ numbers. Please select the one you wish to import, or click \"Other Database\" if your database is not listed.] +;[Miranda has found Miranda profiles with the following names. Please select the one you wish to import, or click \"Other Profile\" if your profile is not listed, or if the list is empty.] +;[Miranda has now been configured to automatically download the contacts in your server-side contact list the next time you connect to ICQ.] +;[New contacts && groups] +;[Now importing...] +;[Only import contacts] +;[Only since:] +;[Other] +;[Outgoing] +;[Progress1] +;[Select items to import:] +;[Select this if you want to customize what to import.] +;[Select this if you want to import as much data as possible. This is the recommended option.] +;[Select this if you want to import contacts but don't want to import any message history.] +;[System history] +;[This wizard will help you import contacts and message history from Mirabilis ICQ, as well as letting you import from other Miranda IM profiles.] +;[URLs] +;[Use the Find/Add contacts tool to populate my contact list.] +;[Warning: Mirabilis ICQ running. Import may not be reliable.] +;[You will probably never need to use this wizard again, so you can save memory by not loading it every time you start Miranda. This will mean that the import menu item will no longer be available.] + +; ../../plugins/Import/wizard.cpp +;[Finish] diff --git a/plugins/Import/import-translation.txt b/plugins/Import/import-translation.txt deleted file mode 100644 index 18838c6ad9..0000000000 --- a/plugins/Import/import-translation.txt +++ /dev/null @@ -1,164 +0,0 @@ -; Common strings that belong to many files -;[Added %d contacts and %d groups.] -;[All Files] -;[Cancel] -;[Import completed in %d seconds.] -;[Importing groups.] -;[The given file does not exist. Please check that you have entered the name correctly.] - -; ../../plugins/Import/main.cpp -;[&Import...] -;[Added %s contact %s] -;[Added %s contact %s, '%s'] -;[Added contact %u (found in history)] -;[Failed to add %s contact %s] -;[Ignored event from/to self] -;[Skipping duplicate group %s.] - -; ../../plugins/Import/mirabilis.cpp -;[Added %d events and skipped %d duplicates.] -;[All groups may not have not been imported.] -;[Attempting to parse group list, type %d.] -;[Attempting to parse property block at offset %u.] -;[Attempting to parse property block list at offset %u.] -;[Attempting to parse sub list at offset %u.] -;[Attempting to parse wav file list at offset %u.] -;[ERROR: An error occurred while importing groups.] -;[ERROR: Failed to find contact list groups.] -;[ERROR: Failed to find owner information.] -;[Error: Unknown datatype (%u) at offset %u.] -;[Error: Unknown sub list type (%u) at offset %u.] -;[Failed to open database file] -;[Failed to open index file] -;[Failed to read Property block.] -;[Group import was not completed.] -;[ICQ account is not installed.] -;[Ignoring msg from user %d at ofs %d.] -;[Ignoring msg with no text from %d ofs %d.] -;[Import aborted] -;[Importing contacts] -;[Importing history (this may take a while)] -;[Mirabilis ICQ database indexes] -;[Mirabilis Import] -;[No ICQ contacts or history will be imported.] -;[Skipping 'Auth. accepted' msg, ofs %d.] -;[Skipping 'Auth. denied' msg, ofs %d.] -;[Skipping 'Birthday' msg (?), ofs %d.] -;[Skipping 'Chat request' msg, ofs %d.] -;[Skipping 'Contact' msg, ofs %d.] -;[Skipping 'Email Express' msg, ofs %d.] -;[Skipping 'Phonecall' msg (?), ofs %d.] -;[Skipping 'Request for auth.' msg, ofs %d.] -;[Skipping 'SMS' msg (?), ofs %d.] -;[Skipping 'System message', ofs %d.] -;[Skipping 'WWW Pager' msg, ofs %d.] -;[Skipping 'You were added' msg, ofs %d.] -;[Skipping 29 msg, ofs %d.] -;[Skipping 32 msg, ofs %d.] -;[Skipping contact with unsupported version.] -;[Skipping duplicate ICQ contact %u] -;[Skipping duplicate ICQ contact %u, %s] -;[Skipping event with ID < 2001.] -;[Skipping file message offset %d.] -;[Skipping inactive contact.] -;[Skipping message type 0xE3 at offset %d.] -;[Skipping non-ICQ contact %u.] -;[Skipping unknown 0xE0 subtype (%d), ofs %d.] -;[Skipping unknown event type %d at offset %d.] -;[Skipping unrecognizable contact.] -;[This database does not contain any contact groups.] -;[This database is an unknown version.] -;[This looks like a ICQ 2000a database.] -;[This looks like a ICQ 2000b database.] -;[This looks like a ICQ 2001, 2002 or 2003a database.] -;[This looks like a ICQ 99a database.] -;[This looks like a ICQ 99b database.] -;[default] - -; ../../plugins/Import/miranda.cpp -;[Added %d contacts, %d groups and %d events.] -;[Could not open file.] -;[DEBUG: Deleted setting treated as 0-length setting] -;[ERROR: Chain broken, no valid contact at %d] -;[ERROR: Faulty settings chain] -;[Failed to add message] -;[Failed to find module %s] -;[Failed to find setting %s] -;[Found module: %s] -;[Getting type %u value for setting: %s] -;[Group import failed.] -;[Ignoring module: %s] -;[Ignoring setting: %s] -;[Importing contacts.] -;[Importing history.] -;[Importing system history.] -;[Miranda IM database] -;[Miranda Import] -;[Modulename corrupted] -;[No owner found.] -;[Number of contacts in database: %d] -;[Read failure.] -;[Signature mismatch] -;[Skipped %d contacts.] -;[Skipped %d duplicates and %d filtered events.] -;[Skipped %d duplicates.] -;[Skipping %s contact, ID not found] -;[Skipping contact with no protocol] -;[Skipping contact, %s not installed.] -;[Skipping duplicate %s contact %s] -;[Skipping history import.] -;[Skipping new contacts import.] -;[Skipping non-IM contact (%s)] -;[Skipping system history import.] -;[This is not a valid Miranda IM database.] -;[This looks like a Miranda database, version 0.1.0.0 or above.] -;[Unknown error while adding %s contact %s] -;[Version mismatch] -;[Warning: Found module with no name] - -; ../../plugins/Import/resource.rc -;[&Account:] -;[&Filename:] -;[&Next >] -;[&Other Database...] -;[&Other Profile...] -;[< &Back] -;[Choose how you would like to import:] -;[Click \"Next\" to choose the information you wish to import, or click \"Cancel\" to exit the wizard and continue using Miranda.] -;[Custom import] -;[Do not load the import plugin at startup again] -;[File Transfers] -;[From a Mirabilis ICQ (99a - 2003a) database.] -;[From a Miranda IM database.] -;[If at a future date you wish to use the wizard again, you can make it load again by going to the Plugins section of the Options dialog box.] -;[If you want to change the way Miranda handles server-side contacts at a later time, you can do this in the \"ICQ Contacts\" page in the Miranda options.] -;[If you wish to import more information, click \"Next\" to return to the start of the wizard, otherwise click \"Finish\" to start using Miranda.] -;[Import Information Wizard] -;[Import all contacts and all messages] -;[Import completed] -;[Incoming] -;[It is recommended that you create a backup of your current Miranda profile before importing.] -;[Messages] -;[Miranda has found Mirabilis ICQ databases corresponding to the following ICQ numbers. Please select the one you wish to import, or click \"Other Database\" if your database is not listed.] -;[Miranda has found Miranda profiles with the following names. Please select the one you wish to import, or click \"Other Profile\" if your profile is not listed, or if the list is empty.] -;[Miranda has now been configured to automatically download the contacts in your server-side contact list the next time you connect to ICQ.] -;[New contacts && groups] -;[Now importing...] -;[Only import contacts] -;[Only since:] -;[Other] -;[Outgoing] -;[Progress1] -;[Select items to import:] -;[Select this if you want to customize what to import.] -;[Select this if you want to import as much data as possible. This is the recommended option.] -;[Select this if you want to import contacts but don't want to import any message history.] -;[System history] -;[This wizard will help you import contacts and message history from Mirabilis ICQ, as well as letting you import from other Miranda IM profiles.] -;[URLs] -;[Use the Find/Add contacts tool to populate my contact list.] -;[Warning: Mirabilis ICQ running. Import may not be reliable.] -;[You will probably never need to use this wizard again, so you can save memory by not loading it every time you start Miranda. This will mean that the import menu item will no longer be available.] - -; ../../plugins/Import/wizard.cpp -;[Finish] diff --git a/plugins/Import/import.h b/plugins/Import/import.h deleted file mode 100644 index cbb6111a35..0000000000 --- a/plugins/Import/import.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - -Import plugin for Miranda IM - -Copyright (C) 2001,2002,2003,2004 Martin Öberg, Richard Hughes, Roland Rabien & Tristan Van de Vreede - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - - -//#define _LOGGING 1 - -#define MIRANDA_VER 0x0A00 - -#define WINVER 0x0501 -#define _WIN32_WINNT 0x0501 -#define _WIN32_IE 0x0501 - -#include - -#include -#include // datetimepicker - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// ** Global constants - -#define IMPORT_MODULE "MIMImport" // Module name -#define IMPORT_SERVICE "MIMImport/Import" // Service for menu item - -// Keys -#define IMP_KEY_FR "FirstRun" // First run - - -#define WIZM_GOTOPAGE (WM_USER+10) //wParam=resource id, lParam=dlgproc -#define WIZM_DISABLEBUTTON (WM_USER+11) //wParam=0:back, 1:next, 2:cancel -#define WIZM_SETCANCELTEXT (WM_USER+12) //lParam=(char*)newText -#define WIZM_ENABLEBUTTON (WM_USER+13) //wParam=0:back, 1:next, 2:cancel - -#define PROGM_SETPROGRESS (WM_USER+10) //wParam=0..100 -#define PROGM_ADDMESSAGE (WM_USER+11) //lParam=(char*)szText -#define SetProgress(n) SendMessage(hdlgProgress,PROGM_SETPROGRESS,n,0) - -#define ICQOSCPROTONAME "ICQ" -#define MSNPROTONAME "MSN" -#define YAHOOPROTONAME "YAHOO" -#define NSPPROTONAME "NET_SEND" -#define ICQCORPPROTONAME "ICQ Corp" -#define AIMPROTONAME "AIM" - -// Import type -#define IMPORT_CONTACTS 0 -#define IMPORT_ALL 1 -#define IMPORT_CUSTOM 2 - -// Custom import options -#define IOPT_ADDUNKNOWN 1 -#define IOPT_MSGSENT 2 -#define IOPT_MSGRECV 4 -#define IOPT_URLSENT 8 -#define IOPT_URLRECV 16 -#define IOPT_AUTHREQ 32 -#define IOPT_ADDED 64 -#define IOPT_FILESENT 128 -#define IOPT_FILERECV 256 -#define IOPT_OTHERSENT 512 -#define IOPT_OTHERRECV 1024 -#define IOPT_SYSTEM 2048 -#define IOPT_CONTACTS 4096 -#define IOPT_GROUPS 8192 - -void AddMessage( const char* fmt, ... ); - -int CreateGroup(BYTE type, const char* name, HANDLE hContact); - -extern HWND hdlgProgress; - -extern DWORD nDupes, nContactsCount, nMessagesCount, nGroupsCount, nSkippedEvents, nSkippedContacts; diff --git a/plugins/Import/import.ico b/plugins/Import/import.ico deleted file mode 100644 index bf7417ae50..0000000000 Binary files a/plugins/Import/import.ico and /dev/null differ diff --git a/plugins/Import/import_10.vcxproj b/plugins/Import/import_10.vcxproj index 59b817462f..55f52a577a 100644 --- a/plugins/Import/import_10.vcxproj +++ b/plugins/Import/import_10.vcxproj @@ -73,7 +73,7 @@ Disabled ..\..\include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;IMPORT_EXPORTS;%(PreprocessorDefinitions) + WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebugDLL true @@ -82,7 +82,6 @@ import.h Level3 EditAndContinue - 4996;%(DisableSpecificWarnings) _DEBUG;%(PreprocessorDefinitions) @@ -106,14 +105,13 @@ Disabled ..\..\include;%(AdditionalIncludeDirectories) - WIN64;_DEBUG;_WINDOWS;_USRDLL;IMPORT_EXPORTS;%(PreprocessorDefinitions) + WIN64;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebugDLL true Use import.h Level3 - 4996;%(DisableSpecificWarnings) _DEBUG;%(PreprocessorDefinitions) @@ -139,7 +137,7 @@ OnlyExplicitInline Size ..\..\include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;IMPORT_EXPORTS;%(PreprocessorDefinitions) + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true false false @@ -148,14 +146,12 @@ Use import.h Level3 - 4996;%(DisableSpecificWarnings) NDEBUG;%(PreprocessorDefinitions) ..\..\include\msapi - /ALIGN:4096 /ignore:4108 %(AdditionalOptions) comctl32.lib;%(AdditionalDependencies) type=%27Win32%27 name=%27Microsoft.Windows.Common-Controls%27 version=%276.0.0.0%27 processorArchitecture=%27X86%27 publicKeyToken=%276595b64144ccf1df%27 language=%27*%27;%(AdditionalManifestDependencies) true @@ -177,7 +173,7 @@ OnlyExplicitInline Size ..\..\include;%(AdditionalIncludeDirectories) - WIN64;NDEBUG;_WINDOWS;_USRDLL;IMPORT_EXPORTS;%(PreprocessorDefinitions) + WIN64;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true false false @@ -186,14 +182,12 @@ Use import.h Level3 - 4996;%(DisableSpecificWarnings) NDEBUG;%(PreprocessorDefinitions) ..\..\include\msapi - /ALIGN:4096 /ignore:4108 %(AdditionalOptions) comctl32.lib;%(AdditionalDependencies) type=%27Win32%27 name=%27Microsoft.Windows.Common-Controls%27 version=%276.0.0.0%27 processorArchitecture=%27*%27 publicKeyToken=%276595b64144ccf1df%27 language=%27*%27;%(AdditionalManifestDependencies) true @@ -210,31 +204,30 @@ - - + + Create - - - - + + + + - - - - - + + + + + - - + diff --git a/plugins/Import/import_10.vcxproj.filters b/plugins/Import/import_10.vcxproj.filters index 48118ce444..33a708cb33 100644 --- a/plugins/Import/import_10.vcxproj.filters +++ b/plugins/Import/import_10.vcxproj.filters @@ -18,46 +18,43 @@ - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - - Resource Files - Documentation @@ -72,7 +69,7 @@ - + Resource Files diff --git a/plugins/Import/main.cpp b/plugins/Import/main.cpp deleted file mode 100644 index 8b7524c040..0000000000 --- a/plugins/Import/main.cpp +++ /dev/null @@ -1,543 +0,0 @@ -/* - -Import plugin for Miranda IM - -Copyright (C) 2001-2005 Martin Öberg, Richard Hughes, Roland Rabien & Tristan Van de Vreede - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "import.h" -#include "version.h" -#include "resource.h" - -void FreeVariant( DBVARIANT* dbv ); -void WriteVariant( HANDLE hContact, const char* module, const char* var, DBVARIANT* dbv ); - -BOOL IsDuplicateEvent(HANDLE hContact, DBEVENTINFO dbei); - - -int nImportOption; -int nCustomOptions; - -int cICQAccounts = 0; -char ** szICQModuleName = NULL; -TCHAR ** tszICQAccountName = NULL; -int iICQAccount = 0; - -static HANDLE hHookModulesLoaded = NULL; -static HANDLE hHookOnExit = NULL; -static HANDLE hImportService = NULL; - - -INT_PTR CALLBACK WizardDlgProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam); - -HINSTANCE hInst; - -static HWND hwndWizard = NULL; -int hLangpack; - -PLUGININFOEX pluginInfo = { - sizeof(PLUGININFOEX), - "Import contacts and messages", - __VERSION_DWORD, - "Imports contacts and messages from Mirabilis ICQ and Miranda IM.", - "Miranda team", - "info@miranda-im.org", - "© 2000-2010 Martin Öberg, Richard Hughes, Dmitry Kuzkin, George Hazan", - "http://www.miranda-im.org", - UNICODE_AWARE, //{2D77A746-00A6-4343-BFC5-F808CDD772EA} - {0x2d77a746, 0xa6, 0x4343, { 0xbf, 0xc5, 0xf8, 0x8, 0xcd, 0xd7, 0x72, 0xea }} -}; - -BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) -{ - hInst = hinstDLL; - return TRUE; -} - -static INT_PTR ImportCommand(WPARAM wParam,LPARAM lParam) -{ - if (IsWindow(hwndWizard)) { - SetForegroundWindow(hwndWizard); - SetFocus(hwndWizard); - } - else hwndWizard = CreateDialog(hInst, MAKEINTRESOURCE(IDD_WIZARD), NULL, WizardDlgProc); - - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// MirandaPluginInfoEx - returns an information about a plugin - -extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) -{ - return &pluginInfo; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// MirandaInterfaces - returns the protocol interface to the core - -extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = {MIID_IMPORT, MIID_LAST}; - -///////////////////////////////////////////////////////////////////////////////////////// -// Performs a primary set of actions upon plugin loading - -static int ModulesLoaded(WPARAM wParam, LPARAM lParam) -{ - int nProtocols = 0; - int n; - PROTOCOLDESCRIPTOR **ppProtos = NULL; - - if (DBGetContactSettingByte(NULL, IMPORT_MODULE, IMP_KEY_FR, 0)) - return 0; - - // Only autorun import wizard if at least one protocol is installed - CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&nProtocols, (LPARAM)&ppProtos); - for (n=0; n < nProtocols; n++) { - if (ppProtos[n]->type == PROTOTYPE_PROTOCOL) { - CallService(IMPORT_SERVICE, 0, 0); - DBWriteContactSettingByte(NULL, IMPORT_MODULE, IMP_KEY_FR, 1); - break; - } } - return 0; -} - -static int OnExit(WPARAM wParam, LPARAM lParam) -{ - if ( hwndWizard ) - SendMessage(hwndWizard, WM_CLOSE, 0, 0); - return 0; -} - -extern "C" __declspec(dllexport) int Load(void) -{ - mir_getLP( &pluginInfo ); - - hImportService = CreateServiceFunction(IMPORT_SERVICE, ImportCommand); - { - CLISTMENUITEM mi; - ZeroMemory(&mi, sizeof(mi)); - mi.cbSize = sizeof(mi); - mi.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_IMPORT)); - mi.pszName = LPGEN("&Import..."); - mi.position = 500050000; - mi.pszService = IMPORT_SERVICE; - Menu_AddMainMenuItem(&mi); - } - hHookModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoaded); - hHookOnExit = HookEvent(ME_SYSTEM_OKTOEXIT, OnExit); - { - INITCOMMONCONTROLSEX icex; - icex.dwSize = sizeof(icex); - icex.dwICC = ICC_DATE_CLASSES; - InitCommonControlsEx(&icex); - } - - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Unload a plugin - -extern "C" __declspec(dllexport) int Unload(void) -{ - if (hHookModulesLoaded) - UnhookEvent(hHookModulesLoaded); - if (hHookOnExit) - UnhookEvent(hHookOnExit); - if (hImportService) - DestroyServiceFunction(hImportService); - - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -BOOL IsProtocolLoaded(char* pszProtocolName) -{ - return CallService(MS_PROTO_ISPROTOCOLLOADED, 0, (LPARAM)pszProtocolName) ? TRUE : FALSE; -} - -BOOL EnumICQAccounts() -{ - int count, i = 0; - PROTOACCOUNT ** accs; - - while (cICQAccounts) - { - cICQAccounts--; - free(szICQModuleName[cICQAccounts]); - free(tszICQAccountName[cICQAccounts]); - } - - ProtoEnumAccounts(&count, &accs); - szICQModuleName = (char**)realloc(szICQModuleName, count * sizeof(char**)); - tszICQAccountName = (TCHAR**)realloc(tszICQAccountName, count * sizeof(TCHAR**)); - while (i < count) - { - if ((0 == strcmp(ICQOSCPROTONAME, accs[i]->szProtoName)) && accs[i]->bIsEnabled) - { - szICQModuleName[cICQAccounts] = strdup(accs[i]->szModuleName); - tszICQAccountName[cICQAccounts] = _tcsdup(accs[i]->tszAccountName); - cICQAccounts++; - } - i++; - } - return cICQAccounts != 0; -} - -void FreeICQAccountsList() -{ - while (cICQAccounts) - { - cICQAccounts--; - free(szICQModuleName[cICQAccounts]); - free(tszICQAccountName[cICQAccounts]); - } - - if (szICQModuleName) - free(szICQModuleName); - if (tszICQAccountName) - free(tszICQAccountName); - - szICQModuleName = NULL; - tszICQAccountName = NULL; -} - -HANDLE HContactFromNumericID(char* pszProtoName, char* pszSetting, DWORD dwID) -{ - char* szProto; - HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); - while (hContact != NULL) - { - if (DBGetContactSettingDword(hContact, pszProtoName, pszSetting, 0) == dwID) - { - szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); - if (szProto != NULL && !strcmp(szProto, pszProtoName)) - return hContact; - } - hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); - } - return INVALID_HANDLE_VALUE; -} - -HANDLE HContactFromID(char* pszProtoName, char* pszSetting, char* pszID) -{ - DBVARIANT dbv; - HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); - while (hContact != NULL) { - char* szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); - if ( !lstrcmpA(szProto, pszProtoName)) { - if (DBGetContactSettingString(hContact, pszProtoName, pszSetting, &dbv) == 0) { - if (strcmp(pszID, dbv.pszVal) == 0) { - DBFreeVariant(&dbv); - return hContact; - } - DBFreeVariant(&dbv); - } - } - - hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); - } - return INVALID_HANDLE_VALUE; -} - -HANDLE HistoryImportFindContact(HWND hdlgProgress, char* szModuleName, DWORD uin, int addUnknown) -{ - HANDLE hContact = HContactFromNumericID(szModuleName, "UIN", uin); - if (hContact == NULL) { - AddMessage( LPGEN("Ignored event from/to self")); - return INVALID_HANDLE_VALUE; - } - - if (hContact != INVALID_HANDLE_VALUE) - return hContact; - - if (!addUnknown) - return INVALID_HANDLE_VALUE; - - hContact = (HANDLE)CallService(MS_DB_CONTACT_ADD, 0, 0); - CallService(MS_PROTO_ADDTOCONTACT, (WPARAM)hContact, (LPARAM)szModuleName); - DBWriteContactSettingDword(hContact, szModuleName, "UIN", uin); - AddMessage( LPGEN("Added contact %u (found in history)"), uin ); - return hContact; -} - -HANDLE AddContact(HWND hdlgProgress, char* pszProtoName, char* pszUniqueSetting, - DBVARIANT* id, DBVARIANT* nick, DBVARIANT* group) -{ - HANDLE hContact; - char szid[ 40 ]; - char* pszUserID = ( id->type == DBVT_DWORD ) ? _ltoa( id->dVal, szid, 10 ) : id->pszVal; - - 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); - AddMessage( LPGEN("Failed to add %s contact %s"), pszProtoName, pszUserID ); - FreeVariant( id ); - FreeVariant( nick ); - FreeVariant( group ); - return INVALID_HANDLE_VALUE; - } - - WriteVariant( hContact, pszProtoName, pszUniqueSetting, id ); - - if ( group->type ) - CreateGroup( group->type, group->pszVal, hContact ); - - if ( nick->type && nick->pszVal[0] ) { - WriteVariant( hContact, "CList", "MyHandle", nick ); - if (nick->type == DBVT_UTF8) { - char *tmp = mir_utf8decodeA(nick->pszVal); - AddMessage( LPGEN("Added %s contact %s, '%s'"), pszProtoName, pszUserID, tmp ); - mir_free(tmp); - } - else AddMessage( LPGEN("Added %s contact %s, '%s'"), pszProtoName, pszUserID, nick->pszVal ); - } - else AddMessage( LPGEN("Added %s contact %s"), pszProtoName, pszUserID ); - - FreeVariant( id ); - FreeVariant( nick ); - FreeVariant( group ); - return hContact; -} - -// ------------------------------------------------ -// Creates a group with a specified name in the -// Miranda contact list. -// If contact is specified adds it to group -// ------------------------------------------------ -// Returns 1 if successful and 0 when it fails. -int CreateGroup(BYTE type, const char* name, HANDLE hContact) -{ - int groupId; - TCHAR *tmp, *tszGrpName; - char groupIdStr[11]; - size_t cbName; - - if (type == DBVT_UTF8) - tmp = mir_utf8decodeT( name ); - else if (type == DBVT_WCHAR) - tmp = mir_u2t(( wchar_t* )name ); - else - tmp = mir_a2t( name ); - - if ( tmp == NULL ) - return 0; - - cbName = _tcslen(tmp); - tszGrpName = (TCHAR*)_alloca(( cbName+2 )*sizeof( TCHAR )); - tszGrpName[0] = 1 | GROUPF_EXPANDED; - _tcscpy( tszGrpName+1, tmp ); - mir_free( tmp ); - - // Check for duplicate & find unused id - for (groupId = 0; ; groupId++) { - DBVARIANT dbv; - itoa(groupId, groupIdStr,10); - if (DBGetContactSettingTString(NULL, "CListGroups", groupIdStr, &dbv)) - break; - - if ( !lstrcmp(dbv.ptszVal + 1, tszGrpName + 1 )) { - if (hContact) - DBWriteContactSettingTString( hContact, "CList", "Group", tszGrpName+1 ); - else { - char *str = mir_t2a(tszGrpName + 1); - AddMessage( LPGEN("Skipping duplicate group %s."), str); - mir_free(str); - } - - DBFreeVariant(&dbv); - return 0; - } - - DBFreeVariant(&dbv); - } - - DBWriteContactSettingTString( NULL, "CListGroups", groupIdStr, tszGrpName ); - - if (hContact) - DBWriteContactSettingTString( hContact, "CList", "Group", tszGrpName+1 ); - - return 1; -} - -// Returns TRUE if the event already exist in the database -BOOL IsDuplicateEvent(HANDLE hContact, DBEVENTINFO dbei) -{ - static DWORD dwPreviousTimeStamp = -1; - static HANDLE hPreviousContact = INVALID_HANDLE_VALUE; - static HANDLE hPreviousDbEvent = NULL; - - HANDLE hExistingDbEvent; - DWORD dwEventTimeStamp; - DBEVENTINFO dbeiExisting; - - // get last event - if (!(hExistingDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDLAST, (WPARAM)hContact, 0))) - return FALSE; - - ZeroMemory(&dbeiExisting, sizeof(dbeiExisting)); - dbeiExisting.cbSize = sizeof(dbeiExisting); - CallService(MS_DB_EVENT_GET, (WPARAM)hExistingDbEvent, (LPARAM)&dbeiExisting); - dwEventTimeStamp = dbeiExisting.timestamp; - - // compare with last timestamp - if (dbei.timestamp > dwEventTimeStamp) - { - // remember event - hPreviousDbEvent = hExistingDbEvent; - dwPreviousTimeStamp = dwEventTimeStamp; - return FALSE; - } - - if (hContact != hPreviousContact) - { - hPreviousContact = hContact; - // remember event - hPreviousDbEvent = hExistingDbEvent; - dwPreviousTimeStamp = dwEventTimeStamp; - - // get first event - if (!(hExistingDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDFIRST, (WPARAM)hContact, 0))) - return FALSE; - - ZeroMemory(&dbeiExisting, sizeof(dbeiExisting)); - dbeiExisting.cbSize = sizeof(dbeiExisting); - CallService(MS_DB_EVENT_GET, (WPARAM)hExistingDbEvent, (LPARAM)&dbeiExisting); - dwEventTimeStamp = dbeiExisting.timestamp; - - // compare with first timestamp - if (dbei.timestamp <= dwEventTimeStamp) - { - // remember event - dwPreviousTimeStamp = dwEventTimeStamp; - hPreviousDbEvent = hExistingDbEvent; - - if ( dbei.timestamp != dwEventTimeStamp ) - return FALSE; - } - - } - // check for equal timestamps - if (dbei.timestamp == dwPreviousTimeStamp) - { - ZeroMemory(&dbeiExisting, sizeof(dbeiExisting)); - dbeiExisting.cbSize = sizeof(dbeiExisting); - CallService(MS_DB_EVENT_GET, (WPARAM)hPreviousDbEvent, (LPARAM)&dbeiExisting); - - if ((dbei.timestamp == dbeiExisting.timestamp) && - (dbei.eventType == dbeiExisting.eventType) && - (dbei.cbBlob == dbeiExisting.cbBlob) && - ((dbei.flags&DBEF_SENT) == (dbeiExisting.flags&DBEF_SENT))) - return TRUE; - - // find event with another timestamp - hExistingDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDNEXT, (WPARAM)hPreviousDbEvent, 0); - while (hExistingDbEvent != NULL) - { - ZeroMemory(&dbeiExisting, sizeof(dbeiExisting)); - dbeiExisting.cbSize = sizeof(dbeiExisting); - CallService(MS_DB_EVENT_GET, (WPARAM)hExistingDbEvent, (LPARAM)&dbeiExisting); - - if (dbeiExisting.timestamp != dwPreviousTimeStamp) - { - // use found event - hPreviousDbEvent = hExistingDbEvent; - dwPreviousTimeStamp = dbeiExisting.timestamp; - break; - } - - hPreviousDbEvent = hExistingDbEvent; - hExistingDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDNEXT, (WPARAM)hExistingDbEvent, 0); - } - } - - hExistingDbEvent = hPreviousDbEvent; - - if (dbei.timestamp <= dwPreviousTimeStamp) - { - // look back - while (hExistingDbEvent != NULL) - { - ZeroMemory(&dbeiExisting, sizeof(dbeiExisting)); - dbeiExisting.cbSize = sizeof(dbeiExisting); - CallService(MS_DB_EVENT_GET, (WPARAM)hExistingDbEvent, (LPARAM)&dbeiExisting); - - if (dbei.timestamp > dbeiExisting.timestamp) - { - // remember event - hPreviousDbEvent = hExistingDbEvent; - dwPreviousTimeStamp = dbeiExisting.timestamp; - return FALSE; - } - - // Compare event with import candidate - if ((dbei.timestamp == dbeiExisting.timestamp) && - (dbei.eventType == dbeiExisting.eventType) && - (dbei.cbBlob == dbeiExisting.cbBlob) && - ((dbei.flags&DBEF_SENT) == (dbeiExisting.flags&DBEF_SENT))) - { - // remember event - hPreviousDbEvent = hExistingDbEvent; - dwPreviousTimeStamp = dbeiExisting.timestamp; - return TRUE; - } - - // Get previous event in chain - hExistingDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDPREV, (WPARAM)hExistingDbEvent, 0); - } - - } - else - { - // look forward - while (hExistingDbEvent != NULL) - { - ZeroMemory(&dbeiExisting, sizeof(dbeiExisting)); - dbeiExisting.cbSize = sizeof(dbeiExisting); - CallService(MS_DB_EVENT_GET, (WPARAM)hExistingDbEvent, (LPARAM)&dbeiExisting); - - if (dbei.timestamp < dbeiExisting.timestamp) - { - // remember event - hPreviousDbEvent = hExistingDbEvent; - dwPreviousTimeStamp = dbeiExisting.timestamp; - return FALSE; - } - - // Compare event with import candidate - if ((dbei.timestamp == dbeiExisting.timestamp) && - (dbei.eventType == dbeiExisting.eventType) && - (dbei.cbBlob == dbeiExisting.cbBlob) && - ((dbei.flags&DBEF_SENT) == (dbeiExisting.flags&DBEF_SENT))) - { - // remember event - hPreviousDbEvent = hExistingDbEvent; - dwPreviousTimeStamp = dbeiExisting.timestamp; - return TRUE; - } - - // Get next event in chain - hExistingDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDNEXT, (WPARAM)hExistingDbEvent, 0); - } - - } - // reset last event - hPreviousContact = INVALID_HANDLE_VALUE; - return FALSE; -} diff --git a/plugins/Import/mirabilis.cpp b/plugins/Import/mirabilis.cpp deleted file mode 100644 index 1f032827af..0000000000 --- a/plugins/Import/mirabilis.cpp +++ /dev/null @@ -1,1493 +0,0 @@ -/* - -Import plugin for Miranda IM - -Copyright (C) 2001-2005 Martin Öberg, Richard Hughes, Roland Rabien & Tristan Van de Vreede - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -// ============== -// == INCLUDES == -// ============== - -#include "import.h" -#include "mirabilis.h" -#include "resource.h" - -BOOL IsDuplicateEvent(HANDLE hContact, DBEVENTINFO dbei); -BOOL IsProtocolLoaded(char* pszProtocolName); -HANDLE HContactFromNumericID(char* pszProtoName, char* pszSetting, DWORD dwID); -HANDLE AddContact(HWND hdlgProgress, char* pszProtoName, char* pszUniqueSetting, DBVARIANT* id, DBVARIANT* nick, DBVARIANT* group); - -// ==================== -// ==================== -// == IMPLEMENTATION == -// ==================== -// ==================== - -static void SearchForDatabases(HWND hdlg, const TCHAR *dbPath, const TCHAR *type) -{ - HANDLE hFind; - WIN32_FIND_DATA fd; - TCHAR szSearchPath[MAX_PATH]; - TCHAR szRootName[MAX_PATH],*str2; - - int i; - - wsprintf(szSearchPath, _T("%s\\*.idx"), dbPath); - hFind=FindFirstFile(szSearchPath,&fd); - if(hFind!=INVALID_HANDLE_VALUE) { - do { - lstrcpy(szRootName,fd.cFileName); - str2=_tcsrchr(szRootName,'.'); - if(str2!=NULL) *str2=0; - if(lstrlen(szRootName)>3 && !lstrcmpi(szRootName+lstrlen(szRootName)-3,_T("tmp"))) - continue; - lstrcat(szRootName,type); - i=SendDlgItemMessage(hdlg,IDC_LIST,LB_ADDSTRING,0,(LPARAM)szRootName); - str2 = (TCHAR*)mir_alloc((lstrlen(dbPath) + 2+lstrlen(fd.cFileName))*sizeof(TCHAR)); - wsprintf(str2, _T("%s\\%s"), dbPath, fd.cFileName); - SendDlgItemMessage(hdlg,IDC_LIST,LB_SETITEMDATA,i,(LPARAM)str2); - } - while( FindNextFile( hFind, &fd )); - - FindClose(hFind); - } -} - -INT_PTR CALLBACK MirabilisPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam) -{ - switch(message) { - case WM_INITDIALOG: - { - HKEY hKey; - LONG lResult; - int i; - TranslateDialogDefault(hdlg); - if (ERROR_SUCCESS != (lResult = RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software\\Mirabilis\\ICQ\\DefaultPrefs"), 0, KEY_QUERY_VALUE, &hKey))) - lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\Mirabilis\\ICQ\\DefaultPrefs"), 0, KEY_QUERY_VALUE, &hKey); - - if (lResult == ERROR_SUCCESS) { - TCHAR dbPath[MAX_PATH]; - DWORD cch; - cch=sizeof(dbPath); - if(ERROR_SUCCESS==RegQueryValueEx(hKey,_T("New Database"),NULL,NULL,(LPBYTE)dbPath,&cch)) - SearchForDatabases(hdlg,dbPath,_T(" (99a)")); - cch=sizeof(dbPath); - if(ERROR_SUCCESS==RegQueryValueEx(hKey,_T("99b Database"),NULL,NULL,(LPBYTE)dbPath,&cch)) - SearchForDatabases(hdlg,dbPath,_T(" (99b)")); - cch=sizeof(dbPath); - if(ERROR_SUCCESS==RegQueryValueEx(hKey,_T("2000a Database"),NULL,NULL,(LPBYTE)dbPath,&cch)) - SearchForDatabases(hdlg,dbPath,_T(" (2000a)")); - cch=sizeof(dbPath); - if(ERROR_SUCCESS==RegQueryValueEx(hKey,_T("2000b Database"),NULL,NULL,(LPBYTE)dbPath,&cch)) - SearchForDatabases(hdlg,dbPath,_T(" (2000b)")); - cch=sizeof(dbPath); - if(ERROR_SUCCESS==RegQueryValueEx(hKey,_T("2001a Database"),NULL,NULL,(LPBYTE)dbPath,&cch)) - SearchForDatabases(hdlg,dbPath,_T(" (2001a)")); - cch=sizeof(dbPath); - if(ERROR_SUCCESS==RegQueryValueEx(hKey,_T("2001b Database"),NULL,NULL,(LPBYTE)dbPath,&cch)) - SearchForDatabases(hdlg,dbPath,_T(" (2001b)")); - cch=sizeof(dbPath); - if(ERROR_SUCCESS==RegQueryValueEx(hKey,_T("2002a Database"),NULL,NULL,(LPBYTE)dbPath,&cch)) - SearchForDatabases(hdlg,dbPath,_T(" (2002a)")); - cch=sizeof(dbPath); - if(ERROR_SUCCESS==RegQueryValueEx(hKey,_T("2003a Database"),NULL,NULL,(LPBYTE)dbPath,&cch)) - SearchForDatabases(hdlg,dbPath,_T(" (2003a)")); - } - - for (i = 0; i < cICQAccounts; i++) - { - SendDlgItemMessage(hdlg, IDC_MIRABILISACCOUNT, CB_ADDSTRING, 0, (LPARAM)tszICQAccountName[i]); - } - SendDlgItemMessage(hdlg, IDC_MIRABILISACCOUNT, CB_SETCURSEL, 0, 0); - - SetTimer(hdlg,1,2000,NULL); - SendMessage(hdlg,WM_TIMER,0,0); - return TRUE; - } - case WM_TIMER: - { HANDLE hMirabilisMutex; - hMirabilisMutex=OpenMutexA(MUTEX_ALL_ACCESS,FALSE,"Mirabilis ICQ Mutex"); - if(hMirabilisMutex!=NULL) { - CloseHandle(hMirabilisMutex); - ShowWindow(GetDlgItem(hdlg,IDC_MIRABILISRUNNING),SW_SHOW); - } - else ShowWindow(GetDlgItem(hdlg,IDC_MIRABILISRUNNING),SW_HIDE); - } - break; - case WM_COMMAND: - switch(LOWORD(wParam)) { - case IDC_BACK: - PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_IMPORTTYPE,(LPARAM)ImportTypePageProc); - break; - case IDOK: - { TCHAR filename[MAX_PATH]; - GetDlgItemText(hdlg,IDC_FILENAME,filename,SIZEOF(filename)); - if(_taccess(filename,4)) { - MessageBox(hdlg,TranslateT("The given file does not exist. Please check that you have entered the name correctly."),TranslateT("Mirabilis Import"),MB_OK); - break; - } - lstrcpy(importFile,filename); - iICQAccount = SendDlgItemMessage(hdlg, IDC_MIRABILISACCOUNT, CB_GETCURSEL, 0, 0); - PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_OPTIONS,(LPARAM)MirabilisOptionsPageProc); - break; - } - case IDCANCEL: - PostMessage(GetParent(hdlg),WM_CLOSE,0,0); - break; - case IDC_LIST: - if(HIWORD(wParam)==LBN_SELCHANGE) { - int sel=SendDlgItemMessage(hdlg,IDC_LIST,LB_GETCURSEL,0,0); - if(sel==LB_ERR) break; - SetDlgItemText(hdlg,IDC_FILENAME,(TCHAR*)SendDlgItemMessage(hdlg,IDC_LIST,LB_GETITEMDATA,sel,0)); - } - break; - case IDC_OTHER: - { OPENFILENAME ofn; - TCHAR str[MAX_PATH], text[256]; - int index; - - // TranslateTS doesnt translate \0 separated strings - index = mir_sntprintf(text, 64, _T("%s (*.idx)"), TranslateT("Mirabilis ICQ database indexes")) + 1; - _tcscpy(text + index, _T("*.idx")); index += 6; - index += mir_sntprintf(text + index, 64, _T("%s (*.*)"), TranslateT("All Files")) + 1; - _tcscpy(text + index, _T("*.*")); index += 4; - text[index] = 0; - - GetDlgItemText(hdlg,IDC_FILENAME,str,SIZEOF(str)); - ZeroMemory(&ofn, sizeof(ofn)); - ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; - ofn.hwndOwner = hdlg; - ofn.lpstrFilter = text; - ofn.lpstrFile = str; - ofn.Flags = OFN_FILEMUSTEXIST | OFN_EXPLORER | OFN_NOCHANGEDIR | OFN_DONTADDTORECENT; - ofn.nMaxFile = SIZEOF(str); - ofn.lpstrDefExt = _T("idx"); - if(GetOpenFileName(&ofn)) - SetDlgItemText(hdlg,IDC_FILENAME,str); - break; - } - } - break; - - case WM_DESTROY: - { int i; - for(i=SendDlgItemMessage(hdlg,IDC_LIST,LB_GETCOUNT,0,0)-1;i>=0;i--) - mir_free((char*)SendDlgItemMessage(hdlg,IDC_LIST,LB_GETITEMDATA,i,0)); - break; - } - } - return FALSE; -} - - -INT_PTR CALLBACK MirabilisOptionsPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam) -{ - switch(message) { - case WM_INITDIALOG: - TranslateDialogDefault(hdlg); - EnableWindow(GetDlgItem(hdlg, IDC_RADIO_ALL), TRUE); - EnableWindow(GetDlgItem(hdlg, IDC_STATIC_ALL), TRUE); - EnableWindow(GetDlgItem(hdlg, IDC_RADIO_CONTACTS), TRUE); - EnableWindow(GetDlgItem(hdlg, IDC_STATIC_CONTACTS), TRUE); - CheckDlgButton(hdlg, IDC_RADIO_ALL, BST_CHECKED); - return TRUE; - - case WM_COMMAND: - switch(LOWORD(wParam)) { - case IDC_BACK: - PostMessage(GetParent(hdlg), WIZM_GOTOPAGE, IDD_MIRABILISDB, (LPARAM)MirabilisPageProc); - break; - case IDOK: - if (IsDlgButtonChecked(hdlg, IDC_RADIO_ALL)) { - DoImport = MirabilisImport; - nImportOption = IMPORT_ALL; - nCustomOptions = IOPT_MSGSENT|IOPT_MSGRECV|IOPT_URLSENT|IOPT_URLRECV; - PostMessage(GetParent(hdlg), WIZM_GOTOPAGE, IDD_PROGRESS, (LPARAM)ProgressPageProc); - break; - } - if (IsDlgButtonChecked(hdlg, IDC_RADIO_CONTACTS)) { - DoImport = MirabilisImport; - nImportOption = IMPORT_CONTACTS; - nCustomOptions = 0; - PostMessage(GetParent(hdlg), WIZM_GOTOPAGE, IDD_PROGRESS, (LPARAM)ProgressPageProc); - break; - } - break; - case IDCANCEL: - PostMessage(GetParent(hdlg), WM_CLOSE, 0, 0); - break; - } - break; - } - - return FALSE; -} - -static int GetHighestIndexEntry(void) -{ - struct TIdxIndexEntry *entry; - DWORD ofs; - - ofs=*(PDWORD)(pIdx+12); - for (;;) { - entry=(struct TIdxIndexEntry*)(pIdx+ofs); - if(entry->entryIdLow==(DWORD)-2) return ((struct TIdxDatEntry*)entry)->entryId; - if(entry->ofsHigher>=0xF0000000) ofs=entry->ofsInHere; - else ofs=entry->ofsHigher; - } -} - -static int GetIdDatOfs(DWORD id) -{ - struct TIdxIndexEntry *entry; - DWORD ofs = *(PDWORD)(pIdx+12); - for (;;) { - entry=(struct TIdxIndexEntry*)(pIdx+ofs); - if(entry->entryIdLow==(DWORD)-2) { - if(entry->entryIdHigh==id) return ((struct TIdxDatEntry*)entry)->datOfs; - return 0; - } - if(identryIdLow) ofs=entry->ofsLower; - else if(entry->ofsHigher<0xF0000000 && id>=entry->entryIdHigh) ofs=entry->ofsHigher; - else ofs=entry->ofsInHere; - } - return 0; -} - -static int GetDatEntryType(DWORD ofs) -{ - return *(int*)(pDat+ofs+4); -} - -DWORD GetDBVersion() -{ - dwDBVersion = *(PDWORD)(pIdx+16); - - switch (dwDBVersion) { - case DBV99A: - AddMessage( LPGEN("This looks like a ICQ 99a database.")); - break; - case DBV99B: - AddMessage( LPGEN("This looks like a ICQ 99b database.")); - break; - case DBV2000A: - AddMessage( LPGEN("This looks like a ICQ 2000a database.")); - break; - case DBV2000B: - AddMessage( LPGEN("This looks like a ICQ 2000b database.")); - break; - case DBV2001A: - AddMessage( LPGEN("This looks like a ICQ 2001, 2002 or 2003a database.")); - break; - default: - AddMessage( LPGEN("This database is an unknown version.")); - return 0; - } - - return dwDBVersion; -} - -int GetEntryVersion(WORD wSeparatorValue) -{ - int nVersion; - - if (wSeparatorValue < ENTRYV99A) - nVersion = 0; // Cannot handle ICQ98 contacts - else if ((wSeparatorValue >= ENTRYV99A) && (wSeparatorValue < ENTRYV99B)) - nVersion = ENTRYV99A; - else if ((wSeparatorValue >= ENTRYV99B) && (wSeparatorValue < ENTRYV2000A)) - nVersion = ENTRYV99B; - else if ((wSeparatorValue >= ENTRYV2000A) && (wSeparatorValue < ENTRYV2000B)) - nVersion = ENTRYV2000A; - else if ((wSeparatorValue >= ENTRYV2000B) && (wSeparatorValue < ENTRYV2001A)) - nVersion = ENTRYV2000B; - else if ((wSeparatorValue >= ENTRYV2001A) && (wSeparatorValue < ENTRYV2001B)) - nVersion = ENTRYV2001A; - else if ((wSeparatorValue >= ENTRYV2001B) && (wSeparatorValue < ENTRYV2002A)) - nVersion = ENTRYV2001B; - else if (wSeparatorValue >= ENTRYV2002A) - nVersion = ENTRYV2002A; - else - nVersion = ENTRYVUNKNOWN; // Just in case... Skip undocumented contact versions - - return nVersion; -} - -DWORD ReadSubList(DWORD dwOffset) -{ - DWORD dwSubType, dwProperties, n; - - #ifdef _LOGGING - AddMessage( LPGEN("Attempting to parse sub list at offset %u."), dwOffset); - #endif - - // Check number of properties in sub list - dwProperties = *(PDWORD)(pDat+dwOffset); - dwOffset+=4; - - // Check sub list type - dwSubType = *(PBYTE)(pDat+dwOffset); - dwOffset+=1; - - switch (dwSubType){ - case 0x6B: - for(n=0;n 1) - return 6 + (char*)(pDat + dwOffset); - - break; - } - else - // Skip to next group - dwOffset += *(PWORD)(pDat + dwOffset + 4) + 12; - } - break; - - case DBV2000A: - case DBV2000B: - case DBV2001A: - for (n = 0; n < dwGroups; n++) { - if (tmpOfs = ReadPropertyBlock(dwOffset, "GroupID", &nSearchResult)) { - if (nSearchResult) { - if (dwGroupID == *(PDWORD)(pDat + tmpOfs + 1)) { - strGroupName = 3 + (char*)(pDat + ReadPropertyBlock(dwOffset, "GroupName", &nSearchResult)); - if (nSearchResult) { - if ((DWORD)*(strGroupName - 2) > 1) - return strGroupName; - break; - } } } } - - // Skip to next group - if ( dwOffset != ReadPropertyBlock(dwOffset, NULL, NULL)) - break; - } - break; - } - - // The GroupID was not found, or it was found - // but the group did not have a name, or there - // was an error during parsing. - return 0; -} - -// ------------------------------------------------ -// Scans a group list and adds all found groups to -// the Miranda contact list -// ------------------------------------------------ -// dwOffset must point to the number of entries in -// the following group list. -// Returns the number of added groups, or -1 if an error -// occurred - -int ImportGroups() -{ - DWORD dwGroups, n, tmpOfs, dwOffset; - int nImported = 0; - int nSearchResult, nFormat; - WORD wSeparatorValue; - - if (!(dwOffset = FindMyDetails())) { - AddMessage( LPGEN("ERROR: Failed to find owner information.")); - return -1; - } - - wSeparatorValue = *(PWORD)(pDat + dwOffset + 0x1c); - nFormat = GetEntryVersion(wSeparatorValue); - - dwGroupListOfs = dwOffset = FindGroupList(dwOffset); - if (!dwOffset) { - AddMessage( LPGEN("ERROR: Failed to find contact list groups.")); - #ifdef _LOGGING - { // If this is a debug build, dump MyDetails block to disk - FILE *stream; - DWORD dwSize; - dwOffset = FindMyDetails(); - dwSize = *(PDWORD)(pDat + dwOffset); - stream = fopen("import_grouplist_dump.bin", "w"); - fwrite(pDat + dwOffset, 1, dwSize, stream); - fclose(stream); - } - #endif - return -1; - } - - // Check number of groups - dwGroups = *(PDWORD)(pDat + dwOffset); - if (dwGroups > 0) - AddMessage( LPGEN("Importing groups.")); - else { - AddMessage( LPGEN("This database does not contain any contact groups.")); - return 0; - } - - dwOffset += 4; - - // Import all groups with a name - switch (nFormat) { - case ENTRYV99A: - case ENTRYV99B: - for (n = 0; n < dwGroups; n++) { - if (*(PWORD)(pDat+dwOffset+4) > 1) { - if ( CreateGroup(DBVT_ASCIIZ, (char*)(pDat + dwOffset) + 6, NULL )) - nImported++; - dwOffset += *(PWORD)(pDat + dwOffset + 4) + 12; - } } - break; - - case ENTRYV2000A: - case ENTRYV2000B: - case ENTRYV2001A: - case ENTRYV2001B: - case ENTRYV2002A: - for (n = 0; n < dwGroups; n++) { - if (tmpOfs = ReadPropertyBlock(dwOffset, "GroupName", &nSearchResult)) { - if (nSearchResult) { - if (CreateGroup( DBVT_ASCIIZ, (char*)(pDat + tmpOfs + 3), NULL )) - nImported++; - } } - - dwOffset = ReadPropertyBlock(dwOffset, NULL, NULL); - if (!dwOffset) { - AddMessage( LPGEN("ERROR: An error occurred while importing groups.")); - AddMessage( LPGEN("All groups may not have not been imported.")); - #ifdef _LOGGING - { // If this is a debug build, dump MyDetails block to disk - FILE *stream; - DWORD dwSize; - dwOffset = FindMyDetails(); - dwSize = *(PDWORD)(pDat + dwOffset); - stream = fopen("import_grouplist_dump.bin", "w"); - fwrite(pDat + dwOffset, 1, dwSize, stream); - fclose(stream); - } - #endif - return -1; - } } - break; - - default: - return -1; - } - - return nImported; -} - -// Imports the contact at offset dwOffset -// Returns the HANDLE of the Miranda contact -// or INVALID_HANDLE_VALUE on failure - -HANDLE ImportContact(DWORD dwOffset) -{ - int nContactVersion, nSearchResult; - BYTE Status; - WORD wSeparatorValue; - DWORD dwGroup, dwUIN = 0, tmpOfs = 0; - char *strNickname = 0, *strGroupName = 0; - - if (*(int*)(pDat + dwOffset + 4) != DATENTRY_CONTACT) - return INVALID_HANDLE_VALUE; - - if (*(int*)(pDat + dwOffset + 0x1e) != 'USER') - return INVALID_HANDLE_VALUE; - - #ifdef _LOGGING - { // If this is a debug build, dump contact to disk - FILE *stream; - DWORD dwSize; - dwSize = *(PDWORD)(pDat + dwOffset); - stream = fopen("import_last_contact.bin", "w"); - fwrite(pDat + dwOffset, 1, dwSize, stream); - fclose(stream); - } - #endif - - Status = *(pDat + dwOffset + 0x22); - wSeparatorValue = *(PWORD)(pDat + dwOffset + 0x1c); - nContactVersion = GetEntryVersion(wSeparatorValue); - - dwGroup = *(PDWORD)(pDat + dwOffset + 0x26); - if (dwGroup >= 1000) - strGroupName = GetGroupName(dwGroup); - - if (Status == 5) - return INVALID_HANDLE_VALUE; // Skip deleted contacts - - if ((Status != 2) && (Status != 3)) { - AddMessage( LPGEN("Skipping inactive contact.")); - return INVALID_HANDLE_VALUE; - } - - if ((nContactVersion < ENTRYV99A) || (nContactVersion == 0)) { - AddMessage( LPGEN("Skipping contact with unsupported version.")); - return INVALID_HANDLE_VALUE; - } - - switch(nContactVersion){ - case ENTRYV99A: - if (!(dwOffset = ReadWavList(dwOffset + 0x54))) return INVALID_HANDLE_VALUE; - if (!(dwOffset = ReadPropertyBlock(dwOffset + 0x26, NULL, NULL))) return INVALID_HANDLE_VALUE; - // Check for custom nickname - if (*(PWORD)(pDat + dwOffset) > 1) strNickname = (char*)(dwOffset + pDat + 2); - // Find UIN - dwOffset += *(PWORD)(pDat + dwOffset) + 2; // Custom nick name - dwOffset += *(PWORD)(pDat + dwOffset) + 2; // Nick name - dwOffset += *(PWORD)(pDat + dwOffset) + 2; // First name - dwOffset += *(PWORD)(pDat + dwOffset) + 2; // Last name - dwOffset += *(PWORD)(pDat + dwOffset) + 2; // E-mail - dwUIN = *(PDWORD)(pDat + dwOffset); // UIN - break; - - case ENTRYV99B: - case ENTRYV2000A: - case ENTRYV2000B: - if (!(dwOffset = ReadWavList(dwOffset + 0x2C))) return INVALID_HANDLE_VALUE; - tmpOfs = ReadPropertyBlockList(dwOffset + 0x02, "UIN", &nSearchResult); - if (nSearchResult) dwUIN = *(PDWORD)(pDat + tmpOfs + 1); - tmpOfs = ReadPropertyBlockList(dwOffset + 0x02, "MyDefinedHandle", &nSearchResult); - if (nSearchResult) strNickname = (char*)(tmpOfs + pDat + 3); - break; - - case ENTRYV2001A: - case ENTRYV2001B: - tmpOfs = ReadPropertyBlockList(dwOffset + 0x2C, "MyDefinedHandle", &nSearchResult); - if (nSearchResult) strNickname = (char*)(tmpOfs + pDat + 3); - tmpOfs = ReadPropertyBlockList(dwOffset + 0x2C, "UIN", &nSearchResult); - if (nSearchResult) dwUIN = *(PDWORD)(pDat + tmpOfs + 1); - break; - - case ENTRYV2002A: - tmpOfs = ReadPropertyBlockList(dwOffset + 0x32, "MyDefinedHandle", &nSearchResult); - if (nSearchResult) strNickname = (char*)(tmpOfs + pDat + 3); - tmpOfs = ReadPropertyBlockList(dwOffset + 0x32, "UIN", &nSearchResult); - if (nSearchResult) dwUIN = *(PDWORD)(pDat + tmpOfs + 1); - break; - } - - if (!dwUIN) { - AddMessage( LPGEN("Skipping unrecognizable contact.")); - return INVALID_HANDLE_VALUE; - } - - if (dwUIN < 10000) { - AddMessage( LPGEN("Skipping non-ICQ contact %u."), dwUIN ); - return INVALID_HANDLE_VALUE; - } - - if (HContactFromNumericID( szICQModuleName[ iICQAccount ], "UIN", dwUIN) == INVALID_HANDLE_VALUE) { - DBVARIANT id, nick, group; - id.type = DBVT_DWORD; id.dVal = dwUIN; - if ( strNickname != NULL && strlen(strNickname) > 0 ) - nick.type = DBVT_ASCIIZ, nick.pszVal = strNickname; - else - nick.type = DBVT_DELETED; - group.type = DBVT_ASCIIZ, group.pszVal = strGroupName; - return AddContact(hdlgProgress, szICQModuleName[ iICQAccount ], "UIN", &id, &nick, &group); - } - else { - if ((strNickname != NULL) && (strlen(strNickname) > 0)) - AddMessage( LPGEN("Skipping duplicate ICQ contact %u, %s"), dwUIN, strNickname); - else - AddMessage( LPGEN("Skipping duplicate ICQ contact %u"), dwUIN); - } - - // Failure - return INVALID_HANDLE_VALUE; -} - -BOOL ImportMessage(DWORD dwOffset) -{ - struct TDatMessage *msg = (struct TDatMessage*)(pDat + dwOffset); - struct TDatEntryFooter *footer; - DBEVENTINFO dbei; - HANDLE hContact; - int nUCTOffset; - TIME_ZONE_INFORMATION TimeZoneInformation; - int nHistoryCount = 0; - - // Get timestamp offset. In ICQ, event timestamps are stored - // as UTC + (0-TZ offset). YES! That's the negation of the - // timezone offset, only God and Mirabilis knows why. - GetTimeZoneInformation(&TimeZoneInformation); - nUCTOffset = -TimeZoneInformation.Bias * 60; - - // Ignore messages in 'Deleted' folder - if (msg->filingStatus&FILING_DELETED) - return FALSE; - - // Skip messages from non-icq contacts - if (msg->uin < 10000) { - AddMessage( LPGEN("Ignoring msg from user %d at ofs %d."), msg->uin, dwOffset ); - return FALSE; - } - - // Ignore received messages? - if (( msg->filingStatus & FILING_RECEIVED ) && !( nCustomOptions & IOPT_MSGRECV )) - return FALSE; - - // Ignores sent messages? - if ( !(msg->filingStatus & FILING_RECEIVED) && !( nCustomOptions & IOPT_MSGSENT )) - return FALSE; - - // Check if contact exists in Miranda database - hContact = HistoryImportFindContact(hdlgProgress, szICQModuleName[ iICQAccount ], msg->uin, nCustomOptions&IOPT_ADDUNKNOWN); - if (hContact == INVALID_HANDLE_VALUE) - return FALSE; // Contact couldn't be found/added - - // Convert the event to a Miranda dbevent - footer = (struct TDatEntryFooter*)(pDat + dwOffset + msg->textLen + offsetof(struct TDatMessage, text)); - ZeroMemory(&dbei, sizeof(dbei)); - dbei.cbSize = sizeof(dbei); - dbei.eventType = EVENTTYPE_MESSAGE; - dbei.flags = footer->sent == 1 ? DBEF_SENT : DBEF_READ; - dbei.szModule = szICQModuleName[ iICQAccount ]; - // Convert timestamp - dbei.timestamp = footer->timestamp + nUCTOffset; - dbei.cbBlob = msg->textLen; - dbei.pBlob = (PBYTE)alloca(msg->textLen); - CopyMemory(dbei.pBlob, msg->text, dbei.cbBlob); - dbei.pBlob[dbei.cbBlob - 1] = 0; - - // Check for duplicate entries - if (IsDuplicateEvent(hContact, dbei)) { - nDupes++; - } - else { - if (CallService(MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&dbei)) - nMessagesCount++; - } - - return TRUE; -} - -BOOL ImportExtendedMessage(DWORD dwOffset) -{ - struct TDatMessage *msg = (struct TDatMessage*)(pDat + dwOffset); - struct TDatEntryFooter *footer; - DBEVENTINFO dbei; - HANDLE hContact; - int nUCTOffset; - TIME_ZONE_INFORMATION TimeZoneInformation; - int nHistoryCount = 0; - char* pszText = 0; - DWORD dwRichTextOffset = 0; - DWORD wRichTextLength = 0; - DWORD wLength = 0; - BOOL bFreeMe = FALSE; - - // Get timestamp offset. In ICQ, event timestamps are stored - // as UTC + (0-TZ offset). YES! That's the negation of the - // timezone offset, only God and Mirabilis knows why. - GetTimeZoneInformation(&TimeZoneInformation); - nUCTOffset = -TimeZoneInformation.Bias * 60; - - // Ignore messages in 'Deleted' folder - if (msg->filingStatus&FILING_DELETED) - return FALSE; - - // Skip messages from non-icq contacts - if (msg->uin < 10000) { - AddMessage( LPGEN("Ignoring msg from user %d at ofs %d."), msg->uin, dwOffset ); - return FALSE; - } - - // Ignore received messages? - if (( msg->filingStatus & FILING_RECEIVED) && !( nCustomOptions & IOPT_MSGRECV )) - return FALSE; - - // Ignore sent messages? - if ( !( msg->filingStatus & FILING_RECEIVED ) && !( nCustomOptions & IOPT_MSGSENT )) - return FALSE; - - // Check if contact exists in Miranda database - hContact = HistoryImportFindContact(hdlgProgress, szICQModuleName[ iICQAccount ], msg->uin, nCustomOptions&IOPT_ADDUNKNOWN); - if (hContact == INVALID_HANDLE_VALUE) - return FALSE; // Contact couldn't be found/added - - // Find a piece of usable text content - if (msg->textLen <= 1) { - // Skip past the RTF segment - wRichTextLength = *(PWORD)(pDat + dwOffset + 0x2A + msg->textLen + 0x21); - dwRichTextOffset = dwOffset + 0x2A + msg->textLen + 0x23; - - // Use the UTF-8 text segment - wLength = *(PWORD)(pDat + dwRichTextOffset + wRichTextLength); - if (wLength <= 1) { - AddMessage( LPGEN("Ignoring msg with no text from %d ofs %d."), msg->uin, dwOffset ); - return FALSE; - } - pszText = _strdup((char*)pDat + dwRichTextOffset + wRichTextLength + 2); - bFreeMe = TRUE; - mir_utf8decode(pszText, NULL); - wLength = (DWORD)strlen(pszText)+1; - } - else { - // Use the ANSI text segment - wLength = msg->textLen; - pszText = (char*)(pDat + dwOffset + 0x2A); - } - - // Convert the event to a Miranda dbevent - footer = (struct TDatEntryFooter*)(pDat + dwOffset + msg->textLen + offsetof(struct TDatMessage, text)); - ZeroMemory(&dbei, sizeof(dbei)); - dbei.cbSize = sizeof(dbei); - dbei.eventType = EVENTTYPE_MESSAGE; - dbei.flags = footer->sent == 1 ? DBEF_SENT : DBEF_READ; - dbei.szModule = szICQModuleName[ iICQAccount ]; - // Convert timestamp - dbei.timestamp = footer->timestamp + nUCTOffset; - dbei.cbBlob = wLength; - dbei.pBlob = (PBYTE)calloc(wLength,1); - CopyMemory(dbei.pBlob, pszText, dbei.cbBlob); - dbei.pBlob[dbei.cbBlob - 1] = 0; - - // Check for duplicate entries - if (IsDuplicateEvent(hContact, dbei)) { - nDupes++; - } - else { - if (CallService(MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&dbei)) - nMessagesCount++; - } - - free(dbei.pBlob); - if (bFreeMe) - free(pszText); - - return TRUE; -} - -BOOL ImportURLMessage(DWORD dwOffset) -{ - struct TDatMessage *msg = (struct TDatMessage*)(pDat + dwOffset); - struct TDatEntryFooter *footer; - DBEVENTINFO dbei; - HANDLE hContact; - int nUCTOffset; - TIME_ZONE_INFORMATION TimeZoneInformation; - int nHistoryCount = 0; - char *pSeparator; - - // Get timestamp offset. In ICQ, event timestamps are stored - // as UTC + (0-TZ offset). YES! That's the negation of the - // timezone offset, only God and Mirabilis knows why. - GetTimeZoneInformation(&TimeZoneInformation); - nUCTOffset = -TimeZoneInformation.Bias * 60; - - // Ignore URLs in 'Deleted' folder - if (msg->filingStatus&FILING_DELETED) - return FALSE; - - // Skip URLs from non-icq contacts - if (msg->uin < 10000) { - AddMessage( LPGEN("Ignoring msg from user %d at ofs %d."), msg->uin, dwOffset ); - return FALSE; - } - - // Ignore received URLs? - if (( msg->filingStatus & FILING_RECEIVED ) && !( nCustomOptions & IOPT_URLRECV )) - return FALSE; - - // Ignores sent URLs? - if ( !( msg->filingStatus & FILING_RECEIVED ) && !( nCustomOptions & IOPT_URLSENT )) - return FALSE; - - // Check if contact exists in Miranda database - hContact = HistoryImportFindContact(hdlgProgress, szICQModuleName[ iICQAccount ], msg->uin, nCustomOptions&IOPT_ADDUNKNOWN); - if (hContact == INVALID_HANDLE_VALUE) - return FALSE; // Contact couldn't be found/added - - // Convert the event to a Miranda dbevent - footer = (struct TDatEntryFooter*)(pDat + dwOffset + msg->textLen + offsetof(struct TDatMessage, text)); - ZeroMemory(&dbei, sizeof(dbei)); - dbei.cbSize = sizeof(dbei); - dbei.eventType = EVENTTYPE_URL; - dbei.flags = footer->sent == 1 ? DBEF_SENT : DBEF_READ; - dbei.szModule = szICQModuleName[ iICQAccount ]; - // Convert timestamp - dbei.timestamp = footer->timestamp + nUCTOffset; - dbei.cbBlob = msg->textLen; - dbei.pBlob = (PBYTE)alloca(msg->textLen); - CopyMemory(dbei.pBlob, msg->text, dbei.cbBlob); - dbei.pBlob[dbei.cbBlob - 1] = 0; - // Separate URL and description - pSeparator = strchr((char*)dbei.pBlob, 0xFE); - if (pSeparator != NULL) - *pSeparator = 0; - - // Check for duplicate entries - if (IsDuplicateEvent(hContact, dbei)) - nDupes++; - else if (CallService(MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&dbei)) - nMessagesCount++; - - return TRUE; -} - -BOOL ImportEvent(DWORD dwOffset) -{ - struct TDatMessage *msg = (struct TDatMessage*)(pDat + dwOffset); - - // Events have IDs > 2000 - if (msg->hdr.entryId < 2001) { - AddMessage( LPGEN("Skipping event with ID < 2001.")); - return FALSE; - } - - // Separate code paths based on the event signature - switch (msg->hdr.subType) { - - case SUBTYPE_MESSAGE: // All kinds of messages - switch (msg->type) { - case 1: // Normal message - if ((nCustomOptions&IOPT_MSGRECV) || (nCustomOptions&IOPT_MSGSENT)) { - return ImportMessage(dwOffset); - } - break; - - case 4: // URL - if ((nCustomOptions&IOPT_URLSENT) || (nCustomOptions&IOPT_URLRECV)) { - return ImportURLMessage(dwOffset); - } - break; - - case 6: // Request for authorization - #ifdef _LOGGING - AddMessage( LPGEN("Skipping 'Request for auth.' msg, ofs %d."), dwOffset ); - #endif - break; - - case 7: // Authorization request denied - #ifdef _LOGGING - AddMessage( LPGEN("Skipping 'Auth. denied' msg, ofs %d."), dwOffset ); - #endif - break; - - case 8: // Authorization request accepted - #ifdef _LOGGING - AddMessage( LPGEN("Skipping 'Auth. accepted' msg, ofs %d."), dwOffset ); - #endif - break; - - case 9: // System message - #ifdef _LOGGING - AddMessage( LPGEN("Skipping 'System message', ofs %d."), dwOffset ); - #endif - break; - - case 12: // You were added - #ifdef _LOGGING - AddMessage( LPGEN("Skipping 'You were added' msg, ofs %d."), dwOffset ); - #endif - break; - - case 13: // WWWPager ? - #ifdef _LOGGING - AddMessage( LPGEN("Skipping 'WWW Pager' msg, ofs %d."), dwOffset ); - #endif - break; - - case 14: // Email Express ? - #ifdef _LOGGING - AddMessage( LPGEN("Skipping 'Email Express' msg, ofs %d."), dwOffset ); - #endif - break; - - case 19: // Contact list - #ifdef _LOGGING - AddMessage( LPGEN("Skipping 'Contact' msg, ofs %d."), dwOffset ); - #endif - break; - - case 21: // Phonecall request? - #ifdef _LOGGING - AddMessage( LPGEN("Skipping 'Phonecall' msg (?), ofs %d."), dwOffset ); - #endif - break; - - case 26: // SMS request? - #ifdef _LOGGING - AddMessage( LPGEN("Skipping 'SMS' msg (?), ofs %d."), dwOffset ); - #endif - break; - - case 29: // Active list invitation ?? - #ifdef _LOGGING - AddMessage( LPGEN("Skipping 29 msg, ofs %d."), dwOffset ); - #endif - break; - - case 30: // Birthday reminder - #ifdef _LOGGING - AddMessage( LPGEN("Skipping 'Birthday' msg (?), ofs %d."), dwOffset ); - #endif - break; - - case 32: // Unknown (Tomer) - #ifdef _LOGGING - AddMessage( LPGEN("Skipping 32 msg, ofs %d."), dwOffset ); - #endif - break; - - default: - AddMessage( LPGEN("Skipping unknown 0xE0 subtype (%d), ofs %d."), msg->type, dwOffset ); - - #ifdef _LOGGING - { // If this is a debug build, dump entry to disk - FILE *stream; - DWORD dwSize = *(PDWORD)(pDat + dwOffset); - wsprintfA(str, "import_unknown_E0subtype_%u-%u.bin", msg->type, dwOffset); - stream = fopen(str, "w"); - fwrite(pDat + dwOffset, 1, dwSize, stream); - fclose(stream); - } - #endif - - return FALSE; - } - break; - - case SUBTYPE_CHATREQUEST: // 0xE1 - #ifdef _LOGGING - if (nImportOption != IMPORT_CONTACTS) - AddMessage( LPGEN("Skipping 'Chat request' msg, ofs %d."), dwOffset ); - #endif - break; - - case SUBTYPE_FILEREQUEST: // 0xE2 - #ifdef _LOGGING - if (nImportOption != IMPORT_CONTACTS) - AddMessage( LPGEN("Skipping file message offset %d."), dwOffset ); - #endif - break; - - case 0xE3: // External (IPhone, Battlecom) Maybe general voice calls? - #ifdef _LOGGING - if (nImportOption != IMPORT_CONTACTS) - AddMessage( LPGEN("Skipping message type 0xE3 at offset %d."), dwOffset ); - #endif - break; - - case 0xE4: // My details - break; - case 0xE5: // Contact - break; - case 0xE6: // Reminder - break; - case 0xE7: // Addressbook - break; - case 0xEC: // Voice message - break; - case 0xED: // Unknown, something to do with chatting and .CHT files - // if (importHistory) { - // wsprintf(str, "Skipping message type 0xED at offset %d.", dwOffset); - // AddMessage( LPGEN(str); - // } - break; - case 0xEE: // Note - break; - case 0xEF: // Event folder - break; - // case 0xF0: // Unknown - // if (importHistory) { - // wsprintf(str, "Skipping message type 0xF0 at offset %d.", dwOffset); - // AddMessage( LPGEN(str); - // } - // break; - case 0xF1: // Server list - break; - // case 0xF6: // Unknown - // if (importHistory) { - // wsprintf(str, "Skipping message type 0xF6 at offset %d.", dwOffset); - // AddMessage( LPGEN(str); - // } - // break; - case 0x50: // Extended message, ICQ 2000a+? - if (nImportOption != IMPORT_CONTACTS) { - return ImportExtendedMessage(dwOffset); - } - break; - - case 0xA0: // URL message type 2 - if (nImportOption != IMPORT_CONTACTS) { - if ((msg->filingStatus&FILING_RECEIVED) || (nCustomOptions&IOPT_URLRECV)) { - return ImportURLMessage(dwOffset); - } - } - break; - - default: - if (nImportOption != IMPORT_CONTACTS) { - AddMessage( LPGEN("Skipping unknown event type %d at offset %d."), msg->hdr.subType, dwOffset ); - -#ifdef _LOGGING - { // If this is a debug build, dump entry to disk - FILE *stream; - DWORD dwSize; - dwSize = *(PDWORD)(pDat + dwOffset); - wsprintfA(str, "import_unknown_eventtype_%u-%u.bin", msg->hdr.subType, dwOffset); - stream = fopen(str, "w"); - fwrite(pDat + dwOffset, 1, dwSize, stream); - fclose(stream); - } -#endif - - } - break; - } - - return FALSE; -} - - -static void MirabilisImport(HWND hdlgProgressWnd) -{ - HANDLE hIdx, hDat, hIdxMapping, hDatMapping; - DWORD i, ofs, highestIndexEntry; - TCHAR datFilename[MAX_PATH]; - MSG msg; - DWORD dwTimer; - - - int status = 0; - hdlgProgress = hdlgProgressWnd; - nDupes = nContactsCount = nMessagesCount = 0; - - SetProgress(0); - lstrcpy(datFilename, importFile); - { - TCHAR* str2; - str2 = _tcsrchr(datFilename,'.'); - if ( str2 != NULL ) - lstrcpy(str2, _T(".dat")); - } - - hIdx = CreateFile(importFile, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); - if (hIdx == INVALID_HANDLE_VALUE) { - AddMessage( LPGEN("Failed to open index file")); - AddMessage( LPGEN("Import aborted")); - SetProgress(100); - return; - } - - hDat = CreateFile(datFilename, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); - if (hDat == INVALID_HANDLE_VALUE) { - AddMessage( LPGEN("Failed to open database file")); - AddMessage( LPGEN("Import aborted")); - SetProgress(100); - return; - } - - // Creating file mappings - hIdxMapping = CreateFileMapping(hIdx, NULL, PAGE_READONLY, 0, 0, NULL); - hDatMapping = CreateFileMapping(hDat, NULL, PAGE_READONLY, 0, 0, NULL); - - // Mapping views of files - pIdx = (PBYTE)MapViewOfFile(hIdxMapping, FILE_MAP_READ, 0, 0, 0); - pDat = (PBYTE)MapViewOfFile(hDatMapping, FILE_MAP_READ, 0, 0, 0); - - // Is this a supported format? - if (GetDBVersion()) { - AddMessage( "" ); - - highestIndexEntry = GetHighestIndexEntry(); - - // Import groups - nGroupsCount = ImportGroups(); - if (nGroupsCount < 0) { - AddMessage( LPGEN("Group import was not completed.")); - nGroupsCount = 0; - } - AddMessage( "" ); - - // Start benchmark timer - dwTimer = time(NULL); - - if ( !IsProtocolLoaded( szICQModuleName[iICQAccount] )) { - AddMessage( LPGEN("ICQ account is not installed.")); - AddMessage( LPGEN("No ICQ contacts or history will be imported.")); - AddMessage( "" ); - } - else { - // Configure database for fast writing - CallService(MS_DB_SETSAFETYMODE, FALSE, 0); - - // Import contacts - AddMessage( LPGEN("Importing contacts")); - for (i = 2001; i <= highestIndexEntry; i++) { //event ids start at 2001 - if (!(i%10)) { - if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - if (!(i%100)) - SetProgress(100 * (i - 2001) / (highestIndexEntry - 2001)); - - ofs = GetIdDatOfs(i); - if (ofs != 0) { - if (ImportContact(ofs) != INVALID_HANDLE_VALUE) - nContactsCount++; - } - } - AddMessage( "" ); - - // Import history - if (nImportOption != IMPORT_CONTACTS) { - AddMessage( LPGEN("Importing history (this may take a while)")); - for (i = 2001; i <= highestIndexEntry; i++) { //event ids start at 2001 - if (!(i%10)) { - if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - - if (!(i%100)) - SetProgress(100 * (i - 2001) / (highestIndexEntry - 2001)); - - ofs = GetIdDatOfs(i); - if (ofs != 0) ImportEvent(ofs); - } - AddMessage( "" ); - } - - // Restore database writing mode - CallService(MS_DB_SETSAFETYMODE, TRUE, 0); - } - - dwTimer = time(NULL) - dwTimer; - - AddMessage( LPGEN("Import completed in %d seconds."), dwTimer ); - SetProgress(100); - AddMessage( LPGEN("Added %d contacts and %d groups."), nContactsCount, nGroupsCount ); - if ( nImportOption != IMPORT_CONTACTS ) - AddMessage( LPGEN("Added %d events and skipped %d duplicates."), nMessagesCount, nDupes ); - } - - UnmapViewOfFile(pDat); - UnmapViewOfFile(pIdx); - CloseHandle(hDatMapping); - CloseHandle(hIdxMapping); - CloseHandle(hDat); - CloseHandle(hIdx); -} diff --git a/plugins/Import/mirabilis.h b/plugins/Import/mirabilis.h deleted file mode 100644 index 47f10141e1..0000000000 --- a/plugins/Import/mirabilis.h +++ /dev/null @@ -1,200 +0,0 @@ -/* - -Import plugin for Miranda IM - -Copyright (C) 2001,2002,2003,2004 Martin Öberg, Richard Hughes, Roland Rabien & Tristan Van de Vreede - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - - - -#ifndef MIRABILIS_H -#define MIRABILIS_H - -#include -#include -#include - -// ====================== -// == GLOBAL FUNCTIONS == -// ====================== - -HANDLE HistoryImportFindContact(HWND hdlgProgress, char* szModuleName, DWORD uin,int addUnknown); - -// ===================== -// == LOCAL FUNCTIONS == -// ===================== - - -// Main function -static void MirabilisImport(HWND hdlgProgressWnd); - -// GUI callbacks -INT_PTR CALLBACK ImportTypePageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam); -INT_PTR CALLBACK FinishedPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam); -INT_PTR CALLBACK ProgressPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam); -INT_PTR CALLBACK MirabilisPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam); -INT_PTR CALLBACK MirabilisOptionsPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam); - -// Helper functions for entries -static int GetHighestIndexEntry(void); -static int GetIdDatOfs(DWORD id); -static int GetDatEntryType(DWORD ofs); -DWORD FindMyDetails(void); - -// Parsing functions -DWORD GetDBVersion(); -int GetEntryVersion(WORD wSeparatorValue); -DWORD ReadPropertyBlock(DWORD dwOffset, char* SearchWord, int* nSearchResult); -DWORD ReadSubList(DWORD dwOffset); -DWORD ReadPropertyBlock(DWORD dwOffset, char* SearchWord, int* nSearchResult); -DWORD ReadPropertyBlockList(DWORD dwOffset, char* SearchWord, int* nSearchResult); -DWORD ReadWavList(DWORD ofs); -DWORD FindGroupList(DWORD dwOffset); -char* GetGroupName(DWORD dwGroupID); -int ImportGroups(); -static HANDLE ImportContact(DWORD dwOffset); - -BOOL ImportEvent(DWORD dwOffset); -BOOL ImportMessage(DWORD dwOffset); -BOOL ImportExtendedMessage(DWORD dwOffset); -BOOL ImportURLMessage(DWORD dwOffset); - - - - -// ====================== -// == GLOBAL VARIABLES == -// ====================== - -extern TCHAR importFile[MAX_PATH]; -extern void (*DoImport)(HWND); -extern int nImportOption; -extern int nCustomOptions; - - -extern int cICQAccounts; -extern char ** szICQModuleName; -extern TCHAR ** tszICQAccountName; -extern int iICQAccount; - -// ===================== -// == LOCAL VARIABLES == -// ===================== - -static DWORD dwDBVersion; -static DWORD dwGroupListOfs; -static PBYTE pIdx,pDat; - -// ============= -// == DEFINES == -// ============= - -// Contact versions -// These numbers are not 100% accurate -#define ENTRYVUNKNOWN -1 -#define ENTRYV99A 200 -#define ENTRYV99B 300 -#define ENTRYV2000A 400 -#define ENTRYV2000B 455 -#define ENTRYV2001A 500 -#define ENTRYV2001B 515 -#define ENTRYV2002A 533 - -// Database versions -#define DBV99A 10 -#define DBV99B 14 -#define DBV2000A 17 -#define DBV2000B 18 -#define DBV2001A 19 // This is used by ICQ 2001a, 2001b & 2002a - -#define DATENTRY_UNFILED (DWORD)(-1) -#define DATENTRY_MESSAGE 0 -#define DATENTRY_CONTACT 1 -#define DATENTRY_IGNORED 2 -#define DATENTRY_SYSTEM 9 - -#define MAX_NON_ICQ_CONTACTS 100 - -#define SUBTYPE_NEWMESSAGE 0x50 -#define SUBTYPE_NEWURL 0xA0 - -#define SUBTYPE_MESSAGE 0xE0 //Message / URL Message / Request For Authorization / "Authorization" / System Request / "You Were Added" / Contacts List -#define SUBTYPE_CHATREQUEST 0xE1 -#define SUBTYPE_FILEREQUEST 0xE2 -#define SUBTYPE_MYDETAILS 0xE4 -#define SUBTYPE_CONTACTINFO 0xE5 -#define SUBTYPE_REMINDER 0xE6 -#define SUBTYPE_ADDRESSBOOK 0xE7 -#define SUBTYPE_VOICEMSG 0xEC //??? -#define SUBTYPE_NOTE 0xEE -#define SUBTYPE_EVENTFOLDER 0xEF -#define SUBTYPE_SERVERLIST 0xF1 //and objectionable word list -#define SUBTYPE_X1 0xF6 //(new to ICQ 99b???) - -#define FILING_RECEIVED 0x01 -#define FILING_DELETED 0x02 -#define FILING_MESSAGE 0x04 -#define MSGTYPE_MESSAGE 1 -#define MSGTYPE_URL 4 -#define MSGTYPE_CLIST 19 -#include - -struct TIdxDatEntry { - DWORD status; //-2=valid, else is an index entry - DWORD entryId; - DWORD ofsNext,ofsPrev; - DWORD datOfs; -}; - -struct TIdxIndexEntry { - DWORD entryIdLow; - DWORD entryIdHigh; - DWORD ofsLower; - DWORD ofsInHere; - DWORD ofsHigher; -}; - -struct TDatEntryHeader { - DWORD entrySize; //in bytes - DWORD entryType; //DATENTRY_* constant - DWORD entryId; //same as in index - BYTE subType; //SUBTYPE_* constant - BYTE signature[15]; -}; - -struct TDatEntryFooter { - DWORD unknown; - DWORD sent; //1 if sent, 0 if received - WORD separator; - DWORD timestamp; //unix time -}; - -struct TDatMessage { - struct TDatEntryHeader hdr; //hdr.entryType==DATENTRY_MESSAGE && hdr.subType==MSGTYPE_MESSAGE - WORD separator; - DWORD filingStatus; //FILING_* flags - WORD type; //MSGTYPE_* constant - DWORD uin; - WORD textLen; - char text[1]; //0xFE separates description & URL in URLs - //a struct TDatEntryFooter comes here -}; - -#include - -#endif diff --git a/plugins/Import/miranda.cpp b/plugins/Import/miranda.cpp deleted file mode 100644 index 4f616fb714..0000000000 --- a/plugins/Import/miranda.cpp +++ /dev/null @@ -1,1445 +0,0 @@ -/* - -Import plugin for Miranda IM - -Copyright (C) 2001-2005 Martin Öberg, Richard Hughes, Roland Rabien & Tristan Van de Vreede - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -// ============== -// == INCLUDES == -// ============== - -#include "import.h" - -#include "resource.h" -#include "mirandadb0700.h" - -// ====================== -// == GLOBAL FUNCTIONS == -// ====================== - -HANDLE HContactFromNumericID(char* pszProtoName, char* pszSetting, DWORD dwID); -HANDLE HContactFromID(char* pszProtoName, char* pszSetting, char* pszID); - -HANDLE AddContact(HWND hdlgProgress, char* pszProtoName, char* pszUniqueSetting, DBVARIANT* id, DBVARIANT* nick, DBVARIANT* group); - -BOOL IsProtocolLoaded(char* pszProtocolName); -BOOL IsDuplicateEvent(HANDLE hContact, DBEVENTINFO dbei); - -INT_PTR CALLBACK ImportTypePageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam); -INT_PTR CALLBACK FinishedPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam); -INT_PTR CALLBACK ProgressPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam); -INT_PTR CALLBACK MirandaOptionsPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam); -INT_PTR CALLBACK MirandaAdvOptionsPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam); - -// ===================== -// == LOCAL FUNCTIONS == -// ===================== - -void MirandaImport(HWND hdlgProgress); -int CheckFileFormat(HANDLE hFile); -static HANDLE ImportContact(HANDLE hDbFile, struct DBContact Contact); -static void ImportHistory(HANDLE hDbFile, struct DBContact Contact, PROTOCOLDESCRIPTOR **protocol, int protoCount); -static int ImportGroups(HANDLE hDbFile, struct DBHeader *pdbHeader); - -// Comment: The Find* functions only return a file offset. -// The Get* functions actually reads the requested -// data from the file and gives you a pointer to a structure -// containing the data. - -DWORD FindFirstContact(struct DBHeader* pDbHeader); -DWORD FindNextContact(struct DBContact* pDbContact); -DWORD FindNextEvent(HANDLE hDbFile, DWORD dwOffset); -DWORD FindOwnerContact(struct DBHeader* pDbHeader); - -int GetContactCount(struct DBHeader* pDbHeader); -BOOL GetContact(HANDLE hDbFile, DWORD dwOffset, struct DBContact* pDbContact); -BOOL GetSetting(HANDLE hDbFile, struct DBContact* pDbContact, char* pszModuleName, char* pszSettingName, DBVARIANT* pValue); -char* GetNextSetting(char* pDbSetting); -BOOL GetSettings(HANDLE hDbFile, DWORD dwOffset, struct DBContactSettings** pDbSettings); -struct DBContactSettings* GetSettingsGroupByModuleName(HANDLE hdbFile, struct DBContact* pDbContact, char* pszName); -DWORD GetBlobSize(struct DBContactSettings* pDbSettings); -int GetSettingByName(struct DBContactSettings* pDbSettings, char* pszSettingName, DBVARIANT* pValue); -int GetSettingValue(char* pBlob,DBVARIANT* pValue); - -BOOL GetEvent(HANDLE hDbFile, DWORD dwOffset, DBEVENTINFO* pDBEI); -char* GetName(HANDLE hDbFile, DWORD dwOffset); - - -// ====================== -// == GLOBAL VARIABLES == -// ====================== - -extern void (*DoImport)(HWND); -extern int nImportOption; -extern int nCustomOptions; - - -// ===================== -// == LOCAL VARIABLES == -// ===================== - -TCHAR importFile[MAX_PATH]; -HWND hdlgProgress; -DWORD dwFileSize; - -DWORD nDupes; -DWORD nContactsCount; -DWORD nMessagesCount; -DWORD nGroupsCount; -DWORD nSkippedEvents; -DWORD nSkippedContacts; - -time_t dwSinceDate = 0; - -// ============= -// == DEFINES == -// ============= - -#define EVENTTYPE_MESSAGE 0 -#define EVENTTYPE_URL 1 -#define EVENTTYPE_FILE 1002 - - -// Supported database versions -#define DB_INVALID 0x00000000 // Unknown or corrupted DAT -#define DB_000700 0x00000700 // Miranda 0.1.0.0 - 0.1.2.2+ - -// DAT file signature -struct DBSignature { - char name[15]; - BYTE eof; -}; - -static struct DBSignature dbSignature={"Miranda ICQ DB",0x1A}; - -// ==================== -// ==================== -// == IMPLEMENTATION == -// ==================== -// ==================== - -static void SearchForLists(HWND hdlg, const TCHAR *mirandaPath, const TCHAR *mirandaProf, const TCHAR *pattern, const TCHAR *type) -{ - HANDLE hFind; - WIN32_FIND_DATA fd; - TCHAR szSearchPath[MAX_PATH]; - TCHAR szRootName[MAX_PATH]; - TCHAR* str2; - int i; - - mir_sntprintf(szSearchPath, SIZEOF(szSearchPath), _T("%s\\%s"), mirandaPath, pattern); - hFind = FindFirstFile(szSearchPath, &fd); - if (hFind != INVALID_HANDLE_VALUE) - { - do - { - _tcscpy(szRootName, fd.cFileName); - str2 = _tcsrchr(szRootName, '.'); - if (str2 != NULL) *str2 = 0; - if (mirandaProf == NULL || _tcsicmp(mirandaProf, szRootName)) - { - _tcscat(szRootName, type); - i = SendDlgItemMessage(hdlg, IDC_LIST, LB_ADDSTRING, 0, (LPARAM)szRootName); - str2 = (TCHAR*)mir_alloc((_tcslen(mirandaPath) + 2 + _tcslen(fd.cFileName)) * sizeof(TCHAR)); - wsprintf(str2, _T("%s\\%s"), mirandaPath, fd.cFileName); - SendDlgItemMessage(hdlg, IDC_LIST, LB_SETITEMDATA, i, (LPARAM)str2); - } - } - while( FindNextFile( hFind, &fd )); - - FindClose( hFind ); - } -} - -INT_PTR CALLBACK MirandaPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam) -{ - switch(message) { - case WM_INITDIALOG: - TranslateDialogDefault(hdlg); - { - TCHAR *pfd, *pfd1, *pfd2, *pfn; - - REPLACEVARSDATA dat = {0}; - dat.cbSize = sizeof(dat); - dat.dwFlags = RVF_TCHAR; - - pfd = (TCHAR*)CallService(MS_UTILS_REPLACEVARS, (WPARAM)_T("%miranda_path%\\Profiles"), (LPARAM)&dat); - pfd1 = (TCHAR*)CallService(MS_UTILS_REPLACEVARS, (WPARAM)_T("%miranda_path%"), (LPARAM)&dat); - pfd2 = (TCHAR*)CallService(MS_UTILS_REPLACEVARS, (WPARAM)_T("%miranda_profile%"), (LPARAM)&dat); - pfn = (TCHAR*)CallService(MS_UTILS_REPLACEVARS, (WPARAM)_T("%miranda_profilename%"), (LPARAM)&dat); - - SearchForLists(hdlg, pfd2, pfn, _T("*.dat"), _T(" (Miranda IM v0.x)")); - SearchForLists(hdlg, pfd1, NULL, _T("*.dat"), _T(" (Miranda IM v0.x)")); - if (lstrcmpi(pfd, pfd2)) - SearchForLists(hdlg, pfd, NULL, _T("*.dat"), _T(" (Miranda IM v0.x)")); - - mir_free(pfn); - mir_free(pfd2); - mir_free(pfd1); - mir_free(pfd); - return TRUE; - } - - case WM_COMMAND: - switch(LOWORD(wParam)) { - case IDC_BACK: - PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_IMPORTTYPE,(LPARAM)ImportTypePageProc); - break; - - case IDOK: - { - TCHAR filename[MAX_PATH]; - - GetDlgItemText(hdlg, IDC_FILENAME, filename, SIZEOF(filename)); - if (_taccess(filename, 4)) { - MessageBox(hdlg, TranslateT("The given file does not exist. Please check that you have entered the name correctly."), TranslateT("Miranda Import"), MB_OK); - break; - } - lstrcpy(importFile, filename); - PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_OPTIONS,(LPARAM)MirandaOptionsPageProc); - } - break; - - case IDCANCEL: - PostMessage(GetParent(hdlg),WM_CLOSE,0,0); - break; - - case IDC_LIST: - if(HIWORD(wParam)==LBN_SELCHANGE) { - int sel = SendDlgItemMessage(hdlg, IDC_LIST, LB_GETCURSEL, 0, 0); - if (sel == LB_ERR) break; - SetDlgItemText(hdlg, IDC_FILENAME, (TCHAR*)SendDlgItemMessage(hdlg, IDC_LIST, LB_GETITEMDATA, sel, 0)); - } - break; - - case IDC_OTHER: - { - OPENFILENAME ofn; - TCHAR str[MAX_PATH], text[256]; - TCHAR *pfd; - int index; - - pfd = Utils_ReplaceVarsT(_T("%miranda_profile%")); - - // TranslateTS doesnt translate \0 separated strings - index = mir_sntprintf(text, 64, _T("%s (*.dat)"), TranslateT("Miranda IM database")) + 1; - _tcscpy(text + index, _T("*.dat")); index += 6; - index += mir_sntprintf(text + index, 64, _T("%s (*.*)"), TranslateT("All Files")) + 1; - _tcscpy(text + index, _T("*.*")); index += 4; - text[index] = 0; - - GetDlgItemText(hdlg, IDC_FILENAME, str, SIZEOF(str)); - ZeroMemory(&ofn, sizeof(ofn)); - ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; - ofn.hwndOwner = hdlg; - ofn.lpstrFilter = text; - ofn.lpstrDefExt = _T("dat"); - ofn.lpstrFile = str; - ofn.Flags = OFN_FILEMUSTEXIST | OFN_EXPLORER | OFN_NOCHANGEDIR | OFN_DONTADDTORECENT; - ofn.nMaxFile = SIZEOF(str); - ofn.lpstrInitialDir = pfd; - if (GetOpenFileName(&ofn)) - SetDlgItemText(hdlg,IDC_FILENAME,str); - - mir_free(pfd); - break; - } - } - break; - case WM_DESTROY: - { - int i; - - for(i=SendDlgItemMessage(hdlg,IDC_LIST,LB_GETCOUNT,0,0)-1;i>=0;i--) - mir_free((char*)SendDlgItemMessage(hdlg,IDC_LIST,LB_GETITEMDATA,i,0)); - break; - } } - - return FALSE; -} - - -INT_PTR CALLBACK MirandaOptionsPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam) -{ - switch(message) { - case WM_INITDIALOG: - TranslateDialogDefault(hdlg); - EnableWindow(GetDlgItem(hdlg,IDC_RADIO_ALL), TRUE); - EnableWindow(GetDlgItem(hdlg,IDC_STATIC_ALL), TRUE); - EnableWindow(GetDlgItem(hdlg,IDC_RADIO_CONTACTS), TRUE); - EnableWindow(GetDlgItem(hdlg,IDC_STATIC_CONTACTS), TRUE); - EnableWindow(GetDlgItem(hdlg,IDC_RADIO_CUSTOM), TRUE); - EnableWindow(GetDlgItem(hdlg,IDC_STATIC_CUSTOM), TRUE); - CheckDlgButton(hdlg,IDC_RADIO_ALL,BST_UNCHECKED); - return TRUE; - - case WM_COMMAND: - switch(LOWORD(wParam)) { - case IDC_BACK: - PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_MIRANDADB,(LPARAM)MirandaPageProc); - break; - - case IDOK: - if(IsDlgButtonChecked(hdlg,IDC_RADIO_ALL)) { - nImportOption = IMPORT_ALL; - nCustomOptions = 0;//IOPT_MSGSENT|IOPT_MSGRECV|IOPT_URLSENT|IOPT_URLRECV; - DoImport = MirandaImport; - PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_PROGRESS,(LPARAM)ProgressPageProc); - break; - } - - if(IsDlgButtonChecked(hdlg,IDC_RADIO_CONTACTS)) { - nImportOption = IMPORT_CONTACTS; - nCustomOptions = 0; - DoImport = MirandaImport; - PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_PROGRESS,(LPARAM)ProgressPageProc); - break; - } - - if(IsDlgButtonChecked(hdlg,IDC_RADIO_CUSTOM)) { - PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_ADVOPTIONS,(LPARAM)MirandaAdvOptionsPageProc); - break; - } - break; - - case IDCANCEL: - PostMessage(GetParent(hdlg), WM_CLOSE, 0, 0); - break; - } - break; - } - return FALSE; -} - -static const UINT InControls[]={IDC_IN_MSG,IDC_IN_URL,IDC_IN_FT,IDC_IN_OTHER}; -static const UINT OutControls[]={IDC_OUT_MSG,IDC_OUT_URL,IDC_OUT_FT,IDC_OUT_OTHER}; -static const UINT SysControls[]={IDC_CONTACTS, IDC_SYSTEM}; - -INT_PTR CALLBACK MirandaAdvOptionsPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam) -{ - switch(message) { - case WM_INITDIALOG: - TranslateDialogDefault(hdlg); - { - struct tm *TM = NULL; - struct _SYSTEMTIME ST = {0}; - - dwSinceDate = DBGetContactSettingDword(NULL,IMPORT_MODULE,"ImportSinceTS",time(NULL)); - - TM = localtime(&dwSinceDate); - - ST.wYear = TM->tm_year + 1900; - ST.wMonth = TM->tm_mon + 1; - ST.wDay = TM->tm_mday; - - DateTime_SetSystemtime(GetDlgItem(hdlg,IDC_DATETIMEPICKER),GDT_VALID,&ST); - } - return TRUE; - - case WM_COMMAND: - switch(LOWORD(wParam)) { - case IDC_BACK: - PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_OPTIONS,(LPARAM)MirandaOptionsPageProc); - break; - - case IDOK: - DoImport = MirandaImport; - nImportOption = IMPORT_CUSTOM; - nCustomOptions = 0; - - if (IsDlgButtonChecked(hdlg,IDC_CONTACTS)) - nCustomOptions |= IOPT_CONTACTS | IOPT_GROUPS; - if (IsDlgButtonChecked(hdlg,IDC_SYSTEM)) - nCustomOptions |= IOPT_SYSTEM; - - // incoming - if (IsDlgButtonChecked(hdlg,IDC_IN_MSG)) - nCustomOptions |= IOPT_MSGRECV; - if (IsDlgButtonChecked(hdlg,IDC_IN_URL)) - nCustomOptions |= IOPT_URLRECV; - if (IsDlgButtonChecked(hdlg,IDC_IN_FT)) - nCustomOptions |= IOPT_FILERECV; - if (IsDlgButtonChecked(hdlg,IDC_IN_OTHER)) - nCustomOptions |= IOPT_OTHERRECV; - - // outgoing - if (IsDlgButtonChecked(hdlg,IDC_OUT_MSG)) - nCustomOptions |= IOPT_MSGSENT; - if (IsDlgButtonChecked(hdlg,IDC_OUT_URL)) - nCustomOptions |= IOPT_URLSENT; - if (IsDlgButtonChecked(hdlg,IDC_OUT_FT)) - nCustomOptions |= IOPT_FILESENT; - if (IsDlgButtonChecked(hdlg,IDC_OUT_OTHER)) - nCustomOptions |= IOPT_OTHERSENT; - - // since date - dwSinceDate = 0; - - if ( IsDlgButtonChecked( hdlg, IDC_SINCE )) { - struct _SYSTEMTIME ST = {0}; - - if (DateTime_GetSystemtime(GetDlgItem(hdlg,IDC_DATETIMEPICKER), &ST) == GDT_VALID) { - struct tm TM = {0}; - - TM.tm_mday = ST.wDay; - TM.tm_mon = ST.wMonth - 1; - TM.tm_year = ST.wYear - 1900; - - dwSinceDate = mktime(&TM); - - DBWriteContactSettingDword(NULL,IMPORT_MODULE,"ImportSinceTS",dwSinceDate); - } } - - if (nCustomOptions) - PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_PROGRESS,(LPARAM)ProgressPageProc); - break; - - case IDCANCEL: - PostMessage(GetParent(hdlg), WM_CLOSE, 0, 0); - break; - - case IDC_SINCE: - EnableWindow(GetDlgItem(hdlg, IDC_DATETIMEPICKER), IsDlgButtonChecked(hdlg, IDC_SINCE)); - break; - - if (HIWORD(wParam) != STN_CLICKED) - break; - - case IDC_ALL: - case IDC_INCOMING: - case IDC_OUTGOING: - { - int i; - - if (LOWORD(wParam) == IDC_ALL) - for (i = 0; i < sizeof(SysControls)/sizeof(SysControls[0]); i++) - CheckDlgButton(hdlg,SysControls[i], !IsDlgButtonChecked(hdlg,SysControls[i])); - - if (LOWORD(wParam) != IDC_OUTGOING) - for (i = 0; i < sizeof(InControls)/sizeof(InControls[0]); i++) - CheckDlgButton(hdlg,InControls[i], !IsDlgButtonChecked(hdlg,InControls[i])); - - if (LOWORD(wParam) != IDC_INCOMING) - for (i = 0; i < sizeof(OutControls)/sizeof(OutControls[0]); i++) - CheckDlgButton(hdlg,OutControls[i], !IsDlgButtonChecked(hdlg,OutControls[i])); - } - break; - - case IDC_MSG: - CheckDlgButton(hdlg,IDC_IN_MSG, !IsDlgButtonChecked(hdlg,IDC_IN_MSG)); - CheckDlgButton(hdlg,IDC_OUT_MSG, !IsDlgButtonChecked(hdlg,IDC_OUT_MSG)); - break; - - case IDC_URL: - CheckDlgButton(hdlg,IDC_IN_URL, !IsDlgButtonChecked(hdlg,IDC_IN_URL)); - CheckDlgButton(hdlg,IDC_OUT_URL, !IsDlgButtonChecked(hdlg,IDC_OUT_URL)); - break; - - case IDC_FT: - CheckDlgButton(hdlg,IDC_IN_FT, !IsDlgButtonChecked(hdlg,IDC_IN_FT)); - CheckDlgButton(hdlg,IDC_OUT_FT, !IsDlgButtonChecked(hdlg,IDC_OUT_FT)); - break; - - case IDC_OTHER: - CheckDlgButton(hdlg,IDC_IN_OTHER, !IsDlgButtonChecked(hdlg,IDC_IN_OTHER)); - CheckDlgButton(hdlg,IDC_OUT_OTHER, !IsDlgButtonChecked(hdlg,IDC_OUT_OTHER)); - break; - } - break; - } - return FALSE; -} - -#ifndef INVALID_SET_FILE_POINTER -#define INVALID_SET_FILE_POINTER ((DWORD)-1) -#endif - -// Read header from file, returns null on failure -struct DBHeader* GetHeader(HANDLE hDbFile) -{ - struct DBHeader* pdbHeader; - DWORD dwBytesRead; - - if (( pdbHeader = (DBHeader*)calloc(1, sizeof(struct DBHeader))) == NULL ) - return NULL; - - // Goto start of file - if (SetFilePointer(hDbFile, 0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) - return FALSE; - - // Read header - if ( !ReadFile(hDbFile, pdbHeader, sizeof(struct DBHeader), &dwBytesRead, NULL ) || - dwBytesRead != sizeof(struct DBHeader)) - return NULL; - - // Return pointer to header - return pdbHeader; -} - -int CheckFileFormat(HANDLE hDbFile) -{ - struct DBHeader* pdbHeader; - - // Read header - if (( pdbHeader = GetHeader(hDbFile)) == NULL ) - return DB_INVALID; - - // Check header signature - if (memcmp(pdbHeader->signature, &dbSignature, sizeof(pdbHeader->signature))) { - AddMessage( LPGEN("Signature mismatch" )); - return DB_INVALID; - } - - // Determine Miranda version - switch (pdbHeader->version) { - case DB_000700: - AddMessage( LPGEN("This looks like a Miranda database, version 0.1.0.0 or above." )); - free(pdbHeader); - return DB_000700; - - default: - AddMessage( LPGEN("Version mismatch" )); - free(pdbHeader); - return DB_INVALID; -} } - -// High level Miranda DB access functions -// Returns true if pValue points to the requested value - -BOOL GetSetting(HANDLE hDbFile, struct DBContact* pDbContact, char* pszModuleName, char* pszSettingName, DBVARIANT* pValue) -{ - struct DBContactSettings* pDbSettings; - if ( pDbSettings = GetSettingsGroupByModuleName(hDbFile, pDbContact, pszModuleName)) { - if ( GetSettingByName( pDbSettings, pszSettingName, pValue )) { - free(pDbSettings); - return TRUE; - } - #ifdef _LOGGING - AddMessage( LPGEN("Failed to find setting %s" ), pszSettingName ); - #endif - free(pDbSettings); - } -#ifdef _LOGGING - else AddMessage( LPGEN("Failed to find module %s" ), pszModuleName ); -#endif - - // Search failed - pValue->type = 0; - return FALSE; -} - -// ** -// ** CONTACT CHAIN -// ** - -// Return offset to first contact -DWORD FindFirstContact(struct DBHeader* pDbHeader) -{ - if (!pDbHeader) - return 0; - - return pDbHeader->ofsFirstContact; -} - -DWORD FindOwnerContact(struct DBHeader* pDbHeader) -{ - if (!pDbHeader) - return 0; - - return pDbHeader->ofsUser; -} - -// Return offset to next contact -DWORD FindNextContact(struct DBContact* pDbContact) -{ - if (!pDbContact) - return 0; - - if (pDbContact->signature != DBCONTACT_SIGNATURE) - return 0; - - return pDbContact->ofsNext; -} - - -// Read the contact at offset 'dwOffset' -// Returns true if successful and pDbContact points to the contact struct -// pDbContact must point to allocated struct -BOOL GetContact(HANDLE hDbFile, DWORD dwOffset, struct DBContact* pDbContact) -{ - DWORD dwBytesRead; - - // Early reject - if (dwOffset == 0 || dwOffset >= dwFileSize) - return FALSE; - - // ** Read and verify the struct - - if (SetFilePointer(hDbFile, (LONG)dwOffset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) - return FALSE; - - if ((!ReadFile(hDbFile, pDbContact, sizeof(struct DBContact), &dwBytesRead, NULL)) || - (dwBytesRead != sizeof(struct DBContact))) - return FALSE; - - if ((pDbContact->signature != DBCONTACT_SIGNATURE) || - (pDbContact->ofsNext >= dwFileSize)) - return FALSE; // Contact corrupted - - return TRUE; -} - -// Return ptr to next setting in settings struct -char* GetNextSetting(char* pDbSetting) -{ - // Get next setting - pDbSetting = pDbSetting + *pDbSetting+1; // Skip name - switch( *(BYTE*)pDbSetting ) { - case DBVT_BYTE: - pDbSetting = pDbSetting+1+1; - break; - - case DBVT_WORD: - pDbSetting = pDbSetting+1+2; - break; - - case DBVT_DWORD: - pDbSetting = pDbSetting+1+4; - break; - - case DBVT_ASCIIZ: - case DBVT_UTF8: - case DBVT_BLOB: - case DBVTF_VARIABLELENGTH: - pDbSetting = pDbSetting + 3 + *(WORD*)(pDbSetting+1); - break; - - case DBVT_DELETED: - AddMessage( LPGEN("DEBUG: Deleted setting treated as 0-length setting")); - pDbSetting = pDbSetting+1; - break; - - default: - // Unknown datatype assert - AddMessage( LPGEN("ERROR: Faulty settings chain")); - return NULL; - } - - return pDbSetting; -} - - -// ** -// ** SETTINGS CHAIN -// ** - -// Return the settings at offset 'dwOffset' -BOOL GetSettingsGroup(HANDLE hDbFile, DWORD dwOffset, struct DBContactSettings** pDbSettings) -{ - DWORD dwBytesRead, dwBlobSize, dwHead; - struct DBContactSettings pSettings; - - // Early reject - if (dwOffset == 0 || dwOffset >= dwFileSize) - return FALSE; - - // ** Read and verify the struct - if (SetFilePointer(hDbFile, dwOffset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) - return FALSE; - - dwHead = offsetof(struct DBContactSettings, blob); - if ((!ReadFile(hDbFile, &pSettings, dwHead, &dwBytesRead, NULL)) || - (dwBytesRead != dwHead)) - return FALSE; - - if (pSettings.signature != DBCONTACTSETTINGS_SIGNATURE) - return FALSE; // Setttings corrupted - - // ** Read the struct and the following blob - dwBlobSize = pSettings.cbBlob; - if (!(*pDbSettings = (DBContactSettings *)calloc(1, sizeof(struct DBContactSettings) + dwBlobSize))) - return FALSE; - - memcpy(*pDbSettings, &pSettings, dwHead ); - - if ((!ReadFile(hDbFile, (*pDbSettings)->blob, sizeof(struct DBContactSettings) - dwHead + dwBlobSize, &dwBytesRead, NULL)) || - (dwBytesRead != sizeof(struct DBContactSettings) - dwHead + dwBlobSize)) - { - free(*pDbSettings); - return FALSE; - } - - return TRUE; -} - -// pDbContact is a ptr to a struct DBContact -// Returns pointer to a struct DBContactSettings or NULL -struct DBContactSettings* GetSettingsGroupByModuleName(HANDLE hDbFile, struct DBContact* pDbContact, char* pszName) -{ - char* pszGroupName; - struct DBContactSettings* pSettingsGroup; - DWORD dwGroupOfs; - - // Get ptr to first settings group - if (!(dwGroupOfs = pDbContact->ofsFirstSettings)) - return NULL; // No settings exists in this contact - - // Loop over all settings groups - while (dwGroupOfs && dwGroupOfs < dwFileSize) { - pSettingsGroup = NULL; - - // Read and verify the struct - if (!GetSettingsGroup(hDbFile, dwGroupOfs, &pSettingsGroup)) - return NULL; // Bad struct - - // Struct OK, now get the name - if ((pszGroupName = GetName(hDbFile, pSettingsGroup->ofsModuleName))) { - - // Is it the right one? - if (strcmp(pszGroupName, pszName) == 0) { - #ifdef _LOGGING - AddMessage( LPGEN("Found module: %s"), pszGroupName ); - #endif - return pSettingsGroup; - } - #ifdef _LOGGING - else AddMessage( LPGEN("Ignoring module: %s"), pszGroupName ); - #endif - } - else AddMessage( LPGEN("Warning: Found module with no name")); - - dwGroupOfs = pSettingsGroup->ofsNext; - - if (pSettingsGroup) - free(pSettingsGroup); - } - - // Search failed - return NULL; -} - -// pDbSettings must point to a complete DBContactSettings struct in memory -int GetSettingByName(struct DBContactSettings* pDbSettings, char* pszSettingName, DBVARIANT* dbv) -{ - char pszName[256]; - // We need at least one setting to start with - char* pDbSetting = (char*)pDbSettings->blob; - if ( !pDbSetting ) - return FALSE; - - // ** pDbSettings now points to the first setting in this module - - // Loop over all settings - while (pDbSetting && *pDbSetting) { - memcpy(pszName, pDbSetting+1, *pDbSetting); - pszName[*pDbSetting] = 0; - - // Is this the right one? - if (strcmp(pszSettingName, pszName) == 0) { - return GetSettingValue(pDbSetting, dbv); - } - - #ifdef _LOGGING - AddMessage( LPGEN("Ignoring setting: %s"), pszName ); - #endif - pDbSetting = GetNextSetting(pDbSetting); - } - - // Search failed - return FALSE; -} - -// dwSettingpointer points to a valid DBSettings struct -int GetSettingValue(char* pBlob, DBVARIANT* dbv) -{ - #ifdef _LOGGING - { - char* pszName = calloc((*pBlob)+1, 1); - memcpy(pszName, pBlob+1, *pBlob); - AddMessage( LPGEN("Getting type %u value for setting: %s"), (BYTE)*(pBlob+(*pBlob)+1), pszName ); - free(pszName); - } - #endif - - // Skip name - pBlob = pBlob + (*pBlob)+1; - dbv->type = ( BYTE )*pBlob++; - - // Check what type it is - switch( dbv->type ) { - case DBVT_BYTE: - dbv->bVal = *pBlob; - return TRUE; - - case DBVT_WORD: - dbv->wVal = *(WORD*)pBlob; - return TRUE; - - case DBVT_DWORD: - dbv->dVal = *(DWORD*)pBlob; - return TRUE; - - case DBVT_ASCIIZ: - case DBVT_UTF8: - dbv->cchVal = *(WORD*)pBlob; - dbv->pszVal = (char *)calloc( dbv->cchVal+1, sizeof( char )); - memcpy( dbv->pszVal, pBlob+2, dbv->cchVal ); - dbv->pszVal[ dbv->cchVal ] = 0; - return TRUE; - - case DBVTF_VARIABLELENGTH: - case DBVT_BLOB: - dbv->cpbVal = *(WORD*)pBlob; - dbv->pbVal = (BYTE *)calloc( dbv->cpbVal+1, sizeof( char )); - memcpy( dbv->pbVal, pBlob+2, dbv->cpbVal ); - dbv->pbVal[ dbv->cpbVal ] = 0; - return TRUE; - - case DBVT_DELETED: - AddMessage( LPGEN("DEBUG: Deleted setting treated as 0-length setting")); - - default: - dbv->type = DBVT_DELETED; - } - - return FALSE; -} - -void FreeVariant( DBVARIANT* dbv ) -{ - switch( dbv->type ) { - case DBVT_ASCIIZ: - case DBVT_UTF8: - if ( dbv->pszVal ) - free( dbv->pszVal ); - break; - - case DBVTF_VARIABLELENGTH: - case DBVT_BLOB: - if ( dbv->pbVal ) - free( dbv->pbVal ); - break; - } - - dbv->type = 0; -} - -void WriteVariant( HANDLE hContact, const char* module, const char* var, DBVARIANT* dbv ) -{ - DBCONTACTWRITESETTING dbw; - dbw.szModule = module; - dbw.szSetting = var; - dbw.value = *dbv; - CallService( MS_DB_CONTACT_WRITESETTING, (WPARAM)hContact, (LPARAM)&dbw ); -} - -// Returns true if pDBEI has been filled in with nice values -// Don't forget to free those pointers! -BOOL GetEvent(HANDLE hDbFile, DWORD dwOffset, DBEVENTINFO* pDBEI) -{ - DWORD dwBytesRead; - struct DBEvent pEvent; - static char pBlob[65536]; - - // Early reject - if (dwOffset == 0 || dwOffset >= dwFileSize) - return FALSE; - - // ** Read and verify the struct - if (SetFilePointer(hDbFile, dwOffset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) - return FALSE; - - if (!ReadFile(hDbFile, &pEvent, offsetof(struct DBEvent, blob), &dwBytesRead, NULL) || - (dwBytesRead != offsetof(struct DBEvent, blob))) - return FALSE; - - if (pEvent.signature != DBEVENT_SIGNATURE) - return FALSE; // Event corrupted - - // ** Read the blob - if ((!ReadFile(hDbFile, pBlob, pEvent.cbBlob, &dwBytesRead, NULL)) || - (dwBytesRead != pEvent.cbBlob)) - { - return FALSE; - } - - // ** Copy the static part to the event info struct - pDBEI->timestamp = pEvent.timestamp; - pDBEI->eventType = pEvent.eventType; - pDBEI->cbSize = sizeof(DBEVENTINFO); - pDBEI->cbBlob = pEvent.cbBlob; - pDBEI->pBlob = (PBYTE)pBlob; - pDBEI->flags = (pEvent.flags & ~(DBEF_SENT+DBEF_READ)) + - ((pEvent.flags & DBEF_SENT) ? DBEF_SENT : DBEF_READ ); // Imported events are always marked READ - - if (!(pDBEI->szModule = GetName(hDbFile, pEvent.ofsModuleName))) { - return FALSE; - } - - return TRUE; -} - -// Returns a pointer to a string with the name -// from a DBModuleName struct if given a file offset -// Returns NULL on failure -char* GetName(HANDLE hDbFile, DWORD dwOffset) -{ - static DWORD dwLastOffset = 0; - static HANDLE hLastDbFile = NULL; - static char szName[256] = {0}; - - DWORD dwBytesRead; - struct DBModuleName pModule; - - // Early reject - if (dwOffset == 0 || dwOffset >= dwFileSize) - return FALSE; - - // Quick lookup - if (dwOffset == dwLastOffset && hDbFile == hLastDbFile) - return szName; - - // ** Read and verify the name struct - if (SetFilePointer(hDbFile, dwOffset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) - return NULL; - - if ((!ReadFile(hDbFile, &pModule, offsetof(struct DBModuleName, name), &dwBytesRead, NULL)) || - (dwBytesRead != offsetof(struct DBModuleName, name))) - return NULL; - - if (pModule.signature != DBMODULENAME_SIGNATURE) { - AddMessage( LPGEN("Modulename corrupted")); - return NULL; // ModuleName corrupted - } - - // ** Name struct OK, now read name into string buffer - if ((!ReadFile(hDbFile, szName, pModule.cbName, &dwBytesRead, NULL)) || (dwBytesRead != pModule.cbName)) { - return NULL; - } - - // terminate string - szName[pModule.cbName] = 0; - - // update last offset - dwLastOffset = dwOffset; - hLastDbFile = hDbFile; - - return szName; -} - -DWORD FindNextEvent(HANDLE hDbFile, DWORD dwOffset) -{ - DWORD dwBytesRead; - struct DBEvent pEvent; - - // Early reject - if (dwOffset == 0 || dwOffset >= dwFileSize) - return FALSE; - - // ** Read and verify the struct - if (SetFilePointer(hDbFile, dwOffset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) - return FALSE; - - if ((!ReadFile(hDbFile, &pEvent, sizeof(struct DBEvent), &dwBytesRead, NULL)) || - (dwBytesRead != sizeof(struct DBEvent))) - return FALSE; - - if ( pEvent.signature != DBEVENT_SIGNATURE || pEvent.ofsNext > dwFileSize ) - return FALSE; // Event corrupted - - return pEvent.ofsNext; -} - -int ImportGroups(HANDLE hDbFile, struct DBHeader* pdbHeader) -{ - struct DBContactSettings* pDbSettings; - struct DBContact DbContact; - char* pSetting; - DWORD dwOffset; - int nGroups = 0; - - // Find owner data - dwOffset = pdbHeader->ofsUser; - if (!GetContact(hDbFile, dwOffset, &DbContact)) { - AddMessage( LPGEN("No owner found.")); - return -1; - } - - // Find the module with the groups, and import them all - if ( pDbSettings = GetSettingsGroupByModuleName( hDbFile, &DbContact, "CListGroups" )) { - pSetting = (char *)pDbSettings->blob; - while ( pSetting && *pSetting ) { - DBVARIANT dbv; - if ( GetSettingValue( pSetting, &dbv )) { - if ( CreateGroup( dbv.type, dbv.pszVal+1, NULL )) - nGroups++; - FreeVariant( &dbv ); - } - pSetting = GetNextSetting(pSetting); - } - free(pDbSettings); - } - - return nGroups; -} - -HANDLE ImportContact(HANDLE hDbFile, struct DBContact Contact) -{ - HANDLE hContact; - DBVARIANT group, nick, dbv; - char* pszProtoName; - char* pszUniqueSetting; - char* pszUserName; - char id[ 40 ]; - - // Check what protocol this contact belongs to - if ( !GetSetting( hDbFile, &Contact, "Protocol", "p", &dbv )) { - AddMessage( LPGEN("Skipping contact with no protocol")); - return INVALID_HANDLE_VALUE; - } - - pszProtoName = NEWSTR_ALLOCA( dbv.pszVal ); - FreeVariant( &dbv ); - - if ( !IsProtocolLoaded( pszProtoName )) { - AddMessage( LPGEN("Skipping contact, %s not installed."), pszProtoName ); - return INVALID_HANDLE_VALUE; - } - - // Skip protocols with no unique id setting (some non IM protocols return NULL) - pszUniqueSetting = (char*)CallProtoService(pszProtoName, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0); - if ( !pszUniqueSetting || (INT_PTR)pszUniqueSetting == CALLSERVICE_NOTFOUND ) { - AddMessage( LPGEN("Skipping non-IM contact (%s)"), pszProtoName ); - return INVALID_HANDLE_VALUE; - } - - if ( !GetSetting(hDbFile, &Contact, pszProtoName, pszUniqueSetting, &dbv )) { - AddMessage( LPGEN("Skipping %s contact, ID not found"), pszProtoName ); - return INVALID_HANDLE_VALUE; - } - - // Does the contact already exist? - if ( dbv.type == DBVT_DWORD ) { - pszUserName = _ltoa( dbv.dVal, id, 10 ); - hContact = HContactFromNumericID( pszProtoName, pszUniqueSetting, dbv.dVal ); - } - else { - pszUserName = NEWSTR_ALLOCA( dbv.pszVal ); - hContact = HContactFromID( pszProtoName, pszUniqueSetting, dbv.pszVal ); - } - - if ( hContact != INVALID_HANDLE_VALUE ) { - AddMessage( LPGEN("Skipping duplicate %s contact %s"), pszProtoName, pszUserName ); - FreeVariant( &dbv ); - return INVALID_HANDLE_VALUE; - } - // No, add contact and copy some important settings - GetSetting(hDbFile, &Contact, "CList", "Group", &group); - - if ( !GetSetting( hDbFile, &Contact, "CList", "MyHandle", &nick )) - GetSetting(hDbFile, &Contact, pszProtoName, "Nick", &nick ); - - hContact = AddContact( hdlgProgress, pszProtoName, pszUniqueSetting, &dbv, &nick, &group ); - - if ( hContact != INVALID_HANDLE_VALUE) { - - // Hidden? - if ( GetSetting( hDbFile, &Contact, "CList", "Hidden", &dbv )) { - WriteVariant( hContact, "CList", "Hidden", &dbv ); - FreeVariant( &dbv ); - } - // Ignore settings - if ( GetSetting( hDbFile, &Contact, "Ignore", "Mask1", &dbv )) { - WriteVariant( hContact, "Ignore", "Mask1", &dbv ); - FreeVariant( &dbv ); - } - - // Apparent mode - if ( GetSetting( hDbFile, &Contact, pszProtoName, "ApparentMode", &dbv )) { - WriteVariant( hContact, pszProtoName, "ApparentMode", &dbv ); - FreeVariant( &dbv ); - } - - // Nick - if ( GetSetting( hDbFile, &Contact, pszProtoName, "Nick", &dbv )) { - WriteVariant( hContact, pszProtoName, "Nick", &dbv ); - FreeVariant( &dbv ); - } - - // Myhandle - if ( GetSetting( hDbFile, &Contact, pszProtoName, "MyHandle", &dbv )) { - WriteVariant( hContact, pszProtoName, "MyHandle", &dbv ); - FreeVariant( &dbv ); - } - - // First name - if ( GetSetting( hDbFile, &Contact, pszProtoName, "FirstName", &dbv )) { - WriteVariant( hContact, pszProtoName, "FirstName", &dbv ); - FreeVariant( &dbv ); - } - - // Last name - if ( GetSetting( hDbFile, &Contact, pszProtoName, "LastName", &dbv )) { - WriteVariant( hContact, pszProtoName, "LastName", &dbv ); - FreeVariant( &dbv ); - } - - // About - if ( GetSetting( hDbFile, &Contact, pszProtoName, "About", &dbv )) { - WriteVariant( hContact, pszProtoName, "About", &dbv ); - FreeVariant( &dbv ); - } - } - else AddMessage( LPGEN("Unknown error while adding %s contact %s"), pszProtoName, pszUserName ); - - return hContact; -} - -// This function should always be called after contact import. That is -// why there are no messages for errors related to contacts. Those -// would only be a repetition of the messages printed during contact -// import. - -static void ImportHistory(HANDLE hDbFile, struct DBContact Contact, PROTOCOLDESCRIPTOR **protocol, int protoCount) -{ - HANDLE hContact = INVALID_HANDLE_VALUE; - DWORD dwOffset; - MSG msg; - DBVARIANT proto; - int i, skipAll, bIsVoidContact; - - // Is it contats history import? - if ( protoCount == 0 ) { - - // Check what protocol this contact belongs to - if ( GetSetting( hDbFile, &Contact, "Protocol", "p", &proto )) { - - // Protocol installed? - if ( IsProtocolLoaded( proto.pszVal )) { - // Is contact in database? - char* pszUniqueSetting = (char*)CallProtoService( proto.pszVal, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0); - - // Skip protocols with no unique id setting (some non IM protocols return NULL) - if ( pszUniqueSetting && ( INT_PTR )pszUniqueSetting != CALLSERVICE_NOTFOUND ) { - DBVARIANT dbv; - if ( GetSetting( hDbFile, &Contact, proto.pszVal, pszUniqueSetting, &dbv )) { - if ( dbv.type == DBVT_DWORD ) - hContact = HContactFromNumericID( proto.pszVal, pszUniqueSetting, dbv.dVal ); - else - hContact = HContactFromID( proto.pszVal, pszUniqueSetting, dbv.pszVal ); - FreeVariant( &dbv ); - } } } - FreeVariant( &proto ); - } - } - else hContact = NULL; //system history import - - // OK to import this chain? - if (hContact == INVALID_HANDLE_VALUE) { - nSkippedContacts++; - return; - } - - i = skipAll = 0; - bIsVoidContact = CallService( MS_DB_EVENT_GETCOUNT, ( WPARAM )hContact, 0 ) == 0; - - // Get the start of the event chain - dwOffset = Contact.ofsFirstEvent; - while (dwOffset) { - int skip = 0; - - // Copy the event and import it - DBEVENTINFO dbei = { 0 }; - if (GetEvent(hDbFile, dwOffset, &dbei)) { - // check protocols during system history import - if (hContact == NULL) { - int i; - skipAll = 1; - - for(i = 0; i < protoCount; i++) - if (!strcmp(dbei.szModule, protocol[i]->szName)) { //&& protocol[i]->type == PROTOTYPE_PROTOCOL) - skipAll = 0; - break; - } - - skip = skipAll; - } - - // custom filtering - if (!skip && nImportOption == IMPORT_CUSTOM) { - BOOL sent = (dbei.flags&DBEF_SENT); - - if (dbei.timestamp < (DWORD)dwSinceDate) - skip = 1; - - if (!skip) { - if (hContact) { - skip = 1; - switch(dbei.eventType) { - case EVENTTYPE_MESSAGE: - if ((sent?IOPT_MSGSENT:IOPT_MSGRECV)&nCustomOptions) - skip = 0; - break; - case EVENTTYPE_FILE: - if ((sent?IOPT_FILESENT:IOPT_FILERECV)&nCustomOptions) - skip = 0; - break; - case EVENTTYPE_URL: - if ((sent?IOPT_URLSENT:IOPT_URLRECV)&nCustomOptions) - skip = 0; - break; - default: - if ((sent?IOPT_OTHERSENT:IOPT_OTHERRECV)&nCustomOptions) - skip = 0; - break; - } - } - else if ( !( nCustomOptions & IOPT_SYSTEM )) - skip = 1; - } - - if (skip) - nSkippedEvents++; - } - - if (!skip) { - // Check for duplicate entries - if ( !IsDuplicateEvent( hContact, dbei )) { - // Add dbevent - if (!bIsVoidContact) - dbei.flags &= ~DBEF_FIRST; - if (CallService(MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&dbei)) - nMessagesCount++; - else - AddMessage( LPGEN("Failed to add message")); - } - else - nDupes++; - } - } - - if ( !( i%10 )) { - if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } } - - // skip this chain if needed - if ( skipAll ) - break; - - // Get next event - dwOffset = FindNextEvent(hDbFile, dwOffset); - i++; - } -} - -static void MirandaImport(HWND hdlg) -{ - int nDBVersion; - int i; - int nNumberOfContacts = 0; - MSG msg; - DWORD dwTimer; - DWORD dwOffset; - HANDLE hFile; - char* pszModuleName = NULL; - struct DBHeader* pdbHeader = NULL; - struct DBContact Contact; - - // Just to keep the macros happy - hdlgProgress = hdlg; - - // Reset statistics - nSkippedEvents = 0; - nDupes = 0; - nContactsCount = 0; - nMessagesCount = 0; - nGroupsCount = 0; - nSkippedContacts = 0; - SetProgress(0); - - // Open database - hFile = CreateFile(importFile, - GENERIC_READ, // open for reading - 0, // do not share - NULL, // no security - OPEN_EXISTING, // existing file only - FILE_ATTRIBUTE_NORMAL, // normal file - NULL); // no attr. template - - // Read error - if (hFile == INVALID_HANDLE_VALUE) { - AddMessage( LPGEN("Could not open file.")); - SetProgress(100); - return; - } - - // Check filesize - dwFileSize = GetFileSize(hFile, NULL) ; - if ((dwFileSize == INVALID_FILE_SIZE) || (dwFileSize < sizeof(struct DBHeader))) { - AddMessage( LPGEN("This is not a valid Miranda IM database.")); - SetProgress(100); - CloseHandle(hFile); - return; - } - - // Check header and database version - nDBVersion = CheckFileFormat(hFile); - if (nDBVersion == DB_INVALID) { - AddMessage( LPGEN("This is not a valid Miranda IM database.")); - SetProgress(100); - CloseHandle(hFile); - return; - } - - // Load database header - if (!(pdbHeader = GetHeader(hFile))) { - AddMessage( LPGEN("Read failure.")); - SetProgress(100); - CloseHandle(hFile); - return; - } - - // Get number of contacts - nNumberOfContacts = pdbHeader->contactCount; - AddMessage( LPGEN("Number of contacts in database: %d"), nNumberOfContacts ); - AddMessage( "" ); - - // Configure database for fast writing - CallService(MS_DB_SETSAFETYMODE, FALSE, 0); - - // Start benchmark timer - dwTimer = time(NULL); - - // Import Groups - if (nImportOption == IMPORT_ALL || (nCustomOptions & IOPT_GROUPS)) { - AddMessage( LPGEN("Importing groups.")); - nGroupsCount = ImportGroups(hFile, pdbHeader); - if (nGroupsCount == -1) - AddMessage( LPGEN("Group import failed.")); - - AddMessage( "" ); - } - // End of Import Groups - - // Import Contacts - if (nImportOption != IMPORT_CUSTOM || (nCustomOptions & IOPT_CONTACTS)) { - AddMessage( LPGEN("Importing contacts.")); - i = 1; - dwOffset = FindFirstContact(pdbHeader); - while (dwOffset && (dwOffset < dwFileSize)) { - if (!GetContact(hFile, dwOffset, &Contact)) { - AddMessage( LPGEN("ERROR: Chain broken, no valid contact at %d"), dwOffset ); - SetProgress(100); - break; - } - - if (ImportContact(hFile, Contact) != INVALID_HANDLE_VALUE) - nContactsCount++; - - // Update progress bar - SetProgress(100 * i / nNumberOfContacts); - i++; - - // Process queued messages - if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - // Get next contact in chain - dwOffset = FindNextContact(&Contact); - } - } - else AddMessage( LPGEN("Skipping new contacts import.")); - AddMessage( "" ); - // End of Import Contacts - - // Import history - if (nImportOption != IMPORT_CONTACTS) { - // Import NULL contact message chain - if (nImportOption == IMPORT_ALL || (nCustomOptions & IOPT_SYSTEM)) { - AddMessage( LPGEN("Importing system history.")); - dwOffset = FindOwnerContact(pdbHeader); - if (!GetContact(hFile, dwOffset, &Contact)) { - AddMessage( LPGEN("ERROR: Chain broken, no valid contact at %d"), dwOffset ); - SetProgress(100); - } - else { - PROTOCOLDESCRIPTOR **protocol; - int protoCount; - - CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&protoCount, (LPARAM)&protocol); - - if (protoCount > 0) - ImportHistory(hFile, Contact, protocol, protoCount); - } - } - else AddMessage( LPGEN("Skipping system history import.")); - - AddMessage( "" ); - - // Import other contact messages - if (nImportOption == IMPORT_ALL || (nCustomOptions & 2046)) { // 2 - 1024 types - AddMessage( LPGEN("Importing history.")); - dwOffset = FindFirstContact(pdbHeader); - for(i=1; i <= nNumberOfContacts; i++) { - if (!GetContact(hFile, dwOffset, &Contact)) { - AddMessage( LPGEN("ERROR: Chain broken, no valid contact at %d"), dwOffset ); - SetProgress(100); - break; - } - - ImportHistory(hFile, Contact, NULL, 0); - - SetProgress(100 * i / nNumberOfContacts); - dwOffset = FindNextContact(&Contact); - } - } - else AddMessage( LPGEN("Skipping history import.")); - - AddMessage( "" ); - } - // End of Import History - - // Restore database writing mode - CallService(MS_DB_SETSAFETYMODE, TRUE, 0); - - // Clean up before exit - CloseHandle(hFile); - free(pdbHeader); - - // Stop timer - dwTimer = time(NULL) - dwTimer; - - // Print statistics - AddMessage( LPGEN("Import completed in %d seconds."), dwTimer ); - SetProgress(100); - AddMessage((nImportOption == IMPORT_CONTACTS) ? - LPGEN("Added %d contacts and %d groups.") : LPGEN("Added %d contacts, %d groups and %d events."), - nContactsCount, nGroupsCount, nMessagesCount); - - if ( nImportOption != IMPORT_CONTACTS ) { - if (nSkippedContacts) - AddMessage( LPGEN("Skipped %d contacts."), nSkippedContacts ); - - AddMessage((nImportOption == IMPORT_CUSTOM) ? - LPGEN("Skipped %d duplicates and %d filtered events.") : LPGEN("Skipped %d duplicates."), - nDupes, nSkippedEvents); -} } diff --git a/plugins/Import/mirandadb0700.h b/plugins/Import/mirandadb0700.h deleted file mode 100644 index 2c77588951..0000000000 --- a/plugins/Import/mirandadb0700.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - -Import plugin for Miranda IM - -Copyright (C) 2001,2002,2003,2004 Martin Öberg, Richard Hughes, Roland Rabien & Tristan Van de Vreede - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - - - -//all offsets are relative to the start of the file -//offsets are 0 if there is nothing in the chain or this is the last in the -//chain - - - - -/* tree diagram - -DBHeader - |-->end of file (plain offset) - |-->first contact (DBContact) - | |-->next contact (DBContact) - | | \--> ... - | |-->first settings (DBContactSettings) - | | |-->next settings (DBContactSettings) - | | | \--> ... - | | \-->module name (DBModuleName) - | \-->first/last/firstunread event - |-->user contact (DBContact) - | |-->next contact=NULL - | |-->first settings as above - | \-->first/last/firstunread event as above - \-->first module name (DBModuleName) - \-->next module name (DBModuleName) - \--> ... -*/ - -#define DB_THIS_VERSION 0x00000700u - -#include -struct DBHeader { - BYTE signature[16]; // 'Miranda ICQ DB',0,26 - DWORD version; //as 4 bytes, ie 1.2.3.10=0x0102030a - //this version is 0x00000700 - DWORD ofsFileEnd; //offset of the end of the database - place to write - //new structures - DWORD slackSpace; //a counter of the number of bytes that have been - //wasted so far due to deleting structures and/or - //re-making them at the end. We should compact when - //this gets above a threshold - DWORD contactCount; //number of contacts in the chain,excluding the user - DWORD ofsFirstContact; //offset to first struct DBContact in the chain - DWORD ofsUser; //offset to struct DBContact representing the user - DWORD ofsFirstModuleName; //offset to first struct DBModuleName in the chain -}; - -#define DBCONTACT_SIGNATURE 0x43DECADEu -struct DBContact { - DWORD signature; - DWORD ofsNext; //offset to the next contact in the chain. zero if - //this is the 'user' contact or the last contact - //in the chain - DWORD ofsFirstSettings; //offset to the first DBContactSettings in the - //chain for this contact. - DWORD eventCount; //number of events in the chain for this contact - DWORD ofsFirstEvent,ofsLastEvent; //offsets to the first and last DBEvent in - //the chain for this contact - DWORD ofsFirstUnreadEvent; //offset to the first (chronological) unread event - //in the chain, 0 if all are read - DWORD timestampFirstUnread; //timestamp of the event at ofsFirstUnreadEvent -}; - -#define DBMODULENAME_SIGNATURE 0x4DDECADEu -struct DBModuleName { - DWORD signature; - DWORD ofsNext; //offset to the next module name in the chain - BYTE cbName; //number of characters in this module name - char name[1]; //name, no nul terminator -}; - -#define DBCONTACTSETTINGS_SIGNATURE 0x53DECADEu -struct DBContactSettings { - DWORD signature; - DWORD ofsNext; //offset to the next contactsettings in the chain - DWORD ofsModuleName; //offset to the DBModuleName of the owner of these - //settings - DWORD cbBlob; //size of the blob in bytes. May be larger than the - //actual size for reducing the number of moves - //required using granularity in resizing - BYTE blob[1]; //the blob. a back-to-back sequence of DBSetting - //structs, the last has cbName=0 -}; - -/* not a valid structure, content is figured out on the fly -struct DBSetting { - BYTE cbName; //number of bytes in the name of this setting - //this =0 marks the end - char szName[...]; //setting name, excluding nul - BYTE dataType; //type of data. see m_database.h, db/contact/getsetting - union { //a load of types of data, length is defined by dataType - BYTE bVal; WORD wVal; DWORD dVal; - struct { - WORD cbString; - char szVal[...]; //excludes nul terminator - }; - struct { - WORD cbBlob; - BYTE blobVal[...]; - }; - }; -}; -*/ - -#define DBEVENT_SIGNATURE 0x45DECADEu -struct DBEvent { - DWORD signature; - DWORD ofsPrev,ofsNext; //offset to the previous and next events in the - //chain. Chain is sorted chronologically - DWORD ofsModuleName; //offset to a DBModuleName struct of the name of - //the owner of this event - DWORD timestamp; //seconds since 00:00:00 01/01/1970 - DWORD flags; //see m_database.h, db/event/add - WORD eventType; //module-defined event type - DWORD cbBlob; //number of bytes in the blob - BYTE blob[1]; //the blob. module-defined formatting -}; -#include diff --git a/plugins/Import/mirandahistory.cpp b/plugins/Import/mirandahistory.cpp deleted file mode 100644 index ba7a923df7..0000000000 --- a/plugins/Import/mirandahistory.cpp +++ /dev/null @@ -1,208 +0,0 @@ -/* -Miranda ICQ: the free icq client for MS Windows -Copyright (C) 2000-2 Richard Hughes, Roland Rabien & Tristan Van de Vreede - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ -#include -#include -#include -#include "resource.h" -#include "import.h" - -BOOL CALLBACK MirandaPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam); -BOOL CALLBACK FinishedPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam); -BOOL CALLBACK ProgressPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam); -extern char importFile[MAX_PATH]; -extern void (*DoImport)(HWND); -static void OldMirandaHistoryImport(HWND hdlgProgress); -HANDLE HContactFromUIN(DWORD uin); -HANDLE HistoryImportFindContact(HWND hdlgProgress,DWORD uin,int addUnknown); -static DWORD importOptions; - -BOOL CALLBACK MirandaHistoryPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam) -{ - switch(message) { - case WM_INITDIALOG: - CheckDlgButton(hdlg,IDC_ADDUNKNOWN,BST_CHECKED); - CheckDlgButton(hdlg,IDC_MSGRECV,BST_CHECKED); - CheckDlgButton(hdlg,IDC_MSGSENT,BST_CHECKED); - CheckDlgButton(hdlg,IDC_URLRECV,BST_CHECKED); - CheckDlgButton(hdlg,IDC_URLSENT,BST_CHECKED); - CheckDlgButton(hdlg,IDC_AUTHREQ,BST_CHECKED); - CheckDlgButton(hdlg,IDC_ADDED,BST_CHECKED); - return TRUE; - case WM_COMMAND: - switch(LOWORD(wParam)) { - case IDC_BACK: - PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_MIRANDADB,(LPARAM)MirandaPageProc); - break; - case IDOK: - importOptions=0; - if(IsDlgButtonChecked(hdlg,IDC_ADDUNKNOWN)) importOptions|=IOPT_ADDUNKNOWN; - if(IsDlgButtonChecked(hdlg,IDC_MSGSENT)) importOptions|=IOPT_MSGSENT; - if(IsDlgButtonChecked(hdlg,IDC_MSGRECV)) importOptions|=IOPT_MSGRECV; - if(IsDlgButtonChecked(hdlg,IDC_URLSENT)) importOptions|=IOPT_URLSENT; - if(IsDlgButtonChecked(hdlg,IDC_URLRECV)) importOptions|=IOPT_URLRECV; - if(IsDlgButtonChecked(hdlg,IDC_AUTHREQ)) importOptions|=IOPT_AUTHREQ; - if(IsDlgButtonChecked(hdlg,IDC_ADDED)) importOptions|=IOPT_ADDED; - DoImport=OldMirandaHistoryImport; - PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_PROGRESS,(LPARAM)ProgressPageProc); - break; - case IDCANCEL: - PostMessage(GetParent(hdlg),WM_CLOSE,0,0); - break; - } - break; - } - return FALSE; -} - -#define HISTORY_MSGRECV 1 -#define HISTORY_MSGSEND 2 -#define HISTORY_URLRECV 3 -#define HISTORY_URLSEND 4 -#define HISTORY_AUTHREQ 5 -#define HISTORY_ADDED 6 -#define issent(t) ((t)==HISTORY_MSGSEND || (t)==HISTORY_URLSEND) -static int historyTypeToOption[]={0,IOPT_MSGRECV,IOPT_MSGSENT,IOPT_URLRECV,IOPT_URLSENT,IOPT_AUTHREQ,IOPT_ADDED}; - -static PBYTE ReadHistoryLines(FILE *fp,int *cbBlob) -{ - char str[2048]; - char *blob; - int ofs; - *cbBlob=0; - blob=NULL; - while(fgets(str,sizeof(str),fp) && lstrcmp(str,"\xEE\xEE\xEE\xEE\r\n")) { - ofs=*cbBlob; - *cbBlob+=lstrlen(str); - blob=(char*)realloc(blob,*cbBlob+1); - lstrcpy(blob+ofs,str); - } - if (*cbBlob) { - (*cbBlob)--; - blob[*cbBlob-1]=0; - } - else { - *cbBlob=1; - blob=(char*)malloc(1); - blob[0]=0; - } - return (PBYTE)blob; -} - -static void OldMirandaHistoryImport(HWND hdlgProgress) -{ - int fileSize; - FILE *fp; - char str[2048],*eol,*timeofs; - HANDLE hContact; - int type; - DWORD uin; - struct tm tmEventTime; - DBEVENTINFO dbei; - - AddMessage("Old Miranda history import routines initialised"); - fp=fopen(importFile,"rb"); - AddMessage("Calibrating status support functions"); - fseek(fp,0,SEEK_END); - fileSize=ftell(fp); - fseek(fp,0,SEEK_SET); - SetProgress(0); - - ZeroMemory(&dbei,sizeof(dbei)); - dbei.cbSize=sizeof(dbei); - dbei.szModule=ICQOSCPROTONAME; - - while(!feof(fp)) { - SetProgress(100*ftell(fp)/fileSize); - if(fgets(str,sizeof(str),fp)==NULL) break; - eol=str+lstrlen(str)-1; - - while(*eol=='\r' || *eol=='\n' && eol!=str-1) - *(eol--)=0; - - if(lstrlen(str)<20) continue; - type=*eol; - uin=strtoul(str,NULL,10); - if(uin==0) continue; //skip MSN - timeofs=str+lstrlen(str)-20; - tmEventTime.tm_hour=atoi(timeofs); - timeofs=strchr(timeofs,':'); - if(timeofs==NULL) continue; - tmEventTime.tm_min=atoi(timeofs+1); - tmEventTime.tm_sec=0; - tmEventTime.tm_isdst=-1; - tmEventTime.tm_mday=atoi(timeofs+7); - tmEventTime.tm_mon=atoi(timeofs+10)-1; - tmEventTime.tm_year=atoi(timeofs+13)-1900; - dbei.timestamp=mktime(&tmEventTime)+_timezone; - if (!(importOptions&historyTypeToOption[type])) continue; - hContact=HistoryImportFindContact(hdlgProgress,uin,importOptions&IOPT_ADDUNKNOWN); - if(hContact==INVALID_HANDLE_VALUE) break; - dbei.flags=issent(type)?DBEF_SENT:DBEF_READ; - switch(type) { - case HISTORY_MSGRECV: - case HISTORY_MSGSEND: - dbei.eventType=EVENTTYPE_MESSAGE; - dbei.pBlob=ReadHistoryLines(fp,&dbei.cbBlob); - CallService(MS_DB_EVENT_ADD,(WPARAM)hContact,(LPARAM)&dbei); - break; - case HISTORY_URLRECV: - case HISTORY_URLSEND: - dbei.eventType=EVENTTYPE_URL; - dbei.pBlob=ReadHistoryLines(fp,&dbei.cbBlob); - { char *endOfUrl; - endOfUrl=strchr(dbei.pBlob,'\r'); - if(endOfUrl!=NULL) { - *endOfUrl=0; - dbei.cbBlob--; - MoveMemory(endOfUrl+1,endOfUrl+2,dbei.cbBlob-(endOfUrl-dbei.pBlob)); - } - } - CallService(MS_DB_EVENT_ADD,(WPARAM)hContact,(LPARAM)&dbei); - break; - case HISTORY_AUTHREQ: - dbei.eventType=EVENTTYPE_AUTHREQUEST; - dbei.pBlob=ReadHistoryLines(fp,&dbei.cbBlob); - dbei.pBlob=(PBYTE)realloc(dbei.pBlob,dbei.cbBlob+8); - MoveMemory(dbei.pBlob+8,dbei.pBlob,dbei.cbBlob); - *(PDWORD)dbei.pBlob=uin; - *(char*)(dbei.pBlob+4)=0; //leave nick, first, last, email blank - *(char*)(dbei.pBlob+5)=0; - *(char*)(dbei.pBlob+6)=0; - *(char*)(dbei.pBlob+7)=0; - dbei.cbBlob+=8; - CallService(MS_DB_EVENT_ADD,(WPARAM)(HANDLE)NULL,(LPARAM)&dbei); - break; - case HISTORY_ADDED: - dbei.eventType=EVENTTYPE_ADDED; - dbei.pBlob=(PBYTE)malloc(8); - dbei.cbBlob=8; - *(PDWORD)dbei.pBlob=uin; - *(char*)(dbei.pBlob+4)=0; //leave nick, first, last, email blank - *(char*)(dbei.pBlob+5)=0; - *(char*)(dbei.pBlob+6)=0; - *(char*)(dbei.pBlob+7)=0; - CallService(MS_DB_EVENT_ADD,(WPARAM)(HANDLE)NULL,(LPARAM)&dbei); - break; - } - } - AddMessage("Terminating cached I/O access"); - fclose(fp); - AddMessage("Import completed successfully"); - SetProgress(100); -} \ No newline at end of file diff --git a/plugins/Import/progress.cpp b/plugins/Import/progress.cpp deleted file mode 100644 index 99412f647a..0000000000 --- a/plugins/Import/progress.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - -Import plugin for Miranda IM - -Copyright (C) 2001-2005 Martin Öberg, Richard Hughes, Roland Rabien & Tristan Van de Vreede - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include -#include -#include - -#include "import.h" -#include "resource.h" - -#define PROGM_START (WM_USER+100) - -INT_PTR CALLBACK FinishedPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam); - -void (*DoImport)(HWND); - -INT_PTR CALLBACK ProgressPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam) -{ - switch(message) { - case WM_INITDIALOG: - TranslateDialogDefault(hdlg); - SendMessage(GetParent(hdlg),WIZM_DISABLEBUTTON,0,0); - SendMessage(GetParent(hdlg),WIZM_DISABLEBUTTON,1,0); - SendMessage(GetParent(hdlg),WIZM_DISABLEBUTTON,2,0); - SendDlgItemMessage(hdlg,IDC_PROGRESS,PBM_SETRANGE,0,MAKELPARAM(0,100)); - PostMessage(hdlg,PROGM_START,0,0); - return TRUE; - - case PROGM_SETPROGRESS: - SendDlgItemMessage(hdlg,IDC_PROGRESS,PBM_SETPOS,wParam,0); - break; - - case PROGM_ADDMESSAGE: - { - int i=SendDlgItemMessage(hdlg,IDC_STATUS,LB_ADDSTRING,0,lParam); - SendDlgItemMessage(hdlg,IDC_STATUS,LB_SETTOPINDEX,i,0); - } - break; - - case PROGM_START: - DoImport(hdlg); - SendMessage(GetParent(hdlg),WIZM_ENABLEBUTTON,1,0); - SendMessage(GetParent(hdlg),WIZM_ENABLEBUTTON,2,0); - break; - - case WM_COMMAND: - switch(LOWORD(wParam)) { - case IDOK: - PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_FINISHED,(LPARAM)FinishedPageProc); - break; - case IDCANCEL: - PostMessage(GetParent(hdlg),WM_CLOSE,0,0); - break; - } - break; - } - return FALSE; -} - -void AddMessage( const char* fmt, ... ) -{ - va_list args; - char msgBuf[ 4096 ]; - va_start( args, fmt ); - - mir_vsnprintf( msgBuf, sizeof(msgBuf), Translate(fmt), args ); - - #ifdef _LOGGING - { - FILE *stream; - stream = fopen("Import Debug.log", "a"); - fprintf(stream, "%s\n", msgBuf); - fclose(stream); - } - #endif - - { TCHAR* str = mir_a2t( msgBuf ); - SendMessage( hdlgProgress, PROGM_ADDMESSAGE, 0, ( LPARAM )str ); - mir_free( str ); - } -} diff --git a/plugins/Import/res/import.ico b/plugins/Import/res/import.ico new file mode 100644 index 0000000000..bf7417ae50 Binary files /dev/null and b/plugins/Import/res/import.ico differ diff --git a/plugins/Import/res/resource.rc b/plugins/Import/res/resource.rc new file mode 100644 index 0000000000..103ad9c908 --- /dev/null +++ b/plugins/Import/res/resource.rc @@ -0,0 +1,390 @@ +// Microsoft Visual C++ generated resource script. +// +#include "..\src\resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// 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 + "..\\src\\resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include \r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_IMPORTTYPE DIALOGEX 0, 0, 220, 114 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_3DLOOK | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + LTEXT "Choose how you would like to import:",IDC_STATIC,5,16, + 210,8 + CONTROL "From a Miranda IM database.",IDC_MIRANDA,"Button", + BS_AUTORADIOBUTTON,11,31,204,10 + CONTROL "From a Mirabilis ICQ (99a - 2003a) database.", + IDC_MIRABILIS,"Button",BS_AUTORADIOBUTTON,11,46,204,10 + CONTROL "Use the Find/Add contacts tool to populate my contact list.", + IDC_USEFINDADD,"Button",BS_AUTORADIOBUTTON,11,61,204,10 +END + +IDD_WIZARDINTRO DIALOGEX 0, 0, 220, 114 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_3DLOOK | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + LTEXT "This wizard will help you import contacts and message history from Mirabilis ICQ, as well as letting you import from other Miranda IM profiles.", + IDC_STATIC,33,12,182,32 + ICON IDI_IMPORT,IDC_STATIC,5,12,20,20 + LTEXT "Click ""Next"" to choose the information you wish to import, or click ""Cancel"" to exit the wizard and continue using Miranda.", + IDC_STATIC,33,49,182,25 + CTEXT "It is recommended that you create a backup of your current Miranda profile before importing.", + IDC_STATIC,30,81,182,21 +END + +IDD_FINISHED DIALOGEX 0, 0, 220, 114 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_3DLOOK | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + LTEXT "If you wish to import more information, click ""Next"" to return to the start of the wizard, otherwise click ""Finish"" to start using Miranda.", + IDC_STATIC,5,20,210,16 + LTEXT "You will probably never need to use this wizard again, so you can save memory by not loading it every time you start Miranda. This will mean that the import menu item will no longer be available.", + IDC_STATIC,5,41,210,24 + CONTROL "Do not load the import plugin at startup again", + IDC_DONTLOADPLUGIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 6,97,210,10 + LTEXT "Import completed",IDC_STATIC,5,7,210,8 + LTEXT "If at a future date you wish to use the wizard again, you can make it load again by going to the Plugins section of the Options dialog box.", + IDC_STATIC,5,69,210,24 +END + +IDD_MIRABILISDB DIALOGEX 0, 0, 220, 114 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_3DLOOK | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + LTEXT "Miranda has found Mirabilis ICQ databases corresponding to the following ICQ numbers. Please select the one you wish to import, or click ""Other Database"" if your database is not listed.", + IDC_STATIC,5,5,210,24 + LISTBOX IDC_LIST,5,31,210,36,LBS_SORT | LBS_NOINTEGRALHEIGHT | + WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "&Other Database...",IDC_OTHER,149,69,66,14 + RTEXT "&Filename:",IDC_STATIC,5,88,34,8 + EDITTEXT IDC_FILENAME,42,86,173,12,ES_AUTOHSCROLL + CTEXT "Warning: Mirabilis ICQ running. Import may not be reliable.", + IDC_MIRABILISRUNNING,5,101,210,8 + RTEXT "&Account:",IDC_STATIC,6,74,34,8 + COMBOBOX IDC_MIRABILISACCOUNT,42,71,102,30,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP +END + +IDD_MIRANDADB DIALOGEX 0, 0, 220, 114 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_3DLOOK | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + LTEXT "Miranda has found Miranda profiles with the following names. Please select the one you wish to import, or click ""Other Profile"" if your profile is not listed, or if the list is empty.", + IDC_STATIC,5,10,210,24 + LISTBOX IDC_LIST,5,36,210,36,LBS_SORT | LBS_NOINTEGRALHEIGHT | + WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "&Other Profile...",IDC_OTHER,149,74,66,14 + RTEXT "&Filename:",IDC_STATIC,5,93,34,8 + EDITTEXT IDC_FILENAME,41,91,174,12,ES_AUTOHSCROLL +END + +IDD_PROGRESS DIALOGEX 0, 0, 220, 114 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_3DLOOK | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + LTEXT "Now importing...",IDC_STATIC,5,11,62,8 + CONTROL "Progress1",IDC_PROGRESS,"msctls_progress32",PBS_SMOOTH | + WS_BORDER,5,24,210,10 + LISTBOX IDC_STATUS,5,38,210,61,NOT LBS_NOTIFY | + LBS_NOINTEGRALHEIGHT | LBS_DISABLENOSCROLL | LBS_NOSEL | + WS_VSCROLL | WS_TABSTOP +END + +IDD_WIZARD DIALOGEX 0, 0, 220, 143 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_CAPTION | WS_SYSMENU +CAPTION "Import Information Wizard" +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + DEFPUSHBUTTON "&Next >",IDOK,120,124,45,13 + PUSHBUTTON "Cancel",IDCANCEL,170,124,45,13 + PUSHBUTTON "< &Back",IDC_BACK,75,124,45,13 + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,-7,115,234,1 +END + +IDD_OPTIONS DIALOGEX 0, 0, 220, 114 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_3DLOOK | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + CONTROL "Import all contacts and all messages",IDC_RADIO_ALL, + "Button",BS_AUTORADIOBUTTON | WS_TABSTOP | BS_LEFT | BS_TOP,7,10,206, + 11 + CONTROL "Only import contacts",IDC_RADIO_CONTACTS,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,7,42,206,10 + CONTROL "Custom import",IDC_RADIO_CUSTOM,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP | WS_DISABLED,7,74,206,10 + LTEXT "Select this if you want to import as much data as possible. This is the recommended option.", + IDC_STATIC_ALL,26,20,187,16 + LTEXT "Select this if you want to import contacts but don't want to import any message history.", + IDC_STATIC_CONTACTS,26,52,187,16 + LTEXT "Select this if you want to customize what to import.", + IDC_STATIC_CUSTOM,26,84,187,16,WS_DISABLED +END + +IDD_ICQSERVER DIALOGEX 0, 0, 220, 114 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + LTEXT "Miranda has now been configured to automatically download the contacts in your server-side contact list the next time you connect to ICQ.", + IDC_STATIC,7,9,206,31 + LTEXT "If you want to change the way Miranda handles server-side contacts at a later time, you can do this in the ""ICQ Contacts"" page in the Miranda options.", + IDC_STATIC,7,44,206,37 +END + +IDD_ADVOPTIONS DIALOGEX 0, 0, 220, 114 +STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | DS_CONTROL | WS_CHILD +FONT 8, "MS Shell Dlg", 0, 0, 0x0 +BEGIN + CONTROL "New contacts && groups",IDC_CONTACTS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,10,16,100,10 + CONTROL "System history",IDC_SYSTEM,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,120,16,98,10 + LTEXT "Select items to import:",IDC_ALL,10,3,201,10,SS_NOTIFY + CTEXT "Incoming",IDC_INCOMING,2,34,86,10,SS_NOTIFY + CTEXT "Outgoing",IDC_OUTGOING,132,34,86,10,SS_NOTIFY + CONTROL "",IDC_IN_MSG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,40, + 44,10,10 + CONTROL "",IDC_IN_URL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,40, + 56,10,10 + CONTROL "",IDC_IN_FT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,40,68, + 10,10 + CONTROL "",IDC_IN_OTHER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,40, + 80,10,10 + CONTROL "",IDC_OUT_MSG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,170, + 44,10,10 + CONTROL "",IDC_OUT_URL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,170, + 56,10,10 + CONTROL "",IDC_OUT_FT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,170, + 68,10,10 + CONTROL "",IDC_OUT_OTHER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 170,80,10,10 + CONTROL "Only since:",IDC_SINCE,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,10,99,100,10 + CONTROL "",IDC_DATETIMEPICKER,"SysDateTimePick32",DTS_RIGHTALIGN | + WS_DISABLED | WS_TABSTOP,120,97,81,15 + CTEXT "Messages",IDC_MSG,54,44,112,8,SS_NOTIFY + CTEXT "URLs",IDC_URL,54,56,112,8,SS_NOTIFY + CTEXT "File Transfers",IDC_FT,54,68,112,8,SS_NOTIFY + CTEXT "Other",IDC_OTHER,54,80,112,8,SS_NOTIFY + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,0,93,222,1 + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,0,31,223,1 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_IMPORTTYPE, DIALOG + BEGIN + LEFTMARGIN, 5 + RIGHTMARGIN, 215 + TOPMARGIN, 5 + BOTTOMMARGIN, 109 + END + + IDD_WIZARDINTRO, DIALOG + BEGIN + LEFTMARGIN, 5 + RIGHTMARGIN, 215 + TOPMARGIN, 5 + BOTTOMMARGIN, 109 + END + + IDD_FINISHED, DIALOG + BEGIN + LEFTMARGIN, 5 + RIGHTMARGIN, 215 + TOPMARGIN, 5 + BOTTOMMARGIN, 109 + END + + IDD_MIRABILISDB, DIALOG + BEGIN + LEFTMARGIN, 5 + RIGHTMARGIN, 215 + TOPMARGIN, 5 + BOTTOMMARGIN, 109 + END + + IDD_MIRANDADB, DIALOG + BEGIN + LEFTMARGIN, 3 + RIGHTMARGIN, 216 + TOPMARGIN, 1 + BOTTOMMARGIN, 113 + END + + IDD_PROGRESS, DIALOG + BEGIN + LEFTMARGIN, 5 + RIGHTMARGIN, 215 + TOPMARGIN, 5 + BOTTOMMARGIN, 109 + END + + IDD_WIZARD, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 215 + TOPMARGIN, 7 + BOTTOMMARGIN, 137 + END + + IDD_OPTIONS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 213 + TOPMARGIN, 7 + BOTTOMMARGIN, 111 + END + + IDD_ICQSERVER, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 213 + TOPMARGIN, 7 + BOTTOMMARGIN, 107 + END + + IDD_ADVOPTIONS, DIALOG + BEGIN + VERTGUIDE, 10 + VERTGUIDE, 45 + VERTGUIDE, 110 + VERTGUIDE, 120 + VERTGUIDE, 175 + TOPMARGIN, 3 + HORZGUIDE, 16 + HORZGUIDE, 34 + HORZGUIDE, 104 + END +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,8,0,1 + PRODUCTVERSION 0,8,0,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + 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 Import Plugin" + VALUE "FileVersion", "0.8.0.1" + VALUE "InternalName", "import" + VALUE "LegalCopyright", "Copyright © 2000-2009, Martin Öberg, Richard Hughes, Dmitry Kuzkin, George Hazan" + VALUE "OriginalFilename", "import.dll" + VALUE "ProductName", "Miranda IM" + VALUE "ProductVersion", "0.8.0.1" + 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 diff --git a/plugins/Import/resource.h b/plugins/Import/resource.h deleted file mode 100644 index 7bf769f14d..0000000000 --- a/plugins/Import/resource.h +++ /dev/null @@ -1,64 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by resource.rc -// -#define IDC_BACK 3 -#define IDD_WIZARD 101 -#define IDD_OPTIONS 102 -#define IDD_ICQSERVER 104 -#define IDD_IMPORTTYPE 106 -#define IDD_WIZARDINTRO 107 -#define IDD_FINISHED 108 -#define IDD_MIRABILISDB 109 -#define IDD_MIRANDADB 110 -#define IDD_PROGRESS 111 -#define IDD_ADVOPTIONS 112 -#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_STATUS 1009 -#define IDC_MIRABILISRUNNING 1010 -#define IDC_MIRABILISACCOUNT 1011 -#define IDC_RADIO_ALL 1016 -#define IDC_RADIO_CONTACTS 1017 -#define IDC_RADIO_CUSTOM 1018 -#define IDC_STATIC_ALL 1019 -#define IDC_STATIC_CONTACTS 1020 -#define IDC_STATIC_CUSTOM 1021 -#define IDC_DATETIMEPICKER 1023 -#define IDC_IN_FT 1024 -#define IDC_CONTACTS 1025 -#define IDC_SYSTEM 1026 -#define IDC_SINCE 1027 -#define IDC_IN_MSG 1028 -#define IDC_IN_URL 1029 -#define IDC_OUT_FT 1030 -#define IDC_OUT_MSG 1031 -#define IDC_OUT_URL 1032 -#define IDC_IN_OTHER 1033 -#define IDC_OUT_OTHER 1034 -#define IDC_INCOMING 1035 -#define IDC_OUTGOING 1036 -#define IDC_ALL 1037 -#define IDC_MSG 1038 -#define IDC_URL 1039 -#define IDC_FILE 1040 -#define IDC_FT 1040 -#define IDC_STATIC -1 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 105 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1041 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/plugins/Import/resource.rc b/plugins/Import/resource.rc deleted file mode 100644 index 4ca038ce47..0000000000 --- a/plugins/Import/resource.rc +++ /dev/null @@ -1,390 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// 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 \r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_IMPORTTYPE DIALOGEX 0, 0, 220, 114 -STYLE DS_SETFONT | DS_FIXEDSYS | DS_3DLOOK | DS_CONTROL | WS_CHILD -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "Choose how you would like to import:",IDC_STATIC,5,16, - 210,8 - CONTROL "From a Miranda IM database.",IDC_MIRANDA,"Button", - BS_AUTORADIOBUTTON,11,31,204,10 - CONTROL "From a Mirabilis ICQ (99a - 2003a) database.", - IDC_MIRABILIS,"Button",BS_AUTORADIOBUTTON,11,46,204,10 - CONTROL "Use the Find/Add contacts tool to populate my contact list.", - IDC_USEFINDADD,"Button",BS_AUTORADIOBUTTON,11,61,204,10 -END - -IDD_WIZARDINTRO DIALOGEX 0, 0, 220, 114 -STYLE DS_SETFONT | DS_FIXEDSYS | DS_3DLOOK | DS_CONTROL | WS_CHILD -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "This wizard will help you import contacts and message history from Mirabilis ICQ, as well as letting you import from other Miranda IM profiles.", - IDC_STATIC,33,12,182,32 - ICON IDI_IMPORT,IDC_STATIC,5,12,20,20 - LTEXT "Click ""Next"" to choose the information you wish to import, or click ""Cancel"" to exit the wizard and continue using Miranda.", - IDC_STATIC,33,49,182,25 - CTEXT "It is recommended that you create a backup of your current Miranda profile before importing.", - IDC_STATIC,30,81,182,21 -END - -IDD_FINISHED DIALOGEX 0, 0, 220, 114 -STYLE DS_SETFONT | DS_FIXEDSYS | DS_3DLOOK | DS_CONTROL | WS_CHILD -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "If you wish to import more information, click ""Next"" to return to the start of the wizard, otherwise click ""Finish"" to start using Miranda.", - IDC_STATIC,5,20,210,16 - LTEXT "You will probably never need to use this wizard again, so you can save memory by not loading it every time you start Miranda. This will mean that the import menu item will no longer be available.", - IDC_STATIC,5,41,210,24 - CONTROL "Do not load the import plugin at startup again", - IDC_DONTLOADPLUGIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, - 6,97,210,10 - LTEXT "Import completed",IDC_STATIC,5,7,210,8 - LTEXT "If at a future date you wish to use the wizard again, you can make it load again by going to the Plugins section of the Options dialog box.", - IDC_STATIC,5,69,210,24 -END - -IDD_MIRABILISDB DIALOGEX 0, 0, 220, 114 -STYLE DS_SETFONT | DS_FIXEDSYS | DS_3DLOOK | DS_CONTROL | WS_CHILD -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "Miranda has found Mirabilis ICQ databases corresponding to the following ICQ numbers. Please select the one you wish to import, or click ""Other Database"" if your database is not listed.", - IDC_STATIC,5,5,210,24 - LISTBOX IDC_LIST,5,31,210,36,LBS_SORT | LBS_NOINTEGRALHEIGHT | - WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "&Other Database...",IDC_OTHER,149,69,66,14 - RTEXT "&Filename:",IDC_STATIC,5,88,34,8 - EDITTEXT IDC_FILENAME,42,86,173,12,ES_AUTOHSCROLL - CTEXT "Warning: Mirabilis ICQ running. Import may not be reliable.", - IDC_MIRABILISRUNNING,5,101,210,8 - RTEXT "&Account:",IDC_STATIC,6,74,34,8 - COMBOBOX IDC_MIRABILISACCOUNT,42,71,102,30,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP -END - -IDD_MIRANDADB DIALOGEX 0, 0, 220, 114 -STYLE DS_SETFONT | DS_FIXEDSYS | DS_3DLOOK | DS_CONTROL | WS_CHILD -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "Miranda has found Miranda profiles with the following names. Please select the one you wish to import, or click ""Other Profile"" if your profile is not listed, or if the list is empty.", - IDC_STATIC,5,10,210,24 - LISTBOX IDC_LIST,5,36,210,36,LBS_SORT | LBS_NOINTEGRALHEIGHT | - WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "&Other Profile...",IDC_OTHER,149,74,66,14 - RTEXT "&Filename:",IDC_STATIC,5,93,34,8 - EDITTEXT IDC_FILENAME,41,91,174,12,ES_AUTOHSCROLL -END - -IDD_PROGRESS DIALOGEX 0, 0, 220, 114 -STYLE DS_SETFONT | DS_FIXEDSYS | DS_3DLOOK | DS_CONTROL | WS_CHILD -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "Now importing...",IDC_STATIC,5,11,62,8 - CONTROL "Progress1",IDC_PROGRESS,"msctls_progress32",PBS_SMOOTH | - WS_BORDER,5,24,210,10 - LISTBOX IDC_STATUS,5,38,210,61,NOT LBS_NOTIFY | - LBS_NOINTEGRALHEIGHT | LBS_DISABLENOSCROLL | LBS_NOSEL | - WS_VSCROLL | WS_TABSTOP -END - -IDD_WIZARD DIALOGEX 0, 0, 220, 143 -STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_CAPTION | WS_SYSMENU -CAPTION "Import Information Wizard" -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - DEFPUSHBUTTON "&Next >",IDOK,120,124,45,13 - PUSHBUTTON "Cancel",IDCANCEL,170,124,45,13 - PUSHBUTTON "< &Back",IDC_BACK,75,124,45,13 - CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,-7,115,234,1 -END - -IDD_OPTIONS DIALOGEX 0, 0, 220, 114 -STYLE DS_SETFONT | DS_FIXEDSYS | DS_3DLOOK | DS_CONTROL | WS_CHILD -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - CONTROL "Import all contacts and all messages",IDC_RADIO_ALL, - "Button",BS_AUTORADIOBUTTON | WS_TABSTOP | BS_LEFT | BS_TOP,7,10,206, - 11 - CONTROL "Only import contacts",IDC_RADIO_CONTACTS,"Button", - BS_AUTORADIOBUTTON | WS_TABSTOP,7,42,206,10 - CONTROL "Custom import",IDC_RADIO_CUSTOM,"Button", - BS_AUTORADIOBUTTON | WS_TABSTOP | WS_DISABLED,7,74,206,10 - LTEXT "Select this if you want to import as much data as possible. This is the recommended option.", - IDC_STATIC_ALL,26,20,187,16 - LTEXT "Select this if you want to import contacts but don't want to import any message history.", - IDC_STATIC_CONTACTS,26,52,187,16 - LTEXT "Select this if you want to customize what to import.", - IDC_STATIC_CUSTOM,26,84,187,16,WS_DISABLED -END - -IDD_ICQSERVER DIALOGEX 0, 0, 220, 114 -STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - LTEXT "Miranda has now been configured to automatically download the contacts in your server-side contact list the next time you connect to ICQ.", - IDC_STATIC,7,9,206,31 - LTEXT "If you want to change the way Miranda handles server-side contacts at a later time, you can do this in the ""ICQ Contacts"" page in the Miranda options.", - IDC_STATIC,7,44,206,37 -END - -IDD_ADVOPTIONS DIALOGEX 0, 0, 220, 114 -STYLE DS_SETFONT | DS_3DLOOK | DS_FIXEDSYS | DS_CONTROL | WS_CHILD -FONT 8, "MS Shell Dlg", 0, 0, 0x0 -BEGIN - CONTROL "New contacts && groups",IDC_CONTACTS,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,10,16,100,10 - CONTROL "System history",IDC_SYSTEM,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,120,16,98,10 - LTEXT "Select items to import:",IDC_ALL,10,3,201,10,SS_NOTIFY - CTEXT "Incoming",IDC_INCOMING,2,34,86,10,SS_NOTIFY - CTEXT "Outgoing",IDC_OUTGOING,132,34,86,10,SS_NOTIFY - CONTROL "",IDC_IN_MSG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,40, - 44,10,10 - CONTROL "",IDC_IN_URL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,40, - 56,10,10 - CONTROL "",IDC_IN_FT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,40,68, - 10,10 - CONTROL "",IDC_IN_OTHER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,40, - 80,10,10 - CONTROL "",IDC_OUT_MSG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,170, - 44,10,10 - CONTROL "",IDC_OUT_URL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,170, - 56,10,10 - CONTROL "",IDC_OUT_FT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,170, - 68,10,10 - CONTROL "",IDC_OUT_OTHER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, - 170,80,10,10 - CONTROL "Only since:",IDC_SINCE,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,10,99,100,10 - CONTROL "",IDC_DATETIMEPICKER,"SysDateTimePick32",DTS_RIGHTALIGN | - WS_DISABLED | WS_TABSTOP,120,97,81,15 - CTEXT "Messages",IDC_MSG,54,44,112,8,SS_NOTIFY - CTEXT "URLs",IDC_URL,54,56,112,8,SS_NOTIFY - CTEXT "File Transfers",IDC_FT,54,68,112,8,SS_NOTIFY - CTEXT "Other",IDC_OTHER,54,80,112,8,SS_NOTIFY - CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,0,93,222,1 - CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,0,31,223,1 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_IMPORTTYPE, DIALOG - BEGIN - LEFTMARGIN, 5 - RIGHTMARGIN, 215 - TOPMARGIN, 5 - BOTTOMMARGIN, 109 - END - - IDD_WIZARDINTRO, DIALOG - BEGIN - LEFTMARGIN, 5 - RIGHTMARGIN, 215 - TOPMARGIN, 5 - BOTTOMMARGIN, 109 - END - - IDD_FINISHED, DIALOG - BEGIN - LEFTMARGIN, 5 - RIGHTMARGIN, 215 - TOPMARGIN, 5 - BOTTOMMARGIN, 109 - END - - IDD_MIRABILISDB, DIALOG - BEGIN - LEFTMARGIN, 5 - RIGHTMARGIN, 215 - TOPMARGIN, 5 - BOTTOMMARGIN, 109 - END - - IDD_MIRANDADB, DIALOG - BEGIN - LEFTMARGIN, 3 - RIGHTMARGIN, 216 - TOPMARGIN, 1 - BOTTOMMARGIN, 113 - END - - IDD_PROGRESS, DIALOG - BEGIN - LEFTMARGIN, 5 - RIGHTMARGIN, 215 - TOPMARGIN, 5 - BOTTOMMARGIN, 109 - END - - IDD_WIZARD, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 215 - TOPMARGIN, 7 - BOTTOMMARGIN, 137 - END - - IDD_OPTIONS, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 213 - TOPMARGIN, 7 - BOTTOMMARGIN, 111 - END - - IDD_ICQSERVER, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 213 - TOPMARGIN, 7 - BOTTOMMARGIN, 107 - END - - IDD_ADVOPTIONS, DIALOG - BEGIN - VERTGUIDE, 10 - VERTGUIDE, 45 - VERTGUIDE, 110 - VERTGUIDE, 120 - VERTGUIDE, 175 - TOPMARGIN, 3 - HORZGUIDE, 16 - HORZGUIDE, 34 - HORZGUIDE, 104 - END -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,8,0,1 - PRODUCTVERSION 0,8,0,1 - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x1L - 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 Import Plugin" - VALUE "FileVersion", "0.8.0.1" - VALUE "InternalName", "import" - VALUE "LegalCopyright", "Copyright © 2000-2009, Martin Öberg, Richard Hughes, Dmitry Kuzkin, George Hazan" - VALUE "OriginalFilename", "import.dll" - VALUE "ProductName", "Miranda IM" - VALUE "ProductVersion", "0.8.0.1" - 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 diff --git a/plugins/Import/src/ICQserver.cpp b/plugins/Import/src/ICQserver.cpp new file mode 100644 index 0000000000..372c0cb92c --- /dev/null +++ b/plugins/Import/src/ICQserver.cpp @@ -0,0 +1,74 @@ +/* + +Import plugin for Miranda IM + +Copyright (C) 2001-2005 Martin Öberg, Richard Hughes, Roland Rabien & Tristan Van de Vreede + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +// ============== +// == INCLUDES == +// ============== + +#include "import.h" + +#include "ICQserver.h" +#include "resource.h" + +// ==================== +// ==================== +// == IMPLEMENTATION == +// ==================== +// ==================== + +BOOL CALLBACK ICQserverPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam) +{ + switch(message) { + case WM_INITDIALOG: + SendMessage(GetParent(hdlg),WIZM_DISABLEBUTTON,0,0); + SendMessage(GetParent(hdlg),WIZM_ENABLEBUTTON,1,0); + SendMessage(GetParent(hdlg),WIZM_DISABLEBUTTON,2,0); + TranslateDialogDefault(hdlg); + ICQserverImport(); + return TRUE; + + case WM_COMMAND: + switch(LOWORD(wParam)) { + case IDOK: + PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_FINISHED,(LPARAM)FinishedPageProc); + break; + case IDCANCEL: + PostMessage(GetParent(hdlg),WM_CLOSE,0,0); + break; + } + break; + } + return FALSE; +} + +static void ICQserverImport() +{ + // Clear last update stamp + DBDeleteContactSetting(NULL, szICQModuleName[ iICQAccount ], "SrvLastUpdate"); + DBDeleteContactSetting(NULL, szICQModuleName[ iICQAccount ], "SrvRecordCount"); + + // Enable contacts downloading + DBWriteContactSettingByte(NULL, szICQModuleName[ iICQAccount ], "UseServerCList", 1); + DBWriteContactSettingByte(NULL, szICQModuleName[ iICQAccount ], "AddServerNew", 1); + DBWriteContactSettingByte(NULL, szICQModuleName[ iICQAccount ], "UseServerNicks", 1); + DBWriteContactSettingByte(NULL, szICQModuleName[ iICQAccount ], "ServerAddRemove", 1); +} diff --git a/plugins/Import/src/ICQserver.h b/plugins/Import/src/ICQserver.h new file mode 100644 index 0000000000..864890a978 --- /dev/null +++ b/plugins/Import/src/ICQserver.h @@ -0,0 +1,62 @@ +/* + +Import plugin for Miranda IM + +Copyright (C) 2001,2002,2003,2004 Martin Öberg, Richard Hughes, Roland Rabien & Tristan Van de Vreede + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + + + +#ifndef ICQSERVER_H +#define ICQSERVER_H + +#include + +// ====================== +// == GLOBAL FUNCTIONS == +// ====================== + +// ===================== +// == LOCAL FUNCTIONS == +// ===================== + +// Main function +static void ICQserverImport(); + +// GUI callbacks +INT_PTR CALLBACK FinishedPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam); + + +// ====================== +// == GLOBAL VARIABLES == +// ====================== + +extern int cICQAccounts; +extern char ** szICQModuleName; +extern TCHAR ** tszICQAccountName; +extern int iICQAccount; + +// ===================== +// == LOCAL VARIABLES == +// ===================== + +// ============= +// == DEFINES == +// ============= + +#endif \ No newline at end of file diff --git a/plugins/Import/src/import.h b/plugins/Import/src/import.h new file mode 100644 index 0000000000..d0cb865c02 --- /dev/null +++ b/plugins/Import/src/import.h @@ -0,0 +1,108 @@ +/* + +Import plugin for Miranda IM + +Copyright (C) 2001,2002,2003,2004 Martin Öberg, Richard Hughes, Roland Rabien & Tristan Van de Vreede + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + + +//#define _LOGGING 1 + +#define _CRT_SECURE_NO_WARNINGS +#define _CRT_NONSTDC_NO_DEPRECATE + +#define MIRANDA_VER 0x0A00 + +#define WINVER 0x0501 +#define _WIN32_WINNT 0x0501 +#define _WIN32_IE 0x0501 + +#include + +#include +#include // datetimepicker + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// ** Global constants + +#define IMPORT_MODULE "MIMImport" // Module name +#define IMPORT_SERVICE "MIMImport/Import" // Service for menu item + +// Keys +#define IMP_KEY_FR "FirstRun" // First run + + +#define WIZM_GOTOPAGE (WM_USER+10) //wParam=resource id, lParam=dlgproc +#define WIZM_DISABLEBUTTON (WM_USER+11) //wParam=0:back, 1:next, 2:cancel +#define WIZM_SETCANCELTEXT (WM_USER+12) //lParam=(char*)newText +#define WIZM_ENABLEBUTTON (WM_USER+13) //wParam=0:back, 1:next, 2:cancel + +#define PROGM_SETPROGRESS (WM_USER+10) //wParam=0..100 +#define PROGM_ADDMESSAGE (WM_USER+11) //lParam=(char*)szText +#define SetProgress(n) SendMessage(hdlgProgress,PROGM_SETPROGRESS,n,0) + +#define ICQOSCPROTONAME "ICQ" +#define MSNPROTONAME "MSN" +#define YAHOOPROTONAME "YAHOO" +#define NSPPROTONAME "NET_SEND" +#define ICQCORPPROTONAME "ICQ Corp" +#define AIMPROTONAME "AIM" + +// Import type +#define IMPORT_CONTACTS 0 +#define IMPORT_ALL 1 +#define IMPORT_CUSTOM 2 + +// Custom import options +#define IOPT_ADDUNKNOWN 1 +#define IOPT_MSGSENT 2 +#define IOPT_MSGRECV 4 +#define IOPT_URLSENT 8 +#define IOPT_URLRECV 16 +#define IOPT_AUTHREQ 32 +#define IOPT_ADDED 64 +#define IOPT_FILESENT 128 +#define IOPT_FILERECV 256 +#define IOPT_OTHERSENT 512 +#define IOPT_OTHERRECV 1024 +#define IOPT_SYSTEM 2048 +#define IOPT_CONTACTS 4096 +#define IOPT_GROUPS 8192 + +void AddMessage( const char* fmt, ... ); + +int CreateGroup(BYTE type, const char* name, HANDLE hContact); + +extern HWND hdlgProgress; + +extern DWORD nDupes, nContactsCount, nMessagesCount, nGroupsCount, nSkippedEvents, nSkippedContacts; diff --git a/plugins/Import/src/main.cpp b/plugins/Import/src/main.cpp new file mode 100644 index 0000000000..8b7524c040 --- /dev/null +++ b/plugins/Import/src/main.cpp @@ -0,0 +1,543 @@ +/* + +Import plugin for Miranda IM + +Copyright (C) 2001-2005 Martin Öberg, Richard Hughes, Roland Rabien & Tristan Van de Vreede + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "import.h" +#include "version.h" +#include "resource.h" + +void FreeVariant( DBVARIANT* dbv ); +void WriteVariant( HANDLE hContact, const char* module, const char* var, DBVARIANT* dbv ); + +BOOL IsDuplicateEvent(HANDLE hContact, DBEVENTINFO dbei); + + +int nImportOption; +int nCustomOptions; + +int cICQAccounts = 0; +char ** szICQModuleName = NULL; +TCHAR ** tszICQAccountName = NULL; +int iICQAccount = 0; + +static HANDLE hHookModulesLoaded = NULL; +static HANDLE hHookOnExit = NULL; +static HANDLE hImportService = NULL; + + +INT_PTR CALLBACK WizardDlgProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam); + +HINSTANCE hInst; + +static HWND hwndWizard = NULL; +int hLangpack; + +PLUGININFOEX pluginInfo = { + sizeof(PLUGININFOEX), + "Import contacts and messages", + __VERSION_DWORD, + "Imports contacts and messages from Mirabilis ICQ and Miranda IM.", + "Miranda team", + "info@miranda-im.org", + "© 2000-2010 Martin Öberg, Richard Hughes, Dmitry Kuzkin, George Hazan", + "http://www.miranda-im.org", + UNICODE_AWARE, //{2D77A746-00A6-4343-BFC5-F808CDD772EA} + {0x2d77a746, 0xa6, 0x4343, { 0xbf, 0xc5, 0xf8, 0x8, 0xcd, 0xd7, 0x72, 0xea }} +}; + +BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved) +{ + hInst = hinstDLL; + return TRUE; +} + +static INT_PTR ImportCommand(WPARAM wParam,LPARAM lParam) +{ + if (IsWindow(hwndWizard)) { + SetForegroundWindow(hwndWizard); + SetFocus(hwndWizard); + } + else hwndWizard = CreateDialog(hInst, MAKEINTRESOURCE(IDD_WIZARD), NULL, WizardDlgProc); + + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// MirandaPluginInfoEx - returns an information about a plugin + +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + return &pluginInfo; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// MirandaInterfaces - returns the protocol interface to the core + +extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = {MIID_IMPORT, MIID_LAST}; + +///////////////////////////////////////////////////////////////////////////////////////// +// Performs a primary set of actions upon plugin loading + +static int ModulesLoaded(WPARAM wParam, LPARAM lParam) +{ + int nProtocols = 0; + int n; + PROTOCOLDESCRIPTOR **ppProtos = NULL; + + if (DBGetContactSettingByte(NULL, IMPORT_MODULE, IMP_KEY_FR, 0)) + return 0; + + // Only autorun import wizard if at least one protocol is installed + CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&nProtocols, (LPARAM)&ppProtos); + for (n=0; n < nProtocols; n++) { + if (ppProtos[n]->type == PROTOTYPE_PROTOCOL) { + CallService(IMPORT_SERVICE, 0, 0); + DBWriteContactSettingByte(NULL, IMPORT_MODULE, IMP_KEY_FR, 1); + break; + } } + return 0; +} + +static int OnExit(WPARAM wParam, LPARAM lParam) +{ + if ( hwndWizard ) + SendMessage(hwndWizard, WM_CLOSE, 0, 0); + return 0; +} + +extern "C" __declspec(dllexport) int Load(void) +{ + mir_getLP( &pluginInfo ); + + hImportService = CreateServiceFunction(IMPORT_SERVICE, ImportCommand); + { + CLISTMENUITEM mi; + ZeroMemory(&mi, sizeof(mi)); + mi.cbSize = sizeof(mi); + mi.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_IMPORT)); + mi.pszName = LPGEN("&Import..."); + mi.position = 500050000; + mi.pszService = IMPORT_SERVICE; + Menu_AddMainMenuItem(&mi); + } + hHookModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoaded); + hHookOnExit = HookEvent(ME_SYSTEM_OKTOEXIT, OnExit); + { + INITCOMMONCONTROLSEX icex; + icex.dwSize = sizeof(icex); + icex.dwICC = ICC_DATE_CLASSES; + InitCommonControlsEx(&icex); + } + + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Unload a plugin + +extern "C" __declspec(dllexport) int Unload(void) +{ + if (hHookModulesLoaded) + UnhookEvent(hHookModulesLoaded); + if (hHookOnExit) + UnhookEvent(hHookOnExit); + if (hImportService) + DestroyServiceFunction(hImportService); + + return 0; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +BOOL IsProtocolLoaded(char* pszProtocolName) +{ + return CallService(MS_PROTO_ISPROTOCOLLOADED, 0, (LPARAM)pszProtocolName) ? TRUE : FALSE; +} + +BOOL EnumICQAccounts() +{ + int count, i = 0; + PROTOACCOUNT ** accs; + + while (cICQAccounts) + { + cICQAccounts--; + free(szICQModuleName[cICQAccounts]); + free(tszICQAccountName[cICQAccounts]); + } + + ProtoEnumAccounts(&count, &accs); + szICQModuleName = (char**)realloc(szICQModuleName, count * sizeof(char**)); + tszICQAccountName = (TCHAR**)realloc(tszICQAccountName, count * sizeof(TCHAR**)); + while (i < count) + { + if ((0 == strcmp(ICQOSCPROTONAME, accs[i]->szProtoName)) && accs[i]->bIsEnabled) + { + szICQModuleName[cICQAccounts] = strdup(accs[i]->szModuleName); + tszICQAccountName[cICQAccounts] = _tcsdup(accs[i]->tszAccountName); + cICQAccounts++; + } + i++; + } + return cICQAccounts != 0; +} + +void FreeICQAccountsList() +{ + while (cICQAccounts) + { + cICQAccounts--; + free(szICQModuleName[cICQAccounts]); + free(tszICQAccountName[cICQAccounts]); + } + + if (szICQModuleName) + free(szICQModuleName); + if (tszICQAccountName) + free(tszICQAccountName); + + szICQModuleName = NULL; + tszICQAccountName = NULL; +} + +HANDLE HContactFromNumericID(char* pszProtoName, char* pszSetting, DWORD dwID) +{ + char* szProto; + HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + while (hContact != NULL) + { + if (DBGetContactSettingDword(hContact, pszProtoName, pszSetting, 0) == dwID) + { + szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + if (szProto != NULL && !strcmp(szProto, pszProtoName)) + return hContact; + } + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); + } + return INVALID_HANDLE_VALUE; +} + +HANDLE HContactFromID(char* pszProtoName, char* pszSetting, char* pszID) +{ + DBVARIANT dbv; + HANDLE hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + while (hContact != NULL) { + char* szProto = (char*)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + if ( !lstrcmpA(szProto, pszProtoName)) { + if (DBGetContactSettingString(hContact, pszProtoName, pszSetting, &dbv) == 0) { + if (strcmp(pszID, dbv.pszVal) == 0) { + DBFreeVariant(&dbv); + return hContact; + } + DBFreeVariant(&dbv); + } + } + + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0); + } + return INVALID_HANDLE_VALUE; +} + +HANDLE HistoryImportFindContact(HWND hdlgProgress, char* szModuleName, DWORD uin, int addUnknown) +{ + HANDLE hContact = HContactFromNumericID(szModuleName, "UIN", uin); + if (hContact == NULL) { + AddMessage( LPGEN("Ignored event from/to self")); + return INVALID_HANDLE_VALUE; + } + + if (hContact != INVALID_HANDLE_VALUE) + return hContact; + + if (!addUnknown) + return INVALID_HANDLE_VALUE; + + hContact = (HANDLE)CallService(MS_DB_CONTACT_ADD, 0, 0); + CallService(MS_PROTO_ADDTOCONTACT, (WPARAM)hContact, (LPARAM)szModuleName); + DBWriteContactSettingDword(hContact, szModuleName, "UIN", uin); + AddMessage( LPGEN("Added contact %u (found in history)"), uin ); + return hContact; +} + +HANDLE AddContact(HWND hdlgProgress, char* pszProtoName, char* pszUniqueSetting, + DBVARIANT* id, DBVARIANT* nick, DBVARIANT* group) +{ + HANDLE hContact; + char szid[ 40 ]; + char* pszUserID = ( id->type == DBVT_DWORD ) ? _ltoa( id->dVal, szid, 10 ) : id->pszVal; + + 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); + AddMessage( LPGEN("Failed to add %s contact %s"), pszProtoName, pszUserID ); + FreeVariant( id ); + FreeVariant( nick ); + FreeVariant( group ); + return INVALID_HANDLE_VALUE; + } + + WriteVariant( hContact, pszProtoName, pszUniqueSetting, id ); + + if ( group->type ) + CreateGroup( group->type, group->pszVal, hContact ); + + if ( nick->type && nick->pszVal[0] ) { + WriteVariant( hContact, "CList", "MyHandle", nick ); + if (nick->type == DBVT_UTF8) { + char *tmp = mir_utf8decodeA(nick->pszVal); + AddMessage( LPGEN("Added %s contact %s, '%s'"), pszProtoName, pszUserID, tmp ); + mir_free(tmp); + } + else AddMessage( LPGEN("Added %s contact %s, '%s'"), pszProtoName, pszUserID, nick->pszVal ); + } + else AddMessage( LPGEN("Added %s contact %s"), pszProtoName, pszUserID ); + + FreeVariant( id ); + FreeVariant( nick ); + FreeVariant( group ); + return hContact; +} + +// ------------------------------------------------ +// Creates a group with a specified name in the +// Miranda contact list. +// If contact is specified adds it to group +// ------------------------------------------------ +// Returns 1 if successful and 0 when it fails. +int CreateGroup(BYTE type, const char* name, HANDLE hContact) +{ + int groupId; + TCHAR *tmp, *tszGrpName; + char groupIdStr[11]; + size_t cbName; + + if (type == DBVT_UTF8) + tmp = mir_utf8decodeT( name ); + else if (type == DBVT_WCHAR) + tmp = mir_u2t(( wchar_t* )name ); + else + tmp = mir_a2t( name ); + + if ( tmp == NULL ) + return 0; + + cbName = _tcslen(tmp); + tszGrpName = (TCHAR*)_alloca(( cbName+2 )*sizeof( TCHAR )); + tszGrpName[0] = 1 | GROUPF_EXPANDED; + _tcscpy( tszGrpName+1, tmp ); + mir_free( tmp ); + + // Check for duplicate & find unused id + for (groupId = 0; ; groupId++) { + DBVARIANT dbv; + itoa(groupId, groupIdStr,10); + if (DBGetContactSettingTString(NULL, "CListGroups", groupIdStr, &dbv)) + break; + + if ( !lstrcmp(dbv.ptszVal + 1, tszGrpName + 1 )) { + if (hContact) + DBWriteContactSettingTString( hContact, "CList", "Group", tszGrpName+1 ); + else { + char *str = mir_t2a(tszGrpName + 1); + AddMessage( LPGEN("Skipping duplicate group %s."), str); + mir_free(str); + } + + DBFreeVariant(&dbv); + return 0; + } + + DBFreeVariant(&dbv); + } + + DBWriteContactSettingTString( NULL, "CListGroups", groupIdStr, tszGrpName ); + + if (hContact) + DBWriteContactSettingTString( hContact, "CList", "Group", tszGrpName+1 ); + + return 1; +} + +// Returns TRUE if the event already exist in the database +BOOL IsDuplicateEvent(HANDLE hContact, DBEVENTINFO dbei) +{ + static DWORD dwPreviousTimeStamp = -1; + static HANDLE hPreviousContact = INVALID_HANDLE_VALUE; + static HANDLE hPreviousDbEvent = NULL; + + HANDLE hExistingDbEvent; + DWORD dwEventTimeStamp; + DBEVENTINFO dbeiExisting; + + // get last event + if (!(hExistingDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDLAST, (WPARAM)hContact, 0))) + return FALSE; + + ZeroMemory(&dbeiExisting, sizeof(dbeiExisting)); + dbeiExisting.cbSize = sizeof(dbeiExisting); + CallService(MS_DB_EVENT_GET, (WPARAM)hExistingDbEvent, (LPARAM)&dbeiExisting); + dwEventTimeStamp = dbeiExisting.timestamp; + + // compare with last timestamp + if (dbei.timestamp > dwEventTimeStamp) + { + // remember event + hPreviousDbEvent = hExistingDbEvent; + dwPreviousTimeStamp = dwEventTimeStamp; + return FALSE; + } + + if (hContact != hPreviousContact) + { + hPreviousContact = hContact; + // remember event + hPreviousDbEvent = hExistingDbEvent; + dwPreviousTimeStamp = dwEventTimeStamp; + + // get first event + if (!(hExistingDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDFIRST, (WPARAM)hContact, 0))) + return FALSE; + + ZeroMemory(&dbeiExisting, sizeof(dbeiExisting)); + dbeiExisting.cbSize = sizeof(dbeiExisting); + CallService(MS_DB_EVENT_GET, (WPARAM)hExistingDbEvent, (LPARAM)&dbeiExisting); + dwEventTimeStamp = dbeiExisting.timestamp; + + // compare with first timestamp + if (dbei.timestamp <= dwEventTimeStamp) + { + // remember event + dwPreviousTimeStamp = dwEventTimeStamp; + hPreviousDbEvent = hExistingDbEvent; + + if ( dbei.timestamp != dwEventTimeStamp ) + return FALSE; + } + + } + // check for equal timestamps + if (dbei.timestamp == dwPreviousTimeStamp) + { + ZeroMemory(&dbeiExisting, sizeof(dbeiExisting)); + dbeiExisting.cbSize = sizeof(dbeiExisting); + CallService(MS_DB_EVENT_GET, (WPARAM)hPreviousDbEvent, (LPARAM)&dbeiExisting); + + if ((dbei.timestamp == dbeiExisting.timestamp) && + (dbei.eventType == dbeiExisting.eventType) && + (dbei.cbBlob == dbeiExisting.cbBlob) && + ((dbei.flags&DBEF_SENT) == (dbeiExisting.flags&DBEF_SENT))) + return TRUE; + + // find event with another timestamp + hExistingDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDNEXT, (WPARAM)hPreviousDbEvent, 0); + while (hExistingDbEvent != NULL) + { + ZeroMemory(&dbeiExisting, sizeof(dbeiExisting)); + dbeiExisting.cbSize = sizeof(dbeiExisting); + CallService(MS_DB_EVENT_GET, (WPARAM)hExistingDbEvent, (LPARAM)&dbeiExisting); + + if (dbeiExisting.timestamp != dwPreviousTimeStamp) + { + // use found event + hPreviousDbEvent = hExistingDbEvent; + dwPreviousTimeStamp = dbeiExisting.timestamp; + break; + } + + hPreviousDbEvent = hExistingDbEvent; + hExistingDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDNEXT, (WPARAM)hExistingDbEvent, 0); + } + } + + hExistingDbEvent = hPreviousDbEvent; + + if (dbei.timestamp <= dwPreviousTimeStamp) + { + // look back + while (hExistingDbEvent != NULL) + { + ZeroMemory(&dbeiExisting, sizeof(dbeiExisting)); + dbeiExisting.cbSize = sizeof(dbeiExisting); + CallService(MS_DB_EVENT_GET, (WPARAM)hExistingDbEvent, (LPARAM)&dbeiExisting); + + if (dbei.timestamp > dbeiExisting.timestamp) + { + // remember event + hPreviousDbEvent = hExistingDbEvent; + dwPreviousTimeStamp = dbeiExisting.timestamp; + return FALSE; + } + + // Compare event with import candidate + if ((dbei.timestamp == dbeiExisting.timestamp) && + (dbei.eventType == dbeiExisting.eventType) && + (dbei.cbBlob == dbeiExisting.cbBlob) && + ((dbei.flags&DBEF_SENT) == (dbeiExisting.flags&DBEF_SENT))) + { + // remember event + hPreviousDbEvent = hExistingDbEvent; + dwPreviousTimeStamp = dbeiExisting.timestamp; + return TRUE; + } + + // Get previous event in chain + hExistingDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDPREV, (WPARAM)hExistingDbEvent, 0); + } + + } + else + { + // look forward + while (hExistingDbEvent != NULL) + { + ZeroMemory(&dbeiExisting, sizeof(dbeiExisting)); + dbeiExisting.cbSize = sizeof(dbeiExisting); + CallService(MS_DB_EVENT_GET, (WPARAM)hExistingDbEvent, (LPARAM)&dbeiExisting); + + if (dbei.timestamp < dbeiExisting.timestamp) + { + // remember event + hPreviousDbEvent = hExistingDbEvent; + dwPreviousTimeStamp = dbeiExisting.timestamp; + return FALSE; + } + + // Compare event with import candidate + if ((dbei.timestamp == dbeiExisting.timestamp) && + (dbei.eventType == dbeiExisting.eventType) && + (dbei.cbBlob == dbeiExisting.cbBlob) && + ((dbei.flags&DBEF_SENT) == (dbeiExisting.flags&DBEF_SENT))) + { + // remember event + hPreviousDbEvent = hExistingDbEvent; + dwPreviousTimeStamp = dbeiExisting.timestamp; + return TRUE; + } + + // Get next event in chain + hExistingDbEvent = (HANDLE)CallService(MS_DB_EVENT_FINDNEXT, (WPARAM)hExistingDbEvent, 0); + } + + } + // reset last event + hPreviousContact = INVALID_HANDLE_VALUE; + return FALSE; +} diff --git a/plugins/Import/src/mirabilis.cpp b/plugins/Import/src/mirabilis.cpp new file mode 100644 index 0000000000..1f032827af --- /dev/null +++ b/plugins/Import/src/mirabilis.cpp @@ -0,0 +1,1493 @@ +/* + +Import plugin for Miranda IM + +Copyright (C) 2001-2005 Martin Öberg, Richard Hughes, Roland Rabien & Tristan Van de Vreede + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +// ============== +// == INCLUDES == +// ============== + +#include "import.h" +#include "mirabilis.h" +#include "resource.h" + +BOOL IsDuplicateEvent(HANDLE hContact, DBEVENTINFO dbei); +BOOL IsProtocolLoaded(char* pszProtocolName); +HANDLE HContactFromNumericID(char* pszProtoName, char* pszSetting, DWORD dwID); +HANDLE AddContact(HWND hdlgProgress, char* pszProtoName, char* pszUniqueSetting, DBVARIANT* id, DBVARIANT* nick, DBVARIANT* group); + +// ==================== +// ==================== +// == IMPLEMENTATION == +// ==================== +// ==================== + +static void SearchForDatabases(HWND hdlg, const TCHAR *dbPath, const TCHAR *type) +{ + HANDLE hFind; + WIN32_FIND_DATA fd; + TCHAR szSearchPath[MAX_PATH]; + TCHAR szRootName[MAX_PATH],*str2; + + int i; + + wsprintf(szSearchPath, _T("%s\\*.idx"), dbPath); + hFind=FindFirstFile(szSearchPath,&fd); + if(hFind!=INVALID_HANDLE_VALUE) { + do { + lstrcpy(szRootName,fd.cFileName); + str2=_tcsrchr(szRootName,'.'); + if(str2!=NULL) *str2=0; + if(lstrlen(szRootName)>3 && !lstrcmpi(szRootName+lstrlen(szRootName)-3,_T("tmp"))) + continue; + lstrcat(szRootName,type); + i=SendDlgItemMessage(hdlg,IDC_LIST,LB_ADDSTRING,0,(LPARAM)szRootName); + str2 = (TCHAR*)mir_alloc((lstrlen(dbPath) + 2+lstrlen(fd.cFileName))*sizeof(TCHAR)); + wsprintf(str2, _T("%s\\%s"), dbPath, fd.cFileName); + SendDlgItemMessage(hdlg,IDC_LIST,LB_SETITEMDATA,i,(LPARAM)str2); + } + while( FindNextFile( hFind, &fd )); + + FindClose(hFind); + } +} + +INT_PTR CALLBACK MirabilisPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam) +{ + switch(message) { + case WM_INITDIALOG: + { + HKEY hKey; + LONG lResult; + int i; + TranslateDialogDefault(hdlg); + if (ERROR_SUCCESS != (lResult = RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software\\Mirabilis\\ICQ\\DefaultPrefs"), 0, KEY_QUERY_VALUE, &hKey))) + lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\Mirabilis\\ICQ\\DefaultPrefs"), 0, KEY_QUERY_VALUE, &hKey); + + if (lResult == ERROR_SUCCESS) { + TCHAR dbPath[MAX_PATH]; + DWORD cch; + cch=sizeof(dbPath); + if(ERROR_SUCCESS==RegQueryValueEx(hKey,_T("New Database"),NULL,NULL,(LPBYTE)dbPath,&cch)) + SearchForDatabases(hdlg,dbPath,_T(" (99a)")); + cch=sizeof(dbPath); + if(ERROR_SUCCESS==RegQueryValueEx(hKey,_T("99b Database"),NULL,NULL,(LPBYTE)dbPath,&cch)) + SearchForDatabases(hdlg,dbPath,_T(" (99b)")); + cch=sizeof(dbPath); + if(ERROR_SUCCESS==RegQueryValueEx(hKey,_T("2000a Database"),NULL,NULL,(LPBYTE)dbPath,&cch)) + SearchForDatabases(hdlg,dbPath,_T(" (2000a)")); + cch=sizeof(dbPath); + if(ERROR_SUCCESS==RegQueryValueEx(hKey,_T("2000b Database"),NULL,NULL,(LPBYTE)dbPath,&cch)) + SearchForDatabases(hdlg,dbPath,_T(" (2000b)")); + cch=sizeof(dbPath); + if(ERROR_SUCCESS==RegQueryValueEx(hKey,_T("2001a Database"),NULL,NULL,(LPBYTE)dbPath,&cch)) + SearchForDatabases(hdlg,dbPath,_T(" (2001a)")); + cch=sizeof(dbPath); + if(ERROR_SUCCESS==RegQueryValueEx(hKey,_T("2001b Database"),NULL,NULL,(LPBYTE)dbPath,&cch)) + SearchForDatabases(hdlg,dbPath,_T(" (2001b)")); + cch=sizeof(dbPath); + if(ERROR_SUCCESS==RegQueryValueEx(hKey,_T("2002a Database"),NULL,NULL,(LPBYTE)dbPath,&cch)) + SearchForDatabases(hdlg,dbPath,_T(" (2002a)")); + cch=sizeof(dbPath); + if(ERROR_SUCCESS==RegQueryValueEx(hKey,_T("2003a Database"),NULL,NULL,(LPBYTE)dbPath,&cch)) + SearchForDatabases(hdlg,dbPath,_T(" (2003a)")); + } + + for (i = 0; i < cICQAccounts; i++) + { + SendDlgItemMessage(hdlg, IDC_MIRABILISACCOUNT, CB_ADDSTRING, 0, (LPARAM)tszICQAccountName[i]); + } + SendDlgItemMessage(hdlg, IDC_MIRABILISACCOUNT, CB_SETCURSEL, 0, 0); + + SetTimer(hdlg,1,2000,NULL); + SendMessage(hdlg,WM_TIMER,0,0); + return TRUE; + } + case WM_TIMER: + { HANDLE hMirabilisMutex; + hMirabilisMutex=OpenMutexA(MUTEX_ALL_ACCESS,FALSE,"Mirabilis ICQ Mutex"); + if(hMirabilisMutex!=NULL) { + CloseHandle(hMirabilisMutex); + ShowWindow(GetDlgItem(hdlg,IDC_MIRABILISRUNNING),SW_SHOW); + } + else ShowWindow(GetDlgItem(hdlg,IDC_MIRABILISRUNNING),SW_HIDE); + } + break; + case WM_COMMAND: + switch(LOWORD(wParam)) { + case IDC_BACK: + PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_IMPORTTYPE,(LPARAM)ImportTypePageProc); + break; + case IDOK: + { TCHAR filename[MAX_PATH]; + GetDlgItemText(hdlg,IDC_FILENAME,filename,SIZEOF(filename)); + if(_taccess(filename,4)) { + MessageBox(hdlg,TranslateT("The given file does not exist. Please check that you have entered the name correctly."),TranslateT("Mirabilis Import"),MB_OK); + break; + } + lstrcpy(importFile,filename); + iICQAccount = SendDlgItemMessage(hdlg, IDC_MIRABILISACCOUNT, CB_GETCURSEL, 0, 0); + PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_OPTIONS,(LPARAM)MirabilisOptionsPageProc); + break; + } + case IDCANCEL: + PostMessage(GetParent(hdlg),WM_CLOSE,0,0); + break; + case IDC_LIST: + if(HIWORD(wParam)==LBN_SELCHANGE) { + int sel=SendDlgItemMessage(hdlg,IDC_LIST,LB_GETCURSEL,0,0); + if(sel==LB_ERR) break; + SetDlgItemText(hdlg,IDC_FILENAME,(TCHAR*)SendDlgItemMessage(hdlg,IDC_LIST,LB_GETITEMDATA,sel,0)); + } + break; + case IDC_OTHER: + { OPENFILENAME ofn; + TCHAR str[MAX_PATH], text[256]; + int index; + + // TranslateTS doesnt translate \0 separated strings + index = mir_sntprintf(text, 64, _T("%s (*.idx)"), TranslateT("Mirabilis ICQ database indexes")) + 1; + _tcscpy(text + index, _T("*.idx")); index += 6; + index += mir_sntprintf(text + index, 64, _T("%s (*.*)"), TranslateT("All Files")) + 1; + _tcscpy(text + index, _T("*.*")); index += 4; + text[index] = 0; + + GetDlgItemText(hdlg,IDC_FILENAME,str,SIZEOF(str)); + ZeroMemory(&ofn, sizeof(ofn)); + ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; + ofn.hwndOwner = hdlg; + ofn.lpstrFilter = text; + ofn.lpstrFile = str; + ofn.Flags = OFN_FILEMUSTEXIST | OFN_EXPLORER | OFN_NOCHANGEDIR | OFN_DONTADDTORECENT; + ofn.nMaxFile = SIZEOF(str); + ofn.lpstrDefExt = _T("idx"); + if(GetOpenFileName(&ofn)) + SetDlgItemText(hdlg,IDC_FILENAME,str); + break; + } + } + break; + + case WM_DESTROY: + { int i; + for(i=SendDlgItemMessage(hdlg,IDC_LIST,LB_GETCOUNT,0,0)-1;i>=0;i--) + mir_free((char*)SendDlgItemMessage(hdlg,IDC_LIST,LB_GETITEMDATA,i,0)); + break; + } + } + return FALSE; +} + + +INT_PTR CALLBACK MirabilisOptionsPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam) +{ + switch(message) { + case WM_INITDIALOG: + TranslateDialogDefault(hdlg); + EnableWindow(GetDlgItem(hdlg, IDC_RADIO_ALL), TRUE); + EnableWindow(GetDlgItem(hdlg, IDC_STATIC_ALL), TRUE); + EnableWindow(GetDlgItem(hdlg, IDC_RADIO_CONTACTS), TRUE); + EnableWindow(GetDlgItem(hdlg, IDC_STATIC_CONTACTS), TRUE); + CheckDlgButton(hdlg, IDC_RADIO_ALL, BST_CHECKED); + return TRUE; + + case WM_COMMAND: + switch(LOWORD(wParam)) { + case IDC_BACK: + PostMessage(GetParent(hdlg), WIZM_GOTOPAGE, IDD_MIRABILISDB, (LPARAM)MirabilisPageProc); + break; + case IDOK: + if (IsDlgButtonChecked(hdlg, IDC_RADIO_ALL)) { + DoImport = MirabilisImport; + nImportOption = IMPORT_ALL; + nCustomOptions = IOPT_MSGSENT|IOPT_MSGRECV|IOPT_URLSENT|IOPT_URLRECV; + PostMessage(GetParent(hdlg), WIZM_GOTOPAGE, IDD_PROGRESS, (LPARAM)ProgressPageProc); + break; + } + if (IsDlgButtonChecked(hdlg, IDC_RADIO_CONTACTS)) { + DoImport = MirabilisImport; + nImportOption = IMPORT_CONTACTS; + nCustomOptions = 0; + PostMessage(GetParent(hdlg), WIZM_GOTOPAGE, IDD_PROGRESS, (LPARAM)ProgressPageProc); + break; + } + break; + case IDCANCEL: + PostMessage(GetParent(hdlg), WM_CLOSE, 0, 0); + break; + } + break; + } + + return FALSE; +} + +static int GetHighestIndexEntry(void) +{ + struct TIdxIndexEntry *entry; + DWORD ofs; + + ofs=*(PDWORD)(pIdx+12); + for (;;) { + entry=(struct TIdxIndexEntry*)(pIdx+ofs); + if(entry->entryIdLow==(DWORD)-2) return ((struct TIdxDatEntry*)entry)->entryId; + if(entry->ofsHigher>=0xF0000000) ofs=entry->ofsInHere; + else ofs=entry->ofsHigher; + } +} + +static int GetIdDatOfs(DWORD id) +{ + struct TIdxIndexEntry *entry; + DWORD ofs = *(PDWORD)(pIdx+12); + for (;;) { + entry=(struct TIdxIndexEntry*)(pIdx+ofs); + if(entry->entryIdLow==(DWORD)-2) { + if(entry->entryIdHigh==id) return ((struct TIdxDatEntry*)entry)->datOfs; + return 0; + } + if(identryIdLow) ofs=entry->ofsLower; + else if(entry->ofsHigher<0xF0000000 && id>=entry->entryIdHigh) ofs=entry->ofsHigher; + else ofs=entry->ofsInHere; + } + return 0; +} + +static int GetDatEntryType(DWORD ofs) +{ + return *(int*)(pDat+ofs+4); +} + +DWORD GetDBVersion() +{ + dwDBVersion = *(PDWORD)(pIdx+16); + + switch (dwDBVersion) { + case DBV99A: + AddMessage( LPGEN("This looks like a ICQ 99a database.")); + break; + case DBV99B: + AddMessage( LPGEN("This looks like a ICQ 99b database.")); + break; + case DBV2000A: + AddMessage( LPGEN("This looks like a ICQ 2000a database.")); + break; + case DBV2000B: + AddMessage( LPGEN("This looks like a ICQ 2000b database.")); + break; + case DBV2001A: + AddMessage( LPGEN("This looks like a ICQ 2001, 2002 or 2003a database.")); + break; + default: + AddMessage( LPGEN("This database is an unknown version.")); + return 0; + } + + return dwDBVersion; +} + +int GetEntryVersion(WORD wSeparatorValue) +{ + int nVersion; + + if (wSeparatorValue < ENTRYV99A) + nVersion = 0; // Cannot handle ICQ98 contacts + else if ((wSeparatorValue >= ENTRYV99A) && (wSeparatorValue < ENTRYV99B)) + nVersion = ENTRYV99A; + else if ((wSeparatorValue >= ENTRYV99B) && (wSeparatorValue < ENTRYV2000A)) + nVersion = ENTRYV99B; + else if ((wSeparatorValue >= ENTRYV2000A) && (wSeparatorValue < ENTRYV2000B)) + nVersion = ENTRYV2000A; + else if ((wSeparatorValue >= ENTRYV2000B) && (wSeparatorValue < ENTRYV2001A)) + nVersion = ENTRYV2000B; + else if ((wSeparatorValue >= ENTRYV2001A) && (wSeparatorValue < ENTRYV2001B)) + nVersion = ENTRYV2001A; + else if ((wSeparatorValue >= ENTRYV2001B) && (wSeparatorValue < ENTRYV2002A)) + nVersion = ENTRYV2001B; + else if (wSeparatorValue >= ENTRYV2002A) + nVersion = ENTRYV2002A; + else + nVersion = ENTRYVUNKNOWN; // Just in case... Skip undocumented contact versions + + return nVersion; +} + +DWORD ReadSubList(DWORD dwOffset) +{ + DWORD dwSubType, dwProperties, n; + + #ifdef _LOGGING + AddMessage( LPGEN("Attempting to parse sub list at offset %u."), dwOffset); + #endif + + // Check number of properties in sub list + dwProperties = *(PDWORD)(pDat+dwOffset); + dwOffset+=4; + + // Check sub list type + dwSubType = *(PBYTE)(pDat+dwOffset); + dwOffset+=1; + + switch (dwSubType){ + case 0x6B: + for(n=0;n 1) + return 6 + (char*)(pDat + dwOffset); + + break; + } + else + // Skip to next group + dwOffset += *(PWORD)(pDat + dwOffset + 4) + 12; + } + break; + + case DBV2000A: + case DBV2000B: + case DBV2001A: + for (n = 0; n < dwGroups; n++) { + if (tmpOfs = ReadPropertyBlock(dwOffset, "GroupID", &nSearchResult)) { + if (nSearchResult) { + if (dwGroupID == *(PDWORD)(pDat + tmpOfs + 1)) { + strGroupName = 3 + (char*)(pDat + ReadPropertyBlock(dwOffset, "GroupName", &nSearchResult)); + if (nSearchResult) { + if ((DWORD)*(strGroupName - 2) > 1) + return strGroupName; + break; + } } } } + + // Skip to next group + if ( dwOffset != ReadPropertyBlock(dwOffset, NULL, NULL)) + break; + } + break; + } + + // The GroupID was not found, or it was found + // but the group did not have a name, or there + // was an error during parsing. + return 0; +} + +// ------------------------------------------------ +// Scans a group list and adds all found groups to +// the Miranda contact list +// ------------------------------------------------ +// dwOffset must point to the number of entries in +// the following group list. +// Returns the number of added groups, or -1 if an error +// occurred + +int ImportGroups() +{ + DWORD dwGroups, n, tmpOfs, dwOffset; + int nImported = 0; + int nSearchResult, nFormat; + WORD wSeparatorValue; + + if (!(dwOffset = FindMyDetails())) { + AddMessage( LPGEN("ERROR: Failed to find owner information.")); + return -1; + } + + wSeparatorValue = *(PWORD)(pDat + dwOffset + 0x1c); + nFormat = GetEntryVersion(wSeparatorValue); + + dwGroupListOfs = dwOffset = FindGroupList(dwOffset); + if (!dwOffset) { + AddMessage( LPGEN("ERROR: Failed to find contact list groups.")); + #ifdef _LOGGING + { // If this is a debug build, dump MyDetails block to disk + FILE *stream; + DWORD dwSize; + dwOffset = FindMyDetails(); + dwSize = *(PDWORD)(pDat + dwOffset); + stream = fopen("import_grouplist_dump.bin", "w"); + fwrite(pDat + dwOffset, 1, dwSize, stream); + fclose(stream); + } + #endif + return -1; + } + + // Check number of groups + dwGroups = *(PDWORD)(pDat + dwOffset); + if (dwGroups > 0) + AddMessage( LPGEN("Importing groups.")); + else { + AddMessage( LPGEN("This database does not contain any contact groups.")); + return 0; + } + + dwOffset += 4; + + // Import all groups with a name + switch (nFormat) { + case ENTRYV99A: + case ENTRYV99B: + for (n = 0; n < dwGroups; n++) { + if (*(PWORD)(pDat+dwOffset+4) > 1) { + if ( CreateGroup(DBVT_ASCIIZ, (char*)(pDat + dwOffset) + 6, NULL )) + nImported++; + dwOffset += *(PWORD)(pDat + dwOffset + 4) + 12; + } } + break; + + case ENTRYV2000A: + case ENTRYV2000B: + case ENTRYV2001A: + case ENTRYV2001B: + case ENTRYV2002A: + for (n = 0; n < dwGroups; n++) { + if (tmpOfs = ReadPropertyBlock(dwOffset, "GroupName", &nSearchResult)) { + if (nSearchResult) { + if (CreateGroup( DBVT_ASCIIZ, (char*)(pDat + tmpOfs + 3), NULL )) + nImported++; + } } + + dwOffset = ReadPropertyBlock(dwOffset, NULL, NULL); + if (!dwOffset) { + AddMessage( LPGEN("ERROR: An error occurred while importing groups.")); + AddMessage( LPGEN("All groups may not have not been imported.")); + #ifdef _LOGGING + { // If this is a debug build, dump MyDetails block to disk + FILE *stream; + DWORD dwSize; + dwOffset = FindMyDetails(); + dwSize = *(PDWORD)(pDat + dwOffset); + stream = fopen("import_grouplist_dump.bin", "w"); + fwrite(pDat + dwOffset, 1, dwSize, stream); + fclose(stream); + } + #endif + return -1; + } } + break; + + default: + return -1; + } + + return nImported; +} + +// Imports the contact at offset dwOffset +// Returns the HANDLE of the Miranda contact +// or INVALID_HANDLE_VALUE on failure + +HANDLE ImportContact(DWORD dwOffset) +{ + int nContactVersion, nSearchResult; + BYTE Status; + WORD wSeparatorValue; + DWORD dwGroup, dwUIN = 0, tmpOfs = 0; + char *strNickname = 0, *strGroupName = 0; + + if (*(int*)(pDat + dwOffset + 4) != DATENTRY_CONTACT) + return INVALID_HANDLE_VALUE; + + if (*(int*)(pDat + dwOffset + 0x1e) != 'USER') + return INVALID_HANDLE_VALUE; + + #ifdef _LOGGING + { // If this is a debug build, dump contact to disk + FILE *stream; + DWORD dwSize; + dwSize = *(PDWORD)(pDat + dwOffset); + stream = fopen("import_last_contact.bin", "w"); + fwrite(pDat + dwOffset, 1, dwSize, stream); + fclose(stream); + } + #endif + + Status = *(pDat + dwOffset + 0x22); + wSeparatorValue = *(PWORD)(pDat + dwOffset + 0x1c); + nContactVersion = GetEntryVersion(wSeparatorValue); + + dwGroup = *(PDWORD)(pDat + dwOffset + 0x26); + if (dwGroup >= 1000) + strGroupName = GetGroupName(dwGroup); + + if (Status == 5) + return INVALID_HANDLE_VALUE; // Skip deleted contacts + + if ((Status != 2) && (Status != 3)) { + AddMessage( LPGEN("Skipping inactive contact.")); + return INVALID_HANDLE_VALUE; + } + + if ((nContactVersion < ENTRYV99A) || (nContactVersion == 0)) { + AddMessage( LPGEN("Skipping contact with unsupported version.")); + return INVALID_HANDLE_VALUE; + } + + switch(nContactVersion){ + case ENTRYV99A: + if (!(dwOffset = ReadWavList(dwOffset + 0x54))) return INVALID_HANDLE_VALUE; + if (!(dwOffset = ReadPropertyBlock(dwOffset + 0x26, NULL, NULL))) return INVALID_HANDLE_VALUE; + // Check for custom nickname + if (*(PWORD)(pDat + dwOffset) > 1) strNickname = (char*)(dwOffset + pDat + 2); + // Find UIN + dwOffset += *(PWORD)(pDat + dwOffset) + 2; // Custom nick name + dwOffset += *(PWORD)(pDat + dwOffset) + 2; // Nick name + dwOffset += *(PWORD)(pDat + dwOffset) + 2; // First name + dwOffset += *(PWORD)(pDat + dwOffset) + 2; // Last name + dwOffset += *(PWORD)(pDat + dwOffset) + 2; // E-mail + dwUIN = *(PDWORD)(pDat + dwOffset); // UIN + break; + + case ENTRYV99B: + case ENTRYV2000A: + case ENTRYV2000B: + if (!(dwOffset = ReadWavList(dwOffset + 0x2C))) return INVALID_HANDLE_VALUE; + tmpOfs = ReadPropertyBlockList(dwOffset + 0x02, "UIN", &nSearchResult); + if (nSearchResult) dwUIN = *(PDWORD)(pDat + tmpOfs + 1); + tmpOfs = ReadPropertyBlockList(dwOffset + 0x02, "MyDefinedHandle", &nSearchResult); + if (nSearchResult) strNickname = (char*)(tmpOfs + pDat + 3); + break; + + case ENTRYV2001A: + case ENTRYV2001B: + tmpOfs = ReadPropertyBlockList(dwOffset + 0x2C, "MyDefinedHandle", &nSearchResult); + if (nSearchResult) strNickname = (char*)(tmpOfs + pDat + 3); + tmpOfs = ReadPropertyBlockList(dwOffset + 0x2C, "UIN", &nSearchResult); + if (nSearchResult) dwUIN = *(PDWORD)(pDat + tmpOfs + 1); + break; + + case ENTRYV2002A: + tmpOfs = ReadPropertyBlockList(dwOffset + 0x32, "MyDefinedHandle", &nSearchResult); + if (nSearchResult) strNickname = (char*)(tmpOfs + pDat + 3); + tmpOfs = ReadPropertyBlockList(dwOffset + 0x32, "UIN", &nSearchResult); + if (nSearchResult) dwUIN = *(PDWORD)(pDat + tmpOfs + 1); + break; + } + + if (!dwUIN) { + AddMessage( LPGEN("Skipping unrecognizable contact.")); + return INVALID_HANDLE_VALUE; + } + + if (dwUIN < 10000) { + AddMessage( LPGEN("Skipping non-ICQ contact %u."), dwUIN ); + return INVALID_HANDLE_VALUE; + } + + if (HContactFromNumericID( szICQModuleName[ iICQAccount ], "UIN", dwUIN) == INVALID_HANDLE_VALUE) { + DBVARIANT id, nick, group; + id.type = DBVT_DWORD; id.dVal = dwUIN; + if ( strNickname != NULL && strlen(strNickname) > 0 ) + nick.type = DBVT_ASCIIZ, nick.pszVal = strNickname; + else + nick.type = DBVT_DELETED; + group.type = DBVT_ASCIIZ, group.pszVal = strGroupName; + return AddContact(hdlgProgress, szICQModuleName[ iICQAccount ], "UIN", &id, &nick, &group); + } + else { + if ((strNickname != NULL) && (strlen(strNickname) > 0)) + AddMessage( LPGEN("Skipping duplicate ICQ contact %u, %s"), dwUIN, strNickname); + else + AddMessage( LPGEN("Skipping duplicate ICQ contact %u"), dwUIN); + } + + // Failure + return INVALID_HANDLE_VALUE; +} + +BOOL ImportMessage(DWORD dwOffset) +{ + struct TDatMessage *msg = (struct TDatMessage*)(pDat + dwOffset); + struct TDatEntryFooter *footer; + DBEVENTINFO dbei; + HANDLE hContact; + int nUCTOffset; + TIME_ZONE_INFORMATION TimeZoneInformation; + int nHistoryCount = 0; + + // Get timestamp offset. In ICQ, event timestamps are stored + // as UTC + (0-TZ offset). YES! That's the negation of the + // timezone offset, only God and Mirabilis knows why. + GetTimeZoneInformation(&TimeZoneInformation); + nUCTOffset = -TimeZoneInformation.Bias * 60; + + // Ignore messages in 'Deleted' folder + if (msg->filingStatus&FILING_DELETED) + return FALSE; + + // Skip messages from non-icq contacts + if (msg->uin < 10000) { + AddMessage( LPGEN("Ignoring msg from user %d at ofs %d."), msg->uin, dwOffset ); + return FALSE; + } + + // Ignore received messages? + if (( msg->filingStatus & FILING_RECEIVED ) && !( nCustomOptions & IOPT_MSGRECV )) + return FALSE; + + // Ignores sent messages? + if ( !(msg->filingStatus & FILING_RECEIVED) && !( nCustomOptions & IOPT_MSGSENT )) + return FALSE; + + // Check if contact exists in Miranda database + hContact = HistoryImportFindContact(hdlgProgress, szICQModuleName[ iICQAccount ], msg->uin, nCustomOptions&IOPT_ADDUNKNOWN); + if (hContact == INVALID_HANDLE_VALUE) + return FALSE; // Contact couldn't be found/added + + // Convert the event to a Miranda dbevent + footer = (struct TDatEntryFooter*)(pDat + dwOffset + msg->textLen + offsetof(struct TDatMessage, text)); + ZeroMemory(&dbei, sizeof(dbei)); + dbei.cbSize = sizeof(dbei); + dbei.eventType = EVENTTYPE_MESSAGE; + dbei.flags = footer->sent == 1 ? DBEF_SENT : DBEF_READ; + dbei.szModule = szICQModuleName[ iICQAccount ]; + // Convert timestamp + dbei.timestamp = footer->timestamp + nUCTOffset; + dbei.cbBlob = msg->textLen; + dbei.pBlob = (PBYTE)alloca(msg->textLen); + CopyMemory(dbei.pBlob, msg->text, dbei.cbBlob); + dbei.pBlob[dbei.cbBlob - 1] = 0; + + // Check for duplicate entries + if (IsDuplicateEvent(hContact, dbei)) { + nDupes++; + } + else { + if (CallService(MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&dbei)) + nMessagesCount++; + } + + return TRUE; +} + +BOOL ImportExtendedMessage(DWORD dwOffset) +{ + struct TDatMessage *msg = (struct TDatMessage*)(pDat + dwOffset); + struct TDatEntryFooter *footer; + DBEVENTINFO dbei; + HANDLE hContact; + int nUCTOffset; + TIME_ZONE_INFORMATION TimeZoneInformation; + int nHistoryCount = 0; + char* pszText = 0; + DWORD dwRichTextOffset = 0; + DWORD wRichTextLength = 0; + DWORD wLength = 0; + BOOL bFreeMe = FALSE; + + // Get timestamp offset. In ICQ, event timestamps are stored + // as UTC + (0-TZ offset). YES! That's the negation of the + // timezone offset, only God and Mirabilis knows why. + GetTimeZoneInformation(&TimeZoneInformation); + nUCTOffset = -TimeZoneInformation.Bias * 60; + + // Ignore messages in 'Deleted' folder + if (msg->filingStatus&FILING_DELETED) + return FALSE; + + // Skip messages from non-icq contacts + if (msg->uin < 10000) { + AddMessage( LPGEN("Ignoring msg from user %d at ofs %d."), msg->uin, dwOffset ); + return FALSE; + } + + // Ignore received messages? + if (( msg->filingStatus & FILING_RECEIVED) && !( nCustomOptions & IOPT_MSGRECV )) + return FALSE; + + // Ignore sent messages? + if ( !( msg->filingStatus & FILING_RECEIVED ) && !( nCustomOptions & IOPT_MSGSENT )) + return FALSE; + + // Check if contact exists in Miranda database + hContact = HistoryImportFindContact(hdlgProgress, szICQModuleName[ iICQAccount ], msg->uin, nCustomOptions&IOPT_ADDUNKNOWN); + if (hContact == INVALID_HANDLE_VALUE) + return FALSE; // Contact couldn't be found/added + + // Find a piece of usable text content + if (msg->textLen <= 1) { + // Skip past the RTF segment + wRichTextLength = *(PWORD)(pDat + dwOffset + 0x2A + msg->textLen + 0x21); + dwRichTextOffset = dwOffset + 0x2A + msg->textLen + 0x23; + + // Use the UTF-8 text segment + wLength = *(PWORD)(pDat + dwRichTextOffset + wRichTextLength); + if (wLength <= 1) { + AddMessage( LPGEN("Ignoring msg with no text from %d ofs %d."), msg->uin, dwOffset ); + return FALSE; + } + pszText = _strdup((char*)pDat + dwRichTextOffset + wRichTextLength + 2); + bFreeMe = TRUE; + mir_utf8decode(pszText, NULL); + wLength = (DWORD)strlen(pszText)+1; + } + else { + // Use the ANSI text segment + wLength = msg->textLen; + pszText = (char*)(pDat + dwOffset + 0x2A); + } + + // Convert the event to a Miranda dbevent + footer = (struct TDatEntryFooter*)(pDat + dwOffset + msg->textLen + offsetof(struct TDatMessage, text)); + ZeroMemory(&dbei, sizeof(dbei)); + dbei.cbSize = sizeof(dbei); + dbei.eventType = EVENTTYPE_MESSAGE; + dbei.flags = footer->sent == 1 ? DBEF_SENT : DBEF_READ; + dbei.szModule = szICQModuleName[ iICQAccount ]; + // Convert timestamp + dbei.timestamp = footer->timestamp + nUCTOffset; + dbei.cbBlob = wLength; + dbei.pBlob = (PBYTE)calloc(wLength,1); + CopyMemory(dbei.pBlob, pszText, dbei.cbBlob); + dbei.pBlob[dbei.cbBlob - 1] = 0; + + // Check for duplicate entries + if (IsDuplicateEvent(hContact, dbei)) { + nDupes++; + } + else { + if (CallService(MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&dbei)) + nMessagesCount++; + } + + free(dbei.pBlob); + if (bFreeMe) + free(pszText); + + return TRUE; +} + +BOOL ImportURLMessage(DWORD dwOffset) +{ + struct TDatMessage *msg = (struct TDatMessage*)(pDat + dwOffset); + struct TDatEntryFooter *footer; + DBEVENTINFO dbei; + HANDLE hContact; + int nUCTOffset; + TIME_ZONE_INFORMATION TimeZoneInformation; + int nHistoryCount = 0; + char *pSeparator; + + // Get timestamp offset. In ICQ, event timestamps are stored + // as UTC + (0-TZ offset). YES! That's the negation of the + // timezone offset, only God and Mirabilis knows why. + GetTimeZoneInformation(&TimeZoneInformation); + nUCTOffset = -TimeZoneInformation.Bias * 60; + + // Ignore URLs in 'Deleted' folder + if (msg->filingStatus&FILING_DELETED) + return FALSE; + + // Skip URLs from non-icq contacts + if (msg->uin < 10000) { + AddMessage( LPGEN("Ignoring msg from user %d at ofs %d."), msg->uin, dwOffset ); + return FALSE; + } + + // Ignore received URLs? + if (( msg->filingStatus & FILING_RECEIVED ) && !( nCustomOptions & IOPT_URLRECV )) + return FALSE; + + // Ignores sent URLs? + if ( !( msg->filingStatus & FILING_RECEIVED ) && !( nCustomOptions & IOPT_URLSENT )) + return FALSE; + + // Check if contact exists in Miranda database + hContact = HistoryImportFindContact(hdlgProgress, szICQModuleName[ iICQAccount ], msg->uin, nCustomOptions&IOPT_ADDUNKNOWN); + if (hContact == INVALID_HANDLE_VALUE) + return FALSE; // Contact couldn't be found/added + + // Convert the event to a Miranda dbevent + footer = (struct TDatEntryFooter*)(pDat + dwOffset + msg->textLen + offsetof(struct TDatMessage, text)); + ZeroMemory(&dbei, sizeof(dbei)); + dbei.cbSize = sizeof(dbei); + dbei.eventType = EVENTTYPE_URL; + dbei.flags = footer->sent == 1 ? DBEF_SENT : DBEF_READ; + dbei.szModule = szICQModuleName[ iICQAccount ]; + // Convert timestamp + dbei.timestamp = footer->timestamp + nUCTOffset; + dbei.cbBlob = msg->textLen; + dbei.pBlob = (PBYTE)alloca(msg->textLen); + CopyMemory(dbei.pBlob, msg->text, dbei.cbBlob); + dbei.pBlob[dbei.cbBlob - 1] = 0; + // Separate URL and description + pSeparator = strchr((char*)dbei.pBlob, 0xFE); + if (pSeparator != NULL) + *pSeparator = 0; + + // Check for duplicate entries + if (IsDuplicateEvent(hContact, dbei)) + nDupes++; + else if (CallService(MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&dbei)) + nMessagesCount++; + + return TRUE; +} + +BOOL ImportEvent(DWORD dwOffset) +{ + struct TDatMessage *msg = (struct TDatMessage*)(pDat + dwOffset); + + // Events have IDs > 2000 + if (msg->hdr.entryId < 2001) { + AddMessage( LPGEN("Skipping event with ID < 2001.")); + return FALSE; + } + + // Separate code paths based on the event signature + switch (msg->hdr.subType) { + + case SUBTYPE_MESSAGE: // All kinds of messages + switch (msg->type) { + case 1: // Normal message + if ((nCustomOptions&IOPT_MSGRECV) || (nCustomOptions&IOPT_MSGSENT)) { + return ImportMessage(dwOffset); + } + break; + + case 4: // URL + if ((nCustomOptions&IOPT_URLSENT) || (nCustomOptions&IOPT_URLRECV)) { + return ImportURLMessage(dwOffset); + } + break; + + case 6: // Request for authorization + #ifdef _LOGGING + AddMessage( LPGEN("Skipping 'Request for auth.' msg, ofs %d."), dwOffset ); + #endif + break; + + case 7: // Authorization request denied + #ifdef _LOGGING + AddMessage( LPGEN("Skipping 'Auth. denied' msg, ofs %d."), dwOffset ); + #endif + break; + + case 8: // Authorization request accepted + #ifdef _LOGGING + AddMessage( LPGEN("Skipping 'Auth. accepted' msg, ofs %d."), dwOffset ); + #endif + break; + + case 9: // System message + #ifdef _LOGGING + AddMessage( LPGEN("Skipping 'System message', ofs %d."), dwOffset ); + #endif + break; + + case 12: // You were added + #ifdef _LOGGING + AddMessage( LPGEN("Skipping 'You were added' msg, ofs %d."), dwOffset ); + #endif + break; + + case 13: // WWWPager ? + #ifdef _LOGGING + AddMessage( LPGEN("Skipping 'WWW Pager' msg, ofs %d."), dwOffset ); + #endif + break; + + case 14: // Email Express ? + #ifdef _LOGGING + AddMessage( LPGEN("Skipping 'Email Express' msg, ofs %d."), dwOffset ); + #endif + break; + + case 19: // Contact list + #ifdef _LOGGING + AddMessage( LPGEN("Skipping 'Contact' msg, ofs %d."), dwOffset ); + #endif + break; + + case 21: // Phonecall request? + #ifdef _LOGGING + AddMessage( LPGEN("Skipping 'Phonecall' msg (?), ofs %d."), dwOffset ); + #endif + break; + + case 26: // SMS request? + #ifdef _LOGGING + AddMessage( LPGEN("Skipping 'SMS' msg (?), ofs %d."), dwOffset ); + #endif + break; + + case 29: // Active list invitation ?? + #ifdef _LOGGING + AddMessage( LPGEN("Skipping 29 msg, ofs %d."), dwOffset ); + #endif + break; + + case 30: // Birthday reminder + #ifdef _LOGGING + AddMessage( LPGEN("Skipping 'Birthday' msg (?), ofs %d."), dwOffset ); + #endif + break; + + case 32: // Unknown (Tomer) + #ifdef _LOGGING + AddMessage( LPGEN("Skipping 32 msg, ofs %d."), dwOffset ); + #endif + break; + + default: + AddMessage( LPGEN("Skipping unknown 0xE0 subtype (%d), ofs %d."), msg->type, dwOffset ); + + #ifdef _LOGGING + { // If this is a debug build, dump entry to disk + FILE *stream; + DWORD dwSize = *(PDWORD)(pDat + dwOffset); + wsprintfA(str, "import_unknown_E0subtype_%u-%u.bin", msg->type, dwOffset); + stream = fopen(str, "w"); + fwrite(pDat + dwOffset, 1, dwSize, stream); + fclose(stream); + } + #endif + + return FALSE; + } + break; + + case SUBTYPE_CHATREQUEST: // 0xE1 + #ifdef _LOGGING + if (nImportOption != IMPORT_CONTACTS) + AddMessage( LPGEN("Skipping 'Chat request' msg, ofs %d."), dwOffset ); + #endif + break; + + case SUBTYPE_FILEREQUEST: // 0xE2 + #ifdef _LOGGING + if (nImportOption != IMPORT_CONTACTS) + AddMessage( LPGEN("Skipping file message offset %d."), dwOffset ); + #endif + break; + + case 0xE3: // External (IPhone, Battlecom) Maybe general voice calls? + #ifdef _LOGGING + if (nImportOption != IMPORT_CONTACTS) + AddMessage( LPGEN("Skipping message type 0xE3 at offset %d."), dwOffset ); + #endif + break; + + case 0xE4: // My details + break; + case 0xE5: // Contact + break; + case 0xE6: // Reminder + break; + case 0xE7: // Addressbook + break; + case 0xEC: // Voice message + break; + case 0xED: // Unknown, something to do with chatting and .CHT files + // if (importHistory) { + // wsprintf(str, "Skipping message type 0xED at offset %d.", dwOffset); + // AddMessage( LPGEN(str); + // } + break; + case 0xEE: // Note + break; + case 0xEF: // Event folder + break; + // case 0xF0: // Unknown + // if (importHistory) { + // wsprintf(str, "Skipping message type 0xF0 at offset %d.", dwOffset); + // AddMessage( LPGEN(str); + // } + // break; + case 0xF1: // Server list + break; + // case 0xF6: // Unknown + // if (importHistory) { + // wsprintf(str, "Skipping message type 0xF6 at offset %d.", dwOffset); + // AddMessage( LPGEN(str); + // } + // break; + case 0x50: // Extended message, ICQ 2000a+? + if (nImportOption != IMPORT_CONTACTS) { + return ImportExtendedMessage(dwOffset); + } + break; + + case 0xA0: // URL message type 2 + if (nImportOption != IMPORT_CONTACTS) { + if ((msg->filingStatus&FILING_RECEIVED) || (nCustomOptions&IOPT_URLRECV)) { + return ImportURLMessage(dwOffset); + } + } + break; + + default: + if (nImportOption != IMPORT_CONTACTS) { + AddMessage( LPGEN("Skipping unknown event type %d at offset %d."), msg->hdr.subType, dwOffset ); + +#ifdef _LOGGING + { // If this is a debug build, dump entry to disk + FILE *stream; + DWORD dwSize; + dwSize = *(PDWORD)(pDat + dwOffset); + wsprintfA(str, "import_unknown_eventtype_%u-%u.bin", msg->hdr.subType, dwOffset); + stream = fopen(str, "w"); + fwrite(pDat + dwOffset, 1, dwSize, stream); + fclose(stream); + } +#endif + + } + break; + } + + return FALSE; +} + + +static void MirabilisImport(HWND hdlgProgressWnd) +{ + HANDLE hIdx, hDat, hIdxMapping, hDatMapping; + DWORD i, ofs, highestIndexEntry; + TCHAR datFilename[MAX_PATH]; + MSG msg; + DWORD dwTimer; + + + int status = 0; + hdlgProgress = hdlgProgressWnd; + nDupes = nContactsCount = nMessagesCount = 0; + + SetProgress(0); + lstrcpy(datFilename, importFile); + { + TCHAR* str2; + str2 = _tcsrchr(datFilename,'.'); + if ( str2 != NULL ) + lstrcpy(str2, _T(".dat")); + } + + hIdx = CreateFile(importFile, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + if (hIdx == INVALID_HANDLE_VALUE) { + AddMessage( LPGEN("Failed to open index file")); + AddMessage( LPGEN("Import aborted")); + SetProgress(100); + return; + } + + hDat = CreateFile(datFilename, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + if (hDat == INVALID_HANDLE_VALUE) { + AddMessage( LPGEN("Failed to open database file")); + AddMessage( LPGEN("Import aborted")); + SetProgress(100); + return; + } + + // Creating file mappings + hIdxMapping = CreateFileMapping(hIdx, NULL, PAGE_READONLY, 0, 0, NULL); + hDatMapping = CreateFileMapping(hDat, NULL, PAGE_READONLY, 0, 0, NULL); + + // Mapping views of files + pIdx = (PBYTE)MapViewOfFile(hIdxMapping, FILE_MAP_READ, 0, 0, 0); + pDat = (PBYTE)MapViewOfFile(hDatMapping, FILE_MAP_READ, 0, 0, 0); + + // Is this a supported format? + if (GetDBVersion()) { + AddMessage( "" ); + + highestIndexEntry = GetHighestIndexEntry(); + + // Import groups + nGroupsCount = ImportGroups(); + if (nGroupsCount < 0) { + AddMessage( LPGEN("Group import was not completed.")); + nGroupsCount = 0; + } + AddMessage( "" ); + + // Start benchmark timer + dwTimer = time(NULL); + + if ( !IsProtocolLoaded( szICQModuleName[iICQAccount] )) { + AddMessage( LPGEN("ICQ account is not installed.")); + AddMessage( LPGEN("No ICQ contacts or history will be imported.")); + AddMessage( "" ); + } + else { + // Configure database for fast writing + CallService(MS_DB_SETSAFETYMODE, FALSE, 0); + + // Import contacts + AddMessage( LPGEN("Importing contacts")); + for (i = 2001; i <= highestIndexEntry; i++) { //event ids start at 2001 + if (!(i%10)) { + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + if (!(i%100)) + SetProgress(100 * (i - 2001) / (highestIndexEntry - 2001)); + + ofs = GetIdDatOfs(i); + if (ofs != 0) { + if (ImportContact(ofs) != INVALID_HANDLE_VALUE) + nContactsCount++; + } + } + AddMessage( "" ); + + // Import history + if (nImportOption != IMPORT_CONTACTS) { + AddMessage( LPGEN("Importing history (this may take a while)")); + for (i = 2001; i <= highestIndexEntry; i++) { //event ids start at 2001 + if (!(i%10)) { + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + if (!(i%100)) + SetProgress(100 * (i - 2001) / (highestIndexEntry - 2001)); + + ofs = GetIdDatOfs(i); + if (ofs != 0) ImportEvent(ofs); + } + AddMessage( "" ); + } + + // Restore database writing mode + CallService(MS_DB_SETSAFETYMODE, TRUE, 0); + } + + dwTimer = time(NULL) - dwTimer; + + AddMessage( LPGEN("Import completed in %d seconds."), dwTimer ); + SetProgress(100); + AddMessage( LPGEN("Added %d contacts and %d groups."), nContactsCount, nGroupsCount ); + if ( nImportOption != IMPORT_CONTACTS ) + AddMessage( LPGEN("Added %d events and skipped %d duplicates."), nMessagesCount, nDupes ); + } + + UnmapViewOfFile(pDat); + UnmapViewOfFile(pIdx); + CloseHandle(hDatMapping); + CloseHandle(hIdxMapping); + CloseHandle(hDat); + CloseHandle(hIdx); +} diff --git a/plugins/Import/src/mirabilis.h b/plugins/Import/src/mirabilis.h new file mode 100644 index 0000000000..47f10141e1 --- /dev/null +++ b/plugins/Import/src/mirabilis.h @@ -0,0 +1,200 @@ +/* + +Import plugin for Miranda IM + +Copyright (C) 2001,2002,2003,2004 Martin Öberg, Richard Hughes, Roland Rabien & Tristan Van de Vreede + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + + + +#ifndef MIRABILIS_H +#define MIRABILIS_H + +#include +#include +#include + +// ====================== +// == GLOBAL FUNCTIONS == +// ====================== + +HANDLE HistoryImportFindContact(HWND hdlgProgress, char* szModuleName, DWORD uin,int addUnknown); + +// ===================== +// == LOCAL FUNCTIONS == +// ===================== + + +// Main function +static void MirabilisImport(HWND hdlgProgressWnd); + +// GUI callbacks +INT_PTR CALLBACK ImportTypePageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam); +INT_PTR CALLBACK FinishedPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam); +INT_PTR CALLBACK ProgressPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam); +INT_PTR CALLBACK MirabilisPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam); +INT_PTR CALLBACK MirabilisOptionsPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam); + +// Helper functions for entries +static int GetHighestIndexEntry(void); +static int GetIdDatOfs(DWORD id); +static int GetDatEntryType(DWORD ofs); +DWORD FindMyDetails(void); + +// Parsing functions +DWORD GetDBVersion(); +int GetEntryVersion(WORD wSeparatorValue); +DWORD ReadPropertyBlock(DWORD dwOffset, char* SearchWord, int* nSearchResult); +DWORD ReadSubList(DWORD dwOffset); +DWORD ReadPropertyBlock(DWORD dwOffset, char* SearchWord, int* nSearchResult); +DWORD ReadPropertyBlockList(DWORD dwOffset, char* SearchWord, int* nSearchResult); +DWORD ReadWavList(DWORD ofs); +DWORD FindGroupList(DWORD dwOffset); +char* GetGroupName(DWORD dwGroupID); +int ImportGroups(); +static HANDLE ImportContact(DWORD dwOffset); + +BOOL ImportEvent(DWORD dwOffset); +BOOL ImportMessage(DWORD dwOffset); +BOOL ImportExtendedMessage(DWORD dwOffset); +BOOL ImportURLMessage(DWORD dwOffset); + + + + +// ====================== +// == GLOBAL VARIABLES == +// ====================== + +extern TCHAR importFile[MAX_PATH]; +extern void (*DoImport)(HWND); +extern int nImportOption; +extern int nCustomOptions; + + +extern int cICQAccounts; +extern char ** szICQModuleName; +extern TCHAR ** tszICQAccountName; +extern int iICQAccount; + +// ===================== +// == LOCAL VARIABLES == +// ===================== + +static DWORD dwDBVersion; +static DWORD dwGroupListOfs; +static PBYTE pIdx,pDat; + +// ============= +// == DEFINES == +// ============= + +// Contact versions +// These numbers are not 100% accurate +#define ENTRYVUNKNOWN -1 +#define ENTRYV99A 200 +#define ENTRYV99B 300 +#define ENTRYV2000A 400 +#define ENTRYV2000B 455 +#define ENTRYV2001A 500 +#define ENTRYV2001B 515 +#define ENTRYV2002A 533 + +// Database versions +#define DBV99A 10 +#define DBV99B 14 +#define DBV2000A 17 +#define DBV2000B 18 +#define DBV2001A 19 // This is used by ICQ 2001a, 2001b & 2002a + +#define DATENTRY_UNFILED (DWORD)(-1) +#define DATENTRY_MESSAGE 0 +#define DATENTRY_CONTACT 1 +#define DATENTRY_IGNORED 2 +#define DATENTRY_SYSTEM 9 + +#define MAX_NON_ICQ_CONTACTS 100 + +#define SUBTYPE_NEWMESSAGE 0x50 +#define SUBTYPE_NEWURL 0xA0 + +#define SUBTYPE_MESSAGE 0xE0 //Message / URL Message / Request For Authorization / "Authorization" / System Request / "You Were Added" / Contacts List +#define SUBTYPE_CHATREQUEST 0xE1 +#define SUBTYPE_FILEREQUEST 0xE2 +#define SUBTYPE_MYDETAILS 0xE4 +#define SUBTYPE_CONTACTINFO 0xE5 +#define SUBTYPE_REMINDER 0xE6 +#define SUBTYPE_ADDRESSBOOK 0xE7 +#define SUBTYPE_VOICEMSG 0xEC //??? +#define SUBTYPE_NOTE 0xEE +#define SUBTYPE_EVENTFOLDER 0xEF +#define SUBTYPE_SERVERLIST 0xF1 //and objectionable word list +#define SUBTYPE_X1 0xF6 //(new to ICQ 99b???) + +#define FILING_RECEIVED 0x01 +#define FILING_DELETED 0x02 +#define FILING_MESSAGE 0x04 +#define MSGTYPE_MESSAGE 1 +#define MSGTYPE_URL 4 +#define MSGTYPE_CLIST 19 +#include + +struct TIdxDatEntry { + DWORD status; //-2=valid, else is an index entry + DWORD entryId; + DWORD ofsNext,ofsPrev; + DWORD datOfs; +}; + +struct TIdxIndexEntry { + DWORD entryIdLow; + DWORD entryIdHigh; + DWORD ofsLower; + DWORD ofsInHere; + DWORD ofsHigher; +}; + +struct TDatEntryHeader { + DWORD entrySize; //in bytes + DWORD entryType; //DATENTRY_* constant + DWORD entryId; //same as in index + BYTE subType; //SUBTYPE_* constant + BYTE signature[15]; +}; + +struct TDatEntryFooter { + DWORD unknown; + DWORD sent; //1 if sent, 0 if received + WORD separator; + DWORD timestamp; //unix time +}; + +struct TDatMessage { + struct TDatEntryHeader hdr; //hdr.entryType==DATENTRY_MESSAGE && hdr.subType==MSGTYPE_MESSAGE + WORD separator; + DWORD filingStatus; //FILING_* flags + WORD type; //MSGTYPE_* constant + DWORD uin; + WORD textLen; + char text[1]; //0xFE separates description & URL in URLs + //a struct TDatEntryFooter comes here +}; + +#include + +#endif diff --git a/plugins/Import/src/miranda.cpp b/plugins/Import/src/miranda.cpp new file mode 100644 index 0000000000..4f616fb714 --- /dev/null +++ b/plugins/Import/src/miranda.cpp @@ -0,0 +1,1445 @@ +/* + +Import plugin for Miranda IM + +Copyright (C) 2001-2005 Martin Öberg, Richard Hughes, Roland Rabien & Tristan Van de Vreede + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +// ============== +// == INCLUDES == +// ============== + +#include "import.h" + +#include "resource.h" +#include "mirandadb0700.h" + +// ====================== +// == GLOBAL FUNCTIONS == +// ====================== + +HANDLE HContactFromNumericID(char* pszProtoName, char* pszSetting, DWORD dwID); +HANDLE HContactFromID(char* pszProtoName, char* pszSetting, char* pszID); + +HANDLE AddContact(HWND hdlgProgress, char* pszProtoName, char* pszUniqueSetting, DBVARIANT* id, DBVARIANT* nick, DBVARIANT* group); + +BOOL IsProtocolLoaded(char* pszProtocolName); +BOOL IsDuplicateEvent(HANDLE hContact, DBEVENTINFO dbei); + +INT_PTR CALLBACK ImportTypePageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam); +INT_PTR CALLBACK FinishedPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam); +INT_PTR CALLBACK ProgressPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam); +INT_PTR CALLBACK MirandaOptionsPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam); +INT_PTR CALLBACK MirandaAdvOptionsPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam); + +// ===================== +// == LOCAL FUNCTIONS == +// ===================== + +void MirandaImport(HWND hdlgProgress); +int CheckFileFormat(HANDLE hFile); +static HANDLE ImportContact(HANDLE hDbFile, struct DBContact Contact); +static void ImportHistory(HANDLE hDbFile, struct DBContact Contact, PROTOCOLDESCRIPTOR **protocol, int protoCount); +static int ImportGroups(HANDLE hDbFile, struct DBHeader *pdbHeader); + +// Comment: The Find* functions only return a file offset. +// The Get* functions actually reads the requested +// data from the file and gives you a pointer to a structure +// containing the data. + +DWORD FindFirstContact(struct DBHeader* pDbHeader); +DWORD FindNextContact(struct DBContact* pDbContact); +DWORD FindNextEvent(HANDLE hDbFile, DWORD dwOffset); +DWORD FindOwnerContact(struct DBHeader* pDbHeader); + +int GetContactCount(struct DBHeader* pDbHeader); +BOOL GetContact(HANDLE hDbFile, DWORD dwOffset, struct DBContact* pDbContact); +BOOL GetSetting(HANDLE hDbFile, struct DBContact* pDbContact, char* pszModuleName, char* pszSettingName, DBVARIANT* pValue); +char* GetNextSetting(char* pDbSetting); +BOOL GetSettings(HANDLE hDbFile, DWORD dwOffset, struct DBContactSettings** pDbSettings); +struct DBContactSettings* GetSettingsGroupByModuleName(HANDLE hdbFile, struct DBContact* pDbContact, char* pszName); +DWORD GetBlobSize(struct DBContactSettings* pDbSettings); +int GetSettingByName(struct DBContactSettings* pDbSettings, char* pszSettingName, DBVARIANT* pValue); +int GetSettingValue(char* pBlob,DBVARIANT* pValue); + +BOOL GetEvent(HANDLE hDbFile, DWORD dwOffset, DBEVENTINFO* pDBEI); +char* GetName(HANDLE hDbFile, DWORD dwOffset); + + +// ====================== +// == GLOBAL VARIABLES == +// ====================== + +extern void (*DoImport)(HWND); +extern int nImportOption; +extern int nCustomOptions; + + +// ===================== +// == LOCAL VARIABLES == +// ===================== + +TCHAR importFile[MAX_PATH]; +HWND hdlgProgress; +DWORD dwFileSize; + +DWORD nDupes; +DWORD nContactsCount; +DWORD nMessagesCount; +DWORD nGroupsCount; +DWORD nSkippedEvents; +DWORD nSkippedContacts; + +time_t dwSinceDate = 0; + +// ============= +// == DEFINES == +// ============= + +#define EVENTTYPE_MESSAGE 0 +#define EVENTTYPE_URL 1 +#define EVENTTYPE_FILE 1002 + + +// Supported database versions +#define DB_INVALID 0x00000000 // Unknown or corrupted DAT +#define DB_000700 0x00000700 // Miranda 0.1.0.0 - 0.1.2.2+ + +// DAT file signature +struct DBSignature { + char name[15]; + BYTE eof; +}; + +static struct DBSignature dbSignature={"Miranda ICQ DB",0x1A}; + +// ==================== +// ==================== +// == IMPLEMENTATION == +// ==================== +// ==================== + +static void SearchForLists(HWND hdlg, const TCHAR *mirandaPath, const TCHAR *mirandaProf, const TCHAR *pattern, const TCHAR *type) +{ + HANDLE hFind; + WIN32_FIND_DATA fd; + TCHAR szSearchPath[MAX_PATH]; + TCHAR szRootName[MAX_PATH]; + TCHAR* str2; + int i; + + mir_sntprintf(szSearchPath, SIZEOF(szSearchPath), _T("%s\\%s"), mirandaPath, pattern); + hFind = FindFirstFile(szSearchPath, &fd); + if (hFind != INVALID_HANDLE_VALUE) + { + do + { + _tcscpy(szRootName, fd.cFileName); + str2 = _tcsrchr(szRootName, '.'); + if (str2 != NULL) *str2 = 0; + if (mirandaProf == NULL || _tcsicmp(mirandaProf, szRootName)) + { + _tcscat(szRootName, type); + i = SendDlgItemMessage(hdlg, IDC_LIST, LB_ADDSTRING, 0, (LPARAM)szRootName); + str2 = (TCHAR*)mir_alloc((_tcslen(mirandaPath) + 2 + _tcslen(fd.cFileName)) * sizeof(TCHAR)); + wsprintf(str2, _T("%s\\%s"), mirandaPath, fd.cFileName); + SendDlgItemMessage(hdlg, IDC_LIST, LB_SETITEMDATA, i, (LPARAM)str2); + } + } + while( FindNextFile( hFind, &fd )); + + FindClose( hFind ); + } +} + +INT_PTR CALLBACK MirandaPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam) +{ + switch(message) { + case WM_INITDIALOG: + TranslateDialogDefault(hdlg); + { + TCHAR *pfd, *pfd1, *pfd2, *pfn; + + REPLACEVARSDATA dat = {0}; + dat.cbSize = sizeof(dat); + dat.dwFlags = RVF_TCHAR; + + pfd = (TCHAR*)CallService(MS_UTILS_REPLACEVARS, (WPARAM)_T("%miranda_path%\\Profiles"), (LPARAM)&dat); + pfd1 = (TCHAR*)CallService(MS_UTILS_REPLACEVARS, (WPARAM)_T("%miranda_path%"), (LPARAM)&dat); + pfd2 = (TCHAR*)CallService(MS_UTILS_REPLACEVARS, (WPARAM)_T("%miranda_profile%"), (LPARAM)&dat); + pfn = (TCHAR*)CallService(MS_UTILS_REPLACEVARS, (WPARAM)_T("%miranda_profilename%"), (LPARAM)&dat); + + SearchForLists(hdlg, pfd2, pfn, _T("*.dat"), _T(" (Miranda IM v0.x)")); + SearchForLists(hdlg, pfd1, NULL, _T("*.dat"), _T(" (Miranda IM v0.x)")); + if (lstrcmpi(pfd, pfd2)) + SearchForLists(hdlg, pfd, NULL, _T("*.dat"), _T(" (Miranda IM v0.x)")); + + mir_free(pfn); + mir_free(pfd2); + mir_free(pfd1); + mir_free(pfd); + return TRUE; + } + + case WM_COMMAND: + switch(LOWORD(wParam)) { + case IDC_BACK: + PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_IMPORTTYPE,(LPARAM)ImportTypePageProc); + break; + + case IDOK: + { + TCHAR filename[MAX_PATH]; + + GetDlgItemText(hdlg, IDC_FILENAME, filename, SIZEOF(filename)); + if (_taccess(filename, 4)) { + MessageBox(hdlg, TranslateT("The given file does not exist. Please check that you have entered the name correctly."), TranslateT("Miranda Import"), MB_OK); + break; + } + lstrcpy(importFile, filename); + PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_OPTIONS,(LPARAM)MirandaOptionsPageProc); + } + break; + + case IDCANCEL: + PostMessage(GetParent(hdlg),WM_CLOSE,0,0); + break; + + case IDC_LIST: + if(HIWORD(wParam)==LBN_SELCHANGE) { + int sel = SendDlgItemMessage(hdlg, IDC_LIST, LB_GETCURSEL, 0, 0); + if (sel == LB_ERR) break; + SetDlgItemText(hdlg, IDC_FILENAME, (TCHAR*)SendDlgItemMessage(hdlg, IDC_LIST, LB_GETITEMDATA, sel, 0)); + } + break; + + case IDC_OTHER: + { + OPENFILENAME ofn; + TCHAR str[MAX_PATH], text[256]; + TCHAR *pfd; + int index; + + pfd = Utils_ReplaceVarsT(_T("%miranda_profile%")); + + // TranslateTS doesnt translate \0 separated strings + index = mir_sntprintf(text, 64, _T("%s (*.dat)"), TranslateT("Miranda IM database")) + 1; + _tcscpy(text + index, _T("*.dat")); index += 6; + index += mir_sntprintf(text + index, 64, _T("%s (*.*)"), TranslateT("All Files")) + 1; + _tcscpy(text + index, _T("*.*")); index += 4; + text[index] = 0; + + GetDlgItemText(hdlg, IDC_FILENAME, str, SIZEOF(str)); + ZeroMemory(&ofn, sizeof(ofn)); + ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; + ofn.hwndOwner = hdlg; + ofn.lpstrFilter = text; + ofn.lpstrDefExt = _T("dat"); + ofn.lpstrFile = str; + ofn.Flags = OFN_FILEMUSTEXIST | OFN_EXPLORER | OFN_NOCHANGEDIR | OFN_DONTADDTORECENT; + ofn.nMaxFile = SIZEOF(str); + ofn.lpstrInitialDir = pfd; + if (GetOpenFileName(&ofn)) + SetDlgItemText(hdlg,IDC_FILENAME,str); + + mir_free(pfd); + break; + } + } + break; + case WM_DESTROY: + { + int i; + + for(i=SendDlgItemMessage(hdlg,IDC_LIST,LB_GETCOUNT,0,0)-1;i>=0;i--) + mir_free((char*)SendDlgItemMessage(hdlg,IDC_LIST,LB_GETITEMDATA,i,0)); + break; + } } + + return FALSE; +} + + +INT_PTR CALLBACK MirandaOptionsPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam) +{ + switch(message) { + case WM_INITDIALOG: + TranslateDialogDefault(hdlg); + EnableWindow(GetDlgItem(hdlg,IDC_RADIO_ALL), TRUE); + EnableWindow(GetDlgItem(hdlg,IDC_STATIC_ALL), TRUE); + EnableWindow(GetDlgItem(hdlg,IDC_RADIO_CONTACTS), TRUE); + EnableWindow(GetDlgItem(hdlg,IDC_STATIC_CONTACTS), TRUE); + EnableWindow(GetDlgItem(hdlg,IDC_RADIO_CUSTOM), TRUE); + EnableWindow(GetDlgItem(hdlg,IDC_STATIC_CUSTOM), TRUE); + CheckDlgButton(hdlg,IDC_RADIO_ALL,BST_UNCHECKED); + return TRUE; + + case WM_COMMAND: + switch(LOWORD(wParam)) { + case IDC_BACK: + PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_MIRANDADB,(LPARAM)MirandaPageProc); + break; + + case IDOK: + if(IsDlgButtonChecked(hdlg,IDC_RADIO_ALL)) { + nImportOption = IMPORT_ALL; + nCustomOptions = 0;//IOPT_MSGSENT|IOPT_MSGRECV|IOPT_URLSENT|IOPT_URLRECV; + DoImport = MirandaImport; + PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_PROGRESS,(LPARAM)ProgressPageProc); + break; + } + + if(IsDlgButtonChecked(hdlg,IDC_RADIO_CONTACTS)) { + nImportOption = IMPORT_CONTACTS; + nCustomOptions = 0; + DoImport = MirandaImport; + PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_PROGRESS,(LPARAM)ProgressPageProc); + break; + } + + if(IsDlgButtonChecked(hdlg,IDC_RADIO_CUSTOM)) { + PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_ADVOPTIONS,(LPARAM)MirandaAdvOptionsPageProc); + break; + } + break; + + case IDCANCEL: + PostMessage(GetParent(hdlg), WM_CLOSE, 0, 0); + break; + } + break; + } + return FALSE; +} + +static const UINT InControls[]={IDC_IN_MSG,IDC_IN_URL,IDC_IN_FT,IDC_IN_OTHER}; +static const UINT OutControls[]={IDC_OUT_MSG,IDC_OUT_URL,IDC_OUT_FT,IDC_OUT_OTHER}; +static const UINT SysControls[]={IDC_CONTACTS, IDC_SYSTEM}; + +INT_PTR CALLBACK MirandaAdvOptionsPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam) +{ + switch(message) { + case WM_INITDIALOG: + TranslateDialogDefault(hdlg); + { + struct tm *TM = NULL; + struct _SYSTEMTIME ST = {0}; + + dwSinceDate = DBGetContactSettingDword(NULL,IMPORT_MODULE,"ImportSinceTS",time(NULL)); + + TM = localtime(&dwSinceDate); + + ST.wYear = TM->tm_year + 1900; + ST.wMonth = TM->tm_mon + 1; + ST.wDay = TM->tm_mday; + + DateTime_SetSystemtime(GetDlgItem(hdlg,IDC_DATETIMEPICKER),GDT_VALID,&ST); + } + return TRUE; + + case WM_COMMAND: + switch(LOWORD(wParam)) { + case IDC_BACK: + PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_OPTIONS,(LPARAM)MirandaOptionsPageProc); + break; + + case IDOK: + DoImport = MirandaImport; + nImportOption = IMPORT_CUSTOM; + nCustomOptions = 0; + + if (IsDlgButtonChecked(hdlg,IDC_CONTACTS)) + nCustomOptions |= IOPT_CONTACTS | IOPT_GROUPS; + if (IsDlgButtonChecked(hdlg,IDC_SYSTEM)) + nCustomOptions |= IOPT_SYSTEM; + + // incoming + if (IsDlgButtonChecked(hdlg,IDC_IN_MSG)) + nCustomOptions |= IOPT_MSGRECV; + if (IsDlgButtonChecked(hdlg,IDC_IN_URL)) + nCustomOptions |= IOPT_URLRECV; + if (IsDlgButtonChecked(hdlg,IDC_IN_FT)) + nCustomOptions |= IOPT_FILERECV; + if (IsDlgButtonChecked(hdlg,IDC_IN_OTHER)) + nCustomOptions |= IOPT_OTHERRECV; + + // outgoing + if (IsDlgButtonChecked(hdlg,IDC_OUT_MSG)) + nCustomOptions |= IOPT_MSGSENT; + if (IsDlgButtonChecked(hdlg,IDC_OUT_URL)) + nCustomOptions |= IOPT_URLSENT; + if (IsDlgButtonChecked(hdlg,IDC_OUT_FT)) + nCustomOptions |= IOPT_FILESENT; + if (IsDlgButtonChecked(hdlg,IDC_OUT_OTHER)) + nCustomOptions |= IOPT_OTHERSENT; + + // since date + dwSinceDate = 0; + + if ( IsDlgButtonChecked( hdlg, IDC_SINCE )) { + struct _SYSTEMTIME ST = {0}; + + if (DateTime_GetSystemtime(GetDlgItem(hdlg,IDC_DATETIMEPICKER), &ST) == GDT_VALID) { + struct tm TM = {0}; + + TM.tm_mday = ST.wDay; + TM.tm_mon = ST.wMonth - 1; + TM.tm_year = ST.wYear - 1900; + + dwSinceDate = mktime(&TM); + + DBWriteContactSettingDword(NULL,IMPORT_MODULE,"ImportSinceTS",dwSinceDate); + } } + + if (nCustomOptions) + PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_PROGRESS,(LPARAM)ProgressPageProc); + break; + + case IDCANCEL: + PostMessage(GetParent(hdlg), WM_CLOSE, 0, 0); + break; + + case IDC_SINCE: + EnableWindow(GetDlgItem(hdlg, IDC_DATETIMEPICKER), IsDlgButtonChecked(hdlg, IDC_SINCE)); + break; + + if (HIWORD(wParam) != STN_CLICKED) + break; + + case IDC_ALL: + case IDC_INCOMING: + case IDC_OUTGOING: + { + int i; + + if (LOWORD(wParam) == IDC_ALL) + for (i = 0; i < sizeof(SysControls)/sizeof(SysControls[0]); i++) + CheckDlgButton(hdlg,SysControls[i], !IsDlgButtonChecked(hdlg,SysControls[i])); + + if (LOWORD(wParam) != IDC_OUTGOING) + for (i = 0; i < sizeof(InControls)/sizeof(InControls[0]); i++) + CheckDlgButton(hdlg,InControls[i], !IsDlgButtonChecked(hdlg,InControls[i])); + + if (LOWORD(wParam) != IDC_INCOMING) + for (i = 0; i < sizeof(OutControls)/sizeof(OutControls[0]); i++) + CheckDlgButton(hdlg,OutControls[i], !IsDlgButtonChecked(hdlg,OutControls[i])); + } + break; + + case IDC_MSG: + CheckDlgButton(hdlg,IDC_IN_MSG, !IsDlgButtonChecked(hdlg,IDC_IN_MSG)); + CheckDlgButton(hdlg,IDC_OUT_MSG, !IsDlgButtonChecked(hdlg,IDC_OUT_MSG)); + break; + + case IDC_URL: + CheckDlgButton(hdlg,IDC_IN_URL, !IsDlgButtonChecked(hdlg,IDC_IN_URL)); + CheckDlgButton(hdlg,IDC_OUT_URL, !IsDlgButtonChecked(hdlg,IDC_OUT_URL)); + break; + + case IDC_FT: + CheckDlgButton(hdlg,IDC_IN_FT, !IsDlgButtonChecked(hdlg,IDC_IN_FT)); + CheckDlgButton(hdlg,IDC_OUT_FT, !IsDlgButtonChecked(hdlg,IDC_OUT_FT)); + break; + + case IDC_OTHER: + CheckDlgButton(hdlg,IDC_IN_OTHER, !IsDlgButtonChecked(hdlg,IDC_IN_OTHER)); + CheckDlgButton(hdlg,IDC_OUT_OTHER, !IsDlgButtonChecked(hdlg,IDC_OUT_OTHER)); + break; + } + break; + } + return FALSE; +} + +#ifndef INVALID_SET_FILE_POINTER +#define INVALID_SET_FILE_POINTER ((DWORD)-1) +#endif + +// Read header from file, returns null on failure +struct DBHeader* GetHeader(HANDLE hDbFile) +{ + struct DBHeader* pdbHeader; + DWORD dwBytesRead; + + if (( pdbHeader = (DBHeader*)calloc(1, sizeof(struct DBHeader))) == NULL ) + return NULL; + + // Goto start of file + if (SetFilePointer(hDbFile, 0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) + return FALSE; + + // Read header + if ( !ReadFile(hDbFile, pdbHeader, sizeof(struct DBHeader), &dwBytesRead, NULL ) || + dwBytesRead != sizeof(struct DBHeader)) + return NULL; + + // Return pointer to header + return pdbHeader; +} + +int CheckFileFormat(HANDLE hDbFile) +{ + struct DBHeader* pdbHeader; + + // Read header + if (( pdbHeader = GetHeader(hDbFile)) == NULL ) + return DB_INVALID; + + // Check header signature + if (memcmp(pdbHeader->signature, &dbSignature, sizeof(pdbHeader->signature))) { + AddMessage( LPGEN("Signature mismatch" )); + return DB_INVALID; + } + + // Determine Miranda version + switch (pdbHeader->version) { + case DB_000700: + AddMessage( LPGEN("This looks like a Miranda database, version 0.1.0.0 or above." )); + free(pdbHeader); + return DB_000700; + + default: + AddMessage( LPGEN("Version mismatch" )); + free(pdbHeader); + return DB_INVALID; +} } + +// High level Miranda DB access functions +// Returns true if pValue points to the requested value + +BOOL GetSetting(HANDLE hDbFile, struct DBContact* pDbContact, char* pszModuleName, char* pszSettingName, DBVARIANT* pValue) +{ + struct DBContactSettings* pDbSettings; + if ( pDbSettings = GetSettingsGroupByModuleName(hDbFile, pDbContact, pszModuleName)) { + if ( GetSettingByName( pDbSettings, pszSettingName, pValue )) { + free(pDbSettings); + return TRUE; + } + #ifdef _LOGGING + AddMessage( LPGEN("Failed to find setting %s" ), pszSettingName ); + #endif + free(pDbSettings); + } +#ifdef _LOGGING + else AddMessage( LPGEN("Failed to find module %s" ), pszModuleName ); +#endif + + // Search failed + pValue->type = 0; + return FALSE; +} + +// ** +// ** CONTACT CHAIN +// ** + +// Return offset to first contact +DWORD FindFirstContact(struct DBHeader* pDbHeader) +{ + if (!pDbHeader) + return 0; + + return pDbHeader->ofsFirstContact; +} + +DWORD FindOwnerContact(struct DBHeader* pDbHeader) +{ + if (!pDbHeader) + return 0; + + return pDbHeader->ofsUser; +} + +// Return offset to next contact +DWORD FindNextContact(struct DBContact* pDbContact) +{ + if (!pDbContact) + return 0; + + if (pDbContact->signature != DBCONTACT_SIGNATURE) + return 0; + + return pDbContact->ofsNext; +} + + +// Read the contact at offset 'dwOffset' +// Returns true if successful and pDbContact points to the contact struct +// pDbContact must point to allocated struct +BOOL GetContact(HANDLE hDbFile, DWORD dwOffset, struct DBContact* pDbContact) +{ + DWORD dwBytesRead; + + // Early reject + if (dwOffset == 0 || dwOffset >= dwFileSize) + return FALSE; + + // ** Read and verify the struct + + if (SetFilePointer(hDbFile, (LONG)dwOffset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) + return FALSE; + + if ((!ReadFile(hDbFile, pDbContact, sizeof(struct DBContact), &dwBytesRead, NULL)) || + (dwBytesRead != sizeof(struct DBContact))) + return FALSE; + + if ((pDbContact->signature != DBCONTACT_SIGNATURE) || + (pDbContact->ofsNext >= dwFileSize)) + return FALSE; // Contact corrupted + + return TRUE; +} + +// Return ptr to next setting in settings struct +char* GetNextSetting(char* pDbSetting) +{ + // Get next setting + pDbSetting = pDbSetting + *pDbSetting+1; // Skip name + switch( *(BYTE*)pDbSetting ) { + case DBVT_BYTE: + pDbSetting = pDbSetting+1+1; + break; + + case DBVT_WORD: + pDbSetting = pDbSetting+1+2; + break; + + case DBVT_DWORD: + pDbSetting = pDbSetting+1+4; + break; + + case DBVT_ASCIIZ: + case DBVT_UTF8: + case DBVT_BLOB: + case DBVTF_VARIABLELENGTH: + pDbSetting = pDbSetting + 3 + *(WORD*)(pDbSetting+1); + break; + + case DBVT_DELETED: + AddMessage( LPGEN("DEBUG: Deleted setting treated as 0-length setting")); + pDbSetting = pDbSetting+1; + break; + + default: + // Unknown datatype assert + AddMessage( LPGEN("ERROR: Faulty settings chain")); + return NULL; + } + + return pDbSetting; +} + + +// ** +// ** SETTINGS CHAIN +// ** + +// Return the settings at offset 'dwOffset' +BOOL GetSettingsGroup(HANDLE hDbFile, DWORD dwOffset, struct DBContactSettings** pDbSettings) +{ + DWORD dwBytesRead, dwBlobSize, dwHead; + struct DBContactSettings pSettings; + + // Early reject + if (dwOffset == 0 || dwOffset >= dwFileSize) + return FALSE; + + // ** Read and verify the struct + if (SetFilePointer(hDbFile, dwOffset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) + return FALSE; + + dwHead = offsetof(struct DBContactSettings, blob); + if ((!ReadFile(hDbFile, &pSettings, dwHead, &dwBytesRead, NULL)) || + (dwBytesRead != dwHead)) + return FALSE; + + if (pSettings.signature != DBCONTACTSETTINGS_SIGNATURE) + return FALSE; // Setttings corrupted + + // ** Read the struct and the following blob + dwBlobSize = pSettings.cbBlob; + if (!(*pDbSettings = (DBContactSettings *)calloc(1, sizeof(struct DBContactSettings) + dwBlobSize))) + return FALSE; + + memcpy(*pDbSettings, &pSettings, dwHead ); + + if ((!ReadFile(hDbFile, (*pDbSettings)->blob, sizeof(struct DBContactSettings) - dwHead + dwBlobSize, &dwBytesRead, NULL)) || + (dwBytesRead != sizeof(struct DBContactSettings) - dwHead + dwBlobSize)) + { + free(*pDbSettings); + return FALSE; + } + + return TRUE; +} + +// pDbContact is a ptr to a struct DBContact +// Returns pointer to a struct DBContactSettings or NULL +struct DBContactSettings* GetSettingsGroupByModuleName(HANDLE hDbFile, struct DBContact* pDbContact, char* pszName) +{ + char* pszGroupName; + struct DBContactSettings* pSettingsGroup; + DWORD dwGroupOfs; + + // Get ptr to first settings group + if (!(dwGroupOfs = pDbContact->ofsFirstSettings)) + return NULL; // No settings exists in this contact + + // Loop over all settings groups + while (dwGroupOfs && dwGroupOfs < dwFileSize) { + pSettingsGroup = NULL; + + // Read and verify the struct + if (!GetSettingsGroup(hDbFile, dwGroupOfs, &pSettingsGroup)) + return NULL; // Bad struct + + // Struct OK, now get the name + if ((pszGroupName = GetName(hDbFile, pSettingsGroup->ofsModuleName))) { + + // Is it the right one? + if (strcmp(pszGroupName, pszName) == 0) { + #ifdef _LOGGING + AddMessage( LPGEN("Found module: %s"), pszGroupName ); + #endif + return pSettingsGroup; + } + #ifdef _LOGGING + else AddMessage( LPGEN("Ignoring module: %s"), pszGroupName ); + #endif + } + else AddMessage( LPGEN("Warning: Found module with no name")); + + dwGroupOfs = pSettingsGroup->ofsNext; + + if (pSettingsGroup) + free(pSettingsGroup); + } + + // Search failed + return NULL; +} + +// pDbSettings must point to a complete DBContactSettings struct in memory +int GetSettingByName(struct DBContactSettings* pDbSettings, char* pszSettingName, DBVARIANT* dbv) +{ + char pszName[256]; + // We need at least one setting to start with + char* pDbSetting = (char*)pDbSettings->blob; + if ( !pDbSetting ) + return FALSE; + + // ** pDbSettings now points to the first setting in this module + + // Loop over all settings + while (pDbSetting && *pDbSetting) { + memcpy(pszName, pDbSetting+1, *pDbSetting); + pszName[*pDbSetting] = 0; + + // Is this the right one? + if (strcmp(pszSettingName, pszName) == 0) { + return GetSettingValue(pDbSetting, dbv); + } + + #ifdef _LOGGING + AddMessage( LPGEN("Ignoring setting: %s"), pszName ); + #endif + pDbSetting = GetNextSetting(pDbSetting); + } + + // Search failed + return FALSE; +} + +// dwSettingpointer points to a valid DBSettings struct +int GetSettingValue(char* pBlob, DBVARIANT* dbv) +{ + #ifdef _LOGGING + { + char* pszName = calloc((*pBlob)+1, 1); + memcpy(pszName, pBlob+1, *pBlob); + AddMessage( LPGEN("Getting type %u value for setting: %s"), (BYTE)*(pBlob+(*pBlob)+1), pszName ); + free(pszName); + } + #endif + + // Skip name + pBlob = pBlob + (*pBlob)+1; + dbv->type = ( BYTE )*pBlob++; + + // Check what type it is + switch( dbv->type ) { + case DBVT_BYTE: + dbv->bVal = *pBlob; + return TRUE; + + case DBVT_WORD: + dbv->wVal = *(WORD*)pBlob; + return TRUE; + + case DBVT_DWORD: + dbv->dVal = *(DWORD*)pBlob; + return TRUE; + + case DBVT_ASCIIZ: + case DBVT_UTF8: + dbv->cchVal = *(WORD*)pBlob; + dbv->pszVal = (char *)calloc( dbv->cchVal+1, sizeof( char )); + memcpy( dbv->pszVal, pBlob+2, dbv->cchVal ); + dbv->pszVal[ dbv->cchVal ] = 0; + return TRUE; + + case DBVTF_VARIABLELENGTH: + case DBVT_BLOB: + dbv->cpbVal = *(WORD*)pBlob; + dbv->pbVal = (BYTE *)calloc( dbv->cpbVal+1, sizeof( char )); + memcpy( dbv->pbVal, pBlob+2, dbv->cpbVal ); + dbv->pbVal[ dbv->cpbVal ] = 0; + return TRUE; + + case DBVT_DELETED: + AddMessage( LPGEN("DEBUG: Deleted setting treated as 0-length setting")); + + default: + dbv->type = DBVT_DELETED; + } + + return FALSE; +} + +void FreeVariant( DBVARIANT* dbv ) +{ + switch( dbv->type ) { + case DBVT_ASCIIZ: + case DBVT_UTF8: + if ( dbv->pszVal ) + free( dbv->pszVal ); + break; + + case DBVTF_VARIABLELENGTH: + case DBVT_BLOB: + if ( dbv->pbVal ) + free( dbv->pbVal ); + break; + } + + dbv->type = 0; +} + +void WriteVariant( HANDLE hContact, const char* module, const char* var, DBVARIANT* dbv ) +{ + DBCONTACTWRITESETTING dbw; + dbw.szModule = module; + dbw.szSetting = var; + dbw.value = *dbv; + CallService( MS_DB_CONTACT_WRITESETTING, (WPARAM)hContact, (LPARAM)&dbw ); +} + +// Returns true if pDBEI has been filled in with nice values +// Don't forget to free those pointers! +BOOL GetEvent(HANDLE hDbFile, DWORD dwOffset, DBEVENTINFO* pDBEI) +{ + DWORD dwBytesRead; + struct DBEvent pEvent; + static char pBlob[65536]; + + // Early reject + if (dwOffset == 0 || dwOffset >= dwFileSize) + return FALSE; + + // ** Read and verify the struct + if (SetFilePointer(hDbFile, dwOffset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) + return FALSE; + + if (!ReadFile(hDbFile, &pEvent, offsetof(struct DBEvent, blob), &dwBytesRead, NULL) || + (dwBytesRead != offsetof(struct DBEvent, blob))) + return FALSE; + + if (pEvent.signature != DBEVENT_SIGNATURE) + return FALSE; // Event corrupted + + // ** Read the blob + if ((!ReadFile(hDbFile, pBlob, pEvent.cbBlob, &dwBytesRead, NULL)) || + (dwBytesRead != pEvent.cbBlob)) + { + return FALSE; + } + + // ** Copy the static part to the event info struct + pDBEI->timestamp = pEvent.timestamp; + pDBEI->eventType = pEvent.eventType; + pDBEI->cbSize = sizeof(DBEVENTINFO); + pDBEI->cbBlob = pEvent.cbBlob; + pDBEI->pBlob = (PBYTE)pBlob; + pDBEI->flags = (pEvent.flags & ~(DBEF_SENT+DBEF_READ)) + + ((pEvent.flags & DBEF_SENT) ? DBEF_SENT : DBEF_READ ); // Imported events are always marked READ + + if (!(pDBEI->szModule = GetName(hDbFile, pEvent.ofsModuleName))) { + return FALSE; + } + + return TRUE; +} + +// Returns a pointer to a string with the name +// from a DBModuleName struct if given a file offset +// Returns NULL on failure +char* GetName(HANDLE hDbFile, DWORD dwOffset) +{ + static DWORD dwLastOffset = 0; + static HANDLE hLastDbFile = NULL; + static char szName[256] = {0}; + + DWORD dwBytesRead; + struct DBModuleName pModule; + + // Early reject + if (dwOffset == 0 || dwOffset >= dwFileSize) + return FALSE; + + // Quick lookup + if (dwOffset == dwLastOffset && hDbFile == hLastDbFile) + return szName; + + // ** Read and verify the name struct + if (SetFilePointer(hDbFile, dwOffset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) + return NULL; + + if ((!ReadFile(hDbFile, &pModule, offsetof(struct DBModuleName, name), &dwBytesRead, NULL)) || + (dwBytesRead != offsetof(struct DBModuleName, name))) + return NULL; + + if (pModule.signature != DBMODULENAME_SIGNATURE) { + AddMessage( LPGEN("Modulename corrupted")); + return NULL; // ModuleName corrupted + } + + // ** Name struct OK, now read name into string buffer + if ((!ReadFile(hDbFile, szName, pModule.cbName, &dwBytesRead, NULL)) || (dwBytesRead != pModule.cbName)) { + return NULL; + } + + // terminate string + szName[pModule.cbName] = 0; + + // update last offset + dwLastOffset = dwOffset; + hLastDbFile = hDbFile; + + return szName; +} + +DWORD FindNextEvent(HANDLE hDbFile, DWORD dwOffset) +{ + DWORD dwBytesRead; + struct DBEvent pEvent; + + // Early reject + if (dwOffset == 0 || dwOffset >= dwFileSize) + return FALSE; + + // ** Read and verify the struct + if (SetFilePointer(hDbFile, dwOffset, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) + return FALSE; + + if ((!ReadFile(hDbFile, &pEvent, sizeof(struct DBEvent), &dwBytesRead, NULL)) || + (dwBytesRead != sizeof(struct DBEvent))) + return FALSE; + + if ( pEvent.signature != DBEVENT_SIGNATURE || pEvent.ofsNext > dwFileSize ) + return FALSE; // Event corrupted + + return pEvent.ofsNext; +} + +int ImportGroups(HANDLE hDbFile, struct DBHeader* pdbHeader) +{ + struct DBContactSettings* pDbSettings; + struct DBContact DbContact; + char* pSetting; + DWORD dwOffset; + int nGroups = 0; + + // Find owner data + dwOffset = pdbHeader->ofsUser; + if (!GetContact(hDbFile, dwOffset, &DbContact)) { + AddMessage( LPGEN("No owner found.")); + return -1; + } + + // Find the module with the groups, and import them all + if ( pDbSettings = GetSettingsGroupByModuleName( hDbFile, &DbContact, "CListGroups" )) { + pSetting = (char *)pDbSettings->blob; + while ( pSetting && *pSetting ) { + DBVARIANT dbv; + if ( GetSettingValue( pSetting, &dbv )) { + if ( CreateGroup( dbv.type, dbv.pszVal+1, NULL )) + nGroups++; + FreeVariant( &dbv ); + } + pSetting = GetNextSetting(pSetting); + } + free(pDbSettings); + } + + return nGroups; +} + +HANDLE ImportContact(HANDLE hDbFile, struct DBContact Contact) +{ + HANDLE hContact; + DBVARIANT group, nick, dbv; + char* pszProtoName; + char* pszUniqueSetting; + char* pszUserName; + char id[ 40 ]; + + // Check what protocol this contact belongs to + if ( !GetSetting( hDbFile, &Contact, "Protocol", "p", &dbv )) { + AddMessage( LPGEN("Skipping contact with no protocol")); + return INVALID_HANDLE_VALUE; + } + + pszProtoName = NEWSTR_ALLOCA( dbv.pszVal ); + FreeVariant( &dbv ); + + if ( !IsProtocolLoaded( pszProtoName )) { + AddMessage( LPGEN("Skipping contact, %s not installed."), pszProtoName ); + return INVALID_HANDLE_VALUE; + } + + // Skip protocols with no unique id setting (some non IM protocols return NULL) + pszUniqueSetting = (char*)CallProtoService(pszProtoName, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0); + if ( !pszUniqueSetting || (INT_PTR)pszUniqueSetting == CALLSERVICE_NOTFOUND ) { + AddMessage( LPGEN("Skipping non-IM contact (%s)"), pszProtoName ); + return INVALID_HANDLE_VALUE; + } + + if ( !GetSetting(hDbFile, &Contact, pszProtoName, pszUniqueSetting, &dbv )) { + AddMessage( LPGEN("Skipping %s contact, ID not found"), pszProtoName ); + return INVALID_HANDLE_VALUE; + } + + // Does the contact already exist? + if ( dbv.type == DBVT_DWORD ) { + pszUserName = _ltoa( dbv.dVal, id, 10 ); + hContact = HContactFromNumericID( pszProtoName, pszUniqueSetting, dbv.dVal ); + } + else { + pszUserName = NEWSTR_ALLOCA( dbv.pszVal ); + hContact = HContactFromID( pszProtoName, pszUniqueSetting, dbv.pszVal ); + } + + if ( hContact != INVALID_HANDLE_VALUE ) { + AddMessage( LPGEN("Skipping duplicate %s contact %s"), pszProtoName, pszUserName ); + FreeVariant( &dbv ); + return INVALID_HANDLE_VALUE; + } + // No, add contact and copy some important settings + GetSetting(hDbFile, &Contact, "CList", "Group", &group); + + if ( !GetSetting( hDbFile, &Contact, "CList", "MyHandle", &nick )) + GetSetting(hDbFile, &Contact, pszProtoName, "Nick", &nick ); + + hContact = AddContact( hdlgProgress, pszProtoName, pszUniqueSetting, &dbv, &nick, &group ); + + if ( hContact != INVALID_HANDLE_VALUE) { + + // Hidden? + if ( GetSetting( hDbFile, &Contact, "CList", "Hidden", &dbv )) { + WriteVariant( hContact, "CList", "Hidden", &dbv ); + FreeVariant( &dbv ); + } + // Ignore settings + if ( GetSetting( hDbFile, &Contact, "Ignore", "Mask1", &dbv )) { + WriteVariant( hContact, "Ignore", "Mask1", &dbv ); + FreeVariant( &dbv ); + } + + // Apparent mode + if ( GetSetting( hDbFile, &Contact, pszProtoName, "ApparentMode", &dbv )) { + WriteVariant( hContact, pszProtoName, "ApparentMode", &dbv ); + FreeVariant( &dbv ); + } + + // Nick + if ( GetSetting( hDbFile, &Contact, pszProtoName, "Nick", &dbv )) { + WriteVariant( hContact, pszProtoName, "Nick", &dbv ); + FreeVariant( &dbv ); + } + + // Myhandle + if ( GetSetting( hDbFile, &Contact, pszProtoName, "MyHandle", &dbv )) { + WriteVariant( hContact, pszProtoName, "MyHandle", &dbv ); + FreeVariant( &dbv ); + } + + // First name + if ( GetSetting( hDbFile, &Contact, pszProtoName, "FirstName", &dbv )) { + WriteVariant( hContact, pszProtoName, "FirstName", &dbv ); + FreeVariant( &dbv ); + } + + // Last name + if ( GetSetting( hDbFile, &Contact, pszProtoName, "LastName", &dbv )) { + WriteVariant( hContact, pszProtoName, "LastName", &dbv ); + FreeVariant( &dbv ); + } + + // About + if ( GetSetting( hDbFile, &Contact, pszProtoName, "About", &dbv )) { + WriteVariant( hContact, pszProtoName, "About", &dbv ); + FreeVariant( &dbv ); + } + } + else AddMessage( LPGEN("Unknown error while adding %s contact %s"), pszProtoName, pszUserName ); + + return hContact; +} + +// This function should always be called after contact import. That is +// why there are no messages for errors related to contacts. Those +// would only be a repetition of the messages printed during contact +// import. + +static void ImportHistory(HANDLE hDbFile, struct DBContact Contact, PROTOCOLDESCRIPTOR **protocol, int protoCount) +{ + HANDLE hContact = INVALID_HANDLE_VALUE; + DWORD dwOffset; + MSG msg; + DBVARIANT proto; + int i, skipAll, bIsVoidContact; + + // Is it contats history import? + if ( protoCount == 0 ) { + + // Check what protocol this contact belongs to + if ( GetSetting( hDbFile, &Contact, "Protocol", "p", &proto )) { + + // Protocol installed? + if ( IsProtocolLoaded( proto.pszVal )) { + // Is contact in database? + char* pszUniqueSetting = (char*)CallProtoService( proto.pszVal, PS_GETCAPS, PFLAG_UNIQUEIDSETTING, 0); + + // Skip protocols with no unique id setting (some non IM protocols return NULL) + if ( pszUniqueSetting && ( INT_PTR )pszUniqueSetting != CALLSERVICE_NOTFOUND ) { + DBVARIANT dbv; + if ( GetSetting( hDbFile, &Contact, proto.pszVal, pszUniqueSetting, &dbv )) { + if ( dbv.type == DBVT_DWORD ) + hContact = HContactFromNumericID( proto.pszVal, pszUniqueSetting, dbv.dVal ); + else + hContact = HContactFromID( proto.pszVal, pszUniqueSetting, dbv.pszVal ); + FreeVariant( &dbv ); + } } } + FreeVariant( &proto ); + } + } + else hContact = NULL; //system history import + + // OK to import this chain? + if (hContact == INVALID_HANDLE_VALUE) { + nSkippedContacts++; + return; + } + + i = skipAll = 0; + bIsVoidContact = CallService( MS_DB_EVENT_GETCOUNT, ( WPARAM )hContact, 0 ) == 0; + + // Get the start of the event chain + dwOffset = Contact.ofsFirstEvent; + while (dwOffset) { + int skip = 0; + + // Copy the event and import it + DBEVENTINFO dbei = { 0 }; + if (GetEvent(hDbFile, dwOffset, &dbei)) { + // check protocols during system history import + if (hContact == NULL) { + int i; + skipAll = 1; + + for(i = 0; i < protoCount; i++) + if (!strcmp(dbei.szModule, protocol[i]->szName)) { //&& protocol[i]->type == PROTOTYPE_PROTOCOL) + skipAll = 0; + break; + } + + skip = skipAll; + } + + // custom filtering + if (!skip && nImportOption == IMPORT_CUSTOM) { + BOOL sent = (dbei.flags&DBEF_SENT); + + if (dbei.timestamp < (DWORD)dwSinceDate) + skip = 1; + + if (!skip) { + if (hContact) { + skip = 1; + switch(dbei.eventType) { + case EVENTTYPE_MESSAGE: + if ((sent?IOPT_MSGSENT:IOPT_MSGRECV)&nCustomOptions) + skip = 0; + break; + case EVENTTYPE_FILE: + if ((sent?IOPT_FILESENT:IOPT_FILERECV)&nCustomOptions) + skip = 0; + break; + case EVENTTYPE_URL: + if ((sent?IOPT_URLSENT:IOPT_URLRECV)&nCustomOptions) + skip = 0; + break; + default: + if ((sent?IOPT_OTHERSENT:IOPT_OTHERRECV)&nCustomOptions) + skip = 0; + break; + } + } + else if ( !( nCustomOptions & IOPT_SYSTEM )) + skip = 1; + } + + if (skip) + nSkippedEvents++; + } + + if (!skip) { + // Check for duplicate entries + if ( !IsDuplicateEvent( hContact, dbei )) { + // Add dbevent + if (!bIsVoidContact) + dbei.flags &= ~DBEF_FIRST; + if (CallService(MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&dbei)) + nMessagesCount++; + else + AddMessage( LPGEN("Failed to add message")); + } + else + nDupes++; + } + } + + if ( !( i%10 )) { + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } } + + // skip this chain if needed + if ( skipAll ) + break; + + // Get next event + dwOffset = FindNextEvent(hDbFile, dwOffset); + i++; + } +} + +static void MirandaImport(HWND hdlg) +{ + int nDBVersion; + int i; + int nNumberOfContacts = 0; + MSG msg; + DWORD dwTimer; + DWORD dwOffset; + HANDLE hFile; + char* pszModuleName = NULL; + struct DBHeader* pdbHeader = NULL; + struct DBContact Contact; + + // Just to keep the macros happy + hdlgProgress = hdlg; + + // Reset statistics + nSkippedEvents = 0; + nDupes = 0; + nContactsCount = 0; + nMessagesCount = 0; + nGroupsCount = 0; + nSkippedContacts = 0; + SetProgress(0); + + // Open database + hFile = CreateFile(importFile, + GENERIC_READ, // open for reading + 0, // do not share + NULL, // no security + OPEN_EXISTING, // existing file only + FILE_ATTRIBUTE_NORMAL, // normal file + NULL); // no attr. template + + // Read error + if (hFile == INVALID_HANDLE_VALUE) { + AddMessage( LPGEN("Could not open file.")); + SetProgress(100); + return; + } + + // Check filesize + dwFileSize = GetFileSize(hFile, NULL) ; + if ((dwFileSize == INVALID_FILE_SIZE) || (dwFileSize < sizeof(struct DBHeader))) { + AddMessage( LPGEN("This is not a valid Miranda IM database.")); + SetProgress(100); + CloseHandle(hFile); + return; + } + + // Check header and database version + nDBVersion = CheckFileFormat(hFile); + if (nDBVersion == DB_INVALID) { + AddMessage( LPGEN("This is not a valid Miranda IM database.")); + SetProgress(100); + CloseHandle(hFile); + return; + } + + // Load database header + if (!(pdbHeader = GetHeader(hFile))) { + AddMessage( LPGEN("Read failure.")); + SetProgress(100); + CloseHandle(hFile); + return; + } + + // Get number of contacts + nNumberOfContacts = pdbHeader->contactCount; + AddMessage( LPGEN("Number of contacts in database: %d"), nNumberOfContacts ); + AddMessage( "" ); + + // Configure database for fast writing + CallService(MS_DB_SETSAFETYMODE, FALSE, 0); + + // Start benchmark timer + dwTimer = time(NULL); + + // Import Groups + if (nImportOption == IMPORT_ALL || (nCustomOptions & IOPT_GROUPS)) { + AddMessage( LPGEN("Importing groups.")); + nGroupsCount = ImportGroups(hFile, pdbHeader); + if (nGroupsCount == -1) + AddMessage( LPGEN("Group import failed.")); + + AddMessage( "" ); + } + // End of Import Groups + + // Import Contacts + if (nImportOption != IMPORT_CUSTOM || (nCustomOptions & IOPT_CONTACTS)) { + AddMessage( LPGEN("Importing contacts.")); + i = 1; + dwOffset = FindFirstContact(pdbHeader); + while (dwOffset && (dwOffset < dwFileSize)) { + if (!GetContact(hFile, dwOffset, &Contact)) { + AddMessage( LPGEN("ERROR: Chain broken, no valid contact at %d"), dwOffset ); + SetProgress(100); + break; + } + + if (ImportContact(hFile, Contact) != INVALID_HANDLE_VALUE) + nContactsCount++; + + // Update progress bar + SetProgress(100 * i / nNumberOfContacts); + i++; + + // Process queued messages + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + // Get next contact in chain + dwOffset = FindNextContact(&Contact); + } + } + else AddMessage( LPGEN("Skipping new contacts import.")); + AddMessage( "" ); + // End of Import Contacts + + // Import history + if (nImportOption != IMPORT_CONTACTS) { + // Import NULL contact message chain + if (nImportOption == IMPORT_ALL || (nCustomOptions & IOPT_SYSTEM)) { + AddMessage( LPGEN("Importing system history.")); + dwOffset = FindOwnerContact(pdbHeader); + if (!GetContact(hFile, dwOffset, &Contact)) { + AddMessage( LPGEN("ERROR: Chain broken, no valid contact at %d"), dwOffset ); + SetProgress(100); + } + else { + PROTOCOLDESCRIPTOR **protocol; + int protoCount; + + CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&protoCount, (LPARAM)&protocol); + + if (protoCount > 0) + ImportHistory(hFile, Contact, protocol, protoCount); + } + } + else AddMessage( LPGEN("Skipping system history import.")); + + AddMessage( "" ); + + // Import other contact messages + if (nImportOption == IMPORT_ALL || (nCustomOptions & 2046)) { // 2 - 1024 types + AddMessage( LPGEN("Importing history.")); + dwOffset = FindFirstContact(pdbHeader); + for(i=1; i <= nNumberOfContacts; i++) { + if (!GetContact(hFile, dwOffset, &Contact)) { + AddMessage( LPGEN("ERROR: Chain broken, no valid contact at %d"), dwOffset ); + SetProgress(100); + break; + } + + ImportHistory(hFile, Contact, NULL, 0); + + SetProgress(100 * i / nNumberOfContacts); + dwOffset = FindNextContact(&Contact); + } + } + else AddMessage( LPGEN("Skipping history import.")); + + AddMessage( "" ); + } + // End of Import History + + // Restore database writing mode + CallService(MS_DB_SETSAFETYMODE, TRUE, 0); + + // Clean up before exit + CloseHandle(hFile); + free(pdbHeader); + + // Stop timer + dwTimer = time(NULL) - dwTimer; + + // Print statistics + AddMessage( LPGEN("Import completed in %d seconds."), dwTimer ); + SetProgress(100); + AddMessage((nImportOption == IMPORT_CONTACTS) ? + LPGEN("Added %d contacts and %d groups.") : LPGEN("Added %d contacts, %d groups and %d events."), + nContactsCount, nGroupsCount, nMessagesCount); + + if ( nImportOption != IMPORT_CONTACTS ) { + if (nSkippedContacts) + AddMessage( LPGEN("Skipped %d contacts."), nSkippedContacts ); + + AddMessage((nImportOption == IMPORT_CUSTOM) ? + LPGEN("Skipped %d duplicates and %d filtered events.") : LPGEN("Skipped %d duplicates."), + nDupes, nSkippedEvents); +} } diff --git a/plugins/Import/src/mirandadb0700.h b/plugins/Import/src/mirandadb0700.h new file mode 100644 index 0000000000..2c77588951 --- /dev/null +++ b/plugins/Import/src/mirandadb0700.h @@ -0,0 +1,142 @@ +/* + +Import plugin for Miranda IM + +Copyright (C) 2001,2002,2003,2004 Martin Öberg, Richard Hughes, Roland Rabien & Tristan Van de Vreede + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + + + +//all offsets are relative to the start of the file +//offsets are 0 if there is nothing in the chain or this is the last in the +//chain + + + + +/* tree diagram + +DBHeader + |-->end of file (plain offset) + |-->first contact (DBContact) + | |-->next contact (DBContact) + | | \--> ... + | |-->first settings (DBContactSettings) + | | |-->next settings (DBContactSettings) + | | | \--> ... + | | \-->module name (DBModuleName) + | \-->first/last/firstunread event + |-->user contact (DBContact) + | |-->next contact=NULL + | |-->first settings as above + | \-->first/last/firstunread event as above + \-->first module name (DBModuleName) + \-->next module name (DBModuleName) + \--> ... +*/ + +#define DB_THIS_VERSION 0x00000700u + +#include +struct DBHeader { + BYTE signature[16]; // 'Miranda ICQ DB',0,26 + DWORD version; //as 4 bytes, ie 1.2.3.10=0x0102030a + //this version is 0x00000700 + DWORD ofsFileEnd; //offset of the end of the database - place to write + //new structures + DWORD slackSpace; //a counter of the number of bytes that have been + //wasted so far due to deleting structures and/or + //re-making them at the end. We should compact when + //this gets above a threshold + DWORD contactCount; //number of contacts in the chain,excluding the user + DWORD ofsFirstContact; //offset to first struct DBContact in the chain + DWORD ofsUser; //offset to struct DBContact representing the user + DWORD ofsFirstModuleName; //offset to first struct DBModuleName in the chain +}; + +#define DBCONTACT_SIGNATURE 0x43DECADEu +struct DBContact { + DWORD signature; + DWORD ofsNext; //offset to the next contact in the chain. zero if + //this is the 'user' contact or the last contact + //in the chain + DWORD ofsFirstSettings; //offset to the first DBContactSettings in the + //chain for this contact. + DWORD eventCount; //number of events in the chain for this contact + DWORD ofsFirstEvent,ofsLastEvent; //offsets to the first and last DBEvent in + //the chain for this contact + DWORD ofsFirstUnreadEvent; //offset to the first (chronological) unread event + //in the chain, 0 if all are read + DWORD timestampFirstUnread; //timestamp of the event at ofsFirstUnreadEvent +}; + +#define DBMODULENAME_SIGNATURE 0x4DDECADEu +struct DBModuleName { + DWORD signature; + DWORD ofsNext; //offset to the next module name in the chain + BYTE cbName; //number of characters in this module name + char name[1]; //name, no nul terminator +}; + +#define DBCONTACTSETTINGS_SIGNATURE 0x53DECADEu +struct DBContactSettings { + DWORD signature; + DWORD ofsNext; //offset to the next contactsettings in the chain + DWORD ofsModuleName; //offset to the DBModuleName of the owner of these + //settings + DWORD cbBlob; //size of the blob in bytes. May be larger than the + //actual size for reducing the number of moves + //required using granularity in resizing + BYTE blob[1]; //the blob. a back-to-back sequence of DBSetting + //structs, the last has cbName=0 +}; + +/* not a valid structure, content is figured out on the fly +struct DBSetting { + BYTE cbName; //number of bytes in the name of this setting + //this =0 marks the end + char szName[...]; //setting name, excluding nul + BYTE dataType; //type of data. see m_database.h, db/contact/getsetting + union { //a load of types of data, length is defined by dataType + BYTE bVal; WORD wVal; DWORD dVal; + struct { + WORD cbString; + char szVal[...]; //excludes nul terminator + }; + struct { + WORD cbBlob; + BYTE blobVal[...]; + }; + }; +}; +*/ + +#define DBEVENT_SIGNATURE 0x45DECADEu +struct DBEvent { + DWORD signature; + DWORD ofsPrev,ofsNext; //offset to the previous and next events in the + //chain. Chain is sorted chronologically + DWORD ofsModuleName; //offset to a DBModuleName struct of the name of + //the owner of this event + DWORD timestamp; //seconds since 00:00:00 01/01/1970 + DWORD flags; //see m_database.h, db/event/add + WORD eventType; //module-defined event type + DWORD cbBlob; //number of bytes in the blob + BYTE blob[1]; //the blob. module-defined formatting +}; +#include diff --git a/plugins/Import/src/mirandahistory.cpp b/plugins/Import/src/mirandahistory.cpp new file mode 100644 index 0000000000..ba7a923df7 --- /dev/null +++ b/plugins/Import/src/mirandahistory.cpp @@ -0,0 +1,208 @@ +/* +Miranda ICQ: the free icq client for MS Windows +Copyright (C) 2000-2 Richard Hughes, Roland Rabien & Tristan Van de Vreede + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#include +#include +#include +#include "resource.h" +#include "import.h" + +BOOL CALLBACK MirandaPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam); +BOOL CALLBACK FinishedPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam); +BOOL CALLBACK ProgressPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam); +extern char importFile[MAX_PATH]; +extern void (*DoImport)(HWND); +static void OldMirandaHistoryImport(HWND hdlgProgress); +HANDLE HContactFromUIN(DWORD uin); +HANDLE HistoryImportFindContact(HWND hdlgProgress,DWORD uin,int addUnknown); +static DWORD importOptions; + +BOOL CALLBACK MirandaHistoryPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam) +{ + switch(message) { + case WM_INITDIALOG: + CheckDlgButton(hdlg,IDC_ADDUNKNOWN,BST_CHECKED); + CheckDlgButton(hdlg,IDC_MSGRECV,BST_CHECKED); + CheckDlgButton(hdlg,IDC_MSGSENT,BST_CHECKED); + CheckDlgButton(hdlg,IDC_URLRECV,BST_CHECKED); + CheckDlgButton(hdlg,IDC_URLSENT,BST_CHECKED); + CheckDlgButton(hdlg,IDC_AUTHREQ,BST_CHECKED); + CheckDlgButton(hdlg,IDC_ADDED,BST_CHECKED); + return TRUE; + case WM_COMMAND: + switch(LOWORD(wParam)) { + case IDC_BACK: + PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_MIRANDADB,(LPARAM)MirandaPageProc); + break; + case IDOK: + importOptions=0; + if(IsDlgButtonChecked(hdlg,IDC_ADDUNKNOWN)) importOptions|=IOPT_ADDUNKNOWN; + if(IsDlgButtonChecked(hdlg,IDC_MSGSENT)) importOptions|=IOPT_MSGSENT; + if(IsDlgButtonChecked(hdlg,IDC_MSGRECV)) importOptions|=IOPT_MSGRECV; + if(IsDlgButtonChecked(hdlg,IDC_URLSENT)) importOptions|=IOPT_URLSENT; + if(IsDlgButtonChecked(hdlg,IDC_URLRECV)) importOptions|=IOPT_URLRECV; + if(IsDlgButtonChecked(hdlg,IDC_AUTHREQ)) importOptions|=IOPT_AUTHREQ; + if(IsDlgButtonChecked(hdlg,IDC_ADDED)) importOptions|=IOPT_ADDED; + DoImport=OldMirandaHistoryImport; + PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_PROGRESS,(LPARAM)ProgressPageProc); + break; + case IDCANCEL: + PostMessage(GetParent(hdlg),WM_CLOSE,0,0); + break; + } + break; + } + return FALSE; +} + +#define HISTORY_MSGRECV 1 +#define HISTORY_MSGSEND 2 +#define HISTORY_URLRECV 3 +#define HISTORY_URLSEND 4 +#define HISTORY_AUTHREQ 5 +#define HISTORY_ADDED 6 +#define issent(t) ((t)==HISTORY_MSGSEND || (t)==HISTORY_URLSEND) +static int historyTypeToOption[]={0,IOPT_MSGRECV,IOPT_MSGSENT,IOPT_URLRECV,IOPT_URLSENT,IOPT_AUTHREQ,IOPT_ADDED}; + +static PBYTE ReadHistoryLines(FILE *fp,int *cbBlob) +{ + char str[2048]; + char *blob; + int ofs; + *cbBlob=0; + blob=NULL; + while(fgets(str,sizeof(str),fp) && lstrcmp(str,"\xEE\xEE\xEE\xEE\r\n")) { + ofs=*cbBlob; + *cbBlob+=lstrlen(str); + blob=(char*)realloc(blob,*cbBlob+1); + lstrcpy(blob+ofs,str); + } + if (*cbBlob) { + (*cbBlob)--; + blob[*cbBlob-1]=0; + } + else { + *cbBlob=1; + blob=(char*)malloc(1); + blob[0]=0; + } + return (PBYTE)blob; +} + +static void OldMirandaHistoryImport(HWND hdlgProgress) +{ + int fileSize; + FILE *fp; + char str[2048],*eol,*timeofs; + HANDLE hContact; + int type; + DWORD uin; + struct tm tmEventTime; + DBEVENTINFO dbei; + + AddMessage("Old Miranda history import routines initialised"); + fp=fopen(importFile,"rb"); + AddMessage("Calibrating status support functions"); + fseek(fp,0,SEEK_END); + fileSize=ftell(fp); + fseek(fp,0,SEEK_SET); + SetProgress(0); + + ZeroMemory(&dbei,sizeof(dbei)); + dbei.cbSize=sizeof(dbei); + dbei.szModule=ICQOSCPROTONAME; + + while(!feof(fp)) { + SetProgress(100*ftell(fp)/fileSize); + if(fgets(str,sizeof(str),fp)==NULL) break; + eol=str+lstrlen(str)-1; + + while(*eol=='\r' || *eol=='\n' && eol!=str-1) + *(eol--)=0; + + if(lstrlen(str)<20) continue; + type=*eol; + uin=strtoul(str,NULL,10); + if(uin==0) continue; //skip MSN + timeofs=str+lstrlen(str)-20; + tmEventTime.tm_hour=atoi(timeofs); + timeofs=strchr(timeofs,':'); + if(timeofs==NULL) continue; + tmEventTime.tm_min=atoi(timeofs+1); + tmEventTime.tm_sec=0; + tmEventTime.tm_isdst=-1; + tmEventTime.tm_mday=atoi(timeofs+7); + tmEventTime.tm_mon=atoi(timeofs+10)-1; + tmEventTime.tm_year=atoi(timeofs+13)-1900; + dbei.timestamp=mktime(&tmEventTime)+_timezone; + if (!(importOptions&historyTypeToOption[type])) continue; + hContact=HistoryImportFindContact(hdlgProgress,uin,importOptions&IOPT_ADDUNKNOWN); + if(hContact==INVALID_HANDLE_VALUE) break; + dbei.flags=issent(type)?DBEF_SENT:DBEF_READ; + switch(type) { + case HISTORY_MSGRECV: + case HISTORY_MSGSEND: + dbei.eventType=EVENTTYPE_MESSAGE; + dbei.pBlob=ReadHistoryLines(fp,&dbei.cbBlob); + CallService(MS_DB_EVENT_ADD,(WPARAM)hContact,(LPARAM)&dbei); + break; + case HISTORY_URLRECV: + case HISTORY_URLSEND: + dbei.eventType=EVENTTYPE_URL; + dbei.pBlob=ReadHistoryLines(fp,&dbei.cbBlob); + { char *endOfUrl; + endOfUrl=strchr(dbei.pBlob,'\r'); + if(endOfUrl!=NULL) { + *endOfUrl=0; + dbei.cbBlob--; + MoveMemory(endOfUrl+1,endOfUrl+2,dbei.cbBlob-(endOfUrl-dbei.pBlob)); + } + } + CallService(MS_DB_EVENT_ADD,(WPARAM)hContact,(LPARAM)&dbei); + break; + case HISTORY_AUTHREQ: + dbei.eventType=EVENTTYPE_AUTHREQUEST; + dbei.pBlob=ReadHistoryLines(fp,&dbei.cbBlob); + dbei.pBlob=(PBYTE)realloc(dbei.pBlob,dbei.cbBlob+8); + MoveMemory(dbei.pBlob+8,dbei.pBlob,dbei.cbBlob); + *(PDWORD)dbei.pBlob=uin; + *(char*)(dbei.pBlob+4)=0; //leave nick, first, last, email blank + *(char*)(dbei.pBlob+5)=0; + *(char*)(dbei.pBlob+6)=0; + *(char*)(dbei.pBlob+7)=0; + dbei.cbBlob+=8; + CallService(MS_DB_EVENT_ADD,(WPARAM)(HANDLE)NULL,(LPARAM)&dbei); + break; + case HISTORY_ADDED: + dbei.eventType=EVENTTYPE_ADDED; + dbei.pBlob=(PBYTE)malloc(8); + dbei.cbBlob=8; + *(PDWORD)dbei.pBlob=uin; + *(char*)(dbei.pBlob+4)=0; //leave nick, first, last, email blank + *(char*)(dbei.pBlob+5)=0; + *(char*)(dbei.pBlob+6)=0; + *(char*)(dbei.pBlob+7)=0; + CallService(MS_DB_EVENT_ADD,(WPARAM)(HANDLE)NULL,(LPARAM)&dbei); + break; + } + } + AddMessage("Terminating cached I/O access"); + fclose(fp); + AddMessage("Import completed successfully"); + SetProgress(100); +} \ No newline at end of file diff --git a/plugins/Import/src/progress.cpp b/plugins/Import/src/progress.cpp new file mode 100644 index 0000000000..99412f647a --- /dev/null +++ b/plugins/Import/src/progress.cpp @@ -0,0 +1,100 @@ +/* + +Import plugin for Miranda IM + +Copyright (C) 2001-2005 Martin Öberg, Richard Hughes, Roland Rabien & Tristan Van de Vreede + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include +#include +#include + +#include "import.h" +#include "resource.h" + +#define PROGM_START (WM_USER+100) + +INT_PTR CALLBACK FinishedPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam); + +void (*DoImport)(HWND); + +INT_PTR CALLBACK ProgressPageProc(HWND hdlg,UINT message,WPARAM wParam,LPARAM lParam) +{ + switch(message) { + case WM_INITDIALOG: + TranslateDialogDefault(hdlg); + SendMessage(GetParent(hdlg),WIZM_DISABLEBUTTON,0,0); + SendMessage(GetParent(hdlg),WIZM_DISABLEBUTTON,1,0); + SendMessage(GetParent(hdlg),WIZM_DISABLEBUTTON,2,0); + SendDlgItemMessage(hdlg,IDC_PROGRESS,PBM_SETRANGE,0,MAKELPARAM(0,100)); + PostMessage(hdlg,PROGM_START,0,0); + return TRUE; + + case PROGM_SETPROGRESS: + SendDlgItemMessage(hdlg,IDC_PROGRESS,PBM_SETPOS,wParam,0); + break; + + case PROGM_ADDMESSAGE: + { + int i=SendDlgItemMessage(hdlg,IDC_STATUS,LB_ADDSTRING,0,lParam); + SendDlgItemMessage(hdlg,IDC_STATUS,LB_SETTOPINDEX,i,0); + } + break; + + case PROGM_START: + DoImport(hdlg); + SendMessage(GetParent(hdlg),WIZM_ENABLEBUTTON,1,0); + SendMessage(GetParent(hdlg),WIZM_ENABLEBUTTON,2,0); + break; + + case WM_COMMAND: + switch(LOWORD(wParam)) { + case IDOK: + PostMessage(GetParent(hdlg),WIZM_GOTOPAGE,IDD_FINISHED,(LPARAM)FinishedPageProc); + break; + case IDCANCEL: + PostMessage(GetParent(hdlg),WM_CLOSE,0,0); + break; + } + break; + } + return FALSE; +} + +void AddMessage( const char* fmt, ... ) +{ + va_list args; + char msgBuf[ 4096 ]; + va_start( args, fmt ); + + mir_vsnprintf( msgBuf, sizeof(msgBuf), Translate(fmt), args ); + + #ifdef _LOGGING + { + FILE *stream; + stream = fopen("Import Debug.log", "a"); + fprintf(stream, "%s\n", msgBuf); + fclose(stream); + } + #endif + + { TCHAR* str = mir_a2t( msgBuf ); + SendMessage( hdlgProgress, PROGM_ADDMESSAGE, 0, ( LPARAM )str ); + mir_free( str ); + } +} diff --git a/plugins/Import/src/resource.h b/plugins/Import/src/resource.h new file mode 100644 index 0000000000..7bf769f14d --- /dev/null +++ b/plugins/Import/src/resource.h @@ -0,0 +1,64 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by resource.rc +// +#define IDC_BACK 3 +#define IDD_WIZARD 101 +#define IDD_OPTIONS 102 +#define IDD_ICQSERVER 104 +#define IDD_IMPORTTYPE 106 +#define IDD_WIZARDINTRO 107 +#define IDD_FINISHED 108 +#define IDD_MIRABILISDB 109 +#define IDD_MIRANDADB 110 +#define IDD_PROGRESS 111 +#define IDD_ADVOPTIONS 112 +#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_STATUS 1009 +#define IDC_MIRABILISRUNNING 1010 +#define IDC_MIRABILISACCOUNT 1011 +#define IDC_RADIO_ALL 1016 +#define IDC_RADIO_CONTACTS 1017 +#define IDC_RADIO_CUSTOM 1018 +#define IDC_STATIC_ALL 1019 +#define IDC_STATIC_CONTACTS 1020 +#define IDC_STATIC_CUSTOM 1021 +#define IDC_DATETIMEPICKER 1023 +#define IDC_IN_FT 1024 +#define IDC_CONTACTS 1025 +#define IDC_SYSTEM 1026 +#define IDC_SINCE 1027 +#define IDC_IN_MSG 1028 +#define IDC_IN_URL 1029 +#define IDC_OUT_FT 1030 +#define IDC_OUT_MSG 1031 +#define IDC_OUT_URL 1032 +#define IDC_IN_OTHER 1033 +#define IDC_OUT_OTHER 1034 +#define IDC_INCOMING 1035 +#define IDC_OUTGOING 1036 +#define IDC_ALL 1037 +#define IDC_MSG 1038 +#define IDC_URL 1039 +#define IDC_FILE 1040 +#define IDC_FT 1040 +#define IDC_STATIC -1 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 105 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1041 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/plugins/Import/src/version.h b/plugins/Import/src/version.h new file mode 100644 index 0000000000..58f9cf348c --- /dev/null +++ b/plugins/Import/src/version.h @@ -0,0 +1,5 @@ +#include + +#define __FILEVERSION_STRING MIRANDA_VERSION_FILEVERSION +#define __VERSION_STRING MIRANDA_VERSION_STRING +#define __VERSION_DWORD MIRANDA_VERSION_DWORD diff --git a/plugins/Import/src/wizard.cpp b/plugins/Import/src/wizard.cpp new file mode 100644 index 0000000000..780501a10a --- /dev/null +++ b/plugins/Import/src/wizard.cpp @@ -0,0 +1,216 @@ +/* + +Import plugin for Miranda IM + +Copyright (C) 2001-2005 Martin Öberg, Richard Hughes, Roland Rabien & Tristan Van de Vreede + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "import.h" +#include "resource.h" + +INT_PTR CALLBACK WizardIntroPageProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK FinishedPageProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK MirabilisPageProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK MirandaPageProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK ICQserverPageProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam); + +extern HINSTANCE hInst; +BOOL IsProtocolLoaded(char* pszProtocolName); +BOOL EnumICQAccounts(); +void FreeICQAccountsList(); + +INT_PTR CALLBACK ImportTypePageProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch( message ) { + case WM_INITDIALOG: + TranslateDialogDefault(hdlg); + CheckDlgButton(hdlg, IDC_MIRANDA, BST_CHECKED); + + // Disable Mirabilis import if ICQ isn't loaded. + if (!EnumICQAccounts()) + EnableWindow(GetDlgItem(hdlg, IDC_MIRABILIS), FALSE); + + return TRUE; + + case WM_COMMAND: + switch( LOWORD( wParam )) { + case IDC_BACK: + PostMessage(GetParent(hdlg), WIZM_GOTOPAGE, IDD_WIZARDINTRO, (LPARAM)WizardIntroPageProc); + break; + + case IDOK: + if (IsDlgButtonChecked(hdlg, IDC_MIRANDA)) + PostMessage(GetParent(hdlg), WIZM_GOTOPAGE, IDD_MIRANDADB, (LPARAM)MirandaPageProc); + else if (IsDlgButtonChecked(hdlg, IDC_MIRABILIS)) + PostMessage(GetParent(hdlg), WIZM_GOTOPAGE, IDD_MIRABILISDB, (LPARAM)MirabilisPageProc); + else if (IsDlgButtonChecked(hdlg, IDC_USEFINDADD)) { + CallService(MS_FINDADD_FINDADD, 0, 0); + PostMessage(GetParent(hdlg), WIZM_GOTOPAGE, IDD_FINISHED, (LPARAM)FinishedPageProc); + } + break; + + case IDCANCEL: + PostMessage(GetParent(hdlg), WM_CLOSE, 0, 0); + break; + } } + + return FALSE; +} + +INT_PTR CALLBACK WizardIntroPageProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch( message ) { + case WM_INITDIALOG: + TranslateDialogDefault(hdlg); + SendMessage(GetParent(hdlg), WIZM_DISABLEBUTTON, 0, 0); + return TRUE; + + case WM_COMMAND: + switch( LOWORD( wParam )) { + case IDOK: + PostMessage(GetParent(hdlg), WIZM_GOTOPAGE, IDD_IMPORTTYPE, (LPARAM)ImportTypePageProc); + break; + + case IDCANCEL: + PostMessage(GetParent(hdlg), WM_CLOSE, 0, 0); + break; + } } + + return FALSE; +} + +INT_PTR CALLBACK FinishedPageProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch( message ) { + case WM_INITDIALOG: + TranslateDialogDefault(hdlg); + SendMessage(GetParent(hdlg), WIZM_DISABLEBUTTON, 0, 0); + SendMessage(GetParent(hdlg), WIZM_SETCANCELTEXT, 0, (LPARAM)TranslateT("Finish")); + CheckDlgButton(hdlg, IDC_DONTLOADPLUGIN, BST_UNCHECKED); + return TRUE; + + case WM_COMMAND: + switch( LOWORD( wParam )) { + case IDOK: + PostMessage(GetParent(hdlg), WIZM_GOTOPAGE, IDD_IMPORTTYPE, (LPARAM)ImportTypePageProc); + break; + + case IDCANCEL: + if ( IsDlgButtonChecked( hdlg, IDC_DONTLOADPLUGIN )) { + char sModuleFileName[MAX_PATH]; + char *pszFileName; + + GetModuleFileNameA(hInst, sModuleFileName, sizeof(sModuleFileName)); + pszFileName = strrchr(sModuleFileName, '\\' ); + if (pszFileName == NULL) + pszFileName = sModuleFileName; + else + pszFileName++; + + // We must lower case here because if a DLL is loaded in two + // processes, its file name from GetModuleFileName in one process may + // differ in case from its file name in the other process. This will + // prevent the plugin from disabling/enabling correctly (this fix relies + // on the plugin loader to ignore case) + CharLowerA(pszFileName); + DBWriteContactSettingByte(NULL, "PluginDisable", pszFileName, 1); + } + PostMessage(GetParent(hdlg), WM_CLOSE, 0, 0); + break; + } + break; + } + + return FALSE; +} + +INT_PTR CALLBACK WizardDlgProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + static HWND hwndPage; + + switch ( message ) { + case WM_INITDIALOG: + TranslateDialogDefault(hdlg); + hwndPage = CreateDialog(hInst, MAKEINTRESOURCE(IDD_WIZARDINTRO), hdlg, WizardIntroPageProc); + SetWindowPos(hwndPage, 0, 0, 0, 0, 0, SWP_NOZORDER|SWP_NOSIZE); + ShowWindow(hwndPage, SW_SHOW); + ShowWindow(hdlg, SW_SHOW); + SendMessage(hdlg, WM_SETICON, ICON_BIG, (LPARAM)LoadIcon(hInst,MAKEINTRESOURCE(IDI_IMPORT))); + return TRUE; + + case WIZM_GOTOPAGE: + DestroyWindow(hwndPage); + EnableWindow(GetDlgItem(hdlg, IDC_BACK), TRUE); + EnableWindow(GetDlgItem(hdlg, IDOK), TRUE); + EnableWindow(GetDlgItem(hdlg, IDCANCEL), TRUE); + SetDlgItemText(hdlg, IDCANCEL, TranslateT("Cancel")); + hwndPage = CreateDialog(hInst, MAKEINTRESOURCE(wParam), hdlg, (DLGPROC)lParam); + SetWindowPos(hwndPage, 0, 0, 0, 0, 0, SWP_NOZORDER|SWP_NOSIZE); + ShowWindow(hwndPage, SW_SHOW); + break; + + case WIZM_DISABLEBUTTON: + switch ( wParam ) { + case 0: + EnableWindow(GetDlgItem(hdlg, IDC_BACK), FALSE); + break; + + case 1: + EnableWindow(GetDlgItem(hdlg, IDOK), FALSE); + break; + + case 2: + EnableWindow(GetDlgItem(hdlg, IDCANCEL), FALSE); + break; + } + break; + + case WIZM_ENABLEBUTTON: + switch ( wParam ) { + case 0: + EnableWindow(GetDlgItem(hdlg, IDC_BACK), TRUE); + break; + + case 1: + EnableWindow(GetDlgItem(hdlg, IDOK), TRUE); + break; + + case 2: + EnableWindow(GetDlgItem(hdlg, IDCANCEL), TRUE); + break; + } + break; + + case WIZM_SETCANCELTEXT: + SetDlgItemText(hdlg, IDCANCEL, (TCHAR*)lParam); + break; + + case WM_COMMAND: + SendMessage(hwndPage, WM_COMMAND, wParam, lParam); + break; + + case WM_CLOSE: + DestroyWindow(hwndPage); + DestroyWindow(hdlg); + + FreeICQAccountsList(); + break; + } + + return FALSE; +} diff --git a/plugins/Import/version.h b/plugins/Import/version.h deleted file mode 100644 index 58f9cf348c..0000000000 --- a/plugins/Import/version.h +++ /dev/null @@ -1,5 +0,0 @@ -#include - -#define __FILEVERSION_STRING MIRANDA_VERSION_FILEVERSION -#define __VERSION_STRING MIRANDA_VERSION_STRING -#define __VERSION_DWORD MIRANDA_VERSION_DWORD diff --git a/plugins/Import/wizard.cpp b/plugins/Import/wizard.cpp deleted file mode 100644 index 780501a10a..0000000000 --- a/plugins/Import/wizard.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/* - -Import plugin for Miranda IM - -Copyright (C) 2001-2005 Martin Öberg, Richard Hughes, Roland Rabien & Tristan Van de Vreede - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#include "import.h" -#include "resource.h" - -INT_PTR CALLBACK WizardIntroPageProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam); -INT_PTR CALLBACK FinishedPageProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam); -INT_PTR CALLBACK MirabilisPageProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam); -INT_PTR CALLBACK MirandaPageProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam); -INT_PTR CALLBACK ICQserverPageProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam); - -extern HINSTANCE hInst; -BOOL IsProtocolLoaded(char* pszProtocolName); -BOOL EnumICQAccounts(); -void FreeICQAccountsList(); - -INT_PTR CALLBACK ImportTypePageProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch( message ) { - case WM_INITDIALOG: - TranslateDialogDefault(hdlg); - CheckDlgButton(hdlg, IDC_MIRANDA, BST_CHECKED); - - // Disable Mirabilis import if ICQ isn't loaded. - if (!EnumICQAccounts()) - EnableWindow(GetDlgItem(hdlg, IDC_MIRABILIS), FALSE); - - return TRUE; - - case WM_COMMAND: - switch( LOWORD( wParam )) { - case IDC_BACK: - PostMessage(GetParent(hdlg), WIZM_GOTOPAGE, IDD_WIZARDINTRO, (LPARAM)WizardIntroPageProc); - break; - - case IDOK: - if (IsDlgButtonChecked(hdlg, IDC_MIRANDA)) - PostMessage(GetParent(hdlg), WIZM_GOTOPAGE, IDD_MIRANDADB, (LPARAM)MirandaPageProc); - else if (IsDlgButtonChecked(hdlg, IDC_MIRABILIS)) - PostMessage(GetParent(hdlg), WIZM_GOTOPAGE, IDD_MIRABILISDB, (LPARAM)MirabilisPageProc); - else if (IsDlgButtonChecked(hdlg, IDC_USEFINDADD)) { - CallService(MS_FINDADD_FINDADD, 0, 0); - PostMessage(GetParent(hdlg), WIZM_GOTOPAGE, IDD_FINISHED, (LPARAM)FinishedPageProc); - } - break; - - case IDCANCEL: - PostMessage(GetParent(hdlg), WM_CLOSE, 0, 0); - break; - } } - - return FALSE; -} - -INT_PTR CALLBACK WizardIntroPageProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch( message ) { - case WM_INITDIALOG: - TranslateDialogDefault(hdlg); - SendMessage(GetParent(hdlg), WIZM_DISABLEBUTTON, 0, 0); - return TRUE; - - case WM_COMMAND: - switch( LOWORD( wParam )) { - case IDOK: - PostMessage(GetParent(hdlg), WIZM_GOTOPAGE, IDD_IMPORTTYPE, (LPARAM)ImportTypePageProc); - break; - - case IDCANCEL: - PostMessage(GetParent(hdlg), WM_CLOSE, 0, 0); - break; - } } - - return FALSE; -} - -INT_PTR CALLBACK FinishedPageProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch( message ) { - case WM_INITDIALOG: - TranslateDialogDefault(hdlg); - SendMessage(GetParent(hdlg), WIZM_DISABLEBUTTON, 0, 0); - SendMessage(GetParent(hdlg), WIZM_SETCANCELTEXT, 0, (LPARAM)TranslateT("Finish")); - CheckDlgButton(hdlg, IDC_DONTLOADPLUGIN, BST_UNCHECKED); - return TRUE; - - case WM_COMMAND: - switch( LOWORD( wParam )) { - case IDOK: - PostMessage(GetParent(hdlg), WIZM_GOTOPAGE, IDD_IMPORTTYPE, (LPARAM)ImportTypePageProc); - break; - - case IDCANCEL: - if ( IsDlgButtonChecked( hdlg, IDC_DONTLOADPLUGIN )) { - char sModuleFileName[MAX_PATH]; - char *pszFileName; - - GetModuleFileNameA(hInst, sModuleFileName, sizeof(sModuleFileName)); - pszFileName = strrchr(sModuleFileName, '\\' ); - if (pszFileName == NULL) - pszFileName = sModuleFileName; - else - pszFileName++; - - // We must lower case here because if a DLL is loaded in two - // processes, its file name from GetModuleFileName in one process may - // differ in case from its file name in the other process. This will - // prevent the plugin from disabling/enabling correctly (this fix relies - // on the plugin loader to ignore case) - CharLowerA(pszFileName); - DBWriteContactSettingByte(NULL, "PluginDisable", pszFileName, 1); - } - PostMessage(GetParent(hdlg), WM_CLOSE, 0, 0); - break; - } - break; - } - - return FALSE; -} - -INT_PTR CALLBACK WizardDlgProc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - static HWND hwndPage; - - switch ( message ) { - case WM_INITDIALOG: - TranslateDialogDefault(hdlg); - hwndPage = CreateDialog(hInst, MAKEINTRESOURCE(IDD_WIZARDINTRO), hdlg, WizardIntroPageProc); - SetWindowPos(hwndPage, 0, 0, 0, 0, 0, SWP_NOZORDER|SWP_NOSIZE); - ShowWindow(hwndPage, SW_SHOW); - ShowWindow(hdlg, SW_SHOW); - SendMessage(hdlg, WM_SETICON, ICON_BIG, (LPARAM)LoadIcon(hInst,MAKEINTRESOURCE(IDI_IMPORT))); - return TRUE; - - case WIZM_GOTOPAGE: - DestroyWindow(hwndPage); - EnableWindow(GetDlgItem(hdlg, IDC_BACK), TRUE); - EnableWindow(GetDlgItem(hdlg, IDOK), TRUE); - EnableWindow(GetDlgItem(hdlg, IDCANCEL), TRUE); - SetDlgItemText(hdlg, IDCANCEL, TranslateT("Cancel")); - hwndPage = CreateDialog(hInst, MAKEINTRESOURCE(wParam), hdlg, (DLGPROC)lParam); - SetWindowPos(hwndPage, 0, 0, 0, 0, 0, SWP_NOZORDER|SWP_NOSIZE); - ShowWindow(hwndPage, SW_SHOW); - break; - - case WIZM_DISABLEBUTTON: - switch ( wParam ) { - case 0: - EnableWindow(GetDlgItem(hdlg, IDC_BACK), FALSE); - break; - - case 1: - EnableWindow(GetDlgItem(hdlg, IDOK), FALSE); - break; - - case 2: - EnableWindow(GetDlgItem(hdlg, IDCANCEL), FALSE); - break; - } - break; - - case WIZM_ENABLEBUTTON: - switch ( wParam ) { - case 0: - EnableWindow(GetDlgItem(hdlg, IDC_BACK), TRUE); - break; - - case 1: - EnableWindow(GetDlgItem(hdlg, IDOK), TRUE); - break; - - case 2: - EnableWindow(GetDlgItem(hdlg, IDCANCEL), TRUE); - break; - } - break; - - case WIZM_SETCANCELTEXT: - SetDlgItemText(hdlg, IDCANCEL, (TCHAR*)lParam); - break; - - case WM_COMMAND: - SendMessage(hwndPage, WM_COMMAND, wParam, lParam); - break; - - case WM_CLOSE: - DestroyWindow(hwndPage); - DestroyWindow(hdlg); - - FreeICQAccountsList(); - break; - } - - return FALSE; -} diff --git a/plugins/KeyboardNotify/AggressiveOptimize.h b/plugins/KeyboardNotify/AggressiveOptimize.h deleted file mode 100644 index 34c6074320..0000000000 --- a/plugins/KeyboardNotify/AggressiveOptimize.h +++ /dev/null @@ -1,165 +0,0 @@ -////////////////////////////// -// Version 1.40 -// October 22nd, 2002 - .NET (VC7, _MSC_VER=1300) support! -// Version 1.30 -// Nov 24th, 2000 -// Version 1.20 -// Jun 9th, 2000 -// Version 1.10 -// Jan 23rd, 2000 -// Version 1.00 -// May 20th, 1999 -// Todd C. Wilson, Fresh Ground Software -// (todd@nopcode.com) -// This header file will kick in settings for Visual C++ 5 and 6 that will (usually) -// result in smaller exe's. -// The "trick" is to tell the compiler to not pad out the function calls; this is done -// by not using the /O1 or /O2 option - if you do, you implicitly use /Gy, which pads -// out each and every function call. In one single 500k dll, I managed to cut out 120k -// by this alone! -// The other two "tricks" are telling the Linker to merge all data-type segments together -// in the exe file. The relocation, read-only (constants) data, and code section (.text) -// sections can almost always be merged. Each section merged can save 4k in exe space, -// since each section is padded out to 4k chunks. This is very noticeable with smaller -// exes, since you could have only 700 bytes of data, 300 bytes of code, 94 bytes of -// strings - padded out, this could be 12k of runtime, for 1094 bytes of stuff! For larger -// programs, this is less overall, but can save at least 4k. -// Note that if you're using MFC static or some other 3rd party libs, you may get poor -// results with merging the readonly (.rdata) section - the exe may grow larger. -// To use this feature, define _MERGE_RDATA_ in your project or before this header is used. -// With Visual C++ 5, the program uses a file alignment of 512 bytes, which results -// in a small exe. Under VC6, the program instead uses 4k, which is the same as the -// section size. The reason (from what I understand) is that 4k is the chunk size of -// the virtual memory manager, and that WinAlign (an end-user tuning tool for Win98) -// will re-align the programs on this boundary. The problem with this is that all of -// Microsoft's system exes and dlls are *NOT* tuned like this, and using 4k causes serious -// exe bloat. This is very noticeable for smaller programs. -// The "trick" for this is to use the undocumented FILEALIGN linker parm to change the -// padding from 4k to 1/2k, which results in a much smaller exe - anywhere from 20%-75% -// depending on the size. Note that this is the same as using /OPT:NOWIN98, which *is* -// a previously documented switch, but was left out of the docs for some reason in VC6 and -// all of the current MSDN's - see KB:Q235956 for more information. -// Microsoft does say that using the 4k alignment will "speed up process loading", -// but I've been unable to notice a difference, even on my P180, with a very large (4meg) exe. -// Please note, however, that this will probably not change the size of the COMPRESSED -// file (either in a .zip file or in an install archive), since this 4k is all zeroes and -// gets compressed away. -// Also, the /ALIGN:4096 switch will "magically" do the same thing, even though this is the -// default setting for this switch. Apparently this sets the same values as the above two -// switches do. We do not use this in this header, since it smacks of a bug and not a feature. -// Thanks to Michael Geary for some additional tips! -// -// Notes about using this header in .NET -// First off, VC7 does not allow a lot of the linker command options in pragma's. There is no -// honest or good reason why Microsoft decided to make this change, it just doesn't. -// So that is why there are a lot of <1300 #if's in the header. -// If you want to take full advantage of the VC7 linker options, you will need to do it on a -// PER PROJECT BASIS; you can no longer use a global header file like this to make it better. -// Items I strongly suggest putting in all your VC7 project linker options command line settings: -// /ignore:4078 /RELEASE -// Compiler options: -// /GL (Whole Program Optimization) -// If you're making an .EXE and not a .DLL, consider adding in: -// /GA (Optimize for Windows Application) -// Some items to consider using in your VC7 projects (not VC6): -// Link-time Code Generation - whole code optimization. Put this in your exe/dll project link settings. -// /LTCG:NOSTATUS -// The classic no-padding and no-bloat compiler C/C++ switch: -// /opt:nowin98 -// -// (C++ command line options: /GL /opt:nowin98 and /GA for .exe files) -// (Link command line options: /ignore:4078 /RELEASE /LTCG:NOSTATUS) -// -// Now, notes on using these options in VC7 vs VC6. -// VC6 consistently, for me, produces smaller code from C++ the exact same sources, -// with or without this header. On average, VC6 produces 5% smaller binaries compared -// to VC7 compiling the exact same project, *without* this header. With this header, VC6 -// will make a 13k file, while VC7 will make a 64k one. VC7 is just bloaty, pure and -// simple - all that managed/unmanaged C++ runtimes, and the CLR stuff must be getting -// in the way of code generation. However, template support is better, so there. -// Both VC6 and VC7 show the same end kind of end result savings - larger binary output -// will shave about 2% off, where as smaller projects (support DLL's, cpl's, -// activex controls, ATL libs, etc) get the best result, since the padding is usually -// more than the actual usable code. But again, VC7 does not compile down as small as VC6. -// -// The argument can be made that doing this is a waste of time, since the "zero bytes" -// will be compressed out in a zip file or install archive. Not really - it doesn't matter -// if the data is a string of zeroes or ones or 85858585 - it will still take room (20 bytes -// in a zip file, 29 bytes if only *4* of them 4k bytes are not the same) and time to -// compress that data and decompress it. Also, 20k of zeros is NOT 20k on disk - it's the -// size of the cluster slop- for Fat32 systems, 20k can be 32k, NTFS could make it 24k if you're -// just 1 byte over (round up). Most end users do not have the dual P4 Xeon systems with -// two gigs of RDram and a Raid 0+1 of Western Digital 120meg Special Editions that all -// worthy developers have (all six of us), so they will need any space and LOADING TIME -// savings they will need; taking an extra 32k or more out of your end user's 64megs of -// ram on Windows 98 is Not a Good Thing. -// -// Now, as a ADDED BONUS at NO EXTRA COST TO YOU! Under VC6, using the /merge:.text=.data -// pragma will cause the output file to be un-disassembleable! (is that a word?) At least, -// with the normal tools - WinDisam, DumpBin, and the like will not work. Try it - use the -// header, compile release, and then use DUMPBIN /DISASM filename.exe - no code! -// Thanks to Gëzim Pani for discovering this gem - for a full writeup on -// this issue and the ramifactions of it, visit www.nopcode.com for the Aggressive Optimize -// article. - -#ifndef _AGGRESSIVEOPTIMIZE_H_ -#define _AGGRESSIVEOPTIMIZE_H_ - -#pragma warning(disable:4711) - -#ifdef NDEBUG -// /Og (global optimizations), /Os (favor small code), /Oy (no frame pointers) -#pragma optimize("gsy",on) - -#if (_MSC_VER<1300) - #pragma comment(linker,"/RELEASE") -#endif - -// Note that merging the .rdata section will result in LARGER exe's if you using -// MFC (esp. static link). If this is desirable, define _MERGE_RDATA_ in your project. -//#ifdef _MERGE_RDATA_ -//#pragma comment(linker,"/merge:.rdata=.data") -//#endif // _MERGE_RDATA_ - -//#pragma comment(linker,"/merge:.text=.data") -//#if (_MSC_VER<1300) - // In VC7, this causes problems with the relocation and data tables, so best to not merge them -// #pragma comment(linker,"/merge:.reloc=.data") -//#endif - -// Merging sections with different attributes causes a linker warning, so -// turn off the warning. From Michael Geary. Undocumented, as usual! -#if (_MSC_VER<1300) - // In VC7, you will need to put this in your project settings - #pragma comment(linker,"/ignore:4078") -#endif - -// With Visual C++ 5, you already get the 512-byte alignment, so you will only need -// it for VC6, and maybe later. -#if _MSC_VER >= 1000 - -// Option #1: use /filealign -// Totally undocumented! And if you set it lower than 512 bytes, the program crashes. -// Either leave at 0x200 or 0x1000 -//#pragma comment(linker,"/FILEALIGN:0x200") - -// Option #2: use /opt:nowin98 -// See KB:Q235956 or the READMEVC.htm in your VC directory for info on this one. -// This is our currently preferred option, since it is fully documented and unlikely -// to break in service packs and updates. -#if (_MSC_VER<1300) - // In VC7, you will need to put this in your project settings - #pragma comment(linker,"/opt:nowin98") -#else - -// Option #3: use /align:4096 -// A side effect of using the default align value is that it turns on the above switch. -// Does nothing under Vc7 that /opt:nowin98 doesn't already give you -// #pragma comment(linker,"/ALIGN:512") -#endif - -#endif // _MSC_VER >= 1000 - -#endif // NDEBUG - -#endif // _AGGRESSIVEOPTIMIZE_H_ diff --git a/plugins/KeyboardNotify/EnumProc.cpp b/plugins/KeyboardNotify/EnumProc.cpp deleted file mode 100644 index 7a5a23f0e3..0000000000 --- a/plugins/KeyboardNotify/EnumProc.cpp +++ /dev/null @@ -1,260 +0,0 @@ -/* - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#define WIN32_LEAN_AND_MEAN - -#include -#include -#include -#include -#include "EnumProc.h" - - -BOOL findFilename(TCHAR *); -TCHAR *filename(TCHAR *); -BOOL WINAPI Enum16(DWORD, WORD, WORD, TCHAR *, TCHAR *, LPARAM); - - -// Globals -extern double dWinVer; -extern BOOL bWindowsNT; -extern PROCESS_LIST ProcessList; - -HINSTANCE hInstLib, hInstLib2; -HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD, DWORD); -BOOL (WINAPI *lpfProcess32First)(HANDLE, LPPROCESSENTRY32); -BOOL (WINAPI *lpfProcess32Next)(HANDLE, LPPROCESSENTRY32); -BOOL (WINAPI *lpfEnumProcesses)(DWORD *, DWORD, DWORD *); -BOOL (WINAPI *lpfEnumProcessModules)(HANDLE, HMODULE *, DWORD, LPDWORD); -DWORD (WINAPI *lpfGetModuleBaseName)(HANDLE, HMODULE, LPTSTR, DWORD); -INT (WINAPI *lpfVDMEnumTaskWOWEx)(DWORD, TASKENUMPROCEX, LPARAM); - - -void LoadProcsLibrary(void) -{ - if (bWindowsNT && dWinVer < 5) { - - if (!(hInstLib = LoadLibraryA("PSAPI.DLL"))) - return; - - if (!(hInstLib2 = LoadLibraryA("VDMDBG.DLL"))) - return; - - lpfEnumProcesses = (BOOL (WINAPI *)(DWORD *, DWORD, DWORD*)) GetProcAddress(hInstLib, "EnumProcesses"); - lpfEnumProcessModules = (BOOL (WINAPI *)(HANDLE, HMODULE *, DWORD, LPDWORD)) GetProcAddress(hInstLib, "EnumProcessModules"); - lpfGetModuleBaseName = (DWORD (WINAPI *)(HANDLE, HMODULE, LPTSTR, DWORD)) GetProcAddress(hInstLib, "GetModuleBaseNameA"); - - lpfVDMEnumTaskWOWEx = (INT (WINAPI *)(DWORD, TASKENUMPROCEX, LPARAM)) GetProcAddress(hInstLib2, "VDMEnumTaskWOWEx"); - } else { - - if (!(hInstLib = LoadLibraryA("Kernel32.DLL"))) - return; - - if (bWindowsNT && !(hInstLib2 = LoadLibraryA("VDMDBG.DLL"))) - return; - - lpfCreateToolhelp32Snapshot = (HANDLE (WINAPI *)(DWORD,DWORD)) GetProcAddress(hInstLib, "CreateToolhelp32Snapshot"); - lpfProcess32First = (BOOL (WINAPI *)(HANDLE,LPPROCESSENTRY32)) GetProcAddress(hInstLib, "Process32First"); - lpfProcess32Next = (BOOL (WINAPI *)(HANDLE,LPPROCESSENTRY32)) GetProcAddress(hInstLib, "Process32Next"); - - if (bWindowsNT) - lpfVDMEnumTaskWOWEx = (INT (WINAPI *)(DWORD, TASKENUMPROCEX, LPARAM)) GetProcAddress(hInstLib2, "VDMEnumTaskWOWEx"); - } -} - - -void UnloadProcsLibrary(void) -{ - if (hInstLib) - FreeLibrary(hInstLib); - if (hInstLib2) - FreeLibrary(hInstLib2); - - hInstLib = hInstLib = NULL; - lpfCreateToolhelp32Snapshot = NULL; - lpfProcess32First = NULL; - lpfProcess32Next = NULL; - lpfEnumProcesses = NULL; - lpfEnumProcessModules = NULL; - lpfGetModuleBaseName = NULL; - lpfVDMEnumTaskWOWEx = NULL; -} - - -BOOL areThereProcessesRunning(void) -{ - HANDLE hSnapShot = NULL; - LPDWORD lpdwPIDs = NULL; - PROCESSENTRY32 procentry; - BOOL bFlag; - DWORD dwSize; - DWORD dwSize2; - DWORD dwIndex; - HMODULE hMod; - HANDLE hProcess; - TCHAR szFileName[MAX_PATH+1]; - - - if (!ProcessList.count) // Process list is empty - return FALSE; - - // If Windows NT 4.0 - if (bWindowsNT && dWinVer < 5) { - - if (!lpfEnumProcesses || !lpfEnumProcessModules || !lpfGetModuleBaseName || !lpfVDMEnumTaskWOWEx) - return FALSE; - - // - // Call the PSAPI function EnumProcesses to get all of the ProcID's currently in the system. - // - // NOTE: In the documentation, the third parameter of EnumProcesses is named cbNeeded, which implies that you - // can call the function once to find out how much space to allocate for a buffer and again to fill the buffer. - // This is not the case. The cbNeeded parameter returns the number of PIDs returned, so if your buffer size is - // zero cbNeeded returns zero. - // - // NOTE: The "HeapAlloc" loop here ensures that we actually allocate a buffer large enough for all the - // PIDs in the system. - // - dwSize2 = 256 * sizeof(DWORD); - do { - if (lpdwPIDs) { - HeapFree(GetProcessHeap(), 0, lpdwPIDs); - dwSize2 *= 2; - } - if (!(lpdwPIDs = (LPDWORD)HeapAlloc(GetProcessHeap(), 0, dwSize2))) - return FALSE; - if (!lpfEnumProcesses(lpdwPIDs, dwSize2, &dwSize)) { - HeapFree(GetProcessHeap(), 0, lpdwPIDs); - return FALSE; - } - } while (dwSize == dwSize2); - - // How many ProcID's did we get? - dwSize /= sizeof(DWORD); - - // Loop through each ProcID. - for (dwIndex = 0; dwIndex < dwSize; dwIndex++) { - TCHAR *szFileNameAux; - szFileName[0] = '\0'; - - // Open the process (if we can... security does not permit every process in the system to be opened). - hProcess = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, FALSE, lpdwPIDs[dwIndex]); - if (hProcess) { - // Here we call EnumProcessModules to get only the first module in the process. This will be the - // EXE module for which we will retrieve the name. - if (lpfEnumProcessModules(hProcess, &hMod, sizeof(hMod), &dwSize2)) { - // Get the module name - if (!lpfGetModuleBaseName(hProcess, hMod, szFileName, sizeof(szFileName))) - szFileName[0] = '\0'; - } - CloseHandle(hProcess); - } - szFileNameAux = filename(szFileName); - - // Search szFileName in user-defined list - if (findFilename(szFileNameAux)) { - HeapFree(GetProcessHeap(), 0, lpdwPIDs); - return TRUE; - } - - // Did we just bump into an NTVDM? - if (!_wcsicmp(szFileNameAux, L"NTVDM.EXE")) { - BOOL bFound = FALSE; - - // Enum the 16-bit stuff. - lpfVDMEnumTaskWOWEx(lpdwPIDs[dwIndex], (TASKENUMPROCEX) Enum16, (LPARAM)&bFound); - - // Did we find any user-defined process? - if (bFound) { - HeapFree(GetProcessHeap(), 0, lpdwPIDs); - return TRUE; - } - } - } - HeapFree(GetProcessHeap(), 0, lpdwPIDs); - - // If any OS other than Windows NT 4.0. - } else { - - if (!lpfProcess32Next || !lpfProcess32First || !lpfCreateToolhelp32Snapshot) - return FALSE; - - // Get a handle to a Toolhelp snapshot of all processes. - if ((hSnapShot = lpfCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) == INVALID_HANDLE_VALUE) - return FALSE; - - // While there are processes, keep looping. - for (procentry.dwSize=sizeof(PROCESSENTRY32), bFlag=lpfProcess32First(hSnapShot, &procentry); bFlag; procentry.dwSize=sizeof(PROCESSENTRY32), bFlag=lpfProcess32Next(hSnapShot, &procentry)) { - TCHAR *szFileNameAux = filename(procentry.szExeFile); - - // Search szFileName in user-defined list - if (findFilename(szFileNameAux)) - return TRUE; - - // Did we just bump into an NTVDM? - if (lpfVDMEnumTaskWOWEx && !_wcsicmp(szFileNameAux, L"NTVDM.EXE")) { - BOOL bFound = FALSE; - - // Enum the 16-bit stuff. - lpfVDMEnumTaskWOWEx(procentry.th32ProcessID, (TASKENUMPROCEX)Enum16, (LPARAM)&bFound); - - // Did we find any user-defined process? - if (bFound) - return TRUE; - } - } - } - - return FALSE; -} - - -BOOL WINAPI Enum16(DWORD dwThreadId, WORD hMod16, WORD hTask16, TCHAR *szModName, TCHAR *szFileName, LPARAM lpUserDefined) -{ - BOOL bRet; - BOOL *pbFound = (BOOL *)lpUserDefined; - - if ((bRet = findFilename(filename(szFileName)))) - *pbFound = TRUE; - - return bRet; -} - - -BOOL findFilename(TCHAR *fileName) -{ - unsigned int i; - - for (i=0; i < ProcessList.count; i++) - if (ProcessList.szFileName[i] && !_wcsicmp(ProcessList.szFileName[i], fileName)) - return TRUE; - - return FALSE; -} - - -TCHAR *filename(TCHAR *fullFileName) -{ - TCHAR *str; - - str = wcsrchr(fullFileName, '\\'); - if (!str) - return fullFileName; - - return ++str; -} \ No newline at end of file diff --git a/plugins/KeyboardNotify/EnumProc.h b/plugins/KeyboardNotify/EnumProc.h deleted file mode 100644 index 09b3cba8d6..0000000000 --- a/plugins/KeyboardNotify/EnumProc.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - -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. - -*/ - -typedef struct { - unsigned int count; - TCHAR **szFileName; -} PROCESS_LIST; - - -void LoadProcsLibrary(void); -void UnloadProcsLibrary(void); -BOOL areThereProcessesRunning(void); diff --git a/plugins/KeyboardNotify/KeyboardNotify_10.vcxproj b/plugins/KeyboardNotify/KeyboardNotify_10.vcxproj index 9b64f36c80..8e39f9709e 100644 --- a/plugins/KeyboardNotify/KeyboardNotify_10.vcxproj +++ b/plugins/KeyboardNotify/KeyboardNotify_10.vcxproj @@ -73,11 +73,10 @@ Disabled ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_WINDOWS;_USRDLL;KEYBORDNOTIFY_EXPORTS;%(PreprocessorDefinitions) + WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreadedDebugDLL Level3 EditAndContinue - 4996 true @@ -96,10 +95,9 @@ Disabled ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) - WIN64;_DEBUG;_WINDOWS;_USRDLL;KEYBORDNOTIFY_EXPORTS;%(PreprocessorDefinitions) + WIN64;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreadedDebugDLL Level3 - 4996 comctl32.lib;%(AdditionalDependencies) @@ -119,9 +117,8 @@ Full Size ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_WINDOWS;_USRDLL;KEYBORDNOTIFY_EXPORTS;%(PreprocessorDefinitions) + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) Level3 - 4996 comctl32.lib;%(AdditionalDependencies) @@ -143,9 +140,8 @@ Full Size ..\..\include;..\ExternalAPI;%(AdditionalIncludeDirectories) - WIN64;NDEBUG;_WINDOWS;_USRDLL;KEYBORDNOTIFY_EXPORTS;%(PreprocessorDefinitions) + WIN64;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) Level3 - 4996 comctl32.lib;%(AdditionalDependencies) @@ -163,31 +159,31 @@ - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - + + + + + + + + + - + diff --git a/plugins/KeyboardNotify/KeyboardNotify_10.vcxproj.filters b/plugins/KeyboardNotify/KeyboardNotify_10.vcxproj.filters index 35c9d4b195..8fe859e1ea 100644 --- a/plugins/KeyboardNotify/KeyboardNotify_10.vcxproj.filters +++ b/plugins/KeyboardNotify/KeyboardNotify_10.vcxproj.filters @@ -12,71 +12,71 @@ - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Header Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files - + Resource Files diff --git a/plugins/KeyboardNotify/constants.h b/plugins/KeyboardNotify/constants.h deleted file mode 100644 index d50ded6d23..0000000000 --- a/plugins/KeyboardNotify/constants.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - -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. - -*/ - -// Settings values -#define KEYBDMODULE "keybdnotify" -#define FLASH_SAMETIME 0 -#define FLASH_INTURN 1 -#define FLASH_INSEQUENCE 2 -#define FLASH_CUSTOM 3 -#define FLASH_TRILLIAN 4 -#define SEQ_LEFT2RIGHT 0 -#define SEQ_RIGHT2LEFT 1 -#define SEQ_LIKEKIT 2 -#define ACTIVE_MIRANDA 0 -#define ACTIVE_WINDOWS 1 -// Until settings map -#define UNTIL_NBLINKS 1 -#define UNTIL_REATTENDED 2 -#define UNTIL_EVENTSOPEN 4 -#define UNTIL_CONDITIONS 8 - -// Status map -#define MAP_ONLINE 1 -#define MAP_AWAY 2 -#define MAP_NA 4 -#define MAP_OCCUPIED 8 -#define MAP_DND 16 -#define MAP_FREECHAT 32 -#define MAP_INVISIBLE 64 -#define MAP_ONTHEPHONE 128 -#define MAP_OUTTOLUNCH 256 -#define MAP_OFFLINE 512 - -// Default settings -#define DEF_SETTING_ONMSG 1 // 1: Yes, 0: No -#define DEF_SETTING_ONURL 1 // 1: Yes, 0: No -#define DEF_SETTING_ONFILE 1 // 1: Yes, 0: No -#define DEF_SETTING_OTHER 1 // 1: Yes, 0: No -#define DEF_SETTING_FSCREEN 1 // 1: Yes, 0: No -#define DEF_SETTING_SSAVER 1 // 1: Yes, 0: No -#define DEF_SETTING_LOCKED 1 // 1: Yes, 0: No -#define DEF_SETTING_PROCS 0 // 1: Yes, 0: No -#define DEF_SETTING_ACTIVE 1 // 1: Yes, 0: No -#define DEF_SETTING_IFMSGOPEN 1 // 1: Yes, 0: No -#define DEF_SETTING_IFMSGNOTTOP 0 // 1: Yes, 0: No -#define DEF_SETTING_IFMSGOLDER 0 // 1: Yes, 0: No -#define DEF_SETTING_SECSOLDER 10 // Seconds -#define DEF_SETTING_FLASHUNTIL 2 // 1 = After x blinks, 2 = Until Miranda/Windows become active, 4 = Events are opened, 8 = Until end of 'notify when' conditions -#define DEF_SETTING_NBLINKS 4 // Seconds -#define DEF_SETTING_MIRORWIN 0 // 0-1, 0 = Miranda becomes active, 1 = Windows becomes active -#define DEF_SETTING_STATUS 1023 // 1023 = All -#define DEF_SETTING_CHECKTIME 0 // Minutes, 0 = don't check -#define DEF_SETTING_FLASHCAPS 1 // 1: Yes, 0: No -#define DEF_SETTING_FLASHNUM 1 // 1: Yes, 0: No -#define DEF_SETTING_FLASHSCROLL 1 // 1: Yes, 0: No -#define DEF_SETTING_FLASHEFFECT 0 // 0-3, 0 = All together, 1 = In turn, 2 = In sequence, 3 = Custom Theme, 4 = Trillian-like sequences -#define DEF_SETTING_SEQORDER 0 // 0-2, 0 = left to right, 1 = right to left, 2 = left <-> right -#define DEF_SETTING_CUSTOMTHEME 0 // Theme number -#define DEF_SETTING_LEDSMSG 2 // 2: Num Lock -#define DEF_SETTING_LEDSFILE 4 // 2: Caps Lock -#define DEF_SETTING_LEDSURL 1 // 2: Scroll Lock -#define DEF_SETTING_LEDSOTHER 7 // 2: Num Lock + Caps Lock + Scroll Lock -#define DEF_SETTING_STARTDELAY 2 // Seconds -#define DEF_SETTING_FLASHSPEED 3 // 0-5, 0 = really slow, 5 = really fast -#define DEF_SETTING_KEYPRESSES 0 // 1: Yes, 0: No -#define DEF_SETTING_OVERRIDE 0 // 1: Yes, 0: No -#define DEF_SETTING_TESTNUM 2 // Number of sequences to test before stopping -#define DEF_SETTING_TESTSECS 2 // Seconds to test before stopping -#define DEF_SETTING_PROTOCOL 1 // 1: Yes, 0: No -#define DEF_SETTING_XSTATUS 1 // 1: Yes, 0: No diff --git a/plugins/KeyboardNotify/docs/keyboardnotify-translation.txt b/plugins/KeyboardNotify/docs/keyboardnotify-translation.txt new file mode 100644 index 0000000000..f73628491f --- /dev/null +++ b/plugins/KeyboardNotify/docs/keyboardnotify-translation.txt @@ -0,0 +1,113 @@ +; Common strings that belong to many files +;[Ignore] + +; ../../plugins/KeyboardNotify/ignore.cpp +;[** All contacts **] +;[** Unknown contacts **] + +; ../../plugins/KeyboardNotify/main.cpp +;[Message Received] +;[Message Session] +;[Message Session is typing...] + +; ../../plugins/KeyboardNotify/options.cpp +;[Flashing] +;[Keyboard Flash] +;[None] +;[Plugins] +;[Protocol] +;[Protocols] +;[Rules] +;[Themes] +;[\n; Automatically generated Keyboard Notify Theme file\n\n\n] +;[\n; End of automatically generated Keyboard Notify Theme file\n] + +; ../../plugins/KeyboardNotify/resources.rc +;[ ... and not in foreground] +;[&Preview] +;[Accordingly to events' count] +;[Add] +;[All at the same time] +;[All other situations] +;[Away] +;[Blink if message window is open] +;[Cancel] +;[Caps] +;[Caps Lock] +;[Consider event opened after] +;[Create/Edit Themes] +;[Custom theme] +;[DND] +;[Defined programs are running] +;[Delete] +;[Emulate keypresses (Use this option if you are using an USB keyboard)] +;[End of 'notify when' conditions] +;[Events are opened] +;[Events to react on] +;[Everything else] +;[Export...] +;[Fast] +;[File events] +;[Flash speed] +;[Flash until] +;[Flashing effects] +;[Free for chat] +;[Full Screen mode] +;[Ignore URLs] +;[Ignore all] +;[Ignore files] +;[Ignore messages] +;[Ignore none] +;[Ignore others] +;[Import...] +;[Import/Export] +;[In sequence] +;[In turn] +;[Incoming URLs] +;[Incoming files] +;[Incoming messages] +;[Invisible] +;[Keys to flash] +;[Message events] +;[Message-Event only] +;[NA] +;[Notify when] +;[Num] +;[Num Lock] +;[OK] +;[Occupied] +;[Offline] +;[On the phone] +;[Online] +;[Only if last is] +;[Only notify if status is] +;[Other events] +;[Out to lunch] +;[Override existing] +;[Pending Events] +;[Program] +;[Protocols to check] +;[Remind me every] +;[Screen Saver is running] +;[Scroll] +;[Scroll Lock] +;[Set LEDs for events] +;[Set program list] +;[Set xStatus list] +;[Slider1] +;[Slow] +;[Spin1] +;[Tab1] +;[Test] +;[The following events are being ignored:] +;[Theme] +;[URL events] +;[Update] +;[Use custom theme] +;[Wait before starting flashing] +;[Workstation is Locked (2000/XP)] +;[is re-attended] +;[minutes] +;[sec. old] +;[seconds] +;[xStatuses] diff --git a/plugins/KeyboardNotify/flash.cpp b/plugins/KeyboardNotify/flash.cpp deleted file mode 100644 index aa0014a329..0000000000 --- a/plugins/KeyboardNotify/flash.cpp +++ /dev/null @@ -1,438 +0,0 @@ -/* - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#define WIN32_LEAN_AND_MEAN - -#include -#include "flash.h" -#include "keyboard.h" -#include "keypresses.h" -#include "utils.h" -#include "constants.h" -#include -#include - -typedef struct { - unsigned int size; - unsigned int index; - BYTE frame[MAX_PATH]; -} FLASHING_SEQUENCE; - - -// Prototypes -FLASHING_SEQUENCE *getCustomSeq(void); -FLASHING_SEQUENCE *getPredefinedSeq(void); -FLASHING_SEQUENCE *getTrillianSeq(void); -void updateTrillianSeq(void); -static void TestThread(FLASHING_SEQUENCE *); -static void PreviewThread(void *); -FLASHING_SEQUENCE str2FS(TCHAR *); -BYTE KbdChar2Byte(char); -void countUnopenEvents(int *, int *, int *, int *); - -#define Leds2Flash ((BYTE)(bFlashLed[2] + (bFlashLed[0]<<1) + (bFlashLed[1]<<2))) - -// Flashing settings -FLASHING_SEQUENCE *pFS; -BOOL bTemporarilyUseExtern; -extern BYTE bFlashLed[3]; -extern BYTE bFlashEffect; extern BYTE bSequenceOrder; -extern WORD wCustomTheme; -extern BYTE bTrillianLedsMsg; extern BYTE bTrillianLedsURL; extern BYTE bTrillianLedsFile; extern BYTE bTrillianLedsOther; -extern BYTE bEmulateKeypresses; - - -// TestThread/PreviewThread globals -extern int nWaitDelay; extern WORD wStartDelay; -BOOL bTestSemaphore, bPreviewSemaphore, bPreview; - - -void RestoreLEDState(void) -{ - if (bEmulateKeypresses) - keypresses_RestoreLEDState(); - else - ToggleKeyboardLights((BYTE)(LedState(VK_SCROLL) + (LedState(VK_NUMLOCK)<<1) + (LedState(VK_CAPITAL)<<2))); -} - - -BYTE getBlinkingLeds(void) -{ - if (!pFS->size) - return (BYTE)(LedState(VK_SCROLL) + (LedState(VK_NUMLOCK)<<1) + (LedState(VK_CAPITAL)<<2)); - - pFS->index %= pFS->size; - if (bFlashEffect == FLASH_TRILLIAN && !bTemporarilyUseExtern && !pFS->index) - updateTrillianSeq(); - return pFS->frame[pFS->index++]; -} - - -void setFlashingSequence(void) -{ - switch (bFlashEffect) { - case FLASH_CUSTOM: - pFS = getCustomSeq(); - break; - case FLASH_TRILLIAN: - pFS = getTrillianSeq(); - break; - default: - pFS = getPredefinedSeq(); - } - bTemporarilyUseExtern = FALSE; -} - - -FLASHING_SEQUENCE *getCustomSeq(void) -{ - static FLASHING_SEQUENCE Custom = {0}; - - DBVARIANT dbv; - TCHAR customStr[MAX_PATH+1]; - - - customStr[0] = _T('\0'); - if (!DBGetContactSetting(NULL, KEYBDMODULE, fmtDBSettingName("custom%d", wCustomTheme), &dbv)) { - wcscpy(customStr, dbv.pwszVal); - DBFreeVariant(&dbv); - } - - Custom = str2FS(customStr); - - return &Custom; -} - - -FLASHING_SEQUENCE *getPredefinedSeq(void) -{ - static FLASHING_SEQUENCE Predefined = {0}; - - FLASHING_SEQUENCE *pAux; - FLASHING_SEQUENCE SameTime = {2, 0, {7, 0}}; - FLASHING_SEQUENCE InTurn = {2, 0, {3, 4}}; - FLASHING_SEQUENCE InSeq = {3, 0, {2, 4, 1}}; - FLASHING_SEQUENCE InSeqRev = {3, 0, {1, 4, 2}}; - FLASHING_SEQUENCE InSeqKIT = {4, 0, {2, 4, 1, 4}}; - - - if (Leds2Flash < 3 || Leds2Flash == 4) - pAux = &SameTime; - else - switch (bFlashEffect) { - default: - case FLASH_SAMETIME: - pAux = &SameTime; - break; - case FLASH_INTURN: - if (Leds2Flash == 3) // 3 = Num+Scroll - pAux = &InSeq; - else - pAux = &InTurn; - break; - case FLASH_INSEQUENCE: - switch (bSequenceOrder) { - default: - case SEQ_LEFT2RIGHT: - pAux = &InSeq; - break; - case SEQ_RIGHT2LEFT: - pAux = &InSeqRev; - break; - case SEQ_LIKEKIT: - if (Leds2Flash != 7) // 7 = Num+Caps+Scroll - pAux = &InSeq; - else - pAux = &InSeqKIT; - break; - } - break; - } - - Predefined.size = Predefined.index = 0; - for (pAux->index=0; pAux->index < pAux->size; pAux->index++) - if (!pAux->frame[pAux->index] || (pAux->frame[pAux->index] & Leds2Flash)) { - Predefined.size++; - Predefined.frame[Predefined.size - 1] = pAux->frame[pAux->index] & Leds2Flash; - } - - return &Predefined; -} - - -FLASHING_SEQUENCE *getTrillianSeq(void) -{ - static FLASHING_SEQUENCE Trillian = {2, 0, {0, 0}}; - - Trillian.size = 2; - Trillian.index = 0; - - return &Trillian; -} - - -void updateTrillianSeq(void) -{ - int i, msgCount=0, fileCount=0, urlCount=0, otherCount=0; - - pFS->size = 2; - countUnopenEvents(&msgCount, &fileCount, &urlCount, &otherCount); - - if ((bTrillianLedsMsg & Leds2Flash) && (pFS->size + 2 * msgCount) <= MAX_PATH) - for (i=0; i < msgCount; i++) { - pFS->frame[pFS->size++] = bTrillianLedsMsg & Leds2Flash; - pFS->frame[pFS->size++] = 0; - } - - if ((bTrillianLedsFile & Leds2Flash) && (pFS->size + 2 * fileCount) <= MAX_PATH) - for (i=0; i < fileCount; i++) { - pFS->frame[pFS->size++] = bTrillianLedsFile & Leds2Flash; - pFS->frame[pFS->size++] = 0; - } - - if ((bTrillianLedsURL & Leds2Flash) && (pFS->size + 2 * urlCount) <= MAX_PATH) - for (i=0; i < urlCount; i++) { - pFS->frame[pFS->size++] = bTrillianLedsURL & Leds2Flash; - pFS->frame[pFS->size++] = 0; - } - - if ((bTrillianLedsOther & Leds2Flash) && (pFS->size + 2 * otherCount) <= MAX_PATH) - for (i=0; i < otherCount; i++) { - pFS->frame[pFS->size++] = bTrillianLedsOther & Leds2Flash; - pFS->frame[pFS->size++] = 0; - } - -} - - -void useExternSequence(TCHAR *extStr) -{ - static FLASHING_SEQUENCE Extern = {0}; - - TCHAR externStr[MAX_PATH+1]; - - - wcscpy(externStr, extStr); - - Extern = str2FS(normalizeCustomString(externStr)); - - pFS = &Extern; - bTemporarilyUseExtern = TRUE; -} - - -TCHAR *normalizeCustomString(TCHAR *customStr) -{ - int len=0, status=0; - BOOL used[4]; - TCHAR strAux[MAX_PATH+1], *str; - - for (wcscpy(str=strAux, customStr); *str; str++) - switch (*str) { - case _T('['): - if (status == 0) { - status = 1; - customStr[len++] = *str; - used[0] = used [1] = used[2] = used[3] = FALSE; - } - break; - case _T(']'): - if (status == 1) { - status = 0; - customStr[len++] = *str; - } - break; - case _T('0'): - case _T('1'): - case _T('2'): - case _T('3'): - if (status == 0) - customStr[len++] = *str; - else - if (!used[*str - _T('0')]) { - customStr[len++] = *str; - used[*str - _T('0')] = TRUE; - } - break; - } - if (status == 1) - customStr[len++] = _T(']'); - customStr[len] = _T('\0'); - - return customStr; -} - - -TCHAR *getCurrentSequenceString(void) -{ - static TCHAR CurrentSeqString[MAX_PATH+1]; - - unsigned int i; - TCHAR *str; - - - for (i=0, str=CurrentSeqString; i < pFS->size; i++) - switch (pFS->frame[i]) { - case 0: - *(str++) = _T('0'); - break; - case 1: - *(str++) = _T('3'); - break; - case 2: - *(str++) = _T('1'); - break; - case 3: - *(str++) = _T('['); - *(str++) = _T('1'); - *(str++) = _T('3'); - *(str++) = _T(']'); - break; - case 4: - *(str++) = _T('2'); - break; - case 5: - *(str++) = _T('['); - *(str++) = _T('2'); - *(str++) = _T('3'); - *(str++) = _T(']'); - break; - case 6: - *(str++) = _T('['); - *(str++) = _T('1'); - *(str++) = _T('2'); - *(str++) = _T(']'); - break; - case 7: - *(str++) = _T('['); - *(str++) = _T('1'); - *(str++) = _T('2'); - *(str++) = _T('3'); - *(str++) = _T(']'); - } - *str = _T('\0'); - - - return CurrentSeqString; -} - - -void testSequence(TCHAR *testStr) -{ - static FLASHING_SEQUENCE Test = {0}; - - DWORD threadID = 0; - - - if (bTestSemaphore) // we try to avoid concurrent test threads - return; - bTestSemaphore = TRUE; - - Test = str2FS(testStr); - - CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)TestThread, &Test, 0, &threadID); -} - - -static void TestThread(FLASHING_SEQUENCE *pTest) -{ - unsigned int i; - DWORD dwEndTest; - - unsigned int testNum = (unsigned int)DBGetContactSettingByte(NULL, KEYBDMODULE, "testnum", DEF_SETTING_TESTNUM); - unsigned int testSecs = (unsigned int)DBGetContactSettingByte(NULL, KEYBDMODULE, "testsecs", DEF_SETTING_TESTSECS); - - for (i=0, dwEndTest=GetTickCount()+testSecs*1000; i < testNum || GetTickCount() < dwEndTest; i++) - for (pTest->index=0; pTest->index < pTest->size; pTest->index++) { - ToggleKeyboardLights(pTest->frame[pTest->index]); - Sleep(nWaitDelay); - } - - RestoreLEDState(); - - bTestSemaphore = FALSE; -} - - -void previewFlashing(BOOL buttonState) -{ - DWORD threadID = 0; - - bPreview = buttonState; - - if (!bPreview || bPreviewSemaphore) // turn off flashing or already running - return; - - bPreviewSemaphore = TRUE; - CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PreviewThread, NULL, 0, &threadID); -} - - -static void PreviewThread(void *dummy) -{ - unsigned int i; - BYTE unchangedLeds; - - if (wStartDelay > 0) - Sleep(wStartDelay * 1000); - - unchangedLeds = (BYTE)(LedState(VK_SCROLL) * !bFlashLed[2] + ((LedState(VK_NUMLOCK) * !bFlashLed[0])<<1) + ((LedState(VK_CAPITAL) * !bFlashLed[1])<<2)); - - while (bPreview) - for (i=0; bPreview && i < pFS->size; i++) { - ToggleKeyboardLights((BYTE)(pFS->frame[i%pFS->size]|unchangedLeds)); - Sleep(nWaitDelay); - } - - RestoreLEDState(); - - bPreviewSemaphore = FALSE; -} - - -FLASHING_SEQUENCE str2FS(TCHAR *str) -{ - FLASHING_SEQUENCE Temp = {0}; - - for (Temp.size=Temp.index=0; *str; str++) { - Temp.size++; - if (*str == _T('[')) { - Temp.frame[Temp.size - 1] = 0; - for (str++; *str && *str != _T(']'); str++) - Temp.frame[Temp.size - 1] += KbdChar2Byte(*str) & Leds2Flash; - if (!*str) break; - } else - Temp.frame[Temp.size - 1] = KbdChar2Byte(*str) & Leds2Flash; - } - - return Temp; -} - - -BYTE KbdChar2Byte(char kbdChar) -{ - switch (kbdChar) { - case '1': //NumLock - return 2; - case '2': //CapsLock - return 4; - case '3': //ScrollLock - return 1; - } - return 0; -} diff --git a/plugins/KeyboardNotify/flash.h b/plugins/KeyboardNotify/flash.h deleted file mode 100644 index f60706fc76..0000000000 --- a/plugins/KeyboardNotify/flash.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - -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. - -*/ - -void RestoreLEDState(void); -BYTE getBlinkingLeds(void); -void setFlashingSequence(void); -void useExternSequence(TCHAR *); -TCHAR *normalizeCustomString(TCHAR *); -TCHAR *getCurrentSequenceString(void); -void testSequence(TCHAR *); -void previewFlashing(BOOL); - -#define LedState(a) (((BYTE)(GetKeyState(a) & 0xffff))!=0) diff --git a/plugins/KeyboardNotify/ignore.cpp b/plugins/KeyboardNotify/ignore.cpp deleted file mode 100644 index 57fcceb8a6..0000000000 --- a/plugins/KeyboardNotify/ignore.cpp +++ /dev/null @@ -1,389 +0,0 @@ -/* - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#define WIN32_LEAN_AND_MEAN - -#include -#include -#include -#include -#include -#include "ignore.h" -#include "resource.h" -#include "constants.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define IGNOREEVENT_MAX 4 -#define IDI_SMALLDOT 211 -#define IDI_FILLEDBLOB 212 -#define IDI_EMPTYBLOB 213 - -#define SIZEOF(a) (sizeof(a) / sizeof(a[0])) - -static const DWORD ignoreIdToPf1[IGNOREEVENT_MAX] = {PF1_IMRECV, PF1_URLRECV, PF1_FILERECV, 0xFFFFFFFF}; - -extern double dWinVer; -extern BOOL bWindowsNT; - - -static DWORD GetMask(HANDLE hContact) -{ - DWORD mask = DBGetContactSettingDword(hContact, KEYBDMODULE, "Mask1", (DWORD)(-1)); - if(mask == (DWORD)(-1)) { - if(hContact == NULL) - mask=0; - else { - if(DBGetContactSettingByte(hContact, "CList", "Hidden", 0) || DBGetContactSettingByte(hContact, "CList", "NotOnList", 0)) - mask = DBGetContactSettingDword(NULL, KEYBDMODULE, "Mask1", 0); - else - mask = DBGetContactSettingDword(NULL, KEYBDMODULE, "Default1", 0); - } - } - return mask; -} - -static void SetListGroupIcons(HWND hwndList, HANDLE hFirstItem, HANDLE hParentItem, int *groupChildCount) -{ - int typeOfFirst; - int iconOn[IGNOREEVENT_MAX]={1,1,1,1}; - int childCount[IGNOREEVENT_MAX]={0,0,0,0}, i; - int iImage; - HANDLE hItem, hChildItem; - - typeOfFirst = SendMessage(hwndList, CLM_GETITEMTYPE, (WPARAM)hFirstItem, 0); - //check groups - if(typeOfFirst == CLCIT_GROUP) - hItem = hFirstItem; - else - hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTGROUP, (LPARAM)hFirstItem); - while(hItem) { - hChildItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_CHILD, (LPARAM)hItem); - if(hChildItem) - SetListGroupIcons(hwndList, hChildItem, hItem, childCount); - for(i=0; i < SIZEOF(iconOn); i++) - if(iconOn[i] && SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, i) == 0) - iconOn[i] = 0; - hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTGROUP, (LPARAM)hItem); - } - //check contacts - if(typeOfFirst == CLCIT_CONTACT) - hItem = hFirstItem; - else - hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTCONTACT, (LPARAM)hFirstItem); - while(hItem) { - for(i=0; i < SIZEOF(iconOn); i++) { - iImage = SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, i); - if(iconOn[i] && iImage == 0) - iconOn[i] = 0; - if(iImage != 0xFF) - childCount[i]++; - } - hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTCONTACT, (LPARAM)hItem); - } - //set icons - for(i=0; i < SIZEOF(iconOn); i++) { - SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hParentItem, MAKELPARAM(i, childCount[i]?(iconOn[i]?i+3:0):0xFF)); - if(groupChildCount) - groupChildCount[i] += childCount[i]; - } - SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hParentItem, MAKELPARAM(IGNOREEVENT_MAX, 1)); - SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hParentItem, MAKELPARAM(IGNOREEVENT_MAX+1, 2)); -} - -static void SetAllChildIcons(HWND hwndList, HANDLE hFirstItem, int iColumn, int iImage) -{ - int typeOfFirst, iOldIcon; - HANDLE hItem, hChildItem; - - typeOfFirst = SendMessage(hwndList,CLM_GETITEMTYPE,(WPARAM)hFirstItem, 0); - //check groups - if(typeOfFirst == CLCIT_GROUP) - hItem = hFirstItem; - else - hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTGROUP, (LPARAM)hFirstItem); - while(hItem) { - hChildItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_CHILD, (LPARAM)hItem); - if(hChildItem) - SetAllChildIcons(hwndList, hChildItem, iColumn, iImage); - hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTGROUP, (LPARAM)hItem); - } - //check contacts - if(typeOfFirst == CLCIT_CONTACT) - hItem = hFirstItem; - else - hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTCONTACT, (LPARAM)hFirstItem); - while(hItem) { - iOldIcon = SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, iColumn); - if(iOldIcon != 0xFF && iOldIcon != iImage) - SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(iColumn, iImage)); - hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTCONTACT, (LPARAM)hItem); - } -} - -static void ResetListOptions(HWND hwndList) -{ - int i; - - SendMessage(hwndList, CLM_SETBKBITMAP, 0, (LPARAM)NULL); - SendMessage(hwndList, CLM_SETBKCOLOR, GetSysColor(COLOR_WINDOW), 0); - SendMessage(hwndList, CLM_SETGREYOUTFLAGS, 0, 0); - SendMessage(hwndList, CLM_SETLEFTMARGIN, 4, 0); - SendMessage(hwndList, CLM_SETINDENT, 10, 0); - SendMessage(hwndList, CLM_SETHIDEEMPTYGROUPS, 1, 0); - for(i=0; i <= FONTID_MAX; i++) - SendMessage(hwndList, CLM_SETTEXTCOLOR, i, GetSysColor(COLOR_WINDOWTEXT)); -} - -static void SetIconsForColumn(HWND hwndList, HANDLE hItem, HANDLE hItemAll, int iColumn, int iImage) -{ - int itemType; - - itemType = SendMessage(hwndList, CLM_GETITEMTYPE, (WPARAM)hItem, 0); - if(itemType == CLCIT_CONTACT) { - int oldiImage = SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, iColumn); - if (oldiImage != 0xFF && oldiImage != iImage) - SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(iColumn, iImage)); - } - else if(itemType == CLCIT_INFO) { - if(hItem == hItemAll) - SetAllChildIcons(hwndList, hItem, iColumn, iImage); - else - SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(iColumn, iImage)); //hItemUnknown - } - else if(itemType == CLCIT_GROUP) { - hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_CHILD, (LPARAM)hItem); - if(hItem) - SetAllChildIcons(hwndList, hItem, iColumn, iImage); - } -} - -static void InitialiseItem(HWND hwndList, HANDLE hContact, HANDLE hItem, DWORD protoCaps) -{ - DWORD mask; - int i; - - mask = GetMask(hContact); - for(i=0; i < IGNOREEVENT_MAX; i++) - if(ignoreIdToPf1[i] == 0xFFFFFFFF || protoCaps & ignoreIdToPf1[i]) - SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(i, mask&(1<= 5.01)?ILC_COLOR32:ILC_COLOR16)|ILC_MASK, 3+IGNOREEVENT_MAX, 3+IGNOREEVENT_MAX); - ImageList_AddIcon(hIml, LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_SMALLDOT))); - ImageList_AddIcon(hIml, LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_FILLEDBLOB))); - ImageList_AddIcon(hIml, LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_EMPTYBLOB))); - ImageList_AddIcon(hIml, LoadSkinnedIcon(SKINICON_EVENT_MESSAGE)); - ImageList_AddIcon(hIml, LoadSkinnedIcon(SKINICON_EVENT_URL)); - ImageList_AddIcon(hIml, LoadSkinnedIcon(SKINICON_EVENT_FILE)); - ImageList_AddIcon(hIml, LoadSkinnedIcon(SKINICON_OTHER_MIRANDA)); - SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_SETEXTRAIMAGELIST, 0, (LPARAM)hIml); - for(i=0; i < SIZEOF(hIcons); i++) - hIcons[i] = ImageList_GetIcon(hIml, 1+i, ILD_NORMAL); - } - SendDlgItemMessage(hwndDlg, IDC_ALLICON, STM_SETICON, (WPARAM)hIcons[0], 0); - SendDlgItemMessage(hwndDlg, IDC_NONEICON, STM_SETICON, (WPARAM)hIcons[1], 0); - SendDlgItemMessage(hwndDlg, IDC_MSGICON, STM_SETICON, (WPARAM)hIcons[2], 0); - SendDlgItemMessage(hwndDlg, IDC_URLICON, STM_SETICON, (WPARAM)hIcons[3], 0); - SendDlgItemMessage(hwndDlg, IDC_FILEICON, STM_SETICON, (WPARAM)hIcons[4], 0); - SendDlgItemMessage(hwndDlg, IDC_OTHERICON, STM_SETICON, (WPARAM)hIcons[5], 0); - - SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_LIST), GWL_STYLE, GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_LIST), GWL_STYLE) &~ (CLS_CHECKBOXES|CLS_GROUPCHECKBOXES)); - SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_AUTOREBUILD, 0, 0); - - ResetListOptions(GetDlgItem(hwndDlg, IDC_LIST)); - SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_SETEXTRACOLUMNS, IGNOREEVENT_MAX+2, 0); - - { CLCINFOITEM cii = {0}; - cii.cbSize = sizeof(cii); - cii.flags = CLCIIF_GROUPFONT; - cii.pszText = TranslateT("** All contacts **"); - hItemAll=(HANDLE)SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_ADDINFOITEM, 0, (LPARAM)&cii); - - cii.pszText = TranslateT("** Unknown contacts **"); - hItemUnknown=(HANDLE)SendDlgItemMessage(hwndDlg, IDC_LIST,CLM_ADDINFOITEM, 0, (LPARAM)&cii); - InitialiseItem(GetDlgItem(hwndDlg, IDC_LIST), NULL, hItemUnknown, 0xFFFFFFFF); - } - - SetAllContactIcons(GetDlgItem(hwndDlg, IDC_LIST)); - SetListGroupIcons(GetDlgItem(hwndDlg, IDC_LIST),(HANDLE)SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_GETNEXTITEM, CLGN_ROOT, 0), hItemAll, NULL); - return TRUE; - case WM_SETFOCUS: - SetFocus(GetDlgItem(hwndDlg, IDC_LIST)); - break; - case WM_NOTIFY: - switch(((LPNMHDR)lParam)->idFrom) { - case IDC_LIST: - switch (((LPNMHDR)lParam)->code) - { - case CLN_NEWCONTACT: - case CLN_LISTREBUILT: - SetAllContactIcons(GetDlgItem(hwndDlg, IDC_LIST)); - //fall through - case CLN_CONTACTMOVED: - SetListGroupIcons(GetDlgItem(hwndDlg, IDC_LIST), (HANDLE)SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_GETNEXTITEM, CLGN_ROOT, 0), hItemAll, NULL); - break; - case CLN_OPTIONSCHANGED: - ResetListOptions(GetDlgItem(hwndDlg, IDC_LIST)); - break; - case CLN_CHECKCHANGED: - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - break; - case NM_CLICK: - { int iImage; - HANDLE hItem; - DWORD hitFlags; - NMCLISTCONTROL *nm = (NMCLISTCONTROL*)lParam; - - if(nm->iColumn == -1) - break; - hItem = (HANDLE)SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_HITTEST, (WPARAM)&hitFlags, MAKELPARAM(nm->pt.x, nm->pt.y)); - if(hItem == NULL) - break; - if (!(hitFlags & CLCHT_ONITEMEXTRA)) - break; - if(nm->iColumn == IGNOREEVENT_MAX) { //ignore all - for(iImage=0; iImage < IGNOREEVENT_MAX; iImage++) - SetIconsForColumn(GetDlgItem(hwndDlg, IDC_LIST), hItem, hItemAll, iImage, iImage+3); - } - else if(nm->iColumn == IGNOREEVENT_MAX+1) { //ignore none - for(iImage=0; iImage < IGNOREEVENT_MAX; iImage++) - SetIconsForColumn(GetDlgItem(hwndDlg, IDC_LIST), hItem, hItemAll, iImage, 0); - } - else { - iImage = SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_GETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(nm->iColumn, 0)); - if(iImage == 0) - iImage = nm->iColumn + 3; - else if(iImage != 0xFF) - iImage = 0; - SetIconsForColumn(GetDlgItem(hwndDlg, IDC_LIST), hItem, hItemAll, nm->iColumn, iImage); - } - SetListGroupIcons(GetDlgItem(hwndDlg, IDC_LIST),(HANDLE)SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_GETNEXTITEM, CLGN_ROOT, 0), hItemAll, NULL); - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - break; - } - } - break; - case 0: - switch (((LPNMHDR)lParam)->code) - { - case PSN_APPLY: - { HANDLE hContact, hItem; - - hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); - do { - hItem = (HANDLE)SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_FINDCONTACT, (WPARAM)hContact, 0); - if(hItem) - SaveItemMask(GetDlgItem(hwndDlg, IDC_LIST), hContact, hItem, "Mask1"); - } while(hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)); - SaveItemMask(GetDlgItem(hwndDlg, IDC_LIST), NULL, hItemAll, "Default1"); - SaveItemMask(GetDlgItem(hwndDlg, IDC_LIST), NULL, hItemUnknown, "Mask1"); - return TRUE; - } - } - break; - } - break; - case WM_DESTROY: - { int i; - HIMAGELIST hIml; - for(i=0; i < SIZEOF(hIcons); i++) - DestroyIcon(hIcons[i]); - hIml = (HIMAGELIST)SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_GETEXTRAIMAGELIST, 0, 0); - ImageList_Destroy(hIml); - break; - } - } - return FALSE; -} - -BOOL IsIgnored(HANDLE hContact, WORD eventType) -{ - WORD ignoreID = 0; - DWORD mask = GetMask(hContact); - - switch(eventType) { - case EVENTTYPE_MESSAGE: - ignoreID = 0; - break; - case EVENTTYPE_URL: - ignoreID = 1; - break; - case EVENTTYPE_FILE: - ignoreID = 2; - break; - default: - ignoreID = 3; - } - - return (mask>>ignoreID)&1; -} diff --git a/plugins/KeyboardNotify/ignore.h b/plugins/KeyboardNotify/ignore.h deleted file mode 100644 index a72df7b6f6..0000000000 --- a/plugins/KeyboardNotify/ignore.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - -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. - -*/ - -BOOL IsIgnored(HANDLE, WORD); -INT_PTR CALLBACK DlgProcIgnoreOptions(HWND, UINT, WPARAM, LPARAM); diff --git a/plugins/KeyboardNotify/keyboard.cpp b/plugins/KeyboardNotify/keyboard.cpp deleted file mode 100644 index df1033fce7..0000000000 --- a/plugins/KeyboardNotify/keyboard.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#define WIN32_LEAN_AND_MEAN - -#include -#include -#include -#include "keypresses.h" -#include -#include - - -// Globals -extern BOOL bWindowsNT; -extern BYTE bEmulateKeypresses; -HANDLE hKbdDev[10] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE}; - -// Defines -#define MAX_KBDHANDLES 10 -#define IOCTL_KEYBOARD_SET_INDICATORS CTL_CODE(FILE_DEVICE_KEYBOARD, 0x0002, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_KEYBOARD_QUERY_TYPEMATIC CTL_CODE(FILE_DEVICE_KEYBOARD, 0x0008, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_KEYBOARD_QUERY_INDICATORS CTL_CODE(FILE_DEVICE_KEYBOARD, 0x0010, METHOD_BUFFERED, FILE_ANY_ACCESS) - -typedef struct _KEYBOARD_INDICATOR_PARAMETERS { - USHORT UnitId; // Unit identifier. - USHORT LedFlags; // LED indicator state. - -} KEYBOARD_INDICATOR_PARAMETERS, *PKEYBOARD_INDICATOR_PARAMETERS; - - -void outportb(UINT portid, BYTE value) -{ - #if !defined( _WIN64 ) - __asm mov edx,portid - __asm mov al,value - __asm out dx,al - #endif -} - - -BOOL OpenKeyboardDevice() -{ - int i = 0; - TCHAR aux1[MAX_PATH+1], aux2[MAX_PATH+1]; - - if (!bWindowsNT) - return TRUE; - - do { - _snwprintf(aux1, sizeof(aux1), _T("Kbd%d"), i); - _snwprintf(aux2, sizeof(aux2), _T("\\Device\\KeyboardClass%d"), i); - DefineDosDevice(DDD_RAW_TARGET_PATH, aux1, aux2); - - _snwprintf(aux1, sizeof(aux1), _T("\\\\.\\Kbd%d"), i); - hKbdDev[i] = CreateFile(aux1, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); - - } while (hKbdDev[i] != INVALID_HANDLE_VALUE && ++i < MAX_KBDHANDLES); - - return hKbdDev[0] != INVALID_HANDLE_VALUE; -} - -BOOL ToggleKeyboardLights(BYTE byte) -{ - int i; BOOL result = FALSE; - KEYBOARD_INDICATOR_PARAMETERS InputBuffer; // Input buffer for DeviceIoControl - ULONG DataLength = sizeof(KEYBOARD_INDICATOR_PARAMETERS); - ULONG ReturnedLength; // Number of bytes returned in output buffer - - if (bEmulateKeypresses) - return keypresses_ToggleKeyboardLights(byte); - - if (!bWindowsNT) { - outportb(0x60, 0xED); - Sleep(10); - outportb(0x60, byte); - return TRUE; - } - - InputBuffer.UnitId = 0; - InputBuffer.LedFlags = byte; - - for (i=0; i < MAX_KBDHANDLES && hKbdDev[i] != INVALID_HANDLE_VALUE; i++) - result |= DeviceIoControl(hKbdDev[i], IOCTL_KEYBOARD_SET_INDICATORS, &InputBuffer, DataLength, NULL, 0, &ReturnedLength, NULL); - - return result; -} - -void CloseKeyboardDevice() -{ - int i = 0; - TCHAR aux[MAX_PATH+1]; - - if (!bWindowsNT) - return; - - do { - if (hKbdDev[i] != INVALID_HANDLE_VALUE) - CloseHandle(hKbdDev[i]); - - _snwprintf(aux, sizeof(aux), _T("Kbd%d"), i); - DefineDosDevice(DDD_REMOVE_DEFINITION, aux, NULL); - - } while (hKbdDev[i] != INVALID_HANDLE_VALUE && ++i < MAX_KBDHANDLES); -} diff --git a/plugins/KeyboardNotify/keyboard.h b/plugins/KeyboardNotify/keyboard.h deleted file mode 100644 index 8fe6b52fe9..0000000000 --- a/plugins/KeyboardNotify/keyboard.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - -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. - -*/ - -BOOL OpenKeyboardDevice(void); -BOOL ToggleKeyboardLights(BYTE); -void CloseKeyboardDevice(void); diff --git a/plugins/KeyboardNotify/keyboardnotify-translation.txt b/plugins/KeyboardNotify/keyboardnotify-translation.txt deleted file mode 100644 index f73628491f..0000000000 --- a/plugins/KeyboardNotify/keyboardnotify-translation.txt +++ /dev/null @@ -1,113 +0,0 @@ -; Common strings that belong to many files -;[Ignore] - -; ../../plugins/KeyboardNotify/ignore.cpp -;[** All contacts **] -;[** Unknown contacts **] - -; ../../plugins/KeyboardNotify/main.cpp -;[Message Received] -;[Message Session] -;[Message Session is typing...] - -; ../../plugins/KeyboardNotify/options.cpp -;[Flashing] -;[Keyboard Flash] -;[None] -;[Plugins] -;[Protocol] -;[Protocols] -;[Rules] -;[Themes] -;[\n; Automatically generated Keyboard Notify Theme file\n\n\n] -;[\n; End of automatically generated Keyboard Notify Theme file\n] - -; ../../plugins/KeyboardNotify/resources.rc -;[ ... and not in foreground] -;[&Preview] -;[Accordingly to events' count] -;[Add] -;[All at the same time] -;[All other situations] -;[Away] -;[Blink if message window is open] -;[Cancel] -;[Caps] -;[Caps Lock] -;[Consider event opened after] -;[Create/Edit Themes] -;[Custom theme] -;[DND] -;[Defined programs are running] -;[Delete] -;[Emulate keypresses (Use this option if you are using an USB keyboard)] -;[End of 'notify when' conditions] -;[Events are opened] -;[Events to react on] -;[Everything else] -;[Export...] -;[Fast] -;[File events] -;[Flash speed] -;[Flash until] -;[Flashing effects] -;[Free for chat] -;[Full Screen mode] -;[Ignore URLs] -;[Ignore all] -;[Ignore files] -;[Ignore messages] -;[Ignore none] -;[Ignore others] -;[Import...] -;[Import/Export] -;[In sequence] -;[In turn] -;[Incoming URLs] -;[Incoming files] -;[Incoming messages] -;[Invisible] -;[Keys to flash] -;[Message events] -;[Message-Event only] -;[NA] -;[Notify when] -;[Num] -;[Num Lock] -;[OK] -;[Occupied] -;[Offline] -;[On the phone] -;[Online] -;[Only if last is] -;[Only notify if status is] -;[Other events] -;[Out to lunch] -;[Override existing] -;[Pending Events] -;[Program] -;[Protocols to check] -;[Remind me every] -;[Screen Saver is running] -;[Scroll] -;[Scroll Lock] -;[Set LEDs for events] -;[Set program list] -;[Set xStatus list] -;[Slider1] -;[Slow] -;[Spin1] -;[Tab1] -;[Test] -;[The following events are being ignored:] -;[Theme] -;[URL events] -;[Update] -;[Use custom theme] -;[Wait before starting flashing] -;[Workstation is Locked (2000/XP)] -;[is re-attended] -;[minutes] -;[sec. old] -;[seconds] -;[xStatuses] diff --git a/plugins/KeyboardNotify/keypresses.cpp b/plugins/KeyboardNotify/keypresses.cpp deleted file mode 100644 index 6d1cef58e6..0000000000 --- a/plugins/KeyboardNotify/keypresses.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#define WIN32_LEAN_AND_MEAN -#define _WIN32_WINNT 0x0500 - -#include -#include "flash.h" -#include "keypresses.h" - - -// Prototypes -void SetLock(WORD, BYTE, unsigned int *, INPUT *); - -// Globals -BOOL LEDstateSaved = FALSE; -BYTE LEDstate; - - -void keypresses_RestoreLEDState(void) -{ - if (LEDstateSaved) - keypresses_ToggleKeyboardLights(LEDstate); - LEDstateSaved = FALSE; -} - -BOOL keypresses_ToggleKeyboardLights(BYTE byte) -{ - unsigned int n = 0; - INPUT keystrokes[6] = {0}; - - if (!LEDstateSaved) { - LEDstate = (BYTE)(LedState(VK_SCROLL) + (LedState(VK_NUMLOCK)<<1) + (LedState(VK_CAPITAL)<<2)); - LEDstateSaved = TRUE; - } - - SetLock(VK_NUMLOCK, (BYTE)(byte&2), &n, keystrokes); - SetLock(VK_CAPITAL, (BYTE)(byte&4), &n, keystrokes); - SetLock(VK_SCROLL, (BYTE)(byte&1), &n, keystrokes); - SendInput(n, keystrokes, sizeof(INPUT)); - - return TRUE; -} - -void SetLock(WORD keyCode, BYTE value, unsigned int *n, INPUT *keystrokes) -{ - BYTE status; - - GetAsyncKeyState(keyCode); - status = GetKeyState(keyCode) & 1; - - if ((!value && status) || (value && !status)) { - keystrokes[*n].type = INPUT_KEYBOARD; - keystrokes[*n].ki.wVk = keyCode; - keystrokes[*n].ki.wScan = 0x45; - keystrokes[(*n)++].ki.dwFlags = KEYEVENTF_EXTENDEDKEY | 0; - keystrokes[*n].type = INPUT_KEYBOARD; - keystrokes[*n].ki.wVk = keyCode; - keystrokes[*n].ki.wScan = 0x45; - keystrokes[(*n)++].ki.dwFlags = KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP; - } -} diff --git a/plugins/KeyboardNotify/keypresses.h b/plugins/KeyboardNotify/keypresses.h deleted file mode 100644 index 57e99aa25c..0000000000 --- a/plugins/KeyboardNotify/keypresses.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - -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. - -*/ - -void keypresses_RestoreLEDState(void); -BOOL keypresses_ToggleKeyboardLights(BYTE); diff --git a/plugins/KeyboardNotify/main.cpp b/plugins/KeyboardNotify/main.cpp deleted file mode 100644 index e82cc2cfdc..0000000000 --- a/plugins/KeyboardNotify/main.cpp +++ /dev/null @@ -1,1448 +0,0 @@ -/* - KeyboardNotify plugin v1.5 for Miranda IM - _________________________________________ - - Copyright (C) 2002,2003 Martin Öberg - Copyright (C) 2004 Std - Copyright (C) 2005,2006 TioDuke (tioduke@yahoo.ca) - - - 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. - - - Description - ----------- - This plugin for Miranda-IM notifies user of specified events (as incoming messages, - incoming files, incoming URLs or other events). This plugin is based on the original one - by Martin Öberg (aka strickz) and Std's modifications (mainly the idea of using direct - port handling using a driver). - It has many options allowing: - a) To select on which events to react - b) Under which conditions (eg: fullscreen mode, ScreenSaver running, workstation locked) - c) To act only if the protocol receiving the event is under specified status - d) For message events you can choose to be notified if the message window is open or not - e) A notification feature allowing to be notified of pending events (unopen events) - after specified period of time - f) To select method for stopping the blinking (after x secs, if Miranda is re-attended, - if Windows is re-attended, if all notified events are opened or when the notify conditions - end) - g) And several flashing options: select leds to blink, effects (all at the same time, - in turn, in sequence and like KITT!), preview button - It was designed to be flexible and performing several different tasks. It can be - configured to act like the original one and has several functions from other Miranda's - keyboard notifier plugins. - It also provides a service to allow third party plugins use its notifier abilities. - - Options - ------- - Options page Options->Plugins->Keyboard Flash. Tabbed: Protocols, Rules (when), Flashing (how), Themes and Ignore. - - Thanks - ------ - - Pete for the numerous patches he sent, actively helping to improve the code and - functionality - - UnregistereD for great help in solving problem with Windows activity detection - - Slacktarn, Sir_qwerty and Tweety for giving great help with ideas (most of the new - features included in this plugin were suggested by them) and testing - - The authors of AAA, PopUp+, KeyScrollNotify, original KeyboardNotify, Neweventnotify, - IEView, NGEventNotify for part of their code used in this plugin. - - Vampik fot the InTurn flashing option - - Miranda IM developers for this amazing program - - all other people from Miranda community - - History - ------- - 1.5.7.7: - [!] Added support for Miranda 0.8.x.x. - 1.5.7.6: - [!] Fixed bug in Ignore module. - 1.5.7.5: - [!] Updated TriggerPlugin support for latest version. - 1.5.7.4: - [*] Updated screenshot - [*] Minor code cleaning - 1.5.7.3: - [+] Added xstatus support - 1.5.7.2: - [+] Added per contact Ignore options - 1.5.7.1: - [!] Fix in Options for themes under WinXP+ (really essential feature) - 1.5.7.0: - [+] Added support for Trigger plugin - 1.5.6.3: - [-] Removed device presence validation: it is not needed now that the plugin works on USB (thanks Nick, aka Aestetic) - [+] Added a new service to the API for 'normalizing' a custom flashing sequence string - [-] Simplified the API (the extended version of the start blink service is no longer needed). - 1.5.6.2: - [!] Fixed problem while trying to detect if message window is in foreground. - 1.5.6.1: - [!] Fixed bug with keypress emulation and "until Windows is re-attended" option. - 1.5.6.0: - [+] Option to emulate keypresses (for the USB people) - [*] Changed the emergency key (to make it stop with PAUSE instead of SCROLL LOCK key). - 1.5.5.4: - [*] Improved ListView control handling - [*] Changed the default values (for the sake of new users). - 1.5.5.3: - [*] More code optimization. - 1.5.5.2: - [+] Support for Update plugin. - 1.5.5.1: - [!] Minor source fixes. - 1.5.5.0: - [+] New 'notify when' option: while defined programs are running (just like gamerstatus) - [+] Extended the API to add two new services to disable and re-enable keyboard notifications (for use by bosskey plugin). - 1.5.4.4: - [!] Fixed (hopefully) problems with some system configurations (with PS2 keyboards) where the KeyboardClass0 device was not the apropriate one (thanks pete!) - [+] Extended the plugin API (requested bt tweety). - 1.5.4.3: - [!] Fixed some compatibility issues with nconvers++ (thank you donatas for your help). - 1.5.4.2: - [!] Fixed problem with Windows' activity detection under Win9X when using other plugins that do the same. - [!] Fixed crash caused by incoming authorisation requests when metacontacts was enabled. - 1.5.4.1: - [!] Some corrections on third party plugins events handling (now they are more assimilated to the 'other events') - [*] Some code cleaning - [!] Fixed problem with first message in Metacontacts recognition while checking for pending events (thank you again NirG) - 1.5.4.0: - [+] New plugin API (thank you CriS for your ideas and great help) - [!] Added Offline status to status check list (thank you Slaktarn for finding it). - 1.5.3.4: - [!] Fixed Metacontacts recognition in checking and counting of pending events (thank you NirG for finding the problem) - [!] Fixed problems with multiple instances of the plugin running (thank you tweety for reporting and testing). - 1.5.3.3: - [!] Changed behaviour of Preview button to make it independent of the rules' options. - 1.5.3.2: - [+] New dialog to asign leds to specific events for the trillian-like sequences. - 1.5.3.1: - [!] Fixed bug of loosing any other until setting when selecting 'Events are opened'. - 1.5.3.0: - [+] Applied pete's patches (thank you very much for your great work) - - Use of GetLastInputInfo when possible for detecting Windows' activity - - Made Windows' mouse hooks also aware of mouse clicking - - Made Miranda re-attended option react on windows restoring and ignoring mouse hovering an unfocused window - - New option for message events to avoid blinking if message window is focused - - Made the plugin handle metacontact's special issues - [!] Use of the new message API for windows detection when possible - [+] New message event option to check last message timestamp (requested by D46MD) - [+] Possibility of choosing more than one flash until option at the same time - [+] New flashing effect to make the leds blink accordingly to number of events - [+] Possibility of selecting/unselecting protocols (requested by tweety, usuful to avoid flashing on some protocols as rss) - 1.5.2.2: - [!] scriver's message window detection (thanks D46MD for your great help) - [!] corrected 'flash until' checking accordingly to pete's patch (thank you) - 1.5.2.1: - [!] nconvers++'s message window detection - [!] checked window detection for srmm, scriver, sramm and srmm_mod - 1.5.2.0: - [+] Custom theme support - [-] Custom order history - 1.5.1.0: - [+] Custom order effect - [+] Custom order history - 1.5.0.0: - [+] Drivers aren't needed anymore - [+] Status selection option - [+] Miranda/Windows activity detection (thank you Peter Boon) - [+] 'Opened events' stop method - [+] x seconds stop method - [+] Hooking database event for detecting incoming events - [+] Notifier option for pending events - [+] Checkbox for enabling disabling open messages notification - [+] In sequence and KIT flashing effects - [+] Preview button - [+] Tabbed options - [!] Several corrections/improvements in options page - [!] Not selected leds will preserve their original state - 1.4.1.0: (by me and Vampik) - [+] Notify on fullscreen, screensaver, worksation locked - [!] Try to improve Win98 keysimulation routines - [+] Added InTurn effect (thank you Vampik) - [!] Corrected speed of blinking (thank you Vampik) - 1.4.0.0: (by Std, unreleased) - [+] Added direct port handling using PortTalk.sys driver - 1.3.0.0: (by strickz) - This is strickz' final release. It still uses keypress simulation. It was nice (thanks *g*) - - -*/ - -#define WIN32_LEAN_AND_MEAN -#define _WIN32_WINNT 0x0500 - -#include -#include -#include -#include "flash.h" -#include "ignore.h" -#include "keyboard.h" -#include "trigger.h" -#include "constants.h" -#include "protolist.h" -#include "EnumProc.h" -#include "utils.h" -#include "m_kbdnotify.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#pragma comment(lib, "advapi32.lib") - -#define NCONVERS_BLINKID ((HANDLE)123456) //nconvers' random identifier used to flash an icon for "incoming message" on contact list - -#ifndef SPI_GETSCREENSAVERRUNNING -#define SPI_GETSCREENSAVERRUNNING 114 -#endif - -#ifndef WM_XBUTTONDBLCLK -#define WM_XBUTTONDBLCLK 0x020D -#endif -#ifndef WM_NCXBUTTONDBLCLK -#define WM_NCXBUTTONDBLCLK 0x00AD -#endif - - -HINSTANCE hInst; - -int hLangpack; - -DWORD IDThread = 0; -HANDLE hThread = NULL; -HANDLE hFlashEvent; -HANDLE hExitEvent; - -HANDLE hModulesLoaded = NULL; -HANDLE hMsgEventHook = NULL; -HANDLE hOptionsInitialize = NULL; -HANDLE hEnableService = NULL; -HANDLE hDisableService = NULL; -HANDLE hStartBlinkService = NULL; -HANDLE hEventsOpenedService = NULL; -HANDLE hFlashingEventService = NULL; -HANDLE hNormalizeSequenceService = NULL; - -HHOOK hMirandaMouseHook = NULL; -HHOOK hMirandaKeyBoardHook = NULL; -HHOOK hMirandaWndProcHook = NULL; -UINT hReminderTimer = 0; - -#pragma data_seg("Shared") -HHOOK hMouseHook = NULL; -HHOOK hKeyBoardHook = NULL; -BYTE bEmulateKeypresses = 0; -DWORD dwLastInput = 0; -POINT lastGlobalMousePos = {0, 0}; -#pragma data_seg() -#pragma comment(linker, "/section:Shared,rws") - -static BOOL (WINAPI * MyGetLastInputInfo)(PLASTINPUTINFO); - - -BYTE bFlashOnMsg; -BYTE bFlashOnURL; -BYTE bFlashOnFile; -BYTE bFlashOnOther; -BYTE bFullScreenMode; -BYTE bScreenSaverRunning; -BYTE bWorkstationLocked; -BYTE bProcessesAreRunning; -BYTE bWorkstationActive; -BYTE bFlashIfMsgOpen; -BYTE bFlashIfMsgWinNotTop; -BYTE bFlashIfMsgOlder; -WORD wSecondsOlder; -BYTE bFlashUntil; -WORD wBlinksNumber; -BYTE bMirandaOrWindows; -WORD wStatusMap; -WORD wReminderCheck; -BYTE bFlashLed[3]; -BYTE bFlashEffect; -BYTE bSequenceOrder; -WORD wCustomTheme; -WORD wStartDelay; -BYTE bFlashSpeed; -BYTE bOverride; -BYTE bTrillianLedsMsg; -BYTE bTrillianLedsURL; -BYTE bTrillianLedsFile; -BYTE bTrillianLedsOther; - -PROTOCOL_LIST ProtoList = {0, NULL}; -PROCESS_LIST ProcessList = {0, NULL}; - -double dWinVer; -BOOL bWindowsNT; - -int nWaitDelay; -unsigned int nExternCount = 0; -BOOL bFlashingEnabled = TRUE; -BOOL bReminderDisabled = FALSE; - -char *szMetaProto = NULL; -BYTE bMetaProtoEnabled = 0; - -#define MIID_KBDNOTIFY {0x119d7288, 0x2050, 0x448d, { 0x99, 0x00, 0xd8, 0x6a, 0xc7, 0x04, 0x26, 0xbf }} - -PLUGININFOEX pluginInfo={ - sizeof(PLUGININFOEX), - "Keyboard Notify Ext.", - PLUGIN_MAKE_VERSION(1,5,7,7), - "Flashes your keyboard LEDs when a message has arrived", - "TioDuke", - "tioduke@yahoo.ca", - "© 2002-2003 M.Öberg, 2004 Std, 2005-2008 TioDuke", - "http://addons.miranda-im.org/", - UNICODE_AWARE, //doesn't replace anything built-in - MIID_KBDNOTIFY //{119D7288-2050-448d-9900-D86AC70426BF} -}; - - - -int InitializeOptions(WPARAM,LPARAM); -void LoadSettings(void); -int HookWindowsHooks(void); -int UnhookWindowsHooks(void); -static LRESULT CALLBACK MouseHookFunction(int, WPARAM, LPARAM); -static LRESULT CALLBACK KeyBoardHookFunction(int, WPARAM, LPARAM); -static LRESULT CALLBACK MirandaMouseHookFunction(int, WPARAM, LPARAM); -static LRESULT CALLBACK MirandaKeyBoardHookFunction(int, WPARAM, LPARAM); -static LRESULT CALLBACK MirandaWndProcHookFunction(int, WPARAM, LPARAM); -BOOL CheckMsgWnd(HANDLE, BOOL *); - - -BOOL isMetaContactsSubContact(HANDLE hMetaContact, HANDLE hContact) -{ - char *szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hMetaContact, 0); - if (szProto && !strcmp(szMetaProto, szProto)) { // Safety check - int i = DBGetContactSettingDword(hContact, szMetaProto, "ContactNumber", -1); - if (i >= 0 && hContact == (HANDLE)CallService(MS_MC_GETSUBCONTACT, (WPARAM)hMetaContact, i)) - return TRUE; - } - return FALSE; -} - - -BOOL checkOpenWindow(HANDLE hContact) -{ - BOOL found, focus; - - if (bFlashIfMsgOpen && !bFlashIfMsgWinNotTop) - return TRUE; - - found = CheckMsgWnd(hContact, &focus); - if (!found && szMetaProto && bMetaProtoEnabled) { - HANDLE hMetaContact = (HANDLE)DBGetContactSettingDword(hContact, szMetaProto, "Handle", 0); - if (hMetaContact && isMetaContactsSubContact(hMetaContact, hContact)) - found = CheckMsgWnd(hMetaContact, &focus); - } - if (!found) - return TRUE; - - if (bFlashIfMsgOpen && !focus) - return TRUE; - - return FALSE; -} - - -BOOL IsSaverOnNT4() -{ - HDESK hd = OpenDesktop(L"screen-saver", 0, FALSE, MAXIMUM_ALLOWED); - - if(hd == NULL) - return GetLastError()==ERROR_ACCESS_DENIED; - - CloseDesktop(hd); - return TRUE; -} - - -BOOL isScreenSaverRunning() -{ - BOOL screenSaverIsRunning=FALSE; - - if (bWindowsNT && dWinVer < 5) return IsSaverOnNT4(); - - SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, &screenSaverIsRunning, FALSE); - return screenSaverIsRunning; -} - - -/* this function is from the original idle module */ -BOOL isWorkstationLocked() -{ - HDESK hd; - char buf[MAX_PATH]; - - if (!bWindowsNT) return FALSE; - - hd = OpenInputDesktop(0, FALSE, MAXIMUM_ALLOWED); /* if it fails then the workstation is prolly locked anyway */ - if (hd == NULL) return TRUE; - GetUserObjectInformation(hd, UOI_NAME, buf, sizeof(buf), NULL); /* if we got it (hmm,) get a name */ - CloseDesktop(hd); - return strcmp(buf, "Winlogon")==0; -} - - -BOOL isFullScreen() -{ - int w = GetSystemMetrics(SM_CXSCREEN); - int h = GetSystemMetrics(SM_CYSCREEN); - - HWND hWnd = 0; - while (hWnd = FindWindowEx(NULL, hWnd, NULL, NULL)) { - RECT WindowRect; - - if (!(GetWindowLongPtr(hWnd, GWL_EXSTYLE) & WS_EX_TOPMOST)) - continue; - - GetWindowRect(hWnd, &WindowRect); - if ((w != (WindowRect.right - WindowRect.left)) || (h != (WindowRect.bottom - WindowRect.top))) - continue; - - return TRUE; - } - - return FALSE; -} - - -BOOL checkNotifyOptions() -{ - BOOL fullScreenMode, screenSaverIsRunning, workstationIsLocked, processesRunning; - - screenSaverIsRunning = isScreenSaverRunning(); - if (screenSaverIsRunning && bScreenSaverRunning) - return TRUE; - - workstationIsLocked = isWorkstationLocked(); - if (workstationIsLocked && bWorkstationLocked) - return TRUE; - - fullScreenMode = isFullScreen() && !screenSaverIsRunning; - if (fullScreenMode && bFullScreenMode) - return TRUE; - - processesRunning = areThereProcessesRunning(); - if (processesRunning && bProcessesAreRunning) - return TRUE; - - return (!fullScreenMode && !screenSaverIsRunning && !workstationIsLocked && !processesRunning && bWorkstationActive); -} - - -BOOL isStatusEnabled(int status) -{ - switch (status) { - case ID_STATUS_OFFLINE: return wStatusMap & MAP_OFFLINE; - case ID_STATUS_ONLINE: return wStatusMap & MAP_ONLINE; - case ID_STATUS_AWAY: return wStatusMap & MAP_AWAY; - case ID_STATUS_NA: return wStatusMap & MAP_NA; - case ID_STATUS_OCCUPIED: return wStatusMap & MAP_OCCUPIED; - case ID_STATUS_DND: return wStatusMap & MAP_DND; - case ID_STATUS_FREECHAT: return wStatusMap & MAP_FREECHAT; - case ID_STATUS_INVISIBLE: return wStatusMap & MAP_INVISIBLE; - case ID_STATUS_ONTHEPHONE: return wStatusMap & MAP_ONTHEPHONE; - case ID_STATUS_OUTTOLUNCH: return wStatusMap & MAP_OUTTOLUNCH; - default: return FALSE; - } -} - - -BOOL checkGlobalStatus() -{ - return isStatusEnabled(CallService(MS_CLIST_GETSTATUSMODE, 0, 0)); -} - - -BOOL checkGlobalXstatus() -{ - ICQ_CUSTOM_STATUS xstatus={0}; - unsigned int i, protosSupporting; int status=0; - - for(i=0, protosSupporting=0; i < ProtoList.protoCount; i++) { - if (!ProtoList.protoInfo[i].enabled || !ProtoList.protoInfo[i].xstatus.count) continue; - - protosSupporting++; - // Retrieve xstatus for protocol - xstatus.cbSize = sizeof(ICQ_CUSTOM_STATUS); - xstatus.flags = CSSF_MASK_STATUS; - xstatus.status = &status; - CallProtoService(ProtoList.protoInfo[i].szProto, PS_ICQ_GETCUSTOMSTATUSEX, 0, (LPARAM)&xstatus); - - if (ProtoList.protoInfo[i].xstatus.enabled[status]) return TRUE; - } - - if (!protosSupporting) - return TRUE; - else - return FALSE; -} - - -DBEVENTINFO createMsgEventInfo(HANDLE hContact) -{ - DBEVENTINFO einfo = {0}; - - einfo.cbSize = sizeof(einfo); - einfo.eventType = EVENTTYPE_MESSAGE; - einfo.szModule = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); - - return einfo; -} - - -DBEVENTINFO readEventInfo(HANDLE hDbEvent, HANDLE hContact) -{ - DBEVENTINFO einfo = {0}; - - if (hDbEvent == NCONVERS_BLINKID) // we need to handle nconvers' blink event - return createMsgEventInfo(hContact); - - einfo.cbSize = sizeof(einfo); - einfo.cbBlob = 0; - einfo.pBlob = NULL; - CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&einfo); - - return einfo; -} - - -BOOL checkIgnore(HANDLE hContact, WORD eventType) -{ - return !IsIgnored(hContact, eventType); -} - - -BOOL checkProtocol(char *szProto) -{ - unsigned int i; - - if (!szProto) - return FALSE; - - for(i=0; i < ProtoList.protoCount; i++) - if (ProtoList.protoInfo[i].szProto && !strcmp(ProtoList.protoInfo[i].szProto, szProto)) - return ProtoList.protoInfo[i].enabled; - - return FALSE; -} - - -BOOL metaCheckProtocol(char *szProto, HANDLE hContact, WORD eventType) -{ - HANDLE hSubContact=NULL; - - if (szMetaProto && bMetaProtoEnabled && szProto && !strcmp(szMetaProto, szProto)) - if (hSubContact = (HANDLE)CallService(MS_MC_GETMOSTONLINECONTACT, (WPARAM)hContact, 0)) - szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hSubContact, 0); - - return checkProtocol(szProto) && checkIgnore(hSubContact?hSubContact:hContact, eventType); -} - - -BOOL checkUnopenEvents() -{ - int nIndex; - CLISTEVENT *pCLEvent; - - if (nExternCount && bFlashOnOther) - return TRUE; - - for (nIndex = 0; pCLEvent = (CLISTEVENT*)CallService(MS_CLIST_GETEVENT, -1, nIndex); nIndex++) { - DBEVENTINFO einfo = readEventInfo(pCLEvent->hDbEvent, pCLEvent->hContact); - - if ((einfo.eventType == EVENTTYPE_MESSAGE && bFlashOnMsg) || - (einfo.eventType == EVENTTYPE_URL && bFlashOnURL) || - (einfo.eventType == EVENTTYPE_FILE && bFlashOnFile) || - (einfo.eventType != EVENTTYPE_MESSAGE && einfo.eventType != EVENTTYPE_URL && einfo.eventType != EVENTTYPE_FILE && bFlashOnOther)) - - if (metaCheckProtocol(einfo.szModule, pCLEvent->hContact, einfo.eventType)) - return TRUE; - } - - return FALSE; -} - - -static void FlashThreadFunction() -{ - BOOL bEvent = FALSE; - DWORD dwEventStarted, dwFlashStarted; - BYTE data, unchangedLeds; - - while (TRUE) { - unchangedLeds = (BYTE)(LedState(VK_PAUSE) * !bFlashLed[2] + ((LedState(VK_NUMLOCK) * !bFlashLed[0])<<1) + ((LedState(VK_CAPITAL) * !bFlashLed[1])<<2)); - GetAsyncKeyState(VK_PAUSE); // empty Pause/Break's keystroke buffer - - // Start flashing - while(bEvent && bFlashingEnabled) - { - // Let's give the user the opportunity of finishing flashing manually :) - if (GetAsyncKeyState(VK_PAUSE) & 1) - break; - - if ((bFlashUntil & UNTIL_NBLINKS) && GetTickCount() > (dwFlashStarted + wBlinksNumber * 1000)) - break; - if (bFlashUntil & UNTIL_REATTENDED) { - if (bMirandaOrWindows == ACTIVE_WINDOWS && MyGetLastInputInfo && !bEmulateKeypresses) { - LASTINPUTINFO lii; - ZeroMemory(&lii, sizeof(lii)); - lii.cbSize = sizeof(lii); - MyGetLastInputInfo(&lii); - dwLastInput = lii.dwTime; - } - if (dwLastInput > dwEventStarted) - break; - } - if ((bFlashUntil & UNTIL_EVENTSOPEN) && !checkUnopenEvents()) - break; - if ((bFlashUntil & UNTIL_CONDITIONS) && (!checkNotifyOptions() || !checkGlobalStatus() || !checkGlobalXstatus())) - break; - - data = getBlinkingLeds(); - ToggleKeyboardLights((BYTE)(data|unchangedLeds)); - - // Wait for exit event - if (WaitForSingleObject(hExitEvent, nWaitDelay) == WAIT_OBJECT_0) - return; - } - RestoreLEDState(); - - setFlashingSequence(); - bReminderDisabled = FALSE; - - // Wait for new event - { - DWORD dwEvent; - HANDLE Objects[2]; - Objects[0] = hFlashEvent; - Objects[1] = hExitEvent; - dwEvent = WaitForMultipleObjects(2, Objects, FALSE, INFINITE); - if ((dwEvent - WAIT_OBJECT_0) == 1) - return; - } - - bEvent = TRUE; - bReminderDisabled = TRUE; - dwEventStarted = GetTickCount(); - // Wait StartDelay seconds - if (wStartDelay > 0) - Sleep(wStartDelay * 1000); - dwFlashStarted = GetTickCount(); - - } - -} - - -BOOL checkMsgTimestamp(HANDLE hEventCurrent, DWORD timestampCurrent) -{ - HANDLE hEvent; - - if (!bFlashIfMsgOlder) - return TRUE; - - for (hEvent=(HANDLE)CallService(MS_DB_EVENT_FINDPREV, (WPARAM)hEventCurrent, 0); hEvent; hEvent=(HANDLE)CallService(MS_DB_EVENT_FINDPREV, (WPARAM)hEvent, 0)) { - DBEVENTINFO einfo = {0}; - - einfo.cbSize = sizeof(einfo); - einfo.cbBlob = 0; - einfo.pBlob = NULL; - CallService(MS_DB_EVENT_GET, (WPARAM)hEvent, (LPARAM)&einfo); - if ((einfo.timestamp + wSecondsOlder) <= timestampCurrent) - return TRUE; - if (einfo.eventType == EVENTTYPE_MESSAGE) - return FALSE; - } - - return TRUE; -} - - -BOOL contactCheckProtocol(char *szProto, HANDLE hContact, WORD eventType) -{ - if (szMetaProto && bMetaProtoEnabled && hContact) { - HANDLE hMetaContact = (HANDLE)DBGetContactSettingDword(hContact, szMetaProto, "Handle", 0); - if (hMetaContact && isMetaContactsSubContact(hMetaContact, hContact)) - return FALSE; - } - - return (metaCheckProtocol(szProto, hContact, eventType)); -} - - -BOOL checkStatus(char *szProto) -{ - if (!szProto) - return checkGlobalStatus(); - - return isStatusEnabled(CallProtoService(szProto, PS_GETSTATUS, 0, 0)); -} - - -BOOL checkXstatus(char *szProto) -{ - unsigned int i; int status=0; - ICQ_CUSTOM_STATUS xstatus={0}; - - if (!szProto) - return checkGlobalXstatus(); - - for(i=0; i < ProtoList.protoCount; i++) - if (ProtoList.protoInfo[i].szProto && !strcmp(ProtoList.protoInfo[i].szProto, szProto)) { - if (!ProtoList.protoInfo[i].xstatus.count) return TRUE; - - // Retrieve xstatus for protocol - xstatus.cbSize = sizeof(ICQ_CUSTOM_STATUS); - xstatus.flags = CSSF_MASK_STATUS; - xstatus.status = &status; - CallProtoService(ProtoList.protoInfo[i].szProto, PS_ICQ_GETCUSTOMSTATUSEX, 0, (LPARAM)&xstatus); - - return ProtoList.protoInfo[i].xstatus.enabled[status]; - } - - return TRUE; -} - - -// 'Pings' the FlashThread to keep the LEDs flashing. -static int PluginMessageEventHook(WPARAM wParam, LPARAM lParam) -{ - DBEVENTINFO einfo = {0}; - HANDLE hContact = (HANDLE)wParam; - HANDLE hEvent = (HANDLE)lParam; - - //get DBEVENTINFO without pBlob - einfo.cbSize = sizeof(einfo); - einfo.cbBlob = 0; - einfo.pBlob = NULL; - CallService(MS_DB_EVENT_GET, (WPARAM)hEvent, (LPARAM)&einfo); - - if (!(einfo.flags & DBEF_SENT)) - if ((einfo.eventType == EVENTTYPE_MESSAGE && bFlashOnMsg && checkOpenWindow(hContact) && checkMsgTimestamp(hEvent, einfo.timestamp)) || - (einfo.eventType == EVENTTYPE_URL && bFlashOnURL) || - (einfo.eventType == EVENTTYPE_FILE && bFlashOnFile) || - (einfo.eventType != EVENTTYPE_MESSAGE && einfo.eventType != EVENTTYPE_URL && einfo.eventType != EVENTTYPE_FILE && bFlashOnOther)) { - - if (contactCheckProtocol(einfo.szModule, hContact, einfo.eventType) && checkNotifyOptions() && checkStatus(einfo.szModule) && checkXstatus(einfo.szModule)) - - SetEvent(hFlashEvent); - } - - return 0; -} - - -// ** -// ** Checks for pending events. If it finds any, it pings the FlashThread to keep the LEDs flashing. -// ** - -static VOID CALLBACK ReminderTimer(HWND hwnd, UINT message, UINT_PTR idEvent, DWORD dwTime) -{ - int nIndex; - CLISTEVENT *pCLEvent; - - if (!bReminderDisabled && nExternCount && bFlashOnOther) { - SetEvent(hFlashEvent); - return; - } - - for (nIndex = 0; !bReminderDisabled && (pCLEvent = (CLISTEVENT*)CallService(MS_CLIST_GETEVENT, -1, nIndex)); nIndex++) { - DBEVENTINFO einfo = readEventInfo(pCLEvent->hDbEvent, pCLEvent->hContact); - - if ((einfo.eventType == EVENTTYPE_MESSAGE && bFlashOnMsg) || - (einfo.eventType == EVENTTYPE_URL && bFlashOnURL) || - (einfo.eventType == EVENTTYPE_FILE && bFlashOnFile) || - (einfo.eventType != EVENTTYPE_MESSAGE && einfo.eventType != EVENTTYPE_URL && einfo.eventType != EVENTTYPE_FILE && bFlashOnOther)) - - if (metaCheckProtocol(einfo.szModule, pCLEvent->hContact, einfo.eventType) && checkNotifyOptions() && checkStatus(einfo.szModule) && checkXstatus(einfo.szModule)) { - - SetEvent(hFlashEvent); - return; - } - } - -} - - -// Support for third-party plugins and mBot's scripts -static INT_PTR EnableService(WPARAM wParam, LPARAM lParam) -{ - bFlashingEnabled = TRUE; - return 0; -} - -static INT_PTR DisableService(WPARAM wParam, LPARAM lParam) -{ - bFlashingEnabled = FALSE; - return 0; -} - -static INT_PTR StartBlinkService(WPARAM wParam, LPARAM lParam) -{ - nExternCount += (unsigned int)wParam; - if (bFlashOnOther && checkNotifyOptions() && checkGlobalStatus() && checkGlobalXstatus()) { - if (lParam) - useExternSequence((TCHAR *)lParam); - SetEvent(hFlashEvent); - } - - return 0; -} - -static INT_PTR EventsWereOpenedService(WPARAM wParam, LPARAM lParam) -{ - if ((unsigned int)wParam > nExternCount) - nExternCount = 0; - else - nExternCount -= (unsigned int)wParam; - - return 0; -} - - -static INT_PTR IsFlashingActiveService(WPARAM wParam, LPARAM lParam) -{ - if (!bReminderDisabled) - return 0; - - return (int)getCurrentSequenceString(); -} - - -INT_PTR NormalizeSequenceService(WPARAM wParam, LPARAM lParam) -{ - TCHAR strAux[MAX_PATH+1], *strIn = (TCHAR *)lParam; - - _snwprintf(strAux, MAX_PATH, _T("%s"), strIn); - _snwprintf(strIn, MAX_PATH, _T("%s"), normalizeCustomString(strAux)); - - return (int)strIn; -} - - -// Support for Trigger plugin -static void ForceEventsWereOpenedThread(void *eventMaxSeconds) -{ - Sleep(((WORD)eventMaxSeconds) * 1000); - CallService(MS_KBDNOTIFY_EVENTSOPENED, 1, 0); -} - - -void StartBlinkAction(char *flashSequence, WORD eventMaxSeconds) -{ - DWORD threadID = 0; - - if (eventMaxSeconds) - CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ForceEventsWereOpenedThread, (void *)eventMaxSeconds, 0, &threadID); - - CallService(MS_KBDNOTIFY_STARTBLINK, 1, (LPARAM)flashSequence); -} - - -void createProcessList(void) -{ - DBVARIANT dbv; - unsigned int i, count; - - count = (unsigned int)DBGetContactSettingWord(NULL, KEYBDMODULE, "processcount", 0); - - ProcessList.count = 0; - ProcessList.szFileName = (TCHAR **)malloc(count * sizeof(TCHAR *)); - if (ProcessList.szFileName) { - for(i=0; i < count; i++) - if (DBGetContactSetting(NULL, KEYBDMODULE, fmtDBSettingName("process%d", i), &dbv)) - ProcessList.szFileName[i] = NULL; - else { - ProcessList.szFileName[i] = (TCHAR *)malloc(wcslen(dbv.ptszVal) + 1); - if (ProcessList.szFileName[i]) - wcscpy(ProcessList.szFileName[i], dbv.ptszVal); - DBFreeVariant(&dbv); - } - ProcessList.count = count; - } - -} - - -void destroyProcessList(void) -{ - unsigned int i, count; - - count = ProcessList.count; - - ProcessList.count = 0; - for(i=0; i < count; i++) - if (ProcessList.szFileName[i]) - free(ProcessList.szFileName[i]); - - if (ProcessList.szFileName) - free(ProcessList.szFileName); - ProcessList.szFileName = NULL; -} - - -void LoadSettings(void) -{ - unsigned int i; - - bFlashOnMsg = DBGetContactSettingByte(NULL, KEYBDMODULE, "onmsg", DEF_SETTING_ONMSG); - bFlashOnURL = DBGetContactSettingByte(NULL, KEYBDMODULE, "onurl", DEF_SETTING_ONURL); - bFlashOnFile = DBGetContactSettingByte(NULL, KEYBDMODULE, "onfile", DEF_SETTING_ONFILE); - bFlashOnOther = DBGetContactSettingByte(NULL, KEYBDMODULE, "onother", DEF_SETTING_OTHER); - bFullScreenMode = DBGetContactSettingByte(NULL, KEYBDMODULE, "fscreenmode", DEF_SETTING_FSCREEN); - bScreenSaverRunning = DBGetContactSettingByte(NULL, KEYBDMODULE, "ssaverrunning", DEF_SETTING_SSAVER); - bWorkstationLocked = (bWindowsNT ? DBGetContactSettingByte(NULL, KEYBDMODULE, "wstationlocked", DEF_SETTING_LOCKED):0); - bProcessesAreRunning = DBGetContactSettingByte(NULL, KEYBDMODULE, "procsrunning", DEF_SETTING_PROCS); - bWorkstationActive = DBGetContactSettingByte(NULL, KEYBDMODULE, "wstationactive", DEF_SETTING_ACTIVE); - bFlashIfMsgOpen = DBGetContactSettingByte(NULL, KEYBDMODULE, "ifmsgopen", DEF_SETTING_IFMSGOPEN); - bFlashIfMsgWinNotTop = DBGetContactSettingByte(NULL, KEYBDMODULE, "ifmsgnottop", DEF_SETTING_IFMSGNOTTOP); - bFlashIfMsgOlder = DBGetContactSettingByte(NULL, KEYBDMODULE, "ifmsgolder", DEF_SETTING_IFMSGOLDER); - wSecondsOlder = DBGetContactSettingWord(NULL, KEYBDMODULE, "secsolder", DEF_SETTING_SECSOLDER); - bFlashUntil = DBGetContactSettingByte(NULL, KEYBDMODULE, "funtil", DEF_SETTING_FLASHUNTIL); - wBlinksNumber = DBGetContactSettingWord(NULL, KEYBDMODULE, "nblinks", DEF_SETTING_NBLINKS); - bMirandaOrWindows = DBGetContactSettingByte(NULL, KEYBDMODULE, "mirorwin", DEF_SETTING_MIRORWIN); - wStatusMap = DBGetContactSettingWord(NULL, KEYBDMODULE, "status", DEF_SETTING_STATUS); - wReminderCheck = DBGetContactSettingWord(NULL, KEYBDMODULE, "remcheck", DEF_SETTING_CHECKTIME); - bFlashLed[0] = !!DBGetContactSettingByte(NULL, KEYBDMODULE, "fnum", DEF_SETTING_FLASHNUM); - bFlashLed[1] = !!DBGetContactSettingByte(NULL, KEYBDMODULE, "fcaps", DEF_SETTING_FLASHCAPS); - bFlashLed[2] = !!DBGetContactSettingByte(NULL, KEYBDMODULE, "fscroll", DEF_SETTING_FLASHSCROLL); - bFlashEffect = DBGetContactSettingByte(NULL, KEYBDMODULE, "feffect", DEF_SETTING_FLASHEFFECT); - bSequenceOrder = DBGetContactSettingByte(NULL, KEYBDMODULE, "order", DEF_SETTING_SEQORDER); - wCustomTheme = DBGetContactSettingWord(NULL, KEYBDMODULE, "custom", DEF_SETTING_CUSTOMTHEME); - bTrillianLedsMsg = DBGetContactSettingByte(NULL, KEYBDMODULE, "ledsmsg", DEF_SETTING_LEDSMSG); - bTrillianLedsURL = DBGetContactSettingByte(NULL, KEYBDMODULE, "ledsurl", DEF_SETTING_LEDSURL); - bTrillianLedsFile = DBGetContactSettingByte(NULL, KEYBDMODULE, "ledsfile", DEF_SETTING_LEDSFILE); - bTrillianLedsOther = DBGetContactSettingByte(NULL, KEYBDMODULE, "ledsother", DEF_SETTING_LEDSOTHER); - wStartDelay = DBGetContactSettingWord(NULL, KEYBDMODULE, "sdelay", DEF_SETTING_STARTDELAY); - bFlashSpeed = DBGetContactSettingByte(NULL, KEYBDMODULE, "speed", DEF_SETTING_FLASHSPEED); - switch (bFlashSpeed) { - case 0: nWaitDelay = 1500; break; - case 1: nWaitDelay = 0750; break; - case 2: nWaitDelay = 0250; break; - case 3: nWaitDelay = 0150; break; - case 4: nWaitDelay = 0100; break; - default: nWaitDelay = 0050; break; - } - setFlashingSequence(); - bEmulateKeypresses = DBGetContactSettingByte(NULL, KEYBDMODULE, "keypresses", DEF_SETTING_KEYPRESSES); - bOverride = DBGetContactSettingByte(NULL, KEYBDMODULE, "override", DEF_SETTING_OVERRIDE); - // Create hidden settings (for test button) if needed - if (DBGetContactSettingByte(NULL, KEYBDMODULE, "testnum", -1) == -1) - DBWriteContactSettingByte(NULL, KEYBDMODULE, "testnum", DEF_SETTING_TESTNUM); - if (DBGetContactSettingByte(NULL, KEYBDMODULE, "testsecs", -1) == -1) - DBWriteContactSettingByte(NULL, KEYBDMODULE, "testsecs", DEF_SETTING_TESTSECS); - for(i=0; i < ProtoList.protoCount; i++) - if (ProtoList.protoInfo[i].visible) { - unsigned int j; - ProtoList.protoInfo[i].enabled = DBGetContactSettingByte(NULL, KEYBDMODULE, ProtoList.protoInfo[i].szProto, DEF_SETTING_PROTOCOL); - for(j=0; j < ProtoList.protoInfo[i].xstatus.count; j++) - ProtoList.protoInfo[i].xstatus.enabled[j] = DBGetContactSettingByte(NULL, KEYBDMODULE, fmtDBSettingName("%sxstatus%d", ProtoList.protoInfo[i].szProto, j), DEF_SETTING_XSTATUS); - } - - if (szMetaProto) - bMetaProtoEnabled = DBGetContactSettingByte(NULL, szMetaProto, "Enabled", 1); - - destroyProcessList(); - createProcessList(); - UnhookWindowsHooks(); - HookWindowsHooks(); -} - - -void GetWindowsVersion(void) -{ - OSVERSIONINFOEX osvi; - BOOL bOsVersionInfoEx; - - ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - if (!(bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO *) &osvi))) { - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - if (!GetVersionEx((OSVERSIONINFO *)&osvi)) - osvi.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS; - } - bWindowsNT = osvi.dwPlatformId==VER_PLATFORM_WIN32_NT; - dWinVer = osvi.dwMajorVersion + osvi.dwMinorVersion / 10.0; -} - - -void updateXstatusProto(PROTOCOL_INFO *protoInfo) -{ - unsigned int i; - char szServiceName[MAXMODULELABELLENGTH]; - ICQ_CUSTOM_STATUS xstatus={0}; - - mir_snprintf(szServiceName, sizeof(szServiceName), "%s%s", protoInfo->szProto, PS_ICQ_GETCUSTOMSTATUSEX); - if (!ServiceExists(szServiceName)) return; - - // Retrieve xstatus.count - xstatus.cbSize = sizeof(ICQ_CUSTOM_STATUS); - xstatus.flags = CSSF_STATUSES_COUNT; - xstatus.wParam = &(protoInfo->xstatus.count); - CallProtoService(protoInfo->szProto, PS_ICQ_GETCUSTOMSTATUSEX, 0, (LPARAM)&xstatus); - (protoInfo->xstatus.count)++; // Don't forget about xstatus=0 (None) - - // Alloc and initiailize xstatus.enabled array - protoInfo->xstatus.enabled = (BOOL *)malloc(protoInfo->xstatus.count * sizeof(BOOL)); - if (!protoInfo->xstatus.enabled) - protoInfo->xstatus.count = 0; - else - for(i=0; i < protoInfo->xstatus.count; i++) - protoInfo->xstatus.enabled[i] = FALSE; - -} - - -void createProtocolList(void) -{ - unsigned int i; - PROTOCOLDESCRIPTOR **proto; - - if (ServiceExists(MS_MC_GETPROTOCOLNAME)) - szMetaProto = (char *)CallService(MS_MC_GETPROTOCOLNAME, 0, 0); - - CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&ProtoList.protoCount, (LPARAM)&proto); - ProtoList.protoInfo = (PROTOCOL_INFO *)malloc(ProtoList.protoCount * sizeof(PROTOCOL_INFO)); - if (!ProtoList.protoInfo) - ProtoList.protoCount = 0; - else - for(i=0; i < ProtoList.protoCount; i++) { - ProtoList.protoInfo[i].xstatus.count = 0; - ProtoList.protoInfo[i].xstatus.enabled = NULL; - ProtoList.protoInfo[i].szProto = (char *)malloc(strlen(proto[i]->szName) + 1); - if (!ProtoList.protoInfo[i].szProto) { - ProtoList.protoInfo[i].enabled = FALSE; - ProtoList.protoInfo[i].visible = FALSE; - } else { - strcpy(ProtoList.protoInfo[i].szProto, proto[i]->szName); - ProtoList.protoInfo[i].enabled = FALSE; - if (proto[i]->type != PROTOTYPE_PROTOCOL) - ProtoList.protoInfo[i].visible = FALSE; - else - if (szMetaProto && !strcmp(proto[i]->szName, szMetaProto)) - ProtoList.protoInfo[i].visible = FALSE; - else { - ProtoList.protoInfo[i].visible = TRUE; - updateXstatusProto(&(ProtoList.protoInfo[i])); - } - } - } - -} - - -// We use the profile name to create the first part of each event name -// We do so to avoid problems between different instances of the plugin concurrently running -void createEventPrefix(TCHAR *prefixName, size_t maxLen) -{ - size_t len; - TCHAR profileName[MAX_PATH+1], *str; - - getAbsoluteProfileName(profileName, MAX_PATH); - - while (str = wcschr(profileName, _T('\\'))) - *str = _T('/'); - if ((len = wcslen(profileName)) <= maxLen) - wcscpy(prefixName, profileName); - else { - str = profileName + len - maxLen / 2; - _snwprintf(prefixName, maxLen / 2, L"%s", profileName); - wcscat(prefixName, str); - } -} - - -// ** -// ** Everything below is just Miranda init/uninit stuff -// ** - - -static int ModulesLoaded(WPARAM wParam, LPARAM lParam) -{ - TCHAR eventPrefix[MAX_PATH+1], eventName[MAX_PATH+1]; - - LoadProcsLibrary(); - if (bWindowsNT && dWinVer >= 5) - MyGetLastInputInfo = (BOOL (WINAPI *)(PLASTINPUTINFO)) GetProcAddress(GetModuleHandle(L"user32"), "GetLastInputInfo"); - else - MyGetLastInputInfo = NULL; - - createProtocolList(); - LoadSettings(); - - // Create some synchronisation objects - createEventPrefix(eventPrefix, MAX_PATH - 11); - _snwprintf(eventName, sizeof(eventName), _T("%s/FlashEvent"), eventPrefix); - hFlashEvent = CreateEvent(NULL, FALSE, FALSE, eventName); - _snwprintf(eventName, sizeof(eventName), _T("%s/ExitEvent"), eventPrefix); - hExitEvent = CreateEvent(NULL, FALSE, FALSE, eventName); - - hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)FlashThreadFunction, NULL, 0, &IDThread); - - hMsgEventHook = HookEvent(ME_DB_EVENT_ADDED, PluginMessageEventHook); - hOptionsInitialize = HookEvent(ME_OPT_INITIALISE, InitializeOptions); - hEnableService = CreateServiceFunction(MS_KBDNOTIFY_ENABLE, EnableService); - hDisableService = CreateServiceFunction(MS_KBDNOTIFY_DISABLE, DisableService); - hStartBlinkService = CreateServiceFunction(MS_KBDNOTIFY_STARTBLINK, StartBlinkService); - hEventsOpenedService = CreateServiceFunction(MS_KBDNOTIFY_EVENTSOPENED, EventsWereOpenedService); - hFlashingEventService = CreateServiceFunction(MS_KBDNOTIFY_FLASHINGACTIVE, IsFlashingActiveService); - hNormalizeSequenceService = CreateServiceFunction(MS_KBDNOTIFY_NORMALSEQUENCE, NormalizeSequenceService); - - RegisterAction(); - if (ServiceExists("DBEditorpp/RegisterSingleModule")) - CallService("DBEditorpp/RegisterSingleModule", (WPARAM)KEYBDMODULE, 0); - - return 0; -} - - - -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ - - hInst = hinstDLL; - - return TRUE; - -} - -extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) -{ - return &pluginInfo; -} - -extern "C" __declspec(dllexport) int Load(void) -{ - - mir_getLP(&pluginInfo); - - GetWindowsVersion(); - OpenKeyboardDevice(); - hModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoaded); - - return 0; -} - - - -void destroyProtocolList(void) -{ - unsigned int i; - - for(i=0; i < ProtoList.protoCount; i++) { - if (ProtoList.protoInfo[i].szProto) - free(ProtoList.protoInfo[i].szProto); - if (ProtoList.protoInfo[i].xstatus.enabled) - free(ProtoList.protoInfo[i].xstatus.enabled); - } - - ProtoList.protoCount = 0; - if (ProtoList.protoInfo) - free(ProtoList.protoInfo); -} - - -extern "C" __declspec(dllexport) int Unload(void) -{ - - UnhookWindowsHooks(); - DeInitAction(); - if (hModulesLoaded) - UnhookEvent(hModulesLoaded); - if (hMsgEventHook) - UnhookEvent(hMsgEventHook); - if (hOptionsInitialize) - UnhookEvent(hOptionsInitialize); - if (hEnableService) - DestroyServiceFunction(hEnableService); - if (hDisableService) - DestroyServiceFunction(hDisableService); - if (hStartBlinkService) - DestroyServiceFunction(hStartBlinkService); - if (hEventsOpenedService) - DestroyServiceFunction(hEventsOpenedService); - if (hFlashingEventService) - DestroyServiceFunction(hFlashingEventService); - if (hNormalizeSequenceService) - DestroyServiceFunction(hNormalizeSequenceService); - - // Wait for thread to exit - SetEvent(hExitEvent); - WaitForSingleObject(hThread, INFINITE); - - RestoreLEDState(); - CloseKeyboardDevice(); - - UnloadProcsLibrary(); - destroyProcessList(); - destroyProtocolList(); - - return 0; -} - - -// ========================== Windows hooks ========================== -int HookWindowsHooks() -{ - if (wReminderCheck) - hReminderTimer = SetTimer(NULL,0, wReminderCheck * 60000, ReminderTimer); - - if (bFlashUntil & UNTIL_REATTENDED) - switch (bMirandaOrWindows) { - case ACTIVE_WINDOWS: - if (!MyGetLastInputInfo || bEmulateKeypresses) { - if (hMouseHook == NULL) - hMouseHook = SetWindowsHookEx(WH_MOUSE, MouseHookFunction, hInst, 0); - if (hKeyBoardHook == NULL) - hKeyBoardHook = SetWindowsHookEx(WH_KEYBOARD, KeyBoardHookFunction, hInst, 0); - } - break; - case ACTIVE_MIRANDA: - if (hMirandaMouseHook == NULL) - hMirandaMouseHook = SetWindowsHookEx(WH_MOUSE, MirandaMouseHookFunction, NULL, GetCurrentThreadId()); - if (hMirandaKeyBoardHook == NULL) - hMirandaKeyBoardHook = SetWindowsHookEx(WH_KEYBOARD, MirandaKeyBoardHookFunction, NULL, GetCurrentThreadId()); - if (hMirandaWndProcHook == NULL) - hMirandaWndProcHook = SetWindowsHookEx(WH_CALLWNDPROC, MirandaWndProcHookFunction, NULL, GetCurrentThreadId()); - } - - return 0; -} - -int UnhookWindowsHooks() -{ - if (hReminderTimer) - KillTimer(NULL, hReminderTimer); - if (hMouseHook) - UnhookWindowsHookEx(hMouseHook); - if (hKeyBoardHook) - UnhookWindowsHookEx(hKeyBoardHook); - if (hMirandaMouseHook) - UnhookWindowsHookEx(hMirandaMouseHook); - if (hMirandaKeyBoardHook) - UnhookWindowsHookEx(hMirandaKeyBoardHook); - if (hMirandaWndProcHook) - UnhookWindowsHookEx(hMirandaWndProcHook); - - hReminderTimer = 0; - hMouseHook = hKeyBoardHook = hMirandaMouseHook = hMirandaKeyBoardHook = hMirandaWndProcHook = NULL; - - return 0; -} - -static LRESULT CALLBACK MouseHookFunction(int code, WPARAM wParam, LPARAM lParam) -{ - if (code >= 0) { - /* This should handle all mouse buttons ... */ - if ((wParam >= WM_NCLBUTTONDOWN && wParam <= WM_NCXBUTTONDBLCLK && wParam != 0x00AA) || (wParam >= WM_LBUTTONDOWN && wParam <= WM_XBUTTONDBLCLK)) - dwLastInput = GetTickCount(); - /* ... and here it is either mouse move, hover, leave or something unexpected */ - else { - PMOUSEHOOKSTRUCT mouseInfo = (PMOUSEHOOKSTRUCT)lParam; - POINT pt = mouseInfo->pt; - if (pt.x!=lastGlobalMousePos.x || pt.y!=lastGlobalMousePos.y) { - lastGlobalMousePos = pt; - dwLastInput = GetTickCount(); - } - } - } - - return CallNextHookEx(hMouseHook, code, wParam, lParam); -} - -static LRESULT CALLBACK KeyBoardHookFunction(int code, WPARAM wParam, LPARAM lParam) -{ - if (code >= 0 && (!bEmulateKeypresses || (bEmulateKeypresses && wParam != VK_NUMLOCK && wParam != VK_CAPITAL && wParam != VK_SCROLL))) - dwLastInput = GetTickCount(); - - return CallNextHookEx(hKeyBoardHook, code, wParam, lParam); -} - -static LRESULT CALLBACK MirandaMouseHookFunction(int code, WPARAM wParam, LPARAM lParam) -{ - static POINT lastMousePos = {0, 0}; - - if (code >= 0) { - /* Movement mouse messages are for some reason incoming in inactive/background window too, that is not input */ - DWORD pid; - GetWindowThreadProcessId(GetForegroundWindow(), &pid); - if(pid == GetCurrentProcessId()) { - /* This should handle all mouse buttons ... */ - if ((wParam >= WM_NCLBUTTONDOWN && wParam <= WM_NCXBUTTONDBLCLK && wParam != 0x00AA) || (wParam >= WM_LBUTTONDOWN && wParam <= WM_XBUTTONDBLCLK)) - dwLastInput = GetTickCount(); - /* ... and here it is either mouse move, hover, leave or something unexpected */ - else { - PMOUSEHOOKSTRUCT mouseInfo = (PMOUSEHOOKSTRUCT)lParam; - POINT pt = mouseInfo->pt; - if (pt.x!=lastMousePos.x || pt.y!=lastMousePos.y) { - lastMousePos = pt; - dwLastInput = GetTickCount(); - } - } - } - } - - return CallNextHookEx(hMirandaMouseHook, code, wParam, lParam); -} - -static LRESULT CALLBACK MirandaKeyBoardHookFunction(int code, WPARAM wParam, LPARAM lParam) { - - if (code >= 0 && (!bEmulateKeypresses || (bEmulateKeypresses && wParam != VK_NUMLOCK && wParam != VK_CAPITAL && wParam != VK_SCROLL))) - dwLastInput = GetTickCount(); - - return CallNextHookEx(hMirandaKeyBoardHook, code, wParam, lParam); -} - -static LRESULT CALLBACK MirandaWndProcHookFunction(int code, WPARAM wParam, LPARAM lParam) { - - if (code >= 0) { - /* WM_ACTIVATEAPP with nonzero wParam means someone brought miranda to foreground, that equals to input */ - PCWPSTRUCT cwpInfo = (PCWPSTRUCT)lParam; - if(cwpInfo->message == WM_ACTIVATEAPP && cwpInfo->wParam) - dwLastInput = GetTickCount(); - } - - return CallNextHookEx(hMirandaWndProcHook, code, wParam, lParam); -} - - -//===================== Check Window Message function ===================== - -// Took this snippet of code from "EventNotify" by micron-x, thx *g* -// and updated with NGEventNotify and pete's patch -// checks if the message-dialog window is already opened and returns: -// TRUE - Windows found -// FALSE - No window found - -HWND findMessageWindow(HANDLE hContact) -{ - HWND hwnd; - TCHAR newtitle[256]; - char *szProto, *contactName, *szStatus; - CONTACTINFO ci = {0}; - - szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); - contactName = (char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, 0); - szStatus = (char *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, szProto==NULL?ID_STATUS_OFFLINE:DBGetContactSettingWord(hContact, szProto, "Status", ID_STATUS_OFFLINE), 0); - - _snwprintf(newtitle, sizeof(newtitle), _T("%s (%s): %s"), contactName, szStatus, TranslateT("Message Received")); - if(hwnd = FindWindow(NULL, newtitle)) - return hwnd; - - _snwprintf(newtitle, sizeof(newtitle), _T("%s %s"), contactName, szStatus); - if(hwnd = FindWindow(NULL, newtitle)) - return hwnd; - _snwprintf(newtitle, sizeof(newtitle), _T("%s (%s): %s"), contactName, szStatus, TranslateT("Message Session")); - if(hwnd = FindWindow(NULL, newtitle)) - return hwnd; - _snwprintf(newtitle, sizeof(newtitle), _T("%s (%s): %s"), contactName, szStatus, TranslateT("Message Session is typing...")); - if(hwnd = FindWindow(NULL, newtitle)) - return hwnd; - // search for the nconvers++ message window that uses the UIN - ci.cbSize = sizeof(CONTACTINFO); - ci.dwFlag = CNF_UNIQUEID; - ci.hContact = hContact; - if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM)&ci)) { - switch(ci.type) { - case CNFT_BYTE: - _snwprintf(newtitle, sizeof(newtitle), _T("%s (%d) %s"), contactName, ci.bVal, szStatus); - break; - case CNFT_WORD: - _snwprintf(newtitle, sizeof(newtitle), _T("%s (%d) %s"), contactName, ci.wVal, szStatus); - break; - case CNFT_DWORD: - _snwprintf(newtitle, sizeof(newtitle), _T("%s (%d) %s"), contactName, ci.dVal, szStatus); - break; - case CNFT_ASCIIZ: - _snwprintf(newtitle, sizeof(newtitle), _T("%s (%s) %s"), contactName, ci.pszVal, szStatus); - break; - } - if(hwnd = FindWindow(NULL, newtitle)) - return hwnd; - } - - return NULL; -} - -BOOL CheckMsgWnd(HANDLE hContact, BOOL *focus) -{ - if (ServiceExists(MS_MSG_GETWINDOWDATA)) { // use the new message API - MessageWindowData mwd; - MessageWindowInputData mwid; - mwid.cbSize = sizeof(MessageWindowInputData); - mwid.hContact = hContact; - mwid.uFlags = MSG_WINDOW_UFLAG_MSG_BOTH; - mwd.cbSize = sizeof(MessageWindowData); - mwd.hContact = hContact; - if (!CallService(MS_MSG_GETWINDOWDATA, (WPARAM)&mwid, (LPARAM)&mwd) && mwd.hwndWindow) { - *focus = mwd.uState & MSG_WINDOW_STATE_FOCUS; - return TRUE; - } - } else { // old way: find it by using the window class & title - HWND hwnd; - - if(hwnd = findMessageWindow(hContact)) { - *focus = hwnd==GetForegroundWindow(); - return TRUE; - } - } - - *focus = FALSE; - return FALSE; -} - - -void countUnopenEvents(int *msgCount, int *fileCount, int *urlCount, int *otherCount) -{ - int nIndex; - CLISTEVENT *pCLEvent; - - for (nIndex = 0; pCLEvent = (CLISTEVENT*)CallService(MS_CLIST_GETEVENT, -1, nIndex); nIndex++) { - DBEVENTINFO einfo = readEventInfo(pCLEvent->hDbEvent, pCLEvent->hContact); - - if (metaCheckProtocol(einfo.szModule, pCLEvent->hContact, einfo.eventType)) - switch (einfo.eventType) { - case EVENTTYPE_MESSAGE: - if (bFlashOnMsg) - (*msgCount)++; - break; - case EVENTTYPE_URL: - if (bFlashOnURL) - (*urlCount)++; - break; - case EVENTTYPE_FILE: - if (bFlashOnFile) - (*fileCount)++; - break; - default: - if (bFlashOnOther) - (*otherCount)++; - } - } - if (bFlashOnOther) - (*otherCount) += nExternCount; -} diff --git a/plugins/KeyboardNotify/options.cpp b/plugins/KeyboardNotify/options.cpp deleted file mode 100644 index d74902aec8..0000000000 --- a/plugins/KeyboardNotify/options.cpp +++ /dev/null @@ -1,1565 +0,0 @@ -/* - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#define WIN32_LEAN_AND_MEAN - -#include -#include -#include -#include -#include -#include "flash.h" -#include "ignore.h" -#include "resource.h" -#include "constants.h" -#include "protolist.h" -#include "EnumProc.h" -#include "utils.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define IDI_BLANK 200 - -#ifndef ETDT_ENABLE -#define ETDT_ENABLE 0x00000002 -#endif -#ifndef ETDT_USETABTEXTURE -#define ETDT_USETABTEXTURE 0x00000004 -#endif -#ifndef ETDT_ENABLETAB -#define ETDT_ENABLETAB (ETDT_ENABLE|ETDT_USETABTEXTURE) -#endif - -#ifndef ListView_SetCheckState -#define ListView_SetCheckState(hLv, iItem, bCheck) \ - ListView_SetItemState(hLv, iItem, bCheck ? INDEXTOSTATEIMAGEMASK(2) : INDEXTOSTATEIMAGEMASK(1), LVIS_STATEIMAGEMASK) -#endif - -#ifndef TVS_NOHSCROLL -#define TVS_NOHSCROLL 0x8000 -#endif - -#ifndef TVM_GETITEMSTATE -#define TVM_GETITEMSTATE (TV_FIRST+39) -#endif - -#ifndef TreeView_SetItemState -#define TreeView_SetItemState(hwndTv, hti, data, _mask) \ - { TVITEM _TVI; \ - _TVI.mask = TVIF_STATE; \ - _TVI.hItem = hti; \ - _TVI.stateMask = _mask; \ - _TVI.state = data; \ - SendMessageA((hwndTv), TVM_SETITEM, 0, (LPARAM)&_TVI); } -#endif - -#ifndef TreeView_GetItemState -#define TreeView_GetItemState(hwndTv, hti, mask) \ - (UINT)SendMessageA((hwndTv), TVM_GETITEMSTATE, (WPARAM)(hti), (LPARAM)(mask)) -#endif - -void LoadSettings(void); -int InitializeOptions(WPARAM,LPARAM); -INT_PTR CALLBACK DlgProcOptions(HWND, UINT, WPARAM, LPARAM); -INT_PTR CALLBACK DlgProcProtoOptions(HWND, UINT, WPARAM, LPARAM); -INT_PTR CALLBACK DlgProcBasicOptions(HWND, UINT, WPARAM, LPARAM); -INT_PTR CALLBACK DlgProcEffectOptions(HWND, UINT, WPARAM, LPARAM); -INT_PTR CALLBACK DlgProcThemeOptions(HWND, UINT, WPARAM, LPARAM); -INT_PTR CALLBACK DlgProcProcesses(HWND, UINT, WPARAM, LPARAM); -INT_PTR CALLBACK DlgProcEventLeds(HWND, UINT, WPARAM, LPARAM); -INT_PTR CALLBACK DlgProcXstatusList(HWND, UINT, WPARAM, LPARAM); -void exportThemes(const TCHAR *); -void importThemes(const TCHAR *, BOOL); -void writeThemeToCombo(const TCHAR *, const TCHAR *, BOOL); -void createProcessListAux(void); -void destroyProcessListAux(void); -void createXstatusListAux(void); -void destroyXstatusListAux(void); - - -extern HINSTANCE hInst; -extern double dWinVer; -extern BOOL bWindowsNT; - -extern BYTE bFlashOnMsg; -extern BYTE bFlashOnURL; -extern BYTE bFlashOnFile; -extern BYTE bFlashOnOther; -extern BYTE bFullScreenMode; -extern BYTE bScreenSaverRunning; -extern BYTE bWorkstationLocked; -extern BYTE bProcessesAreRunning; -extern BYTE bWorkstationActive; -extern BYTE bFlashIfMsgOpen; -extern BYTE bFlashIfMsgOlder; -extern WORD wSecondsOlder; -extern BYTE bFlashUntil; -extern WORD wBlinksNumber; -extern BYTE bMirandaOrWindows; -extern WORD wStatusMap; -extern WORD wReminderCheck; -extern BYTE bFlashLed[3]; -extern BYTE bFlashEffect; -extern BYTE bSequenceOrder; -extern WORD wCustomTheme; -extern WORD wStartDelay; -extern BYTE bFlashSpeed; -extern BYTE bEmulateKeypresses; -extern BYTE bOverride; -extern BYTE bFlashIfMsgWinNotTop; -extern BYTE bTrillianLedsMsg; -extern BYTE bTrillianLedsURL; -extern BYTE bTrillianLedsFile; -extern BYTE bTrillianLedsOther; - -extern PROTOCOL_LIST ProtoList; -extern PROCESS_LIST ProcessList; - -HWND hwndProto, hwndBasic, hwndEffect, hwndTheme, hwndIgnore, hwndCurrentTab; - -TCHAR *AttendedName[]={_T("Miranda"), _T("Windows")}; -TCHAR *OrderName[]={_T("left->right"), _T("right->left"), _T("left<->right")}; - -PROCESS_LIST ProcessListAux; -XSTATUS_INFO *XstatusListAux; -BYTE trillianLedsMsg, trillianLedsURL, trillianLedsFile, trillianLedsOther; - -static BOOL (WINAPI *pfnEnableThemeDialogTexture)(HANDLE, DWORD) = 0; - - -// ** -// ** Initialize the Miranda options page -// ** -int InitializeOptions(WPARAM wParam,LPARAM lParam) -{ - if (bWindowsNT && dWinVer >= 5.01) { - HMODULE hUxTheme = GetModuleHandle(L"uxtheme.dll"); - if(hUxTheme) - pfnEnableThemeDialogTexture = (BOOL (WINAPI *)(HANDLE, DWORD))GetProcAddress(hUxTheme, "EnableThemeDialogTexture"); - } - - OPTIONSDIALOGPAGE odp = { 0 }; - odp.cbSize = sizeof(odp); - odp.position = 0; - odp.hInstance = hInst; - odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS); - odp.pszTitle = LPGEN("Keyboard Flash"); - odp.pszGroup = LPGEN("Plugins"); - odp.groupPosition = 910000000; - odp.flags = ODPF_BOLDGROUPS; - odp.pfnDlgProc = DlgProcOptions; - odp.nIDBottomSimpleControl = 0; - Options_AddPage(wParam, &odp); - - return 0; -} - -INT_PTR CALLBACK DlgProcOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - case WM_INITDIALOG: - { - HWND tc; - TCITEM tci; - tc = GetDlgItem(hwndDlg, IDC_TABS); - tci.mask = TCIF_TEXT; - tci.pszText = TranslateT("Protocols"); - TabCtrl_InsertItem(tc, 0, &tci); - tci.pszText = TranslateT("Rules"); - TabCtrl_InsertItem(tc, 1, &tci); - tci.pszText = TranslateT("Flashing"); - TabCtrl_InsertItem(tc, 2, &tci); - tci.pszText = TranslateT("Themes"); - TabCtrl_InsertItem(tc, 3, &tci); - tci.pszText = TranslateT("Ignore"); - TabCtrl_InsertItem(tc, 4, &tci); - - hwndProto = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_PROTO_OPTIONS), hwndDlg, DlgProcProtoOptions, (LPARAM) NULL); - if(hwndProto && pfnEnableThemeDialogTexture) - pfnEnableThemeDialogTexture(hwndProto, ETDT_ENABLETAB); - SetWindowPos(hwndProto, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - ShowWindow(hwndProto, SW_SHOW); - hwndBasic = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_BASIC_OPTIONS), hwndDlg, DlgProcBasicOptions, (LPARAM) NULL); - if(hwndBasic && pfnEnableThemeDialogTexture) - pfnEnableThemeDialogTexture(hwndBasic, ETDT_ENABLETAB); - SetWindowPos(hwndBasic, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - hwndEffect = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_EFFECT_OPTIONS), hwndDlg, DlgProcEffectOptions, (LPARAM) NULL); - if(hwndEffect && pfnEnableThemeDialogTexture) - pfnEnableThemeDialogTexture(hwndEffect, ETDT_ENABLETAB); - SetWindowPos(hwndEffect, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - hwndTheme = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_THEME_OPTIONS), hwndDlg, DlgProcThemeOptions, (LPARAM) NULL); - if(hwndTheme && pfnEnableThemeDialogTexture) - pfnEnableThemeDialogTexture(hwndTheme, ETDT_ENABLETAB); - SetWindowPos(hwndTheme, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - hwndIgnore = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_IGNORE_OPTIONS), hwndDlg, DlgProcIgnoreOptions, (LPARAM) NULL); - if(hwndIgnore && pfnEnableThemeDialogTexture) - pfnEnableThemeDialogTexture(hwndIgnore, ETDT_ENABLETAB); - SetWindowPos(hwndIgnore, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - hwndCurrentTab = hwndProto; - return TRUE; - - } - case WM_COMMAND: - break; - case WM_NOTIFY: - { - switch (((LPNMHDR) lParam)->code) { - case TCN_SELCHANGE: - switch (wParam) { - case IDC_TABS: - { - HWND hwnd; - switch (TabCtrl_GetCurSel(GetDlgItem(hwndDlg, IDC_TABS))) { - default: - case 0: - hwnd = hwndProto; - break; - case 1: - hwnd = hwndBasic; - break; - case 2: - hwnd = hwndEffect; - break; - case 3: - hwnd = hwndTheme; - break; - case 4: - hwnd = hwndIgnore; - break; - } - if (hwnd!=hwndCurrentTab) { - ShowWindow(hwnd, SW_SHOW); - ShowWindow(hwndCurrentTab, SW_HIDE); - hwndCurrentTab = hwnd; - } - } - break; - } - break; - case PSN_APPLY: - SendMessage(hwndProto, WM_NOTIFY, wParam, lParam); - SendMessage(hwndBasic, WM_NOTIFY, wParam, lParam); - SendMessage(hwndEffect, WM_NOTIFY, wParam, lParam); - SendMessage(hwndTheme, WM_NOTIFY, wParam, lParam); - SendMessage(hwndIgnore, WM_NOTIFY, wParam, lParam); - return TRUE; - } - } - break; - case WM_DESTROY: - break; - } - return FALSE; -} - - -INT_PTR CALLBACK DlgProcProtoOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - static BOOL initDlg=FALSE; - - switch (msg) { - - case WM_INITDIALOG: - initDlg=TRUE; - TranslateDialogDefault(hwndDlg); - - // proto list - { - unsigned int i; - LVCOLUMN lvCol; - LVITEM lvItem; - HWND hList = GetDlgItem(hwndDlg, IDC_PROTOCOLLIST); - - // create columns - ListView_SetExtendedListViewStyleEx(hList, LVS_EX_CHECKBOXES, LVS_EX_CHECKBOXES); - memset(&lvCol, 0, sizeof(lvCol)); - lvCol.mask = LVCF_WIDTH|LVCF_TEXT; - lvCol.pszText = TranslateT("Protocol"); - lvCol.cx = 118; - ListView_InsertColumn(hList, 0, &lvCol); - // fill - memset(&lvItem, 0, sizeof(lvItem)); - lvItem.mask = LVIF_TEXT|LVIF_PARAM; - lvItem.cchTextMax = 256; - lvItem.iItem = 0; - lvItem.iSubItem = 0; - for(i=0; i < ProtoList.protoCount; i++) { - int count; PROTOACCOUNT** protos; - ProtoEnumAccounts( &count, &protos ); - if(ProtoList.protoInfo[i].visible) { - lvItem.lParam = (LPARAM)ProtoList.protoInfo[i].szProto; - lvItem.pszText = protos[i] -> tszAccountName; - ListView_InsertItem(hList, &lvItem); - ListView_SetCheckState(hList, lvItem.iItem, ProtoList.protoInfo[i].enabled); - lvItem.iItem++; - } - } - } - - initDlg=FALSE; - return TRUE; - - case WM_NOTIFY: - { - //Here we have pressed either the OK or the APPLY button. - switch(((LPNMHDR)lParam)->idFrom) { - case 0: - switch (((LPNMHDR)lParam)->code) { - case PSN_APPLY: - // enabled protos - { - int i; - LVITEM lvItem; - HWND hList = GetDlgItem(hwndDlg, IDC_PROTOCOLLIST); - - memset(&lvItem, 0, sizeof(lvItem)); - lvItem.mask = LVIF_PARAM; - lvItem.iSubItem = 0; - for (i=0; i < ListView_GetItemCount(hList); i++) { - lvItem.iItem = i; - ListView_GetItem(hList, &lvItem); - DBWriteContactSettingByte(NULL, KEYBDMODULE, (char *)lvItem.lParam, (BYTE)!!ListView_GetCheckState(hList, lvItem.iItem)); - } - } - - LoadSettings(); - - return TRUE; - } // switch code - 0 - break; - case IDC_PROTOCOLLIST: - switch(((NMHDR*)lParam)->code) { - case LVN_ITEMCHANGED: - { - NMLISTVIEW *nmlv = (NMLISTVIEW *)lParam; - - if (!initDlg && ((nmlv->uNewState ^ nmlv->uOldState) & LVIS_STATEIMAGEMASK)) - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - } - break; - } // switch code - IDC_PROTOCOLLIST - break; - } //switch idFrom - } - break; //End WM_NOTIFY - - default: - break; - } - - return FALSE; -} - -INT_PTR CALLBACK DlgProcBasicOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - unsigned int i; - static BOOL initDlg=FALSE; - - switch (msg) { - - case WM_INITDIALOG: - initDlg=TRUE; - TranslateDialogDefault(hwndDlg); - - createProcessListAux(); - createXstatusListAux(); - - CheckDlgButton(hwndDlg, IDC_ONMESSAGE, bFlashOnMsg ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_ONURL, bFlashOnURL ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_ONFILE, bFlashOnFile ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_ONOTHER, bFlashOnOther ? BST_CHECKED:BST_UNCHECKED); - - CheckDlgButton(hwndDlg, IDC_FSCREEN, bFullScreenMode ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_SSAVER, bScreenSaverRunning ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_LOCKED, bWorkstationLocked ? BST_CHECKED:BST_UNCHECKED); - if (!bWindowsNT) - EnableWindow(GetDlgItem(hwndDlg, IDC_LOCKED), FALSE); - CheckDlgButton(hwndDlg, IDC_PGMS, bProcessesAreRunning ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_ACTIVE, bWorkstationActive ? BST_CHECKED:BST_UNCHECKED); - - CheckDlgButton(hwndDlg, IDC_IFOPEN, bFlashIfMsgOpen ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_IFNOTTOP, bFlashIfMsgWinNotTop ? BST_CHECKED:BST_UNCHECKED); - if (!bFlashIfMsgOpen) - EnableWindow(GetDlgItem(hwndDlg, IDC_IFNOTTOP), FALSE); - CheckDlgButton(hwndDlg, IDC_IFOLDER, bFlashIfMsgOlder ? BST_CHECKED:BST_UNCHECKED); - SendDlgItemMessage(hwndDlg, IDC_OLDERSPIN, UDM_SETBUDDY, (WPARAM)GetDlgItem(hwndDlg, IDC_SOLDER), 0); - SendDlgItemMessage(hwndDlg, IDC_OLDERSPIN, UDM_SETRANGE32, 1, MAKELONG(UD_MAXVAL, 0)); - SendDlgItemMessage(hwndDlg, IDC_OLDERSPIN, UDM_SETPOS, 0, MAKELONG(wSecondsOlder, 0)); - if (!bFlashIfMsgOlder) { - EnableWindow(GetDlgItem(hwndDlg, IDC_SOLDER), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_OLDERSPIN), FALSE); - } - - CheckDlgButton(hwndDlg, IDC_UNTILBLK, bFlashUntil&UNTIL_NBLINKS ? BST_CHECKED:BST_UNCHECKED); - SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_SETBUDDY, (WPARAM)GetDlgItem(hwndDlg, IDC_SBLINK), 0); - SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_SETRANGE32, 1, MAKELONG(UD_MAXVAL, 0)); - SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_SETPOS, 0, MAKELONG(wBlinksNumber, 0)); - if (!(bFlashUntil & UNTIL_NBLINKS)) { - EnableWindow(GetDlgItem(hwndDlg, IDC_SBLINK), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_BLINKSPIN), FALSE); - } - CheckDlgButton(hwndDlg, IDC_UNTILATTENDED, bFlashUntil&UNTIL_REATTENDED ? BST_CHECKED:BST_UNCHECKED); - for (i=0; i < 2; i++) { - int index = SendDlgItemMessage(hwndDlg, IDC_MIRORWIN, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)AttendedName[i]); - if (index != CB_ERR && index != CB_ERRSPACE) - SendDlgItemMessage(hwndDlg, IDC_MIRORWIN, CB_SETITEMDATA, (WPARAM)index, (LPARAM)i); - } - SendDlgItemMessage(hwndDlg, IDC_MIRORWIN, CB_SETCURSEL, (WPARAM)bMirandaOrWindows, 0); - if (!(bFlashUntil & UNTIL_REATTENDED)) - EnableWindow(GetDlgItem(hwndDlg, IDC_MIRORWIN), FALSE); - CheckDlgButton(hwndDlg, IDC_UNTILOPEN, bFlashUntil&UNTIL_EVENTSOPEN ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_UNTILCOND, bFlashUntil&UNTIL_CONDITIONS ? BST_CHECKED:BST_UNCHECKED); - - CheckDlgButton(hwndDlg, IDC_ONLINE, wStatusMap&MAP_ONLINE ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_AWAY, wStatusMap&MAP_AWAY ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_NA, wStatusMap&MAP_NA ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_OCCUPIED, wStatusMap&MAP_OCCUPIED ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_DND, wStatusMap&MAP_DND ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_FREECHAT, wStatusMap&MAP_FREECHAT ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_INVISIBLE, wStatusMap&MAP_INVISIBLE ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_ONTHEPHONE, wStatusMap&MAP_ONTHEPHONE ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_OUTTOLUNCH, wStatusMap&MAP_OUTTOLUNCH ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_OFFLINE, wStatusMap&MAP_OFFLINE ? BST_CHECKED:BST_UNCHECKED); - - SendDlgItemMessage(hwndDlg, IDC_REMCHECK, UDM_SETBUDDY, (WPARAM)GetDlgItem(hwndDlg, IDC_SREMCHECK), 0); - SendDlgItemMessage(hwndDlg, IDC_REMCHECK, UDM_SETRANGE32, 0, MAKELONG(UD_MAXVAL, 0)); - SendDlgItemMessage(hwndDlg, IDC_REMCHECK, UDM_SETPOS, 0, MAKELONG(wReminderCheck, 0)); - - initDlg=FALSE; - return TRUE; - - case WM_VSCROLL: - case WM_HSCROLL: - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - break; - - case WM_DESTROY: - destroyProcessListAux(); - destroyXstatusListAux(); - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_ONMESSAGE: - case IDC_ONURL: - case IDC_ONFILE: - case IDC_ONOTHER: - case IDC_IFOPEN: - case IDC_IFNOTTOP: - case IDC_IFOLDER: - case IDC_UNTILBLK: - case IDC_UNTILATTENDED: - case IDC_MIRORWIN: - case IDC_UNTILOPEN: - case IDC_UNTILCOND: - case IDC_FSCREEN: - case IDC_SSAVER: - case IDC_LOCKED: - case IDC_PGMS: - case IDC_ACTIVE: - case IDC_ONLINE: - case IDC_AWAY: - case IDC_NA: - case IDC_OCCUPIED: - case IDC_DND: - case IDC_FREECHAT: - case IDC_INVISIBLE: - case IDC_ONTHEPHONE: - case IDC_OUTTOLUNCH: - case IDC_OFFLINE: - EnableWindow(GetDlgItem(hwndDlg, IDC_IFNOTTOP), IsDlgButtonChecked(hwndDlg, IDC_IFOPEN) == BST_CHECKED); - EnableWindow(GetDlgItem(hwndDlg, IDC_SOLDER), IsDlgButtonChecked(hwndDlg, IDC_IFOLDER) == BST_CHECKED); - EnableWindow(GetDlgItem(hwndDlg, IDC_OLDERSPIN), IsDlgButtonChecked(hwndDlg, IDC_IFOLDER) == BST_CHECKED); - EnableWindow(GetDlgItem(hwndDlg, IDC_SBLINK), IsDlgButtonChecked(hwndDlg, IDC_UNTILBLK) == BST_CHECKED); - EnableWindow(GetDlgItem(hwndDlg, IDC_BLINKSPIN), IsDlgButtonChecked(hwndDlg, IDC_UNTILBLK) == BST_CHECKED); - EnableWindow(GetDlgItem(hwndDlg, IDC_MIRORWIN), IsDlgButtonChecked(hwndDlg, IDC_UNTILATTENDED) == BST_CHECKED); - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - return TRUE; - case IDC_SOLDER: - if(HIWORD(wParam) == EN_CHANGE && !initDlg) { - BOOL translated; - int val = GetDlgItemInt(hwndDlg, IDC_SOLDER, &translated, FALSE); - if (translated && val < 1) - SendDlgItemMessage(hwndDlg, IDC_OLDERSPIN, UDM_SETPOS, 0, MAKELONG(val, 0)); - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - } - return TRUE; - case IDC_SBLINK: - if(HIWORD(wParam) == EN_CHANGE && !initDlg) { - BOOL translated; - int val = GetDlgItemInt(hwndDlg, IDC_SBLINK, &translated, FALSE); - if (translated && val < 1) - SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_SETPOS, 0, MAKELONG(val, 0)); - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - } - return TRUE; - case IDC_ASSIGNPGMS: - if (DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_PROCESSES), hwndDlg, DlgProcProcesses, 0) == IDC_OKPGM) - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - return TRUE; - case IDC_SELECTXSTATUS: - if (DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_XSTATUSES), hwndDlg, DlgProcXstatusList, 0) == IDC_OKXST) - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - return TRUE; - case IDC_SREMCHECK: - if(HIWORD(wParam) == EN_CHANGE && !initDlg) - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - return TRUE; - } - break; - - case WM_NOTIFY: - { - unsigned int j; - BYTE untilMap = 0; - WORD statusMap = 0; - //Here we have pressed either the OK or the APPLY button. - switch(((LPNMHDR)lParam)->idFrom) { - case 0: - switch (((LPNMHDR)lParam)->code) { - case PSN_APPLY: - DBWriteContactSettingByte(NULL, KEYBDMODULE, "onmsg", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_ONMESSAGE) == BST_CHECKED ? 1:0)); - DBWriteContactSettingByte(NULL, KEYBDMODULE, "onurl", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_ONURL) == BST_CHECKED ? 1:0)); - DBWriteContactSettingByte(NULL, KEYBDMODULE, "onfile", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_ONFILE) == BST_CHECKED ? 1:0)); - DBWriteContactSettingByte(NULL, KEYBDMODULE, "onother", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_ONOTHER) == BST_CHECKED ? 1:0)); - - DBWriteContactSettingByte(NULL, KEYBDMODULE, "fscreenmode", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_FSCREEN) == BST_CHECKED ? 1:0)); - DBWriteContactSettingByte(NULL, KEYBDMODULE, "ssaverrunning", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_SSAVER) == BST_CHECKED ? 1:0)); - DBWriteContactSettingByte(NULL, KEYBDMODULE, "wstationlocked", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_LOCKED) == BST_CHECKED ? 1:0)); - DBWriteContactSettingByte(NULL, KEYBDMODULE, "procsrunning", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_PGMS) == BST_CHECKED ? 1:0)); - DBWriteContactSettingByte(NULL, KEYBDMODULE, "wstationactive", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_ACTIVE) == BST_CHECKED ? 1:0)); - - DBWriteContactSettingByte(NULL, KEYBDMODULE, "ifmsgopen", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_IFOPEN) == BST_CHECKED ? 1:0)); - DBWriteContactSettingByte(NULL, KEYBDMODULE, "ifmsgnottop", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_IFNOTTOP) == BST_CHECKED ? 1:0)); - DBWriteContactSettingByte(NULL, KEYBDMODULE, "ifmsgolder", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_IFOLDER) == BST_CHECKED ? 1:0)); - DBWriteContactSettingWord(NULL, KEYBDMODULE, "secsolder", (WORD)SendDlgItemMessage(hwndDlg, IDC_OLDERSPIN, UDM_GETPOS, 0, 0)); - - if(IsDlgButtonChecked(hwndDlg, IDC_UNTILBLK) == BST_CHECKED) - untilMap |= UNTIL_NBLINKS; - if (IsDlgButtonChecked(hwndDlg, IDC_UNTILATTENDED) == BST_CHECKED) - untilMap |= UNTIL_REATTENDED; - if (IsDlgButtonChecked(hwndDlg, IDC_UNTILOPEN) == BST_CHECKED) - untilMap |= UNTIL_EVENTSOPEN; - if (IsDlgButtonChecked(hwndDlg, IDC_UNTILCOND) == BST_CHECKED) - untilMap |= UNTIL_CONDITIONS; - DBWriteContactSettingByte(NULL, KEYBDMODULE, "funtil", untilMap); - DBWriteContactSettingWord(NULL, KEYBDMODULE, "nblinks", (WORD)SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_GETPOS, 0, 0)); - DBWriteContactSettingByte(NULL, KEYBDMODULE, "mirorwin", (BYTE)SendDlgItemMessage(hwndDlg, IDC_MIRORWIN, CB_GETITEMDATA, (WPARAM)SendDlgItemMessage(hwndDlg, IDC_MIRORWIN, CB_GETCURSEL, 0, 0), 0)); - - if(IsDlgButtonChecked(hwndDlg, IDC_ONLINE) == BST_CHECKED) - statusMap |= MAP_ONLINE; - if(IsDlgButtonChecked(hwndDlg, IDC_AWAY) == BST_CHECKED) - statusMap |= MAP_AWAY; - if(IsDlgButtonChecked(hwndDlg, IDC_NA) == BST_CHECKED) - statusMap |= MAP_NA; - if(IsDlgButtonChecked(hwndDlg, IDC_OCCUPIED) == BST_CHECKED) - statusMap |= MAP_OCCUPIED; - if(IsDlgButtonChecked(hwndDlg, IDC_DND) == BST_CHECKED) - statusMap |= MAP_DND; - if(IsDlgButtonChecked(hwndDlg, IDC_FREECHAT) == BST_CHECKED) - statusMap |= MAP_FREECHAT; - if(IsDlgButtonChecked(hwndDlg, IDC_INVISIBLE) == BST_CHECKED) - statusMap |= MAP_INVISIBLE; - if(IsDlgButtonChecked(hwndDlg, IDC_ONTHEPHONE) == BST_CHECKED) - statusMap |= MAP_ONTHEPHONE; - if(IsDlgButtonChecked(hwndDlg, IDC_OUTTOLUNCH) == BST_CHECKED) - statusMap |= MAP_OUTTOLUNCH; - if(IsDlgButtonChecked(hwndDlg, IDC_OFFLINE) == BST_CHECKED) - statusMap |= MAP_OFFLINE; - DBWriteContactSettingWord(NULL, KEYBDMODULE, "status", statusMap); - - DBWriteContactSettingWord(NULL, KEYBDMODULE, "remcheck", (WORD)SendDlgItemMessage(hwndDlg, IDC_REMCHECK, UDM_GETPOS, 0, 0)); - - for (i=0, j=0; j < ProcessListAux.count; j++) - if (ProcessListAux.szFileName[j]) - DBWriteContactSettingWString(NULL, KEYBDMODULE, fmtDBSettingName("process%d", i++), ProcessListAux.szFileName[j]); - DBWriteContactSettingWord(NULL, KEYBDMODULE, "processcount", (WORD)i); - while (!DBDeleteContactSetting(NULL, KEYBDMODULE, fmtDBSettingName("process%d", i++))); - - if (XstatusListAux) - for (i=0; i < ProtoList.protoCount; i++) - for(j=0; j < XstatusListAux[i].count; j++) - DBWriteContactSettingByte(NULL, KEYBDMODULE, fmtDBSettingName("%sxstatus%d", ProtoList.protoInfo[i].szProto, j), (BYTE)XstatusListAux[i].enabled[j]); - - LoadSettings(); - - return TRUE; - } // switch code - break; - } //switch idFrom - } - break; //End WM_NOTIFY - - default: - break; - } - - return FALSE; -} - -INT_PTR CALLBACK DlgProcEffectOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - int i; - DBVARIANT dbv; - static BOOL initDlg=FALSE; - - switch (msg) { - - case WM_INITDIALOG: - initDlg=TRUE; - TranslateDialogDefault(hwndDlg); - - trillianLedsMsg = bTrillianLedsMsg; - trillianLedsURL = bTrillianLedsURL; - trillianLedsFile = bTrillianLedsFile; - trillianLedsOther = bTrillianLedsOther; - - CheckDlgButton(hwndDlg, IDC_NUM, bFlashLed[0] ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_CAPS, bFlashLed[1] ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_SCROLL, bFlashLed[2] ? BST_CHECKED:BST_UNCHECKED); - - CheckDlgButton(hwndDlg, IDC_SAMETIME, bFlashEffect == FLASH_SAMETIME ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_INTURN, bFlashEffect == FLASH_INTURN ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_INSEQUENCE, bFlashEffect == FLASH_INSEQUENCE ? BST_CHECKED:BST_UNCHECKED); - for (i=0; i < 3; i++) { - int index = SendDlgItemMessage(hwndDlg, IDC_SEQORDER, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)(OrderName[i])); - if (index != CB_ERR && index != CB_ERRSPACE) - SendDlgItemMessage(hwndDlg, IDC_SEQORDER, CB_SETITEMDATA, (WPARAM)index, (LPARAM)i); - } - SendDlgItemMessage(hwndDlg, IDC_SEQORDER, CB_SETCURSEL, (WPARAM)bSequenceOrder, 0); - if (bFlashEffect != FLASH_INSEQUENCE) - EnableWindow(GetDlgItem(hwndDlg, IDC_SEQORDER), FALSE); - CheckDlgButton(hwndDlg, IDC_CUSTOM, bFlashEffect == FLASH_CUSTOM ? BST_CHECKED:BST_UNCHECKED); - for (i=0; !DBGetContactSetting(NULL, KEYBDMODULE, fmtDBSettingName("theme%d", i), &dbv); i++) { - int index = SendDlgItemMessage(hwndDlg, IDC_SCUSTOM, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)dbv.ptszVal); - DBFreeVariant(&dbv); - if (index != CB_ERR && index != CB_ERRSPACE) - SendDlgItemMessage(hwndDlg, IDC_SCUSTOM, CB_SETITEMDATA, (WPARAM)index, (LPARAM)i); - } - SendDlgItemMessage(hwndDlg, IDC_SCUSTOM, CB_SETCURSEL, (WPARAM)wCustomTheme, 0); - if (bFlashEffect != FLASH_CUSTOM) - EnableWindow(GetDlgItem(hwndDlg, IDC_SCUSTOM), FALSE); - CheckDlgButton(hwndDlg, IDC_TRILLIAN, bFlashEffect == FLASH_TRILLIAN ? BST_CHECKED:BST_UNCHECKED); - if (bFlashEffect != FLASH_TRILLIAN) - EnableWindow(GetDlgItem(hwndDlg, IDC_ASSIGNLEDS), FALSE); - - SendDlgItemMessage(hwndDlg, IDC_DELAYSPIN, UDM_SETBUDDY, (WPARAM)GetDlgItem(hwndDlg, IDC_SDELAY), 0); - SendDlgItemMessage(hwndDlg, IDC_DELAYSPIN, UDM_SETRANGE32, 0, MAKELONG(UD_MAXVAL, 0)); - SendDlgItemMessage(hwndDlg, IDC_DELAYSPIN, UDM_SETPOS, 0, MAKELONG(wStartDelay, 0)); - - SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_SETRANGE, FALSE, MAKELONG(0, 5)); - SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_SETPOS, TRUE, bFlashSpeed); - - CheckDlgButton(hwndDlg, IDC_KEYPRESSES, bEmulateKeypresses ? BST_CHECKED:BST_UNCHECKED); - - initDlg=FALSE; - return TRUE; - - case WM_VSCROLL: - case WM_HSCROLL: - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - break; - - case WM_DESTROY: - previewFlashing(FALSE); - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_NUM: - case IDC_CAPS: - case IDC_SCROLL: - case IDC_SAMETIME: - case IDC_INTURN: - case IDC_INSEQUENCE: - case IDC_SEQORDER: - case IDC_CUSTOM: - case IDC_TRILLIAN: - case IDC_SCUSTOM: - case IDC_SPEED: - case IDC_KEYPRESSES: - EnableWindow(GetDlgItem(hwndDlg, IDC_SEQORDER), IsDlgButtonChecked(hwndDlg, IDC_INSEQUENCE) == BST_CHECKED); - EnableWindow(GetDlgItem(hwndDlg, IDC_SCUSTOM), IsDlgButtonChecked(hwndDlg, IDC_CUSTOM) == BST_CHECKED); - EnableWindow(GetDlgItem(hwndDlg, IDC_ASSIGNLEDS), IsDlgButtonChecked(hwndDlg, IDC_TRILLIAN) == BST_CHECKED); - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - return TRUE; - case IDC_ASSIGNLEDS: - if (DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_EVENTLEDS), hwndDlg, DlgProcEventLeds, 0) == IDC_OK) - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - return TRUE; - case IDC_SDELAY: - if(HIWORD(wParam) == EN_CHANGE && !initDlg) - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - return TRUE; - case IDC_PREVIEW: - previewFlashing(IsDlgButtonChecked(hwndDlg, IDC_PREVIEW) == BST_CHECKED); - return TRUE; - } - break; - - case WM_NOTIFY: - { - //Here we have pressed either the OK or the APPLY button. - switch(((LPNMHDR)lParam)->idFrom) { - case 0: - switch (((LPNMHDR)lParam)->code) { - case PSN_APPLY: - DBWriteContactSettingByte(NULL, KEYBDMODULE, "fnum", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_NUM) == BST_CHECKED ? 1:0)); - DBWriteContactSettingByte(NULL, KEYBDMODULE, "fcaps", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CAPS) == BST_CHECKED ? 1:0)); - DBWriteContactSettingByte(NULL, KEYBDMODULE, "fscroll", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_SCROLL) == BST_CHECKED ? 1:0)); - - if(IsDlgButtonChecked(hwndDlg, IDC_INTURN) == BST_CHECKED) - DBWriteContactSettingByte(NULL, KEYBDMODULE, "feffect", FLASH_INTURN); - else - if (IsDlgButtonChecked(hwndDlg, IDC_INSEQUENCE) == BST_CHECKED) - DBWriteContactSettingByte(NULL, KEYBDMODULE, "feffect", FLASH_INSEQUENCE); - else - if (IsDlgButtonChecked(hwndDlg, IDC_CUSTOM) == BST_CHECKED) - DBWriteContactSettingByte(NULL, KEYBDMODULE, "feffect", FLASH_CUSTOM); - else - if (IsDlgButtonChecked(hwndDlg, IDC_TRILLIAN) == BST_CHECKED) - DBWriteContactSettingByte(NULL, KEYBDMODULE, "feffect", FLASH_TRILLIAN); - else - DBWriteContactSettingByte(NULL, KEYBDMODULE, "feffect", FLASH_SAMETIME); - DBWriteContactSettingByte(NULL, KEYBDMODULE, "order", (BYTE)SendDlgItemMessage(hwndDlg, IDC_SEQORDER, CB_GETITEMDATA, (WPARAM)SendDlgItemMessage(hwndDlg, IDC_SEQORDER, CB_GETCURSEL, 0, 0), 0)); - DBWriteContactSettingWord(NULL, KEYBDMODULE, "custom", (WORD)SendDlgItemMessage(hwndDlg, IDC_SCUSTOM, CB_GETITEMDATA, (WPARAM)SendDlgItemMessage(hwndDlg, IDC_SCUSTOM, CB_GETCURSEL, 0, 0), 0)); - - DBWriteContactSettingByte(NULL, KEYBDMODULE, "ledsmsg", trillianLedsMsg); - DBWriteContactSettingByte(NULL, KEYBDMODULE, "ledsfile", trillianLedsFile); - DBWriteContactSettingByte(NULL, KEYBDMODULE, "ledsurl", trillianLedsURL); - DBWriteContactSettingByte(NULL, KEYBDMODULE, "ledsother", trillianLedsOther); - - DBWriteContactSettingWord(NULL, KEYBDMODULE, "sdelay", (WORD)SendDlgItemMessage(hwndDlg, IDC_DELAYSPIN, UDM_GETPOS, 0, 0)); - - DBWriteContactSettingByte(NULL, KEYBDMODULE, "speed", (BYTE)SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_GETPOS, 0, 0)); - - DBWriteContactSettingByte(NULL, KEYBDMODULE, "keypresses", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_KEYPRESSES) == BST_CHECKED ? 1:0)); - - LoadSettings(); - - return TRUE; - } // switch code - break; - } //switch idFrom - } - break; //End WM_NOTIFY - - default: - break; - } - - return FALSE; -} - -INT_PTR CALLBACK DlgProcThemeOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - int i; - TCHAR *str; - DBVARIANT dbv; - static BOOL initDlg=FALSE; - - switch (msg) { - - case WM_INITDIALOG: - initDlg=TRUE; - TranslateDialogDefault(hwndDlg); - - SendDlgItemMessage(hwndDlg, IDC_THEME, EM_LIMITTEXT, MAX_PATH, 0); - SendDlgItemMessage(hwndDlg, IDC_CUSTOMSTRING, EM_LIMITTEXT, MAX_PATH, 0); - - for (i=0; !DBGetContactSetting(NULL, KEYBDMODULE, fmtDBSettingName("theme%d", i), &dbv); i++) { - int index = SendDlgItemMessage(hwndDlg, IDC_THEME, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)dbv.pszVal); - DBFreeVariant(&dbv); - if (index != CB_ERR && index != CB_ERRSPACE) { - str = (TCHAR *)malloc(MAX_PATH+1); - if (str) - if (DBGetContactSetting(NULL, KEYBDMODULE, fmtDBSettingName("custom%d", i), &dbv)) - str[0] = _T('\0'); - else { - wcscpy(str, dbv.ptszVal); - DBFreeVariant(&dbv); - } - SendDlgItemMessage(hwndDlg, IDC_THEME, CB_SETITEMDATA, (WPARAM)index, (LPARAM)str); - } - } - - EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), FALSE); - if (SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETCOUNT, 0, 0) == 0) - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE), FALSE); - else { - SendDlgItemMessage(hwndDlg, IDC_THEME, CB_SETCURSEL, (WPARAM)wCustomTheme, 0); - str = (TCHAR *)SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETITEMDATA, (WPARAM)wCustomTheme, 0); - if (str) - SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, str); - } - - CheckDlgButton(hwndDlg, IDC_OVERRIDE, bOverride ? BST_CHECKED:BST_UNCHECKED); - - initDlg=FALSE; - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_THEME: - switch (HIWORD(wParam)) { - int item; - TCHAR theme[MAX_PATH+1]; - - case CBN_SELENDOK: - case CBN_SELCHANGE: - str = (TCHAR *)SendMessage((HWND)lParam, CB_GETITEMDATA, (WPARAM)SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0), 0); - if (str) - SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, str); - else - SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, _T("")); - EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE), TRUE); - break; - case CBN_EDITCHANGE: - GetDlgItemText(hwndDlg, IDC_THEME, theme, sizeof(theme)); - if ((item = SendMessage((HWND)lParam, CB_FINDSTRINGEXACT, -1, (LPARAM)theme)) == CB_ERR) { //new theme - SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, _T("")); - EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE), FALSE); - } else { - str = (TCHAR *)SendMessage((HWND)lParam, CB_GETITEMDATA, (WPARAM)item, 0); - if (str) - SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, str); - else - SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, _T("")); - EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE), TRUE); - } - EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), FALSE); - break; - } - return TRUE; - case IDC_CUSTOMSTRING: - if(HIWORD(wParam) == EN_CHANGE) { - int item; - TCHAR theme[MAX_PATH+1], customAux[MAX_PATH+1]; - - GetDlgItemText(hwndDlg, IDC_THEME, theme, sizeof(theme)); - if ((item = SendDlgItemMessage(hwndDlg, IDC_THEME, CB_FINDSTRINGEXACT, -1, (LPARAM)theme)) == CB_ERR) - return TRUE; - str = (TCHAR *)SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETITEMDATA, (WPARAM)item, 0); - if (str) { - GetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, customAux, MAX_PATH); - if (wcscmp(str, customAux)) - EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), TRUE); - else - EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), FALSE); - } - } - return TRUE; - case IDC_TEST: - { - TCHAR custom[MAX_PATH+1]; - - GetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, custom, MAX_PATH); - SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, normalizeCustomString(custom)); - testSequence(custom); - } - return TRUE; - case IDC_ADD: - { - int item; - TCHAR theme[MAX_PATH+1]; - - GetDlgItemText(hwndDlg, IDC_THEME, theme, sizeof(theme)); - if (!theme[0]) - return TRUE; - item = SendDlgItemMessage(hwndDlg, IDC_THEME, CB_ADDSTRING, 0, (LPARAM)theme); - str = (TCHAR *)malloc(MAX_PATH+1); - if (str) { - GetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, str, MAX_PATH); - SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, normalizeCustomString(str)); - } - SendDlgItemMessage(hwndDlg, IDC_THEME, CB_SETITEMDATA, (WPARAM)item, (LPARAM)str); - EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE), TRUE); - } - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - return TRUE; - case IDC_UPDATE: - { - int item; - TCHAR theme[MAX_PATH+1]; - - GetDlgItemText(hwndDlg, IDC_THEME, theme, sizeof(theme)); - item = SendDlgItemMessage(hwndDlg, IDC_THEME, CB_FINDSTRINGEXACT, -1, (LPARAM)theme); - str = (TCHAR *)SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETITEMDATA, (WPARAM)item, 0); - if (str) { - GetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, str, MAX_PATH); - SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, normalizeCustomString(str)); - } - EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), FALSE); - } - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - return TRUE; - case IDC_DELETE: - { - int item; - TCHAR theme[MAX_PATH+1]; - - GetDlgItemText(hwndDlg, IDC_THEME, theme, sizeof(theme)); - item = SendDlgItemMessage(hwndDlg, IDC_THEME, CB_FINDSTRINGEXACT, -1, (LPARAM)theme); - str = (TCHAR *)SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETITEMDATA, (WPARAM)item, 0); - if (str) - free(str); - SendDlgItemMessage(hwndDlg, IDC_THEME, CB_DELETESTRING, (WPARAM)item, 0); - if (SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETCOUNT, 0, 0) == 0) { - SetDlgItemText(hwndDlg, IDC_THEME, _T("")); - SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, _T("")); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE), FALSE); - } else { - SendDlgItemMessage(hwndDlg, IDC_THEME, CB_SETCURSEL, 0, 0); - str = (TCHAR *)SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETITEMDATA, 0, 0); - if (str) - SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, str); - } - EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), FALSE); - } - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - return TRUE; - case IDC_EXPORT: - { - TCHAR path[MAX_PATH+1], filter[MAX_PATH+1], *pfilter; - OPENFILENAME ofn={0}; - - path[0] = _T('\0'); - ofn.lStructSize = sizeof(OPENFILENAME); - ofn.hwndOwner = hwndDlg; - ofn.hInstance = NULL; - wcscpy(filter,_T("Keyboard Notify Theme")); - wcscat(filter, _T(" (*.knt)")); - pfilter = filter + wcslen(filter) + 1; - wcscpy(pfilter, _T("*.knt")); - pfilter = pfilter + wcslen(pfilter) + 1; - wcscpy(pfilter, _T("All Files")); - pfilter = pfilter + wcslen(pfilter) + 1; - wcscpy(pfilter, _T("*.*")); - pfilter = pfilter + wcslen(pfilter) + 1; - *pfilter = _T('\0'); - ofn.lpstrFilter = filter; - ofn.lpstrFile = path; - ofn.Flags = OFN_HIDEREADONLY|OFN_NOCHANGEDIR|OFN_NOREADONLYRETURN|OFN_PATHMUSTEXIST; - ofn.nMaxFile = sizeof(path); - ofn.lpstrDefExt = _T("knt"); - if(GetSaveFileName(&ofn)) - exportThemes(path); - } - return TRUE; - case IDC_IMPORT: - { - TCHAR path[MAX_PATH+1], filter[MAX_PATH+1], *pfilter; - OPENFILENAME ofn={0}; - - path[0] = _T('\0'); - ofn.lStructSize = sizeof(OPENFILENAME); - ofn.hwndOwner = hwndDlg; - ofn.hInstance = NULL; - wcscpy(filter, _T("Keyboard Notify Theme")); - wcscat(filter, _T(" (*.knt)")); - pfilter = filter + wcslen(filter) + 1; - wcscpy(pfilter, _T("*.knt")); - pfilter = pfilter + wcslen(pfilter) + 1; - wcscpy(pfilter, _T("All Files")); - pfilter = pfilter + wcslen(pfilter) + 1; - wcscpy(pfilter, _T("*.*")); - pfilter = pfilter + wcslen(pfilter) + 1; - *pfilter = _T('\0'); - ofn.lpstrFilter = filter; - ofn.lpstrFile = path; - ofn.Flags = OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_NOCHANGEDIR; - ofn.nMaxFile = sizeof(path); - ofn.lpstrDefExt = _T("knt"); - if(GetOpenFileName(&ofn)) { - importThemes(path, IsDlgButtonChecked(hwndDlg, IDC_OVERRIDE) == BST_CHECKED); - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - } - } - return TRUE; - case IDC_OVERRIDE: - SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); - return TRUE; - } - break; - - case WM_NOTIFY: - { - int count; - TCHAR theme[MAX_PATH+1], themeAux[MAX_PATH+1], *str; - //Here we have pressed either the OK or the APPLY button. - switch(((LPNMHDR)lParam)->idFrom) { - case 0: - switch (((LPNMHDR)lParam)->code) { - case PSN_APPLY: - if (!DBGetContactSetting(NULL, KEYBDMODULE, fmtDBSettingName("theme%d", wCustomTheme), &dbv)) - wcscpy(theme, dbv.ptszVal); - else - theme[0] = _T('\0'); - - // Here we will delete all the items in the theme combo on the Flashing tab: we will load them again later - for (i=0; SendDlgItemMessage(hwndEffect, IDC_SCUSTOM, CB_DELETESTRING, 0, (LPARAM)i) != CB_ERR; i++); - - count = SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETCOUNT, 0, 0); - for (i=0, wCustomTheme=0; i < count; i++) { - SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETLBTEXT, (WPARAM)i, (LPARAM)themeAux); - DBWriteContactSettingWString(NULL, KEYBDMODULE, fmtDBSettingName("theme%d", i), themeAux); - str = (TCHAR *)SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETITEMDATA, (WPARAM)i, 0); - if (str) - DBWriteContactSettingWString(NULL, KEYBDMODULE, fmtDBSettingName("custom%d", i), str); - else - DBWriteContactSettingWString(NULL, KEYBDMODULE, fmtDBSettingName("custom%d", i), _T("")); - - if (!wcscmp(theme, themeAux)) - wCustomTheme = i; - - // Here we will update the theme combo on the Flashing tab: horrible but can't imagine a better way right now - SendDlgItemMessage(hwndEffect, IDC_SCUSTOM, CB_INSERTSTRING, (WPARAM)i, (LPARAM)themeAux); - SendDlgItemMessage(hwndEffect, IDC_SCUSTOM, CB_SETITEMDATA, (WPARAM)i, (LPARAM)i); - } - for (i=count; !DBDeleteContactSetting(NULL, KEYBDMODULE, fmtDBSettingName("theme%d", i)); i++) - DBDeleteContactSetting(NULL, KEYBDMODULE, fmtDBSettingName("custom%d", i)); - - DBWriteContactSettingWord(NULL, KEYBDMODULE, "custom", wCustomTheme); - // Still updating here the the Flashing tab's controls - SendDlgItemMessage(hwndEffect, IDC_SCUSTOM, CB_SETCURSEL, (WPARAM)wCustomTheme, 0); - - DBWriteContactSettingByte(NULL, KEYBDMODULE, "override", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_OVERRIDE) == BST_CHECKED ? 1:0)); - - return TRUE; - } // switch code - break; - } //switch idFrom - } - break; //End WM_NOTIFY - - case WM_DESTROY: - { - int item, count = SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETCOUNT, 0, 0); - - for (item=0; item < count; item++) { - str = (TCHAR *)SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETITEMDATA, (WPARAM)item, 0); - if (str) - free(str); - } - break; - } - - default: - break; - } - - return FALSE; -} - - -void exportThemes(const TCHAR *filename) -{ - int i; - FILE *fExport; - DBVARIANT dbv; - - if (!(fExport = _wfopen(filename, _T("wt")))) - return; - - fwprintf(fExport, TranslateT("\n; Automatically generated Keyboard Notify Theme file\n\n\n")); - - for (i=0; !DBGetContactSetting(NULL, KEYBDMODULE, fmtDBSettingName("theme%d", i), &dbv); i++) { - fwprintf(fExport, _T("[%s]\n"), dbv.ptszVal); - DBFreeVariant(&dbv); - if (DBGetContactSetting(NULL, KEYBDMODULE, fmtDBSettingName("custom%d", i), &dbv)) - fwprintf(fExport, _T("0\n\n")); - else { - fwprintf(fExport, _T("%s\n\n"), dbv.ptszVal); - DBFreeVariant(&dbv); - } - } - - fwprintf(fExport, TranslateT("\n; End of automatically generated Keyboard Notify Theme file\n")); - - fclose(fExport); -} - - -void importThemes(const TCHAR *filename, BOOL overrideExisting) -{ - int status=0; - size_t i; - FILE *fImport; - TCHAR buffer[MAX_PATH+1], theme[MAX_PATH+1], *str; - - if (!(fImport = _wfopen(filename, _T("rt")))) - return; - - while (fgetws(buffer, MAX_PATH, fImport) != NULL) { - for (str=buffer; *str && isspace(*str); str++); //ltrim - if (!*str || *str == ';') //empty line or comment - continue; - for (i=wcslen(str)-1; isspace(str[i]); str[i--]='\0'); //rtrim - switch (status) { - case 0: - if (i > 1 && str[0] == '[' && str[i] == ']') { - status = 1; - wcscpy(theme, str+1); - theme[i-1] = '\0'; - } - break; - case 1: - status = 0; - writeThemeToCombo(theme, normalizeCustomString(str), overrideExisting); - break; - } - } - - fclose(fImport); -} - - -void writeThemeToCombo(const TCHAR *theme, const TCHAR *custom, BOOL overrideExisting) -{ - int item; - TCHAR *str; - - item = SendDlgItemMessage(hwndTheme, IDC_THEME, CB_FINDSTRINGEXACT, -1, (LPARAM)theme); - if (item == CB_ERR) { - item = SendDlgItemMessage(hwndTheme, IDC_THEME, CB_ADDSTRING, 0, (LPARAM)theme); - str = (TCHAR *)malloc(MAX_PATH+1); - if (str) - wcscpy(str, custom); - SendDlgItemMessage(hwndTheme, IDC_THEME, CB_SETITEMDATA, (WPARAM)item, (LPARAM)str); - } else - if (overrideExisting) { - str = (TCHAR *)SendDlgItemMessage(hwndTheme, IDC_THEME, CB_GETITEMDATA, (WPARAM)item, 0); - if (str) - wcscpy(str, custom); - } -} - - -INT_PTR CALLBACK DlgProcProcesses(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - unsigned int i; - - switch (msg) { - - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - - SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, EM_LIMITTEXT, MAX_PATH, 0); - - for (i=0; i < ProcessListAux.count; i++) - if (ProcessListAux.szFileName[i]) { - int index = SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)ProcessListAux.szFileName[i]); - if (index != CB_ERR && index != CB_ERRSPACE) - SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_SETITEMDATA, (WPARAM)index, (LPARAM)i); - } - - EnableWindow(GetDlgItem(hwndDlg, IDC_ADDPGM), FALSE); - if (SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_GETCOUNT, 0, 0) == 0) - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETEPGM), FALSE); - else - SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_SETCURSEL, 0, 0); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_PROGRAMS: - switch (HIWORD(wParam)) { - int item; - TCHAR szFileName[MAX_PATH+1]; - - case CBN_SELENDOK: - case CBN_SELCHANGE: - EnableWindow(GetDlgItem(hwndDlg, IDC_ADDPGM), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETEPGM), TRUE); - break; - case CBN_EDITCHANGE: - GetDlgItemText(hwndDlg, IDC_PROGRAMS, szFileName, sizeof(szFileName)); - if ((item = SendMessage((HWND)lParam, CB_FINDSTRINGEXACT, -1, (LPARAM)szFileName)) == CB_ERR) { //new program - EnableWindow(GetDlgItem(hwndDlg, IDC_ADDPGM), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETEPGM), FALSE); - } else { - EnableWindow(GetDlgItem(hwndDlg, IDC_ADDPGM), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETEPGM), TRUE); - } - break; - } - break; - case IDC_ADDPGM: - { - int item; - TCHAR szFileName[MAX_PATH+1]; - - GetDlgItemText(hwndDlg, IDC_PROGRAMS, szFileName, sizeof(szFileName)); - if (!szFileName[0]) - break; - item = SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_ADDSTRING, 0, (LPARAM)szFileName); - EnableWindow(GetDlgItem(hwndDlg, IDC_ADDPGM), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETEPGM), TRUE); - } - break; - case IDC_DELETEPGM: - { - int item; - TCHAR szFileName[MAX_PATH+1]; - - GetDlgItemText(hwndDlg, IDC_PROGRAMS, szFileName, sizeof(szFileName)); - item = SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_FINDSTRINGEXACT, -1, (LPARAM)szFileName); - SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_DELETESTRING, (WPARAM)item, 0); - if (SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_GETCOUNT, 0, 0) == 0) { - SetDlgItemText(hwndDlg, IDC_PROGRAMS, _T("")); - EnableWindow(GetDlgItem(hwndDlg, IDC_DELETEPGM), FALSE); - } else - SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_SETCURSEL, 0, 0); - } - break; - case IDC_OKPGM: - destroyProcessListAux(); - - ProcessListAux.count = SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_GETCOUNT, 0, 0); - ProcessListAux.szFileName = (TCHAR **)malloc(ProcessListAux.count * sizeof(TCHAR *)); - if (!ProcessListAux.szFileName) - ProcessListAux.count = 0; - else - for (i=0; i < ProcessListAux.count; i++) { - TCHAR szFileNameAux[MAX_PATH+1]; - - SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_GETLBTEXT, (WPARAM)i, (LPARAM)szFileNameAux); - ProcessListAux.szFileName[i] = (TCHAR *)malloc(wcslen(szFileNameAux) + 1); - if (ProcessListAux.szFileName[i]) - wcscpy(ProcessListAux.szFileName[i], szFileNameAux); - } - - case IDC_CANCELPGM: - EndDialog(hwndDlg, LOWORD(wParam)); - break; - } - break; - } - - return FALSE; -} - - -void createProcessListAux(void) -{ - unsigned int i; - - ProcessListAux.count = ProcessList.count; - ProcessListAux.szFileName = (TCHAR **)malloc(ProcessListAux.count * sizeof(char *)); - if (!ProcessListAux.szFileName) - ProcessListAux.count = 0; - else - for (i=0; i < ProcessListAux.count; i++) - if (!ProcessList.szFileName[i]) - ProcessListAux.szFileName[i] = NULL; - else { - ProcessListAux.szFileName[i] = (TCHAR *)malloc(wcslen(ProcessList.szFileName[i]) + 1); - if (ProcessListAux.szFileName[i]) - wcscpy(ProcessListAux.szFileName[i], ProcessList.szFileName[i]); - } - -} - - -void destroyProcessListAux(void) -{ - unsigned int i; - - for(i=0; i < ProcessListAux.count; i++) - if (ProcessListAux.szFileName[i]) - free(ProcessListAux.szFileName[i]); - - if (ProcessListAux.szFileName) - free(ProcessListAux.szFileName); - - ProcessListAux.count = 0; - ProcessListAux.szFileName = NULL; -} - - -INT_PTR CALLBACK DlgProcEventLeds(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - - case WM_INITDIALOG: - TranslateDialogDefault(hwndDlg); - - CheckDlgButton(hwndDlg, IDC_MSGLEDNUM, trillianLedsMsg&2 ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_MSGLEDCAPS, trillianLedsMsg&4 ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_MSGLEDSCROLL, trillianLedsMsg&1 ? BST_CHECKED:BST_UNCHECKED); - - CheckDlgButton(hwndDlg, IDC_FILELEDNUM, trillianLedsFile&2 ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_FILELEDCAPS, trillianLedsFile&4 ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_FILELEDSCROLL, trillianLedsFile&1 ? BST_CHECKED:BST_UNCHECKED); - - CheckDlgButton(hwndDlg, IDC_URLLEDNUM, trillianLedsURL&2 ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_URLLEDCAPS, trillianLedsURL&4 ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_URLLEDSCROLL, trillianLedsURL&1 ? BST_CHECKED:BST_UNCHECKED); - - CheckDlgButton(hwndDlg, IDC_OTHERLEDNUM, trillianLedsOther&2 ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_OTHERLEDCAPS, trillianLedsOther&4 ? BST_CHECKED:BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_OTHERLEDSCROLL, trillianLedsOther&1 ? BST_CHECKED:BST_UNCHECKED); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_OK: - trillianLedsMsg = 0; - if(IsDlgButtonChecked(hwndDlg, IDC_MSGLEDNUM) == BST_CHECKED) - trillianLedsMsg |= 2; - if(IsDlgButtonChecked(hwndDlg, IDC_MSGLEDCAPS) == BST_CHECKED) - trillianLedsMsg |= 4; - if(IsDlgButtonChecked(hwndDlg, IDC_MSGLEDSCROLL) == BST_CHECKED) - trillianLedsMsg |= 1; - - trillianLedsFile = 0; - if(IsDlgButtonChecked(hwndDlg, IDC_FILELEDNUM) == BST_CHECKED) - trillianLedsFile |= 2; - if(IsDlgButtonChecked(hwndDlg, IDC_FILELEDCAPS) == BST_CHECKED) - trillianLedsFile |= 4; - if(IsDlgButtonChecked(hwndDlg, IDC_FILELEDSCROLL) == BST_CHECKED) - trillianLedsFile |= 1; - - trillianLedsURL = 0; - if(IsDlgButtonChecked(hwndDlg, IDC_URLLEDNUM) == BST_CHECKED) - trillianLedsURL |= 2; - if(IsDlgButtonChecked(hwndDlg, IDC_URLLEDCAPS) == BST_CHECKED) - trillianLedsURL |= 4; - if(IsDlgButtonChecked(hwndDlg, IDC_URLLEDSCROLL) == BST_CHECKED) - trillianLedsURL |= 1; - - trillianLedsOther = 0; - if(IsDlgButtonChecked(hwndDlg, IDC_OTHERLEDNUM) == BST_CHECKED) - trillianLedsOther |= 2; - if(IsDlgButtonChecked(hwndDlg, IDC_OTHERLEDCAPS) == BST_CHECKED) - trillianLedsOther |= 4; - if(IsDlgButtonChecked(hwndDlg, IDC_OTHERLEDSCROLL) == BST_CHECKED) - trillianLedsOther |= 1; - - case IDC_CANCEL: - EndDialog(hwndDlg, LOWORD(wParam)); - break; - } - break; - } - - return FALSE; -} - - -void createXstatusListAux(void) -{ - unsigned int i, j; - - XstatusListAux = (XSTATUS_INFO *)malloc(ProtoList.protoCount * sizeof(XSTATUS_INFO)); - if (XstatusListAux) - for (i=0; i < ProtoList.protoCount; i++) { - XstatusListAux[i].count = ProtoList.protoInfo[i].xstatus.count; - if (!XstatusListAux[i].count) - XstatusListAux[i].enabled = NULL; - else { - XstatusListAux[i].enabled = (BOOL *)malloc(XstatusListAux[i].count * sizeof(BOOL)); - if (!XstatusListAux[i].enabled) - XstatusListAux[i].count = 0; - else - for(j=0; j < XstatusListAux[i].count; j++) - XstatusListAux[i].enabled[j] = ProtoList.protoInfo[i].xstatus.enabled[j]; - } - } - -} - - -void destroyXstatusListAux(void) -{ - unsigned int i; - - if (XstatusListAux) { - for(i=0; i < ProtoList.protoCount; i++) - if (XstatusListAux[i].enabled) - free(XstatusListAux[i].enabled); - - free(XstatusListAux); - XstatusListAux = NULL; - } - -} - - -INT_PTR CALLBACK DlgProcXstatusList(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - - case WM_INITDIALOG: - - { - unsigned int i; - WPARAM j; - int imageCount; - HICON hIconAux; - HIMAGELIST hImageList; - TVINSERTSTRUCT tvis={0}; - TVITEM tvi={0}; - HTREEITEM hSectionItem, hItem; - HWND hwndTree = GetDlgItem(hwndDlg, IDC_TREE_XSTATUS); - - TranslateDialogDefault(hwndDlg); - SetWindowLongPtr(hwndTree, GWL_STYLE, GetWindowLongPtr(hwndTree, GWL_STYLE)|TVS_NOHSCROLL|TVS_CHECKBOXES); - - if (!XstatusListAux) return TRUE; - - // Calculate hImageList size - for (i=0, imageCount=1; i < ProtoList.protoCount; i++) - if (ProtoList.protoInfo[i].enabled && XstatusListAux[i].count) - imageCount += XstatusListAux[i].count; - - hImageList = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), (bWindowsNT && dWinVer >= 5.01?ILC_COLOR32:ILC_COLOR16)|ILC_MASK, imageCount, imageCount); - TreeView_SetImageList(hwndTree, hImageList, TVSIL_NORMAL); - - ImageList_AddIcon(hImageList, hIconAux=(HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_BLANK), IMAGE_ICON, 0, 0, 0)); - if (hIconAux) DestroyIcon(hIconAux); - - TreeView_SelectItem(hwndTree, NULL); - ShowWindow(hwndTree, SW_HIDE); - TreeView_DeleteAllItems(hwndTree); - - for (i=0; i < ProtoList.protoCount; i++) - if (ProtoList.protoInfo[i].enabled && XstatusListAux[i].count) { - HTREEITEM hParent; - - int count; PROTOACCOUNT** protos; - ProtoEnumAccounts( &count, &protos ); - - tvis.hParent = NULL; - tvis.hInsertAfter = TVI_LAST; - tvis.item.mask = TVIF_TEXT|TVIF_PARAM|TVIF_STATE|TVIF_IMAGE|TVIF_SELECTEDIMAGE; - tvis.item.pszText = protos[i] -> tszAccountName; - tvis.item.lParam = (LPARAM)i; - tvis.item.stateMask = TVIS_BOLD|TVIS_EXPANDED; - tvis.item.state = TVIS_BOLD|TVIS_EXPANDED; - tvis.item.iImage = tvis.item.iSelectedImage = ImageList_AddIcon(hImageList, hIconAux=(HICON)CallProtoService(ProtoList.protoInfo[i].szProto, PS_LOADICON, PLI_PROTOCOL, 0)); - if (hIconAux) DestroyIcon(hIconAux); - hParent = TreeView_InsertItem(hwndTree, &tvis); - for(j=0; j < XstatusListAux[i].count; j++) { - TCHAR szDefaultName[1024]; - ICQ_CUSTOM_STATUS xstatus={0}; - - tvis.hParent = hParent; - tvis.item.mask = TVIF_TEXT|TVIF_PARAM|TVIF_IMAGE|TVIF_SELECTEDIMAGE; - if (!j){ - tvis.item.pszText = TranslateT("None"); } - else { - xstatus.cbSize = sizeof(ICQ_CUSTOM_STATUS); - xstatus.flags = CSSF_MASK_NAME|CSSF_DEFAULT_NAME|CSSF_UNICODE; - xstatus.ptszName = szDefaultName; - xstatus.wParam = &j; - CallProtoService(ProtoList.protoInfo[i].szProto, PS_ICQ_GETCUSTOMSTATUSEX, 0, (LPARAM)&xstatus); - tvis.item.pszText = szDefaultName; - } - tvis.item.lParam = (LPARAM)j; - tvis.item.iImage = tvis.item.iSelectedImage = j?ImageList_AddIcon(hImageList, hIconAux=(HICON)CallProtoService(ProtoList.protoInfo[i].szProto, PS_ICQ_GETCUSTOMSTATUSICON, (WPARAM)j, 0)):0; - if (hIconAux) DestroyIcon(hIconAux); - TreeView_InsertItem(hwndTree, &tvis); - } - } - - tvi.mask = TVIF_HANDLE|TVIF_PARAM; - for (hSectionItem=TreeView_GetRoot(hwndTree); hSectionItem; hSectionItem=TreeView_GetNextSibling(hwndTree, hSectionItem)) { - tvi.hItem = hSectionItem; - TreeView_GetItem(hwndTree, &tvi); - i = (unsigned int)tvi.lParam; - TreeView_SetItemState(hwndTree, hSectionItem, INDEXTOSTATEIMAGEMASK(0), TVIS_STATEIMAGEMASK); - for (hItem=TreeView_GetChild(hwndTree, hSectionItem); hItem; hItem=TreeView_GetNextSibling(hwndTree, hItem)) { - tvi.hItem = hItem; - TreeView_GetItem(hwndTree, &tvi); - j = (unsigned int)tvi.lParam; - TreeView_SetItemState(hwndTree, hItem, INDEXTOSTATEIMAGEMASK(XstatusListAux[i].enabled[j]?2:1), TVIS_STATEIMAGEMASK); - } - } - - ShowWindow(hwndTree, SW_SHOW); - TreeView_SetItemState(hwndTree, 0, TVIS_SELECTED, TVIS_SELECTED); - return TRUE; - } - - case WM_DESTROY: - { - HIMAGELIST hImageList; - - // Destroy tree view imagelist since it does not get destroyed automatically (see msdn docs) - hImageList = TreeView_GetImageList(GetDlgItem(hwndDlg, IDC_TREE_XSTATUS), TVSIL_STATE); - if (hImageList) { - TreeView_SetImageList(GetDlgItem(hwndDlg, IDC_TREE_XSTATUS), NULL, TVSIL_STATE); - ImageList_Destroy(hImageList); - } - hImageList = TreeView_GetImageList(GetDlgItem(hwndDlg, IDC_TREE_XSTATUS), TVSIL_NORMAL); - if (hImageList) { - TreeView_SetImageList(GetDlgItem(hwndDlg, IDC_TREE_XSTATUS), NULL, TVSIL_NORMAL); - ImageList_Destroy(hImageList); - } - return TRUE; - } - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_OKXST: - { - unsigned int i, j; - HTREEITEM hSectionItem, hItem; - TVITEM tvi={0}; - HWND hwndTree = GetDlgItem(hwndDlg, IDC_TREE_XSTATUS); - - tvi.mask = TVIF_HANDLE|TVIF_PARAM; - for (hSectionItem=TreeView_GetRoot(hwndTree); hSectionItem; hSectionItem=TreeView_GetNextSibling(hwndTree, hSectionItem)) { - tvi.hItem = hSectionItem; - TreeView_GetItem(hwndTree, &tvi); - i = (unsigned int)tvi.lParam; - for (hItem=TreeView_GetChild(hwndTree, hSectionItem); hItem; hItem=TreeView_GetNextSibling(hwndTree, hItem)) { - tvi.hItem = hItem; - TreeView_GetItem(hwndTree, &tvi); - j = (unsigned int)tvi.lParam; - XstatusListAux[i].enabled[j] = !!(TreeView_GetItemState(hwndTree, hItem, TVIS_STATEIMAGEMASK)&INDEXTOSTATEIMAGEMASK(2)); - } - } - } - - case IDC_CANCELXST: - EndDialog(hwndDlg, LOWORD(wParam)); - return TRUE; - } - break; - } - - return FALSE; -} diff --git a/plugins/KeyboardNotify/protolist.h b/plugins/KeyboardNotify/protolist.h deleted file mode 100644 index 5a08d929da..0000000000 --- a/plugins/KeyboardNotify/protolist.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - -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. - -*/ - -typedef struct { - UINT_PTR count; - BOOL *enabled; -} XSTATUS_INFO; - -typedef struct { - char *szProto; - BOOL enabled; - BOOL visible; - XSTATUS_INFO xstatus; -} PROTOCOL_INFO; - -typedef struct { - unsigned int protoCount; - PROTOCOL_INFO *protoInfo; -} PROTOCOL_LIST; diff --git a/plugins/KeyboardNotify/res/resources.rc b/plugins/KeyboardNotify/res/resources.rc new file mode 100644 index 0000000000..f63ee9d214 --- /dev/null +++ b/plugins/KeyboardNotify/res/resources.rc @@ -0,0 +1,424 @@ +//Microsoft Developer Studio generated resource script. +// +#include "..\src\resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_OPTIONS DIALOGEX 0, 0, 323, 245 +STYLE DS_FIXEDSYS | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + CONTROL "Tab1",IDC_TABS,"SysTabControl32",TCS_FIXEDWIDTH | 0x8,0, + 0,317,245 +END + +IDD_PROTO_OPTIONS DIALOGEX 1, 15, 314, 229 +STYLE DS_FIXEDSYS | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + GROUPBOX "Protocols to check",IDC_STATIC,81,6,149,143 + CONTROL "",IDC_PROTOCOLLIST,"SysListView32",LVS_REPORT | + LVS_ALIGNLEFT | LVS_NOCOLUMNHEADER | WS_BORDER | + WS_TABSTOP,105,25,100,108 +END + +IDD_BASIC_OPTIONS DIALOGEX 1, 15, 314, 229 +STYLE DS_FIXEDSYS | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg" +BEGIN + GROUPBOX "Events to react on",IDC_STATIC,8,6,147,68 + CONTROL "Incoming messages",IDC_ONMESSAGE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,24,18,127,10 + CONTROL "Incoming files",IDC_ONFILE,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,24,31,127,10 + CONTROL "Incoming URLs",IDC_ONURL,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,24,44,127,10 + CONTROL "Everything else",IDC_ONOTHER,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,24,57,128,10 + GROUPBOX "Message-Event only",IDC_STATIC,8,79,147,57 + CONTROL "Blink if message window is open",IDC_IFOPEN,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,24,91,126,10 + CONTROL " ... and not in foreground",IDC_IFNOTTOP,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,24,104,125,10 + CONTROL "Only if last is",IDC_IFOLDER,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,24,117,54,10 + EDITTEXT IDC_SOLDER,81,116,36,13,ES_NUMBER + CONTROL "Spin1",IDC_OLDERSPIN,"msctls_updown32",UDS_SETBUDDYINT | + UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,107,116, + 9,13 + LTEXT "sec. old",IDC_STATIC,119,118,29,10 + GROUPBOX "Flash until",IDC_STATIC,8,141,147,78 + CONTROL "",IDC_UNTILBLK,"Button",BS_AUTOCHECKBOX | WS_GROUP,24, + 156,11,10 + EDITTEXT IDC_SBLINK,36,154,44,13,ES_NUMBER + CONTROL "Spin1",IDC_BLINKSPIN,"msctls_updown32",UDS_SETBUDDYINT | + UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,68,154, + 9,13 + LTEXT "seconds",IDC_STATIC,83,156,67,10 + CONTROL "",IDC_UNTILATTENDED,"Button",BS_AUTOCHECKBOX,24,171,11, + 10 + COMBOBOX IDC_MIRORWIN,36,169,44,96,CBS_DROPDOWNLIST | WS_TABSTOP + LTEXT "is re-attended",IDC_STATIC,83,171,67,10 + CONTROL "Events are opened",IDC_UNTILOPEN,"Button", + BS_AUTOCHECKBOX,24,186,125,10 + CONTROL "End of 'notify when' conditions",IDC_UNTILCOND,"Button", + BS_AUTOCHECKBOX,24,200,126,10 + GROUPBOX "Notify when",IDC_STATIC,160,6,147,68 + CONTROL "Full Screen mode",IDC_FSCREEN,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,173,16,117,10 + CONTROL "Screen Saver is running",IDC_SSAVER,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,173,27,117,10 + CONTROL "Workstation is Locked (2000/XP)",IDC_LOCKED,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,173,38,117,10 + CONTROL "Defined programs are running",IDC_PGMS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,173,49,111,10 + PUSHBUTTON "...",IDC_ASSIGNPGMS,287,51,15,9 + CONTROL "All other situations",IDC_ACTIVE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,173,60,117,10 + GROUPBOX "Only notify if status is",IDC_STATIC,160,79,147,107 + CONTROL "Online",IDC_ONLINE,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,173,90,65,9 + CONTROL "Away",IDC_AWAY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 173,100,128,9 + CONTROL "Occupied",IDC_OCCUPIED,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,173,120,128,9 + CONTROL "NA",IDC_NA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,173, + 110,128,9 + CONTROL "DND",IDC_DND,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,173, + 130,85,9 + CONTROL "Free for chat",IDC_FREECHAT,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,173,140,127,9 + CONTROL "Invisible",IDC_INVISIBLE,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,173,150,128,9 + CONTROL "On the phone",IDC_ONTHEPHONE,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,173,160,128,9 + CONTROL "Out to lunch",IDC_OUTTOLUNCH,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,173,170,127,9 + GROUPBOX "Pending Events",IDC_STATIC,160,191,147,28 + LTEXT "Remind me every",IDC_STATIC,173,202,58,9 + EDITTEXT IDC_SREMCHECK,231,200,37,13,ES_NUMBER + CONTROL "Spin1",IDC_REMCHECK,"msctls_updown32",UDS_SETBUDDYINT | + UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,257,200, + 9,13 + LTEXT "minutes",IDC_STATIC,271,202,30,9 + CONTROL "Offline",IDC_OFFLINE,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,242,90,61,9 + PUSHBUTTON "xStatuses",IDC_SELECTXSTATUS,263,130,40,9 +END + +IDD_EFFECT_OPTIONS DIALOGEX 1, 15, 314, 229 +STYLE DS_FIXEDSYS | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + GROUPBOX "Keys to flash",IDC_STATIC,8,6,147,91 + CONTROL "Num Lock",IDC_NUM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 24,22,124,10 + CONTROL "Caps Lock",IDC_CAPS,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,24,36,123,10 + CONTROL "Scroll Lock",IDC_SCROLL,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,24,50,124,10 + GROUPBOX "Flashing effects",IDC_STATIC,160,6,147,91 + CONTROL "All at the same time",IDC_SAMETIME,"Button", + BS_AUTORADIOBUTTON | WS_GROUP,172,22,127,10 + CONTROL "In turn",IDC_INTURN,"Button",BS_AUTORADIOBUTTON,172,36, + 126,10 + CONTROL "In sequence",IDC_INSEQUENCE,"Button",BS_AUTORADIOBUTTON, + 172,50,62,10 + COMBOBOX IDC_SEQORDER,235,48,53,95,CBS_DROPDOWNLIST | WS_TABSTOP + CONTROL "Custom theme",IDC_CUSTOM,"Button",BS_AUTORADIOBUTTON, + 172,64,62,10 + COMBOBOX IDC_SCUSTOM,235,63,67,95,CBS_DROPDOWNLIST | + CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + CONTROL "Accordingly to events' count",IDC_TRILLIAN,"Button", + BS_AUTORADIOBUTTON,172,78,113,10 + PUSHBUTTON "...",IDC_ASSIGNLEDS,287,79,15,9 + GROUPBOX "Wait before starting flashing",IDC_STATIC,8,102,147,54 + EDITTEXT IDC_SDELAY,29,122,39,14,ES_NUMBER + LTEXT "seconds",IDC_STATIC,72,124,80,9 + GROUPBOX "Flash speed",IDC_STATIC,160,102,147,54 + CONTROL "Slider1",IDC_SPEED,"msctls_trackbar32",TBS_AUTOTICKS | + WS_TABSTOP,170,128,127,19 + RTEXT "Fast",IDC_STATIC,238,113,50,9 + LTEXT "Slow",IDC_STATIC,178,113,55,8 + CONTROL "Spin1",IDC_DELAYSPIN,"msctls_updown32",UDS_SETBUDDYINT | + UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,59,122, + 9,14 + CONTROL "&Preview",IDC_PREVIEW,"Button",BS_AUTOCHECKBOX | + BS_PUSHLIKE,125,173,63,14 + CONTROL "Emulate keypresses (Use this option if you are using an USB keyboard)", + IDC_KEYPRESSES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11, + 209,293,10 +END + +IDD_THEME_OPTIONS DIALOGEX 1, 15, 314, 229 +STYLE DS_FIXEDSYS | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + GROUPBOX "Create/Edit Themes",IDC_STATIC,8,6,183,92 + LTEXT "Theme",IDC_STATIC,26,25,34,9 + COMBOBOX IDC_THEME,65,23,107,96,CBS_DROPDOWN | CBS_AUTOHSCROLL | + CBS_SORT | WS_VSCROLL | WS_TABSTOP + EDITTEXT IDC_CUSTOMSTRING,26,47,118,14,ES_AUTOHSCROLL + PUSHBUTTON "Test",IDC_TEST,144,47,27,14,BS_FLAT + PUSHBUTTON "Add",IDC_ADD,26,71,44,14 + PUSHBUTTON "Update",IDC_UPDATE,77,71,44,14 + PUSHBUTTON "Delete",IDC_DELETE,128,71,44,14 + GROUPBOX "Import/Export",IDC_STATIC,196,6,111,92 + PUSHBUTTON "Export...",IDC_EXPORT,209,29,83,14 + PUSHBUTTON "Import...",IDC_IMPORT,209,57,83,14 + CONTROL "Override existing",IDC_OVERRIDE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,209,76,84,10 +END + +IDD_PROCESSES DIALOG DISCARDABLE 175, 60, 176, 98 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Set program list" +FONT 8, "MS Sans Serif" +BEGIN + LTEXT "Program",IDC_STATIC,13,20,34,9 + COMBOBOX IDC_PROGRAMS,53,18,107,96,CBS_DROPDOWN | CBS_AUTOHSCROLL | + CBS_SORT | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Add",IDC_ADDPGM,36,41,44,14 + PUSHBUTTON "Delete",IDC_DELETEPGM,99,41,44,14 + DEFPUSHBUTTON "OK",IDC_OKPGM,119,77,50,14 + PUSHBUTTON "Cancel",IDC_CANCELPGM,63,77,50,14 +END + +IDD_EVENTLEDS DIALOG DISCARDABLE 175, 60, 176, 111 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Set LEDs for events" +FONT 8, "MS Sans Serif" +BEGIN + CTEXT "Num",IDC_STATIC,83,7,16,8 + CTEXT "Caps",IDC_STATIC,108,7,17,8 + CTEXT "Scroll",IDC_STATIC,130,7,18,8 + LTEXT "Message events",IDC_STATIC,7,19,74,9 + CONTROL "",IDC_MSGLEDNUM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 87,19,10,10 + CONTROL "",IDC_MSGLEDCAPS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 111,19,10,10 + CONTROL "",IDC_MSGLEDSCROLL,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,135,19,10,10 + LTEXT "File events",IDC_STATIC,7,32,74,10 + CONTROL "",IDC_FILELEDNUM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 87,32,10,10 + CONTROL "",IDC_FILELEDCAPS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 111,32,10,10 + CONTROL "",IDC_FILELEDSCROLL,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,135,32,10,10 + LTEXT "URL events",IDC_STATIC,7,45,74,9 + CONTROL "",IDC_URLLEDNUM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 87,45,10,10 + CONTROL "",IDC_URLLEDCAPS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 111,45,10,10 + CONTROL "",IDC_URLLEDSCROLL,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,135,45,10,10 + LTEXT "Other events",IDC_STATIC,7,58,74,10 + CONTROL "",IDC_OTHERLEDNUM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 87,58,10,10 + CONTROL "",IDC_OTHERLEDCAPS,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,111,58,10,10 + CONTROL "",IDC_OTHERLEDSCROLL,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,135,58,10,10 + DEFPUSHBUTTON "OK",IDC_OK,119,90,50,14 + PUSHBUTTON "Cancel",IDC_CANCEL,63,90,50,14 +END + +IDD_OPT_KN_ACTION DIALOGEX 0, 0, 194, 65 +STYLE DS_3DLOOK | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Sans Serif" +BEGIN + COMBOBOX IDC_CUSTOMTHEME,95,13,84,96,CBS_DROPDOWN | + CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP + LTEXT "Consider event opened after",IDC_STATIC,13,36,98,9 + EDITTEXT IDC_SFORCEOPEN,111,34,37,13,ES_NUMBER + LTEXT "seconds",IDC_STATIC,151,36,32,9 + CONTROL "Use custom theme",IDC_USECUSTOM,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,13,14,82,10 + CONTROL "Spin1",IDC_FORCEOPEN,"msctls_updown32",UDS_SETBUDDYINT | + UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,132,34, + 11,13 +END + +IDD_IGNORE_OPTIONS DIALOGEX 1, 15, 314, 229 +STYLE DS_FIXEDSYS | WS_CHILD +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "The following events are being ignored:",IDC_STATIC,13, + 17,288,8 + ICON "IDI_RECVMSG",IDC_MSGICON,17,177,20,20,SS_CENTERIMAGE + LTEXT "Ignore messages",IDC_STATIC,35,183,70,8,SS_NOPREFIX | + SS_CENTERIMAGE + ICON "IDI_URL",IDC_URLICON,17,192,20,20,SS_CENTERIMAGE + LTEXT "Ignore URLs",IDC_STATIC,35,201,70,8,SS_NOPREFIX | + SS_CENTERIMAGE + ICON "IDI_FILE",IDC_FILEICON,121,177,20,20,SS_CENTERIMAGE + LTEXT "Ignore files",IDC_STATIC,139,183,70,8,SS_NOPREFIX | + SS_CENTERIMAGE + ICON "IDI_MIRANDA",IDC_OTHERICON,121,193,20,20,SS_CENTERIMAGE + LTEXT "Ignore others",IDC_STATIC,139,201,69,8,SS_NOPREFIX | + SS_CENTERIMAGE + ICON "IDI_FILLEDBLOB",IDC_ALLICON,217,178,20,20, + SS_CENTERIMAGE + LTEXT "Ignore all",IDC_STATIC,234,185,64,8,SS_NOPREFIX | + SS_CENTERIMAGE + ICON "IDI_EMPTYBLOB",IDC_NONEICON,217,191,20,20, + SS_CENTERIMAGE + LTEXT "Ignore none",IDC_STATIC,234,201,63,8,SS_NOPREFIX | + SS_CENTERIMAGE + CONTROL "",IDC_LIST,"CListControl",WS_TABSTOP | 0x3da,13,30,286, + 142,WS_EX_CLIENTEDGE + GROUPBOX "Ignore",IDC_STATIC,7,4,300,217 +END + +IDD_XSTATUSES DIALOG DISCARDABLE 175, 60, 175, 204 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Set xStatus list" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDC_OKXST,118,183,50,14 + PUSHBUTTON "Cancel",IDC_CANCELXST,63,183,50,14 + CONTROL "Tree1",IDC_TREE_XSTATUS,"SysTreeView32",TVS_DISABLEDRAGDROP | + WS_BORDER | WS_TABSTOP | 0x8000,7,7,161,166 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_OPTIONS, DIALOG + BEGIN + RIGHTMARGIN, 317 + END + + IDD_BASIC_OPTIONS, DIALOG + BEGIN + BOTTOMMARGIN, 220 + END + + IDD_THEME_OPTIONS, DIALOG + BEGIN + BOTTOMMARGIN, 220 + END + + IDD_PROCESSES, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 169 + TOPMARGIN, 7 + BOTTOMMARGIN, 91 + END + + IDD_EVENTLEDS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 169 + TOPMARGIN, 7 + BOTTOMMARGIN, 104 + END + + IDD_OPT_KN_ACTION, DIALOG + BEGIN + RIGHTMARGIN, 186 + VERTGUIDE, 7 + BOTTOMMARGIN, 55 + HORZGUIDE, 7 + END + + IDD_XSTATUSES, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 168 + TOPMARGIN, 7 + BOTTOMMARGIN, 197 + END +END +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// French (Canada) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRC) +#ifdef _WIN32 +LANGUAGE LANG_FRENCH, SUBLANG_FRENCH_CANADIAN +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "..\\src\\resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // French (Canada) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/plugins/KeyboardNotify/resource.h b/plugins/KeyboardNotify/resource.h deleted file mode 100644 index 4ebfb19cd0..0000000000 --- a/plugins/KeyboardNotify/resource.h +++ /dev/null @@ -1,120 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by resources.rc -// -#define IDC_OTHERICON 1 -#define IDD_OPT_KN_ACTION 120 -#define IDD_OPTIONS 150 -#define IDD_PROTO_OPTIONS 151 -#define IDD_BASIC_OPTIONS 152 -#define IDD_EFFECT_OPTIONS 153 -#define IDD_THEME_OPTIONS 154 -#define IDD_EVENTLEDS 155 -#define IDD_PROCESSES 156 -#define IDD_IGNORE_OPTIONS 157 -#define IDD_XSTATUSES 158 -#define IDC_ONMESSAGE 1000 -#define IDC_ONFILE 1001 -#define IDC_ONURL 1002 -#define IDC_ONOTHER 1003 -#define IDC_IFOPEN 1004 -#define IDC_IFNOTTOP 1005 -#define IDC_IFOLDER 1006 -#define IDC_SOLDER 1007 -#define IDC_OLDERSPIN 1008 -#define IDC_UNTILBLK 1009 -#define IDC_SBLINK 1010 -#define IDC_BLINKSPIN 1011 -#define IDC_UNTILATTENDED 1012 -#define IDC_MIRORWIN 1013 -#define IDC_UNTILOPEN 1014 -#define IDC_UNTILCOND 1015 -#define IDC_FSCREEN 1016 -#define IDC_SSAVER 1017 -#define IDC_LOCKED 1018 -#define IDC_PGMS 1019 -#define IDC_ASSIGNPGMS 1020 -#define IDC_ACTIVE 1021 -#define IDC_ONLINE 1022 -#define IDC_AWAY 1023 -#define IDC_NA 1024 -#define IDC_OCCUPIED 1025 -#define IDC_DND 1026 -#define IDC_FREECHAT 1027 -#define IDC_INVISIBLE 1028 -#define IDC_ONTHEPHONE 1029 -#define IDC_OUTTOLUNCH 1030 -#define IDC_OFFLINE 1031 -#define IDC_REMCHECK 1032 -#define IDC_SREMCHECK 1033 -#define IDC_NUM 1034 -#define IDC_CAPS 1035 -#define IDC_SCROLL 1036 -#define IDC_SAMETIME 1037 -#define IDC_INTURN 1038 -#define IDC_INSEQUENCE 1039 -#define IDC_SEQORDER 1040 -#define IDC_CUSTOM 1041 -#define IDC_SCUSTOM 1042 -#define IDC_TRILLIAN 1043 -#define IDC_ASSIGNLEDS 1044 -#define IDC_SDELAY 1045 -#define IDC_DELAYSPIN 1046 -#define IDC_PREVIEW 1047 -#define IDC_SPEED 1048 -#define IDC_THEME 1049 -#define IDC_CUSTOMSTRING 1050 -#define IDC_TEST 1051 -#define IDC_ADD 1052 -#define IDC_UPDATE 1053 -#define IDC_DELETE 1054 -#define IDC_EXPORT 1055 -#define IDC_IMPORT 1056 -#define IDC_OVERRIDE 1057 -#define IDC_PROTOCOLLIST 1058 -#define IDC_MSGLEDNUM 1059 -#define IDC_MSGLEDCAPS 1060 -#define IDC_MSGLEDSCROLL 1061 -#define IDC_FILELEDNUM 1062 -#define IDC_FILELEDCAPS 1063 -#define IDC_FILELEDSCROLL 1064 -#define IDC_URLLEDNUM 1065 -#define IDC_URLLEDCAPS 1066 -#define IDC_URLLEDSCROLL 1067 -#define IDC_OTHERLEDNUM 1068 -#define IDC_OTHERLEDCAPS 1069 -#define IDC_OTHERLEDSCROLL 1070 -#define IDC_OK 1071 -#define IDC_CANCEL 1072 -#define IDC_PROGRAMS 1073 -#define IDC_ADDPGM 1074 -#define IDC_DELETEPGM 1075 -#define IDC_OKPGM 1076 -#define IDC_CANCELPGM 1077 -#define IDC_KEYPRESSES 1078 -#define IDC_CUSTOMTHEME 1079 -#define IDC_USECUSTOM 1080 -#define IDC_LIST 1081 -#define IDC_FORCEOPEN 1082 -#define IDC_SFORCEOPEN 1083 -#define IDC_SELECTXSTATUS 1084 -#define IDC_TREE_XSTATUS 1085 -#define IDC_OKXST 1086 -#define IDC_CANCELXST 1087 -#define IDC_FILEICON 1206 -#define IDC_ALLICON 1208 -#define IDC_NONEICON 1209 -#define IDC_MSGICON 1375 -#define IDC_URLICON 1376 -#define IDC_TABS 2000 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 103 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1088 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/plugins/KeyboardNotify/resources.rc b/plugins/KeyboardNotify/resources.rc deleted file mode 100644 index 7bbf535460..0000000000 --- a/plugins/KeyboardNotify/resources.rc +++ /dev/null @@ -1,424 +0,0 @@ -//Microsoft Developer Studio generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_OPTIONS DIALOGEX 0, 0, 323, 245 -STYLE DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - CONTROL "Tab1",IDC_TABS,"SysTabControl32",TCS_FIXEDWIDTH | 0x8,0, - 0,317,245 -END - -IDD_PROTO_OPTIONS DIALOGEX 1, 15, 314, 229 -STYLE DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - GROUPBOX "Protocols to check",IDC_STATIC,81,6,149,143 - CONTROL "",IDC_PROTOCOLLIST,"SysListView32",LVS_REPORT | - LVS_ALIGNLEFT | LVS_NOCOLUMNHEADER | WS_BORDER | - WS_TABSTOP,105,25,100,108 -END - -IDD_BASIC_OPTIONS DIALOGEX 1, 15, 314, 229 -STYLE DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg" -BEGIN - GROUPBOX "Events to react on",IDC_STATIC,8,6,147,68 - CONTROL "Incoming messages",IDC_ONMESSAGE,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,24,18,127,10 - CONTROL "Incoming files",IDC_ONFILE,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,24,31,127,10 - CONTROL "Incoming URLs",IDC_ONURL,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,24,44,127,10 - CONTROL "Everything else",IDC_ONOTHER,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,24,57,128,10 - GROUPBOX "Message-Event only",IDC_STATIC,8,79,147,57 - CONTROL "Blink if message window is open",IDC_IFOPEN,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,24,91,126,10 - CONTROL " ... and not in foreground",IDC_IFNOTTOP,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,24,104,125,10 - CONTROL "Only if last is",IDC_IFOLDER,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,24,117,54,10 - EDITTEXT IDC_SOLDER,81,116,36,13,ES_NUMBER - CONTROL "Spin1",IDC_OLDERSPIN,"msctls_updown32",UDS_SETBUDDYINT | - UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,107,116, - 9,13 - LTEXT "sec. old",IDC_STATIC,119,118,29,10 - GROUPBOX "Flash until",IDC_STATIC,8,141,147,78 - CONTROL "",IDC_UNTILBLK,"Button",BS_AUTOCHECKBOX | WS_GROUP,24, - 156,11,10 - EDITTEXT IDC_SBLINK,36,154,44,13,ES_NUMBER - CONTROL "Spin1",IDC_BLINKSPIN,"msctls_updown32",UDS_SETBUDDYINT | - UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,68,154, - 9,13 - LTEXT "seconds",IDC_STATIC,83,156,67,10 - CONTROL "",IDC_UNTILATTENDED,"Button",BS_AUTOCHECKBOX,24,171,11, - 10 - COMBOBOX IDC_MIRORWIN,36,169,44,96,CBS_DROPDOWNLIST | WS_TABSTOP - LTEXT "is re-attended",IDC_STATIC,83,171,67,10 - CONTROL "Events are opened",IDC_UNTILOPEN,"Button", - BS_AUTOCHECKBOX,24,186,125,10 - CONTROL "End of 'notify when' conditions",IDC_UNTILCOND,"Button", - BS_AUTOCHECKBOX,24,200,126,10 - GROUPBOX "Notify when",IDC_STATIC,160,6,147,68 - CONTROL "Full Screen mode",IDC_FSCREEN,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,173,16,117,10 - CONTROL "Screen Saver is running",IDC_SSAVER,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,173,27,117,10 - CONTROL "Workstation is Locked (2000/XP)",IDC_LOCKED,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,173,38,117,10 - CONTROL "Defined programs are running",IDC_PGMS,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,173,49,111,10 - PUSHBUTTON "...",IDC_ASSIGNPGMS,287,51,15,9 - CONTROL "All other situations",IDC_ACTIVE,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,173,60,117,10 - GROUPBOX "Only notify if status is",IDC_STATIC,160,79,147,107 - CONTROL "Online",IDC_ONLINE,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,173,90,65,9 - CONTROL "Away",IDC_AWAY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, - 173,100,128,9 - CONTROL "Occupied",IDC_OCCUPIED,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,173,120,128,9 - CONTROL "NA",IDC_NA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,173, - 110,128,9 - CONTROL "DND",IDC_DND,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,173, - 130,85,9 - CONTROL "Free for chat",IDC_FREECHAT,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,173,140,127,9 - CONTROL "Invisible",IDC_INVISIBLE,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,173,150,128,9 - CONTROL "On the phone",IDC_ONTHEPHONE,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,173,160,128,9 - CONTROL "Out to lunch",IDC_OUTTOLUNCH,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,173,170,127,9 - GROUPBOX "Pending Events",IDC_STATIC,160,191,147,28 - LTEXT "Remind me every",IDC_STATIC,173,202,58,9 - EDITTEXT IDC_SREMCHECK,231,200,37,13,ES_NUMBER - CONTROL "Spin1",IDC_REMCHECK,"msctls_updown32",UDS_SETBUDDYINT | - UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,257,200, - 9,13 - LTEXT "minutes",IDC_STATIC,271,202,30,9 - CONTROL "Offline",IDC_OFFLINE,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,242,90,61,9 - PUSHBUTTON "xStatuses",IDC_SELECTXSTATUS,263,130,40,9 -END - -IDD_EFFECT_OPTIONS DIALOGEX 1, 15, 314, 229 -STYLE DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - GROUPBOX "Keys to flash",IDC_STATIC,8,6,147,91 - CONTROL "Num Lock",IDC_NUM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, - 24,22,124,10 - CONTROL "Caps Lock",IDC_CAPS,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,24,36,123,10 - CONTROL "Scroll Lock",IDC_SCROLL,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,24,50,124,10 - GROUPBOX "Flashing effects",IDC_STATIC,160,6,147,91 - CONTROL "All at the same time",IDC_SAMETIME,"Button", - BS_AUTORADIOBUTTON | WS_GROUP,172,22,127,10 - CONTROL "In turn",IDC_INTURN,"Button",BS_AUTORADIOBUTTON,172,36, - 126,10 - CONTROL "In sequence",IDC_INSEQUENCE,"Button",BS_AUTORADIOBUTTON, - 172,50,62,10 - COMBOBOX IDC_SEQORDER,235,48,53,95,CBS_DROPDOWNLIST | WS_TABSTOP - CONTROL "Custom theme",IDC_CUSTOM,"Button",BS_AUTORADIOBUTTON, - 172,64,62,10 - COMBOBOX IDC_SCUSTOM,235,63,67,95,CBS_DROPDOWNLIST | - CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP - CONTROL "Accordingly to events' count",IDC_TRILLIAN,"Button", - BS_AUTORADIOBUTTON,172,78,113,10 - PUSHBUTTON "...",IDC_ASSIGNLEDS,287,79,15,9 - GROUPBOX "Wait before starting flashing",IDC_STATIC,8,102,147,54 - EDITTEXT IDC_SDELAY,29,122,39,14,ES_NUMBER - LTEXT "seconds",IDC_STATIC,72,124,80,9 - GROUPBOX "Flash speed",IDC_STATIC,160,102,147,54 - CONTROL "Slider1",IDC_SPEED,"msctls_trackbar32",TBS_AUTOTICKS | - WS_TABSTOP,170,128,127,19 - RTEXT "Fast",IDC_STATIC,238,113,50,9 - LTEXT "Slow",IDC_STATIC,178,113,55,8 - CONTROL "Spin1",IDC_DELAYSPIN,"msctls_updown32",UDS_SETBUDDYINT | - UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,59,122, - 9,14 - CONTROL "&Preview",IDC_PREVIEW,"Button",BS_AUTOCHECKBOX | - BS_PUSHLIKE,125,173,63,14 - CONTROL "Emulate keypresses (Use this option if you are using an USB keyboard)", - IDC_KEYPRESSES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11, - 209,293,10 -END - -IDD_THEME_OPTIONS DIALOGEX 1, 15, 314, 229 -STYLE DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg", 0, 0, 0x1 -BEGIN - GROUPBOX "Create/Edit Themes",IDC_STATIC,8,6,183,92 - LTEXT "Theme",IDC_STATIC,26,25,34,9 - COMBOBOX IDC_THEME,65,23,107,96,CBS_DROPDOWN | CBS_AUTOHSCROLL | - CBS_SORT | WS_VSCROLL | WS_TABSTOP - EDITTEXT IDC_CUSTOMSTRING,26,47,118,14,ES_AUTOHSCROLL - PUSHBUTTON "Test",IDC_TEST,144,47,27,14,BS_FLAT - PUSHBUTTON "Add",IDC_ADD,26,71,44,14 - PUSHBUTTON "Update",IDC_UPDATE,77,71,44,14 - PUSHBUTTON "Delete",IDC_DELETE,128,71,44,14 - GROUPBOX "Import/Export",IDC_STATIC,196,6,111,92 - PUSHBUTTON "Export...",IDC_EXPORT,209,29,83,14 - PUSHBUTTON "Import...",IDC_IMPORT,209,57,83,14 - CONTROL "Override existing",IDC_OVERRIDE,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,209,76,84,10 -END - -IDD_PROCESSES DIALOG DISCARDABLE 175, 60, 176, 98 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Set program list" -FONT 8, "MS Sans Serif" -BEGIN - LTEXT "Program",IDC_STATIC,13,20,34,9 - COMBOBOX IDC_PROGRAMS,53,18,107,96,CBS_DROPDOWN | CBS_AUTOHSCROLL | - CBS_SORT | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Add",IDC_ADDPGM,36,41,44,14 - PUSHBUTTON "Delete",IDC_DELETEPGM,99,41,44,14 - DEFPUSHBUTTON "OK",IDC_OKPGM,119,77,50,14 - PUSHBUTTON "Cancel",IDC_CANCELPGM,63,77,50,14 -END - -IDD_EVENTLEDS DIALOG DISCARDABLE 175, 60, 176, 111 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Set LEDs for events" -FONT 8, "MS Sans Serif" -BEGIN - CTEXT "Num",IDC_STATIC,83,7,16,8 - CTEXT "Caps",IDC_STATIC,108,7,17,8 - CTEXT "Scroll",IDC_STATIC,130,7,18,8 - LTEXT "Message events",IDC_STATIC,7,19,74,9 - CONTROL "",IDC_MSGLEDNUM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, - 87,19,10,10 - CONTROL "",IDC_MSGLEDCAPS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, - 111,19,10,10 - CONTROL "",IDC_MSGLEDSCROLL,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,135,19,10,10 - LTEXT "File events",IDC_STATIC,7,32,74,10 - CONTROL "",IDC_FILELEDNUM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, - 87,32,10,10 - CONTROL "",IDC_FILELEDCAPS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, - 111,32,10,10 - CONTROL "",IDC_FILELEDSCROLL,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,135,32,10,10 - LTEXT "URL events",IDC_STATIC,7,45,74,9 - CONTROL "",IDC_URLLEDNUM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, - 87,45,10,10 - CONTROL "",IDC_URLLEDCAPS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, - 111,45,10,10 - CONTROL "",IDC_URLLEDSCROLL,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,135,45,10,10 - LTEXT "Other events",IDC_STATIC,7,58,74,10 - CONTROL "",IDC_OTHERLEDNUM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, - 87,58,10,10 - CONTROL "",IDC_OTHERLEDCAPS,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,111,58,10,10 - CONTROL "",IDC_OTHERLEDSCROLL,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,135,58,10,10 - DEFPUSHBUTTON "OK",IDC_OK,119,90,50,14 - PUSHBUTTON "Cancel",IDC_CANCEL,63,90,50,14 -END - -IDD_OPT_KN_ACTION DIALOGEX 0, 0, 194, 65 -STYLE DS_3DLOOK | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Sans Serif" -BEGIN - COMBOBOX IDC_CUSTOMTHEME,95,13,84,96,CBS_DROPDOWN | - CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP - LTEXT "Consider event opened after",IDC_STATIC,13,36,98,9 - EDITTEXT IDC_SFORCEOPEN,111,34,37,13,ES_NUMBER - LTEXT "seconds",IDC_STATIC,151,36,32,9 - CONTROL "Use custom theme",IDC_USECUSTOM,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,13,14,82,10 - CONTROL "Spin1",IDC_FORCEOPEN,"msctls_updown32",UDS_SETBUDDYINT | - UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,132,34, - 11,13 -END - -IDD_IGNORE_OPTIONS DIALOGEX 1, 15, 314, 229 -STYLE DS_FIXEDSYS | WS_CHILD -EXSTYLE WS_EX_CONTROLPARENT -FONT 8, "MS Shell Dlg" -BEGIN - LTEXT "The following events are being ignored:",IDC_STATIC,13, - 17,288,8 - ICON "IDI_RECVMSG",IDC_MSGICON,17,177,20,20,SS_CENTERIMAGE - LTEXT "Ignore messages",IDC_STATIC,35,183,70,8,SS_NOPREFIX | - SS_CENTERIMAGE - ICON "IDI_URL",IDC_URLICON,17,192,20,20,SS_CENTERIMAGE - LTEXT "Ignore URLs",IDC_STATIC,35,201,70,8,SS_NOPREFIX | - SS_CENTERIMAGE - ICON "IDI_FILE",IDC_FILEICON,121,177,20,20,SS_CENTERIMAGE - LTEXT "Ignore files",IDC_STATIC,139,183,70,8,SS_NOPREFIX | - SS_CENTERIMAGE - ICON "IDI_MIRANDA",IDC_OTHERICON,121,193,20,20,SS_CENTERIMAGE - LTEXT "Ignore others",IDC_STATIC,139,201,69,8,SS_NOPREFIX | - SS_CENTERIMAGE - ICON "IDI_FILLEDBLOB",IDC_ALLICON,217,178,20,20, - SS_CENTERIMAGE - LTEXT "Ignore all",IDC_STATIC,234,185,64,8,SS_NOPREFIX | - SS_CENTERIMAGE - ICON "IDI_EMPTYBLOB",IDC_NONEICON,217,191,20,20, - SS_CENTERIMAGE - LTEXT "Ignore none",IDC_STATIC,234,201,63,8,SS_NOPREFIX | - SS_CENTERIMAGE - CONTROL "",IDC_LIST,"CListControl",WS_TABSTOP | 0x3da,13,30,286, - 142,WS_EX_CLIENTEDGE - GROUPBOX "Ignore",IDC_STATIC,7,4,300,217 -END - -IDD_XSTATUSES DIALOG DISCARDABLE 175, 60, 175, 204 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Set xStatus list" -FONT 8, "MS Sans Serif" -BEGIN - DEFPUSHBUTTON "OK",IDC_OKXST,118,183,50,14 - PUSHBUTTON "Cancel",IDC_CANCELXST,63,183,50,14 - CONTROL "Tree1",IDC_TREE_XSTATUS,"SysTreeView32",TVS_DISABLEDRAGDROP | - WS_BORDER | WS_TABSTOP | 0x8000,7,7,161,166 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO DISCARDABLE -BEGIN - IDD_OPTIONS, DIALOG - BEGIN - RIGHTMARGIN, 317 - END - - IDD_BASIC_OPTIONS, DIALOG - BEGIN - BOTTOMMARGIN, 220 - END - - IDD_THEME_OPTIONS, DIALOG - BEGIN - BOTTOMMARGIN, 220 - END - - IDD_PROCESSES, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 169 - TOPMARGIN, 7 - BOTTOMMARGIN, 91 - END - - IDD_EVENTLEDS, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 169 - TOPMARGIN, 7 - BOTTOMMARGIN, 104 - END - - IDD_OPT_KN_ACTION, DIALOG - BEGIN - RIGHTMARGIN, 186 - VERTGUIDE, 7 - BOTTOMMARGIN, 55 - HORZGUIDE, 7 - END - - IDD_XSTATUSES, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 168 - TOPMARGIN, 7 - BOTTOMMARGIN, 197 - END -END -#endif // APSTUDIO_INVOKED - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - -///////////////////////////////////////////////////////////////////////////// -// French (Canada) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRC) -#ifdef _WIN32 -LANGUAGE LANG_FRENCH, SUBLANG_FRENCH_CANADIAN -#pragma code_page(1252) -#endif //_WIN32 - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE DISCARDABLE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE DISCARDABLE -BEGIN - "#include ""afxres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE DISCARDABLE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -#endif // French (Canada) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/plugins/KeyboardNotify/src/AggressiveOptimize.h b/plugins/KeyboardNotify/src/AggressiveOptimize.h new file mode 100644 index 0000000000..34c6074320 --- /dev/null +++ b/plugins/KeyboardNotify/src/AggressiveOptimize.h @@ -0,0 +1,165 @@ +////////////////////////////// +// Version 1.40 +// October 22nd, 2002 - .NET (VC7, _MSC_VER=1300) support! +// Version 1.30 +// Nov 24th, 2000 +// Version 1.20 +// Jun 9th, 2000 +// Version 1.10 +// Jan 23rd, 2000 +// Version 1.00 +// May 20th, 1999 +// Todd C. Wilson, Fresh Ground Software +// (todd@nopcode.com) +// This header file will kick in settings for Visual C++ 5 and 6 that will (usually) +// result in smaller exe's. +// The "trick" is to tell the compiler to not pad out the function calls; this is done +// by not using the /O1 or /O2 option - if you do, you implicitly use /Gy, which pads +// out each and every function call. In one single 500k dll, I managed to cut out 120k +// by this alone! +// The other two "tricks" are telling the Linker to merge all data-type segments together +// in the exe file. The relocation, read-only (constants) data, and code section (.text) +// sections can almost always be merged. Each section merged can save 4k in exe space, +// since each section is padded out to 4k chunks. This is very noticeable with smaller +// exes, since you could have only 700 bytes of data, 300 bytes of code, 94 bytes of +// strings - padded out, this could be 12k of runtime, for 1094 bytes of stuff! For larger +// programs, this is less overall, but can save at least 4k. +// Note that if you're using MFC static or some other 3rd party libs, you may get poor +// results with merging the readonly (.rdata) section - the exe may grow larger. +// To use this feature, define _MERGE_RDATA_ in your project or before this header is used. +// With Visual C++ 5, the program uses a file alignment of 512 bytes, which results +// in a small exe. Under VC6, the program instead uses 4k, which is the same as the +// section size. The reason (from what I understand) is that 4k is the chunk size of +// the virtual memory manager, and that WinAlign (an end-user tuning tool for Win98) +// will re-align the programs on this boundary. The problem with this is that all of +// Microsoft's system exes and dlls are *NOT* tuned like this, and using 4k causes serious +// exe bloat. This is very noticeable for smaller programs. +// The "trick" for this is to use the undocumented FILEALIGN linker parm to change the +// padding from 4k to 1/2k, which results in a much smaller exe - anywhere from 20%-75% +// depending on the size. Note that this is the same as using /OPT:NOWIN98, which *is* +// a previously documented switch, but was left out of the docs for some reason in VC6 and +// all of the current MSDN's - see KB:Q235956 for more information. +// Microsoft does say that using the 4k alignment will "speed up process loading", +// but I've been unable to notice a difference, even on my P180, with a very large (4meg) exe. +// Please note, however, that this will probably not change the size of the COMPRESSED +// file (either in a .zip file or in an install archive), since this 4k is all zeroes and +// gets compressed away. +// Also, the /ALIGN:4096 switch will "magically" do the same thing, even though this is the +// default setting for this switch. Apparently this sets the same values as the above two +// switches do. We do not use this in this header, since it smacks of a bug and not a feature. +// Thanks to Michael Geary for some additional tips! +// +// Notes about using this header in .NET +// First off, VC7 does not allow a lot of the linker command options in pragma's. There is no +// honest or good reason why Microsoft decided to make this change, it just doesn't. +// So that is why there are a lot of <1300 #if's in the header. +// If you want to take full advantage of the VC7 linker options, you will need to do it on a +// PER PROJECT BASIS; you can no longer use a global header file like this to make it better. +// Items I strongly suggest putting in all your VC7 project linker options command line settings: +// /ignore:4078 /RELEASE +// Compiler options: +// /GL (Whole Program Optimization) +// If you're making an .EXE and not a .DLL, consider adding in: +// /GA (Optimize for Windows Application) +// Some items to consider using in your VC7 projects (not VC6): +// Link-time Code Generation - whole code optimization. Put this in your exe/dll project link settings. +// /LTCG:NOSTATUS +// The classic no-padding and no-bloat compiler C/C++ switch: +// /opt:nowin98 +// +// (C++ command line options: /GL /opt:nowin98 and /GA for .exe files) +// (Link command line options: /ignore:4078 /RELEASE /LTCG:NOSTATUS) +// +// Now, notes on using these options in VC7 vs VC6. +// VC6 consistently, for me, produces smaller code from C++ the exact same sources, +// with or without this header. On average, VC6 produces 5% smaller binaries compared +// to VC7 compiling the exact same project, *without* this header. With this header, VC6 +// will make a 13k file, while VC7 will make a 64k one. VC7 is just bloaty, pure and +// simple - all that managed/unmanaged C++ runtimes, and the CLR stuff must be getting +// in the way of code generation. However, template support is better, so there. +// Both VC6 and VC7 show the same end kind of end result savings - larger binary output +// will shave about 2% off, where as smaller projects (support DLL's, cpl's, +// activex controls, ATL libs, etc) get the best result, since the padding is usually +// more than the actual usable code. But again, VC7 does not compile down as small as VC6. +// +// The argument can be made that doing this is a waste of time, since the "zero bytes" +// will be compressed out in a zip file or install archive. Not really - it doesn't matter +// if the data is a string of zeroes or ones or 85858585 - it will still take room (20 bytes +// in a zip file, 29 bytes if only *4* of them 4k bytes are not the same) and time to +// compress that data and decompress it. Also, 20k of zeros is NOT 20k on disk - it's the +// size of the cluster slop- for Fat32 systems, 20k can be 32k, NTFS could make it 24k if you're +// just 1 byte over (round up). Most end users do not have the dual P4 Xeon systems with +// two gigs of RDram and a Raid 0+1 of Western Digital 120meg Special Editions that all +// worthy developers have (all six of us), so they will need any space and LOADING TIME +// savings they will need; taking an extra 32k or more out of your end user's 64megs of +// ram on Windows 98 is Not a Good Thing. +// +// Now, as a ADDED BONUS at NO EXTRA COST TO YOU! Under VC6, using the /merge:.text=.data +// pragma will cause the output file to be un-disassembleable! (is that a word?) At least, +// with the normal tools - WinDisam, DumpBin, and the like will not work. Try it - use the +// header, compile release, and then use DUMPBIN /DISASM filename.exe - no code! +// Thanks to Gëzim Pani for discovering this gem - for a full writeup on +// this issue and the ramifactions of it, visit www.nopcode.com for the Aggressive Optimize +// article. + +#ifndef _AGGRESSIVEOPTIMIZE_H_ +#define _AGGRESSIVEOPTIMIZE_H_ + +#pragma warning(disable:4711) + +#ifdef NDEBUG +// /Og (global optimizations), /Os (favor small code), /Oy (no frame pointers) +#pragma optimize("gsy",on) + +#if (_MSC_VER<1300) + #pragma comment(linker,"/RELEASE") +#endif + +// Note that merging the .rdata section will result in LARGER exe's if you using +// MFC (esp. static link). If this is desirable, define _MERGE_RDATA_ in your project. +//#ifdef _MERGE_RDATA_ +//#pragma comment(linker,"/merge:.rdata=.data") +//#endif // _MERGE_RDATA_ + +//#pragma comment(linker,"/merge:.text=.data") +//#if (_MSC_VER<1300) + // In VC7, this causes problems with the relocation and data tables, so best to not merge them +// #pragma comment(linker,"/merge:.reloc=.data") +//#endif + +// Merging sections with different attributes causes a linker warning, so +// turn off the warning. From Michael Geary. Undocumented, as usual! +#if (_MSC_VER<1300) + // In VC7, you will need to put this in your project settings + #pragma comment(linker,"/ignore:4078") +#endif + +// With Visual C++ 5, you already get the 512-byte alignment, so you will only need +// it for VC6, and maybe later. +#if _MSC_VER >= 1000 + +// Option #1: use /filealign +// Totally undocumented! And if you set it lower than 512 bytes, the program crashes. +// Either leave at 0x200 or 0x1000 +//#pragma comment(linker,"/FILEALIGN:0x200") + +// Option #2: use /opt:nowin98 +// See KB:Q235956 or the READMEVC.htm in your VC directory for info on this one. +// This is our currently preferred option, since it is fully documented and unlikely +// to break in service packs and updates. +#if (_MSC_VER<1300) + // In VC7, you will need to put this in your project settings + #pragma comment(linker,"/opt:nowin98") +#else + +// Option #3: use /align:4096 +// A side effect of using the default align value is that it turns on the above switch. +// Does nothing under Vc7 that /opt:nowin98 doesn't already give you +// #pragma comment(linker,"/ALIGN:512") +#endif + +#endif // _MSC_VER >= 1000 + +#endif // NDEBUG + +#endif // _AGGRESSIVEOPTIMIZE_H_ diff --git a/plugins/KeyboardNotify/src/EnumProc.cpp b/plugins/KeyboardNotify/src/EnumProc.cpp new file mode 100644 index 0000000000..7a5a23f0e3 --- /dev/null +++ b/plugins/KeyboardNotify/src/EnumProc.cpp @@ -0,0 +1,260 @@ +/* + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#define WIN32_LEAN_AND_MEAN + +#include +#include +#include +#include +#include "EnumProc.h" + + +BOOL findFilename(TCHAR *); +TCHAR *filename(TCHAR *); +BOOL WINAPI Enum16(DWORD, WORD, WORD, TCHAR *, TCHAR *, LPARAM); + + +// Globals +extern double dWinVer; +extern BOOL bWindowsNT; +extern PROCESS_LIST ProcessList; + +HINSTANCE hInstLib, hInstLib2; +HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD, DWORD); +BOOL (WINAPI *lpfProcess32First)(HANDLE, LPPROCESSENTRY32); +BOOL (WINAPI *lpfProcess32Next)(HANDLE, LPPROCESSENTRY32); +BOOL (WINAPI *lpfEnumProcesses)(DWORD *, DWORD, DWORD *); +BOOL (WINAPI *lpfEnumProcessModules)(HANDLE, HMODULE *, DWORD, LPDWORD); +DWORD (WINAPI *lpfGetModuleBaseName)(HANDLE, HMODULE, LPTSTR, DWORD); +INT (WINAPI *lpfVDMEnumTaskWOWEx)(DWORD, TASKENUMPROCEX, LPARAM); + + +void LoadProcsLibrary(void) +{ + if (bWindowsNT && dWinVer < 5) { + + if (!(hInstLib = LoadLibraryA("PSAPI.DLL"))) + return; + + if (!(hInstLib2 = LoadLibraryA("VDMDBG.DLL"))) + return; + + lpfEnumProcesses = (BOOL (WINAPI *)(DWORD *, DWORD, DWORD*)) GetProcAddress(hInstLib, "EnumProcesses"); + lpfEnumProcessModules = (BOOL (WINAPI *)(HANDLE, HMODULE *, DWORD, LPDWORD)) GetProcAddress(hInstLib, "EnumProcessModules"); + lpfGetModuleBaseName = (DWORD (WINAPI *)(HANDLE, HMODULE, LPTSTR, DWORD)) GetProcAddress(hInstLib, "GetModuleBaseNameA"); + + lpfVDMEnumTaskWOWEx = (INT (WINAPI *)(DWORD, TASKENUMPROCEX, LPARAM)) GetProcAddress(hInstLib2, "VDMEnumTaskWOWEx"); + } else { + + if (!(hInstLib = LoadLibraryA("Kernel32.DLL"))) + return; + + if (bWindowsNT && !(hInstLib2 = LoadLibraryA("VDMDBG.DLL"))) + return; + + lpfCreateToolhelp32Snapshot = (HANDLE (WINAPI *)(DWORD,DWORD)) GetProcAddress(hInstLib, "CreateToolhelp32Snapshot"); + lpfProcess32First = (BOOL (WINAPI *)(HANDLE,LPPROCESSENTRY32)) GetProcAddress(hInstLib, "Process32First"); + lpfProcess32Next = (BOOL (WINAPI *)(HANDLE,LPPROCESSENTRY32)) GetProcAddress(hInstLib, "Process32Next"); + + if (bWindowsNT) + lpfVDMEnumTaskWOWEx = (INT (WINAPI *)(DWORD, TASKENUMPROCEX, LPARAM)) GetProcAddress(hInstLib2, "VDMEnumTaskWOWEx"); + } +} + + +void UnloadProcsLibrary(void) +{ + if (hInstLib) + FreeLibrary(hInstLib); + if (hInstLib2) + FreeLibrary(hInstLib2); + + hInstLib = hInstLib = NULL; + lpfCreateToolhelp32Snapshot = NULL; + lpfProcess32First = NULL; + lpfProcess32Next = NULL; + lpfEnumProcesses = NULL; + lpfEnumProcessModules = NULL; + lpfGetModuleBaseName = NULL; + lpfVDMEnumTaskWOWEx = NULL; +} + + +BOOL areThereProcessesRunning(void) +{ + HANDLE hSnapShot = NULL; + LPDWORD lpdwPIDs = NULL; + PROCESSENTRY32 procentry; + BOOL bFlag; + DWORD dwSize; + DWORD dwSize2; + DWORD dwIndex; + HMODULE hMod; + HANDLE hProcess; + TCHAR szFileName[MAX_PATH+1]; + + + if (!ProcessList.count) // Process list is empty + return FALSE; + + // If Windows NT 4.0 + if (bWindowsNT && dWinVer < 5) { + + if (!lpfEnumProcesses || !lpfEnumProcessModules || !lpfGetModuleBaseName || !lpfVDMEnumTaskWOWEx) + return FALSE; + + // + // Call the PSAPI function EnumProcesses to get all of the ProcID's currently in the system. + // + // NOTE: In the documentation, the third parameter of EnumProcesses is named cbNeeded, which implies that you + // can call the function once to find out how much space to allocate for a buffer and again to fill the buffer. + // This is not the case. The cbNeeded parameter returns the number of PIDs returned, so if your buffer size is + // zero cbNeeded returns zero. + // + // NOTE: The "HeapAlloc" loop here ensures that we actually allocate a buffer large enough for all the + // PIDs in the system. + // + dwSize2 = 256 * sizeof(DWORD); + do { + if (lpdwPIDs) { + HeapFree(GetProcessHeap(), 0, lpdwPIDs); + dwSize2 *= 2; + } + if (!(lpdwPIDs = (LPDWORD)HeapAlloc(GetProcessHeap(), 0, dwSize2))) + return FALSE; + if (!lpfEnumProcesses(lpdwPIDs, dwSize2, &dwSize)) { + HeapFree(GetProcessHeap(), 0, lpdwPIDs); + return FALSE; + } + } while (dwSize == dwSize2); + + // How many ProcID's did we get? + dwSize /= sizeof(DWORD); + + // Loop through each ProcID. + for (dwIndex = 0; dwIndex < dwSize; dwIndex++) { + TCHAR *szFileNameAux; + szFileName[0] = '\0'; + + // Open the process (if we can... security does not permit every process in the system to be opened). + hProcess = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, FALSE, lpdwPIDs[dwIndex]); + if (hProcess) { + // Here we call EnumProcessModules to get only the first module in the process. This will be the + // EXE module for which we will retrieve the name. + if (lpfEnumProcessModules(hProcess, &hMod, sizeof(hMod), &dwSize2)) { + // Get the module name + if (!lpfGetModuleBaseName(hProcess, hMod, szFileName, sizeof(szFileName))) + szFileName[0] = '\0'; + } + CloseHandle(hProcess); + } + szFileNameAux = filename(szFileName); + + // Search szFileName in user-defined list + if (findFilename(szFileNameAux)) { + HeapFree(GetProcessHeap(), 0, lpdwPIDs); + return TRUE; + } + + // Did we just bump into an NTVDM? + if (!_wcsicmp(szFileNameAux, L"NTVDM.EXE")) { + BOOL bFound = FALSE; + + // Enum the 16-bit stuff. + lpfVDMEnumTaskWOWEx(lpdwPIDs[dwIndex], (TASKENUMPROCEX) Enum16, (LPARAM)&bFound); + + // Did we find any user-defined process? + if (bFound) { + HeapFree(GetProcessHeap(), 0, lpdwPIDs); + return TRUE; + } + } + } + HeapFree(GetProcessHeap(), 0, lpdwPIDs); + + // If any OS other than Windows NT 4.0. + } else { + + if (!lpfProcess32Next || !lpfProcess32First || !lpfCreateToolhelp32Snapshot) + return FALSE; + + // Get a handle to a Toolhelp snapshot of all processes. + if ((hSnapShot = lpfCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) == INVALID_HANDLE_VALUE) + return FALSE; + + // While there are processes, keep looping. + for (procentry.dwSize=sizeof(PROCESSENTRY32), bFlag=lpfProcess32First(hSnapShot, &procentry); bFlag; procentry.dwSize=sizeof(PROCESSENTRY32), bFlag=lpfProcess32Next(hSnapShot, &procentry)) { + TCHAR *szFileNameAux = filename(procentry.szExeFile); + + // Search szFileName in user-defined list + if (findFilename(szFileNameAux)) + return TRUE; + + // Did we just bump into an NTVDM? + if (lpfVDMEnumTaskWOWEx && !_wcsicmp(szFileNameAux, L"NTVDM.EXE")) { + BOOL bFound = FALSE; + + // Enum the 16-bit stuff. + lpfVDMEnumTaskWOWEx(procentry.th32ProcessID, (TASKENUMPROCEX)Enum16, (LPARAM)&bFound); + + // Did we find any user-defined process? + if (bFound) + return TRUE; + } + } + } + + return FALSE; +} + + +BOOL WINAPI Enum16(DWORD dwThreadId, WORD hMod16, WORD hTask16, TCHAR *szModName, TCHAR *szFileName, LPARAM lpUserDefined) +{ + BOOL bRet; + BOOL *pbFound = (BOOL *)lpUserDefined; + + if ((bRet = findFilename(filename(szFileName)))) + *pbFound = TRUE; + + return bRet; +} + + +BOOL findFilename(TCHAR *fileName) +{ + unsigned int i; + + for (i=0; i < ProcessList.count; i++) + if (ProcessList.szFileName[i] && !_wcsicmp(ProcessList.szFileName[i], fileName)) + return TRUE; + + return FALSE; +} + + +TCHAR *filename(TCHAR *fullFileName) +{ + TCHAR *str; + + str = wcsrchr(fullFileName, '\\'); + if (!str) + return fullFileName; + + return ++str; +} \ No newline at end of file diff --git a/plugins/KeyboardNotify/src/EnumProc.h b/plugins/KeyboardNotify/src/EnumProc.h new file mode 100644 index 0000000000..09b3cba8d6 --- /dev/null +++ b/plugins/KeyboardNotify/src/EnumProc.h @@ -0,0 +1,27 @@ +/* + +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. + +*/ + +typedef struct { + unsigned int count; + TCHAR **szFileName; +} PROCESS_LIST; + + +void LoadProcsLibrary(void); +void UnloadProcsLibrary(void); +BOOL areThereProcessesRunning(void); diff --git a/plugins/KeyboardNotify/src/constants.h b/plugins/KeyboardNotify/src/constants.h new file mode 100644 index 0000000000..d50ded6d23 --- /dev/null +++ b/plugins/KeyboardNotify/src/constants.h @@ -0,0 +1,85 @@ +/* + +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. + +*/ + +// Settings values +#define KEYBDMODULE "keybdnotify" +#define FLASH_SAMETIME 0 +#define FLASH_INTURN 1 +#define FLASH_INSEQUENCE 2 +#define FLASH_CUSTOM 3 +#define FLASH_TRILLIAN 4 +#define SEQ_LEFT2RIGHT 0 +#define SEQ_RIGHT2LEFT 1 +#define SEQ_LIKEKIT 2 +#define ACTIVE_MIRANDA 0 +#define ACTIVE_WINDOWS 1 +// Until settings map +#define UNTIL_NBLINKS 1 +#define UNTIL_REATTENDED 2 +#define UNTIL_EVENTSOPEN 4 +#define UNTIL_CONDITIONS 8 + +// Status map +#define MAP_ONLINE 1 +#define MAP_AWAY 2 +#define MAP_NA 4 +#define MAP_OCCUPIED 8 +#define MAP_DND 16 +#define MAP_FREECHAT 32 +#define MAP_INVISIBLE 64 +#define MAP_ONTHEPHONE 128 +#define MAP_OUTTOLUNCH 256 +#define MAP_OFFLINE 512 + +// Default settings +#define DEF_SETTING_ONMSG 1 // 1: Yes, 0: No +#define DEF_SETTING_ONURL 1 // 1: Yes, 0: No +#define DEF_SETTING_ONFILE 1 // 1: Yes, 0: No +#define DEF_SETTING_OTHER 1 // 1: Yes, 0: No +#define DEF_SETTING_FSCREEN 1 // 1: Yes, 0: No +#define DEF_SETTING_SSAVER 1 // 1: Yes, 0: No +#define DEF_SETTING_LOCKED 1 // 1: Yes, 0: No +#define DEF_SETTING_PROCS 0 // 1: Yes, 0: No +#define DEF_SETTING_ACTIVE 1 // 1: Yes, 0: No +#define DEF_SETTING_IFMSGOPEN 1 // 1: Yes, 0: No +#define DEF_SETTING_IFMSGNOTTOP 0 // 1: Yes, 0: No +#define DEF_SETTING_IFMSGOLDER 0 // 1: Yes, 0: No +#define DEF_SETTING_SECSOLDER 10 // Seconds +#define DEF_SETTING_FLASHUNTIL 2 // 1 = After x blinks, 2 = Until Miranda/Windows become active, 4 = Events are opened, 8 = Until end of 'notify when' conditions +#define DEF_SETTING_NBLINKS 4 // Seconds +#define DEF_SETTING_MIRORWIN 0 // 0-1, 0 = Miranda becomes active, 1 = Windows becomes active +#define DEF_SETTING_STATUS 1023 // 1023 = All +#define DEF_SETTING_CHECKTIME 0 // Minutes, 0 = don't check +#define DEF_SETTING_FLASHCAPS 1 // 1: Yes, 0: No +#define DEF_SETTING_FLASHNUM 1 // 1: Yes, 0: No +#define DEF_SETTING_FLASHSCROLL 1 // 1: Yes, 0: No +#define DEF_SETTING_FLASHEFFECT 0 // 0-3, 0 = All together, 1 = In turn, 2 = In sequence, 3 = Custom Theme, 4 = Trillian-like sequences +#define DEF_SETTING_SEQORDER 0 // 0-2, 0 = left to right, 1 = right to left, 2 = left <-> right +#define DEF_SETTING_CUSTOMTHEME 0 // Theme number +#define DEF_SETTING_LEDSMSG 2 // 2: Num Lock +#define DEF_SETTING_LEDSFILE 4 // 2: Caps Lock +#define DEF_SETTING_LEDSURL 1 // 2: Scroll Lock +#define DEF_SETTING_LEDSOTHER 7 // 2: Num Lock + Caps Lock + Scroll Lock +#define DEF_SETTING_STARTDELAY 2 // Seconds +#define DEF_SETTING_FLASHSPEED 3 // 0-5, 0 = really slow, 5 = really fast +#define DEF_SETTING_KEYPRESSES 0 // 1: Yes, 0: No +#define DEF_SETTING_OVERRIDE 0 // 1: Yes, 0: No +#define DEF_SETTING_TESTNUM 2 // Number of sequences to test before stopping +#define DEF_SETTING_TESTSECS 2 // Seconds to test before stopping +#define DEF_SETTING_PROTOCOL 1 // 1: Yes, 0: No +#define DEF_SETTING_XSTATUS 1 // 1: Yes, 0: No diff --git a/plugins/KeyboardNotify/src/flash.cpp b/plugins/KeyboardNotify/src/flash.cpp new file mode 100644 index 0000000000..aa0014a329 --- /dev/null +++ b/plugins/KeyboardNotify/src/flash.cpp @@ -0,0 +1,438 @@ +/* + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#define WIN32_LEAN_AND_MEAN + +#include +#include "flash.h" +#include "keyboard.h" +#include "keypresses.h" +#include "utils.h" +#include "constants.h" +#include +#include + +typedef struct { + unsigned int size; + unsigned int index; + BYTE frame[MAX_PATH]; +} FLASHING_SEQUENCE; + + +// Prototypes +FLASHING_SEQUENCE *getCustomSeq(void); +FLASHING_SEQUENCE *getPredefinedSeq(void); +FLASHING_SEQUENCE *getTrillianSeq(void); +void updateTrillianSeq(void); +static void TestThread(FLASHING_SEQUENCE *); +static void PreviewThread(void *); +FLASHING_SEQUENCE str2FS(TCHAR *); +BYTE KbdChar2Byte(char); +void countUnopenEvents(int *, int *, int *, int *); + +#define Leds2Flash ((BYTE)(bFlashLed[2] + (bFlashLed[0]<<1) + (bFlashLed[1]<<2))) + +// Flashing settings +FLASHING_SEQUENCE *pFS; +BOOL bTemporarilyUseExtern; +extern BYTE bFlashLed[3]; +extern BYTE bFlashEffect; extern BYTE bSequenceOrder; +extern WORD wCustomTheme; +extern BYTE bTrillianLedsMsg; extern BYTE bTrillianLedsURL; extern BYTE bTrillianLedsFile; extern BYTE bTrillianLedsOther; +extern BYTE bEmulateKeypresses; + + +// TestThread/PreviewThread globals +extern int nWaitDelay; extern WORD wStartDelay; +BOOL bTestSemaphore, bPreviewSemaphore, bPreview; + + +void RestoreLEDState(void) +{ + if (bEmulateKeypresses) + keypresses_RestoreLEDState(); + else + ToggleKeyboardLights((BYTE)(LedState(VK_SCROLL) + (LedState(VK_NUMLOCK)<<1) + (LedState(VK_CAPITAL)<<2))); +} + + +BYTE getBlinkingLeds(void) +{ + if (!pFS->size) + return (BYTE)(LedState(VK_SCROLL) + (LedState(VK_NUMLOCK)<<1) + (LedState(VK_CAPITAL)<<2)); + + pFS->index %= pFS->size; + if (bFlashEffect == FLASH_TRILLIAN && !bTemporarilyUseExtern && !pFS->index) + updateTrillianSeq(); + return pFS->frame[pFS->index++]; +} + + +void setFlashingSequence(void) +{ + switch (bFlashEffect) { + case FLASH_CUSTOM: + pFS = getCustomSeq(); + break; + case FLASH_TRILLIAN: + pFS = getTrillianSeq(); + break; + default: + pFS = getPredefinedSeq(); + } + bTemporarilyUseExtern = FALSE; +} + + +FLASHING_SEQUENCE *getCustomSeq(void) +{ + static FLASHING_SEQUENCE Custom = {0}; + + DBVARIANT dbv; + TCHAR customStr[MAX_PATH+1]; + + + customStr[0] = _T('\0'); + if (!DBGetContactSetting(NULL, KEYBDMODULE, fmtDBSettingName("custom%d", wCustomTheme), &dbv)) { + wcscpy(customStr, dbv.pwszVal); + DBFreeVariant(&dbv); + } + + Custom = str2FS(customStr); + + return &Custom; +} + + +FLASHING_SEQUENCE *getPredefinedSeq(void) +{ + static FLASHING_SEQUENCE Predefined = {0}; + + FLASHING_SEQUENCE *pAux; + FLASHING_SEQUENCE SameTime = {2, 0, {7, 0}}; + FLASHING_SEQUENCE InTurn = {2, 0, {3, 4}}; + FLASHING_SEQUENCE InSeq = {3, 0, {2, 4, 1}}; + FLASHING_SEQUENCE InSeqRev = {3, 0, {1, 4, 2}}; + FLASHING_SEQUENCE InSeqKIT = {4, 0, {2, 4, 1, 4}}; + + + if (Leds2Flash < 3 || Leds2Flash == 4) + pAux = &SameTime; + else + switch (bFlashEffect) { + default: + case FLASH_SAMETIME: + pAux = &SameTime; + break; + case FLASH_INTURN: + if (Leds2Flash == 3) // 3 = Num+Scroll + pAux = &InSeq; + else + pAux = &InTurn; + break; + case FLASH_INSEQUENCE: + switch (bSequenceOrder) { + default: + case SEQ_LEFT2RIGHT: + pAux = &InSeq; + break; + case SEQ_RIGHT2LEFT: + pAux = &InSeqRev; + break; + case SEQ_LIKEKIT: + if (Leds2Flash != 7) // 7 = Num+Caps+Scroll + pAux = &InSeq; + else + pAux = &InSeqKIT; + break; + } + break; + } + + Predefined.size = Predefined.index = 0; + for (pAux->index=0; pAux->index < pAux->size; pAux->index++) + if (!pAux->frame[pAux->index] || (pAux->frame[pAux->index] & Leds2Flash)) { + Predefined.size++; + Predefined.frame[Predefined.size - 1] = pAux->frame[pAux->index] & Leds2Flash; + } + + return &Predefined; +} + + +FLASHING_SEQUENCE *getTrillianSeq(void) +{ + static FLASHING_SEQUENCE Trillian = {2, 0, {0, 0}}; + + Trillian.size = 2; + Trillian.index = 0; + + return &Trillian; +} + + +void updateTrillianSeq(void) +{ + int i, msgCount=0, fileCount=0, urlCount=0, otherCount=0; + + pFS->size = 2; + countUnopenEvents(&msgCount, &fileCount, &urlCount, &otherCount); + + if ((bTrillianLedsMsg & Leds2Flash) && (pFS->size + 2 * msgCount) <= MAX_PATH) + for (i=0; i < msgCount; i++) { + pFS->frame[pFS->size++] = bTrillianLedsMsg & Leds2Flash; + pFS->frame[pFS->size++] = 0; + } + + if ((bTrillianLedsFile & Leds2Flash) && (pFS->size + 2 * fileCount) <= MAX_PATH) + for (i=0; i < fileCount; i++) { + pFS->frame[pFS->size++] = bTrillianLedsFile & Leds2Flash; + pFS->frame[pFS->size++] = 0; + } + + if ((bTrillianLedsURL & Leds2Flash) && (pFS->size + 2 * urlCount) <= MAX_PATH) + for (i=0; i < urlCount; i++) { + pFS->frame[pFS->size++] = bTrillianLedsURL & Leds2Flash; + pFS->frame[pFS->size++] = 0; + } + + if ((bTrillianLedsOther & Leds2Flash) && (pFS->size + 2 * otherCount) <= MAX_PATH) + for (i=0; i < otherCount; i++) { + pFS->frame[pFS->size++] = bTrillianLedsOther & Leds2Flash; + pFS->frame[pFS->size++] = 0; + } + +} + + +void useExternSequence(TCHAR *extStr) +{ + static FLASHING_SEQUENCE Extern = {0}; + + TCHAR externStr[MAX_PATH+1]; + + + wcscpy(externStr, extStr); + + Extern = str2FS(normalizeCustomString(externStr)); + + pFS = &Extern; + bTemporarilyUseExtern = TRUE; +} + + +TCHAR *normalizeCustomString(TCHAR *customStr) +{ + int len=0, status=0; + BOOL used[4]; + TCHAR strAux[MAX_PATH+1], *str; + + for (wcscpy(str=strAux, customStr); *str; str++) + switch (*str) { + case _T('['): + if (status == 0) { + status = 1; + customStr[len++] = *str; + used[0] = used [1] = used[2] = used[3] = FALSE; + } + break; + case _T(']'): + if (status == 1) { + status = 0; + customStr[len++] = *str; + } + break; + case _T('0'): + case _T('1'): + case _T('2'): + case _T('3'): + if (status == 0) + customStr[len++] = *str; + else + if (!used[*str - _T('0')]) { + customStr[len++] = *str; + used[*str - _T('0')] = TRUE; + } + break; + } + if (status == 1) + customStr[len++] = _T(']'); + customStr[len] = _T('\0'); + + return customStr; +} + + +TCHAR *getCurrentSequenceString(void) +{ + static TCHAR CurrentSeqString[MAX_PATH+1]; + + unsigned int i; + TCHAR *str; + + + for (i=0, str=CurrentSeqString; i < pFS->size; i++) + switch (pFS->frame[i]) { + case 0: + *(str++) = _T('0'); + break; + case 1: + *(str++) = _T('3'); + break; + case 2: + *(str++) = _T('1'); + break; + case 3: + *(str++) = _T('['); + *(str++) = _T('1'); + *(str++) = _T('3'); + *(str++) = _T(']'); + break; + case 4: + *(str++) = _T('2'); + break; + case 5: + *(str++) = _T('['); + *(str++) = _T('2'); + *(str++) = _T('3'); + *(str++) = _T(']'); + break; + case 6: + *(str++) = _T('['); + *(str++) = _T('1'); + *(str++) = _T('2'); + *(str++) = _T(']'); + break; + case 7: + *(str++) = _T('['); + *(str++) = _T('1'); + *(str++) = _T('2'); + *(str++) = _T('3'); + *(str++) = _T(']'); + } + *str = _T('\0'); + + + return CurrentSeqString; +} + + +void testSequence(TCHAR *testStr) +{ + static FLASHING_SEQUENCE Test = {0}; + + DWORD threadID = 0; + + + if (bTestSemaphore) // we try to avoid concurrent test threads + return; + bTestSemaphore = TRUE; + + Test = str2FS(testStr); + + CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)TestThread, &Test, 0, &threadID); +} + + +static void TestThread(FLASHING_SEQUENCE *pTest) +{ + unsigned int i; + DWORD dwEndTest; + + unsigned int testNum = (unsigned int)DBGetContactSettingByte(NULL, KEYBDMODULE, "testnum", DEF_SETTING_TESTNUM); + unsigned int testSecs = (unsigned int)DBGetContactSettingByte(NULL, KEYBDMODULE, "testsecs", DEF_SETTING_TESTSECS); + + for (i=0, dwEndTest=GetTickCount()+testSecs*1000; i < testNum || GetTickCount() < dwEndTest; i++) + for (pTest->index=0; pTest->index < pTest->size; pTest->index++) { + ToggleKeyboardLights(pTest->frame[pTest->index]); + Sleep(nWaitDelay); + } + + RestoreLEDState(); + + bTestSemaphore = FALSE; +} + + +void previewFlashing(BOOL buttonState) +{ + DWORD threadID = 0; + + bPreview = buttonState; + + if (!bPreview || bPreviewSemaphore) // turn off flashing or already running + return; + + bPreviewSemaphore = TRUE; + CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PreviewThread, NULL, 0, &threadID); +} + + +static void PreviewThread(void *dummy) +{ + unsigned int i; + BYTE unchangedLeds; + + if (wStartDelay > 0) + Sleep(wStartDelay * 1000); + + unchangedLeds = (BYTE)(LedState(VK_SCROLL) * !bFlashLed[2] + ((LedState(VK_NUMLOCK) * !bFlashLed[0])<<1) + ((LedState(VK_CAPITAL) * !bFlashLed[1])<<2)); + + while (bPreview) + for (i=0; bPreview && i < pFS->size; i++) { + ToggleKeyboardLights((BYTE)(pFS->frame[i%pFS->size]|unchangedLeds)); + Sleep(nWaitDelay); + } + + RestoreLEDState(); + + bPreviewSemaphore = FALSE; +} + + +FLASHING_SEQUENCE str2FS(TCHAR *str) +{ + FLASHING_SEQUENCE Temp = {0}; + + for (Temp.size=Temp.index=0; *str; str++) { + Temp.size++; + if (*str == _T('[')) { + Temp.frame[Temp.size - 1] = 0; + for (str++; *str && *str != _T(']'); str++) + Temp.frame[Temp.size - 1] += KbdChar2Byte(*str) & Leds2Flash; + if (!*str) break; + } else + Temp.frame[Temp.size - 1] = KbdChar2Byte(*str) & Leds2Flash; + } + + return Temp; +} + + +BYTE KbdChar2Byte(char kbdChar) +{ + switch (kbdChar) { + case '1': //NumLock + return 2; + case '2': //CapsLock + return 4; + case '3': //ScrollLock + return 1; + } + return 0; +} diff --git a/plugins/KeyboardNotify/src/flash.h b/plugins/KeyboardNotify/src/flash.h new file mode 100644 index 0000000000..f60706fc76 --- /dev/null +++ b/plugins/KeyboardNotify/src/flash.h @@ -0,0 +1,28 @@ +/* + +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. + +*/ + +void RestoreLEDState(void); +BYTE getBlinkingLeds(void); +void setFlashingSequence(void); +void useExternSequence(TCHAR *); +TCHAR *normalizeCustomString(TCHAR *); +TCHAR *getCurrentSequenceString(void); +void testSequence(TCHAR *); +void previewFlashing(BOOL); + +#define LedState(a) (((BYTE)(GetKeyState(a) & 0xffff))!=0) diff --git a/plugins/KeyboardNotify/src/ignore.cpp b/plugins/KeyboardNotify/src/ignore.cpp new file mode 100644 index 0000000000..57fcceb8a6 --- /dev/null +++ b/plugins/KeyboardNotify/src/ignore.cpp @@ -0,0 +1,389 @@ +/* + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#define WIN32_LEAN_AND_MEAN + +#include +#include +#include +#include +#include +#include "ignore.h" +#include "resource.h" +#include "constants.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define IGNOREEVENT_MAX 4 +#define IDI_SMALLDOT 211 +#define IDI_FILLEDBLOB 212 +#define IDI_EMPTYBLOB 213 + +#define SIZEOF(a) (sizeof(a) / sizeof(a[0])) + +static const DWORD ignoreIdToPf1[IGNOREEVENT_MAX] = {PF1_IMRECV, PF1_URLRECV, PF1_FILERECV, 0xFFFFFFFF}; + +extern double dWinVer; +extern BOOL bWindowsNT; + + +static DWORD GetMask(HANDLE hContact) +{ + DWORD mask = DBGetContactSettingDword(hContact, KEYBDMODULE, "Mask1", (DWORD)(-1)); + if(mask == (DWORD)(-1)) { + if(hContact == NULL) + mask=0; + else { + if(DBGetContactSettingByte(hContact, "CList", "Hidden", 0) || DBGetContactSettingByte(hContact, "CList", "NotOnList", 0)) + mask = DBGetContactSettingDword(NULL, KEYBDMODULE, "Mask1", 0); + else + mask = DBGetContactSettingDword(NULL, KEYBDMODULE, "Default1", 0); + } + } + return mask; +} + +static void SetListGroupIcons(HWND hwndList, HANDLE hFirstItem, HANDLE hParentItem, int *groupChildCount) +{ + int typeOfFirst; + int iconOn[IGNOREEVENT_MAX]={1,1,1,1}; + int childCount[IGNOREEVENT_MAX]={0,0,0,0}, i; + int iImage; + HANDLE hItem, hChildItem; + + typeOfFirst = SendMessage(hwndList, CLM_GETITEMTYPE, (WPARAM)hFirstItem, 0); + //check groups + if(typeOfFirst == CLCIT_GROUP) + hItem = hFirstItem; + else + hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTGROUP, (LPARAM)hFirstItem); + while(hItem) { + hChildItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_CHILD, (LPARAM)hItem); + if(hChildItem) + SetListGroupIcons(hwndList, hChildItem, hItem, childCount); + for(i=0; i < SIZEOF(iconOn); i++) + if(iconOn[i] && SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, i) == 0) + iconOn[i] = 0; + hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTGROUP, (LPARAM)hItem); + } + //check contacts + if(typeOfFirst == CLCIT_CONTACT) + hItem = hFirstItem; + else + hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTCONTACT, (LPARAM)hFirstItem); + while(hItem) { + for(i=0; i < SIZEOF(iconOn); i++) { + iImage = SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, i); + if(iconOn[i] && iImage == 0) + iconOn[i] = 0; + if(iImage != 0xFF) + childCount[i]++; + } + hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTCONTACT, (LPARAM)hItem); + } + //set icons + for(i=0; i < SIZEOF(iconOn); i++) { + SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hParentItem, MAKELPARAM(i, childCount[i]?(iconOn[i]?i+3:0):0xFF)); + if(groupChildCount) + groupChildCount[i] += childCount[i]; + } + SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hParentItem, MAKELPARAM(IGNOREEVENT_MAX, 1)); + SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hParentItem, MAKELPARAM(IGNOREEVENT_MAX+1, 2)); +} + +static void SetAllChildIcons(HWND hwndList, HANDLE hFirstItem, int iColumn, int iImage) +{ + int typeOfFirst, iOldIcon; + HANDLE hItem, hChildItem; + + typeOfFirst = SendMessage(hwndList,CLM_GETITEMTYPE,(WPARAM)hFirstItem, 0); + //check groups + if(typeOfFirst == CLCIT_GROUP) + hItem = hFirstItem; + else + hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTGROUP, (LPARAM)hFirstItem); + while(hItem) { + hChildItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_CHILD, (LPARAM)hItem); + if(hChildItem) + SetAllChildIcons(hwndList, hChildItem, iColumn, iImage); + hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTGROUP, (LPARAM)hItem); + } + //check contacts + if(typeOfFirst == CLCIT_CONTACT) + hItem = hFirstItem; + else + hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTCONTACT, (LPARAM)hFirstItem); + while(hItem) { + iOldIcon = SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, iColumn); + if(iOldIcon != 0xFF && iOldIcon != iImage) + SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(iColumn, iImage)); + hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_NEXTCONTACT, (LPARAM)hItem); + } +} + +static void ResetListOptions(HWND hwndList) +{ + int i; + + SendMessage(hwndList, CLM_SETBKBITMAP, 0, (LPARAM)NULL); + SendMessage(hwndList, CLM_SETBKCOLOR, GetSysColor(COLOR_WINDOW), 0); + SendMessage(hwndList, CLM_SETGREYOUTFLAGS, 0, 0); + SendMessage(hwndList, CLM_SETLEFTMARGIN, 4, 0); + SendMessage(hwndList, CLM_SETINDENT, 10, 0); + SendMessage(hwndList, CLM_SETHIDEEMPTYGROUPS, 1, 0); + for(i=0; i <= FONTID_MAX; i++) + SendMessage(hwndList, CLM_SETTEXTCOLOR, i, GetSysColor(COLOR_WINDOWTEXT)); +} + +static void SetIconsForColumn(HWND hwndList, HANDLE hItem, HANDLE hItemAll, int iColumn, int iImage) +{ + int itemType; + + itemType = SendMessage(hwndList, CLM_GETITEMTYPE, (WPARAM)hItem, 0); + if(itemType == CLCIT_CONTACT) { + int oldiImage = SendMessage(hwndList, CLM_GETEXTRAIMAGE, (WPARAM)hItem, iColumn); + if (oldiImage != 0xFF && oldiImage != iImage) + SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(iColumn, iImage)); + } + else if(itemType == CLCIT_INFO) { + if(hItem == hItemAll) + SetAllChildIcons(hwndList, hItem, iColumn, iImage); + else + SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(iColumn, iImage)); //hItemUnknown + } + else if(itemType == CLCIT_GROUP) { + hItem = (HANDLE)SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_CHILD, (LPARAM)hItem); + if(hItem) + SetAllChildIcons(hwndList, hItem, iColumn, iImage); + } +} + +static void InitialiseItem(HWND hwndList, HANDLE hContact, HANDLE hItem, DWORD protoCaps) +{ + DWORD mask; + int i; + + mask = GetMask(hContact); + for(i=0; i < IGNOREEVENT_MAX; i++) + if(ignoreIdToPf1[i] == 0xFFFFFFFF || protoCaps & ignoreIdToPf1[i]) + SendMessage(hwndList, CLM_SETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(i, mask&(1<= 5.01)?ILC_COLOR32:ILC_COLOR16)|ILC_MASK, 3+IGNOREEVENT_MAX, 3+IGNOREEVENT_MAX); + ImageList_AddIcon(hIml, LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_SMALLDOT))); + ImageList_AddIcon(hIml, LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_FILLEDBLOB))); + ImageList_AddIcon(hIml, LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_EMPTYBLOB))); + ImageList_AddIcon(hIml, LoadSkinnedIcon(SKINICON_EVENT_MESSAGE)); + ImageList_AddIcon(hIml, LoadSkinnedIcon(SKINICON_EVENT_URL)); + ImageList_AddIcon(hIml, LoadSkinnedIcon(SKINICON_EVENT_FILE)); + ImageList_AddIcon(hIml, LoadSkinnedIcon(SKINICON_OTHER_MIRANDA)); + SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_SETEXTRAIMAGELIST, 0, (LPARAM)hIml); + for(i=0; i < SIZEOF(hIcons); i++) + hIcons[i] = ImageList_GetIcon(hIml, 1+i, ILD_NORMAL); + } + SendDlgItemMessage(hwndDlg, IDC_ALLICON, STM_SETICON, (WPARAM)hIcons[0], 0); + SendDlgItemMessage(hwndDlg, IDC_NONEICON, STM_SETICON, (WPARAM)hIcons[1], 0); + SendDlgItemMessage(hwndDlg, IDC_MSGICON, STM_SETICON, (WPARAM)hIcons[2], 0); + SendDlgItemMessage(hwndDlg, IDC_URLICON, STM_SETICON, (WPARAM)hIcons[3], 0); + SendDlgItemMessage(hwndDlg, IDC_FILEICON, STM_SETICON, (WPARAM)hIcons[4], 0); + SendDlgItemMessage(hwndDlg, IDC_OTHERICON, STM_SETICON, (WPARAM)hIcons[5], 0); + + SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_LIST), GWL_STYLE, GetWindowLongPtr(GetDlgItem(hwndDlg, IDC_LIST), GWL_STYLE) &~ (CLS_CHECKBOXES|CLS_GROUPCHECKBOXES)); + SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_AUTOREBUILD, 0, 0); + + ResetListOptions(GetDlgItem(hwndDlg, IDC_LIST)); + SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_SETEXTRACOLUMNS, IGNOREEVENT_MAX+2, 0); + + { CLCINFOITEM cii = {0}; + cii.cbSize = sizeof(cii); + cii.flags = CLCIIF_GROUPFONT; + cii.pszText = TranslateT("** All contacts **"); + hItemAll=(HANDLE)SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_ADDINFOITEM, 0, (LPARAM)&cii); + + cii.pszText = TranslateT("** Unknown contacts **"); + hItemUnknown=(HANDLE)SendDlgItemMessage(hwndDlg, IDC_LIST,CLM_ADDINFOITEM, 0, (LPARAM)&cii); + InitialiseItem(GetDlgItem(hwndDlg, IDC_LIST), NULL, hItemUnknown, 0xFFFFFFFF); + } + + SetAllContactIcons(GetDlgItem(hwndDlg, IDC_LIST)); + SetListGroupIcons(GetDlgItem(hwndDlg, IDC_LIST),(HANDLE)SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_GETNEXTITEM, CLGN_ROOT, 0), hItemAll, NULL); + return TRUE; + case WM_SETFOCUS: + SetFocus(GetDlgItem(hwndDlg, IDC_LIST)); + break; + case WM_NOTIFY: + switch(((LPNMHDR)lParam)->idFrom) { + case IDC_LIST: + switch (((LPNMHDR)lParam)->code) + { + case CLN_NEWCONTACT: + case CLN_LISTREBUILT: + SetAllContactIcons(GetDlgItem(hwndDlg, IDC_LIST)); + //fall through + case CLN_CONTACTMOVED: + SetListGroupIcons(GetDlgItem(hwndDlg, IDC_LIST), (HANDLE)SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_GETNEXTITEM, CLGN_ROOT, 0), hItemAll, NULL); + break; + case CLN_OPTIONSCHANGED: + ResetListOptions(GetDlgItem(hwndDlg, IDC_LIST)); + break; + case CLN_CHECKCHANGED: + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + break; + case NM_CLICK: + { int iImage; + HANDLE hItem; + DWORD hitFlags; + NMCLISTCONTROL *nm = (NMCLISTCONTROL*)lParam; + + if(nm->iColumn == -1) + break; + hItem = (HANDLE)SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_HITTEST, (WPARAM)&hitFlags, MAKELPARAM(nm->pt.x, nm->pt.y)); + if(hItem == NULL) + break; + if (!(hitFlags & CLCHT_ONITEMEXTRA)) + break; + if(nm->iColumn == IGNOREEVENT_MAX) { //ignore all + for(iImage=0; iImage < IGNOREEVENT_MAX; iImage++) + SetIconsForColumn(GetDlgItem(hwndDlg, IDC_LIST), hItem, hItemAll, iImage, iImage+3); + } + else if(nm->iColumn == IGNOREEVENT_MAX+1) { //ignore none + for(iImage=0; iImage < IGNOREEVENT_MAX; iImage++) + SetIconsForColumn(GetDlgItem(hwndDlg, IDC_LIST), hItem, hItemAll, iImage, 0); + } + else { + iImage = SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_GETEXTRAIMAGE, (WPARAM)hItem, MAKELPARAM(nm->iColumn, 0)); + if(iImage == 0) + iImage = nm->iColumn + 3; + else if(iImage != 0xFF) + iImage = 0; + SetIconsForColumn(GetDlgItem(hwndDlg, IDC_LIST), hItem, hItemAll, nm->iColumn, iImage); + } + SetListGroupIcons(GetDlgItem(hwndDlg, IDC_LIST),(HANDLE)SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_GETNEXTITEM, CLGN_ROOT, 0), hItemAll, NULL); + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + break; + } + } + break; + case 0: + switch (((LPNMHDR)lParam)->code) + { + case PSN_APPLY: + { HANDLE hContact, hItem; + + hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDFIRST, 0, 0); + do { + hItem = (HANDLE)SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_FINDCONTACT, (WPARAM)hContact, 0); + if(hItem) + SaveItemMask(GetDlgItem(hwndDlg, IDC_LIST), hContact, hItem, "Mask1"); + } while(hContact = (HANDLE)CallService(MS_DB_CONTACT_FINDNEXT, (WPARAM)hContact, 0)); + SaveItemMask(GetDlgItem(hwndDlg, IDC_LIST), NULL, hItemAll, "Default1"); + SaveItemMask(GetDlgItem(hwndDlg, IDC_LIST), NULL, hItemUnknown, "Mask1"); + return TRUE; + } + } + break; + } + break; + case WM_DESTROY: + { int i; + HIMAGELIST hIml; + for(i=0; i < SIZEOF(hIcons); i++) + DestroyIcon(hIcons[i]); + hIml = (HIMAGELIST)SendDlgItemMessage(hwndDlg, IDC_LIST, CLM_GETEXTRAIMAGELIST, 0, 0); + ImageList_Destroy(hIml); + break; + } + } + return FALSE; +} + +BOOL IsIgnored(HANDLE hContact, WORD eventType) +{ + WORD ignoreID = 0; + DWORD mask = GetMask(hContact); + + switch(eventType) { + case EVENTTYPE_MESSAGE: + ignoreID = 0; + break; + case EVENTTYPE_URL: + ignoreID = 1; + break; + case EVENTTYPE_FILE: + ignoreID = 2; + break; + default: + ignoreID = 3; + } + + return (mask>>ignoreID)&1; +} diff --git a/plugins/KeyboardNotify/src/ignore.h b/plugins/KeyboardNotify/src/ignore.h new file mode 100644 index 0000000000..a72df7b6f6 --- /dev/null +++ b/plugins/KeyboardNotify/src/ignore.h @@ -0,0 +1,20 @@ +/* + +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. + +*/ + +BOOL IsIgnored(HANDLE, WORD); +INT_PTR CALLBACK DlgProcIgnoreOptions(HWND, UINT, WPARAM, LPARAM); diff --git a/plugins/KeyboardNotify/src/keyboard.cpp b/plugins/KeyboardNotify/src/keyboard.cpp new file mode 100644 index 0000000000..df1033fce7 --- /dev/null +++ b/plugins/KeyboardNotify/src/keyboard.cpp @@ -0,0 +1,120 @@ +/* + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#define WIN32_LEAN_AND_MEAN + +#include +#include +#include +#include "keypresses.h" +#include +#include + + +// Globals +extern BOOL bWindowsNT; +extern BYTE bEmulateKeypresses; +HANDLE hKbdDev[10] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE}; + +// Defines +#define MAX_KBDHANDLES 10 +#define IOCTL_KEYBOARD_SET_INDICATORS CTL_CODE(FILE_DEVICE_KEYBOARD, 0x0002, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_KEYBOARD_QUERY_TYPEMATIC CTL_CODE(FILE_DEVICE_KEYBOARD, 0x0008, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_KEYBOARD_QUERY_INDICATORS CTL_CODE(FILE_DEVICE_KEYBOARD, 0x0010, METHOD_BUFFERED, FILE_ANY_ACCESS) + +typedef struct _KEYBOARD_INDICATOR_PARAMETERS { + USHORT UnitId; // Unit identifier. + USHORT LedFlags; // LED indicator state. + +} KEYBOARD_INDICATOR_PARAMETERS, *PKEYBOARD_INDICATOR_PARAMETERS; + + +void outportb(UINT portid, BYTE value) +{ + #if !defined( _WIN64 ) + __asm mov edx,portid + __asm mov al,value + __asm out dx,al + #endif +} + + +BOOL OpenKeyboardDevice() +{ + int i = 0; + TCHAR aux1[MAX_PATH+1], aux2[MAX_PATH+1]; + + if (!bWindowsNT) + return TRUE; + + do { + _snwprintf(aux1, sizeof(aux1), _T("Kbd%d"), i); + _snwprintf(aux2, sizeof(aux2), _T("\\Device\\KeyboardClass%d"), i); + DefineDosDevice(DDD_RAW_TARGET_PATH, aux1, aux2); + + _snwprintf(aux1, sizeof(aux1), _T("\\\\.\\Kbd%d"), i); + hKbdDev[i] = CreateFile(aux1, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + + } while (hKbdDev[i] != INVALID_HANDLE_VALUE && ++i < MAX_KBDHANDLES); + + return hKbdDev[0] != INVALID_HANDLE_VALUE; +} + +BOOL ToggleKeyboardLights(BYTE byte) +{ + int i; BOOL result = FALSE; + KEYBOARD_INDICATOR_PARAMETERS InputBuffer; // Input buffer for DeviceIoControl + ULONG DataLength = sizeof(KEYBOARD_INDICATOR_PARAMETERS); + ULONG ReturnedLength; // Number of bytes returned in output buffer + + if (bEmulateKeypresses) + return keypresses_ToggleKeyboardLights(byte); + + if (!bWindowsNT) { + outportb(0x60, 0xED); + Sleep(10); + outportb(0x60, byte); + return TRUE; + } + + InputBuffer.UnitId = 0; + InputBuffer.LedFlags = byte; + + for (i=0; i < MAX_KBDHANDLES && hKbdDev[i] != INVALID_HANDLE_VALUE; i++) + result |= DeviceIoControl(hKbdDev[i], IOCTL_KEYBOARD_SET_INDICATORS, &InputBuffer, DataLength, NULL, 0, &ReturnedLength, NULL); + + return result; +} + +void CloseKeyboardDevice() +{ + int i = 0; + TCHAR aux[MAX_PATH+1]; + + if (!bWindowsNT) + return; + + do { + if (hKbdDev[i] != INVALID_HANDLE_VALUE) + CloseHandle(hKbdDev[i]); + + _snwprintf(aux, sizeof(aux), _T("Kbd%d"), i); + DefineDosDevice(DDD_REMOVE_DEFINITION, aux, NULL); + + } while (hKbdDev[i] != INVALID_HANDLE_VALUE && ++i < MAX_KBDHANDLES); +} diff --git a/plugins/KeyboardNotify/src/keyboard.h b/plugins/KeyboardNotify/src/keyboard.h new file mode 100644 index 0000000000..8fe6b52fe9 --- /dev/null +++ b/plugins/KeyboardNotify/src/keyboard.h @@ -0,0 +1,21 @@ +/* + +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. + +*/ + +BOOL OpenKeyboardDevice(void); +BOOL ToggleKeyboardLights(BYTE); +void CloseKeyboardDevice(void); diff --git a/plugins/KeyboardNotify/src/keypresses.cpp b/plugins/KeyboardNotify/src/keypresses.cpp new file mode 100644 index 0000000000..6d1cef58e6 --- /dev/null +++ b/plugins/KeyboardNotify/src/keypresses.cpp @@ -0,0 +1,77 @@ +/* + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#define WIN32_LEAN_AND_MEAN +#define _WIN32_WINNT 0x0500 + +#include +#include "flash.h" +#include "keypresses.h" + + +// Prototypes +void SetLock(WORD, BYTE, unsigned int *, INPUT *); + +// Globals +BOOL LEDstateSaved = FALSE; +BYTE LEDstate; + + +void keypresses_RestoreLEDState(void) +{ + if (LEDstateSaved) + keypresses_ToggleKeyboardLights(LEDstate); + LEDstateSaved = FALSE; +} + +BOOL keypresses_ToggleKeyboardLights(BYTE byte) +{ + unsigned int n = 0; + INPUT keystrokes[6] = {0}; + + if (!LEDstateSaved) { + LEDstate = (BYTE)(LedState(VK_SCROLL) + (LedState(VK_NUMLOCK)<<1) + (LedState(VK_CAPITAL)<<2)); + LEDstateSaved = TRUE; + } + + SetLock(VK_NUMLOCK, (BYTE)(byte&2), &n, keystrokes); + SetLock(VK_CAPITAL, (BYTE)(byte&4), &n, keystrokes); + SetLock(VK_SCROLL, (BYTE)(byte&1), &n, keystrokes); + SendInput(n, keystrokes, sizeof(INPUT)); + + return TRUE; +} + +void SetLock(WORD keyCode, BYTE value, unsigned int *n, INPUT *keystrokes) +{ + BYTE status; + + GetAsyncKeyState(keyCode); + status = GetKeyState(keyCode) & 1; + + if ((!value && status) || (value && !status)) { + keystrokes[*n].type = INPUT_KEYBOARD; + keystrokes[*n].ki.wVk = keyCode; + keystrokes[*n].ki.wScan = 0x45; + keystrokes[(*n)++].ki.dwFlags = KEYEVENTF_EXTENDEDKEY | 0; + keystrokes[*n].type = INPUT_KEYBOARD; + keystrokes[*n].ki.wVk = keyCode; + keystrokes[*n].ki.wScan = 0x45; + keystrokes[(*n)++].ki.dwFlags = KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP; + } +} diff --git a/plugins/KeyboardNotify/src/keypresses.h b/plugins/KeyboardNotify/src/keypresses.h new file mode 100644 index 0000000000..57e99aa25c --- /dev/null +++ b/plugins/KeyboardNotify/src/keypresses.h @@ -0,0 +1,20 @@ +/* + +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. + +*/ + +void keypresses_RestoreLEDState(void); +BOOL keypresses_ToggleKeyboardLights(BYTE); diff --git a/plugins/KeyboardNotify/src/main.cpp b/plugins/KeyboardNotify/src/main.cpp new file mode 100644 index 0000000000..e82cc2cfdc --- /dev/null +++ b/plugins/KeyboardNotify/src/main.cpp @@ -0,0 +1,1448 @@ +/* + KeyboardNotify plugin v1.5 for Miranda IM + _________________________________________ + + Copyright (C) 2002,2003 Martin Öberg + Copyright (C) 2004 Std + Copyright (C) 2005,2006 TioDuke (tioduke@yahoo.ca) + + + 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. + + + Description + ----------- + This plugin for Miranda-IM notifies user of specified events (as incoming messages, + incoming files, incoming URLs or other events). This plugin is based on the original one + by Martin Öberg (aka strickz) and Std's modifications (mainly the idea of using direct + port handling using a driver). + It has many options allowing: + a) To select on which events to react + b) Under which conditions (eg: fullscreen mode, ScreenSaver running, workstation locked) + c) To act only if the protocol receiving the event is under specified status + d) For message events you can choose to be notified if the message window is open or not + e) A notification feature allowing to be notified of pending events (unopen events) + after specified period of time + f) To select method for stopping the blinking (after x secs, if Miranda is re-attended, + if Windows is re-attended, if all notified events are opened or when the notify conditions + end) + g) And several flashing options: select leds to blink, effects (all at the same time, + in turn, in sequence and like KITT!), preview button + It was designed to be flexible and performing several different tasks. It can be + configured to act like the original one and has several functions from other Miranda's + keyboard notifier plugins. + It also provides a service to allow third party plugins use its notifier abilities. + + Options + ------- + Options page Options->Plugins->Keyboard Flash. Tabbed: Protocols, Rules (when), Flashing (how), Themes and Ignore. + + Thanks + ------ + - Pete for the numerous patches he sent, actively helping to improve the code and + functionality + - UnregistereD for great help in solving problem with Windows activity detection + - Slacktarn, Sir_qwerty and Tweety for giving great help with ideas (most of the new + features included in this plugin were suggested by them) and testing + - The authors of AAA, PopUp+, KeyScrollNotify, original KeyboardNotify, Neweventnotify, + IEView, NGEventNotify for part of their code used in this plugin. + - Vampik fot the InTurn flashing option + - Miranda IM developers for this amazing program + - all other people from Miranda community + + History + ------- + 1.5.7.7: + [!] Added support for Miranda 0.8.x.x. + 1.5.7.6: + [!] Fixed bug in Ignore module. + 1.5.7.5: + [!] Updated TriggerPlugin support for latest version. + 1.5.7.4: + [*] Updated screenshot + [*] Minor code cleaning + 1.5.7.3: + [+] Added xstatus support + 1.5.7.2: + [+] Added per contact Ignore options + 1.5.7.1: + [!] Fix in Options for themes under WinXP+ (really essential feature) + 1.5.7.0: + [+] Added support for Trigger plugin + 1.5.6.3: + [-] Removed device presence validation: it is not needed now that the plugin works on USB (thanks Nick, aka Aestetic) + [+] Added a new service to the API for 'normalizing' a custom flashing sequence string + [-] Simplified the API (the extended version of the start blink service is no longer needed). + 1.5.6.2: + [!] Fixed problem while trying to detect if message window is in foreground. + 1.5.6.1: + [!] Fixed bug with keypress emulation and "until Windows is re-attended" option. + 1.5.6.0: + [+] Option to emulate keypresses (for the USB people) + [*] Changed the emergency key (to make it stop with PAUSE instead of SCROLL LOCK key). + 1.5.5.4: + [*] Improved ListView control handling + [*] Changed the default values (for the sake of new users). + 1.5.5.3: + [*] More code optimization. + 1.5.5.2: + [+] Support for Update plugin. + 1.5.5.1: + [!] Minor source fixes. + 1.5.5.0: + [+] New 'notify when' option: while defined programs are running (just like gamerstatus) + [+] Extended the API to add two new services to disable and re-enable keyboard notifications (for use by bosskey plugin). + 1.5.4.4: + [!] Fixed (hopefully) problems with some system configurations (with PS2 keyboards) where the KeyboardClass0 device was not the apropriate one (thanks pete!) + [+] Extended the plugin API (requested bt tweety). + 1.5.4.3: + [!] Fixed some compatibility issues with nconvers++ (thank you donatas for your help). + 1.5.4.2: + [!] Fixed problem with Windows' activity detection under Win9X when using other plugins that do the same. + [!] Fixed crash caused by incoming authorisation requests when metacontacts was enabled. + 1.5.4.1: + [!] Some corrections on third party plugins events handling (now they are more assimilated to the 'other events') + [*] Some code cleaning + [!] Fixed problem with first message in Metacontacts recognition while checking for pending events (thank you again NirG) + 1.5.4.0: + [+] New plugin API (thank you CriS for your ideas and great help) + [!] Added Offline status to status check list (thank you Slaktarn for finding it). + 1.5.3.4: + [!] Fixed Metacontacts recognition in checking and counting of pending events (thank you NirG for finding the problem) + [!] Fixed problems with multiple instances of the plugin running (thank you tweety for reporting and testing). + 1.5.3.3: + [!] Changed behaviour of Preview button to make it independent of the rules' options. + 1.5.3.2: + [+] New dialog to asign leds to specific events for the trillian-like sequences. + 1.5.3.1: + [!] Fixed bug of loosing any other until setting when selecting 'Events are opened'. + 1.5.3.0: + [+] Applied pete's patches (thank you very much for your great work) + - Use of GetLastInputInfo when possible for detecting Windows' activity + - Made Windows' mouse hooks also aware of mouse clicking + - Made Miranda re-attended option react on windows restoring and ignoring mouse hovering an unfocused window + - New option for message events to avoid blinking if message window is focused + - Made the plugin handle metacontact's special issues + [!] Use of the new message API for windows detection when possible + [+] New message event option to check last message timestamp (requested by D46MD) + [+] Possibility of choosing more than one flash until option at the same time + [+] New flashing effect to make the leds blink accordingly to number of events + [+] Possibility of selecting/unselecting protocols (requested by tweety, usuful to avoid flashing on some protocols as rss) + 1.5.2.2: + [!] scriver's message window detection (thanks D46MD for your great help) + [!] corrected 'flash until' checking accordingly to pete's patch (thank you) + 1.5.2.1: + [!] nconvers++'s message window detection + [!] checked window detection for srmm, scriver, sramm and srmm_mod + 1.5.2.0: + [+] Custom theme support + [-] Custom order history + 1.5.1.0: + [+] Custom order effect + [+] Custom order history + 1.5.0.0: + [+] Drivers aren't needed anymore + [+] Status selection option + [+] Miranda/Windows activity detection (thank you Peter Boon) + [+] 'Opened events' stop method + [+] x seconds stop method + [+] Hooking database event for detecting incoming events + [+] Notifier option for pending events + [+] Checkbox for enabling disabling open messages notification + [+] In sequence and KIT flashing effects + [+] Preview button + [+] Tabbed options + [!] Several corrections/improvements in options page + [!] Not selected leds will preserve their original state + 1.4.1.0: (by me and Vampik) + [+] Notify on fullscreen, screensaver, worksation locked + [!] Try to improve Win98 keysimulation routines + [+] Added InTurn effect (thank you Vampik) + [!] Corrected speed of blinking (thank you Vampik) + 1.4.0.0: (by Std, unreleased) + [+] Added direct port handling using PortTalk.sys driver + 1.3.0.0: (by strickz) + This is strickz' final release. It still uses keypress simulation. It was nice (thanks *g*) + + +*/ + +#define WIN32_LEAN_AND_MEAN +#define _WIN32_WINNT 0x0500 + +#include +#include +#include +#include "flash.h" +#include "ignore.h" +#include "keyboard.h" +#include "trigger.h" +#include "constants.h" +#include "protolist.h" +#include "EnumProc.h" +#include "utils.h" +#include "m_kbdnotify.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#pragma comment(lib, "advapi32.lib") + +#define NCONVERS_BLINKID ((HANDLE)123456) //nconvers' random identifier used to flash an icon for "incoming message" on contact list + +#ifndef SPI_GETSCREENSAVERRUNNING +#define SPI_GETSCREENSAVERRUNNING 114 +#endif + +#ifndef WM_XBUTTONDBLCLK +#define WM_XBUTTONDBLCLK 0x020D +#endif +#ifndef WM_NCXBUTTONDBLCLK +#define WM_NCXBUTTONDBLCLK 0x00AD +#endif + + +HINSTANCE hInst; + +int hLangpack; + +DWORD IDThread = 0; +HANDLE hThread = NULL; +HANDLE hFlashEvent; +HANDLE hExitEvent; + +HANDLE hModulesLoaded = NULL; +HANDLE hMsgEventHook = NULL; +HANDLE hOptionsInitialize = NULL; +HANDLE hEnableService = NULL; +HANDLE hDisableService = NULL; +HANDLE hStartBlinkService = NULL; +HANDLE hEventsOpenedService = NULL; +HANDLE hFlashingEventService = NULL; +HANDLE hNormalizeSequenceService = NULL; + +HHOOK hMirandaMouseHook = NULL; +HHOOK hMirandaKeyBoardHook = NULL; +HHOOK hMirandaWndProcHook = NULL; +UINT hReminderTimer = 0; + +#pragma data_seg("Shared") +HHOOK hMouseHook = NULL; +HHOOK hKeyBoardHook = NULL; +BYTE bEmulateKeypresses = 0; +DWORD dwLastInput = 0; +POINT lastGlobalMousePos = {0, 0}; +#pragma data_seg() +#pragma comment(linker, "/section:Shared,rws") + +static BOOL (WINAPI * MyGetLastInputInfo)(PLASTINPUTINFO); + + +BYTE bFlashOnMsg; +BYTE bFlashOnURL; +BYTE bFlashOnFile; +BYTE bFlashOnOther; +BYTE bFullScreenMode; +BYTE bScreenSaverRunning; +BYTE bWorkstationLocked; +BYTE bProcessesAreRunning; +BYTE bWorkstationActive; +BYTE bFlashIfMsgOpen; +BYTE bFlashIfMsgWinNotTop; +BYTE bFlashIfMsgOlder; +WORD wSecondsOlder; +BYTE bFlashUntil; +WORD wBlinksNumber; +BYTE bMirandaOrWindows; +WORD wStatusMap; +WORD wReminderCheck; +BYTE bFlashLed[3]; +BYTE bFlashEffect; +BYTE bSequenceOrder; +WORD wCustomTheme; +WORD wStartDelay; +BYTE bFlashSpeed; +BYTE bOverride; +BYTE bTrillianLedsMsg; +BYTE bTrillianLedsURL; +BYTE bTrillianLedsFile; +BYTE bTrillianLedsOther; + +PROTOCOL_LIST ProtoList = {0, NULL}; +PROCESS_LIST ProcessList = {0, NULL}; + +double dWinVer; +BOOL bWindowsNT; + +int nWaitDelay; +unsigned int nExternCount = 0; +BOOL bFlashingEnabled = TRUE; +BOOL bReminderDisabled = FALSE; + +char *szMetaProto = NULL; +BYTE bMetaProtoEnabled = 0; + +#define MIID_KBDNOTIFY {0x119d7288, 0x2050, 0x448d, { 0x99, 0x00, 0xd8, 0x6a, 0xc7, 0x04, 0x26, 0xbf }} + +PLUGININFOEX pluginInfo={ + sizeof(PLUGININFOEX), + "Keyboard Notify Ext.", + PLUGIN_MAKE_VERSION(1,5,7,7), + "Flashes your keyboard LEDs when a message has arrived", + "TioDuke", + "tioduke@yahoo.ca", + "© 2002-2003 M.Öberg, 2004 Std, 2005-2008 TioDuke", + "http://addons.miranda-im.org/", + UNICODE_AWARE, //doesn't replace anything built-in + MIID_KBDNOTIFY //{119D7288-2050-448d-9900-D86AC70426BF} +}; + + + +int InitializeOptions(WPARAM,LPARAM); +void LoadSettings(void); +int HookWindowsHooks(void); +int UnhookWindowsHooks(void); +static LRESULT CALLBACK MouseHookFunction(int, WPARAM, LPARAM); +static LRESULT CALLBACK KeyBoardHookFunction(int, WPARAM, LPARAM); +static LRESULT CALLBACK MirandaMouseHookFunction(int, WPARAM, LPARAM); +static LRESULT CALLBACK MirandaKeyBoardHookFunction(int, WPARAM, LPARAM); +static LRESULT CALLBACK MirandaWndProcHookFunction(int, WPARAM, LPARAM); +BOOL CheckMsgWnd(HANDLE, BOOL *); + + +BOOL isMetaContactsSubContact(HANDLE hMetaContact, HANDLE hContact) +{ + char *szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hMetaContact, 0); + if (szProto && !strcmp(szMetaProto, szProto)) { // Safety check + int i = DBGetContactSettingDword(hContact, szMetaProto, "ContactNumber", -1); + if (i >= 0 && hContact == (HANDLE)CallService(MS_MC_GETSUBCONTACT, (WPARAM)hMetaContact, i)) + return TRUE; + } + return FALSE; +} + + +BOOL checkOpenWindow(HANDLE hContact) +{ + BOOL found, focus; + + if (bFlashIfMsgOpen && !bFlashIfMsgWinNotTop) + return TRUE; + + found = CheckMsgWnd(hContact, &focus); + if (!found && szMetaProto && bMetaProtoEnabled) { + HANDLE hMetaContact = (HANDLE)DBGetContactSettingDword(hContact, szMetaProto, "Handle", 0); + if (hMetaContact && isMetaContactsSubContact(hMetaContact, hContact)) + found = CheckMsgWnd(hMetaContact, &focus); + } + if (!found) + return TRUE; + + if (bFlashIfMsgOpen && !focus) + return TRUE; + + return FALSE; +} + + +BOOL IsSaverOnNT4() +{ + HDESK hd = OpenDesktop(L"screen-saver", 0, FALSE, MAXIMUM_ALLOWED); + + if(hd == NULL) + return GetLastError()==ERROR_ACCESS_DENIED; + + CloseDesktop(hd); + return TRUE; +} + + +BOOL isScreenSaverRunning() +{ + BOOL screenSaverIsRunning=FALSE; + + if (bWindowsNT && dWinVer < 5) return IsSaverOnNT4(); + + SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, &screenSaverIsRunning, FALSE); + return screenSaverIsRunning; +} + + +/* this function is from the original idle module */ +BOOL isWorkstationLocked() +{ + HDESK hd; + char buf[MAX_PATH]; + + if (!bWindowsNT) return FALSE; + + hd = OpenInputDesktop(0, FALSE, MAXIMUM_ALLOWED); /* if it fails then the workstation is prolly locked anyway */ + if (hd == NULL) return TRUE; + GetUserObjectInformation(hd, UOI_NAME, buf, sizeof(buf), NULL); /* if we got it (hmm,) get a name */ + CloseDesktop(hd); + return strcmp(buf, "Winlogon")==0; +} + + +BOOL isFullScreen() +{ + int w = GetSystemMetrics(SM_CXSCREEN); + int h = GetSystemMetrics(SM_CYSCREEN); + + HWND hWnd = 0; + while (hWnd = FindWindowEx(NULL, hWnd, NULL, NULL)) { + RECT WindowRect; + + if (!(GetWindowLongPtr(hWnd, GWL_EXSTYLE) & WS_EX_TOPMOST)) + continue; + + GetWindowRect(hWnd, &WindowRect); + if ((w != (WindowRect.right - WindowRect.left)) || (h != (WindowRect.bottom - WindowRect.top))) + continue; + + return TRUE; + } + + return FALSE; +} + + +BOOL checkNotifyOptions() +{ + BOOL fullScreenMode, screenSaverIsRunning, workstationIsLocked, processesRunning; + + screenSaverIsRunning = isScreenSaverRunning(); + if (screenSaverIsRunning && bScreenSaverRunning) + return TRUE; + + workstationIsLocked = isWorkstationLocked(); + if (workstationIsLocked && bWorkstationLocked) + return TRUE; + + fullScreenMode = isFullScreen() && !screenSaverIsRunning; + if (fullScreenMode && bFullScreenMode) + return TRUE; + + processesRunning = areThereProcessesRunning(); + if (processesRunning && bProcessesAreRunning) + return TRUE; + + return (!fullScreenMode && !screenSaverIsRunning && !workstationIsLocked && !processesRunning && bWorkstationActive); +} + + +BOOL isStatusEnabled(int status) +{ + switch (status) { + case ID_STATUS_OFFLINE: return wStatusMap & MAP_OFFLINE; + case ID_STATUS_ONLINE: return wStatusMap & MAP_ONLINE; + case ID_STATUS_AWAY: return wStatusMap & MAP_AWAY; + case ID_STATUS_NA: return wStatusMap & MAP_NA; + case ID_STATUS_OCCUPIED: return wStatusMap & MAP_OCCUPIED; + case ID_STATUS_DND: return wStatusMap & MAP_DND; + case ID_STATUS_FREECHAT: return wStatusMap & MAP_FREECHAT; + case ID_STATUS_INVISIBLE: return wStatusMap & MAP_INVISIBLE; + case ID_STATUS_ONTHEPHONE: return wStatusMap & MAP_ONTHEPHONE; + case ID_STATUS_OUTTOLUNCH: return wStatusMap & MAP_OUTTOLUNCH; + default: return FALSE; + } +} + + +BOOL checkGlobalStatus() +{ + return isStatusEnabled(CallService(MS_CLIST_GETSTATUSMODE, 0, 0)); +} + + +BOOL checkGlobalXstatus() +{ + ICQ_CUSTOM_STATUS xstatus={0}; + unsigned int i, protosSupporting; int status=0; + + for(i=0, protosSupporting=0; i < ProtoList.protoCount; i++) { + if (!ProtoList.protoInfo[i].enabled || !ProtoList.protoInfo[i].xstatus.count) continue; + + protosSupporting++; + // Retrieve xstatus for protocol + xstatus.cbSize = sizeof(ICQ_CUSTOM_STATUS); + xstatus.flags = CSSF_MASK_STATUS; + xstatus.status = &status; + CallProtoService(ProtoList.protoInfo[i].szProto, PS_ICQ_GETCUSTOMSTATUSEX, 0, (LPARAM)&xstatus); + + if (ProtoList.protoInfo[i].xstatus.enabled[status]) return TRUE; + } + + if (!protosSupporting) + return TRUE; + else + return FALSE; +} + + +DBEVENTINFO createMsgEventInfo(HANDLE hContact) +{ + DBEVENTINFO einfo = {0}; + + einfo.cbSize = sizeof(einfo); + einfo.eventType = EVENTTYPE_MESSAGE; + einfo.szModule = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + + return einfo; +} + + +DBEVENTINFO readEventInfo(HANDLE hDbEvent, HANDLE hContact) +{ + DBEVENTINFO einfo = {0}; + + if (hDbEvent == NCONVERS_BLINKID) // we need to handle nconvers' blink event + return createMsgEventInfo(hContact); + + einfo.cbSize = sizeof(einfo); + einfo.cbBlob = 0; + einfo.pBlob = NULL; + CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&einfo); + + return einfo; +} + + +BOOL checkIgnore(HANDLE hContact, WORD eventType) +{ + return !IsIgnored(hContact, eventType); +} + + +BOOL checkProtocol(char *szProto) +{ + unsigned int i; + + if (!szProto) + return FALSE; + + for(i=0; i < ProtoList.protoCount; i++) + if (ProtoList.protoInfo[i].szProto && !strcmp(ProtoList.protoInfo[i].szProto, szProto)) + return ProtoList.protoInfo[i].enabled; + + return FALSE; +} + + +BOOL metaCheckProtocol(char *szProto, HANDLE hContact, WORD eventType) +{ + HANDLE hSubContact=NULL; + + if (szMetaProto && bMetaProtoEnabled && szProto && !strcmp(szMetaProto, szProto)) + if (hSubContact = (HANDLE)CallService(MS_MC_GETMOSTONLINECONTACT, (WPARAM)hContact, 0)) + szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hSubContact, 0); + + return checkProtocol(szProto) && checkIgnore(hSubContact?hSubContact:hContact, eventType); +} + + +BOOL checkUnopenEvents() +{ + int nIndex; + CLISTEVENT *pCLEvent; + + if (nExternCount && bFlashOnOther) + return TRUE; + + for (nIndex = 0; pCLEvent = (CLISTEVENT*)CallService(MS_CLIST_GETEVENT, -1, nIndex); nIndex++) { + DBEVENTINFO einfo = readEventInfo(pCLEvent->hDbEvent, pCLEvent->hContact); + + if ((einfo.eventType == EVENTTYPE_MESSAGE && bFlashOnMsg) || + (einfo.eventType == EVENTTYPE_URL && bFlashOnURL) || + (einfo.eventType == EVENTTYPE_FILE && bFlashOnFile) || + (einfo.eventType != EVENTTYPE_MESSAGE && einfo.eventType != EVENTTYPE_URL && einfo.eventType != EVENTTYPE_FILE && bFlashOnOther)) + + if (metaCheckProtocol(einfo.szModule, pCLEvent->hContact, einfo.eventType)) + return TRUE; + } + + return FALSE; +} + + +static void FlashThreadFunction() +{ + BOOL bEvent = FALSE; + DWORD dwEventStarted, dwFlashStarted; + BYTE data, unchangedLeds; + + while (TRUE) { + unchangedLeds = (BYTE)(LedState(VK_PAUSE) * !bFlashLed[2] + ((LedState(VK_NUMLOCK) * !bFlashLed[0])<<1) + ((LedState(VK_CAPITAL) * !bFlashLed[1])<<2)); + GetAsyncKeyState(VK_PAUSE); // empty Pause/Break's keystroke buffer + + // Start flashing + while(bEvent && bFlashingEnabled) + { + // Let's give the user the opportunity of finishing flashing manually :) + if (GetAsyncKeyState(VK_PAUSE) & 1) + break; + + if ((bFlashUntil & UNTIL_NBLINKS) && GetTickCount() > (dwFlashStarted + wBlinksNumber * 1000)) + break; + if (bFlashUntil & UNTIL_REATTENDED) { + if (bMirandaOrWindows == ACTIVE_WINDOWS && MyGetLastInputInfo && !bEmulateKeypresses) { + LASTINPUTINFO lii; + ZeroMemory(&lii, sizeof(lii)); + lii.cbSize = sizeof(lii); + MyGetLastInputInfo(&lii); + dwLastInput = lii.dwTime; + } + if (dwLastInput > dwEventStarted) + break; + } + if ((bFlashUntil & UNTIL_EVENTSOPEN) && !checkUnopenEvents()) + break; + if ((bFlashUntil & UNTIL_CONDITIONS) && (!checkNotifyOptions() || !checkGlobalStatus() || !checkGlobalXstatus())) + break; + + data = getBlinkingLeds(); + ToggleKeyboardLights((BYTE)(data|unchangedLeds)); + + // Wait for exit event + if (WaitForSingleObject(hExitEvent, nWaitDelay) == WAIT_OBJECT_0) + return; + } + RestoreLEDState(); + + setFlashingSequence(); + bReminderDisabled = FALSE; + + // Wait for new event + { + DWORD dwEvent; + HANDLE Objects[2]; + Objects[0] = hFlashEvent; + Objects[1] = hExitEvent; + dwEvent = WaitForMultipleObjects(2, Objects, FALSE, INFINITE); + if ((dwEvent - WAIT_OBJECT_0) == 1) + return; + } + + bEvent = TRUE; + bReminderDisabled = TRUE; + dwEventStarted = GetTickCount(); + // Wait StartDelay seconds + if (wStartDelay > 0) + Sleep(wStartDelay * 1000); + dwFlashStarted = GetTickCount(); + + } + +} + + +BOOL checkMsgTimestamp(HANDLE hEventCurrent, DWORD timestampCurrent) +{ + HANDLE hEvent; + + if (!bFlashIfMsgOlder) + return TRUE; + + for (hEvent=(HANDLE)CallService(MS_DB_EVENT_FINDPREV, (WPARAM)hEventCurrent, 0); hEvent; hEvent=(HANDLE)CallService(MS_DB_EVENT_FINDPREV, (WPARAM)hEvent, 0)) { + DBEVENTINFO einfo = {0}; + + einfo.cbSize = sizeof(einfo); + einfo.cbBlob = 0; + einfo.pBlob = NULL; + CallService(MS_DB_EVENT_GET, (WPARAM)hEvent, (LPARAM)&einfo); + if ((einfo.timestamp + wSecondsOlder) <= timestampCurrent) + return TRUE; + if (einfo.eventType == EVENTTYPE_MESSAGE) + return FALSE; + } + + return TRUE; +} + + +BOOL contactCheckProtocol(char *szProto, HANDLE hContact, WORD eventType) +{ + if (szMetaProto && bMetaProtoEnabled && hContact) { + HANDLE hMetaContact = (HANDLE)DBGetContactSettingDword(hContact, szMetaProto, "Handle", 0); + if (hMetaContact && isMetaContactsSubContact(hMetaContact, hContact)) + return FALSE; + } + + return (metaCheckProtocol(szProto, hContact, eventType)); +} + + +BOOL checkStatus(char *szProto) +{ + if (!szProto) + return checkGlobalStatus(); + + return isStatusEnabled(CallProtoService(szProto, PS_GETSTATUS, 0, 0)); +} + + +BOOL checkXstatus(char *szProto) +{ + unsigned int i; int status=0; + ICQ_CUSTOM_STATUS xstatus={0}; + + if (!szProto) + return checkGlobalXstatus(); + + for(i=0; i < ProtoList.protoCount; i++) + if (ProtoList.protoInfo[i].szProto && !strcmp(ProtoList.protoInfo[i].szProto, szProto)) { + if (!ProtoList.protoInfo[i].xstatus.count) return TRUE; + + // Retrieve xstatus for protocol + xstatus.cbSize = sizeof(ICQ_CUSTOM_STATUS); + xstatus.flags = CSSF_MASK_STATUS; + xstatus.status = &status; + CallProtoService(ProtoList.protoInfo[i].szProto, PS_ICQ_GETCUSTOMSTATUSEX, 0, (LPARAM)&xstatus); + + return ProtoList.protoInfo[i].xstatus.enabled[status]; + } + + return TRUE; +} + + +// 'Pings' the FlashThread to keep the LEDs flashing. +static int PluginMessageEventHook(WPARAM wParam, LPARAM lParam) +{ + DBEVENTINFO einfo = {0}; + HANDLE hContact = (HANDLE)wParam; + HANDLE hEvent = (HANDLE)lParam; + + //get DBEVENTINFO without pBlob + einfo.cbSize = sizeof(einfo); + einfo.cbBlob = 0; + einfo.pBlob = NULL; + CallService(MS_DB_EVENT_GET, (WPARAM)hEvent, (LPARAM)&einfo); + + if (!(einfo.flags & DBEF_SENT)) + if ((einfo.eventType == EVENTTYPE_MESSAGE && bFlashOnMsg && checkOpenWindow(hContact) && checkMsgTimestamp(hEvent, einfo.timestamp)) || + (einfo.eventType == EVENTTYPE_URL && bFlashOnURL) || + (einfo.eventType == EVENTTYPE_FILE && bFlashOnFile) || + (einfo.eventType != EVENTTYPE_MESSAGE && einfo.eventType != EVENTTYPE_URL && einfo.eventType != EVENTTYPE_FILE && bFlashOnOther)) { + + if (contactCheckProtocol(einfo.szModule, hContact, einfo.eventType) && checkNotifyOptions() && checkStatus(einfo.szModule) && checkXstatus(einfo.szModule)) + + SetEvent(hFlashEvent); + } + + return 0; +} + + +// ** +// ** Checks for pending events. If it finds any, it pings the FlashThread to keep the LEDs flashing. +// ** + +static VOID CALLBACK ReminderTimer(HWND hwnd, UINT message, UINT_PTR idEvent, DWORD dwTime) +{ + int nIndex; + CLISTEVENT *pCLEvent; + + if (!bReminderDisabled && nExternCount && bFlashOnOther) { + SetEvent(hFlashEvent); + return; + } + + for (nIndex = 0; !bReminderDisabled && (pCLEvent = (CLISTEVENT*)CallService(MS_CLIST_GETEVENT, -1, nIndex)); nIndex++) { + DBEVENTINFO einfo = readEventInfo(pCLEvent->hDbEvent, pCLEvent->hContact); + + if ((einfo.eventType == EVENTTYPE_MESSAGE && bFlashOnMsg) || + (einfo.eventType == EVENTTYPE_URL && bFlashOnURL) || + (einfo.eventType == EVENTTYPE_FILE && bFlashOnFile) || + (einfo.eventType != EVENTTYPE_MESSAGE && einfo.eventType != EVENTTYPE_URL && einfo.eventType != EVENTTYPE_FILE && bFlashOnOther)) + + if (metaCheckProtocol(einfo.szModule, pCLEvent->hContact, einfo.eventType) && checkNotifyOptions() && checkStatus(einfo.szModule) && checkXstatus(einfo.szModule)) { + + SetEvent(hFlashEvent); + return; + } + } + +} + + +// Support for third-party plugins and mBot's scripts +static INT_PTR EnableService(WPARAM wParam, LPARAM lParam) +{ + bFlashingEnabled = TRUE; + return 0; +} + +static INT_PTR DisableService(WPARAM wParam, LPARAM lParam) +{ + bFlashingEnabled = FALSE; + return 0; +} + +static INT_PTR StartBlinkService(WPARAM wParam, LPARAM lParam) +{ + nExternCount += (unsigned int)wParam; + if (bFlashOnOther && checkNotifyOptions() && checkGlobalStatus() && checkGlobalXstatus()) { + if (lParam) + useExternSequence((TCHAR *)lParam); + SetEvent(hFlashEvent); + } + + return 0; +} + +static INT_PTR EventsWereOpenedService(WPARAM wParam, LPARAM lParam) +{ + if ((unsigned int)wParam > nExternCount) + nExternCount = 0; + else + nExternCount -= (unsigned int)wParam; + + return 0; +} + + +static INT_PTR IsFlashingActiveService(WPARAM wParam, LPARAM lParam) +{ + if (!bReminderDisabled) + return 0; + + return (int)getCurrentSequenceString(); +} + + +INT_PTR NormalizeSequenceService(WPARAM wParam, LPARAM lParam) +{ + TCHAR strAux[MAX_PATH+1], *strIn = (TCHAR *)lParam; + + _snwprintf(strAux, MAX_PATH, _T("%s"), strIn); + _snwprintf(strIn, MAX_PATH, _T("%s"), normalizeCustomString(strAux)); + + return (int)strIn; +} + + +// Support for Trigger plugin +static void ForceEventsWereOpenedThread(void *eventMaxSeconds) +{ + Sleep(((WORD)eventMaxSeconds) * 1000); + CallService(MS_KBDNOTIFY_EVENTSOPENED, 1, 0); +} + + +void StartBlinkAction(char *flashSequence, WORD eventMaxSeconds) +{ + DWORD threadID = 0; + + if (eventMaxSeconds) + CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ForceEventsWereOpenedThread, (void *)eventMaxSeconds, 0, &threadID); + + CallService(MS_KBDNOTIFY_STARTBLINK, 1, (LPARAM)flashSequence); +} + + +void createProcessList(void) +{ + DBVARIANT dbv; + unsigned int i, count; + + count = (unsigned int)DBGetContactSettingWord(NULL, KEYBDMODULE, "processcount", 0); + + ProcessList.count = 0; + ProcessList.szFileName = (TCHAR **)malloc(count * sizeof(TCHAR *)); + if (ProcessList.szFileName) { + for(i=0; i < count; i++) + if (DBGetContactSetting(NULL, KEYBDMODULE, fmtDBSettingName("process%d", i), &dbv)) + ProcessList.szFileName[i] = NULL; + else { + ProcessList.szFileName[i] = (TCHAR *)malloc(wcslen(dbv.ptszVal) + 1); + if (ProcessList.szFileName[i]) + wcscpy(ProcessList.szFileName[i], dbv.ptszVal); + DBFreeVariant(&dbv); + } + ProcessList.count = count; + } + +} + + +void destroyProcessList(void) +{ + unsigned int i, count; + + count = ProcessList.count; + + ProcessList.count = 0; + for(i=0; i < count; i++) + if (ProcessList.szFileName[i]) + free(ProcessList.szFileName[i]); + + if (ProcessList.szFileName) + free(ProcessList.szFileName); + ProcessList.szFileName = NULL; +} + + +void LoadSettings(void) +{ + unsigned int i; + + bFlashOnMsg = DBGetContactSettingByte(NULL, KEYBDMODULE, "onmsg", DEF_SETTING_ONMSG); + bFlashOnURL = DBGetContactSettingByte(NULL, KEYBDMODULE, "onurl", DEF_SETTING_ONURL); + bFlashOnFile = DBGetContactSettingByte(NULL, KEYBDMODULE, "onfile", DEF_SETTING_ONFILE); + bFlashOnOther = DBGetContactSettingByte(NULL, KEYBDMODULE, "onother", DEF_SETTING_OTHER); + bFullScreenMode = DBGetContactSettingByte(NULL, KEYBDMODULE, "fscreenmode", DEF_SETTING_FSCREEN); + bScreenSaverRunning = DBGetContactSettingByte(NULL, KEYBDMODULE, "ssaverrunning", DEF_SETTING_SSAVER); + bWorkstationLocked = (bWindowsNT ? DBGetContactSettingByte(NULL, KEYBDMODULE, "wstationlocked", DEF_SETTING_LOCKED):0); + bProcessesAreRunning = DBGetContactSettingByte(NULL, KEYBDMODULE, "procsrunning", DEF_SETTING_PROCS); + bWorkstationActive = DBGetContactSettingByte(NULL, KEYBDMODULE, "wstationactive", DEF_SETTING_ACTIVE); + bFlashIfMsgOpen = DBGetContactSettingByte(NULL, KEYBDMODULE, "ifmsgopen", DEF_SETTING_IFMSGOPEN); + bFlashIfMsgWinNotTop = DBGetContactSettingByte(NULL, KEYBDMODULE, "ifmsgnottop", DEF_SETTING_IFMSGNOTTOP); + bFlashIfMsgOlder = DBGetContactSettingByte(NULL, KEYBDMODULE, "ifmsgolder", DEF_SETTING_IFMSGOLDER); + wSecondsOlder = DBGetContactSettingWord(NULL, KEYBDMODULE, "secsolder", DEF_SETTING_SECSOLDER); + bFlashUntil = DBGetContactSettingByte(NULL, KEYBDMODULE, "funtil", DEF_SETTING_FLASHUNTIL); + wBlinksNumber = DBGetContactSettingWord(NULL, KEYBDMODULE, "nblinks", DEF_SETTING_NBLINKS); + bMirandaOrWindows = DBGetContactSettingByte(NULL, KEYBDMODULE, "mirorwin", DEF_SETTING_MIRORWIN); + wStatusMap = DBGetContactSettingWord(NULL, KEYBDMODULE, "status", DEF_SETTING_STATUS); + wReminderCheck = DBGetContactSettingWord(NULL, KEYBDMODULE, "remcheck", DEF_SETTING_CHECKTIME); + bFlashLed[0] = !!DBGetContactSettingByte(NULL, KEYBDMODULE, "fnum", DEF_SETTING_FLASHNUM); + bFlashLed[1] = !!DBGetContactSettingByte(NULL, KEYBDMODULE, "fcaps", DEF_SETTING_FLASHCAPS); + bFlashLed[2] = !!DBGetContactSettingByte(NULL, KEYBDMODULE, "fscroll", DEF_SETTING_FLASHSCROLL); + bFlashEffect = DBGetContactSettingByte(NULL, KEYBDMODULE, "feffect", DEF_SETTING_FLASHEFFECT); + bSequenceOrder = DBGetContactSettingByte(NULL, KEYBDMODULE, "order", DEF_SETTING_SEQORDER); + wCustomTheme = DBGetContactSettingWord(NULL, KEYBDMODULE, "custom", DEF_SETTING_CUSTOMTHEME); + bTrillianLedsMsg = DBGetContactSettingByte(NULL, KEYBDMODULE, "ledsmsg", DEF_SETTING_LEDSMSG); + bTrillianLedsURL = DBGetContactSettingByte(NULL, KEYBDMODULE, "ledsurl", DEF_SETTING_LEDSURL); + bTrillianLedsFile = DBGetContactSettingByte(NULL, KEYBDMODULE, "ledsfile", DEF_SETTING_LEDSFILE); + bTrillianLedsOther = DBGetContactSettingByte(NULL, KEYBDMODULE, "ledsother", DEF_SETTING_LEDSOTHER); + wStartDelay = DBGetContactSettingWord(NULL, KEYBDMODULE, "sdelay", DEF_SETTING_STARTDELAY); + bFlashSpeed = DBGetContactSettingByte(NULL, KEYBDMODULE, "speed", DEF_SETTING_FLASHSPEED); + switch (bFlashSpeed) { + case 0: nWaitDelay = 1500; break; + case 1: nWaitDelay = 0750; break; + case 2: nWaitDelay = 0250; break; + case 3: nWaitDelay = 0150; break; + case 4: nWaitDelay = 0100; break; + default: nWaitDelay = 0050; break; + } + setFlashingSequence(); + bEmulateKeypresses = DBGetContactSettingByte(NULL, KEYBDMODULE, "keypresses", DEF_SETTING_KEYPRESSES); + bOverride = DBGetContactSettingByte(NULL, KEYBDMODULE, "override", DEF_SETTING_OVERRIDE); + // Create hidden settings (for test button) if needed + if (DBGetContactSettingByte(NULL, KEYBDMODULE, "testnum", -1) == -1) + DBWriteContactSettingByte(NULL, KEYBDMODULE, "testnum", DEF_SETTING_TESTNUM); + if (DBGetContactSettingByte(NULL, KEYBDMODULE, "testsecs", -1) == -1) + DBWriteContactSettingByte(NULL, KEYBDMODULE, "testsecs", DEF_SETTING_TESTSECS); + for(i=0; i < ProtoList.protoCount; i++) + if (ProtoList.protoInfo[i].visible) { + unsigned int j; + ProtoList.protoInfo[i].enabled = DBGetContactSettingByte(NULL, KEYBDMODULE, ProtoList.protoInfo[i].szProto, DEF_SETTING_PROTOCOL); + for(j=0; j < ProtoList.protoInfo[i].xstatus.count; j++) + ProtoList.protoInfo[i].xstatus.enabled[j] = DBGetContactSettingByte(NULL, KEYBDMODULE, fmtDBSettingName("%sxstatus%d", ProtoList.protoInfo[i].szProto, j), DEF_SETTING_XSTATUS); + } + + if (szMetaProto) + bMetaProtoEnabled = DBGetContactSettingByte(NULL, szMetaProto, "Enabled", 1); + + destroyProcessList(); + createProcessList(); + UnhookWindowsHooks(); + HookWindowsHooks(); +} + + +void GetWindowsVersion(void) +{ + OSVERSIONINFOEX osvi; + BOOL bOsVersionInfoEx; + + ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + if (!(bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO *) &osvi))) { + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + if (!GetVersionEx((OSVERSIONINFO *)&osvi)) + osvi.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS; + } + bWindowsNT = osvi.dwPlatformId==VER_PLATFORM_WIN32_NT; + dWinVer = osvi.dwMajorVersion + osvi.dwMinorVersion / 10.0; +} + + +void updateXstatusProto(PROTOCOL_INFO *protoInfo) +{ + unsigned int i; + char szServiceName[MAXMODULELABELLENGTH]; + ICQ_CUSTOM_STATUS xstatus={0}; + + mir_snprintf(szServiceName, sizeof(szServiceName), "%s%s", protoInfo->szProto, PS_ICQ_GETCUSTOMSTATUSEX); + if (!ServiceExists(szServiceName)) return; + + // Retrieve xstatus.count + xstatus.cbSize = sizeof(ICQ_CUSTOM_STATUS); + xstatus.flags = CSSF_STATUSES_COUNT; + xstatus.wParam = &(protoInfo->xstatus.count); + CallProtoService(protoInfo->szProto, PS_ICQ_GETCUSTOMSTATUSEX, 0, (LPARAM)&xstatus); + (protoInfo->xstatus.count)++; // Don't forget about xstatus=0 (None) + + // Alloc and initiailize xstatus.enabled array + protoInfo->xstatus.enabled = (BOOL *)malloc(protoInfo->xstatus.count * sizeof(BOOL)); + if (!protoInfo->xstatus.enabled) + protoInfo->xstatus.count = 0; + else + for(i=0; i < protoInfo->xstatus.count; i++) + protoInfo->xstatus.enabled[i] = FALSE; + +} + + +void createProtocolList(void) +{ + unsigned int i; + PROTOCOLDESCRIPTOR **proto; + + if (ServiceExists(MS_MC_GETPROTOCOLNAME)) + szMetaProto = (char *)CallService(MS_MC_GETPROTOCOLNAME, 0, 0); + + CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&ProtoList.protoCount, (LPARAM)&proto); + ProtoList.protoInfo = (PROTOCOL_INFO *)malloc(ProtoList.protoCount * sizeof(PROTOCOL_INFO)); + if (!ProtoList.protoInfo) + ProtoList.protoCount = 0; + else + for(i=0; i < ProtoList.protoCount; i++) { + ProtoList.protoInfo[i].xstatus.count = 0; + ProtoList.protoInfo[i].xstatus.enabled = NULL; + ProtoList.protoInfo[i].szProto = (char *)malloc(strlen(proto[i]->szName) + 1); + if (!ProtoList.protoInfo[i].szProto) { + ProtoList.protoInfo[i].enabled = FALSE; + ProtoList.protoInfo[i].visible = FALSE; + } else { + strcpy(ProtoList.protoInfo[i].szProto, proto[i]->szName); + ProtoList.protoInfo[i].enabled = FALSE; + if (proto[i]->type != PROTOTYPE_PROTOCOL) + ProtoList.protoInfo[i].visible = FALSE; + else + if (szMetaProto && !strcmp(proto[i]->szName, szMetaProto)) + ProtoList.protoInfo[i].visible = FALSE; + else { + ProtoList.protoInfo[i].visible = TRUE; + updateXstatusProto(&(ProtoList.protoInfo[i])); + } + } + } + +} + + +// We use the profile name to create the first part of each event name +// We do so to avoid problems between different instances of the plugin concurrently running +void createEventPrefix(TCHAR *prefixName, size_t maxLen) +{ + size_t len; + TCHAR profileName[MAX_PATH+1], *str; + + getAbsoluteProfileName(profileName, MAX_PATH); + + while (str = wcschr(profileName, _T('\\'))) + *str = _T('/'); + if ((len = wcslen(profileName)) <= maxLen) + wcscpy(prefixName, profileName); + else { + str = profileName + len - maxLen / 2; + _snwprintf(prefixName, maxLen / 2, L"%s", profileName); + wcscat(prefixName, str); + } +} + + +// ** +// ** Everything below is just Miranda init/uninit stuff +// ** + + +static int ModulesLoaded(WPARAM wParam, LPARAM lParam) +{ + TCHAR eventPrefix[MAX_PATH+1], eventName[MAX_PATH+1]; + + LoadProcsLibrary(); + if (bWindowsNT && dWinVer >= 5) + MyGetLastInputInfo = (BOOL (WINAPI *)(PLASTINPUTINFO)) GetProcAddress(GetModuleHandle(L"user32"), "GetLastInputInfo"); + else + MyGetLastInputInfo = NULL; + + createProtocolList(); + LoadSettings(); + + // Create some synchronisation objects + createEventPrefix(eventPrefix, MAX_PATH - 11); + _snwprintf(eventName, sizeof(eventName), _T("%s/FlashEvent"), eventPrefix); + hFlashEvent = CreateEvent(NULL, FALSE, FALSE, eventName); + _snwprintf(eventName, sizeof(eventName), _T("%s/ExitEvent"), eventPrefix); + hExitEvent = CreateEvent(NULL, FALSE, FALSE, eventName); + + hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)FlashThreadFunction, NULL, 0, &IDThread); + + hMsgEventHook = HookEvent(ME_DB_EVENT_ADDED, PluginMessageEventHook); + hOptionsInitialize = HookEvent(ME_OPT_INITIALISE, InitializeOptions); + hEnableService = CreateServiceFunction(MS_KBDNOTIFY_ENABLE, EnableService); + hDisableService = CreateServiceFunction(MS_KBDNOTIFY_DISABLE, DisableService); + hStartBlinkService = CreateServiceFunction(MS_KBDNOTIFY_STARTBLINK, StartBlinkService); + hEventsOpenedService = CreateServiceFunction(MS_KBDNOTIFY_EVENTSOPENED, EventsWereOpenedService); + hFlashingEventService = CreateServiceFunction(MS_KBDNOTIFY_FLASHINGACTIVE, IsFlashingActiveService); + hNormalizeSequenceService = CreateServiceFunction(MS_KBDNOTIFY_NORMALSEQUENCE, NormalizeSequenceService); + + RegisterAction(); + if (ServiceExists("DBEditorpp/RegisterSingleModule")) + CallService("DBEditorpp/RegisterSingleModule", (WPARAM)KEYBDMODULE, 0); + + return 0; +} + + + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + + hInst = hinstDLL; + + return TRUE; + +} + +extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + return &pluginInfo; +} + +extern "C" __declspec(dllexport) int Load(void) +{ + + mir_getLP(&pluginInfo); + + GetWindowsVersion(); + OpenKeyboardDevice(); + hModulesLoaded = HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoaded); + + return 0; +} + + + +void destroyProtocolList(void) +{ + unsigned int i; + + for(i=0; i < ProtoList.protoCount; i++) { + if (ProtoList.protoInfo[i].szProto) + free(ProtoList.protoInfo[i].szProto); + if (ProtoList.protoInfo[i].xstatus.enabled) + free(ProtoList.protoInfo[i].xstatus.enabled); + } + + ProtoList.protoCount = 0; + if (ProtoList.protoInfo) + free(ProtoList.protoInfo); +} + + +extern "C" __declspec(dllexport) int Unload(void) +{ + + UnhookWindowsHooks(); + DeInitAction(); + if (hModulesLoaded) + UnhookEvent(hModulesLoaded); + if (hMsgEventHook) + UnhookEvent(hMsgEventHook); + if (hOptionsInitialize) + UnhookEvent(hOptionsInitialize); + if (hEnableService) + DestroyServiceFunction(hEnableService); + if (hDisableService) + DestroyServiceFunction(hDisableService); + if (hStartBlinkService) + DestroyServiceFunction(hStartBlinkService); + if (hEventsOpenedService) + DestroyServiceFunction(hEventsOpenedService); + if (hFlashingEventService) + DestroyServiceFunction(hFlashingEventService); + if (hNormalizeSequenceService) + DestroyServiceFunction(hNormalizeSequenceService); + + // Wait for thread to exit + SetEvent(hExitEvent); + WaitForSingleObject(hThread, INFINITE); + + RestoreLEDState(); + CloseKeyboardDevice(); + + UnloadProcsLibrary(); + destroyProcessList(); + destroyProtocolList(); + + return 0; +} + + +// ========================== Windows hooks ========================== +int HookWindowsHooks() +{ + if (wReminderCheck) + hReminderTimer = SetTimer(NULL,0, wReminderCheck * 60000, ReminderTimer); + + if (bFlashUntil & UNTIL_REATTENDED) + switch (bMirandaOrWindows) { + case ACTIVE_WINDOWS: + if (!MyGetLastInputInfo || bEmulateKeypresses) { + if (hMouseHook == NULL) + hMouseHook = SetWindowsHookEx(WH_MOUSE, MouseHookFunction, hInst, 0); + if (hKeyBoardHook == NULL) + hKeyBoardHook = SetWindowsHookEx(WH_KEYBOARD, KeyBoardHookFunction, hInst, 0); + } + break; + case ACTIVE_MIRANDA: + if (hMirandaMouseHook == NULL) + hMirandaMouseHook = SetWindowsHookEx(WH_MOUSE, MirandaMouseHookFunction, NULL, GetCurrentThreadId()); + if (hMirandaKeyBoardHook == NULL) + hMirandaKeyBoardHook = SetWindowsHookEx(WH_KEYBOARD, MirandaKeyBoardHookFunction, NULL, GetCurrentThreadId()); + if (hMirandaWndProcHook == NULL) + hMirandaWndProcHook = SetWindowsHookEx(WH_CALLWNDPROC, MirandaWndProcHookFunction, NULL, GetCurrentThreadId()); + } + + return 0; +} + +int UnhookWindowsHooks() +{ + if (hReminderTimer) + KillTimer(NULL, hReminderTimer); + if (hMouseHook) + UnhookWindowsHookEx(hMouseHook); + if (hKeyBoardHook) + UnhookWindowsHookEx(hKeyBoardHook); + if (hMirandaMouseHook) + UnhookWindowsHookEx(hMirandaMouseHook); + if (hMirandaKeyBoardHook) + UnhookWindowsHookEx(hMirandaKeyBoardHook); + if (hMirandaWndProcHook) + UnhookWindowsHookEx(hMirandaWndProcHook); + + hReminderTimer = 0; + hMouseHook = hKeyBoardHook = hMirandaMouseHook = hMirandaKeyBoardHook = hMirandaWndProcHook = NULL; + + return 0; +} + +static LRESULT CALLBACK MouseHookFunction(int code, WPARAM wParam, LPARAM lParam) +{ + if (code >= 0) { + /* This should handle all mouse buttons ... */ + if ((wParam >= WM_NCLBUTTONDOWN && wParam <= WM_NCXBUTTONDBLCLK && wParam != 0x00AA) || (wParam >= WM_LBUTTONDOWN && wParam <= WM_XBUTTONDBLCLK)) + dwLastInput = GetTickCount(); + /* ... and here it is either mouse move, hover, leave or something unexpected */ + else { + PMOUSEHOOKSTRUCT mouseInfo = (PMOUSEHOOKSTRUCT)lParam; + POINT pt = mouseInfo->pt; + if (pt.x!=lastGlobalMousePos.x || pt.y!=lastGlobalMousePos.y) { + lastGlobalMousePos = pt; + dwLastInput = GetTickCount(); + } + } + } + + return CallNextHookEx(hMouseHook, code, wParam, lParam); +} + +static LRESULT CALLBACK KeyBoardHookFunction(int code, WPARAM wParam, LPARAM lParam) +{ + if (code >= 0 && (!bEmulateKeypresses || (bEmulateKeypresses && wParam != VK_NUMLOCK && wParam != VK_CAPITAL && wParam != VK_SCROLL))) + dwLastInput = GetTickCount(); + + return CallNextHookEx(hKeyBoardHook, code, wParam, lParam); +} + +static LRESULT CALLBACK MirandaMouseHookFunction(int code, WPARAM wParam, LPARAM lParam) +{ + static POINT lastMousePos = {0, 0}; + + if (code >= 0) { + /* Movement mouse messages are for some reason incoming in inactive/background window too, that is not input */ + DWORD pid; + GetWindowThreadProcessId(GetForegroundWindow(), &pid); + if(pid == GetCurrentProcessId()) { + /* This should handle all mouse buttons ... */ + if ((wParam >= WM_NCLBUTTONDOWN && wParam <= WM_NCXBUTTONDBLCLK && wParam != 0x00AA) || (wParam >= WM_LBUTTONDOWN && wParam <= WM_XBUTTONDBLCLK)) + dwLastInput = GetTickCount(); + /* ... and here it is either mouse move, hover, leave or something unexpected */ + else { + PMOUSEHOOKSTRUCT mouseInfo = (PMOUSEHOOKSTRUCT)lParam; + POINT pt = mouseInfo->pt; + if (pt.x!=lastMousePos.x || pt.y!=lastMousePos.y) { + lastMousePos = pt; + dwLastInput = GetTickCount(); + } + } + } + } + + return CallNextHookEx(hMirandaMouseHook, code, wParam, lParam); +} + +static LRESULT CALLBACK MirandaKeyBoardHookFunction(int code, WPARAM wParam, LPARAM lParam) { + + if (code >= 0 && (!bEmulateKeypresses || (bEmulateKeypresses && wParam != VK_NUMLOCK && wParam != VK_CAPITAL && wParam != VK_SCROLL))) + dwLastInput = GetTickCount(); + + return CallNextHookEx(hMirandaKeyBoardHook, code, wParam, lParam); +} + +static LRESULT CALLBACK MirandaWndProcHookFunction(int code, WPARAM wParam, LPARAM lParam) { + + if (code >= 0) { + /* WM_ACTIVATEAPP with nonzero wParam means someone brought miranda to foreground, that equals to input */ + PCWPSTRUCT cwpInfo = (PCWPSTRUCT)lParam; + if(cwpInfo->message == WM_ACTIVATEAPP && cwpInfo->wParam) + dwLastInput = GetTickCount(); + } + + return CallNextHookEx(hMirandaWndProcHook, code, wParam, lParam); +} + + +//===================== Check Window Message function ===================== + +// Took this snippet of code from "EventNotify" by micron-x, thx *g* +// and updated with NGEventNotify and pete's patch +// checks if the message-dialog window is already opened and returns: +// TRUE - Windows found +// FALSE - No window found + +HWND findMessageWindow(HANDLE hContact) +{ + HWND hwnd; + TCHAR newtitle[256]; + char *szProto, *contactName, *szStatus; + CONTACTINFO ci = {0}; + + szProto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); + contactName = (char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, 0); + szStatus = (char *)CallService(MS_CLIST_GETSTATUSMODEDESCRIPTION, szProto==NULL?ID_STATUS_OFFLINE:DBGetContactSettingWord(hContact, szProto, "Status", ID_STATUS_OFFLINE), 0); + + _snwprintf(newtitle, sizeof(newtitle), _T("%s (%s): %s"), contactName, szStatus, TranslateT("Message Received")); + if(hwnd = FindWindow(NULL, newtitle)) + return hwnd; + + _snwprintf(newtitle, sizeof(newtitle), _T("%s %s"), contactName, szStatus); + if(hwnd = FindWindow(NULL, newtitle)) + return hwnd; + _snwprintf(newtitle, sizeof(newtitle), _T("%s (%s): %s"), contactName, szStatus, TranslateT("Message Session")); + if(hwnd = FindWindow(NULL, newtitle)) + return hwnd; + _snwprintf(newtitle, sizeof(newtitle), _T("%s (%s): %s"), contactName, szStatus, TranslateT("Message Session is typing...")); + if(hwnd = FindWindow(NULL, newtitle)) + return hwnd; + // search for the nconvers++ message window that uses the UIN + ci.cbSize = sizeof(CONTACTINFO); + ci.dwFlag = CNF_UNIQUEID; + ci.hContact = hContact; + if (!CallService(MS_CONTACT_GETCONTACTINFO, 0, (LPARAM)&ci)) { + switch(ci.type) { + case CNFT_BYTE: + _snwprintf(newtitle, sizeof(newtitle), _T("%s (%d) %s"), contactName, ci.bVal, szStatus); + break; + case CNFT_WORD: + _snwprintf(newtitle, sizeof(newtitle), _T("%s (%d) %s"), contactName, ci.wVal, szStatus); + break; + case CNFT_DWORD: + _snwprintf(newtitle, sizeof(newtitle), _T("%s (%d) %s"), contactName, ci.dVal, szStatus); + break; + case CNFT_ASCIIZ: + _snwprintf(newtitle, sizeof(newtitle), _T("%s (%s) %s"), contactName, ci.pszVal, szStatus); + break; + } + if(hwnd = FindWindow(NULL, newtitle)) + return hwnd; + } + + return NULL; +} + +BOOL CheckMsgWnd(HANDLE hContact, BOOL *focus) +{ + if (ServiceExists(MS_MSG_GETWINDOWDATA)) { // use the new message API + MessageWindowData mwd; + MessageWindowInputData mwid; + mwid.cbSize = sizeof(MessageWindowInputData); + mwid.hContact = hContact; + mwid.uFlags = MSG_WINDOW_UFLAG_MSG_BOTH; + mwd.cbSize = sizeof(MessageWindowData); + mwd.hContact = hContact; + if (!CallService(MS_MSG_GETWINDOWDATA, (WPARAM)&mwid, (LPARAM)&mwd) && mwd.hwndWindow) { + *focus = mwd.uState & MSG_WINDOW_STATE_FOCUS; + return TRUE; + } + } else { // old way: find it by using the window class & title + HWND hwnd; + + if(hwnd = findMessageWindow(hContact)) { + *focus = hwnd==GetForegroundWindow(); + return TRUE; + } + } + + *focus = FALSE; + return FALSE; +} + + +void countUnopenEvents(int *msgCount, int *fileCount, int *urlCount, int *otherCount) +{ + int nIndex; + CLISTEVENT *pCLEvent; + + for (nIndex = 0; pCLEvent = (CLISTEVENT*)CallService(MS_CLIST_GETEVENT, -1, nIndex); nIndex++) { + DBEVENTINFO einfo = readEventInfo(pCLEvent->hDbEvent, pCLEvent->hContact); + + if (metaCheckProtocol(einfo.szModule, pCLEvent->hContact, einfo.eventType)) + switch (einfo.eventType) { + case EVENTTYPE_MESSAGE: + if (bFlashOnMsg) + (*msgCount)++; + break; + case EVENTTYPE_URL: + if (bFlashOnURL) + (*urlCount)++; + break; + case EVENTTYPE_FILE: + if (bFlashOnFile) + (*fileCount)++; + break; + default: + if (bFlashOnOther) + (*otherCount)++; + } + } + if (bFlashOnOther) + (*otherCount) += nExternCount; +} diff --git a/plugins/KeyboardNotify/src/options.cpp b/plugins/KeyboardNotify/src/options.cpp new file mode 100644 index 0000000000..d74902aec8 --- /dev/null +++ b/plugins/KeyboardNotify/src/options.cpp @@ -0,0 +1,1565 @@ +/* + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#define WIN32_LEAN_AND_MEAN + +#include +#include +#include +#include +#include +#include "flash.h" +#include "ignore.h" +#include "resource.h" +#include "constants.h" +#include "protolist.h" +#include "EnumProc.h" +#include "utils.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define IDI_BLANK 200 + +#ifndef ETDT_ENABLE +#define ETDT_ENABLE 0x00000002 +#endif +#ifndef ETDT_USETABTEXTURE +#define ETDT_USETABTEXTURE 0x00000004 +#endif +#ifndef ETDT_ENABLETAB +#define ETDT_ENABLETAB (ETDT_ENABLE|ETDT_USETABTEXTURE) +#endif + +#ifndef ListView_SetCheckState +#define ListView_SetCheckState(hLv, iItem, bCheck) \ + ListView_SetItemState(hLv, iItem, bCheck ? INDEXTOSTATEIMAGEMASK(2) : INDEXTOSTATEIMAGEMASK(1), LVIS_STATEIMAGEMASK) +#endif + +#ifndef TVS_NOHSCROLL +#define TVS_NOHSCROLL 0x8000 +#endif + +#ifndef TVM_GETITEMSTATE +#define TVM_GETITEMSTATE (TV_FIRST+39) +#endif + +#ifndef TreeView_SetItemState +#define TreeView_SetItemState(hwndTv, hti, data, _mask) \ + { TVITEM _TVI; \ + _TVI.mask = TVIF_STATE; \ + _TVI.hItem = hti; \ + _TVI.stateMask = _mask; \ + _TVI.state = data; \ + SendMessageA((hwndTv), TVM_SETITEM, 0, (LPARAM)&_TVI); } +#endif + +#ifndef TreeView_GetItemState +#define TreeView_GetItemState(hwndTv, hti, mask) \ + (UINT)SendMessageA((hwndTv), TVM_GETITEMSTATE, (WPARAM)(hti), (LPARAM)(mask)) +#endif + +void LoadSettings(void); +int InitializeOptions(WPARAM,LPARAM); +INT_PTR CALLBACK DlgProcOptions(HWND, UINT, WPARAM, LPARAM); +INT_PTR CALLBACK DlgProcProtoOptions(HWND, UINT, WPARAM, LPARAM); +INT_PTR CALLBACK DlgProcBasicOptions(HWND, UINT, WPARAM, LPARAM); +INT_PTR CALLBACK DlgProcEffectOptions(HWND, UINT, WPARAM, LPARAM); +INT_PTR CALLBACK DlgProcThemeOptions(HWND, UINT, WPARAM, LPARAM); +INT_PTR CALLBACK DlgProcProcesses(HWND, UINT, WPARAM, LPARAM); +INT_PTR CALLBACK DlgProcEventLeds(HWND, UINT, WPARAM, LPARAM); +INT_PTR CALLBACK DlgProcXstatusList(HWND, UINT, WPARAM, LPARAM); +void exportThemes(const TCHAR *); +void importThemes(const TCHAR *, BOOL); +void writeThemeToCombo(const TCHAR *, const TCHAR *, BOOL); +void createProcessListAux(void); +void destroyProcessListAux(void); +void createXstatusListAux(void); +void destroyXstatusListAux(void); + + +extern HINSTANCE hInst; +extern double dWinVer; +extern BOOL bWindowsNT; + +extern BYTE bFlashOnMsg; +extern BYTE bFlashOnURL; +extern BYTE bFlashOnFile; +extern BYTE bFlashOnOther; +extern BYTE bFullScreenMode; +extern BYTE bScreenSaverRunning; +extern BYTE bWorkstationLocked; +extern BYTE bProcessesAreRunning; +extern BYTE bWorkstationActive; +extern BYTE bFlashIfMsgOpen; +extern BYTE bFlashIfMsgOlder; +extern WORD wSecondsOlder; +extern BYTE bFlashUntil; +extern WORD wBlinksNumber; +extern BYTE bMirandaOrWindows; +extern WORD wStatusMap; +extern WORD wReminderCheck; +extern BYTE bFlashLed[3]; +extern BYTE bFlashEffect; +extern BYTE bSequenceOrder; +extern WORD wCustomTheme; +extern WORD wStartDelay; +extern BYTE bFlashSpeed; +extern BYTE bEmulateKeypresses; +extern BYTE bOverride; +extern BYTE bFlashIfMsgWinNotTop; +extern BYTE bTrillianLedsMsg; +extern BYTE bTrillianLedsURL; +extern BYTE bTrillianLedsFile; +extern BYTE bTrillianLedsOther; + +extern PROTOCOL_LIST ProtoList; +extern PROCESS_LIST ProcessList; + +HWND hwndProto, hwndBasic, hwndEffect, hwndTheme, hwndIgnore, hwndCurrentTab; + +TCHAR *AttendedName[]={_T("Miranda"), _T("Windows")}; +TCHAR *OrderName[]={_T("left->right"), _T("right->left"), _T("left<->right")}; + +PROCESS_LIST ProcessListAux; +XSTATUS_INFO *XstatusListAux; +BYTE trillianLedsMsg, trillianLedsURL, trillianLedsFile, trillianLedsOther; + +static BOOL (WINAPI *pfnEnableThemeDialogTexture)(HANDLE, DWORD) = 0; + + +// ** +// ** Initialize the Miranda options page +// ** +int InitializeOptions(WPARAM wParam,LPARAM lParam) +{ + if (bWindowsNT && dWinVer >= 5.01) { + HMODULE hUxTheme = GetModuleHandle(L"uxtheme.dll"); + if(hUxTheme) + pfnEnableThemeDialogTexture = (BOOL (WINAPI *)(HANDLE, DWORD))GetProcAddress(hUxTheme, "EnableThemeDialogTexture"); + } + + OPTIONSDIALOGPAGE odp = { 0 }; + odp.cbSize = sizeof(odp); + odp.position = 0; + odp.hInstance = hInst; + odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS); + odp.pszTitle = LPGEN("Keyboard Flash"); + odp.pszGroup = LPGEN("Plugins"); + odp.groupPosition = 910000000; + odp.flags = ODPF_BOLDGROUPS; + odp.pfnDlgProc = DlgProcOptions; + odp.nIDBottomSimpleControl = 0; + Options_AddPage(wParam, &odp); + + return 0; +} + +INT_PTR CALLBACK DlgProcOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) { + case WM_INITDIALOG: + { + HWND tc; + TCITEM tci; + tc = GetDlgItem(hwndDlg, IDC_TABS); + tci.mask = TCIF_TEXT; + tci.pszText = TranslateT("Protocols"); + TabCtrl_InsertItem(tc, 0, &tci); + tci.pszText = TranslateT("Rules"); + TabCtrl_InsertItem(tc, 1, &tci); + tci.pszText = TranslateT("Flashing"); + TabCtrl_InsertItem(tc, 2, &tci); + tci.pszText = TranslateT("Themes"); + TabCtrl_InsertItem(tc, 3, &tci); + tci.pszText = TranslateT("Ignore"); + TabCtrl_InsertItem(tc, 4, &tci); + + hwndProto = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_PROTO_OPTIONS), hwndDlg, DlgProcProtoOptions, (LPARAM) NULL); + if(hwndProto && pfnEnableThemeDialogTexture) + pfnEnableThemeDialogTexture(hwndProto, ETDT_ENABLETAB); + SetWindowPos(hwndProto, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + ShowWindow(hwndProto, SW_SHOW); + hwndBasic = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_BASIC_OPTIONS), hwndDlg, DlgProcBasicOptions, (LPARAM) NULL); + if(hwndBasic && pfnEnableThemeDialogTexture) + pfnEnableThemeDialogTexture(hwndBasic, ETDT_ENABLETAB); + SetWindowPos(hwndBasic, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + hwndEffect = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_EFFECT_OPTIONS), hwndDlg, DlgProcEffectOptions, (LPARAM) NULL); + if(hwndEffect && pfnEnableThemeDialogTexture) + pfnEnableThemeDialogTexture(hwndEffect, ETDT_ENABLETAB); + SetWindowPos(hwndEffect, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + hwndTheme = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_THEME_OPTIONS), hwndDlg, DlgProcThemeOptions, (LPARAM) NULL); + if(hwndTheme && pfnEnableThemeDialogTexture) + pfnEnableThemeDialogTexture(hwndTheme, ETDT_ENABLETAB); + SetWindowPos(hwndTheme, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + hwndIgnore = CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_IGNORE_OPTIONS), hwndDlg, DlgProcIgnoreOptions, (LPARAM) NULL); + if(hwndIgnore && pfnEnableThemeDialogTexture) + pfnEnableThemeDialogTexture(hwndIgnore, ETDT_ENABLETAB); + SetWindowPos(hwndIgnore, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + hwndCurrentTab = hwndProto; + return TRUE; + + } + case WM_COMMAND: + break; + case WM_NOTIFY: + { + switch (((LPNMHDR) lParam)->code) { + case TCN_SELCHANGE: + switch (wParam) { + case IDC_TABS: + { + HWND hwnd; + switch (TabCtrl_GetCurSel(GetDlgItem(hwndDlg, IDC_TABS))) { + default: + case 0: + hwnd = hwndProto; + break; + case 1: + hwnd = hwndBasic; + break; + case 2: + hwnd = hwndEffect; + break; + case 3: + hwnd = hwndTheme; + break; + case 4: + hwnd = hwndIgnore; + break; + } + if (hwnd!=hwndCurrentTab) { + ShowWindow(hwnd, SW_SHOW); + ShowWindow(hwndCurrentTab, SW_HIDE); + hwndCurrentTab = hwnd; + } + } + break; + } + break; + case PSN_APPLY: + SendMessage(hwndProto, WM_NOTIFY, wParam, lParam); + SendMessage(hwndBasic, WM_NOTIFY, wParam, lParam); + SendMessage(hwndEffect, WM_NOTIFY, wParam, lParam); + SendMessage(hwndTheme, WM_NOTIFY, wParam, lParam); + SendMessage(hwndIgnore, WM_NOTIFY, wParam, lParam); + return TRUE; + } + } + break; + case WM_DESTROY: + break; + } + return FALSE; +} + + +INT_PTR CALLBACK DlgProcProtoOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static BOOL initDlg=FALSE; + + switch (msg) { + + case WM_INITDIALOG: + initDlg=TRUE; + TranslateDialogDefault(hwndDlg); + + // proto list + { + unsigned int i; + LVCOLUMN lvCol; + LVITEM lvItem; + HWND hList = GetDlgItem(hwndDlg, IDC_PROTOCOLLIST); + + // create columns + ListView_SetExtendedListViewStyleEx(hList, LVS_EX_CHECKBOXES, LVS_EX_CHECKBOXES); + memset(&lvCol, 0, sizeof(lvCol)); + lvCol.mask = LVCF_WIDTH|LVCF_TEXT; + lvCol.pszText = TranslateT("Protocol"); + lvCol.cx = 118; + ListView_InsertColumn(hList, 0, &lvCol); + // fill + memset(&lvItem, 0, sizeof(lvItem)); + lvItem.mask = LVIF_TEXT|LVIF_PARAM; + lvItem.cchTextMax = 256; + lvItem.iItem = 0; + lvItem.iSubItem = 0; + for(i=0; i < ProtoList.protoCount; i++) { + int count; PROTOACCOUNT** protos; + ProtoEnumAccounts( &count, &protos ); + if(ProtoList.protoInfo[i].visible) { + lvItem.lParam = (LPARAM)ProtoList.protoInfo[i].szProto; + lvItem.pszText = protos[i] -> tszAccountName; + ListView_InsertItem(hList, &lvItem); + ListView_SetCheckState(hList, lvItem.iItem, ProtoList.protoInfo[i].enabled); + lvItem.iItem++; + } + } + } + + initDlg=FALSE; + return TRUE; + + case WM_NOTIFY: + { + //Here we have pressed either the OK or the APPLY button. + switch(((LPNMHDR)lParam)->idFrom) { + case 0: + switch (((LPNMHDR)lParam)->code) { + case PSN_APPLY: + // enabled protos + { + int i; + LVITEM lvItem; + HWND hList = GetDlgItem(hwndDlg, IDC_PROTOCOLLIST); + + memset(&lvItem, 0, sizeof(lvItem)); + lvItem.mask = LVIF_PARAM; + lvItem.iSubItem = 0; + for (i=0; i < ListView_GetItemCount(hList); i++) { + lvItem.iItem = i; + ListView_GetItem(hList, &lvItem); + DBWriteContactSettingByte(NULL, KEYBDMODULE, (char *)lvItem.lParam, (BYTE)!!ListView_GetCheckState(hList, lvItem.iItem)); + } + } + + LoadSettings(); + + return TRUE; + } // switch code - 0 + break; + case IDC_PROTOCOLLIST: + switch(((NMHDR*)lParam)->code) { + case LVN_ITEMCHANGED: + { + NMLISTVIEW *nmlv = (NMLISTVIEW *)lParam; + + if (!initDlg && ((nmlv->uNewState ^ nmlv->uOldState) & LVIS_STATEIMAGEMASK)) + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + } + break; + } // switch code - IDC_PROTOCOLLIST + break; + } //switch idFrom + } + break; //End WM_NOTIFY + + default: + break; + } + + return FALSE; +} + +INT_PTR CALLBACK DlgProcBasicOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + unsigned int i; + static BOOL initDlg=FALSE; + + switch (msg) { + + case WM_INITDIALOG: + initDlg=TRUE; + TranslateDialogDefault(hwndDlg); + + createProcessListAux(); + createXstatusListAux(); + + CheckDlgButton(hwndDlg, IDC_ONMESSAGE, bFlashOnMsg ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_ONURL, bFlashOnURL ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_ONFILE, bFlashOnFile ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_ONOTHER, bFlashOnOther ? BST_CHECKED:BST_UNCHECKED); + + CheckDlgButton(hwndDlg, IDC_FSCREEN, bFullScreenMode ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_SSAVER, bScreenSaverRunning ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_LOCKED, bWorkstationLocked ? BST_CHECKED:BST_UNCHECKED); + if (!bWindowsNT) + EnableWindow(GetDlgItem(hwndDlg, IDC_LOCKED), FALSE); + CheckDlgButton(hwndDlg, IDC_PGMS, bProcessesAreRunning ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_ACTIVE, bWorkstationActive ? BST_CHECKED:BST_UNCHECKED); + + CheckDlgButton(hwndDlg, IDC_IFOPEN, bFlashIfMsgOpen ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_IFNOTTOP, bFlashIfMsgWinNotTop ? BST_CHECKED:BST_UNCHECKED); + if (!bFlashIfMsgOpen) + EnableWindow(GetDlgItem(hwndDlg, IDC_IFNOTTOP), FALSE); + CheckDlgButton(hwndDlg, IDC_IFOLDER, bFlashIfMsgOlder ? BST_CHECKED:BST_UNCHECKED); + SendDlgItemMessage(hwndDlg, IDC_OLDERSPIN, UDM_SETBUDDY, (WPARAM)GetDlgItem(hwndDlg, IDC_SOLDER), 0); + SendDlgItemMessage(hwndDlg, IDC_OLDERSPIN, UDM_SETRANGE32, 1, MAKELONG(UD_MAXVAL, 0)); + SendDlgItemMessage(hwndDlg, IDC_OLDERSPIN, UDM_SETPOS, 0, MAKELONG(wSecondsOlder, 0)); + if (!bFlashIfMsgOlder) { + EnableWindow(GetDlgItem(hwndDlg, IDC_SOLDER), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_OLDERSPIN), FALSE); + } + + CheckDlgButton(hwndDlg, IDC_UNTILBLK, bFlashUntil&UNTIL_NBLINKS ? BST_CHECKED:BST_UNCHECKED); + SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_SETBUDDY, (WPARAM)GetDlgItem(hwndDlg, IDC_SBLINK), 0); + SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_SETRANGE32, 1, MAKELONG(UD_MAXVAL, 0)); + SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_SETPOS, 0, MAKELONG(wBlinksNumber, 0)); + if (!(bFlashUntil & UNTIL_NBLINKS)) { + EnableWindow(GetDlgItem(hwndDlg, IDC_SBLINK), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_BLINKSPIN), FALSE); + } + CheckDlgButton(hwndDlg, IDC_UNTILATTENDED, bFlashUntil&UNTIL_REATTENDED ? BST_CHECKED:BST_UNCHECKED); + for (i=0; i < 2; i++) { + int index = SendDlgItemMessage(hwndDlg, IDC_MIRORWIN, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)AttendedName[i]); + if (index != CB_ERR && index != CB_ERRSPACE) + SendDlgItemMessage(hwndDlg, IDC_MIRORWIN, CB_SETITEMDATA, (WPARAM)index, (LPARAM)i); + } + SendDlgItemMessage(hwndDlg, IDC_MIRORWIN, CB_SETCURSEL, (WPARAM)bMirandaOrWindows, 0); + if (!(bFlashUntil & UNTIL_REATTENDED)) + EnableWindow(GetDlgItem(hwndDlg, IDC_MIRORWIN), FALSE); + CheckDlgButton(hwndDlg, IDC_UNTILOPEN, bFlashUntil&UNTIL_EVENTSOPEN ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_UNTILCOND, bFlashUntil&UNTIL_CONDITIONS ? BST_CHECKED:BST_UNCHECKED); + + CheckDlgButton(hwndDlg, IDC_ONLINE, wStatusMap&MAP_ONLINE ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_AWAY, wStatusMap&MAP_AWAY ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_NA, wStatusMap&MAP_NA ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_OCCUPIED, wStatusMap&MAP_OCCUPIED ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_DND, wStatusMap&MAP_DND ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_FREECHAT, wStatusMap&MAP_FREECHAT ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_INVISIBLE, wStatusMap&MAP_INVISIBLE ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_ONTHEPHONE, wStatusMap&MAP_ONTHEPHONE ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_OUTTOLUNCH, wStatusMap&MAP_OUTTOLUNCH ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_OFFLINE, wStatusMap&MAP_OFFLINE ? BST_CHECKED:BST_UNCHECKED); + + SendDlgItemMessage(hwndDlg, IDC_REMCHECK, UDM_SETBUDDY, (WPARAM)GetDlgItem(hwndDlg, IDC_SREMCHECK), 0); + SendDlgItemMessage(hwndDlg, IDC_REMCHECK, UDM_SETRANGE32, 0, MAKELONG(UD_MAXVAL, 0)); + SendDlgItemMessage(hwndDlg, IDC_REMCHECK, UDM_SETPOS, 0, MAKELONG(wReminderCheck, 0)); + + initDlg=FALSE; + return TRUE; + + case WM_VSCROLL: + case WM_HSCROLL: + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + break; + + case WM_DESTROY: + destroyProcessListAux(); + destroyXstatusListAux(); + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_ONMESSAGE: + case IDC_ONURL: + case IDC_ONFILE: + case IDC_ONOTHER: + case IDC_IFOPEN: + case IDC_IFNOTTOP: + case IDC_IFOLDER: + case IDC_UNTILBLK: + case IDC_UNTILATTENDED: + case IDC_MIRORWIN: + case IDC_UNTILOPEN: + case IDC_UNTILCOND: + case IDC_FSCREEN: + case IDC_SSAVER: + case IDC_LOCKED: + case IDC_PGMS: + case IDC_ACTIVE: + case IDC_ONLINE: + case IDC_AWAY: + case IDC_NA: + case IDC_OCCUPIED: + case IDC_DND: + case IDC_FREECHAT: + case IDC_INVISIBLE: + case IDC_ONTHEPHONE: + case IDC_OUTTOLUNCH: + case IDC_OFFLINE: + EnableWindow(GetDlgItem(hwndDlg, IDC_IFNOTTOP), IsDlgButtonChecked(hwndDlg, IDC_IFOPEN) == BST_CHECKED); + EnableWindow(GetDlgItem(hwndDlg, IDC_SOLDER), IsDlgButtonChecked(hwndDlg, IDC_IFOLDER) == BST_CHECKED); + EnableWindow(GetDlgItem(hwndDlg, IDC_OLDERSPIN), IsDlgButtonChecked(hwndDlg, IDC_IFOLDER) == BST_CHECKED); + EnableWindow(GetDlgItem(hwndDlg, IDC_SBLINK), IsDlgButtonChecked(hwndDlg, IDC_UNTILBLK) == BST_CHECKED); + EnableWindow(GetDlgItem(hwndDlg, IDC_BLINKSPIN), IsDlgButtonChecked(hwndDlg, IDC_UNTILBLK) == BST_CHECKED); + EnableWindow(GetDlgItem(hwndDlg, IDC_MIRORWIN), IsDlgButtonChecked(hwndDlg, IDC_UNTILATTENDED) == BST_CHECKED); + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + return TRUE; + case IDC_SOLDER: + if(HIWORD(wParam) == EN_CHANGE && !initDlg) { + BOOL translated; + int val = GetDlgItemInt(hwndDlg, IDC_SOLDER, &translated, FALSE); + if (translated && val < 1) + SendDlgItemMessage(hwndDlg, IDC_OLDERSPIN, UDM_SETPOS, 0, MAKELONG(val, 0)); + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + } + return TRUE; + case IDC_SBLINK: + if(HIWORD(wParam) == EN_CHANGE && !initDlg) { + BOOL translated; + int val = GetDlgItemInt(hwndDlg, IDC_SBLINK, &translated, FALSE); + if (translated && val < 1) + SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_SETPOS, 0, MAKELONG(val, 0)); + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + } + return TRUE; + case IDC_ASSIGNPGMS: + if (DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_PROCESSES), hwndDlg, DlgProcProcesses, 0) == IDC_OKPGM) + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + return TRUE; + case IDC_SELECTXSTATUS: + if (DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_XSTATUSES), hwndDlg, DlgProcXstatusList, 0) == IDC_OKXST) + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + return TRUE; + case IDC_SREMCHECK: + if(HIWORD(wParam) == EN_CHANGE && !initDlg) + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + return TRUE; + } + break; + + case WM_NOTIFY: + { + unsigned int j; + BYTE untilMap = 0; + WORD statusMap = 0; + //Here we have pressed either the OK or the APPLY button. + switch(((LPNMHDR)lParam)->idFrom) { + case 0: + switch (((LPNMHDR)lParam)->code) { + case PSN_APPLY: + DBWriteContactSettingByte(NULL, KEYBDMODULE, "onmsg", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_ONMESSAGE) == BST_CHECKED ? 1:0)); + DBWriteContactSettingByte(NULL, KEYBDMODULE, "onurl", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_ONURL) == BST_CHECKED ? 1:0)); + DBWriteContactSettingByte(NULL, KEYBDMODULE, "onfile", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_ONFILE) == BST_CHECKED ? 1:0)); + DBWriteContactSettingByte(NULL, KEYBDMODULE, "onother", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_ONOTHER) == BST_CHECKED ? 1:0)); + + DBWriteContactSettingByte(NULL, KEYBDMODULE, "fscreenmode", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_FSCREEN) == BST_CHECKED ? 1:0)); + DBWriteContactSettingByte(NULL, KEYBDMODULE, "ssaverrunning", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_SSAVER) == BST_CHECKED ? 1:0)); + DBWriteContactSettingByte(NULL, KEYBDMODULE, "wstationlocked", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_LOCKED) == BST_CHECKED ? 1:0)); + DBWriteContactSettingByte(NULL, KEYBDMODULE, "procsrunning", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_PGMS) == BST_CHECKED ? 1:0)); + DBWriteContactSettingByte(NULL, KEYBDMODULE, "wstationactive", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_ACTIVE) == BST_CHECKED ? 1:0)); + + DBWriteContactSettingByte(NULL, KEYBDMODULE, "ifmsgopen", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_IFOPEN) == BST_CHECKED ? 1:0)); + DBWriteContactSettingByte(NULL, KEYBDMODULE, "ifmsgnottop", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_IFNOTTOP) == BST_CHECKED ? 1:0)); + DBWriteContactSettingByte(NULL, KEYBDMODULE, "ifmsgolder", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_IFOLDER) == BST_CHECKED ? 1:0)); + DBWriteContactSettingWord(NULL, KEYBDMODULE, "secsolder", (WORD)SendDlgItemMessage(hwndDlg, IDC_OLDERSPIN, UDM_GETPOS, 0, 0)); + + if(IsDlgButtonChecked(hwndDlg, IDC_UNTILBLK) == BST_CHECKED) + untilMap |= UNTIL_NBLINKS; + if (IsDlgButtonChecked(hwndDlg, IDC_UNTILATTENDED) == BST_CHECKED) + untilMap |= UNTIL_REATTENDED; + if (IsDlgButtonChecked(hwndDlg, IDC_UNTILOPEN) == BST_CHECKED) + untilMap |= UNTIL_EVENTSOPEN; + if (IsDlgButtonChecked(hwndDlg, IDC_UNTILCOND) == BST_CHECKED) + untilMap |= UNTIL_CONDITIONS; + DBWriteContactSettingByte(NULL, KEYBDMODULE, "funtil", untilMap); + DBWriteContactSettingWord(NULL, KEYBDMODULE, "nblinks", (WORD)SendDlgItemMessage(hwndDlg, IDC_BLINKSPIN, UDM_GETPOS, 0, 0)); + DBWriteContactSettingByte(NULL, KEYBDMODULE, "mirorwin", (BYTE)SendDlgItemMessage(hwndDlg, IDC_MIRORWIN, CB_GETITEMDATA, (WPARAM)SendDlgItemMessage(hwndDlg, IDC_MIRORWIN, CB_GETCURSEL, 0, 0), 0)); + + if(IsDlgButtonChecked(hwndDlg, IDC_ONLINE) == BST_CHECKED) + statusMap |= MAP_ONLINE; + if(IsDlgButtonChecked(hwndDlg, IDC_AWAY) == BST_CHECKED) + statusMap |= MAP_AWAY; + if(IsDlgButtonChecked(hwndDlg, IDC_NA) == BST_CHECKED) + statusMap |= MAP_NA; + if(IsDlgButtonChecked(hwndDlg, IDC_OCCUPIED) == BST_CHECKED) + statusMap |= MAP_OCCUPIED; + if(IsDlgButtonChecked(hwndDlg, IDC_DND) == BST_CHECKED) + statusMap |= MAP_DND; + if(IsDlgButtonChecked(hwndDlg, IDC_FREECHAT) == BST_CHECKED) + statusMap |= MAP_FREECHAT; + if(IsDlgButtonChecked(hwndDlg, IDC_INVISIBLE) == BST_CHECKED) + statusMap |= MAP_INVISIBLE; + if(IsDlgButtonChecked(hwndDlg, IDC_ONTHEPHONE) == BST_CHECKED) + statusMap |= MAP_ONTHEPHONE; + if(IsDlgButtonChecked(hwndDlg, IDC_OUTTOLUNCH) == BST_CHECKED) + statusMap |= MAP_OUTTOLUNCH; + if(IsDlgButtonChecked(hwndDlg, IDC_OFFLINE) == BST_CHECKED) + statusMap |= MAP_OFFLINE; + DBWriteContactSettingWord(NULL, KEYBDMODULE, "status", statusMap); + + DBWriteContactSettingWord(NULL, KEYBDMODULE, "remcheck", (WORD)SendDlgItemMessage(hwndDlg, IDC_REMCHECK, UDM_GETPOS, 0, 0)); + + for (i=0, j=0; j < ProcessListAux.count; j++) + if (ProcessListAux.szFileName[j]) + DBWriteContactSettingWString(NULL, KEYBDMODULE, fmtDBSettingName("process%d", i++), ProcessListAux.szFileName[j]); + DBWriteContactSettingWord(NULL, KEYBDMODULE, "processcount", (WORD)i); + while (!DBDeleteContactSetting(NULL, KEYBDMODULE, fmtDBSettingName("process%d", i++))); + + if (XstatusListAux) + for (i=0; i < ProtoList.protoCount; i++) + for(j=0; j < XstatusListAux[i].count; j++) + DBWriteContactSettingByte(NULL, KEYBDMODULE, fmtDBSettingName("%sxstatus%d", ProtoList.protoInfo[i].szProto, j), (BYTE)XstatusListAux[i].enabled[j]); + + LoadSettings(); + + return TRUE; + } // switch code + break; + } //switch idFrom + } + break; //End WM_NOTIFY + + default: + break; + } + + return FALSE; +} + +INT_PTR CALLBACK DlgProcEffectOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + int i; + DBVARIANT dbv; + static BOOL initDlg=FALSE; + + switch (msg) { + + case WM_INITDIALOG: + initDlg=TRUE; + TranslateDialogDefault(hwndDlg); + + trillianLedsMsg = bTrillianLedsMsg; + trillianLedsURL = bTrillianLedsURL; + trillianLedsFile = bTrillianLedsFile; + trillianLedsOther = bTrillianLedsOther; + + CheckDlgButton(hwndDlg, IDC_NUM, bFlashLed[0] ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_CAPS, bFlashLed[1] ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_SCROLL, bFlashLed[2] ? BST_CHECKED:BST_UNCHECKED); + + CheckDlgButton(hwndDlg, IDC_SAMETIME, bFlashEffect == FLASH_SAMETIME ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_INTURN, bFlashEffect == FLASH_INTURN ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_INSEQUENCE, bFlashEffect == FLASH_INSEQUENCE ? BST_CHECKED:BST_UNCHECKED); + for (i=0; i < 3; i++) { + int index = SendDlgItemMessage(hwndDlg, IDC_SEQORDER, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)(OrderName[i])); + if (index != CB_ERR && index != CB_ERRSPACE) + SendDlgItemMessage(hwndDlg, IDC_SEQORDER, CB_SETITEMDATA, (WPARAM)index, (LPARAM)i); + } + SendDlgItemMessage(hwndDlg, IDC_SEQORDER, CB_SETCURSEL, (WPARAM)bSequenceOrder, 0); + if (bFlashEffect != FLASH_INSEQUENCE) + EnableWindow(GetDlgItem(hwndDlg, IDC_SEQORDER), FALSE); + CheckDlgButton(hwndDlg, IDC_CUSTOM, bFlashEffect == FLASH_CUSTOM ? BST_CHECKED:BST_UNCHECKED); + for (i=0; !DBGetContactSetting(NULL, KEYBDMODULE, fmtDBSettingName("theme%d", i), &dbv); i++) { + int index = SendDlgItemMessage(hwndDlg, IDC_SCUSTOM, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)dbv.ptszVal); + DBFreeVariant(&dbv); + if (index != CB_ERR && index != CB_ERRSPACE) + SendDlgItemMessage(hwndDlg, IDC_SCUSTOM, CB_SETITEMDATA, (WPARAM)index, (LPARAM)i); + } + SendDlgItemMessage(hwndDlg, IDC_SCUSTOM, CB_SETCURSEL, (WPARAM)wCustomTheme, 0); + if (bFlashEffect != FLASH_CUSTOM) + EnableWindow(GetDlgItem(hwndDlg, IDC_SCUSTOM), FALSE); + CheckDlgButton(hwndDlg, IDC_TRILLIAN, bFlashEffect == FLASH_TRILLIAN ? BST_CHECKED:BST_UNCHECKED); + if (bFlashEffect != FLASH_TRILLIAN) + EnableWindow(GetDlgItem(hwndDlg, IDC_ASSIGNLEDS), FALSE); + + SendDlgItemMessage(hwndDlg, IDC_DELAYSPIN, UDM_SETBUDDY, (WPARAM)GetDlgItem(hwndDlg, IDC_SDELAY), 0); + SendDlgItemMessage(hwndDlg, IDC_DELAYSPIN, UDM_SETRANGE32, 0, MAKELONG(UD_MAXVAL, 0)); + SendDlgItemMessage(hwndDlg, IDC_DELAYSPIN, UDM_SETPOS, 0, MAKELONG(wStartDelay, 0)); + + SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_SETRANGE, FALSE, MAKELONG(0, 5)); + SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_SETPOS, TRUE, bFlashSpeed); + + CheckDlgButton(hwndDlg, IDC_KEYPRESSES, bEmulateKeypresses ? BST_CHECKED:BST_UNCHECKED); + + initDlg=FALSE; + return TRUE; + + case WM_VSCROLL: + case WM_HSCROLL: + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + break; + + case WM_DESTROY: + previewFlashing(FALSE); + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_NUM: + case IDC_CAPS: + case IDC_SCROLL: + case IDC_SAMETIME: + case IDC_INTURN: + case IDC_INSEQUENCE: + case IDC_SEQORDER: + case IDC_CUSTOM: + case IDC_TRILLIAN: + case IDC_SCUSTOM: + case IDC_SPEED: + case IDC_KEYPRESSES: + EnableWindow(GetDlgItem(hwndDlg, IDC_SEQORDER), IsDlgButtonChecked(hwndDlg, IDC_INSEQUENCE) == BST_CHECKED); + EnableWindow(GetDlgItem(hwndDlg, IDC_SCUSTOM), IsDlgButtonChecked(hwndDlg, IDC_CUSTOM) == BST_CHECKED); + EnableWindow(GetDlgItem(hwndDlg, IDC_ASSIGNLEDS), IsDlgButtonChecked(hwndDlg, IDC_TRILLIAN) == BST_CHECKED); + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + return TRUE; + case IDC_ASSIGNLEDS: + if (DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_EVENTLEDS), hwndDlg, DlgProcEventLeds, 0) == IDC_OK) + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + return TRUE; + case IDC_SDELAY: + if(HIWORD(wParam) == EN_CHANGE && !initDlg) + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + return TRUE; + case IDC_PREVIEW: + previewFlashing(IsDlgButtonChecked(hwndDlg, IDC_PREVIEW) == BST_CHECKED); + return TRUE; + } + break; + + case WM_NOTIFY: + { + //Here we have pressed either the OK or the APPLY button. + switch(((LPNMHDR)lParam)->idFrom) { + case 0: + switch (((LPNMHDR)lParam)->code) { + case PSN_APPLY: + DBWriteContactSettingByte(NULL, KEYBDMODULE, "fnum", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_NUM) == BST_CHECKED ? 1:0)); + DBWriteContactSettingByte(NULL, KEYBDMODULE, "fcaps", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_CAPS) == BST_CHECKED ? 1:0)); + DBWriteContactSettingByte(NULL, KEYBDMODULE, "fscroll", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_SCROLL) == BST_CHECKED ? 1:0)); + + if(IsDlgButtonChecked(hwndDlg, IDC_INTURN) == BST_CHECKED) + DBWriteContactSettingByte(NULL, KEYBDMODULE, "feffect", FLASH_INTURN); + else + if (IsDlgButtonChecked(hwndDlg, IDC_INSEQUENCE) == BST_CHECKED) + DBWriteContactSettingByte(NULL, KEYBDMODULE, "feffect", FLASH_INSEQUENCE); + else + if (IsDlgButtonChecked(hwndDlg, IDC_CUSTOM) == BST_CHECKED) + DBWriteContactSettingByte(NULL, KEYBDMODULE, "feffect", FLASH_CUSTOM); + else + if (IsDlgButtonChecked(hwndDlg, IDC_TRILLIAN) == BST_CHECKED) + DBWriteContactSettingByte(NULL, KEYBDMODULE, "feffect", FLASH_TRILLIAN); + else + DBWriteContactSettingByte(NULL, KEYBDMODULE, "feffect", FLASH_SAMETIME); + DBWriteContactSettingByte(NULL, KEYBDMODULE, "order", (BYTE)SendDlgItemMessage(hwndDlg, IDC_SEQORDER, CB_GETITEMDATA, (WPARAM)SendDlgItemMessage(hwndDlg, IDC_SEQORDER, CB_GETCURSEL, 0, 0), 0)); + DBWriteContactSettingWord(NULL, KEYBDMODULE, "custom", (WORD)SendDlgItemMessage(hwndDlg, IDC_SCUSTOM, CB_GETITEMDATA, (WPARAM)SendDlgItemMessage(hwndDlg, IDC_SCUSTOM, CB_GETCURSEL, 0, 0), 0)); + + DBWriteContactSettingByte(NULL, KEYBDMODULE, "ledsmsg", trillianLedsMsg); + DBWriteContactSettingByte(NULL, KEYBDMODULE, "ledsfile", trillianLedsFile); + DBWriteContactSettingByte(NULL, KEYBDMODULE, "ledsurl", trillianLedsURL); + DBWriteContactSettingByte(NULL, KEYBDMODULE, "ledsother", trillianLedsOther); + + DBWriteContactSettingWord(NULL, KEYBDMODULE, "sdelay", (WORD)SendDlgItemMessage(hwndDlg, IDC_DELAYSPIN, UDM_GETPOS, 0, 0)); + + DBWriteContactSettingByte(NULL, KEYBDMODULE, "speed", (BYTE)SendDlgItemMessage(hwndDlg, IDC_SPEED, TBM_GETPOS, 0, 0)); + + DBWriteContactSettingByte(NULL, KEYBDMODULE, "keypresses", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_KEYPRESSES) == BST_CHECKED ? 1:0)); + + LoadSettings(); + + return TRUE; + } // switch code + break; + } //switch idFrom + } + break; //End WM_NOTIFY + + default: + break; + } + + return FALSE; +} + +INT_PTR CALLBACK DlgProcThemeOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + int i; + TCHAR *str; + DBVARIANT dbv; + static BOOL initDlg=FALSE; + + switch (msg) { + + case WM_INITDIALOG: + initDlg=TRUE; + TranslateDialogDefault(hwndDlg); + + SendDlgItemMessage(hwndDlg, IDC_THEME, EM_LIMITTEXT, MAX_PATH, 0); + SendDlgItemMessage(hwndDlg, IDC_CUSTOMSTRING, EM_LIMITTEXT, MAX_PATH, 0); + + for (i=0; !DBGetContactSetting(NULL, KEYBDMODULE, fmtDBSettingName("theme%d", i), &dbv); i++) { + int index = SendDlgItemMessage(hwndDlg, IDC_THEME, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)dbv.pszVal); + DBFreeVariant(&dbv); + if (index != CB_ERR && index != CB_ERRSPACE) { + str = (TCHAR *)malloc(MAX_PATH+1); + if (str) + if (DBGetContactSetting(NULL, KEYBDMODULE, fmtDBSettingName("custom%d", i), &dbv)) + str[0] = _T('\0'); + else { + wcscpy(str, dbv.ptszVal); + DBFreeVariant(&dbv); + } + SendDlgItemMessage(hwndDlg, IDC_THEME, CB_SETITEMDATA, (WPARAM)index, (LPARAM)str); + } + } + + EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), FALSE); + if (SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETCOUNT, 0, 0) == 0) + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE), FALSE); + else { + SendDlgItemMessage(hwndDlg, IDC_THEME, CB_SETCURSEL, (WPARAM)wCustomTheme, 0); + str = (TCHAR *)SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETITEMDATA, (WPARAM)wCustomTheme, 0); + if (str) + SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, str); + } + + CheckDlgButton(hwndDlg, IDC_OVERRIDE, bOverride ? BST_CHECKED:BST_UNCHECKED); + + initDlg=FALSE; + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_THEME: + switch (HIWORD(wParam)) { + int item; + TCHAR theme[MAX_PATH+1]; + + case CBN_SELENDOK: + case CBN_SELCHANGE: + str = (TCHAR *)SendMessage((HWND)lParam, CB_GETITEMDATA, (WPARAM)SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0), 0); + if (str) + SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, str); + else + SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, _T("")); + EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE), TRUE); + break; + case CBN_EDITCHANGE: + GetDlgItemText(hwndDlg, IDC_THEME, theme, sizeof(theme)); + if ((item = SendMessage((HWND)lParam, CB_FINDSTRINGEXACT, -1, (LPARAM)theme)) == CB_ERR) { //new theme + SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, _T("")); + EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE), FALSE); + } else { + str = (TCHAR *)SendMessage((HWND)lParam, CB_GETITEMDATA, (WPARAM)item, 0); + if (str) + SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, str); + else + SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, _T("")); + EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE), TRUE); + } + EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), FALSE); + break; + } + return TRUE; + case IDC_CUSTOMSTRING: + if(HIWORD(wParam) == EN_CHANGE) { + int item; + TCHAR theme[MAX_PATH+1], customAux[MAX_PATH+1]; + + GetDlgItemText(hwndDlg, IDC_THEME, theme, sizeof(theme)); + if ((item = SendDlgItemMessage(hwndDlg, IDC_THEME, CB_FINDSTRINGEXACT, -1, (LPARAM)theme)) == CB_ERR) + return TRUE; + str = (TCHAR *)SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETITEMDATA, (WPARAM)item, 0); + if (str) { + GetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, customAux, MAX_PATH); + if (wcscmp(str, customAux)) + EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), TRUE); + else + EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), FALSE); + } + } + return TRUE; + case IDC_TEST: + { + TCHAR custom[MAX_PATH+1]; + + GetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, custom, MAX_PATH); + SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, normalizeCustomString(custom)); + testSequence(custom); + } + return TRUE; + case IDC_ADD: + { + int item; + TCHAR theme[MAX_PATH+1]; + + GetDlgItemText(hwndDlg, IDC_THEME, theme, sizeof(theme)); + if (!theme[0]) + return TRUE; + item = SendDlgItemMessage(hwndDlg, IDC_THEME, CB_ADDSTRING, 0, (LPARAM)theme); + str = (TCHAR *)malloc(MAX_PATH+1); + if (str) { + GetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, str, MAX_PATH); + SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, normalizeCustomString(str)); + } + SendDlgItemMessage(hwndDlg, IDC_THEME, CB_SETITEMDATA, (WPARAM)item, (LPARAM)str); + EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE), TRUE); + } + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + return TRUE; + case IDC_UPDATE: + { + int item; + TCHAR theme[MAX_PATH+1]; + + GetDlgItemText(hwndDlg, IDC_THEME, theme, sizeof(theme)); + item = SendDlgItemMessage(hwndDlg, IDC_THEME, CB_FINDSTRINGEXACT, -1, (LPARAM)theme); + str = (TCHAR *)SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETITEMDATA, (WPARAM)item, 0); + if (str) { + GetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, str, MAX_PATH); + SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, normalizeCustomString(str)); + } + EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), FALSE); + } + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + return TRUE; + case IDC_DELETE: + { + int item; + TCHAR theme[MAX_PATH+1]; + + GetDlgItemText(hwndDlg, IDC_THEME, theme, sizeof(theme)); + item = SendDlgItemMessage(hwndDlg, IDC_THEME, CB_FINDSTRINGEXACT, -1, (LPARAM)theme); + str = (TCHAR *)SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETITEMDATA, (WPARAM)item, 0); + if (str) + free(str); + SendDlgItemMessage(hwndDlg, IDC_THEME, CB_DELETESTRING, (WPARAM)item, 0); + if (SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETCOUNT, 0, 0) == 0) { + SetDlgItemText(hwndDlg, IDC_THEME, _T("")); + SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, _T("")); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETE), FALSE); + } else { + SendDlgItemMessage(hwndDlg, IDC_THEME, CB_SETCURSEL, 0, 0); + str = (TCHAR *)SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETITEMDATA, 0, 0); + if (str) + SetDlgItemText(hwndDlg, IDC_CUSTOMSTRING, str); + } + EnableWindow(GetDlgItem(hwndDlg, IDC_UPDATE), FALSE); + } + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + return TRUE; + case IDC_EXPORT: + { + TCHAR path[MAX_PATH+1], filter[MAX_PATH+1], *pfilter; + OPENFILENAME ofn={0}; + + path[0] = _T('\0'); + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = hwndDlg; + ofn.hInstance = NULL; + wcscpy(filter,_T("Keyboard Notify Theme")); + wcscat(filter, _T(" (*.knt)")); + pfilter = filter + wcslen(filter) + 1; + wcscpy(pfilter, _T("*.knt")); + pfilter = pfilter + wcslen(pfilter) + 1; + wcscpy(pfilter, _T("All Files")); + pfilter = pfilter + wcslen(pfilter) + 1; + wcscpy(pfilter, _T("*.*")); + pfilter = pfilter + wcslen(pfilter) + 1; + *pfilter = _T('\0'); + ofn.lpstrFilter = filter; + ofn.lpstrFile = path; + ofn.Flags = OFN_HIDEREADONLY|OFN_NOCHANGEDIR|OFN_NOREADONLYRETURN|OFN_PATHMUSTEXIST; + ofn.nMaxFile = sizeof(path); + ofn.lpstrDefExt = _T("knt"); + if(GetSaveFileName(&ofn)) + exportThemes(path); + } + return TRUE; + case IDC_IMPORT: + { + TCHAR path[MAX_PATH+1], filter[MAX_PATH+1], *pfilter; + OPENFILENAME ofn={0}; + + path[0] = _T('\0'); + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = hwndDlg; + ofn.hInstance = NULL; + wcscpy(filter, _T("Keyboard Notify Theme")); + wcscat(filter, _T(" (*.knt)")); + pfilter = filter + wcslen(filter) + 1; + wcscpy(pfilter, _T("*.knt")); + pfilter = pfilter + wcslen(pfilter) + 1; + wcscpy(pfilter, _T("All Files")); + pfilter = pfilter + wcslen(pfilter) + 1; + wcscpy(pfilter, _T("*.*")); + pfilter = pfilter + wcslen(pfilter) + 1; + *pfilter = _T('\0'); + ofn.lpstrFilter = filter; + ofn.lpstrFile = path; + ofn.Flags = OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_NOCHANGEDIR; + ofn.nMaxFile = sizeof(path); + ofn.lpstrDefExt = _T("knt"); + if(GetOpenFileName(&ofn)) { + importThemes(path, IsDlgButtonChecked(hwndDlg, IDC_OVERRIDE) == BST_CHECKED); + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + } + } + return TRUE; + case IDC_OVERRIDE: + SendMessage(GetParent(GetParent(hwndDlg)), PSM_CHANGED, 0, 0); + return TRUE; + } + break; + + case WM_NOTIFY: + { + int count; + TCHAR theme[MAX_PATH+1], themeAux[MAX_PATH+1], *str; + //Here we have pressed either the OK or the APPLY button. + switch(((LPNMHDR)lParam)->idFrom) { + case 0: + switch (((LPNMHDR)lParam)->code) { + case PSN_APPLY: + if (!DBGetContactSetting(NULL, KEYBDMODULE, fmtDBSettingName("theme%d", wCustomTheme), &dbv)) + wcscpy(theme, dbv.ptszVal); + else + theme[0] = _T('\0'); + + // Here we will delete all the items in the theme combo on the Flashing tab: we will load them again later + for (i=0; SendDlgItemMessage(hwndEffect, IDC_SCUSTOM, CB_DELETESTRING, 0, (LPARAM)i) != CB_ERR; i++); + + count = SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETCOUNT, 0, 0); + for (i=0, wCustomTheme=0; i < count; i++) { + SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETLBTEXT, (WPARAM)i, (LPARAM)themeAux); + DBWriteContactSettingWString(NULL, KEYBDMODULE, fmtDBSettingName("theme%d", i), themeAux); + str = (TCHAR *)SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETITEMDATA, (WPARAM)i, 0); + if (str) + DBWriteContactSettingWString(NULL, KEYBDMODULE, fmtDBSettingName("custom%d", i), str); + else + DBWriteContactSettingWString(NULL, KEYBDMODULE, fmtDBSettingName("custom%d", i), _T("")); + + if (!wcscmp(theme, themeAux)) + wCustomTheme = i; + + // Here we will update the theme combo on the Flashing tab: horrible but can't imagine a better way right now + SendDlgItemMessage(hwndEffect, IDC_SCUSTOM, CB_INSERTSTRING, (WPARAM)i, (LPARAM)themeAux); + SendDlgItemMessage(hwndEffect, IDC_SCUSTOM, CB_SETITEMDATA, (WPARAM)i, (LPARAM)i); + } + for (i=count; !DBDeleteContactSetting(NULL, KEYBDMODULE, fmtDBSettingName("theme%d", i)); i++) + DBDeleteContactSetting(NULL, KEYBDMODULE, fmtDBSettingName("custom%d", i)); + + DBWriteContactSettingWord(NULL, KEYBDMODULE, "custom", wCustomTheme); + // Still updating here the the Flashing tab's controls + SendDlgItemMessage(hwndEffect, IDC_SCUSTOM, CB_SETCURSEL, (WPARAM)wCustomTheme, 0); + + DBWriteContactSettingByte(NULL, KEYBDMODULE, "override", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_OVERRIDE) == BST_CHECKED ? 1:0)); + + return TRUE; + } // switch code + break; + } //switch idFrom + } + break; //End WM_NOTIFY + + case WM_DESTROY: + { + int item, count = SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETCOUNT, 0, 0); + + for (item=0; item < count; item++) { + str = (TCHAR *)SendDlgItemMessage(hwndDlg, IDC_THEME, CB_GETITEMDATA, (WPARAM)item, 0); + if (str) + free(str); + } + break; + } + + default: + break; + } + + return FALSE; +} + + +void exportThemes(const TCHAR *filename) +{ + int i; + FILE *fExport; + DBVARIANT dbv; + + if (!(fExport = _wfopen(filename, _T("wt")))) + return; + + fwprintf(fExport, TranslateT("\n; Automatically generated Keyboard Notify Theme file\n\n\n")); + + for (i=0; !DBGetContactSetting(NULL, KEYBDMODULE, fmtDBSettingName("theme%d", i), &dbv); i++) { + fwprintf(fExport, _T("[%s]\n"), dbv.ptszVal); + DBFreeVariant(&dbv); + if (DBGetContactSetting(NULL, KEYBDMODULE, fmtDBSettingName("custom%d", i), &dbv)) + fwprintf(fExport, _T("0\n\n")); + else { + fwprintf(fExport, _T("%s\n\n"), dbv.ptszVal); + DBFreeVariant(&dbv); + } + } + + fwprintf(fExport, TranslateT("\n; End of automatically generated Keyboard Notify Theme file\n")); + + fclose(fExport); +} + + +void importThemes(const TCHAR *filename, BOOL overrideExisting) +{ + int status=0; + size_t i; + FILE *fImport; + TCHAR buffer[MAX_PATH+1], theme[MAX_PATH+1], *str; + + if (!(fImport = _wfopen(filename, _T("rt")))) + return; + + while (fgetws(buffer, MAX_PATH, fImport) != NULL) { + for (str=buffer; *str && isspace(*str); str++); //ltrim + if (!*str || *str == ';') //empty line or comment + continue; + for (i=wcslen(str)-1; isspace(str[i]); str[i--]='\0'); //rtrim + switch (status) { + case 0: + if (i > 1 && str[0] == '[' && str[i] == ']') { + status = 1; + wcscpy(theme, str+1); + theme[i-1] = '\0'; + } + break; + case 1: + status = 0; + writeThemeToCombo(theme, normalizeCustomString(str), overrideExisting); + break; + } + } + + fclose(fImport); +} + + +void writeThemeToCombo(const TCHAR *theme, const TCHAR *custom, BOOL overrideExisting) +{ + int item; + TCHAR *str; + + item = SendDlgItemMessage(hwndTheme, IDC_THEME, CB_FINDSTRINGEXACT, -1, (LPARAM)theme); + if (item == CB_ERR) { + item = SendDlgItemMessage(hwndTheme, IDC_THEME, CB_ADDSTRING, 0, (LPARAM)theme); + str = (TCHAR *)malloc(MAX_PATH+1); + if (str) + wcscpy(str, custom); + SendDlgItemMessage(hwndTheme, IDC_THEME, CB_SETITEMDATA, (WPARAM)item, (LPARAM)str); + } else + if (overrideExisting) { + str = (TCHAR *)SendDlgItemMessage(hwndTheme, IDC_THEME, CB_GETITEMDATA, (WPARAM)item, 0); + if (str) + wcscpy(str, custom); + } +} + + +INT_PTR CALLBACK DlgProcProcesses(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + unsigned int i; + + switch (msg) { + + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + + SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, EM_LIMITTEXT, MAX_PATH, 0); + + for (i=0; i < ProcessListAux.count; i++) + if (ProcessListAux.szFileName[i]) { + int index = SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)ProcessListAux.szFileName[i]); + if (index != CB_ERR && index != CB_ERRSPACE) + SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_SETITEMDATA, (WPARAM)index, (LPARAM)i); + } + + EnableWindow(GetDlgItem(hwndDlg, IDC_ADDPGM), FALSE); + if (SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_GETCOUNT, 0, 0) == 0) + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETEPGM), FALSE); + else + SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_SETCURSEL, 0, 0); + + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_PROGRAMS: + switch (HIWORD(wParam)) { + int item; + TCHAR szFileName[MAX_PATH+1]; + + case CBN_SELENDOK: + case CBN_SELCHANGE: + EnableWindow(GetDlgItem(hwndDlg, IDC_ADDPGM), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETEPGM), TRUE); + break; + case CBN_EDITCHANGE: + GetDlgItemText(hwndDlg, IDC_PROGRAMS, szFileName, sizeof(szFileName)); + if ((item = SendMessage((HWND)lParam, CB_FINDSTRINGEXACT, -1, (LPARAM)szFileName)) == CB_ERR) { //new program + EnableWindow(GetDlgItem(hwndDlg, IDC_ADDPGM), TRUE); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETEPGM), FALSE); + } else { + EnableWindow(GetDlgItem(hwndDlg, IDC_ADDPGM), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETEPGM), TRUE); + } + break; + } + break; + case IDC_ADDPGM: + { + int item; + TCHAR szFileName[MAX_PATH+1]; + + GetDlgItemText(hwndDlg, IDC_PROGRAMS, szFileName, sizeof(szFileName)); + if (!szFileName[0]) + break; + item = SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_ADDSTRING, 0, (LPARAM)szFileName); + EnableWindow(GetDlgItem(hwndDlg, IDC_ADDPGM), FALSE); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETEPGM), TRUE); + } + break; + case IDC_DELETEPGM: + { + int item; + TCHAR szFileName[MAX_PATH+1]; + + GetDlgItemText(hwndDlg, IDC_PROGRAMS, szFileName, sizeof(szFileName)); + item = SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_FINDSTRINGEXACT, -1, (LPARAM)szFileName); + SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_DELETESTRING, (WPARAM)item, 0); + if (SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_GETCOUNT, 0, 0) == 0) { + SetDlgItemText(hwndDlg, IDC_PROGRAMS, _T("")); + EnableWindow(GetDlgItem(hwndDlg, IDC_DELETEPGM), FALSE); + } else + SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_SETCURSEL, 0, 0); + } + break; + case IDC_OKPGM: + destroyProcessListAux(); + + ProcessListAux.count = SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_GETCOUNT, 0, 0); + ProcessListAux.szFileName = (TCHAR **)malloc(ProcessListAux.count * sizeof(TCHAR *)); + if (!ProcessListAux.szFileName) + ProcessListAux.count = 0; + else + for (i=0; i < ProcessListAux.count; i++) { + TCHAR szFileNameAux[MAX_PATH+1]; + + SendDlgItemMessage(hwndDlg, IDC_PROGRAMS, CB_GETLBTEXT, (WPARAM)i, (LPARAM)szFileNameAux); + ProcessListAux.szFileName[i] = (TCHAR *)malloc(wcslen(szFileNameAux) + 1); + if (ProcessListAux.szFileName[i]) + wcscpy(ProcessListAux.szFileName[i], szFileNameAux); + } + + case IDC_CANCELPGM: + EndDialog(hwndDlg, LOWORD(wParam)); + break; + } + break; + } + + return FALSE; +} + + +void createProcessListAux(void) +{ + unsigned int i; + + ProcessListAux.count = ProcessList.count; + ProcessListAux.szFileName = (TCHAR **)malloc(ProcessListAux.count * sizeof(char *)); + if (!ProcessListAux.szFileName) + ProcessListAux.count = 0; + else + for (i=0; i < ProcessListAux.count; i++) + if (!ProcessList.szFileName[i]) + ProcessListAux.szFileName[i] = NULL; + else { + ProcessListAux.szFileName[i] = (TCHAR *)malloc(wcslen(ProcessList.szFileName[i]) + 1); + if (ProcessListAux.szFileName[i]) + wcscpy(ProcessListAux.szFileName[i], ProcessList.szFileName[i]); + } + +} + + +void destroyProcessListAux(void) +{ + unsigned int i; + + for(i=0; i < ProcessListAux.count; i++) + if (ProcessListAux.szFileName[i]) + free(ProcessListAux.szFileName[i]); + + if (ProcessListAux.szFileName) + free(ProcessListAux.szFileName); + + ProcessListAux.count = 0; + ProcessListAux.szFileName = NULL; +} + + +INT_PTR CALLBACK DlgProcEventLeds(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) { + + case WM_INITDIALOG: + TranslateDialogDefault(hwndDlg); + + CheckDlgButton(hwndDlg, IDC_MSGLEDNUM, trillianLedsMsg&2 ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_MSGLEDCAPS, trillianLedsMsg&4 ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_MSGLEDSCROLL, trillianLedsMsg&1 ? BST_CHECKED:BST_UNCHECKED); + + CheckDlgButton(hwndDlg, IDC_FILELEDNUM, trillianLedsFile&2 ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_FILELEDCAPS, trillianLedsFile&4 ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_FILELEDSCROLL, trillianLedsFile&1 ? BST_CHECKED:BST_UNCHECKED); + + CheckDlgButton(hwndDlg, IDC_URLLEDNUM, trillianLedsURL&2 ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_URLLEDCAPS, trillianLedsURL&4 ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_URLLEDSCROLL, trillianLedsURL&1 ? BST_CHECKED:BST_UNCHECKED); + + CheckDlgButton(hwndDlg, IDC_OTHERLEDNUM, trillianLedsOther&2 ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_OTHERLEDCAPS, trillianLedsOther&4 ? BST_CHECKED:BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_OTHERLEDSCROLL, trillianLedsOther&1 ? BST_CHECKED:BST_UNCHECKED); + + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_OK: + trillianLedsMsg = 0; + if(IsDlgButtonChecked(hwndDlg, IDC_MSGLEDNUM) == BST_CHECKED) + trillianLedsMsg |= 2; + if(IsDlgButtonChecked(hwndDlg, IDC_MSGLEDCAPS) == BST_CHECKED) + trillianLedsMsg |= 4; + if(IsDlgButtonChecked(hwndDlg, IDC_MSGLEDSCROLL) == BST_CHECKED) + trillianLedsMsg |= 1; + + trillianLedsFile = 0; + if(IsDlgButtonChecked(hwndDlg, IDC_FILELEDNUM) == BST_CHECKED) + trillianLedsFile |= 2; + if(IsDlgButtonChecked(hwndDlg, IDC_FILELEDCAPS) == BST_CHECKED) + trillianLedsFile |= 4; + if(IsDlgButtonChecked(hwndDlg, IDC_FILELEDSCROLL) == BST_CHECKED) + trillianLedsFile |= 1; + + trillianLedsURL = 0; + if(IsDlgButtonChecked(hwndDlg, IDC_URLLEDNUM) == BST_CHECKED) + trillianLedsURL |= 2; + if(IsDlgButtonChecked(hwndDlg, IDC_URLLEDCAPS) == BST_CHECKED) + trillianLedsURL |= 4; + if(IsDlgButtonChecked(hwndDlg, IDC_URLLEDSCROLL) == BST_CHECKED) + trillianLedsURL |= 1; + + trillianLedsOther = 0; + if(IsDlgButtonChecked(hwndDlg, IDC_OTHERLEDNUM) == BST_CHECKED) + trillianLedsOther |= 2; + if(IsDlgButtonChecked(hwndDlg, IDC_OTHERLEDCAPS) == BST_CHECKED) + trillianLedsOther |= 4; + if(IsDlgButtonChecked(hwndDlg, IDC_OTHERLEDSCROLL) == BST_CHECKED) + trillianLedsOther |= 1; + + case IDC_CANCEL: + EndDialog(hwndDlg, LOWORD(wParam)); + break; + } + break; + } + + return FALSE; +} + + +void createXstatusListAux(void) +{ + unsigned int i, j; + + XstatusListAux = (XSTATUS_INFO *)malloc(ProtoList.protoCount * sizeof(XSTATUS_INFO)); + if (XstatusListAux) + for (i=0; i < ProtoList.protoCount; i++) { + XstatusListAux[i].count = ProtoList.protoInfo[i].xstatus.count; + if (!XstatusListAux[i].count) + XstatusListAux[i].enabled = NULL; + else { + XstatusListAux[i].enabled = (BOOL *)malloc(XstatusListAux[i].count * sizeof(BOOL)); + if (!XstatusListAux[i].enabled) + XstatusListAux[i].count = 0; + else + for(j=0; j < XstatusListAux[i].count; j++) + XstatusListAux[i].enabled[j] = ProtoList.protoInfo[i].xstatus.enabled[j]; + } + } + +} + + +void destroyXstatusListAux(void) +{ + unsigned int i; + + if (XstatusListAux) { + for(i=0; i < ProtoList.protoCount; i++) + if (XstatusListAux[i].enabled) + free(XstatusListAux[i].enabled); + + free(XstatusListAux); + XstatusListAux = NULL; + } + +} + + +INT_PTR CALLBACK DlgProcXstatusList(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) { + + case WM_INITDIALOG: + + { + unsigned int i; + WPARAM j; + int imageCount; + HICON hIconAux; + HIMAGELIST hImageList; + TVINSERTSTRUCT tvis={0}; + TVITEM tvi={0}; + HTREEITEM hSectionItem, hItem; + HWND hwndTree = GetDlgItem(hwndDlg, IDC_TREE_XSTATUS); + + TranslateDialogDefault(hwndDlg); + SetWindowLongPtr(hwndTree, GWL_STYLE, GetWindowLongPtr(hwndTree, GWL_STYLE)|TVS_NOHSCROLL|TVS_CHECKBOXES); + + if (!XstatusListAux) return TRUE; + + // Calculate hImageList size + for (i=0, imageCount=1; i < ProtoList.protoCount; i++) + if (ProtoList.protoInfo[i].enabled && XstatusListAux[i].count) + imageCount += XstatusListAux[i].count; + + hImageList = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), (bWindowsNT && dWinVer >= 5.01?ILC_COLOR32:ILC_COLOR16)|ILC_MASK, imageCount, imageCount); + TreeView_SetImageList(hwndTree, hImageList, TVSIL_NORMAL); + + ImageList_AddIcon(hImageList, hIconAux=(HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_BLANK), IMAGE_ICON, 0, 0, 0)); + if (hIconAux) DestroyIcon(hIconAux); + + TreeView_SelectItem(hwndTree, NULL); + ShowWindow(hwndTree, SW_HIDE); + TreeView_DeleteAllItems(hwndTree); + + for (i=0; i < ProtoList.protoCount; i++) + if (ProtoList.protoInfo[i].enabled && XstatusListAux[i].count) { + HTREEITEM hParent; + + int count; PROTOACCOUNT** protos; + ProtoEnumAccounts( &count, &protos ); + + tvis.hParent = NULL; + tvis.hInsertAfter = TVI_LAST; + tvis.item.mask = TVIF_TEXT|TVIF_PARAM|TVIF_STATE|TVIF_IMAGE|TVIF_SELECTEDIMAGE; + tvis.item.pszText = protos[i] -> tszAccountName; + tvis.item.lParam = (LPARAM)i; + tvis.item.stateMask = TVIS_BOLD|TVIS_EXPANDED; + tvis.item.state = TVIS_BOLD|TVIS_EXPANDED; + tvis.item.iImage = tvis.item.iSelectedImage = ImageList_AddIcon(hImageList, hIconAux=(HICON)CallProtoService(ProtoList.protoInfo[i].szProto, PS_LOADICON, PLI_PROTOCOL, 0)); + if (hIconAux) DestroyIcon(hIconAux); + hParent = TreeView_InsertItem(hwndTree, &tvis); + for(j=0; j < XstatusListAux[i].count; j++) { + TCHAR szDefaultName[1024]; + ICQ_CUSTOM_STATUS xstatus={0}; + + tvis.hParent = hParent; + tvis.item.mask = TVIF_TEXT|TVIF_PARAM|TVIF_IMAGE|TVIF_SELECTEDIMAGE; + if (!j){ + tvis.item.pszText = TranslateT("None"); } + else { + xstatus.cbSize = sizeof(ICQ_CUSTOM_STATUS); + xstatus.flags = CSSF_MASK_NAME|CSSF_DEFAULT_NAME|CSSF_UNICODE; + xstatus.ptszName = szDefaultName; + xstatus.wParam = &j; + CallProtoService(ProtoList.protoInfo[i].szProto, PS_ICQ_GETCUSTOMSTATUSEX, 0, (LPARAM)&xstatus); + tvis.item.pszText = szDefaultName; + } + tvis.item.lParam = (LPARAM)j; + tvis.item.iImage = tvis.item.iSelectedImage = j?ImageList_AddIcon(hImageList, hIconAux=(HICON)CallProtoService(ProtoList.protoInfo[i].szProto, PS_ICQ_GETCUSTOMSTATUSICON, (WPARAM)j, 0)):0; + if (hIconAux) DestroyIcon(hIconAux); + TreeView_InsertItem(hwndTree, &tvis); + } + } + + tvi.mask = TVIF_HANDLE|TVIF_PARAM; + for (hSectionItem=TreeView_GetRoot(hwndTree); hSectionItem; hSectionItem=TreeView_GetNextSibling(hwndTree, hSectionItem)) { + tvi.hItem = hSectionItem; + TreeView_GetItem(hwndTree, &tvi); + i = (unsigned int)tvi.lParam; + TreeView_SetItemState(hwndTree, hSectionItem, INDEXTOSTATEIMAGEMASK(0), TVIS_STATEIMAGEMASK); + for (hItem=TreeView_GetChild(hwndTree, hSectionItem); hItem; hItem=TreeView_GetNextSibling(hwndTree, hItem)) { + tvi.hItem = hItem; + TreeView_GetItem(hwndTree, &tvi); + j = (unsigned int)tvi.lParam; + TreeView_SetItemState(hwndTree, hItem, INDEXTOSTATEIMAGEMASK(XstatusListAux[i].enabled[j]?2:1), TVIS_STATEIMAGEMASK); + } + } + + ShowWindow(hwndTree, SW_SHOW); + TreeView_SetItemState(hwndTree, 0, TVIS_SELECTED, TVIS_SELECTED); + return TRUE; + } + + case WM_DESTROY: + { + HIMAGELIST hImageList; + + // Destroy tree view imagelist since it does not get destroyed automatically (see msdn docs) + hImageList = TreeView_GetImageList(GetDlgItem(hwndDlg, IDC_TREE_XSTATUS), TVSIL_STATE); + if (hImageList) { + TreeView_SetImageList(GetDlgItem(hwndDlg, IDC_TREE_XSTATUS), NULL, TVSIL_STATE); + ImageList_Destroy(hImageList); + } + hImageList = TreeView_GetImageList(GetDlgItem(hwndDlg, IDC_TREE_XSTATUS), TVSIL_NORMAL); + if (hImageList) { + TreeView_SetImageList(GetDlgItem(hwndDlg, IDC_TREE_XSTATUS), NULL, TVSIL_NORMAL); + ImageList_Destroy(hImageList); + } + return TRUE; + } + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_OKXST: + { + unsigned int i, j; + HTREEITEM hSectionItem, hItem; + TVITEM tvi={0}; + HWND hwndTree = GetDlgItem(hwndDlg, IDC_TREE_XSTATUS); + + tvi.mask = TVIF_HANDLE|TVIF_PARAM; + for (hSectionItem=TreeView_GetRoot(hwndTree); hSectionItem; hSectionItem=TreeView_GetNextSibling(hwndTree, hSectionItem)) { + tvi.hItem = hSectionItem; + TreeView_GetItem(hwndTree, &tvi); + i = (unsigned int)tvi.lParam; + for (hItem=TreeView_GetChild(hwndTree, hSectionItem); hItem; hItem=TreeView_GetNextSibling(hwndTree, hItem)) { + tvi.hItem = hItem; + TreeView_GetItem(hwndTree, &tvi); + j = (unsigned int)tvi.lParam; + XstatusListAux[i].enabled[j] = !!(TreeView_GetItemState(hwndTree, hItem, TVIS_STATEIMAGEMASK)&INDEXTOSTATEIMAGEMASK(2)); + } + } + } + + case IDC_CANCELXST: + EndDialog(hwndDlg, LOWORD(wParam)); + return TRUE; + } + break; + } + + return FALSE; +} diff --git a/plugins/KeyboardNotify/src/protolist.h b/plugins/KeyboardNotify/src/protolist.h new file mode 100644 index 0000000000..5a08d929da --- /dev/null +++ b/plugins/KeyboardNotify/src/protolist.h @@ -0,0 +1,34 @@ +/* + +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. + +*/ + +typedef struct { + UINT_PTR count; + BOOL *enabled; +} XSTATUS_INFO; + +typedef struct { + char *szProto; + BOOL enabled; + BOOL visible; + XSTATUS_INFO xstatus; +} PROTOCOL_INFO; + +typedef struct { + unsigned int protoCount; + PROTOCOL_INFO *protoInfo; +} PROTOCOL_LIST; diff --git a/plugins/KeyboardNotify/src/resource.h b/plugins/KeyboardNotify/src/resource.h new file mode 100644 index 0000000000..4ebfb19cd0 --- /dev/null +++ b/plugins/KeyboardNotify/src/resource.h @@ -0,0 +1,120 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by resources.rc +// +#define IDC_OTHERICON 1 +#define IDD_OPT_KN_ACTION 120 +#define IDD_OPTIONS 150 +#define IDD_PROTO_OPTIONS 151 +#define IDD_BASIC_OPTIONS 152 +#define IDD_EFFECT_OPTIONS 153 +#define IDD_THEME_OPTIONS 154 +#define IDD_EVENTLEDS 155 +#define IDD_PROCESSES 156 +#define IDD_IGNORE_OPTIONS 157 +#define IDD_XSTATUSES 158 +#define IDC_ONMESSAGE 1000 +#define IDC_ONFILE 1001 +#define IDC_ONURL 1002 +#define IDC_ONOTHER 1003 +#define IDC_IFOPEN 1004 +#define IDC_IFNOTTOP 1005 +#define IDC_IFOLDER 1006 +#define IDC_SOLDER 1007 +#define IDC_OLDERSPIN 1008 +#define IDC_UNTILBLK 1009 +#define IDC_SBLINK 1010 +#define IDC_BLINKSPIN 1011 +#define IDC_UNTILATTENDED 1012 +#define IDC_MIRORWIN 1013 +#define IDC_UNTILOPEN 1014 +#define IDC_UNTILCOND 1015 +#define IDC_FSCREEN 1016 +#define IDC_SSAVER 1017 +#define IDC_LOCKED 1018 +#define IDC_PGMS 1019 +#define IDC_ASSIGNPGMS 1020 +#define IDC_ACTIVE 1021 +#define IDC_ONLINE 1022 +#define IDC_AWAY 1023 +#define IDC_NA 1024 +#define IDC_OCCUPIED 1025 +#define IDC_DND 1026 +#define IDC_FREECHAT 1027 +#define IDC_INVISIBLE 1028 +#define IDC_ONTHEPHONE 1029 +#define IDC_OUTTOLUNCH 1030 +#define IDC_OFFLINE 1031 +#define IDC_REMCHECK 1032 +#define IDC_SREMCHECK 1033 +#define IDC_NUM 1034 +#define IDC_CAPS 1035 +#define IDC_SCROLL 1036 +#define IDC_SAMETIME 1037 +#define IDC_INTURN 1038 +#define IDC_INSEQUENCE 1039 +#define IDC_SEQORDER 1040 +#define IDC_CUSTOM 1041 +#define IDC_SCUSTOM 1042 +#define IDC_TRILLIAN 1043 +#define IDC_ASSIGNLEDS 1044 +#define IDC_SDELAY 1045 +#define IDC_DELAYSPIN 1046 +#define IDC_PREVIEW 1047 +#define IDC_SPEED 1048 +#define IDC_THEME 1049 +#define IDC_CUSTOMSTRING 1050 +#define IDC_TEST 1051 +#define IDC_ADD 1052 +#define IDC_UPDATE 1053 +#define IDC_DELETE 1054 +#define IDC_EXPORT 1055 +#define IDC_IMPORT 1056 +#define IDC_OVERRIDE 1057 +#define IDC_PROTOCOLLIST 1058 +#define IDC_MSGLEDNUM 1059 +#define IDC_MSGLEDCAPS 1060 +#define IDC_MSGLEDSCROLL 1061 +#define IDC_FILELEDNUM 1062 +#define IDC_FILELEDCAPS 1063 +#define IDC_FILELEDSCROLL 1064 +#define IDC_URLLEDNUM 1065 +#define IDC_URLLEDCAPS 1066 +#define IDC_URLLEDSCROLL 1067 +#define IDC_OTHERLEDNUM 1068 +#define IDC_OTHERLEDCAPS 1069 +#define IDC_OTHERLEDSCROLL 1070 +#define IDC_OK 1071 +#define IDC_CANCEL 1072 +#define IDC_PROGRAMS 1073 +#define IDC_ADDPGM 1074 +#define IDC_DELETEPGM 1075 +#define IDC_OKPGM 1076 +#define IDC_CANCELPGM 1077 +#define IDC_KEYPRESSES 1078 +#define IDC_CUSTOMTHEME 1079 +#define IDC_USECUSTOM 1080 +#define IDC_LIST 1081 +#define IDC_FORCEOPEN 1082 +#define IDC_SFORCEOPEN 1083 +#define IDC_SELECTXSTATUS 1084 +#define IDC_TREE_XSTATUS 1085 +#define IDC_OKXST 1086 +#define IDC_CANCELXST 1087 +#define IDC_FILEICON 1206 +#define IDC_ALLICON 1208 +#define IDC_NONEICON 1209 +#define IDC_MSGICON 1375 +#define IDC_URLICON 1376 +#define IDC_TABS 2000 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 103 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1088 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/plugins/KeyboardNotify/src/trigger.cpp b/plugins/KeyboardNotify/src/trigger.cpp new file mode 100644 index 0000000000..df3d7daaf3 --- /dev/null +++ b/plugins/KeyboardNotify/src/trigger.cpp @@ -0,0 +1,178 @@ +/* + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#define WIN32_LEAN_AND_MEAN + +#include +#include +#include +#include +#include +#include "constants.h" +#include "utils.h" +#include "resource.h" +#include +#include +#include +#include "m_trigger.h" + +extern HINSTANCE hInst; + +void StartBlinkAction(char *, WORD); + + +int getCustomNro(DWORD actionID, HWND hwndDlg, int nItems) +{ + int i; + DBVARIANT dbv; + char theme[MAX_PATH+1]; + + if (DBGetTriggerSetting(actionID, NULL, KEYBDMODULE, "custom", &dbv)) + return DEF_SETTING_CUSTOMTHEME; + + for (i=0; i < nItems; i++) { + SendDlgItemMessage(hwndDlg, IDC_CUSTOMTHEME, CB_GETLBTEXT, (WPARAM)i, (LPARAM)theme); + if (!strcmp(dbv.pszVal, theme)) { + DBFreeVariant(&dbv); + return i; + } + } + + DBFreeVariant(&dbv); + return DEF_SETTING_CUSTOMTHEME; +} + +static INT_PTR CALLBACK DlgProcOptsActionKbdNotify(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + DBVARIANT dbv; + DWORD actionID; + int i, nItems; + char theme[MAX_PATH+1]; + + switch (msg) { + case WM_INITDIALOG: + actionID = (DWORD)lParam; + TranslateDialogDefault(hwndDlg); + + for (i=0; !DBGetContactSetting(NULL, KEYBDMODULE, fmtDBSettingName("theme%d", i), &dbv); i++) { + int index = SendDlgItemMessage(hwndDlg, IDC_CUSTOMTHEME, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)dbv.pszVal); + DBFreeVariant(&dbv); + if (index != CB_ERR && index != CB_ERRSPACE) + SendDlgItemMessage(hwndDlg, IDC_CUSTOMTHEME, CB_SETITEMDATA, (WPARAM)index, (LPARAM)i); + } + + nItems = SendDlgItemMessage(hwndDlg, IDC_CUSTOMTHEME, CB_GETCOUNT, 0, 0); + + CheckDlgButton(hwndDlg, IDC_USECUSTOM, nItems && DBGetTriggerSettingByte(actionID, NULL, KEYBDMODULE, "usecustom", 0) ? BST_CHECKED:BST_UNCHECKED); + EnableWindow(GetDlgItem(hwndDlg, IDC_USECUSTOM), nItems); + + SendDlgItemMessage(hwndDlg, IDC_CUSTOMTHEME, CB_SETCURSEL, (WPARAM)getCustomNro(actionID, hwndDlg, nItems), 0); + EnableWindow(GetDlgItem(hwndDlg, IDC_CUSTOMTHEME), IsDlgButtonChecked(hwndDlg, IDC_USECUSTOM) == BST_CHECKED); + + SendDlgItemMessage(hwndDlg, IDC_FORCEOPEN, UDM_SETBUDDY, (WPARAM)GetDlgItem(hwndDlg, IDC_SFORCEOPEN), 0); + SendDlgItemMessage(hwndDlg, IDC_FORCEOPEN, UDM_SETRANGE32, 1, MAKELONG(UD_MAXVAL, 0)); + SendDlgItemMessage(hwndDlg, IDC_FORCEOPEN, UDM_SETPOS, 0, MAKELONG(DBGetTriggerSettingWord(actionID, NULL, KEYBDMODULE, "forceopen", DEF_SETTING_NBLINKS), 0)); + + break; + + case TM_ADDACTION: // save the settings + actionID = (DWORD)wParam; + DBWriteTriggerSettingByte(actionID, NULL, KEYBDMODULE, "usecustom", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_USECUSTOM) == BST_CHECKED ? 1:0)); + SendDlgItemMessage(hwndDlg, IDC_CUSTOMTHEME, CB_GETLBTEXT, (WPARAM)SendDlgItemMessage(hwndDlg, IDC_CUSTOMTHEME, CB_GETCURSEL, 0, 0), (LPARAM)theme); + DBWriteTriggerSettingString(actionID, NULL, KEYBDMODULE, "custom", theme); + DBWriteTriggerSettingWord(actionID, NULL, KEYBDMODULE, "forceopen", (WORD)SendDlgItemMessage(hwndDlg, IDC_FORCEOPEN, UDM_GETPOS, 0, 0)); + break; + + case WM_COMMAND: + if (LOWORD(wParam) == IDC_USECUSTOM) + EnableWindow(GetDlgItem(hwndDlg, IDC_CUSTOMTHEME), IsDlgButtonChecked(hwndDlg, IDC_USECUSTOM) == BST_CHECKED); + break; + + case WM_DESTROY: + break; + } + + return FALSE; +} + +char *getCustomString(DWORD actionID) +{ + int i; + DBVARIANT dbv, dbv2; + static char customString[MAX_PATH+1]; + + if (DBGetTriggerSetting(actionID, NULL, KEYBDMODULE, "custom", &dbv)) + return NULL; + + for (i=0; !DBGetContactSetting(NULL, KEYBDMODULE, fmtDBSettingName("theme%d", i), &dbv2); i++) { + if (!strcmp(dbv.pszVal, dbv2.pszVal)) { + DBFreeVariant(&dbv); + DBFreeVariant(&dbv2); + if(DBGetContactSetting(NULL, KEYBDMODULE, fmtDBSettingName("custom%d", i), &dbv2)) + return NULL; + strcpy(customString, dbv2.pszVal); + DBFreeVariant(&dbv2); + return customString; + } + DBFreeVariant(&dbv2); + } + + DBFreeVariant(&dbv); + return NULL; +} + +static int TriggerStartBlinkFunction(DWORD actionID, REPORTINFO *ri) +{ + if (ri->flags&ACT_PERFORM) { + char *customStr; + + if (!DBGetTriggerSettingByte(actionID, NULL, KEYBDMODULE, "usecustom", 0)) + customStr = NULL; + else + customStr = getCustomString(actionID); + StartBlinkAction(customStr, DBGetTriggerSettingWord(actionID, NULL, KEYBDMODULE, "forceopen", DEF_SETTING_NBLINKS)); + } + if (ri->flags&ACT_CLEANUP) { // request to delete all associated settings + RemoveAllActionSettings(actionID, KEYBDMODULE); + } + + return 0; // all ok +} + +int RegisterAction() +{ + ACTIONREGISTER ar; + + if (!ServiceExists(MS_TRIGGER_REGISTERACTION)) + return -1; + + ZeroMemory(&ar, sizeof(ar)); + ar.cbSize = sizeof(ar); + ar.pszName = "Keyboard Flash: Start Blinking"; + ar.actionFunction = TriggerStartBlinkFunction; + ar.hInstance = hInst; + ar.pfnDlgProc = DlgProcOptsActionKbdNotify; + ar.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_KN_ACTION); + ar.flags = ARF_FUNCTION; + return CallService(MS_TRIGGER_REGISTERACTION, 0, (LPARAM)&ar); +} + +int DeInitAction() +{ + return 0; +} diff --git a/plugins/KeyboardNotify/src/trigger.h b/plugins/KeyboardNotify/src/trigger.h new file mode 100644 index 0000000000..41d830938c --- /dev/null +++ b/plugins/KeyboardNotify/src/trigger.h @@ -0,0 +1,20 @@ +/* + +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. + +*/ + +int RegisterAction(); +int DeInitAction(); diff --git a/plugins/KeyboardNotify/src/utils.cpp b/plugins/KeyboardNotify/src/utils.cpp new file mode 100644 index 0000000000..9c710ba217 --- /dev/null +++ b/plugins/KeyboardNotify/src/utils.cpp @@ -0,0 +1,52 @@ +/* + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#define WIN32_LEAN_AND_MEAN + +#include +#include +#include "utils.h" +#include +#include +#include + + +char *fmtDBSettingName(const char *fmt, ...) +{ + va_list va; + static char returnString[1024]; + + va_start(va, fmt); + mir_vsnprintf(returnString, sizeof(returnString), fmt, va); + va_end(va); + + return returnString; +} + + +TCHAR *getAbsoluteProfileName(TCHAR *absoluteProfileName, size_t maxLen) +{ + TCHAR profilePath[MAX_PATH+1], profileName[MAX_PATH+1]; + + profilePath[0] = profileName[0] = L'\0'; + CallService(MS_DB_GETPROFILEPATH, MAX_PATH, (LPARAM)profilePath); + CallService(MS_DB_GETPROFILENAME, MAX_PATH, (LPARAM)profileName); + _snwprintf(absoluteProfileName, maxLen, L"%s\\%s", profilePath, profileName); + + return absoluteProfileName; +} diff --git a/plugins/KeyboardNotify/src/utils.h b/plugins/KeyboardNotify/src/utils.h new file mode 100644 index 0000000000..66917754ed --- /dev/null +++ b/plugins/KeyboardNotify/src/utils.h @@ -0,0 +1,20 @@ +/* + +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. + +*/ + +char *fmtDBSettingName(const char *, ...); +TCHAR *getAbsoluteProfileName(TCHAR *, size_t); diff --git a/plugins/KeyboardNotify/trigger.cpp b/plugins/KeyboardNotify/trigger.cpp deleted file mode 100644 index df3d7daaf3..0000000000 --- a/plugins/KeyboardNotify/trigger.cpp +++ /dev/null @@ -1,178 +0,0 @@ -/* - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#define WIN32_LEAN_AND_MEAN - -#include -#include -#include -#include -#include -#include "constants.h" -#include "utils.h" -#include "resource.h" -#include -#include -#include -#include "m_trigger.h" - -extern HINSTANCE hInst; - -void StartBlinkAction(char *, WORD); - - -int getCustomNro(DWORD actionID, HWND hwndDlg, int nItems) -{ - int i; - DBVARIANT dbv; - char theme[MAX_PATH+1]; - - if (DBGetTriggerSetting(actionID, NULL, KEYBDMODULE, "custom", &dbv)) - return DEF_SETTING_CUSTOMTHEME; - - for (i=0; i < nItems; i++) { - SendDlgItemMessage(hwndDlg, IDC_CUSTOMTHEME, CB_GETLBTEXT, (WPARAM)i, (LPARAM)theme); - if (!strcmp(dbv.pszVal, theme)) { - DBFreeVariant(&dbv); - return i; - } - } - - DBFreeVariant(&dbv); - return DEF_SETTING_CUSTOMTHEME; -} - -static INT_PTR CALLBACK DlgProcOptsActionKbdNotify(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) -{ - DBVARIANT dbv; - DWORD actionID; - int i, nItems; - char theme[MAX_PATH+1]; - - switch (msg) { - case WM_INITDIALOG: - actionID = (DWORD)lParam; - TranslateDialogDefault(hwndDlg); - - for (i=0; !DBGetContactSetting(NULL, KEYBDMODULE, fmtDBSettingName("theme%d", i), &dbv); i++) { - int index = SendDlgItemMessage(hwndDlg, IDC_CUSTOMTHEME, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)dbv.pszVal); - DBFreeVariant(&dbv); - if (index != CB_ERR && index != CB_ERRSPACE) - SendDlgItemMessage(hwndDlg, IDC_CUSTOMTHEME, CB_SETITEMDATA, (WPARAM)index, (LPARAM)i); - } - - nItems = SendDlgItemMessage(hwndDlg, IDC_CUSTOMTHEME, CB_GETCOUNT, 0, 0); - - CheckDlgButton(hwndDlg, IDC_USECUSTOM, nItems && DBGetTriggerSettingByte(actionID, NULL, KEYBDMODULE, "usecustom", 0) ? BST_CHECKED:BST_UNCHECKED); - EnableWindow(GetDlgItem(hwndDlg, IDC_USECUSTOM), nItems); - - SendDlgItemMessage(hwndDlg, IDC_CUSTOMTHEME, CB_SETCURSEL, (WPARAM)getCustomNro(actionID, hwndDlg, nItems), 0); - EnableWindow(GetDlgItem(hwndDlg, IDC_CUSTOMTHEME), IsDlgButtonChecked(hwndDlg, IDC_USECUSTOM) == BST_CHECKED); - - SendDlgItemMessage(hwndDlg, IDC_FORCEOPEN, UDM_SETBUDDY, (WPARAM)GetDlgItem(hwndDlg, IDC_SFORCEOPEN), 0); - SendDlgItemMessage(hwndDlg, IDC_FORCEOPEN, UDM_SETRANGE32, 1, MAKELONG(UD_MAXVAL, 0)); - SendDlgItemMessage(hwndDlg, IDC_FORCEOPEN, UDM_SETPOS, 0, MAKELONG(DBGetTriggerSettingWord(actionID, NULL, KEYBDMODULE, "forceopen", DEF_SETTING_NBLINKS), 0)); - - break; - - case TM_ADDACTION: // save the settings - actionID = (DWORD)wParam; - DBWriteTriggerSettingByte(actionID, NULL, KEYBDMODULE, "usecustom", (BYTE)(IsDlgButtonChecked(hwndDlg, IDC_USECUSTOM) == BST_CHECKED ? 1:0)); - SendDlgItemMessage(hwndDlg, IDC_CUSTOMTHEME, CB_GETLBTEXT, (WPARAM)SendDlgItemMessage(hwndDlg, IDC_CUSTOMTHEME, CB_GETCURSEL, 0, 0), (LPARAM)theme); - DBWriteTriggerSettingString(actionID, NULL, KEYBDMODULE, "custom", theme); - DBWriteTriggerSettingWord(actionID, NULL, KEYBDMODULE, "forceopen", (WORD)SendDlgItemMessage(hwndDlg, IDC_FORCEOPEN, UDM_GETPOS, 0, 0)); - break; - - case WM_COMMAND: - if (LOWORD(wParam) == IDC_USECUSTOM) - EnableWindow(GetDlgItem(hwndDlg, IDC_CUSTOMTHEME), IsDlgButtonChecked(hwndDlg, IDC_USECUSTOM) == BST_CHECKED); - break; - - case WM_DESTROY: - break; - } - - return FALSE; -} - -char *getCustomString(DWORD actionID) -{ - int i; - DBVARIANT dbv, dbv2; - static char customString[MAX_PATH+1]; - - if (DBGetTriggerSetting(actionID, NULL, KEYBDMODULE, "custom", &dbv)) - return NULL; - - for (i=0; !DBGetContactSetting(NULL, KEYBDMODULE, fmtDBSettingName("theme%d", i), &dbv2); i++) { - if (!strcmp(dbv.pszVal, dbv2.pszVal)) { - DBFreeVariant(&dbv); - DBFreeVariant(&dbv2); - if(DBGetContactSetting(NULL, KEYBDMODULE, fmtDBSettingName("custom%d", i), &dbv2)) - return NULL; - strcpy(customString, dbv2.pszVal); - DBFreeVariant(&dbv2); - return customString; - } - DBFreeVariant(&dbv2); - } - - DBFreeVariant(&dbv); - return NULL; -} - -static int TriggerStartBlinkFunction(DWORD actionID, REPORTINFO *ri) -{ - if (ri->flags&ACT_PERFORM) { - char *customStr; - - if (!DBGetTriggerSettingByte(actionID, NULL, KEYBDMODULE, "usecustom", 0)) - customStr = NULL; - else - customStr = getCustomString(actionID); - StartBlinkAction(customStr, DBGetTriggerSettingWord(actionID, NULL, KEYBDMODULE, "forceopen", DEF_SETTING_NBLINKS)); - } - if (ri->flags&ACT_CLEANUP) { // request to delete all associated settings - RemoveAllActionSettings(actionID, KEYBDMODULE); - } - - return 0; // all ok -} - -int RegisterAction() -{ - ACTIONREGISTER ar; - - if (!ServiceExists(MS_TRIGGER_REGISTERACTION)) - return -1; - - ZeroMemory(&ar, sizeof(ar)); - ar.cbSize = sizeof(ar); - ar.pszName = "Keyboard Flash: Start Blinking"; - ar.actionFunction = TriggerStartBlinkFunction; - ar.hInstance = hInst; - ar.pfnDlgProc = DlgProcOptsActionKbdNotify; - ar.pszTemplate = MAKEINTRESOURCEA(IDD_OPT_KN_ACTION); - ar.flags = ARF_FUNCTION; - return CallService(MS_TRIGGER_REGISTERACTION, 0, (LPARAM)&ar); -} - -int DeInitAction() -{ - return 0; -} diff --git a/plugins/KeyboardNotify/trigger.h b/plugins/KeyboardNotify/trigger.h deleted file mode 100644 index 41d830938c..0000000000 --- a/plugins/KeyboardNotify/trigger.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - -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. - -*/ - -int RegisterAction(); -int DeInitAction(); diff --git a/plugins/KeyboardNotify/utils.cpp b/plugins/KeyboardNotify/utils.cpp deleted file mode 100644 index 9c710ba217..0000000000 --- a/plugins/KeyboardNotify/utils.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ - -#define WIN32_LEAN_AND_MEAN - -#include -#include -#include "utils.h" -#include -#include -#include - - -char *fmtDBSettingName(const char *fmt, ...) -{ - va_list va; - static char returnString[1024]; - - va_start(va, fmt); - mir_vsnprintf(returnString, sizeof(returnString), fmt, va); - va_end(va); - - return returnString; -} - - -TCHAR *getAbsoluteProfileName(TCHAR *absoluteProfileName, size_t maxLen) -{ - TCHAR profilePath[MAX_PATH+1], profileName[MAX_PATH+1]; - - profilePath[0] = profileName[0] = L'\0'; - CallService(MS_DB_GETPROFILEPATH, MAX_PATH, (LPARAM)profilePath); - CallService(MS_DB_GETPROFILENAME, MAX_PATH, (LPARAM)profileName); - _snwprintf(absoluteProfileName, maxLen, L"%s\\%s", profilePath, profileName); - - return absoluteProfileName; -} diff --git a/plugins/KeyboardNotify/utils.h b/plugins/KeyboardNotify/utils.h deleted file mode 100644 index 66917754ed..0000000000 --- a/plugins/KeyboardNotify/utils.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - -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. - -*/ - -char *fmtDBSettingName(const char *, ...); -TCHAR *getAbsoluteProfileName(TCHAR *, size_t); -- cgit v1.2.3