summaryrefslogtreecommitdiff
path: root/plugins/tabsrmm/src/sendlater.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/tabsrmm/src/sendlater.cpp')
-rw-r--r--plugins/tabsrmm/src/sendlater.cpp989
1 files changed, 0 insertions, 989 deletions
diff --git a/plugins/tabsrmm/src/sendlater.cpp b/plugins/tabsrmm/src/sendlater.cpp
deleted file mode 100644
index 2cbf0b7237..0000000000
--- a/plugins/tabsrmm/src/sendlater.cpp
+++ /dev/null
@@ -1,989 +0,0 @@
-/*
- * astyle --force-indent=tab=4 --brackets=linux --indent-switches
- * --pad=oper --one-line=keep-blocks --unpad=paren
- *
- * Miranda IM: the free IM client for Microsoft* Windows*
- *
- * Copyright 2000-2009 Miranda ICQ/IM project,
- * all portions of this codebase are copyrighted to the people
- * listed in contributors.txt.
- *
- * 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.
- *
- * part of tabSRMM messaging plugin for Miranda.
- *
- * (C) 2005-2010 by silvercircle _at_ gmail _dot_ com and contributors
- *
- * $Id: sendlater.cpp 14225 2012-05-08 19:49:18Z george.hazan $
- *
- * the sendlater class implementation
- */
-
-#include "commonheaders.h"
-#pragma hdrstop
-
-#define U_PREF_UNICODE PREF_UNICODE
-/*
- * implementation of the CSendLaterJob class
- */
-
-CSendLaterJob::CSendLaterJob()
-{
- ZeroMemory(this, sizeof(CSendLaterJob));
- fSuccess = 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);
-}
-
-/**
- * check conditions for deletion
- */
-bool CSendLaterJob::mustDelete()
-{
- if(fSuccess)
- return(true);
- else if(fFailed) {
- if(bCode == JOB_REMOVABLE)
- return(true);
- }
- return(false);
-}
-
-/**
- * clean database entries for a persistent job (currently: manual send later jobs)
- */
-void CSendLaterJob::cleanDB()
-{
- if(isPersistentJob()) {
- char szKey[100];
-
- DBDeleteContactSetting(hContact, "SendLater", szId);
- int iCount = M->GetDword(hContact, "SendLater", "count", 0);
- if(iCount)
- iCount--;
- M->WriteDword(hContact, "SendLater", "count", iCount);
- /*
- * delete flags
- */
- mir_snprintf(szKey, 100, "$%s", szId);
- DBDeleteContactSetting(hContact, "SendLater", szKey);
- }
-}
-
-/**
- * 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;
-
- mir_snprintf(szKey, 100, "$%s", szId);
- localFlags = M->GetDword(hContact, "SendLater", szKey, 0);
-
- 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];
-
- mir_snprintf(szKey, 100, "$%s", szId);
- M->WriteDword(hContact, "SendLater", szKey, localFlags);
- }
-}
-
-/**
- * delete a send later job
- */
-CSendLaterJob::~CSendLaterJob()
-{
- if(fSuccess || fFailed) {
- POPUPDATAT_V2 ppd = {0};
-
- 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 (PluginConfig.g_PopupAvail && fShowPopup) {
- TCHAR *tszName = (TCHAR *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_TCHAR);
-
- ZeroMemory((void *)&ppd, sizeof(ppd));
- ppd.lchContact = hContact;
- ppd.cbSize = sizeof(ppd);
- mir_sntprintf(ppd.lptzContactName, MAX_CONTACTNAME, _T("%s"), tszName ? tszName : CTranslator::get(CTranslator::GEN_UNKNOWN_CONTACT));
- TCHAR *msgPreview = Utils::GetPreviewWithEllipsis(reinterpret_cast<TCHAR *>(&pBuf[lstrlenA((char *)pBuf) + 1]), 100);
- if(fSuccess) {
- mir_sntprintf(ppd.lptzText, MAX_SECONDLINE, CTranslator::get(CTranslator::GEN_SQ_SENDLATER_SUCCESS_POPUP),
- msgPreview);
- mir_free(msgPreview);
- }
- else if(fFailed) {
- mir_sntprintf(ppd.lptzText, MAX_SECONDLINE, CTranslator::get(CTranslator::GEN_SQ_SENDLATER_FAILED_POPUP),
- msgPreview);
- mir_free(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 = reinterpret_cast<WNDPROC>(Utils::PopupDlgProcError);
- ppd.lchIcon = fFailed ? PluginConfig.g_iconErr : PluginConfig.g_IconMsgEvent;
- ppd.PluginData = (void *)hContact;
- ppd.iSeconds = fFailed ? -1 : nen_options.iDelayMsg;
- CallService(MS_POPUP_ADDPOPUPW, (WPARAM)&ppd, 0);
- }
- }
- if(fFailed && (bCode == JOB_AGE || bCode == JOB_REMOVABLE) && szId[0] == 'S')
- cleanDB();
- mir_free(sendBuffer);
- mir_free(pBuf);
- }
-}
-
-CSendLater::CSendLater()
-{
- m_sendLaterContactList.clear();
- m_sendLaterJobList.clear();
- m_fAvail = M->GetByte("sendLaterAvail", 0) ? true : false;
- m_last_sendlater_processed = time(0);
- m_hwndDlg = 0;
- m_fIsInteractive = false;
- m_fErrorPopups = M->GetByte(0, SRMSGMOD_T, "qmgrErrorPopups", 0) ? true : false;
- m_fSuccessPopups = M->GetByte(0, SRMSGMOD_T, "qmgrSuccessPopups", 0) ? true : false;
-}
-
-/**
- * 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()
-{
- if(m_hwndDlg)
- ::DestroyWindow(m_hwndDlg);
-
- if(m_sendLaterJobList.empty())
- return;
-
- SendLaterJobIterator it = m_sendLaterJobList.begin();
-
- while(it != m_sendLaterJobList.end()) {
- mir_free((*it)->sendBuffer);
- mir_free((*it)->pBuf);
- (*it)->fSuccess = false; // avoid clearing jobs from the database
- delete *it;
- it++;
- }
-}
-
-void CSendLater::startJobListProcess()
-{
- m_jobIterator = m_sendLaterJobList.begin();
-
- if (m_hwndDlg)
- Utils::enableDlgControl(m_hwndDlg, IDC_QMGR_LIST, false);
-}
-
-/**
- * checks if the current job in the timer-based process queue is subject
- * for deletion (that is, it has failed or succeeded)
- *
- * if not, it will send the job and increment the list iterator.
- *
- * this method is called once per tick from the timer based scheduler in
- * hotkeyhandler.cpp.
- *
- * returns true if more jobs are awaiting processing, false otherwise.
- */
-bool CSendLater::processCurrentJob()
-{
- if(m_sendLaterJobList.empty() || m_jobIterator == m_sendLaterJobList.end())
- return(false);
-
- if((*m_jobIterator)->fSuccess || (*m_jobIterator)->fFailed) {
- if((*m_jobIterator)->mustDelete()) {
- delete *m_jobIterator;
- m_jobIterator = m_sendLaterJobList.erase(m_jobIterator);
- }
- else
- m_jobIterator++;
- return(m_jobIterator == m_sendLaterJobList.end() ? false : true);
- }
- sendIt(*m_jobIterator);
- m_jobIterator++;
- return(m_jobIterator == m_sendLaterJobList.end() ? false : 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, LPARAM 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 HANDLE hContact)
-{
- int iCount = M->GetDword(hContact, "SendLater", "count", 0);
-
- if(iCount) {
- DBCONTACTENUMSETTINGS ces = {0};
-
- ces.pfnEnumProc = CSendLater::addStub;
- ces.szModule = "SendLater";
- ces.lParam = (LPARAM)hContact;
-
- CallService(MS_DB_CONTACT_ENUMSETTINGS, (WPARAM)hContact, (LPARAM)&ces);
- }
-}
-
-/**
- * called periodically from a timer, check if new contacts were added
- * and process them
- */
-void CSendLater::processContacts()
-{
- if(m_fAvail && !m_sendLaterContactList.empty()) {
- std::vector<HANDLE>::iterator it = m_sendLaterContactList.begin();
- while(it != m_sendLaterContactList.end()) {
- processSingleContact(*it);
- it++;
- }
- m_sendLaterContactList.clear();
- }
-}
-
-/**
- * This function adds a new job to the list of messages to send unattended
- * used by the send later feature and multisend
- *
- * @param szSetting is either the name of the database key for a send later
- * job OR the utf-8 encoded message for a multisend job prefixed with
- * a 'M+timestamp'. Send later job ids start with "S".
- *
- * @param lParam: a contact handle for which the job should be scheduled
- * @return 0 on failure, 1 otherwise
- */
-int CSendLater::addJob(const char *szSetting, LPARAM lParam)
-{
- HANDLE hContact = (HANDLE)lParam;
- DBVARIANT dbv = {0};
- char *szOrig_Utf = 0;
-
- if(!m_fAvail || !szSetting || !strcmp(szSetting, "count") || lstrlenA(szSetting) < 8)
- return(0);
-
- if(szSetting[0] != 'S' && szSetting[0] != 'M')
- return(0);
-
- SendLaterJobIterator it = m_sendLaterJobList.begin();
-
- /*
- * check for possible dupes
- */
- while(it != m_sendLaterJobList.end()) {
- if((*it)->hContact == hContact && !strcmp((*it)->szId, szSetting)) {
- return(0);
- }
- it++;
- }
-
- if(szSetting[0] == 'S') {
- if(0 == DBGetContactSettingString(hContact, "SendLater", szSetting, &dbv))
- szOrig_Utf = dbv.pszVal;
- else
- return(0);
- }
- else if(szSetting[0] == 'M') {
- char *szSep = strchr(const_cast<char *>(szSetting), '|');
- if(!szSep)
- return(0);
- *szSep = 0;
- szOrig_Utf = szSep + 1;
- }
- else
- return(0);
-
- CSendLaterJob *job = new CSendLaterJob;
-
- strncpy(job->szId, szSetting, 20);
- job->szId[19] = 0;
- job->hContact = hContact;
- job->created = atol(&szSetting[1]);
-
- char *szAnsi = 0;
- wchar_t *szWchar = 0;
- UINT required = 0;
-
- int iLen = lstrlenA(szOrig_Utf);
- job->sendBuffer = reinterpret_cast<char *>(mir_alloc(iLen + 1));
- strncpy(job->sendBuffer, szOrig_Utf, iLen);
- job->sendBuffer[iLen] = 0;
-
- /*
- * construct conventional send buffer
- */
-
- szAnsi = M->utf8_decodecp(szOrig_Utf, CP_ACP, &szWchar);
- iLen = lstrlenA(szAnsi);
- if(szWchar)
- required = iLen + 1 + ((lstrlenW(szWchar) + 1) * sizeof(wchar_t));
- else
- required = iLen + 1;
-
- job->pBuf = (PBYTE)mir_calloc(required);
-
- strncpy((char *)job->pBuf, szAnsi, iLen);
- job->pBuf[iLen] = 0;
- if(szWchar)
- wcsncpy((wchar_t *)&job->pBuf[iLen + 1], szWchar, lstrlenW(szWchar));
-
- if(szSetting[0] == 'S')
- DBFreeVariant(&dbv);
-
- mir_free(szWchar);
- job->readFlags();
- m_sendLaterJobList.push_back(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)
-{
- HANDLE hContact = job->hContact;
- time_t now = time(0);
- DWORD dwFlags = 0;
- DBVARIANT dbv = {0};
- const char* szProto = 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)) {
- //_DebugTraceA("Send it: message %s for %s RESEND but not old enough", job->szId, (char *)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, 0));
- return(0); // this one was sent, but probably failed. Resend it after a while
- }
-
- CContactCache *c = CContactCache::getContactCache(hContact);
- if(!c)
- return(0); // should not happen
-
- if(!c->isValid()) {
- job->fFailed = true;
- job->bCode = CSendLaterJob::INVALID_CONTACT;
- return(0); // can happen (contact has been deleted). mark the job as failed
- }
-
- hContact = c->getActiveContact();
- szProto = c->getActiveProto();
-
- if(!hContact || szProto == 0)
- return(0);
-
- WORD wMyStatus = (WORD)CallProtoService(szProto, PS_GETSTATUS, 0, 0);
- WORD wContactStatus = c->getActiveStatus();
-
- /*
- * 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);
- }
- }
- if(wContactStatus == ID_STATUS_OFFLINE) {
- job->bCode = CSendLaterJob::JOB_STATUS;
- return(0);
- }
-
- dwFlags = IsUtfSendAvailable(hContact) ? PREF_UTF : U_PREF_UNICODE;
-
- char *svcName = SendQueue::MsgServiceName(hContact, 0, dwFlags);
-
- job->lastSent = now;
- job->iSendCount++;
- job->hTargetContact = hContact;
- job->bCode = CSendLaterJob::JOB_WAITACK;
-
- if(dwFlags & PREF_UTF)
- job->hProcess = (HANDLE)CallContactService(hContact, svcName, dwFlags, (LPARAM)job->sendBuffer);
- else
- job->hProcess = (HANDLE)CallContactService(hContact, svcName, dwFlags, (LPARAM)job->pBuf);
- return(0);
-}
-
-/*
- * add a contact to the list of contacts having open send later jobs.
- * This ist is periodically checked for new additions (processContacts())
- * and new jobs are created.
- */
-
-void CSendLater::addContact(const HANDLE hContact)
-{
- if(!m_fAvail)
- return;
-
- std::vector<HANDLE>::iterator it = m_sendLaterContactList.begin();
-
- if(m_sendLaterContactList.empty()) {
- m_sendLaterContactList.push_back(hContact);
- m_last_sendlater_processed = 0; // force processing at next tick
- return;
- }
-
- /*
- * this list should not have duplicate entries
- */
-
- while(it != m_sendLaterContactList.end()) {
- if(*it == hContact)
- return;
- it++;
- }
- m_sendLaterContactList.push_back(hContact);
- m_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)
-{
- if(m_sendLaterJobList.empty() || !m_fAvail)
- return(0);
-
- SendLaterJobIterator it = m_sendLaterJobList.begin();
-
- while(it != m_sendLaterJobList.end()) {
- if((*it)->hProcess == ack->hProcess && (*it)->hTargetContact == ack->hContact && !((*it)->fSuccess || (*it)->fFailed)) {
- DBEVENTINFO dbei = {0};
-
- if(!(*it)->fSuccess) {
- dbei.cbSize = sizeof(dbei);
- dbei.eventType = EVENTTYPE_MESSAGE;
- dbei.flags = DBEF_SENT;
- dbei.szModule = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)((*it)->hContact), 0);
- dbei.timestamp = time(NULL);
- dbei.cbBlob = lstrlenA((*it)->sendBuffer) + 1;
- dbei.flags |= DBEF_UTF;
- dbei.pBlob = (PBYTE)((*it)->sendBuffer);
- HANDLE hNewEvent = (HANDLE) CallService(MS_DB_EVENT_ADD, (WPARAM)((*it)->hContact), (LPARAM)&dbei);
-
- (*it)->cleanDB();
- }
- (*it)->fSuccess = true; // mark as successful, job list processing code will remove it later
- (*it)->hProcess = (HANDLE)-1;
- (*it)->bCode = '-';
- qMgrUpdate();
- return(0);
- }
- it++;
- }
- return(0);
-}
-
-/*
- * UI stuff (dialog procedures for the queue manager dialog
- */
-
-void CSendLater::qMgrUpdate(bool fReEnable)
-{
- if(m_hwndDlg) {
- if(fReEnable)
- Utils::enableDlgControl(m_hwndDlg, IDC_QMGR_LIST, true);
- ::SendMessage(m_hwndDlg, WM_USER + 100, 0, 0); // if qmgr is open, tell it to update
- }
-}
-
-LRESULT CSendLater::qMgrAddFilter(const HANDLE hContact, const TCHAR* tszNick)
-{
- LRESULT lr;
-
- lr = ::SendMessage(m_hwndFilter, CB_FINDSTRING, 0, reinterpret_cast<LPARAM>(tszNick));
- if(lr == CB_ERR) {
- lr = ::SendMessage(m_hwndFilter, CB_INSERTSTRING, -1, reinterpret_cast<LPARAM>(tszNick));
- ::SendMessage(m_hwndFilter, CB_SETITEMDATA, lr, reinterpret_cast<LPARAM>(hContact));
- if(hContact == m_hFilter)
- m_sel = lr;
- }
- return(m_sel);
-}
-
-/**
- * fills the list of jobs with current contents of the job queue
- * filters by m_hFilter (contact handle)
- *
- */
-void CSendLater::qMgrFillList(bool fClear)
-{
- LVITEM lvItem = {0};
- unsigned uIndex = 0;
- CContactCache* c = 0;
- TCHAR* formatTime = _T("%Y.%m.%d - %H:%M");
- TCHAR tszTimestamp[30];
- TCHAR tszStatus[20];
- const TCHAR* tszStatusText = 0;
- BYTE bCode = '-';
-
- if(fClear) {
- ::SendMessage(m_hwndList, LVM_DELETEALLITEMS, 0, 0);
- ::SendMessage(m_hwndFilter, CB_RESETCONTENT, 0, 0);
- }
-
- m_sel = 0;
- ::SendMessage(m_hwndFilter, CB_INSERTSTRING, -1,
- reinterpret_cast<LPARAM>(CTranslator::get(CTranslator::QMGR_FILTER_ALLCONTACTS)));
- ::SendMessage(m_hwndFilter, CB_SETITEMDATA, 0, 0);
-
- lvItem.cchTextMax = 255;
-
- SendLaterJobIterator it = m_sendLaterJobList.begin();
-
- while(it != m_sendLaterJobList.end()) {
-
- c = CContactCache::getContactCache((*it)->hContact);
- if(c) {
- const TCHAR* tszNick = c->getNick();
- TCHAR tszBuf[255];
-
- if(m_hFilter && m_hFilter != (*it)->hContact) {
- qMgrAddFilter(c->getContact(), tszNick);
- it++;
- continue;
- }
- lvItem.mask = LVIF_TEXT|LVIF_PARAM;
- mir_sntprintf(tszBuf, 255, _T("%s [%s]"), tszNick, c->getRealAccount());
- lvItem.pszText = tszBuf;
- lvItem.iItem = uIndex++;
- lvItem.iSubItem = 0;
- lvItem.lParam = reinterpret_cast<LPARAM>(*it);
- ::SendMessage(m_hwndList, LVM_INSERTITEM, 0, reinterpret_cast<LPARAM>(&lvItem));
- qMgrAddFilter(c->getContact(), tszNick);
-
- lvItem.mask = LVIF_TEXT;
- _tcsftime(tszTimestamp, 30, formatTime, _localtime32((__time32_t *)&(*it)->created));
- tszTimestamp[29] = 0;
- lvItem.pszText = tszTimestamp;
- lvItem.iSubItem = 1;
- ::SendMessage(m_hwndList, LVM_SETITEM, 0, reinterpret_cast<LPARAM>(&lvItem));
-
- TCHAR* msg = M->utf8_decodeT((*it)->sendBuffer);
- TCHAR* preview = Utils::GetPreviewWithEllipsis(msg, 255);
- lvItem.pszText = preview;
- lvItem.iSubItem = 2;
- ::SendMessage(m_hwndList, LVM_SETITEM, 0, reinterpret_cast<LPARAM>(&lvItem));
- mir_free(preview);
- mir_free(msg);
-
- if((*it)->fFailed) {
- tszStatusText = (*it)->bCode == CSendLaterJob::JOB_REMOVABLE ?
- CTranslator::get(CTranslator::QMGR_STATUS_REMOVED) : CTranslator::get(CTranslator::QMGR_STATUS_FAILED);
- }
- else if((*it)->fSuccess)
- tszStatusText = CTranslator::get(CTranslator::QMGR_STATUS_SENTOK);
- else {
- switch((*it)->bCode) {
- case CSendLaterJob::JOB_DEFERRED:
- tszStatusText = CTranslator::get(CTranslator::QMGR_STATUS_DEFERRED);
- break;
- case CSendLaterJob::JOB_AGE:
- tszStatusText = CTranslator::get(CTranslator::QMGR_STATUS_FAILED);
- break;
- case CSendLaterJob::JOB_HOLD:
- tszStatusText = CTranslator::get(CTranslator::QMGR_STATUS_HOLD);
- break;
- default:
- tszStatusText = CTranslator::get(CTranslator::QMGR_STATUS_PENDING);
- break;
- }
- }
- if((*it)->bCode)
- bCode = (*it)->bCode;
- mir_sntprintf(tszStatus, 20, _T("X/%s[%c] (%d)"), tszStatusText, bCode, (*it)->iSendCount);
- tszStatus[0] = static_cast<TCHAR>((*it)->szId[0]);
- lvItem.pszText = tszStatus;
- lvItem.iSubItem = 3;
- ::SendMessage(m_hwndList, LVM_SETITEM, 0, reinterpret_cast<LPARAM>(&lvItem));
-
- if((*it)->lastSent == 0)
- mir_sntprintf(tszTimestamp, 30, _T("%s"), _T("Never"));
- else {
- _tcsftime(tszTimestamp, 30, formatTime, _localtime32((__time32_t *)&(*it)->lastSent));
- tszTimestamp[29] = 0;
- }
- lvItem.pszText = tszTimestamp;
- lvItem.iSubItem = 4;
- ::SendMessage(m_hwndList, LVM_SETITEM, 0, reinterpret_cast<LPARAM>(&lvItem));
- }
- it++;
- }
- if(m_hFilter == 0)
- ::SendMessage(m_hwndFilter, CB_SETCURSEL, 0, 0);
- else
- ::SendMessage(m_hwndFilter, CB_SETCURSEL, m_sel, 0);
-}
-
-/*
- * set the column headers
- */
-#define QMGR_LIST_NRCOLUMNS 5
-
-static char* szColFormat = "%d;%d;%d;%d;%d";
-static char* szColDefault = "100;120;80;120;120";
-
-void CSendLater::qMgrSetupColumns()
-{
- LVCOLUMN col = {0};
- int nWidths[QMGR_LIST_NRCOLUMNS];
- DBVARIANT dbv = {0};
- RECT rcList;
- LONG cxList;
-
- ::GetWindowRect(m_hwndList, &rcList);
- cxList = rcList.right - rcList.left;
-
- if(0 == M->GetString(0, SRMSGMOD_T, "qmgrListColumns", &dbv)) {
- sscanf(dbv.pszVal, szColFormat, &nWidths[0], &nWidths[1], &nWidths[2], &nWidths[3], &nWidths[4]);
- DBFreeVariant(&dbv);
- }
- else
- sscanf(szColDefault, szColFormat, &nWidths[0], &nWidths[1], &nWidths[2], &nWidths[3], &nWidths[4]);
-
- col.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM;
- col.cx = max(nWidths[0], 10);
- col.pszText = const_cast<TCHAR *>(CTranslator::get(CTranslator::GEN_CONTACT));
-
- ::SendMessage(m_hwndList, LVM_INSERTCOLUMN, 0, reinterpret_cast<LPARAM>(&col));
-
- col.pszText = const_cast<TCHAR *>(CTranslator::get(CTranslator::QMGR_COL_ODATE));
- col.cx = max(nWidths[1], 10);
- ::SendMessage(m_hwndList, LVM_INSERTCOLUMN, 1, reinterpret_cast<LPARAM>(&col));
-
- col.pszText = const_cast<TCHAR *>(CTranslator::get(CTranslator::QMGR_COL_MESSAGETEXT));
- col.cx = max((cxList - nWidths[0] - nWidths[1] - nWidths[3] - nWidths[4] - 10), 10);
- ::SendMessage(m_hwndList, LVM_INSERTCOLUMN, 2, reinterpret_cast<LPARAM>(&col));
-
- col.pszText = const_cast<TCHAR *>(CTranslator::get(CTranslator::QMGR_COL_STATUS));
- col.cx = max(nWidths[3], 10);
- ::SendMessage(m_hwndList, LVM_INSERTCOLUMN, 3, reinterpret_cast<LPARAM>(&col));
-
- col.pszText = const_cast<TCHAR *>(CTranslator::get(CTranslator::QMGR_COL_LASTSENDINFO));
- col.cx = max(nWidths[4], 10);
- ::SendMessage(m_hwndList, LVM_INSERTCOLUMN, 4, reinterpret_cast<LPARAM>(&col));
-
-}
-
-/**
- * save user defined column widths to the database
- */
-void CSendLater::qMgrSaveColumns()
-{
- char szColFormatNew[100];
- int nWidths[QMGR_LIST_NRCOLUMNS], i;
- LVCOLUMN col = {0};
-
- col.mask = LVCF_WIDTH;
- for(i = 0; i < QMGR_LIST_NRCOLUMNS; i++) {
- ::SendMessage(m_hwndList, LVM_GETCOLUMN, i, reinterpret_cast<LPARAM>(&col));
- nWidths[i] = max(col.cx, 10);
- }
- mir_snprintf(szColFormatNew, 100, "%d;%d;%d;%d;%d", nWidths[0], nWidths[1], nWidths[2], nWidths[3], nWidths[4]);
- ::DBWriteContactSettingString(0, SRMSGMOD_T, "qmgrListColumns", szColFormatNew);
-}
-
-INT_PTR CALLBACK CSendLater::DlgProcStub(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- CSendLater *s = reinterpret_cast<CSendLater *>(::GetWindowLongPtr(hwnd, GWLP_USERDATA));
-
- if(s)
- return(s->DlgProc(hwnd, msg, wParam, lParam));
-
- switch(msg) {
- case WM_INITDIALOG: {
- ::SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam);
- s = reinterpret_cast<CSendLater *>(lParam);
- return(s->DlgProc(hwnd, msg, wParam, lParam));
- }
- default:
- break;
- }
- return(FALSE);
-}
-
-INT_PTR CALLBACK CSendLater::DlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- switch(msg) {
- case WM_INITDIALOG:
- m_hwndDlg = hwnd;
- TranslateDialogDefault(hwnd);
- m_hwndList = ::GetDlgItem(m_hwndDlg, IDC_QMGR_LIST);
- m_hwndFilter = ::GetDlgItem(m_hwndDlg, IDC_QMGR_FILTER);
- m_hFilter = reinterpret_cast<HANDLE>(M->GetDword(0, SRMSGMOD_T, "qmgrFilterContact", 0));
-
- ::SetWindowLongPtr(m_hwndList, GWL_STYLE, ::GetWindowLongPtr(m_hwndList, GWL_STYLE) | LVS_SHOWSELALWAYS);
- ::SendMessage(m_hwndList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_LABELTIP|LVS_EX_DOUBLEBUFFER);
- qMgrSetupColumns();
- qMgrFillList();
- if(PluginConfig.g_PopupAvail) {
- ::CheckDlgButton(m_hwndDlg, IDC_QMGR_SUCCESSPOPUPS, m_fSuccessPopups ? BST_CHECKED : BST_UNCHECKED);
- ::CheckDlgButton(m_hwndDlg, IDC_QMGR_ERRORPOPUPS, m_fErrorPopups ? BST_CHECKED : BST_UNCHECKED);
- }
- else {
- Utils::showDlgControl(m_hwndDlg, IDC_QMGR_ERRORPOPUPS, SW_HIDE);
- Utils::showDlgControl(m_hwndDlg, IDC_QMGR_SUCCESSPOPUPS, SW_HIDE);
- }
- ::ShowWindow(hwnd, SW_NORMAL);
- return(FALSE);
-
- case WM_NOTIFY: {
- NMHDR* pNMHDR = reinterpret_cast<NMHDR *>(lParam);
-
- if(pNMHDR->hwndFrom == m_hwndList) {
- switch(pNMHDR->code) {
- case NM_RCLICK: {
- HMENU hMenu = ::LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_TABCONTEXT));
- HMENU hSubMenu = ::GetSubMenu(hMenu, 13);
- ::TranslateMenu(hSubMenu);
-
- POINT pt;
- ::GetCursorPos(&pt);
- /*
- * copy to clipboard only allowed with a single selection
- */
- if(::SendMessage(m_hwndList, LVM_GETSELECTEDCOUNT, 0, 0) == 1)
- ::EnableMenuItem(hSubMenu, ID_QUEUEMANAGER_COPYMESSAGETOCLIPBOARD, MF_ENABLED);
-
- m_fIsInteractive = true;
- int selection = ::TrackPopupMenu(hSubMenu, TPM_RETURNCMD, pt.x, pt.y, 0, m_hwndDlg, NULL);
- if(selection == ID_QUEUEMANAGER_CANCELALLMULTISENDJOBS) {
- SendLaterJobIterator it = m_sendLaterJobList.begin();
- while(it != m_sendLaterJobList.end()) {
- if((*it)->szId[0] == 'M') {
- (*it)->fFailed = true;
- (*it)->bCode = CSendLaterJob::JOB_REMOVABLE;
- }
- it++;
- }
- }
- else if(selection != 0) {
- ::SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDC_QMGR_REMOVE, LOWORD(selection)), 0);
- m_last_sendlater_processed = 0; // force a queue check
- }
- ::DestroyMenu(hMenu);
- m_fIsInteractive = false;
- break;
- }
- default:
- break;
- }
- }
- break;
- }
-
- case WM_COMMAND:
- if(HIWORD(wParam) == CBN_SELCHANGE && reinterpret_cast<HWND>(lParam) == m_hwndFilter) {
- LRESULT lr = ::SendMessage(m_hwndFilter, CB_GETCURSEL, 0, 0);
- if(lr != CB_ERR) {
- m_hFilter = reinterpret_cast<HANDLE>(::SendMessage(m_hwndFilter, CB_GETITEMDATA, lr, 0));
- qMgrFillList();
- }
- break;
- }
- switch(LOWORD(wParam)) {
- case IDOK:
- case IDCANCEL:
- qMgrSaveColumns();
- ::DestroyWindow(hwnd);
- break;
-
- case IDC_QMGR_SUCCESSPOPUPS:
- m_fSuccessPopups = ::IsDlgButtonChecked(m_hwndDlg, IDC_QMGR_SUCCESSPOPUPS) ? true : false;
- M->WriteByte(0, SRMSGMOD_T, "qmgrSuccessPopups", m_fSuccessPopups ? 1 : 0);
- break;
-
- case IDC_QMGR_ERRORPOPUPS:
- m_fErrorPopups = ::IsDlgButtonChecked(m_hwndDlg, IDC_QMGR_ERRORPOPUPS) ? true : false;
- M->WriteByte(0, SRMSGMOD_T, "qmgrErrorPopups", m_fErrorPopups ? 1 : 0);
- break;
-
- case IDC_QMGR_HELP:
- CallService(MS_UTILS_OPENURL, 0, reinterpret_cast<LPARAM>("http://wiki.miranda.or.at/TabSRMM/SendLater"));
- break;
- /*
- * this handles all commands sent by the context menu
- * mark jobs for removal/reset/hold/unhold
- * exception: kill all open multisend jobs is directly handled from the context menu
- */
- case IDC_QMGR_REMOVE: {
- if(::SendMessage(m_hwndList, LVM_GETSELECTEDCOUNT, 0, 0) != 0) {
- LVITEM item = {0};
- LRESULT items = ::SendMessage(m_hwndList, LVM_GETITEMCOUNT, 0, 0);
- item.mask = LVIF_STATE|LVIF_PARAM;
- item.stateMask = LVIS_SELECTED;
-
- if(HIWORD(wParam) != ID_QUEUEMANAGER_COPYMESSAGETOCLIPBOARD) {
- if(MessageBox(0, CTranslator::get(CTranslator::QMGR_WARNING_REMOVAL), CTranslator::get(CTranslator::QMGR_TITLE),
- MB_ICONQUESTION | MB_OKCANCEL) == IDCANCEL)
- break;
- }
- for(LRESULT i = 0; i < items; i++) {
- item.iItem = i;
- ::SendMessage(m_hwndList, LVM_GETITEM, 0, reinterpret_cast<LPARAM>(&item));
- if(item.state & LVIS_SELECTED) {
- CSendLaterJob* job = reinterpret_cast<CSendLaterJob *>(item.lParam);
- if(job) {
- switch(HIWORD(wParam)) {
- case ID_QUEUEMANAGER_MARKSELECTEDFORREMOVAL:
- job->bCode = CSendLaterJob::JOB_REMOVABLE;
- job->fFailed = true;
- break;
- case ID_QUEUEMANAGER_HOLDSELECTED:
- job->bCode = CSendLaterJob::JOB_HOLD;
- job->writeFlags();
- break;
- case ID_QUEUEMANAGER_RESUMESELECTED:
- job->bCode = 0;
- job->writeFlags();
- break;
- case ID_QUEUEMANAGER_COPYMESSAGETOCLIPBOARD: {
- TCHAR *msg = M->utf8_decodeT(job->sendBuffer);
- Utils::CopyToClipBoard(msg, m_hwndDlg);
- mir_free(msg);
- break;
- }
- /*
- * reset deferred and aged jobs
- * so they can be resent at next processing
- */
- case ID_QUEUEMANAGER_RESETSELECTED: {
- if(job->bCode == CSendLaterJob::JOB_DEFERRED) {
- job->iSendCount = 0;
- job->bCode = '-';
- }
- else if(job->bCode == CSendLaterJob::JOB_AGE) {
- job->fFailed = false;
- job->bCode = '-';
- job->created = time(0);
- }
- break;
- }
- default:
- break;
- }
- }
- }
- }
- qMgrFillList();
- }
- break;
- }
- }
- break;
-
- case WM_USER + 100:
- qMgrFillList();
- break;
- case WM_NCDESTROY: {
- m_hwndDlg = 0;
- M->WriteDword(0, SRMSGMOD_T, "qmgrFilterContact", reinterpret_cast<DWORD>(m_hFilter));
- break;
- }
- }
- return(FALSE);
-}
-
-/**
- * invoke queue manager dialog - do nothing if this dialog is already open
- */
-void CSendLater::invokeQueueMgrDlg()
-{
- if(m_hwndDlg == 0)
- m_hwndDlg = ::CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_SENDLATER_QMGR), 0, CSendLater::DlgProcStub,
- reinterpret_cast<LPARAM>(this));
-}
-
-/*
- * service function to invoke the queue manager
- */
-
-INT_PTR CSendLater::svcQMgr(WPARAM wParam, LPARAM lParam)
-{
- sendLater->invokeQueueMgrDlg();
- return(0);
-}
-
-
-CSendLater* sendLater = 0;