summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/TabSRMM/src/generic_msghandlers.cpp4
-rw-r--r--plugins/TabSRMM/src/globals.cpp4
-rw-r--r--plugins/TabSRMM/src/hotkeyhandler.cpp16
-rw-r--r--plugins/TabSRMM/src/mim.cpp2
-rw-r--r--plugins/TabSRMM/src/msgdialog.cpp2
-rw-r--r--plugins/TabSRMM/src/msgs.cpp9
-rw-r--r--plugins/TabSRMM/src/sendlater.cpp720
-rw-r--r--plugins/TabSRMM/src/sendlater.h94
-rw-r--r--plugins/TabSRMM/src/sendqueue.cpp12
-rw-r--r--plugins/TabSRMM/src/srmm.cpp2
10 files changed, 417 insertions, 448 deletions
diff --git a/plugins/TabSRMM/src/generic_msghandlers.cpp b/plugins/TabSRMM/src/generic_msghandlers.cpp
index 5175a533d3..6614834eaf 100644
--- a/plugins/TabSRMM/src/generic_msghandlers.cpp
+++ b/plugins/TabSRMM/src/generic_msghandlers.cpp
@@ -363,7 +363,7 @@ LRESULT CMsgDialog::DM_MsgWindowCmdHandler(UINT cmd, WPARAM wParam, LPARAM lPara
RedrawWindow(m_hwnd, nullptr, nullptr, RDW_ERASENOW | RDW_UPDATENOW);
break;
case ID_SENDMENU_SENDLATER:
- if (sendLater->isAvail())
+ if (SendLater::Avail)
m_sendMode ^= SMODE_SENDLATER;
else
CWarning::show(CWarning::WARN_NO_SENDLATER, MB_OK | MB_ICONINFORMATION);
@@ -689,7 +689,7 @@ void CMsgDialog::DM_UpdateLastMessage() const
HWND CMsgDialog::DM_CreateClist()
{
- if (!sendLater->isAvail()) {
+ if (!SendLater::Avail) {
CWarning::show(CWarning::WARN_NO_SENDLATER, MB_OK | MB_ICONINFORMATION);
m_sendMode &= ~SMODE_MULTIPLE;
return nullptr;
diff --git a/plugins/TabSRMM/src/globals.cpp b/plugins/TabSRMM/src/globals.cpp
index 04dc12876e..e021ed9ffa 100644
--- a/plugins/TabSRMM/src/globals.cpp
+++ b/plugins/TabSRMM/src/globals.cpp
@@ -265,7 +265,7 @@ int CGlobals::ModulesLoaded(WPARAM, LPARAM)
mi.pszService = MS_TABMSG_SETUSERPREFS;
PluginConfig.m_UserMenuItem = Menu_AddContactMenuItem(&mi);
- if (sendLater->isAvail()) {
+ if (SendLater::Avail) {
SET_UID(mi, 0x8f32b04e, 0x314e, 0x42eb, 0x89, 0xc6, 0x56, 0x21, 0xf5, 0x1a, 0x2f, 0x22);
mi.position = -500050006;
mi.hIcolibItem = nullptr;
@@ -461,7 +461,7 @@ void CGlobals::RestoreUnreadMessageAlerts(void)
for (auto &hContact : Contacts()) {
if (db_get_dw(hContact, "SendLater", "count", 0))
- sendLater->addContact(hContact);
+ SendLater::addContact(hContact);
for (MEVENT hDbEvent = db_event_firstUnread(hContact); hDbEvent; hDbEvent = db_event_next(hContact, hDbEvent)) {
DBEVENTINFO dbei = {};
diff --git a/plugins/TabSRMM/src/hotkeyhandler.cpp b/plugins/TabSRMM/src/hotkeyhandler.cpp
index d8e6a59db1..4e11a2f606 100644
--- a/plugins/TabSRMM/src/hotkeyhandler.cpp
+++ b/plugins/TabSRMM/src/hotkeyhandler.cpp
@@ -393,17 +393,17 @@ LONG_PTR CALLBACK HotkeyHandlerDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LP
SendMessage(pCont->m_hwnd, WM_TIMER, TIMERID_HEARTBEAT, 0);
// process send later contacts and jobs, if enough time has elapsed
- if (sendLater->isAvail() && !sendLater->isInteractive() && (time(0) - sendLater->lastProcessed()) > CSendLater::SENDLATER_PROCESS_INTERVAL) {
- sendLater->setLastProcessed(time(0));
+ if (SendLater::Avail && !SendLater::isInteractive() && (time(0) - SendLater::lastProcessed()) > SENDLATER_PROCESS_INTERVAL) {
+ SendLater::setLastProcessed(time(0));
// check the list of contacts that may have new send later jobs
// (added on user's request)
- sendLater->processContacts();
+ SendLater::processContacts();
// start processing the job list
- if (!sendLater->isJobListEmpty()) {
+ if (!SendLater::isJobListEmpty()) {
KillTimer(hwndDlg, wParam);
- sendLater->startJobListProcess();
+ SendLater::startJobListProcess();
SetTimer(hwndDlg, TIMERID_SENDLATER_TICK, TIMEOUT_SENDLATER_TICK, nullptr);
}
}
@@ -413,12 +413,12 @@ LONG_PTR CALLBACK HotkeyHandlerDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LP
// TODO better timings, possibly slow down when many jobs are in the
// queue.
else if (wParam == TIMERID_SENDLATER_TICK) {
- if (!sendLater->haveJobs()) {
+ if (!SendLater::haveJobs()) {
KillTimer(hwndDlg, wParam);
SetTimer(hwndDlg, TIMERID_SENDLATER, TIMEOUT_SENDLATER, nullptr);
- sendLater->qMgrUpdate(true);
+ SendLater::qMgrUpdate(true);
}
- else sendLater->processCurrentJob();
+ else SendLater::processCurrentJob();
}
break;
diff --git a/plugins/TabSRMM/src/mim.cpp b/plugins/TabSRMM/src/mim.cpp
index 0c5708fe4e..5e3476f300 100644
--- a/plugins/TabSRMM/src/mim.cpp
+++ b/plugins/TabSRMM/src/mim.cpp
@@ -335,7 +335,7 @@ int CMimAPI::ProtoAck(WPARAM, LPARAM lParam)
}
}
if (iFound == SendQueue::NR_SENDJOBS) // no matching send info found in the queue
- sendLater->processAck(pAck);
+ SendLater::processAck(pAck);
else // try to find the process handle in the list of open send later jobs
SendMessage(jobs[iFound].hOwnerWnd, HM_EVENTSENT, (WPARAM)MAKELONG(iFound, i), lParam);
}
diff --git a/plugins/TabSRMM/src/msgdialog.cpp b/plugins/TabSRMM/src/msgdialog.cpp
index 6dcc92760c..16ca4dfc45 100644
--- a/plugins/TabSRMM/src/msgdialog.cpp
+++ b/plugins/TabSRMM/src/msgdialog.cpp
@@ -1423,7 +1423,7 @@ int CMsgDialog::OnFilter(MSGFILTER *pFilter)
PostMessage(m_hwnd, WM_COMMAND, MAKELONG(IDC_PIC, BN_CLICKED), 0);
return _dlgReturn(m_hwnd, 1);
case TABSRMM_HK_TOGGLESENDLATER:
- if (sendLater->isAvail()) {
+ if (SendLater::Avail) {
m_sendMode ^= SMODE_SENDLATER;
SetWindowPos(m_message.GetHwnd(), nullptr, 0, 0, 0, 0, SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_NOZORDER |
SWP_NOMOVE | SWP_NOSIZE | SWP_NOCOPYBITS);
diff --git a/plugins/TabSRMM/src/msgs.cpp b/plugins/TabSRMM/src/msgs.cpp
index 2f106f009b..718a80faa2 100644
--- a/plugins/TabSRMM/src/msgs.cpp
+++ b/plugins/TabSRMM/src/msgs.cpp
@@ -650,6 +650,12 @@ static INT_PTR ReloadSettings(WPARAM, LPARAM lParam)
return 0;
}
+static INT_PTR svcQMgr(WPARAM, LPARAM)
+{
+ SendLater::invokeQueueMgrDlg();
+ return 0;
+}
+
/////////////////////////////////////////////////////////////////////////////////////////
// initialises the internal API, services, events etc...
@@ -664,7 +670,7 @@ static void TSAPI InitAPI()
CreateServiceFunction("TabSRMsg/ReloadSettings", ReloadSettings);
CreateServiceFunction(MS_TABMSG_SETUSERPREFS, SetUserPrefs);
- CreateServiceFunction(MS_TABMSG_SLQMGR, CSendLater::svcQMgr);
+ CreateServiceFunction(MS_TABMSG_SLQMGR, svcQMgr);
SI_InitStatusIcons();
}
@@ -685,7 +691,6 @@ int LoadSendRecvMessageModule(void)
PluginConfig.hUserPrefsWindowList = WindowList_Create();
sendQueue = new SendQueue;
Skin = new CSkin;
- sendLater = new CSendLater;
HookEvent(ME_OPT_INITIALISE, OptInitialise);
diff --git a/plugins/TabSRMM/src/sendlater.cpp b/plugins/TabSRMM/src/sendlater.cpp
index b91fa27ee5..3d7af976c5 100644
--- a/plugins/TabSRMM/src/sendlater.cpp
+++ b/plugins/TabSRMM/src/sendlater.cpp
@@ -28,128 +28,219 @@
#include "stdafx.h"
-CSendLater *sendLater = nullptr;
+/////////////////////////////////////////////////////////////////////////////////////////
+// CSendLaterJob class implementation
-// implementation of the CSendLaterJob class
-CSendLaterJob::CSendLaterJob()
+struct CSendLaterJob : public MZeroedObject
{
- memset(this, 0, sizeof(CSendLaterJob));
- fSuccess = false;
-}
+ // job status/error codes
+ enum {
+ INVALID_CONTACT = 'I',
+ JOB_DEFERRED = 'D',
+ JOB_AGE = 'O',
+ JOB_MYSTATUS = 'M',
+ JOB_STATUS = 'S',
+ JOB_WAITACK = 'A',
+ JOB_REMOVABLE = 'R',
+ JOB_HOLD = 'H',
+ };
+
+ // internal flags
+ enum {
+ SLF_SUSPEND = 1,
+ SLF_INVALID = 2
+ };
+
+ char szId[20]; // database key name (time stamp of original send)
+ MCONTACT hContact; // original contact where the message has been assigned
+ MCONTACT hTargetContact; // *real* contact (can be different for metacontacts, e.g).
+ HANDLE hProcess; // returned from the protocols sending service. needed to find it in the ACK handler
+ time_t created; // job was created at this time (important to kill jobs, that are too old)
+ time_t lastSent; // time at which the delivery was initiated. used to handle timeouts
+ char *sendBuffer; // utf-8 send buffer
+ PBYTE pBuf; // conventional send buffer (for non-utf8 protocols)
+ DWORD dwFlags;
+ int iSendCount; // # of times we tried to send it...
+ bool fSuccess, fFailed;
+ BYTE bCode; // error/progress code (for the UI)
+
+ // returns true if this job is persistent (saved to the database).
+ // such a job will survive a restart of Miranda
+ __inline bool isPersistentJob() const {
+ return(szId[0] == 'S' ? true : false);
+ }
-// return true if this job is persistent (saved to the database).
-// such a job will survive a restart of Miranda
-bool CSendLaterJob::isPersistentJob()
-{
- return(szId[0] == 'S' ? true : false);
-}
+ // try to send an open job from the job list
+ // this is ONLY called from the WM_TIMER handler and should never be executed directly.
-// check conditions for deletion
-bool CSendLaterJob::mustDelete()
-{
- if (fSuccess)
- return true;
+ int sendIt()
+ {
+ time_t now = time(0);
+ if (bCode == JOB_HOLD || bCode == JOB_DEFERRED || fSuccess || fFailed || lastSent > now)
+ return 0; // this one is frozen or done (will be removed soon), don't process it now.
- if (fFailed && bCode == JOB_REMOVABLE)
- return true;
+ if (now - created > SENDLATER_AGE_THRESHOLD) { // too old, this will be discarded and user informed by popup
+ fFailed = true;
+ bCode = JOB_AGE;
+ return 0;
+ }
- return false;
-}
+ // mark job as deferred (5 unsuccessful sends). Job will not be removed, but
+ // the user must manually reset it in order to trigger a new send attempt.
+ if (iSendCount == 5) {
+ bCode = JOB_DEFERRED;
+ return 0;
+ }
-// clean database entries for a persistent job (currently: manual send later jobs)
-void CSendLaterJob::cleanDB()
-{
- if (isPersistentJob()) {
- char szKey[100];
-
- db_unset(hContact, "SendLater", szId);
- int iCount = db_get_dw(hContact, "SendLater", "count", 0);
- if (iCount)
- iCount--;
- db_set_dw(hContact, "SendLater", "count", iCount);
-
- // delete flags
- mir_snprintf(szKey, "$%s", szId);
- db_unset(hContact, "SendLater", szKey);
+ if (iSendCount > 0 && (now - lastSent < SENDLATER_RESEND_THRESHOLD))
+ return 0; // this one was sent, but probably failed. Resend it after a while
+
+ CContactCache *c = CContactCache::getContactCache(hContact);
+ if (!c->isValid()) {
+ fFailed = true;
+ bCode = INVALID_CONTACT;
+ return 0; // can happen (contact has been deleted). mark the job as failed
+ }
+
+ MCONTACT cc = c->getActiveContact();
+ const char *szProto = c->getActiveProto();
+ if (!cc || szProto == nullptr)
+ return 0;
+
+ int wMyStatus = Proto_GetStatus(szProto);
+
+ // status mode checks
+ if (wMyStatus == ID_STATUS_OFFLINE) {
+ bCode = JOB_MYSTATUS;
+ return 0;
+ }
+ if (szId[0] == 'S') {
+ if (wMyStatus != ID_STATUS_ONLINE || wMyStatus != ID_STATUS_FREECHAT) {
+ bCode = JOB_MYSTATUS;
+ return 0;
+ }
+ }
+
+ lastSent = now;
+ iSendCount++;
+ hTargetContact = cc;
+ bCode = JOB_WAITACK;
+ hProcess = (HANDLE)ProtoChainSend(cc, PSS_MESSAGE, 0, (LPARAM)sendBuffer);
+ return 0;
}
-}
-// read flags for a persistent jobs from the db
-// flag key name is the job id with a "$" prefix.
-void CSendLaterJob::readFlags()
-{
- if (isPersistentJob()) {
- char szKey[100];
- DWORD localFlags;
+ // reads flags for a persistent jobs from the db
+ // flag key name is the job id with a "$" prefix.
+ void readFlags()
+ {
+ if (isPersistentJob()) {
+ char szKey[100];
+ DWORD localFlags;
- mir_snprintf(szKey, "$%s", szId);
- localFlags = db_get_dw(hContact, "SendLater", szKey, 0);
+ mir_snprintf(szKey, "$%s", szId);
+ localFlags = db_get_dw(hContact, "SendLater", szKey, 0);
- if (localFlags & SLF_SUSPEND)
- bCode = JOB_HOLD;
+ if (localFlags & SLF_SUSPEND)
+ bCode = JOB_HOLD;
+ }
}
-}
-// write flags for a persistent jobs from the db
-// flag key name is the job id with a "$" prefix.
-void CSendLaterJob::writeFlags()
-{
- if (isPersistentJob()) {
- DWORD localFlags = (bCode == JOB_HOLD ? SLF_SUSPEND : 0);
- char szKey[100];
+ // writes flags for a persistent jobs from the db
+ // flag key name is the job id with a "$" prefix.
+ void writeFlags()
+ {
+ if (isPersistentJob()) {
+ DWORD localFlags = (bCode == JOB_HOLD ? SLF_SUSPEND : 0);
+ char szKey[100];
- mir_snprintf(szKey, "$%s", szId);
- db_set_dw(hContact, "SendLater", szKey, localFlags);
+ mir_snprintf(szKey, "$%s", szId);
+ db_set_dw(hContact, "SendLater", szKey, localFlags);
+ }
}
-}
-// delete a send later job
-CSendLaterJob::~CSendLaterJob()
-{
- if (fSuccess || fFailed) {
- if ((sendLater->haveErrorPopups() && fFailed) || (sendLater->haveSuccessPopups() && fSuccess)) {
- bool fShowPopup = true;
-
- if (fFailed && bCode == JOB_REMOVABLE) // no popups for jobs removed on user's request
- fShowPopup = false;
- /*
- * show a popup notification, unless they are disabled
- */
- if (fShowPopup) {
- wchar_t *tszName = Clist_GetContactDisplayName(hContact);
-
- POPUPDATAW ppd;
- ppd.lchContact = hContact;
- wcsncpy_s(ppd.lpwzContactName, (tszName ? tszName : TranslateT("'(Unknown contact)'")), _TRUNCATE);
- wchar_t *msgPreview = Utils::GetPreviewWithEllipsis(reinterpret_cast<wchar_t *>(&pBuf[mir_strlen((char *)pBuf) + 1]), 100);
- if (fSuccess) {
- mir_snwprintf(ppd.lpwzText, TranslateT("A send later job completed successfully.\nThe original message: %s"),
- msgPreview);
- mir_free(msgPreview);
- }
- else if (fFailed) {
- mir_snwprintf(ppd.lpwzText, TranslateT("A send later job failed to complete.\nThe original message: %s"),
- msgPreview);
- mir_free(msgPreview);
- }
+ // cleans database entries for a persistent job (currently: manual send later jobs)
+ void cleanDB()
+ {
+ if (isPersistentJob()) {
+ char szKey[100];
+
+ db_unset(hContact, "SendLater", szId);
+ int iCount = db_get_dw(hContact, "SendLater", "count", 0);
+ if (iCount)
+ iCount--;
+ db_set_dw(hContact, "SendLater", "count", iCount);
+
+ // delete flags
+ mir_snprintf(szKey, "$%s", szId);
+ db_unset(hContact, "SendLater", szKey);
+ }
+ }
+
+ // checks conditions for deletion
+ bool mustDelete()
+ {
+ if (fSuccess)
+ return true;
+
+ if (fFailed && bCode == JOB_REMOVABLE)
+ return true;
+
+ return false;
+ }
+
+ ~CSendLaterJob()
+ {
+ if (fSuccess || fFailed) {
+ if ((SendLater::ErrorPopups && fFailed) || (SendLater::SuccessPopups && fSuccess)) {
+ bool fShowPopup = true;
+
+ if (fFailed && bCode == JOB_REMOVABLE) // no popups for jobs removed on user's request
+ fShowPopup = false;
/*
- * use message settings (timeout/colors) for success popups
- */
- ppd.colorText = fFailed ? RGB(255, 245, 225) : nen_options.colTextMsg;
- ppd.colorBack = fFailed ? RGB(191, 0, 0) : nen_options.colBackMsg;
- ppd.PluginWindowProc = Utils::PopupDlgProcError;
- ppd.lchIcon = fFailed ? PluginConfig.g_iconErr : PluginConfig.g_IconMsgEvent;
- ppd.PluginData = nullptr;
- ppd.iSeconds = fFailed ? -1 : nen_options.iDelayMsg;
- PUAddPopupW(&ppd);
+ * show a popup notification, unless they are disabled
+ */
+ if (fShowPopup) {
+ wchar_t *tszName = Clist_GetContactDisplayName(hContact);
+
+ POPUPDATAW ppd;
+ ppd.lchContact = hContact;
+ wcsncpy_s(ppd.lpwzContactName, (tszName ? tszName : TranslateT("'(Unknown contact)'")), _TRUNCATE);
+ ptrW msgPreview(Utils::GetPreviewWithEllipsis(reinterpret_cast<wchar_t *>(&pBuf[mir_strlen((char *)pBuf) + 1]), 100));
+ if (fSuccess)
+ mir_snwprintf(ppd.lpwzText, TranslateT("A send later job completed successfully.\nThe original message: %s"), msgPreview);
+ else if (fFailed)
+ mir_snwprintf(ppd.lpwzText, TranslateT("A send later job failed to complete.\nThe original message: %s"), msgPreview);
+
+ /*
+ * use message settings (timeout/colors) for success popups
+ */
+ ppd.colorText = fFailed ? RGB(255, 245, 225) : nen_options.colTextMsg;
+ ppd.colorBack = fFailed ? RGB(191, 0, 0) : nen_options.colBackMsg;
+ ppd.PluginWindowProc = Utils::PopupDlgProcError;
+ ppd.lchIcon = fFailed ? PluginConfig.g_iconErr : PluginConfig.g_IconMsgEvent;
+ ppd.PluginData = nullptr;
+ ppd.iSeconds = fFailed ? -1 : nen_options.iDelayMsg;
+ PUAddPopupW(&ppd);
+ }
}
+ if (fFailed && (bCode == JOB_AGE || bCode == JOB_REMOVABLE) && szId[0] == 'S')
+ cleanDB();
}
- if (fFailed && (bCode == JOB_AGE || bCode == JOB_REMOVABLE) && szId[0] == 'S')
- cleanDB();
+
mir_free(sendBuffer);
mir_free(pBuf);
}
-}
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Module data
+
+LIST<void> g_sendLaterContactList(5, PtrKeySortT);
+LIST<CSendLaterJob> g_sendLaterJobList(5);
+
+bool g_bIsInteractive = false;
+time_t g_last_sendlater_processed = time(0);
+int g_currJob = -1;
/////////////////////////////////////////////////////////////////////////////////////////
// Send Later dialog
@@ -163,9 +254,6 @@ static class CSendLaterDlg *pDialog;
class CSendLaterDlg : public CDlgBase
{
- friend class CSendLater;
-
- CSendLater *m_later;
MCONTACT m_hFilter = 0; // contact handle to filter the qmgr list (0 = no filter, show all)
int m_sel = -1; // index of the combo box entry corresponding to the contact filter;
@@ -180,105 +268,6 @@ class CSendLaterDlg : public CDlgBase
return m_sel;
}
- // fills the list of jobs with current contents of the job queue
- // filters by m_hFilter (contact handle)
- void FillList()
- {
- wchar_t *formatTime = L"%Y.%m.%d - %H:%M";
-
- m_sel = 0;
- m_filter.InsertString(TranslateT("<All contacts>"), -1, 0);
-
- LVITEM lvItem = { 0 };
-
- BYTE bCode = '-';
- unsigned uIndex = 0;
- for (auto &p : m_later->m_sendLaterJobList) {
- CContactCache *c = CContactCache::getContactCache(p->hContact);
-
- const wchar_t *tszNick = c->getNick();
- if (m_hFilter && m_hFilter != p->hContact) {
- AddFilter(c->getContact(), tszNick);
- continue;
- }
-
- lvItem.mask = LVIF_TEXT | LVIF_PARAM;
- wchar_t tszBuf[255];
- mir_snwprintf(tszBuf, L"%s [%s]", tszNick, c->getRealAccount());
- lvItem.pszText = tszBuf;
- lvItem.cchTextMax = _countof(tszBuf);
- lvItem.iItem = uIndex++;
- lvItem.iSubItem = 0;
- lvItem.lParam = LPARAM(p);
- m_list.InsertItem(&lvItem);
- AddFilter(c->getContact(), tszNick);
-
- lvItem.mask = LVIF_TEXT;
- wchar_t tszTimestamp[30];
- wcsftime(tszTimestamp, 30, formatTime, _localtime32((__time32_t *)&p->created));
- tszTimestamp[29] = 0;
- lvItem.pszText = tszTimestamp;
- lvItem.iSubItem = 1;
- m_list.SetItem(&lvItem);
-
- wchar_t *msg = mir_utf8decodeW(p->sendBuffer);
- wchar_t *preview = Utils::GetPreviewWithEllipsis(msg, 255);
- lvItem.pszText = preview;
- lvItem.iSubItem = 2;
- m_list.SetItem(&lvItem);
- mir_free(preview);
- mir_free(msg);
-
- const wchar_t *tszStatusText = nullptr;
- if (p->fFailed) {
- tszStatusText = p->bCode == CSendLaterJob::JOB_REMOVABLE ?
- TranslateT("Removed") : TranslateT("Failed");
- }
- else if (p->fSuccess)
- tszStatusText = TranslateT("Sent OK");
- else {
- switch (p->bCode) {
- case CSendLaterJob::JOB_DEFERRED:
- tszStatusText = TranslateT("Deferred");
- break;
- case CSendLaterJob::JOB_AGE:
- tszStatusText = TranslateT("Failed");
- break;
- case CSendLaterJob::JOB_HOLD:
- tszStatusText = TranslateT("Suspended");
- break;
- default:
- tszStatusText = TranslateT("Pending");
- break;
- }
- }
- if (p->bCode)
- bCode = p->bCode;
-
- wchar_t tszStatus[20];
- mir_snwprintf(tszStatus, L"X/%s[%c] (%d)", tszStatusText, bCode, p->iSendCount);
- tszStatus[0] = p->szId[0];
- lvItem.pszText = tszStatus;
- lvItem.iSubItem = 3;
- m_list.SetItem(&lvItem);
-
- if (p->lastSent == 0)
- wcsncpy_s(tszTimestamp, L"Never", _TRUNCATE);
- else {
- wcsftime(tszTimestamp, 30, formatTime, _localtime32((__time32_t *)&p->lastSent));
- tszTimestamp[29] = 0;
- }
- lvItem.pszText = tszTimestamp;
- lvItem.iSubItem = 4;
- m_list.SetItem(&lvItem);
- }
-
- if (m_hFilter == 0)
- m_filter.SetCurSel(0);
- else
- m_filter.SetCurSel(m_sel);
- }
-
// set the column headers
void SetupColumns()
{
@@ -314,14 +303,15 @@ class CSendLaterDlg : public CDlgBase
}
CCtrlCheck chkSuccess, chkError;
+ CCtrlHyperlink m_link;
CCtrlCombo m_filter;
+
+public:
CCtrlListView m_list;
- CCtrlHyperlink m_link;
public:
- CSendLaterDlg(CSendLater *pLater) :
+ CSendLaterDlg() :
CDlgBase(g_plugin, IDD_SENDLATER_QMGR),
- m_later(pLater),
m_list(this, IDC_QMGR_LIST),
m_link(this, IDC_QMGR_HELP, "https://wiki.miranda-ng.org/index.php?title=Plugin:TabSRMM/en/Send_later"),
m_filter(this, IDC_QMGR_FILTER),
@@ -346,8 +336,8 @@ public:
SetupColumns();
FillList();
- chkSuccess.SetState(m_later->m_fSuccessPopups);
- chkError.SetState(m_later->m_fErrorPopups);
+ chkSuccess.SetState(SendLater::SuccessPopups);
+ chkError.SetState(SendLater::ErrorPopups);
Show();
return true;
}
@@ -390,10 +380,10 @@ public:
if (m_list.GetSelectedCount() == 1)
::EnableMenuItem(hSubMenu, ID_QUEUEMANAGER_COPYMESSAGETOCLIPBOARD, MF_ENABLED);
- m_later->m_fIsInteractive = true;
+ g_bIsInteractive = true;
int selection = ::TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, m_hwnd, nullptr);
if (selection == ID_QUEUEMANAGER_CANCELALLMULTISENDJOBS) {
- for (auto &p : m_later->m_sendLaterJobList) {
+ for (auto &p : g_sendLaterJobList) {
if (p->szId[0] == 'M') {
p->fFailed = true;
p->bCode = CSendLaterJob::JOB_REMOVABLE;
@@ -402,21 +392,19 @@ public:
}
else if (selection != 0) {
HandleMenuClick(selection);
- m_later->m_last_sendlater_processed = 0; // force a queue check
+ g_last_sendlater_processed = 0; // force a queue check
}
- m_later->m_fIsInteractive = false;
+ g_bIsInteractive = false;
}
void onChange_Success(CCtrlCheck *)
{
- m_later->m_fSuccessPopups = chkSuccess.GetState();
- db_set_b(0, SRMSGMOD_T, "qmgrSuccessPopups", m_later->m_fSuccessPopups);
+ SendLater::SuccessPopups = chkSuccess.GetState();
}
void onChange_Error(CCtrlCheck *)
{
- m_later->m_fErrorPopups = chkError.GetState();
- db_set_b(0, SRMSGMOD_T, "qmgrErrorPopups", m_later->m_fErrorPopups);
+ SendLater::ErrorPopups = chkError.GetState();
}
// this handles all commands sent by the context menu
@@ -477,30 +465,135 @@ public:
}
FillList();
}
+
+ // fills the list of jobs with current contents of the job queue
+ // filters by m_hFilter (contact handle)
+ void FillList()
+ {
+ wchar_t *formatTime = L"%Y.%m.%d - %H:%M";
+
+ m_sel = 0;
+ m_filter.InsertString(TranslateT("<All contacts>"), -1, 0);
+
+ LVITEM lvItem = { 0 };
+
+ BYTE bCode = '-';
+ unsigned uIndex = 0;
+ for (auto &p : g_sendLaterJobList) {
+ CContactCache *c = CContactCache::getContactCache(p->hContact);
+
+ const wchar_t *tszNick = c->getNick();
+ if (m_hFilter && m_hFilter != p->hContact) {
+ AddFilter(c->getContact(), tszNick);
+ continue;
+ }
+
+ lvItem.mask = LVIF_TEXT | LVIF_PARAM;
+ wchar_t tszBuf[255];
+ mir_snwprintf(tszBuf, L"%s [%s]", tszNick, c->getRealAccount());
+ lvItem.pszText = tszBuf;
+ lvItem.cchTextMax = _countof(tszBuf);
+ lvItem.iItem = uIndex++;
+ lvItem.iSubItem = 0;
+ lvItem.lParam = LPARAM(p);
+ m_list.InsertItem(&lvItem);
+ AddFilter(c->getContact(), tszNick);
+
+ lvItem.mask = LVIF_TEXT;
+ wchar_t tszTimestamp[30];
+ wcsftime(tszTimestamp, 30, formatTime, _localtime32((__time32_t *)&p->created));
+ tszTimestamp[29] = 0;
+ lvItem.pszText = tszTimestamp;
+ lvItem.iSubItem = 1;
+ m_list.SetItem(&lvItem);
+
+ wchar_t *msg = mir_utf8decodeW(p->sendBuffer);
+ wchar_t *preview = Utils::GetPreviewWithEllipsis(msg, 255);
+ lvItem.pszText = preview;
+ lvItem.iSubItem = 2;
+ m_list.SetItem(&lvItem);
+ mir_free(preview);
+ mir_free(msg);
+
+ const wchar_t *tszStatusText = nullptr;
+ if (p->fFailed) {
+ tszStatusText = p->bCode == CSendLaterJob::JOB_REMOVABLE ?
+ TranslateT("Removed") : TranslateT("Failed");
+ }
+ else if (p->fSuccess)
+ tszStatusText = TranslateT("Sent OK");
+ else {
+ switch (p->bCode) {
+ case CSendLaterJob::JOB_DEFERRED:
+ tszStatusText = TranslateT("Deferred");
+ break;
+ case CSendLaterJob::JOB_AGE:
+ tszStatusText = TranslateT("Failed");
+ break;
+ case CSendLaterJob::JOB_HOLD:
+ tszStatusText = TranslateT("Suspended");
+ break;
+ default:
+ tszStatusText = TranslateT("Pending");
+ break;
+ }
+ }
+ if (p->bCode)
+ bCode = p->bCode;
+
+ wchar_t tszStatus[20];
+ mir_snwprintf(tszStatus, L"X/%s[%c] (%d)", tszStatusText, bCode, p->iSendCount);
+ tszStatus[0] = p->szId[0];
+ lvItem.pszText = tszStatus;
+ lvItem.iSubItem = 3;
+ m_list.SetItem(&lvItem);
+
+ if (p->lastSent == 0)
+ wcsncpy_s(tszTimestamp, L"Never", _TRUNCATE);
+ else {
+ wcsftime(tszTimestamp, 30, formatTime, _localtime32((__time32_t *)&p->lastSent));
+ tszTimestamp[29] = 0;
+ }
+ lvItem.pszText = tszTimestamp;
+ lvItem.iSubItem = 4;
+ m_list.SetItem(&lvItem);
+ }
+
+ if (m_hFilter == 0)
+ m_filter.SetCurSel(0);
+ else
+ m_filter.SetCurSel(m_sel);
+ }
};
-CSendLater::CSendLater() :
- m_sendLaterContactList(5, PtrKeySortT),
- m_sendLaterJobList(5),
- m_fAvail(SRMSGMOD_T, "sendLaterAvail", false),
- m_fErrorPopups(SRMSGMOD_T, "qmgrErrorPopups", false),
- m_fSuccessPopups(SRMSGMOD_T, "qmgrSuccessPopups", false)
-{
- m_last_sendlater_processed = time(0);
-}
+/////////////////////////////////////////////////////////////////////////////////////////
+// SendLater class
+
+CMOption<bool> SendLater::Avail(SRMSGMOD_T, "sendLaterAvail", false);
+CMOption<bool> SendLater::ErrorPopups(SRMSGMOD_T, "qmgrErrorPopups", false);
+CMOption<bool> SendLater::SuccessPopups(SRMSGMOD_T, "qmgrSuccessPopups", false);
+bool SendLater::isInteractive() { return g_bIsInteractive; }
+bool SendLater::isJobListEmpty() { return g_sendLaterJobList.getCount() == 0; }
+time_t SendLater::lastProcessed() { return g_last_sendlater_processed; }
+void SendLater::setLastProcessed(const time_t _t) { g_last_sendlater_processed = _t; }
+void SendLater::flushQueue() { g_last_sendlater_processed = 0; }
+bool SendLater::haveJobs() { return (g_sendLaterJobList.getCount() != 0 && g_currJob != -1); }
+
+/////////////////////////////////////////////////////////////////////////////////////////
// clear all open send jobs. Only called on system shutdown to remove
// the jobs from memory. Must _NOT_ delete any sendlater related stuff from
// the database (only successful sends may do this).
-CSendLater::~CSendLater()
+
+void SendLater::shutDown()
{
if (pDialog)
pDialog->Close();
- if (m_sendLaterJobList.getCount() == 0)
+ if (g_sendLaterJobList.getCount() == 0)
return;
- for (auto &p : m_sendLaterJobList) {
+ for (auto &p : g_sendLaterJobList) {
mir_free(p->sendBuffer);
mir_free(p->pBuf);
p->fSuccess = false; // avoid clearing jobs from the database
@@ -508,14 +601,15 @@ CSendLater::~CSendLater()
}
}
-void CSendLater::startJobListProcess()
+void SendLater::startJobListProcess()
{
- m_currJob = 0;
+ g_currJob = 0;
if (pDialog)
pDialog->m_list.Disable();
}
+/////////////////////////////////////////////////////////////////////////////////////////
// checks if the current job in the timer-based process queue is subject
// for deletion (that is, it has failed or succeeded)
//
@@ -525,65 +619,62 @@ void CSendLater::startJobListProcess()
// hotkeyhandler.cpp.
//
// returns true if more jobs are awaiting processing, false otherwise.
-bool CSendLater::processCurrentJob()
+
+bool SendLater::processCurrentJob()
{
- if (!m_sendLaterJobList.getCount() || m_currJob == -1)
+ if (!g_sendLaterJobList.getCount() || g_currJob == -1)
return false;
- if (m_currJob >= m_sendLaterJobList.getCount()) {
- m_currJob = -1;
+ if (g_currJob >= g_sendLaterJobList.getCount()) {
+ g_currJob = -1;
return false;
}
- CSendLaterJob *p = m_sendLaterJobList[m_currJob];
+ CSendLaterJob *p = g_sendLaterJobList[g_currJob];
if (p->fSuccess || p->fFailed) {
if (p->mustDelete()) {
- m_sendLaterJobList.remove(m_currJob);
+ g_sendLaterJobList.remove(g_currJob);
delete p;
}
- else m_currJob++;
+ else g_currJob++;
}
- else sendIt(m_sendLaterJobList[m_currJob++]);
+ else g_sendLaterJobList[g_currJob++]->sendIt();
- if (m_currJob >= m_sendLaterJobList.getCount()) {
- m_currJob = -1;
+ if (g_currJob >= g_sendLaterJobList.getCount()) {
+ g_currJob = -1;
return false;
}
return true;
}
-// stub used as enum proc for the database enumeration, collecting
-// all entries in the SendLater module
-// (static function)
-int _cdecl CSendLater::addStub(const char *szSetting, void *lParam)
+/////////////////////////////////////////////////////////////////////////////////////////
+// called periodically from a timer, check if new contacts were added
+// and process them
+
+static int _cdecl addStub(const char *szSetting, void *lParam)
{
- return(sendLater->addJob(szSetting, lParam));
+ return(SendLater::addJob(szSetting, lParam));
}
-// Process a single contact from the list of contacts with open send later jobs
-// enum the "SendLater" module and add all jobs to the list of open jobs.
-// addJob() will deal with possible duplicates
-// @param hContact HANDLE: contact's handle
-void CSendLater::processSingleContact(const MCONTACT hContact)
+static void processSingleContact(const MCONTACT hContact)
{
int iCount = db_get_dw(hContact, "SendLater", "count", 0);
if (iCount)
- db_enum_settings(hContact, CSendLater::addStub, "SendLater", (void*)hContact);
+ db_enum_settings(hContact, addStub, "SendLater", (void*)hContact);
}
-// called periodically from a timer, check if new contacts were added
-// and process them
-void CSendLater::processContacts()
+void SendLater::processContacts()
{
- if (m_fAvail) {
- for (auto &it : m_sendLaterContactList)
+ if (SendLater::Avail) {
+ for (auto &it : g_sendLaterContactList)
processSingleContact((UINT_PTR)it);
- m_sendLaterContactList.destroy();
+ g_sendLaterContactList.destroy();
}
}
+/////////////////////////////////////////////////////////////////////////////////////////
// This function adds a new job to the list of messages to send unattended
// used by the send later feature and multisend
//
@@ -593,20 +684,21 @@ void CSendLater::processContacts()
//
// @param lParam: a contact handle for which the job should be scheduled
// @return 0 on failure, 1 otherwise
-int CSendLater::addJob(const char *szSetting, void *lParam)
+
+int SendLater::addJob(const char *szSetting, void *lParam)
{
MCONTACT hContact = (UINT_PTR)lParam;
DBVARIANT dbv = { 0 };
char *szOrig_Utf = nullptr;
- if (!m_fAvail || !szSetting || !mir_strcmp(szSetting, "count") || mir_strlen(szSetting) < 8)
+ if (!SendLater::Avail || !szSetting || !mir_strcmp(szSetting, "count") || mir_strlen(szSetting) < 8)
return 0;
if (szSetting[0] != 'S' && szSetting[0] != 'M')
return 0;
// check for possible dupes
- for (auto &p : m_sendLaterJobList)
+ for (auto &p : g_sendLaterJobList)
if (p->hContact == hContact && !mir_strcmp(p->szId, szSetting))
return 0;
@@ -656,105 +748,48 @@ int CSendLater::addJob(const char *szSetting, void *lParam)
mir_free(szWchar);
job->readFlags();
- m_sendLaterJobList.insert(job);
+ g_sendLaterJobList.insert(job);
qMgrUpdate();
return 1;
}
-// Try to send an open job from the job list
-// this is ONLY called from the WM_TIMER handler and should never be executed directly.
-int CSendLater::sendIt(CSendLaterJob *job)
-{
- time_t now = time(0);
- if (job->bCode == CSendLaterJob::JOB_HOLD || job->bCode == CSendLaterJob::JOB_DEFERRED || job->fSuccess || job->fFailed || job->lastSent > now)
- return 0; // this one is frozen or done (will be removed soon), don't process it now.
-
- if (now - job->created > SENDLATER_AGE_THRESHOLD) { // too old, this will be discarded and user informed by popup
- job->fFailed = true;
- job->bCode = CSendLaterJob::JOB_AGE;
- return 0;
- }
-
- // mark job as deferred (5 unsuccessful sends). Job will not be removed, but
- // the user must manually reset it in order to trigger a new send attempt.
- if (job->iSendCount == 5) {
- job->bCode = CSendLaterJob::JOB_DEFERRED;
- return 0;
- }
-
- if (job->iSendCount > 0 && (now - job->lastSent < SENDLATER_RESEND_THRESHOLD))
- return 0; // this one was sent, but probably failed. Resend it after a while
-
- CContactCache *c = CContactCache::getContactCache(job->hContact);
- if (!c->isValid()) {
- job->fFailed = true;
- job->bCode = CSendLaterJob::INVALID_CONTACT;
- return 0; // can happen (contact has been deleted). mark the job as failed
- }
-
- MCONTACT hContact = c->getActiveContact();
- const char *szProto = c->getActiveProto();
- if (!hContact || szProto == nullptr)
- return 0;
-
- int wMyStatus = Proto_GetStatus(szProto);
-
- // status mode checks
- if (wMyStatus == ID_STATUS_OFFLINE) {
- job->bCode = CSendLaterJob::JOB_MYSTATUS;
- return 0;
- }
- if (job->szId[0] == 'S') {
- if (wMyStatus != ID_STATUS_ONLINE || wMyStatus != ID_STATUS_FREECHAT) {
- job->bCode = CSendLaterJob::JOB_MYSTATUS;
- return 0;
- }
- }
-
- job->lastSent = now;
- job->iSendCount++;
- job->hTargetContact = hContact;
- job->bCode = CSendLaterJob::JOB_WAITACK;
- job->hProcess = (HANDLE)ProtoChainSend(hContact, PSS_MESSAGE, 0, (LPARAM)job->sendBuffer);
- return 0;
-}
-
+/////////////////////////////////////////////////////////////////////////////////////////
// add a contact to the list of contacts having open send later jobs.
// This is is periodically checked for new additions (processContacts())
// and new jobs are created.
-void CSendLater::addContact(const MCONTACT hContact)
+
+void SendLater::addContact(const MCONTACT hContact)
{
- if (!m_fAvail)
+ if (!SendLater::Avail)
return;
- if (m_sendLaterContactList.getCount() == 0) {
- m_sendLaterContactList.insert((HANDLE)hContact);
- m_last_sendlater_processed = 0; // force processing at next tick
+ if (g_sendLaterContactList.getCount() == 0) {
+ g_sendLaterContactList.insert((HANDLE)hContact);
+ g_last_sendlater_processed = 0; // force processing at next tick
return;
}
- /*
- * this list should not have duplicate entries
- */
-
- if (m_sendLaterContactList.find((HANDLE)hContact))
+ // this list should not have duplicate entries
+ if (g_sendLaterContactList.find((HANDLE)hContact))
return;
- m_sendLaterContactList.insert((HANDLE)hContact);
- m_last_sendlater_processed = 0; // force processing at next tick
+ g_sendLaterContactList.insert((HANDLE)hContact);
+ g_last_sendlater_processed = 0; // force processing at next tick
}
+/////////////////////////////////////////////////////////////////////////////////////////
// process ACK messages for the send later job list. Called from the proto ack
// handler when it does not find a match in the normal send queue
//
// Add the message to the database and mark it as successful. The job will be
// removed later by the job list processing code.
-HANDLE CSendLater::processAck(const ACKDATA *ack)
+
+HANDLE SendLater::processAck(const ACKDATA *ack)
{
- if (m_sendLaterJobList.getCount() == 0 || !m_fAvail)
+ if (g_sendLaterJobList.getCount() == 0 || !SendLater::Avail)
return nullptr;
- for (auto &p : m_sendLaterJobList)
+ for (auto &p : g_sendLaterJobList)
if (p->hProcess == ack->hProcess && p->hTargetContact == ack->hContact && !(p->fSuccess || p->fFailed)) {
if (!p->fSuccess) {
DBEVENTINFO dbei = {};
@@ -778,26 +813,23 @@ HANDLE CSendLater::processAck(const ACKDATA *ack)
return nullptr;
}
+/////////////////////////////////////////////////////////////////////////////////////////
// UI stuff (dialog procedures for the queue manager dialog
-void CSendLater::qMgrUpdate(bool fReEnable)
+
+void SendLater::qMgrUpdate(bool fReEnable)
{
if (pDialog) {
if (fReEnable)
- pDialog->m_list.Enable(true);
+ pDialog->m_list.Enable();
pDialog->FillList();
}
}
+/////////////////////////////////////////////////////////////////////////////////////////
// invoke queue manager dialog - do nothing if this dialog is already open
-void CSendLater::invokeQueueMgrDlg()
-{
- if (pDialog == nullptr)
- (new CSendLaterDlg(this))->Create();
-}
-// service function to invoke the queue manager
-INT_PTR CSendLater::svcQMgr(WPARAM, LPARAM)
+void SendLater::invokeQueueMgrDlg()
{
- sendLater->invokeQueueMgrDlg();
- return 0;
+ if (pDialog == nullptr)
+ (new CSendLaterDlg())->Create();
}
diff --git a/plugins/TabSRMM/src/sendlater.h b/plugins/TabSRMM/src/sendlater.h
index 18e3d318f8..72d87cbd9b 100644
--- a/plugins/TabSRMM/src/sendlater.h
+++ b/plugins/TabSRMM/src/sendlater.h
@@ -35,87 +35,22 @@
#define TIMEOUT_SENDLATER 10000
#define TIMEOUT_SENDLATER_TICK 200
-struct CSendLaterJob
-{
- // job status/error codes
- enum {
- INVALID_CONTACT = 'I',
- JOB_DEFERRED = 'D',
- JOB_AGE = 'O',
- JOB_MYSTATUS = 'M',
- JOB_STATUS = 'S',
- JOB_WAITACK = 'A',
- JOB_REMOVABLE = 'R',
- JOB_HOLD = 'H',
- };
-
- // internal flags
- enum {
- SLF_SUSPEND = 1,
- SLF_INVALID = 2
- };
-
- void readFlags();
- void writeFlags();
- void cleanDB();
- bool isPersistentJob();
- bool mustDelete();
-
- CSendLaterJob();
- ~CSendLaterJob();
-
- char szId[20]; // database key name (time stamp of original send)
- MCONTACT hContact; // original contact where the message has been assigned
- MCONTACT hTargetContact; // *real* contact (can be different for metacontacts, e.g).
- HANDLE hProcess; // returned from the protocols sending service. needed to find it in the ACK handler
- time_t created; // job was created at this time (important to kill jobs, that are too old)
- time_t lastSent; // time at which the delivery was initiated. used to handle timeouts
- char *sendBuffer; // utf-8 send buffer
- PBYTE pBuf; // conventional send buffer (for non-utf8 protocols)
- DWORD dwFlags;
- int iSendCount; // # of times we tried to send it...
- bool fSuccess, fFailed;
- BYTE bCode; // error/progress code (for the UI)
+enum {
+ SENDLATER_AGE_THRESHOLD = (86400 * 3), // 3 days, older messages will be removed from the db.
+ SENDLATER_RESEND_THRESHOLD = 180, // timeouted messages should be resent after that many seconds
+ SENDLATER_PROCESS_INTERVAL = 50 // process the list of waiting job every this many seconds
};
-class CSendLater
+namespace SendLater
{
- friend class CSendLaterDlg;
-
- void processSingleContact(const MCONTACT hContact);
- int sendIt(CSendLaterJob *job);
-
- LIST<void> m_sendLaterContactList;
- LIST<CSendLaterJob> m_sendLaterJobList;
+ void shutDown();
- CMOption<bool> m_fAvail, m_fErrorPopups, m_fSuccessPopups;
-
- bool m_fIsInteractive = false;
- time_t m_last_sendlater_processed;
- int m_currJob = -1;
-
-public:
- enum {
- SENDLATER_AGE_THRESHOLD = (86400 * 3), // 3 days, older messages will be removed from the db.
- SENDLATER_RESEND_THRESHOLD = 180, // timeouted messages should be resent after that many seconds
- SENDLATER_PROCESS_INTERVAL = 50 // process the list of waiting job every this many seconds
- };
-
- CSendLater();
- ~CSendLater();
-
- __inline bool isAvail() { return m_fAvail; }
- __inline bool haveErrorPopups() { return m_fErrorPopups; }
- __inline bool haveSuccessPopups() { return m_fSuccessPopups; }
-
- __inline bool isInteractive() const { return m_fIsInteractive; }
- __inline bool isJobListEmpty() const { return m_sendLaterJobList.getCount() == 0; }
- __inline time_t lastProcessed() const { return m_last_sendlater_processed; }
- __inline void setLastProcessed(const time_t _t) { m_last_sendlater_processed = _t; }
- __inline void flushQueue() { m_last_sendlater_processed = 0; }
- __inline bool haveJobs() const { return (m_sendLaterJobList.getCount() != 0 && m_currJob != -1); }
-
- static int _cdecl addStub(const char *szSetting, void *lParam);
+ bool isInteractive();
+ bool isJobListEmpty();
+ time_t lastProcessed();
+ void setLastProcessed(const time_t _t);
+ void flushQueue();
+ bool haveJobs();
bool processCurrentJob();
void processContacts();
@@ -126,9 +61,8 @@ public:
void invokeQueueMgrDlg();
void qMgrUpdate(bool fReEnable = false);
- static INT_PTR svcQMgr(WPARAM wParam, LPARAM lParam);
-};
-extern CSendLater *sendLater;
+ extern CMOption<bool> Avail, ErrorPopups, SuccessPopups;
+};
#endif /* __SENDLATER_H */
diff --git a/plugins/TabSRMM/src/sendqueue.cpp b/plugins/TabSRMM/src/sendqueue.cpp
index bf444489fd..51a0904844 100644
--- a/plugins/TabSRMM/src/sendqueue.cpp
+++ b/plugins/TabSRMM/src/sendqueue.cpp
@@ -231,7 +231,7 @@ int SendQueue::sendQueued(CMsgDialog *dat, const int iEntry)
sendQueue->clearJob(iEntry);
if (iJobs)
- sendLater->flushQueue(); // force queue processing
+ SendLater::flushQueue(); // force queue processing
return 0;
}
@@ -535,12 +535,10 @@ LRESULT SendQueue::WarnPendingJobs(unsigned int)
int SendQueue::doSendLater(int iJobIndex, CMsgDialog *dat, MCONTACT hContact, bool fIsSendLater)
{
- bool fAvail = sendLater->isAvail();
-
const wchar_t *szNote = nullptr;
if (fIsSendLater && dat) {
- if (fAvail)
+ if (SendLater::Avail)
szNote = TranslateT("Message successfully queued for later delivery.\nIt will be sent as soon as possible and a popup will inform you about the result.");
else
szNote = TranslateT("The send later feature is not available on this protocol.");
@@ -565,7 +563,7 @@ int SendQueue::doSendLater(int iJobIndex, CMsgDialog *dat, MCONTACT hContact, bo
SendDlgItemMessage(dat->GetHwnd(), IDC_CLOSE, BUTTONADDTOOLTIP, (WPARAM)TranslateT("Close session"), BATF_UNICODE);
dat->m_bSaveBtn = false;
- if (!fAvail)
+ if (!SendLater::Avail)
return 0;
}
@@ -595,7 +593,7 @@ int SendQueue::doSendLater(int iJobIndex, CMsgDialog *dat, MCONTACT hContact, bo
}
else {
mir_snprintf(tszMsg, required, "%s%s", utf_header.get(), job->szSendBuffer);
- sendLater->addJob(tszMsg, (void*)hContact);
+ SendLater::addJob(tszMsg, (void*)hContact);
}
mir_free(tszMsg);
@@ -603,7 +601,7 @@ int SendQueue::doSendLater(int iJobIndex, CMsgDialog *dat, MCONTACT hContact, bo
int iCount = db_get_dw(hContact ? hContact : job->hContact, "SendLater", "count", 0);
iCount++;
db_set_dw(hContact ? hContact : job->hContact, "SendLater", "count", iCount);
- sendLater->addContact(hContact ? hContact : job->hContact);
+ SendLater::addContact(hContact ? hContact : job->hContact);
}
return iJobIndex;
}
diff --git a/plugins/TabSRMM/src/srmm.cpp b/plugins/TabSRMM/src/srmm.cpp
index ea15645329..f2e8da9603 100644
--- a/plugins/TabSRMM/src/srmm.cpp
+++ b/plugins/TabSRMM/src/srmm.cpp
@@ -88,8 +88,8 @@ int CMPlugin::Unload()
Skin->setupTabCloseBitmap(true);
Skin->UnloadAeroTabs();
CleanTempFiles();
+ SendLater::shutDown();
delete Skin;
- delete sendLater;
delete sendQueue;
return iRet;
}