summaryrefslogtreecommitdiff
path: root/plugins/!NotAdopted/WinterSpeak/speak/announce
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/!NotAdopted/WinterSpeak/speak/announce')
-rw-r--r--plugins/!NotAdopted/WinterSpeak/speak/announce/announce_database.cpp111
-rw-r--r--plugins/!NotAdopted/WinterSpeak/speak/announce/announce_database.h80
-rw-r--r--plugins/!NotAdopted/WinterSpeak/speak/announce/dialog_announce.cpp209
-rw-r--r--plugins/!NotAdopted/WinterSpeak/speak/announce/dialog_announce.h48
-rw-r--r--plugins/!NotAdopted/WinterSpeak/speak/announce/event_information.cpp117
-rw-r--r--plugins/!NotAdopted/WinterSpeak/speak/announce/event_information.h69
-rw-r--r--plugins/!NotAdopted/WinterSpeak/speak/announce/protocol_information.cpp100
-rw-r--r--plugins/!NotAdopted/WinterSpeak/speak/announce/protocol_information.h41
-rw-r--r--plugins/!NotAdopted/WinterSpeak/speak/announce/speak_announce.cpp243
-rw-r--r--plugins/!NotAdopted/WinterSpeak/speak/announce/speak_announce.h74
10 files changed, 1092 insertions, 0 deletions
diff --git a/plugins/!NotAdopted/WinterSpeak/speak/announce/announce_database.cpp b/plugins/!NotAdopted/WinterSpeak/speak/announce/announce_database.cpp
new file mode 100644
index 0000000000..f5720624a7
--- /dev/null
+++ b/plugins/!NotAdopted/WinterSpeak/speak/announce/announce_database.cpp
@@ -0,0 +1,111 @@
+//==============================================================================
+// Miranda Speak Plugin, © 2002 Ryan Winter
+//==============================================================================
+
+#pragma warning(disable:4786)
+
+#include "announce_database.h"
+
+#include <general/debug/debug.h>
+
+#include <windows.h>
+#include <miranda32/random/plugins/newpluginapi.h>
+#include <miranda32/database/m_database.h>
+
+//------------------------------------------------------------------------------
+namespace
+{
+ const char *SPEAK = "speak_announce";
+ const char *STATUS_FLAGS = "status_flags";
+ const char *EVENT_FLAGS = "event_flags";
+ const char *MAX_MSG_SIZE = "max_msg_size";
+}
+
+//------------------------------------------------------------------------------
+// public:
+//------------------------------------------------------------------------------
+AnnounceDatabase::AnnounceDatabase()
+ :
+ m_status_flags(0),
+ m_event_flags(0),
+ m_max_msg(0)
+{
+ CLASSCERR("AnnounceDatabase::AnnounceDatabase");
+
+ // load the database from miranda
+ load();
+}
+
+//------------------------------------------------------------------------------
+AnnounceDatabase::~AnnounceDatabase()
+{
+ CLASSCERR("AnnounceDatabase::~AnnounceDatabase");
+}
+
+//------------------------------------------------------------------------------
+bool
+AnnounceDatabase::getStatusFlag(StatusFlag flag) const
+{
+ return ((m_status_flags & (1 << flag)) != 0);
+}
+
+//------------------------------------------------------------------------------
+void
+AnnounceDatabase::setStatusFlag(StatusFlag flag, bool state)
+{
+ if (state)
+ {
+ m_status_flags |= (1 << flag);
+ }
+ else
+ {
+ m_status_flags &= ~(1 << flag);
+ }
+}
+
+//------------------------------------------------------------------------------
+bool
+AnnounceDatabase::getEventFlag(EventFlag flag) const
+{
+ return ((m_event_flags & (1 << flag)) != 0);
+}
+
+//------------------------------------------------------------------------------
+void
+AnnounceDatabase::setEventFlag(EventFlag flag, bool state)
+{
+ if (state)
+ {
+ m_event_flags |= (1 << flag);
+ }
+ else
+ {
+ m_event_flags &= ~(1 << flag);
+ }
+}
+
+//------------------------------------------------------------------------------
+void
+AnnounceDatabase::load()
+{
+ CLASSCERR("AnnounceDatabase::load");
+
+ m_status_flags = DBGetContactSettingDword(NULL, SPEAK, STATUS_FLAGS,
+ 0xffff);
+ m_event_flags = DBGetContactSettingDword(NULL, SPEAK, EVENT_FLAGS,
+ 0xffff);
+ m_max_msg = DBGetContactSettingDword(NULL, SPEAK, MAX_MSG_SIZE, 50);
+}
+
+//------------------------------------------------------------------------------
+void
+AnnounceDatabase::save()
+{
+ CLASSCERR("AnnounceDatabase::save");
+
+ DBWriteContactSettingDword(NULL, SPEAK, STATUS_FLAGS, m_status_flags);
+ DBWriteContactSettingDword(NULL, SPEAK, EVENT_FLAGS, m_event_flags);
+ DBWriteContactSettingDword(NULL, SPEAK, MAX_MSG_SIZE, m_max_msg);
+}
+
+//==============================================================================
diff --git a/plugins/!NotAdopted/WinterSpeak/speak/announce/announce_database.h b/plugins/!NotAdopted/WinterSpeak/speak/announce/announce_database.h
new file mode 100644
index 0000000000..b3c950cd8d
--- /dev/null
+++ b/plugins/!NotAdopted/WinterSpeak/speak/announce/announce_database.h
@@ -0,0 +1,80 @@
+#ifndef guard_speak_announce_announce_database_h
+#define guard_speak_announce_announce_database_h
+//==============================================================================
+// Miranda Speak Plugin, © 2002 Ryan Winter
+//==============================================================================
+
+#include <string>
+
+class AnnounceDatabase
+{
+ public:
+ AnnounceDatabase();
+ ~AnnounceDatabase();
+
+ enum StatusFlag
+ {
+ StatusFlag_Offline = 0,
+ StatusFlag_Online,
+ StatusFlag_Away,
+ StatusFlag_Dnd,
+ StatusFlag_Na,
+ StatusFlag_Occupied,
+ StatusFlag_FreeForChat,
+ StatusFlag_Invisible,
+ StatusFlag_SpeakStatusMsg,
+ StatusFlag_SuppressConnect,
+ };
+
+ enum EventFlag
+ {
+ EventFlag_Message = 0,
+ EventFlag_Url,
+ EventFlag_Added,
+ EventFlag_AuthRequest,
+ EventFlag_File,
+ EventFlag_ReadMsgLength,
+ EventFlag_DialogOpen,
+ EventFlag_DialogFocused,
+ };
+
+ //--------------------------------------------------------------------------
+ // Description : get/set a status flags
+ //--------------------------------------------------------------------------
+ bool getStatusFlag(StatusFlag flag) const;
+ void setStatusFlag(StatusFlag flag, bool state);
+
+ //--------------------------------------------------------------------------
+ // Description : get/set an event flags
+ //--------------------------------------------------------------------------
+ bool getEventFlag(EventFlag flag) const;
+ void setEventFlag(EventFlag flag, bool state);
+
+ //--------------------------------------------------------------------------
+ // Description : get/set an event flags
+ //--------------------------------------------------------------------------
+ unsigned int getMaxMsgSize() const { return m_max_msg; }
+ void setMaxMsgSize(unsigned int size) { m_max_msg = size; }
+
+ //--------------------------------------------------------------------------
+ // Description : load/save the settings from the miranda database
+ //--------------------------------------------------------------------------
+ void load();
+ void save();
+
+ private:
+ unsigned int m_status_flags;
+ unsigned int m_event_flags;
+
+ unsigned int m_max_msg;
+};
+
+//==============================================================================
+//
+// Summary : encapsulate the access to the miranda database
+//
+// Description : see summary
+//
+//==============================================================================
+
+#endif \ No newline at end of file
diff --git a/plugins/!NotAdopted/WinterSpeak/speak/announce/dialog_announce.cpp b/plugins/!NotAdopted/WinterSpeak/speak/announce/dialog_announce.cpp
new file mode 100644
index 0000000000..5a21859ba5
--- /dev/null
+++ b/plugins/!NotAdopted/WinterSpeak/speak/announce/dialog_announce.cpp
@@ -0,0 +1,209 @@
+//==============================================================================
+// Miranda Speak Plugin, © 2002 Ryan Winter
+//==============================================================================
+
+#pragma warning(disable:4786)
+
+#include "announce/dialog_announce.h"
+
+#include "resource.h"
+#include "speak.h"
+
+#include <general/debug/debug.h>
+
+#include <windows.h>
+
+//------------------------------------------------------------------------------
+AnnounceDialog *AnnounceDialog::m_instance = 0;
+
+//------------------------------------------------------------------------------
+// public:
+//------------------------------------------------------------------------------
+AnnounceDialog::AnnounceDialog(AnnounceDatabase &db)
+ :
+ m_db(db)
+{
+ CLASSCERR("AnnounceDialog::AnnounceDialog");
+
+ m_instance = this;
+}
+
+//------------------------------------------------------------------------------
+AnnounceDialog::~AnnounceDialog()
+{
+ CLASSCERR("AnnounceDialog::~AnnounceDialog");
+
+ m_instance = 0;
+}
+
+//------------------------------------------------------------------------------
+// private:
+//------------------------------------------------------------------------------
+int CALLBACK
+AnnounceDialog::process(HWND window, UINT message, WPARAM wparam, LPARAM lparam)
+{
+ if (!m_instance)
+ {
+ return 1;
+ }
+
+ switch (message)
+ {
+ case WM_INITDIALOG:
+ m_instance->load(window);
+ break;
+
+ case WM_COMMAND:
+ m_instance->command(window, wparam);
+ break;
+
+ case WM_NOTIFY:
+ if (PSN_APPLY == LPNMHDR(lparam)->code)
+ {
+ m_instance->save(window);
+ }
+ break;
+ }
+
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+void
+AnnounceDialog::command(HWND window, int control)
+{
+ switch (LOWORD(control))
+ {
+ case IDC_STATUS_OFFLINE:
+ case IDC_STATUS_ONLINE:
+ case IDC_STATUS_AWAY:
+ case IDC_STATUS_DND:
+ case IDC_STATUS_NA:
+ case IDC_STATUS_OCCUPIED:
+ case IDC_STATUS_FREEFORCHAT:
+ case IDC_STATUS_INVISIBLE:
+ case IDC_SPEAK_STATUS_MSG:
+ case IDC_SUPPRESS_CONNECT:
+ case IDC_EVENT_MESSAGE:
+ case IDC_EVENT_URL:
+ case IDC_EVENT_FILE:
+ case IDC_EVENT_AUTHREQUEST:
+ case IDC_EVENT_ADDED:
+ case IDC_READ_MSG_LENGTH:
+ case IDC_DIALOG_OPEN:
+ case IDC_DIALOG_FOCUSED:
+
+ changed(window);
+ break;
+
+ case IDC_MAX_MSG:
+ if (EN_CHANGE == HIWORD(control))
+ {
+ changed(window);
+ }
+ break;
+ }
+}
+
+//------------------------------------------------------------------------------
+void
+AnnounceDialog::load(HWND window)
+{
+ CLASSCERR("AnnounceDialog::load");
+
+ TranslateDialogDefault(window);
+
+ // initialise the checkboxes
+ CheckDlgButton(window, IDC_STATUS_OFFLINE,
+ m_db.getStatusFlag(AnnounceDatabase::StatusFlag_Offline));
+ CheckDlgButton(window, IDC_STATUS_ONLINE,
+ m_db.getStatusFlag(AnnounceDatabase::StatusFlag_Online));
+ CheckDlgButton(window, IDC_STATUS_AWAY,
+ m_db.getStatusFlag(AnnounceDatabase::StatusFlag_Away));
+ CheckDlgButton(window, IDC_STATUS_DND,
+ m_db.getStatusFlag(AnnounceDatabase::StatusFlag_Dnd));
+ CheckDlgButton(window, IDC_STATUS_NA,
+ m_db.getStatusFlag(AnnounceDatabase::StatusFlag_Na));
+ CheckDlgButton(window, IDC_STATUS_OCCUPIED,
+ m_db.getStatusFlag(AnnounceDatabase::StatusFlag_Occupied));
+ CheckDlgButton(window, IDC_STATUS_FREEFORCHAT,
+ m_db.getStatusFlag(AnnounceDatabase::StatusFlag_FreeForChat));
+ CheckDlgButton(window, IDC_STATUS_INVISIBLE,
+ m_db.getStatusFlag(AnnounceDatabase::StatusFlag_Invisible));
+ CheckDlgButton(window, IDC_SPEAK_STATUS_MSG,
+ m_db.getStatusFlag(AnnounceDatabase::StatusFlag_SpeakStatusMsg));
+ CheckDlgButton(window, IDC_SUPPRESS_CONNECT,
+ m_db.getStatusFlag(AnnounceDatabase::StatusFlag_SuppressConnect));
+
+ CheckDlgButton(window, IDC_EVENT_MESSAGE,
+ m_db.getEventFlag(AnnounceDatabase::EventFlag_Message));
+ CheckDlgButton(window, IDC_EVENT_URL,
+ m_db.getEventFlag(AnnounceDatabase::EventFlag_Url));
+ CheckDlgButton(window, IDC_EVENT_FILE,
+ m_db.getEventFlag(AnnounceDatabase::EventFlag_File));
+ CheckDlgButton(window, IDC_EVENT_AUTHREQUEST,
+ m_db.getEventFlag(AnnounceDatabase::EventFlag_AuthRequest));
+ CheckDlgButton(window, IDC_EVENT_ADDED,
+ m_db.getEventFlag(AnnounceDatabase::EventFlag_Added));
+ CheckDlgButton(window, IDC_READ_MSG_LENGTH,
+ m_db.getEventFlag(AnnounceDatabase::EventFlag_ReadMsgLength));
+ CheckDlgButton(window, IDC_DIALOG_OPEN,
+ m_db.getEventFlag(AnnounceDatabase::EventFlag_DialogOpen));
+ CheckDlgButton(window, IDC_DIALOG_FOCUSED,
+ m_db.getEventFlag(AnnounceDatabase::EventFlag_DialogFocused));
+
+ // initialise the welcome message box
+ SetDlgItemInt(window, IDC_MAX_MSG, m_db.getMaxMsgSize(), 0);
+}
+
+//------------------------------------------------------------------------------
+void
+AnnounceDialog::save(HWND window)
+{
+ CLASSCERR("AnnounceDialog::save");
+
+ // store the checkboxes
+ m_db.setStatusFlag(AnnounceDatabase::StatusFlag_Offline,
+ (IsDlgButtonChecked(window, IDC_STATUS_OFFLINE) != 0));
+ m_db.setStatusFlag(AnnounceDatabase::StatusFlag_Online,
+ (IsDlgButtonChecked(window, IDC_STATUS_ONLINE) != 0));
+ m_db.setStatusFlag(AnnounceDatabase::StatusFlag_Away,
+ (IsDlgButtonChecked(window, IDC_STATUS_AWAY) != 0));
+ m_db.setStatusFlag(AnnounceDatabase::StatusFlag_Dnd,
+ (IsDlgButtonChecked(window, IDC_STATUS_DND) != 0));
+ m_db.setStatusFlag(AnnounceDatabase::StatusFlag_Na,
+ (IsDlgButtonChecked(window, IDC_STATUS_NA) != 0));
+ m_db.setStatusFlag(AnnounceDatabase::StatusFlag_Occupied,
+ (IsDlgButtonChecked(window, IDC_STATUS_OCCUPIED) != 0));
+ m_db.setStatusFlag(AnnounceDatabase::StatusFlag_FreeForChat,
+ (IsDlgButtonChecked(window, IDC_STATUS_FREEFORCHAT) != 0));
+ m_db.setStatusFlag(AnnounceDatabase::StatusFlag_Invisible,
+ (IsDlgButtonChecked(window, IDC_STATUS_INVISIBLE) != 0));
+ m_db.setStatusFlag(AnnounceDatabase::StatusFlag_SpeakStatusMsg,
+ (IsDlgButtonChecked(window, IDC_SPEAK_STATUS_MSG) != 0));
+ m_db.setStatusFlag(AnnounceDatabase::StatusFlag_SuppressConnect,
+ (IsDlgButtonChecked(window, IDC_SUPPRESS_CONNECT) != 0));
+
+ m_db.setEventFlag(AnnounceDatabase::EventFlag_Message,
+ (IsDlgButtonChecked(window, IDC_EVENT_MESSAGE) != 0));
+ m_db.setEventFlag(AnnounceDatabase::EventFlag_Url,
+ (IsDlgButtonChecked(window, IDC_EVENT_URL) != 0));
+ m_db.setEventFlag(AnnounceDatabase::EventFlag_File,
+ (IsDlgButtonChecked(window, IDC_EVENT_FILE) != 0));
+ m_db.setEventFlag(AnnounceDatabase::EventFlag_AuthRequest,
+ (IsDlgButtonChecked(window, IDC_EVENT_AUTHREQUEST) != 0));
+ m_db.setEventFlag(AnnounceDatabase::EventFlag_Added,
+ (IsDlgButtonChecked(window, IDC_EVENT_ADDED) != 0));
+ m_db.setEventFlag(AnnounceDatabase::EventFlag_ReadMsgLength,
+ (IsDlgButtonChecked(window, IDC_READ_MSG_LENGTH) != 0));
+ m_db.setEventFlag(AnnounceDatabase::EventFlag_DialogOpen,
+ (IsDlgButtonChecked(window, IDC_DIALOG_OPEN) != 0));
+ m_db.setEventFlag(AnnounceDatabase::EventFlag_DialogFocused,
+ (IsDlgButtonChecked(window, IDC_DIALOG_FOCUSED) != 0));
+
+ m_db.setMaxMsgSize(GetDlgItemInt(window, IDC_MAX_MSG, NULL, 0));
+
+ m_instance->m_db.save();
+}
+
+//============================================================================== \ No newline at end of file
diff --git a/plugins/!NotAdopted/WinterSpeak/speak/announce/dialog_announce.h b/plugins/!NotAdopted/WinterSpeak/speak/announce/dialog_announce.h
new file mode 100644
index 0000000000..ea8fca5407
--- /dev/null
+++ b/plugins/!NotAdopted/WinterSpeak/speak/announce/dialog_announce.h
@@ -0,0 +1,48 @@
+#ifndef guard_speak_announce_announce_dialog_h
+#define guard_speak_announce_announce_dialog_h
+//==============================================================================
+// Miranda Speak Plugin, © 2002 Ryan Winter
+//==============================================================================
+
+#include "dialog/miranda_dialog.h"
+#include "announce/announce_database.h"
+
+#include <wtypes.h>
+#include <string>
+
+class AnnounceDialog : public MirandaDialog
+{
+ public:
+ AnnounceDialog(AnnounceDatabase &db);
+ ~AnnounceDialog();
+
+ //--------------------------------------------------------------------------
+ // Description : process a dialog message
+ // Return : true - update the systems configuration
+ // false - do nothing
+ //--------------------------------------------------------------------------
+ static int CALLBACK process(HWND window, UINT message, WPARAM wparam,
+ LPARAM lparam);
+
+ private:
+ void command(HWND window, int control);
+
+ //--------------------------------------------------------------------------
+ // Description : load/save settings to the miranda database
+ //--------------------------------------------------------------------------
+ void load(HWND window);
+ void save(HWND window);
+
+ static AnnounceDialog *m_instance;
+ AnnounceDatabase &m_db;
+};
+
+//==============================================================================
+//
+// Summary : Configuration Dialog box
+//
+// Description : Set up the configuration dialog box and process its input
+//
+//==============================================================================
+
+#endif \ No newline at end of file
diff --git a/plugins/!NotAdopted/WinterSpeak/speak/announce/event_information.cpp b/plugins/!NotAdopted/WinterSpeak/speak/announce/event_information.cpp
new file mode 100644
index 0000000000..bf326e5cfb
--- /dev/null
+++ b/plugins/!NotAdopted/WinterSpeak/speak/announce/event_information.cpp
@@ -0,0 +1,117 @@
+//==============================================================================
+// Miranda Speak Plugin, © 2002 Ryan Winter
+//==============================================================================
+
+#pragma warning(disable:4786)
+
+#include "event_information.h"
+#include "speak.h"
+
+#include <general/debug/debug.h>
+
+//------------------------------------------------------------------------------
+// public:
+//------------------------------------------------------------------------------
+EventInformation::EventInformation()
+ :
+ m_event_strings(),
+ m_event_info()
+{
+ CLASSCERR("EventInformation::EventInformation");
+
+ // insert the event strings into a map for easy access
+ m_event_strings[EVENTTYPE_MESSAGE]
+ = Translate("incoming message from %u");
+ m_event_strings[EVENTTYPE_URL]
+ = Translate("incoming U R L from %u");
+ m_event_strings[EVENTTYPE_ADDED]
+ = Translate("you have been added to %u's contact list");
+ m_event_strings[EVENTTYPE_AUTHREQUEST]
+ = Translate("%u requests your authorization");
+ m_event_strings[EVENTTYPE_FILE]
+ = Translate("there is an incoming file from %u");
+
+ ZeroMemory(&m_event_info, sizeof(m_event_info));
+}
+
+//------------------------------------------------------------------------------
+EventInformation::~EventInformation()
+{
+ CLASSCERR("EventInformation::~EventInformation");
+}
+
+//------------------------------------------------------------------------------
+bool
+EventInformation::isValidEvent(HANDLE event)
+{
+ CLASSCERR("EventInformation::isValidEvent()");
+
+ // clean up the old event
+ if (m_event_info.pBlob)
+ {
+ delete m_event_info.pBlob;
+ }
+ ZeroMemory(&m_event_info, sizeof(m_event_info));
+
+ // find out and assign the space we need for the new event
+ m_event_info.cbSize = sizeof(m_event_info);
+ m_event_info.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE,
+ reinterpret_cast<LPARAM>(event), 0);
+
+ if (-1 == m_event_info.cbBlob)
+ {
+ return false;
+ }
+
+ m_event_info.pBlob = new unsigned char[m_event_info.cbBlob];
+
+ // get the event info
+ CallService(MS_DB_EVENT_GET, reinterpret_cast<LPARAM>(event),
+ reinterpret_cast<LPARAM>(&m_event_info));
+
+ // if the event has already been read or was sent by me then exit
+ if (m_event_info.flags & (DBEF_SENT | DBEF_READ))
+ {
+ return false;
+ }
+
+ // if the event string doesn't exist in our list then exit
+ if (m_event_strings.find(m_event_info.eventType) == m_event_strings.end())
+ {
+ return false;
+ }
+
+ // event was good
+ return true;
+}
+
+//------------------------------------------------------------------------------
+std::string
+EventInformation::getMessage()
+{
+ CLASSCERR("EventInformation::getMessage");
+
+ const std::string intro = Translate("%u says");
+
+ return intro + " " + (char *)m_event_info.pBlob;
+}
+
+//------------------------------------------------------------------------------
+unsigned int
+EventInformation::getMessageSize()
+{
+ CLASSCERR("EventInformation::getMessageSize");
+
+ return std::string((char *)m_event_info.pBlob).size();
+}
+
+//------------------------------------------------------------------------------
+std::string
+EventInformation::eventString()
+{
+ CLASSCERR("EventInformation::eventString");
+
+ return m_event_strings[m_event_info.eventType];
+}
+
+//==============================================================================
diff --git a/plugins/!NotAdopted/WinterSpeak/speak/announce/event_information.h b/plugins/!NotAdopted/WinterSpeak/speak/announce/event_information.h
new file mode 100644
index 0000000000..626515e8ea
--- /dev/null
+++ b/plugins/!NotAdopted/WinterSpeak/speak/announce/event_information.h
@@ -0,0 +1,69 @@
+#ifndef guard_speak_announce_event_information_h
+#define guard_speak_announce_event_information_h
+//==============================================================================
+// Miranda Speak Plugin, © 2002 Ryan Winter
+//==============================================================================
+
+#include <speak.h>
+
+#include <map>
+#include <string>
+
+class EventInformation
+{
+ public:
+ EventInformation();
+ ~EventInformation();
+
+ //--------------------------------------------------------------------------
+ // Description : is the event valid?
+ // Return : true = the event is valid
+ //--------------------------------------------------------------------------
+ bool isValidEvent(HANDLE event);
+
+ //--------------------------------------------------------------------------
+ // Description : get the last event received
+ // Return : the last event or 0 if none yet received
+ //--------------------------------------------------------------------------
+ unsigned short getLastEvent() { return m_event_info.eventType; }
+
+ //--------------------------------------------------------------------------
+ // Description : was the last event a messsage event?
+ // Return : true - yes it was
+ // false - no it wasn't
+ //--------------------------------------------------------------------------
+// bool isMessageEvent()
+// { return (m_event_info.eventType == EVENTTYPE_MESSAGE); }
+
+ //--------------------------------------------------------------------------
+ // Description : get the message from the last event
+ // Return : the last message
+ //--------------------------------------------------------------------------
+ std::string getMessage();
+
+ //--------------------------------------------------------------------------
+ // Description : get the size of the message from the last event
+ // Return : the size of the message
+ //--------------------------------------------------------------------------
+ unsigned int getMessageSize();
+
+ //--------------------------------------------------------------------------
+ // Description : get the event string
+ //--------------------------------------------------------------------------
+ std::string eventString();
+
+ private:
+ std::map<unsigned short, std::string> m_event_strings;
+
+ DBEVENTINFO m_event_info;
+};
+
+//==============================================================================
+//
+// Summary : API encapsulation
+//
+// Description : This encapsulates the SAPI 5.1 interface
+//
+//==============================================================================
+
+#endif \ No newline at end of file
diff --git a/plugins/!NotAdopted/WinterSpeak/speak/announce/protocol_information.cpp b/plugins/!NotAdopted/WinterSpeak/speak/announce/protocol_information.cpp
new file mode 100644
index 0000000000..b3d9752bd4
--- /dev/null
+++ b/plugins/!NotAdopted/WinterSpeak/speak/announce/protocol_information.cpp
@@ -0,0 +1,100 @@
+//==============================================================================
+// Miranda Speak Plugin, © 2002 Ryan Winter
+//==============================================================================
+
+#pragma warning(disable:4786)
+
+#include "protocol_information.h"
+
+#include <general/debug/debug.h>
+
+//------------------------------------------------------------------------------
+ProtocolInformation *ProtocolInformation::m_instance = 0;
+
+//------------------------------------------------------------------------------
+// public:
+//------------------------------------------------------------------------------
+ProtocolInformation::ProtocolInformation()
+ :
+ m_protocol_timeout()
+{
+ CLASSCERR("ProtocolInformation::ProtocolInformation");
+
+ m_instance = this;
+}
+
+//------------------------------------------------------------------------------
+ProtocolInformation::~ProtocolInformation()
+{
+ CLASSCERR("ProtocolInformation::~ProtocolInformation");
+
+ m_instance = 0;
+
+ // kill all the timers
+ for (ProtocolTimeoutQueue::const_iterator iter = m_protocol_timeout.begin();
+ iter != m_protocol_timeout.end();
+ ++iter)
+ {
+ KillTimer(NULL, (*iter).second);
+ }
+}
+
+//------------------------------------------------------------------------------
+void
+ProtocolInformation::disable(const char *protocol)
+{
+ CLASSCERR("ProtocolInformation::disable(" << protocol << ")");
+
+ if (NULL == protocol)
+ {
+ return;
+ }
+
+ const unsigned int TIMEOUT = 10000;
+
+ unsigned int t
+ = SetTimer(NULL, NULL, TIMEOUT, ProtocolInformation::timeout);
+ m_protocol_timeout.push_back(std::make_pair(protocol, t));
+}
+
+//------------------------------------------------------------------------------
+bool
+ProtocolInformation::isDisabled(const char *protocol) const
+{
+ CLASSCERR("ProtocolInformation::isDisable(" << protocol << ")");
+
+ if (NULL == protocol)
+ {
+ return false;
+ }
+
+ // iterate through the list and see if the protocol has a timer callback
+ for (ProtocolTimeoutQueue::const_iterator iter = m_protocol_timeout.begin();
+ iter != m_protocol_timeout.end();
+ ++iter)
+ {
+ if (0 == (*iter).first.compare(protocol))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+//------------------------------------------------------------------------------
+// private:
+//------------------------------------------------------------------------------
+void CALLBACK
+ProtocolInformation::timeout(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
+{
+ CERR("ProtocolInformation::timeout(,,,)");
+
+ ProtocolTimeout pt = m_instance->m_protocol_timeout.front();
+
+ KillTimer(NULL, pt.second);
+
+ m_instance->m_protocol_timeout.pop_front();
+}
+
+//==============================================================================
diff --git a/plugins/!NotAdopted/WinterSpeak/speak/announce/protocol_information.h b/plugins/!NotAdopted/WinterSpeak/speak/announce/protocol_information.h
new file mode 100644
index 0000000000..c003f43034
--- /dev/null
+++ b/plugins/!NotAdopted/WinterSpeak/speak/announce/protocol_information.h
@@ -0,0 +1,41 @@
+#ifndef guard_speak_announce_protocol_information_h
+#define guard_speak_announce_protocol_information_h
+//==============================================================================
+// Miranda Speak Plugin, © 2002 Ryan Winter
+//==============================================================================
+
+#include <windows.h>
+
+#include <deque>
+#include <utility>
+
+class ProtocolInformation
+{
+ public:
+ ProtocolInformation();
+ ~ProtocolInformation();
+
+ void disable(const char *protocol);
+ bool isDisabled(const char *protocol) const;
+
+ private:
+ typedef std::pair<std::string, unsigned int> ProtocolTimeout;
+ typedef std::deque<ProtocolTimeout> ProtocolTimeoutQueue;
+
+ static void CALLBACK timeout(HWND hwnd, UINT uMsg, UINT idEvent,
+ DWORD dwTime);
+
+ static ProtocolInformation *m_instance;
+
+ ProtocolTimeoutQueue m_protocol_timeout;
+};
+
+//==============================================================================
+//
+// Summary :
+//
+// Description :
+//
+//==============================================================================
+
+#endif \ No newline at end of file
diff --git a/plugins/!NotAdopted/WinterSpeak/speak/announce/speak_announce.cpp b/plugins/!NotAdopted/WinterSpeak/speak/announce/speak_announce.cpp
new file mode 100644
index 0000000000..d54d8354ed
--- /dev/null
+++ b/plugins/!NotAdopted/WinterSpeak/speak/announce/speak_announce.cpp
@@ -0,0 +1,243 @@
+//==============================================================================
+// Miranda Speak Plugin, © 2002 Ryan Winter
+//==============================================================================
+
+#pragma warning(disable:4786)
+
+#include "speak_announce.h"
+
+#include "m_speak.h"
+
+#include <general/debug/debug.h>
+
+//------------------------------------------------------------------------------
+// public:
+//------------------------------------------------------------------------------
+SpeakAnnounce::SpeakAnnounce(HINSTANCE instance)
+ :
+ m_instance(instance),
+ m_db(),
+ m_dialog(m_db),
+ m_user_info(),
+ m_event_info(),
+ m_protocol_info()
+{
+ CLASSCERR("SpeakAnnounce::SpeakAnnounce");
+}
+
+//------------------------------------------------------------------------------
+SpeakAnnounce::~SpeakAnnounce()
+{
+ CLASSCERR("SpeakAnnounce::~SpeakAnnounce");
+}
+
+//------------------------------------------------------------------------------
+void
+SpeakAnnounce::statusChange(DBCONTACTWRITESETTING *write_setting, HANDLE user)
+{
+ const std::string STATUS = "Status";
+
+ // if the user is myself (NULL) then return
+ // if it's not a status change then return
+ // check and update the user's status, if status didn't change the return
+ if ((NULL == user)
+ || (STATUS != write_setting->szSetting)
+ || (!m_user_info.updateStatus(user, write_setting->value.wVal)))
+ {
+ return;
+ }
+
+ // check if we just connected, and want to suppress status changes
+ if (!m_db.getStatusFlag(AnnounceDatabase::StatusFlag_SuppressConnect)
+ && m_protocol_info.isDisabled(
+ (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)user, 0)))
+ {
+ return;
+ }
+
+ bool speak = false;
+
+ switch (write_setting->value.wVal)
+ {
+ case ID_STATUS_OFFLINE:
+ speak = m_db.getStatusFlag(AnnounceDatabase::StatusFlag_Offline);
+ break;
+ case ID_STATUS_ONLINE:
+ speak = m_db.getStatusFlag(AnnounceDatabase::StatusFlag_Online);
+ break;
+ case ID_STATUS_AWAY:
+ speak = m_db.getStatusFlag(AnnounceDatabase::StatusFlag_Away);
+ break;
+ case ID_STATUS_DND:
+ speak = m_db.getStatusFlag(AnnounceDatabase::StatusFlag_Dnd);
+ break;
+ case ID_STATUS_NA:
+ speak = m_db.getStatusFlag(AnnounceDatabase::StatusFlag_Na);
+ break;
+ case ID_STATUS_OCCUPIED:
+ speak = m_db.getStatusFlag(AnnounceDatabase::StatusFlag_Occupied);
+ break;
+ case ID_STATUS_FREECHAT:
+ speak = m_db.getStatusFlag(AnnounceDatabase::StatusFlag_FreeForChat);
+ break;
+ case ID_STATUS_INVISIBLE:
+ speak = m_db.getStatusFlag(AnnounceDatabase::StatusFlag_Invisible);
+ break;
+ }
+
+ if (!speak)
+ {
+ return;
+ }
+
+ // translate, insert name then speak
+ std::string status_str = Translate(m_user_info.statusString(user).c_str());
+ m_user_info.insertName(status_str, user);
+ say(status_str, user);
+}
+
+//------------------------------------------------------------------------------
+void
+SpeakAnnounce::incomingEvent(HANDLE user, HANDLE event)
+{
+ CLASSCERR("SpeakAnnounce::incomingEvent(" << user << "," << event << ")");
+
+ if (m_event_info.isValidEvent(event))
+ {
+ bool speak = false;
+
+ switch (m_event_info.getLastEvent())
+ {
+ case EVENTTYPE_MESSAGE:
+ speak = m_db.getEventFlag(AnnounceDatabase::EventFlag_Message);
+ break;
+
+ case EVENTTYPE_URL:
+ speak = m_db.getEventFlag(AnnounceDatabase::EventFlag_Url);
+ break;
+
+ case EVENTTYPE_ADDED:
+ speak = m_db.getEventFlag(AnnounceDatabase::EventFlag_Added);
+ break;
+
+ case EVENTTYPE_AUTHREQUEST:
+ speak = m_db.getEventFlag(AnnounceDatabase::EventFlag_AuthRequest);
+ break;
+
+ case EVENTTYPE_FILE:
+ speak = m_db.getEventFlag(AnnounceDatabase::EventFlag_File);
+ break;
+
+ }
+
+ if (!speak)
+ {
+ return;
+ }
+
+ std::string event_str = "";
+
+ if (EVENTTYPE_MESSAGE == m_event_info.getLastEvent())
+ {
+ if (!readMessage(user))
+ {
+ // message dialog is open so just leave without saying anything
+ return;
+ }
+
+ if ((m_db.getEventFlag(AnnounceDatabase::EventFlag_ReadMsgLength))
+ && (m_event_info.getMessageSize() <= m_db.getMaxMsgSize()))
+ {
+ // conditions met to read the message
+ event_str = m_event_info.getMessage();
+ }
+ else
+ {
+ event_str = m_event_info.eventString();
+ }
+ }
+ else
+ {
+ event_str = m_event_info.eventString();
+ }
+
+ // translate the string, insert the name, then speak it
+ m_user_info.insertName(event_str, user);
+ say(event_str, user);
+ }
+}
+
+//------------------------------------------------------------------------------
+void
+SpeakAnnounce::protocolAck(ACKDATA *ack)
+{
+ if (ACKTYPE_STATUS != ack->type)
+ {
+ return;
+ }
+
+ if (ID_STATUS_CONNECTING != (int)ack->hProcess)
+ {
+ return;
+ }
+
+ m_protocol_info.disable((char *)ack->szModule);
+}
+
+//------------------------------------------------------------------------------
+void
+SpeakAnnounce::say(const std::string &sentence, HANDLE user)
+{
+ CLASSCERR("SpeakAnnounce::say(" << sentence << ", " << (int)user << ")");
+
+ CallService(ME_SPEAK_SAY, reinterpret_cast<LPARAM>(user),
+ reinterpret_cast<WPARAM>(sentence.c_str()));
+}
+
+//------------------------------------------------------------------------------
+bool
+SpeakAnnounce::readMessage(HANDLE contact)
+{
+ std::string title = m_user_info.nameString(contact) + " ("
+ + m_user_info.statusModeString(contact) + "): ";
+
+ HWND window = NULL;
+
+ window = FindWindow("#32770", (title + Translate("Message Session")).c_str());
+ if (window)
+ {
+ // check if we dont want to read message if dialog is open
+ if (m_db.getEventFlag(AnnounceDatabase::EventFlag_DialogOpen))
+ {
+ return false;
+ }
+
+ // check if we dont want to read message if dialog if focused
+ if ((window == GetForegroundWindow())
+ && m_db.getEventFlag(AnnounceDatabase::EventFlag_DialogFocused))
+ {
+ return false;
+ }
+ }
+
+ window = FindWindow("#32770", (title + Translate("Message Received")).c_str());
+ if (window)
+ {
+ // check if we dont want to read message if dialog is open
+ if (m_db.getEventFlag(AnnounceDatabase::EventFlag_DialogOpen))
+ {
+ return false;
+ }
+
+ // check if we dont want to read message if dialog if focused
+ if ((window == GetForegroundWindow())
+ && m_db.getEventFlag(AnnounceDatabase::EventFlag_DialogFocused))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+//==============================================================================
diff --git a/plugins/!NotAdopted/WinterSpeak/speak/announce/speak_announce.h b/plugins/!NotAdopted/WinterSpeak/speak/announce/speak_announce.h
new file mode 100644
index 0000000000..bd20ed6689
--- /dev/null
+++ b/plugins/!NotAdopted/WinterSpeak/speak/announce/speak_announce.h
@@ -0,0 +1,74 @@
+#ifndef guard_speak_announce_speak_announce_h
+#define guard_speak_announce_speak_announce_h
+//==============================================================================
+// Miranda Speak Plugin, © 2002 Ryan Winter
+//==============================================================================
+
+#include "speak.h"
+#include "user/user_information.h"
+#include "announce/event_information.h"
+#include "announce/protocol_information.h"
+#include "announce/announce_database.h"
+#include "announce/dialog_announce.h"
+
+#include <wtypes.h>
+#include <string>
+#include <memory>
+
+class SpeakAnnounce
+{
+ public:
+ SpeakAnnounce(HINSTANCE instance);
+ ~SpeakAnnounce();
+
+ //--------------------------------------------------------------------------
+ // Description : handle a status change
+ //--------------------------------------------------------------------------
+ void statusChange(DBCONTACTWRITESETTING *write_setting, HANDLE user);
+
+ //--------------------------------------------------------------------------
+ // Description : handle an event
+ //--------------------------------------------------------------------------
+ void incomingEvent(HANDLE user, HANDLE event);
+
+ //--------------------------------------------------------------------------
+ // Description : handle a protocol state change
+ //--------------------------------------------------------------------------
+ void protocolAck(ACKDATA *ack);
+
+ //--------------------------------------------------------------------------
+ // Description : speak a sentence
+ // Parameters : sentence - the sentence to speak
+ // user - the user who is speaking, or NULL for no user
+ // Returns : true - speak successful
+ // false - speak failed
+ //--------------------------------------------------------------------------
+ void say(const std::string &sentence, HANDLE user);
+
+ private:
+ //--------------------------------------------------------------------------
+ // Description : check if the users message window is open and focused
+ // Parameters : contact - the user to check for
+ // Returns : true = message window is open
+ // false = message window not open
+ //--------------------------------------------------------------------------
+ bool readMessage(HANDLE contact);
+
+ HINSTANCE m_instance;
+
+ AnnounceDatabase m_db;
+ AnnounceDialog m_dialog;
+ UserInformation m_user_info;
+ EventInformation m_event_info;
+ ProtocolInformation m_protocol_info;
+};
+
+//==============================================================================
+//
+// Summary : The main object for the speak plugins
+//
+// Description : see summary
+//
+//==============================================================================
+
+#endif \ No newline at end of file