summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/m_srmm_int.h5
-rw-r--r--libs/win32/mir_app.libbin266252 -> 266558 bytes
-rw-r--r--libs/win64/mir_app.libbin265336 -> 265642 bytes
-rw-r--r--plugins/NewStory/src/history_array.cpp43
-rw-r--r--plugins/NewStory/src/history_array.h11
-rw-r--r--plugins/NewStory/src/history_control.cpp44
-rw-r--r--plugins/NewStory/src/history_svc.cpp2
-rw-r--r--src/mir_app/src/mir_app.def1
-rw-r--r--src/mir_app/src/mir_app64.def1
-rw-r--r--src/mir_app/src/srmm_util.cpp5
10 files changed, 79 insertions, 33 deletions
diff --git a/include/m_srmm_int.h b/include/m_srmm_int.h
index 8f47e4cfe2..12c2b1cd8a 100644
--- a/include/m_srmm_int.h
+++ b/include/m_srmm_int.h
@@ -356,6 +356,11 @@ MIR_APP_DLL(void) Srmm_Broadcast(UINT, WPARAM, LPARAM);
MIR_APP_DLL(void) Srmm_CreateHotkey(const char *pszSection, const char *pszDescription);
/////////////////////////////////////////////////////////////////////////////////////////
+// downloads or launches offline file
+
+MIR_APP_DLL(void) Srmm_DownloadOfflineFile(MCONTACT hContact, MEVENT hDbEvent, bool bOpen);
+
+/////////////////////////////////////////////////////////////////////////////////////////
// finds a SRMM window using hContact
MIR_APP_DLL(HWND) Srmm_FindWindow(MCONTACT hContact);
diff --git a/libs/win32/mir_app.lib b/libs/win32/mir_app.lib
index ddea970e69..795089f618 100644
--- a/libs/win32/mir_app.lib
+++ b/libs/win32/mir_app.lib
Binary files differ
diff --git a/libs/win64/mir_app.lib b/libs/win64/mir_app.lib
index ced7b00445..052a17039e 100644
--- a/libs/win64/mir_app.lib
+++ b/libs/win64/mir_app.lib
Binary files differ
diff --git a/plugins/NewStory/src/history_array.cpp b/plugins/NewStory/src/history_array.cpp
index adaa690f81..5463421c37 100644
--- a/plugins/NewStory/src/history_array.cpp
+++ b/plugins/NewStory/src/history_array.cpp
@@ -49,7 +49,7 @@ bool Filter::check(ItemData *item)
void ItemData::checkCreate(HWND hwnd)
{
if (data == nullptr) {
- if (bRtf)
+ if (m_bRtf)
data = MTextCreateEx(htuLog, this->wtext, MTEXT_FLG_WCHAR | MTEXT_FLG_RTF);
else
data = MTextCreateW(htuLog, Proto_GetBaseAccountName(hContact), ptrW(TplFormatString(getTemplate(), hContact, this)));
@@ -104,14 +104,14 @@ bool ItemData::isLinkChar(int idx) const
void ItemData::load(bool bFullLoad)
{
- if (!bFullLoad || bLoaded)
+ if (!bFullLoad || m_bLoaded)
return;
dbe.cbBlob = -1;
if (db_event_get(hEvent, &dbe))
return;
- bLoaded = true;
+ m_bLoaded = true;
switch (dbe.eventType) {
case EVENTTYPE_MESSAGE:
@@ -128,19 +128,34 @@ void ItemData::load(bool bFullLoad)
case EVENTTYPE_FILE:
{
- CMStringW wszFileName;
DB::FILE_BLOB blob(dbe);
if (blob.isOffline()) {
- wszFileName = blob.getLocalName();
- }
- else {
- wchar_t buf[MAX_PATH];
- CallService(MS_FILE_GETRECEIVEDFILESFOLDERW, hContact, (LPARAM)buf);
+ m_bOfflineFile = true;
+
+ CMStringW buf;
+ buf.Append(blob.getName() ? blob.getName() : TranslateT("Unnamed"));
+
+ if (auto *pwszDescr = blob.getDescr()) {
+ buf.Append(L" - ");
+ buf.Append(pwszDescr);
+ }
- wszFileName = buf;
- wszFileName.Append(blob.getName());
+ if (blob.getSize() > 0 && blob.getSize() == blob.getTransferred())
+ buf.AppendFormat(L" %c ", 10004);
+
+ if (uint32_t size = blob.getSize())
+ buf.AppendFormat(L" %uKB", size < 1024 ? 1 : unsigned(blob.getSize() / 1024));
+
+ wtext = buf.Detach();
+ break;
}
+ wchar_t buf[MAX_PATH];
+ CallService(MS_FILE_GETRECEIVEDFILESFOLDERW, hContact, (LPARAM)buf);
+
+ CMStringW wszFileName = buf;
+ wszFileName.Append(blob.getName());
+
// if a filename contains spaces, URL will be broken
if (wszFileName.Find(' ') != -1) {
wchar_t wszShortPath[MAX_PATH];
@@ -168,7 +183,7 @@ void ItemData::load(bool bFullLoad)
bool ItemData::isGrouped() const
{
if (pPrev && g_plugin.bMsgGrouping) {
- if (!pPrev->bLoaded)
+ if (!pPrev->m_bLoaded)
pPrev->load(true);
if (pPrev->hContact == hContact && (pPrev->dbe.flags & DBEF_SENT) == (dbe.flags & DBEF_SENT))
@@ -290,7 +305,7 @@ void HistoryArray::addChatEvent(SESSION_INFO *si, LOGINFO *lin)
auto &p = allocateItem();
p.hContact = si->hContact;
p.wtext = wszText.Detach();
- p.bLoaded = true;
+ p.m_bLoaded = true;
p.dbe.eventType = EVENTTYPE_MESSAGE;
p.dbe.timestamp = lin->time;
@@ -346,7 +361,7 @@ ItemData* HistoryArray::get(int id, bool bLoad)
return nullptr;
auto *p = &pages[pageNo].data[id % HIST_BLOCK_SIZE];
- if (bLoad && !p->bLoaded)
+ if (bLoad && !p->m_bLoaded)
p->load(true);
return p;
}
diff --git a/plugins/NewStory/src/history_array.h b/plugins/NewStory/src/history_array.h
index 6401ff1644..e7657dc135 100644
--- a/plugins/NewStory/src/history_array.h
+++ b/plugins/NewStory/src/history_array.h
@@ -1,14 +1,15 @@
#ifndef __history_array__
#define __history_array__
-struct ItemData
+struct ItemData : public MZeroedObject
{
MCONTACT hContact;
MEVENT hEvent;
- bool bSelected;
- bool bLoaded;
- bool bRtf;
+ bool m_bRtf;
+ bool m_bSelected;
+ bool m_bLoaded;
+ bool m_bOfflineFile;
int savedTop;
DB::EventInfo dbe;
@@ -18,7 +19,7 @@ struct ItemData
HANDLE data;
ItemData *pPrev;
- ItemData() { memset(this, 0, sizeof(*this)); }
+ ItemData() {}
~ItemData();
void checkCreate(HWND hwnd);
diff --git a/plugins/NewStory/src/history_control.cpp b/plugins/NewStory/src/history_control.cpp
index 2e17209030..1a38dce3e5 100644
--- a/plugins/NewStory/src/history_control.cpp
+++ b/plugins/NewStory/src/history_control.cpp
@@ -91,7 +91,7 @@ void NewstoryListData::DeleteItems(void)
int eventCount = items.getCount();
for (int i = eventCount - 1; i >= 0; i--) {
auto *p = items.get(i, false);
- if (p->hEvent && p->bSelected) {
+ if (p->hEvent && p->m_bSelected) {
db_event_delete(p->hEvent);
items.remove(i);
firstSel = i;
@@ -267,7 +267,7 @@ int NewstoryListData::PaintItem(HDC hdc, int index, int top, int width)
item->getFontColor(fontid, colorid);
clText = g_fontTable[fontid].cl;
- if (item->bSelected) {
+ if (item->m_bSelected) {
MTextSendMessage(0, item->data, EM_SETSEL, 0, -1);
clText = g_colorTable[COLOR_SELTEXT].cl;
clBack = g_colorTable[COLOR_SELBACK].cl;
@@ -463,7 +463,7 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
for (int i = start; i <= end; ++i) {
if (auto *p = data->items.get(i, false))
- p->bSelected = true;
+ p->m_bSelected = true;
}
InvalidateRect(hwnd, 0, FALSE);
@@ -479,7 +479,7 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
for (int i = start; i <= end; ++i) {
auto *p = data->items.get(i, false);
- p->bSelected = !p->bSelected;
+ p->m_bSelected = !p->m_bSelected;
}
InvalidateRect(hwnd, 0, FALSE);
@@ -497,9 +497,9 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
for (int i = 0; i < count; ++i) {
auto *p = data->items.get(i, false);
if ((i >= start) && (i <= end))
- p->bSelected = true;
+ p->m_bSelected = true;
else
- p->bSelected = false;
+ p->m_bSelected = false;
}
InvalidateRect(hwnd, 0, FALSE);
@@ -515,7 +515,7 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
for (int i = start; i <= end; ++i) {
auto *p = data->items.get(i, false);
- p->bSelected = false;
+ p->m_bSelected = false;
}
InvalidateRect(hwnd, 0, FALSE);
@@ -589,7 +589,7 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
int eventCount = data->items.getCount();
for (int i = 0; i < eventCount; i++) {
ItemData *p = data->items.get(i, false);
- if (p->bSelected)
+ if (p->m_bSelected)
res.Append(ptrW(TplFormatString(p->getCopyTemplate(), p->hContact, p)));
}
@@ -791,16 +791,34 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
Utils_OpenUrlW(wszUrl);
return 0;
}
-
- if (data->caret == idx) {
- data->BeginEditItem(idx, true);
- return 0;
- }
SendMessage(hwnd, NSM_SELECTITEMS2, idx, idx);
SendMessage(hwnd, NSM_SETCARET, idx, TRUE);
}
}
+ SetFocus(hwnd);
+ return 0;
+
+ case WM_LBUTTONDBLCLK:
+ pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
+ idx = data->GetItemFromPixel(pt.y);
+ if (idx >= 0) {
+ if (data->caret != idx)
+ data->EndEditItem(false);
+
+ auto *pItem = data->items[idx];
+ pt.y -= pItem->savedTop;
+
+ if (pItem->m_bOfflineFile) {
+ Srmm_DownloadOfflineFile(pItem->hContact, pItem->hEvent, true);
+ return 0;
+ }
+
+ if (data->caret == idx) {
+ data->BeginEditItem(idx, true);
+ return 0;
+ }
+ }
SetFocus(hwnd);
return 0;
diff --git a/plugins/NewStory/src/history_svc.cpp b/plugins/NewStory/src/history_svc.cpp
index ae3d2ddd4b..336f0ada37 100644
--- a/plugins/NewStory/src/history_svc.cpp
+++ b/plugins/NewStory/src/history_svc.cpp
@@ -24,7 +24,7 @@ static INT_PTR SvcGetSelection(WPARAM wParam, LPARAM lParam)
if (pData && pRet) {
for (int i = pData->items.getCount(); i >= 0; i--) {
auto *p = pData->items.get(i);
- if (p->bSelected)
+ if (p->m_bSelected)
pRet->push_back(p->hEvent);
}
}
diff --git a/src/mir_app/src/mir_app.def b/src/mir_app/src/mir_app.def
index 3aabd35797..1d06496629 100644
--- a/src/mir_app/src/mir_app.def
+++ b/src/mir_app/src/mir_app.def
@@ -246,6 +246,7 @@ Srmm_RedrawToolbarIcons @338
?Srmm_GetNthButton@@YGPAUCustomButtonData@@H@Z @339 NONAME
?Srmm_GetButtonCount@@YGHXZ @340 NONAME
?Srmm_ClickToolbarIcon@@YGXIHPAUHWND__@@H@Z @341 NONAME
+?Srmm_DownloadOfflineFile@@YGXII_N@Z @342 NONAME
Miranda_OkToExit @344
Miranda_GetVersion @345
Miranda_GetFileVersion @346
diff --git a/src/mir_app/src/mir_app64.def b/src/mir_app/src/mir_app64.def
index 83bdae4f9a..8c6bc1eadc 100644
--- a/src/mir_app/src/mir_app64.def
+++ b/src/mir_app/src/mir_app64.def
@@ -246,6 +246,7 @@ Srmm_RedrawToolbarIcons @338
?Srmm_GetNthButton@@YAPEAUCustomButtonData@@H@Z @339 NONAME
?Srmm_GetButtonCount@@YAHXZ @340 NONAME
?Srmm_ClickToolbarIcon@@YAXIHPEAUHWND__@@H@Z @341 NONAME
+?Srmm_DownloadOfflineFile@@YAXII_N@Z @342 NONAME
Miranda_OkToExit @344
Miranda_GetVersion @345
Miranda_GetFileVersion @346
diff --git a/src/mir_app/src/srmm_util.cpp b/src/mir_app/src/srmm_util.cpp
index e30dff2ea4..a7f95f7752 100644
--- a/src/mir_app/src/srmm_util.cpp
+++ b/src/mir_app/src/srmm_util.cpp
@@ -195,6 +195,11 @@ void DownloadOfflineFile(MCONTACT hContact, MEVENT hDbEvent, bool bOpen, OFD_Cal
}
}
+MIR_APP_DLL(void) Srmm_DownloadOfflineFile(MCONTACT hContact, MEVENT hDbEvent, bool bOpen)
+{
+ DownloadOfflineFile(hContact, hDbEvent, bOpen, new OFD_Download());
+}
+
/////////////////////////////////////////////////////////////////////////////////////////
// serializes all thread-unsafe operation to the first thread