1181 lines
31 KiB
C++
1181 lines
31 KiB
C++
/* almost the same as view_pmp_devices, but only one device*/
|
|
#include "main.h"
|
|
#include <windows.h>
|
|
#include <windowsx.h>
|
|
#include <stdio.h>
|
|
#include <shlobj.h>
|
|
#include "..\..\General\gen_ml/ml.h"
|
|
#include "..\..\General\gen_ml/itemlist.h"
|
|
#include "../nu/listview.h"
|
|
#include "..\..\General\gen_ml/childwnd.h"
|
|
#include "../winamp/wa_ipc.h"
|
|
#include "../winamp/wa_dlg.h"
|
|
#include "resource1.h"
|
|
#include "SkinnedListView.h"
|
|
#include "DeviceView.h"
|
|
#include "api__ml_pmp.h"
|
|
#include "./graphics.h"
|
|
#include <strsafe.h>
|
|
#include "../nu/AutoWide.h"
|
|
|
|
static HRGN g_rgnUpdate = NULL;
|
|
static int offsetX, offsetY, customAllowed;
|
|
static DeviceView *device;
|
|
static SkinnedListView * listTransfers=NULL;
|
|
std::map<DeviceView *, bool> device_update_map;
|
|
|
|
typedef struct TransferView
|
|
{
|
|
HFONT font;
|
|
SIZE unitSize;
|
|
HRGN updateRegion;
|
|
POINT updateOffset;
|
|
} TransferView;
|
|
|
|
#define TRANSFERVIEW(_hwnd) ((TransferView*)GetViewData(_hwnd))
|
|
#define TRANSFERVIEW_RET_VOID(_self, _hwnd) { (_self) = TRANSFERVIEW((_hwnd)); if (NULL == (_self)) return; }
|
|
#define TRANSFERVIEW_RET_VAL(_self, _hwnd, _error) { (_self) = TRANSFERVIEW((_hwnd)); if (NULL == (_self)) return (_error); }
|
|
|
|
#define TRANSFERVIEW_DLU_TO_HORZ_PX(_self, _dlu) MulDiv((_dlu), (_self)->unitSize.cx, 4)
|
|
#define TRANSFERVIEW_DLU_TO_VERT_PX(_self, _dlu) MulDiv((_dlu), (_self)->unitSize.cy, 8)
|
|
|
|
void handleContextMenuResult(int r, C_ItemList * items=NULL, DeviceView * dev=NULL);
|
|
int showContextMenu(int context,HWND hwndDlg, Device * dev, POINT pt);
|
|
|
|
class TransferItemShadowShort
|
|
{
|
|
public:
|
|
CopyInst * c;
|
|
wchar_t * status, * type, * track, * sourceDevice, * destDevice, * lastChanged, * sourceFile, * clientType;
|
|
bool changed;
|
|
TransferItemShadowShort(CopyInst * c)
|
|
{
|
|
changed = false;
|
|
this->c = c;
|
|
status = _wcsdup(c->statusCaption);
|
|
type = _wcsdup(c->typeCaption);
|
|
track = _wcsdup(c->trackCaption);
|
|
lastChanged = _wcsdup(c->lastChanged);
|
|
sourceDevice = _wcsdup(c->sourceDevice);
|
|
destDevice = _wcsdup(c->destDevice);
|
|
sourceFile = _wcsdup(c->sourceFile);
|
|
clientType = AutoWideDup(c->dev->GetConnection());
|
|
}
|
|
~TransferItemShadowShort()
|
|
{
|
|
if (status) free(status);
|
|
if (type) free(type);
|
|
if (track) free(track);
|
|
if (lastChanged) free(lastChanged);
|
|
if (sourceDevice) free(sourceDevice);
|
|
if (destDevice) free(destDevice);
|
|
if (sourceFile) free(sourceFile);
|
|
if (clientType) free(clientType);
|
|
}
|
|
bool Equals(TransferItemShadowShort * a)
|
|
{
|
|
if (!a) return false;
|
|
return (c == a->c) && !wcscmp(track,a->track) && !wcscmp(status,a->status) && !wcscmp(type,a->type);
|
|
}
|
|
};
|
|
|
|
LinkedQueue *getTransferQueue(DeviceView *deviceView)
|
|
{
|
|
if (deviceView)
|
|
{
|
|
return (deviceView->isCloudDevice ? &cloudTransferQueue : &deviceView->transferQueue);
|
|
}
|
|
else if (device)
|
|
{
|
|
return (device->isCloudDevice ? &cloudTransferQueue : &device->transferQueue);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
LinkedQueue *getFinishedTransferQueue(DeviceView *deviceView)
|
|
{
|
|
if (deviceView)
|
|
{
|
|
return (deviceView->isCloudDevice ? &cloudFinishedTransfers : &deviceView->finishedTransfers);
|
|
}
|
|
else if (device)
|
|
{
|
|
return (device->isCloudDevice ? &cloudFinishedTransfers : &device->finishedTransfers);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
int getTransferProgress(DeviceView *deviceView)
|
|
{
|
|
if(deviceView)
|
|
{
|
|
return (deviceView->isCloudDevice ? cloudTransferProgress : deviceView->currentTransferProgress);
|
|
}
|
|
else if(device)
|
|
{
|
|
return (device->isCloudDevice ? cloudTransferProgress : device->currentTransferProgress);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// TODO hook up to a config (would need to work after a reset to be 100% safe...?)
|
|
int sharedQueue = 1;
|
|
static C_ItemList *getTransferListShadow()
|
|
{
|
|
C_ItemList * list = new C_ItemList;
|
|
if (!sharedQueue)
|
|
{
|
|
LinkedQueue * txQueue = getTransferQueue();
|
|
if (txQueue)
|
|
{
|
|
txQueue->lock();
|
|
for (int j = 0; j < txQueue->GetSize(); j++)
|
|
list->Add(new TransferItemShadowShort((CopyInst*)txQueue->Get(j)));
|
|
txQueue->unlock();
|
|
}
|
|
|
|
LinkedQueue * finishedTX = getFinishedTransferQueue();
|
|
if (finishedTX)
|
|
{
|
|
finishedTX->lock();
|
|
for (int j = 0; j < finishedTX->GetSize(); j++)
|
|
list->Add(new TransferItemShadowShort((CopyInst*)finishedTX->Get(j)));
|
|
finishedTX->unlock();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// TODO should probably review this when we're more intelligent on multi-handling
|
|
// we do the cloud transfer queue specifically so as not to duplicate by devices
|
|
LinkedQueue * txQueue = &cloudTransferQueue;
|
|
if (txQueue)
|
|
{
|
|
txQueue->lock();
|
|
for (int j = 0; j < txQueue->GetSize(); j++)
|
|
list->Add(new TransferItemShadowShort((CopyInst*)txQueue->Get(j)));
|
|
txQueue->unlock();
|
|
}
|
|
|
|
LinkedQueue * finishedTX = &cloudFinishedTransfers;
|
|
if (finishedTX)
|
|
{
|
|
finishedTX->lock();
|
|
for (int j = 0; j < finishedTX->GetSize(); j++)
|
|
list->Add(new TransferItemShadowShort((CopyInst*)finishedTX->Get(j)));
|
|
finishedTX->unlock();
|
|
}
|
|
|
|
for (int i = 0; i < devices.GetSize(); i++)
|
|
{
|
|
DeviceView * d = (DeviceView *)devices.Get(i);
|
|
if (!d || d->isCloudDevice) continue;
|
|
|
|
LinkedQueue * txQueue = getTransferQueue(d);
|
|
if (txQueue)
|
|
{
|
|
txQueue->lock();
|
|
for (int j = 0; j < txQueue->GetSize(); j++)
|
|
list->Add(new TransferItemShadowShort((CopyInst*)txQueue->Get(j)));
|
|
txQueue->unlock();
|
|
}
|
|
|
|
LinkedQueue * finishedTX = getFinishedTransferQueue(d);
|
|
if (finishedTX)
|
|
{
|
|
finishedTX->lock();
|
|
for (int j = 0; j < finishedTX->GetSize(); j++)
|
|
list->Add(new TransferItemShadowShort((CopyInst*)finishedTX->Get(j)));
|
|
finishedTX->unlock();
|
|
}
|
|
}
|
|
}
|
|
return list;
|
|
}
|
|
|
|
class TransferContents : public ListContents
|
|
{
|
|
public:
|
|
TransferContents()
|
|
{
|
|
oldSize = 0;
|
|
listShadow = 0;
|
|
InitializeCriticalSection(&cs);
|
|
}
|
|
|
|
void Init()
|
|
{
|
|
lock();
|
|
|
|
if (!listShadow)
|
|
listShadow = getTransferListShadow();
|
|
|
|
unlock();
|
|
}
|
|
|
|
virtual ~TransferContents()
|
|
{
|
|
DeleteCriticalSection(&cs);
|
|
delete listShadow;
|
|
}
|
|
|
|
virtual int GetNumColumns()
|
|
{
|
|
// TODO check the number of columns are ok, etc
|
|
return 7;//(device->isCloudDevice ? 7 : 3);
|
|
}
|
|
|
|
virtual int GetNumRows()
|
|
{
|
|
return (listShadow ? listShadow->GetSize() : 0);
|
|
}
|
|
|
|
virtual wchar_t * GetColumnTitle(int num)
|
|
{
|
|
// TODO need to clean this up as needed
|
|
switch (num + 1)
|
|
{
|
|
case 0: return WASABI_API_LNGSTRINGW(IDS_TYPE);
|
|
case 1: return WASABI_API_LNGSTRINGW(IDS_TRACK);
|
|
case 2: return WASABI_API_LNGSTRINGW(IDS_STATUS);
|
|
case 3: return WASABI_API_LNGSTRINGW(IDS_LAST_CHANGED);
|
|
case 4: return WASABI_API_LNGSTRINGW(IDS_SOURCE);
|
|
case 5: return WASABI_API_LNGSTRINGW(IDS_DESTINATION);
|
|
case 6: return WASABI_API_LNGSTRINGW(IDS_SOURCE_FILE);
|
|
case 7: return WASABI_API_LNGSTRINGW(IDS_CLIENT_TYPE);
|
|
}
|
|
return L"";
|
|
}
|
|
|
|
virtual int GetColumnWidth(int num)
|
|
{
|
|
switch (num)
|
|
{
|
|
case 0: return global_config->ReadInt((!device->isCloudDevice ? L"transfers_col0_width" : L"cloud_col0_width"), 300);
|
|
case 1: return global_config->ReadInt((!device->isCloudDevice ? L"transfers_col1_width" : L"cloud_col1_width"), 150);
|
|
case 2: return global_config->ReadInt((!device->isCloudDevice ? L"transfers_col2_width" : L"cloud_col2_width"), 100);
|
|
case 3: return global_config->ReadInt((!device->isCloudDevice ? L"transfers_col3_width" : L"cloud_col3_width"), 100);
|
|
case 4: return global_config->ReadInt((!device->isCloudDevice ? L"transfers_col4_width" : L"cloud_col4_width"), 100);
|
|
case 5: return global_config->ReadInt((!device->isCloudDevice ? L"transfers_col5_width" : L"cloud_col5_width"), 100);
|
|
case 6: return global_config->ReadInt((!device->isCloudDevice ? L"transfers_col6_width" : L"cloud_col6_width"), 300);
|
|
case 7: return global_config->ReadInt((!device->isCloudDevice ? L"transfers_col7_width" : L"cloud_col7_width"), 100);
|
|
default: return 0;
|
|
}
|
|
}
|
|
|
|
virtual void ColumnResize(int col, int newWidth)
|
|
{
|
|
if (NULL != global_config &&
|
|
col >= 0 &&
|
|
col < GetNumColumns())
|
|
{
|
|
wchar_t buffer[64] = {0};
|
|
|
|
if (FAILED(StringCchPrintf(buffer, ARRAYSIZE(buffer), (!device->isCloudDevice ? L"transfers_col%d_width" : L"cloud_col%d_width"), col)))
|
|
return;
|
|
|
|
global_config->WriteInt(buffer, newWidth);
|
|
}
|
|
}
|
|
|
|
void lock()
|
|
{
|
|
EnterCriticalSection(&cs);
|
|
}
|
|
|
|
void unlock()
|
|
{
|
|
LeaveCriticalSection(&cs);
|
|
}
|
|
|
|
virtual void GetCellText(int row, int col, wchar_t * buf, int buflen)
|
|
{
|
|
if (NULL == buf)
|
|
return;
|
|
|
|
buf[0] = L'\0';
|
|
|
|
lock();
|
|
|
|
if (row < listShadow->GetSize())
|
|
{
|
|
TransferItemShadowShort * t = (TransferItemShadowShort *)listShadow->Get(row);
|
|
if (NULL != t)
|
|
{
|
|
// TODO need to clean this up as needed
|
|
switch (col + 1)
|
|
{
|
|
case 0: /*StringCchCopy(buf, buflen, t->type);*/ break;
|
|
case 1: StringCchCopy(buf, buflen, t->track); break;
|
|
case 2: StringCchCopy(buf, buflen, t->status); break;
|
|
case 3: StringCchCopy(buf, buflen, t->lastChanged); break;
|
|
case 4: StringCchCopy(buf, buflen, t->sourceDevice); break;
|
|
case 5: StringCchCopy(buf, buflen, t->destDevice); break;
|
|
case 6: StringCchCopy(buf, buflen, t->sourceFile); break;
|
|
case 7: StringCchCopy(buf, buflen, t->clientType); break;
|
|
}
|
|
}
|
|
}
|
|
unlock();
|
|
}
|
|
|
|
void PushPopItem(CopyInst *c)
|
|
{
|
|
lock();
|
|
int size = listShadow->GetSize();
|
|
for (int i=0; i<size; i++)
|
|
{
|
|
TransferItemShadowShort * t = (TransferItemShadowShort *)listShadow->Get(i);
|
|
if (c == t->c)
|
|
{
|
|
t->changed=true;
|
|
listShadow->Del(i);
|
|
listShadow->Add(t);
|
|
if (listTransfers)
|
|
{
|
|
HWND hwnd = listTransfers->listview.getwnd();
|
|
PostMessage(hwnd, LVM_REDRAWITEMS, i, size);
|
|
}
|
|
unlock();
|
|
return;
|
|
}
|
|
}
|
|
unlock();
|
|
}
|
|
|
|
void ItemUpdate(CopyInst * c)
|
|
{
|
|
lock();
|
|
int size = listShadow->GetSize();
|
|
for (int i=0; i<size; i++)
|
|
{
|
|
TransferItemShadowShort * t = (TransferItemShadowShort *)listShadow->Get(i);
|
|
if (c == t->c)
|
|
{
|
|
TransferItemShadowShort * n = new TransferItemShadowShort(c);
|
|
n->changed=true;
|
|
listShadow->Set(i,n);
|
|
delete t;
|
|
if (listTransfers)
|
|
{
|
|
HWND hwnd = listTransfers->listview.getwnd();
|
|
PostMessage(hwnd,LVM_REDRAWITEMS,i,i);
|
|
}
|
|
unlock();
|
|
return;
|
|
}
|
|
}
|
|
unlock();
|
|
}
|
|
|
|
void FullUpdate()
|
|
{
|
|
C_ItemList * newListShadow = getTransferListShadow();
|
|
if (newListShadow)
|
|
{
|
|
int newSize = newListShadow->GetSize();
|
|
lock();
|
|
oldSize = listShadow->GetSize();
|
|
for (int i = 0; i < newSize; i++)
|
|
{
|
|
TransferItemShadowShort * newt = (TransferItemShadowShort *)newListShadow->Get(i);
|
|
TransferItemShadowShort * oldt = i < oldSize ? (TransferItemShadowShort *)listShadow->Get(i) : NULL;
|
|
newt->changed = !newt->Equals(oldt);
|
|
}
|
|
|
|
C_ItemList * oldListShadow = listShadow;
|
|
listShadow = newListShadow;
|
|
for (int i = 0; i < oldListShadow->GetSize(); i++) delete(TransferItemShadowShort *)oldListShadow->Get(i);
|
|
delete oldListShadow;
|
|
if (listTransfers)
|
|
{
|
|
HWND hwnd = listTransfers->listview.getwnd();
|
|
if (newSize != oldSize) PostMessage(hwnd,LVM_SETITEMCOUNT,newSize, 0);
|
|
for (int i=0; i<newSize; i++)
|
|
{
|
|
TransferItemShadowShort * t = (TransferItemShadowShort *)listShadow->Get(i);
|
|
if (t->changed) PostMessage(hwnd,LVM_REDRAWITEMS,i,i);
|
|
}
|
|
}
|
|
unlock();
|
|
}
|
|
}
|
|
|
|
virtual songid_t GetTrack(int pos) { return 0; }
|
|
|
|
private:
|
|
CRITICAL_SECTION cs;
|
|
C_ItemList * listShadow;
|
|
int oldSize;
|
|
};
|
|
|
|
static TransferContents transferListContents;
|
|
|
|
static void updateStatus(HWND hwnd)
|
|
{
|
|
HWND statusWindow = GetDlgItem(hwnd, IDC_STATUS);
|
|
if (NULL == statusWindow)
|
|
return;
|
|
|
|
int txProgress = getTransferProgress(device);
|
|
LinkedQueue * txQueue = getTransferQueue(device);
|
|
LinkedQueue * finishedTX = getFinishedTransferQueue(device);
|
|
int size = (txQueue ? txQueue->GetSize() : 0);
|
|
if (size > 0)
|
|
{
|
|
wchar_t buffer[256] = {0}, format[256] = {0};
|
|
int pcnum, time, pc, total;
|
|
|
|
pcnum = (size * 100) - txProgress;
|
|
total = size * 100;
|
|
total += 100 * (finishedTX ? finishedTX->GetSize() : 0);
|
|
|
|
time = (int)(device->transferRate * (((double)pcnum)/100.0));
|
|
pc = ((total-pcnum)*100)/total;
|
|
|
|
WASABI_API_LNGSTRINGW_BUF((time > 0 ? IDS_TRANFERS_PERCENT_REMAINING : IDS_TRANFERS_PERCENT_REMAINING_NOT_TIME), format, ARRAYSIZE(format));
|
|
if (SUCCEEDED(StringCchPrintf(buffer, ARRAYSIZE(buffer), format, size, pc, time/60, time%60)))
|
|
{
|
|
if (0 == SendMessage(statusWindow, WM_GETTEXT, (WPARAM)ARRAYSIZE(format), (LPARAM)format) ||
|
|
CSTR_EQUAL != CompareString(LOCALE_USER_DEFAULT, 0, format, -1, buffer, -1))
|
|
{
|
|
SendMessage(statusWindow, WM_SETTEXT, 0, (LPARAM)buffer);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int length = (int)SendMessage(statusWindow, WM_GETTEXTLENGTH, 0, 0L);
|
|
if (0 != length)
|
|
SendMessage(statusWindow, WM_SETTEXT, 0, 0L);
|
|
}
|
|
}
|
|
|
|
void TransfersListUpdateItem(CopyInst * item, DeviceView *view)
|
|
{
|
|
if (view == device)
|
|
transferListContents.ItemUpdate(item);
|
|
}
|
|
|
|
void TransfersListPushPopItem(CopyInst * item, DeviceView *view)
|
|
{
|
|
if (view == device)
|
|
transferListContents.PushPopItem(item);
|
|
}
|
|
|
|
static bool AddSelectedItems(C_ItemList *items, W_ListView *listview, LinkedQueue *transfer_queue, int &row, DeviceView *&dev)
|
|
{
|
|
transfer_queue->lock();
|
|
int l = transfer_queue->GetSize();
|
|
for (int j=0; j<l; j++)
|
|
{
|
|
if (listview->GetSelected(row++))
|
|
{
|
|
CopyInst * c = (CopyInst *)transfer_queue->Get(j);
|
|
if (c->songid)
|
|
{
|
|
if (!dev && c->dev)
|
|
dev = c->dev;
|
|
if (dev)
|
|
{
|
|
if (c->dev != dev)
|
|
{
|
|
transfer_queue->unlock();
|
|
return false;
|
|
}
|
|
else
|
|
items->Add((void*)c->songid);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
transfer_queue->unlock();
|
|
return true;
|
|
}
|
|
|
|
static void RemoveSelectedItems(DeviceView *device, W_ListView *listview, LinkedQueue *transfer_queue, int &row, bool finished_queue)
|
|
{
|
|
transfer_queue->lock();
|
|
int j = transfer_queue->GetSize();
|
|
while (j-- > 0)
|
|
{
|
|
if (listview->GetSelected(--row))
|
|
{
|
|
if (j == 0 && !finished_queue)
|
|
{
|
|
CopyInst * d = (CopyInst *)transfer_queue->Get(j);
|
|
if (d && (d->status == STATUS_WAITING || d->status == STATUS_CANCELLED) && device->transferContext.IsPaused())
|
|
{
|
|
transfer_queue->Del(j);
|
|
d->Cancelled();
|
|
delete d;
|
|
} // otherwise don't bother
|
|
}
|
|
else
|
|
{
|
|
CopyInst * d = (CopyInst*)transfer_queue->Del(j);
|
|
if (d)
|
|
{
|
|
if ((d->status == STATUS_WAITING || d->status == STATUS_CANCELLED) && !finished_queue)
|
|
d->Cancelled();
|
|
delete d;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
transfer_queue->unlock();
|
|
}
|
|
|
|
static void CancelSelectedItems(DeviceView *device, W_ListView *listview, LinkedQueue *transfer_queue, int &row)
|
|
{
|
|
transfer_queue->lock();
|
|
int j = transfer_queue->GetSize();
|
|
int sel = listview->GetSelectedCount();
|
|
|
|
for (int i = 0, q = 0; i <= j; i++)
|
|
{
|
|
if (listview->GetSelected(i) || !sel)
|
|
{
|
|
CopyInst * d = (CopyInst *)transfer_queue->Get(q);
|
|
if (d && d->status == STATUS_WAITING)
|
|
{
|
|
transfer_queue->Del(q);
|
|
d->Cancelled();
|
|
delete d;
|
|
}
|
|
else if (d && d->status == STATUS_TRANSFERRING)
|
|
{
|
|
d->Cancelled();
|
|
}
|
|
else
|
|
{
|
|
q++;
|
|
}
|
|
}
|
|
}
|
|
|
|
transfer_queue->unlock();
|
|
}
|
|
|
|
static void RetrySelectedItems(DeviceView *device, W_ListView *listview, LinkedQueue *transfer_queue, LinkedQueue *finished_transfer_queue, int &row)
|
|
{
|
|
transfer_queue->lock();
|
|
finished_transfer_queue->lock();
|
|
int j = finished_transfer_queue->GetSize();
|
|
int sel = listview->GetSelectedCount();
|
|
|
|
LinkedQueue retryTransferQueue;
|
|
int i = 0;
|
|
for (int q = 0; i <= j; i++)
|
|
{
|
|
if (listview->GetSelected(i) || !sel)
|
|
{
|
|
CopyInst * d = (CopyInst *)finished_transfer_queue->Get(q);
|
|
if (d && (d->status == STATUS_DONE || d->status == STATUS_CANCELLED || d->status == STATUS_ERROR))
|
|
{
|
|
// due to STATUS_DONE being applied in most cases, have to look at the
|
|
// status message and use as the basis on how to proceed with the item
|
|
if (lstrcmpi(d->statusCaption, WASABI_API_LNGSTRINGW(IDS_UPLOADED)))
|
|
{
|
|
retryTransferQueue.Offer(d);
|
|
finished_transfer_queue->Del(q);
|
|
}
|
|
else
|
|
{
|
|
q++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
q++;
|
|
}
|
|
}
|
|
}
|
|
|
|
i = 0;
|
|
for (; i <= retryTransferQueue.GetSize(); i++)
|
|
{
|
|
CopyInst * d = (CopyInst *)retryTransferQueue.Get(i);
|
|
if (d)
|
|
{
|
|
WASABI_API_LNGSTRINGW_BUF(IDS_WAITING, d->statusCaption, sizeof(d->statusCaption)/sizeof(wchar_t));
|
|
|
|
SYSTEMTIME system_time;
|
|
GetLocalTime(&system_time);
|
|
GetTimeFormat(LOCALE_INVARIANT, NULL, &system_time, NULL, d->lastChanged, sizeof(d->lastChanged)/sizeof(wchar_t));
|
|
|
|
d->dev->AddTrackToTransferQueue(d);
|
|
}
|
|
}
|
|
|
|
transfer_queue->unlock();
|
|
finished_transfer_queue->unlock();
|
|
}
|
|
|
|
typedef struct _LAYOUT
|
|
{
|
|
INT id;
|
|
HWND hwnd;
|
|
INT x;
|
|
INT y;
|
|
INT cx;
|
|
INT cy;
|
|
DWORD flags;
|
|
HRGN rgn;
|
|
}
|
|
LAYOUT, PLAYOUT;
|
|
|
|
#define SETLAYOUTPOS(_layout, _x, _y, _cx, _cy) { _layout->x=_x; _layout->y=_y;_layout->cx=_cx;_layout->cy=_cy;_layout->rgn=NULL; }
|
|
#define SETLAYOUTFLAGS(_layout, _r) \
|
|
{ \
|
|
BOOL fVis; \
|
|
fVis = (WS_VISIBLE & (LONG)GetWindowLongPtr(_layout->hwnd, GWL_STYLE)); \
|
|
if (_layout->x == _r.left && _layout->y == _r.top) _layout->flags |= SWP_NOMOVE; \
|
|
if (_layout->cx == (_r.right - _r.left) && _layout->cy == (_r.bottom - _r.top)) _layout->flags |= SWP_NOSIZE; \
|
|
if ((SWP_HIDEWINDOW & _layout->flags) && !fVis) _layout->flags &= ~SWP_HIDEWINDOW; \
|
|
if ((SWP_SHOWWINDOW & _layout->flags) && fVis) _layout->flags &= ~SWP_SHOWWINDOW; \
|
|
}
|
|
|
|
#define LAYOUTNEEEDUPDATE(_layout) ((SWP_NOMOVE | SWP_NOSIZE) != ((SWP_NOMOVE | SWP_NOSIZE | SWP_HIDEWINDOW | SWP_SHOWWINDOW) & _layout->flags))
|
|
|
|
#define GROUP_MIN 0x1
|
|
#define GROUP_MAX 0x2
|
|
#define GROUP_STATUSBAR 0x1
|
|
#define GROUP_MAIN 0x2
|
|
|
|
/*
|
|
IDC_BUTTON_PAUSETRANSFERS,
|
|
IDC_BUTTONCANCELSELECTED,
|
|
IDC_BUTTON_CLEARFINISHED,
|
|
IDC_BUTTON_REMOVESELECTED,
|
|
IDC_BUTTON_RETRYSELECTED,
|
|
IDC_STATUS,
|
|
IDC_LIST_TRANSFERS,
|
|
*/
|
|
|
|
static void TransferView_UpdateLayout(HWND hwnd, BOOL fRedraw, BOOL fUpdateAll = FALSE)
|
|
{
|
|
static INT controls[] =
|
|
{
|
|
GROUP_STATUSBAR, IDC_BUTTON_PAUSETRANSFERS, IDC_BUTTON_CLEARFINISHED, IDC_BUTTON_REMOVESELECTED, IDC_BUTTON_RETRYSELECTED, IDC_STATUS,
|
|
GROUP_MAIN, IDC_LIST_TRANSFERS
|
|
};
|
|
|
|
INT index;
|
|
RECT rc, rg, ri;
|
|
LAYOUT layout[sizeof(controls)/sizeof(controls[0])], *pl;
|
|
BOOL skipgroup;
|
|
HRGN rgn = NULL;
|
|
|
|
GetClientRect(hwnd, &rc);
|
|
if (rc.bottom == rc.top || rc.right == rc.left) return;
|
|
|
|
SetRect(&rg, rc.left, rc.top, rc.right, rc.bottom);
|
|
|
|
pl = layout;
|
|
skipgroup = FALSE;
|
|
|
|
InvalidateRect(hwnd, NULL, TRUE);
|
|
|
|
for (index = 0; index < sizeof(controls) / sizeof(*controls); index++)
|
|
{
|
|
if (controls[index] >= GROUP_MIN && controls[index] <= GROUP_MAX) // group id
|
|
{
|
|
skipgroup = FALSE;
|
|
switch (controls[index])
|
|
{
|
|
case GROUP_STATUSBAR:
|
|
{
|
|
wchar_t buffer[128] = {0};
|
|
HWND ctrl = GetDlgItem(hwnd, IDC_BUTTON_PAUSETRANSFERS);
|
|
GetWindowTextW(ctrl, buffer, ARRAYSIZE(buffer));
|
|
LRESULT idealSize = MLSkinnedButton_GetIdealSize(ctrl, buffer);
|
|
|
|
SetRect(&rg, rc.left + WASABI_API_APP->getScaleX(1),
|
|
rc.bottom - WASABI_API_APP->getScaleY(HIWORD(idealSize)),
|
|
rc.right, rc.bottom);
|
|
rc.bottom = rg.top - WASABI_API_APP->getScaleY(3);
|
|
}
|
|
break;
|
|
case GROUP_MAIN:
|
|
SetRect(&rg, rc.left + WASABI_API_APP->getScaleX(1), rc.top, rc.right, rc.bottom);
|
|
break;
|
|
}
|
|
continue;
|
|
}
|
|
if (skipgroup) continue;
|
|
|
|
pl->id = controls[index];
|
|
pl->hwnd = GetDlgItem(hwnd, pl->id);
|
|
if (!pl->hwnd) continue;
|
|
|
|
GetWindowRect(pl->hwnd, &ri);
|
|
MapWindowPoints(HWND_DESKTOP, hwnd, (LPPOINT)&ri, 2);
|
|
pl->flags = SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOCOPYBITS;
|
|
|
|
switch (pl->id)
|
|
{
|
|
case IDC_BUTTON_PAUSETRANSFERS:
|
|
case IDC_BUTTON_CLEARFINISHED:
|
|
case IDC_BUTTON_REMOVESELECTED:
|
|
case IDC_BUTTON_RETRYSELECTED:
|
|
{
|
|
wchar_t buffer[128] = {0};
|
|
GetWindowTextW(pl->hwnd, buffer, ARRAYSIZE(buffer));
|
|
LRESULT idealSize = MLSkinnedButton_GetIdealSize(pl->hwnd, buffer);
|
|
LONG width = LOWORD(idealSize) + WASABI_API_APP->getScaleX(6);
|
|
SETLAYOUTPOS(pl, rg.left, rg.bottom - WASABI_API_APP->getScaleY(HIWORD(idealSize)),
|
|
width, WASABI_API_APP->getScaleY(HIWORD(idealSize)));
|
|
pl->flags |= ((rg.right - rg.left) > width) ? SWP_SHOWWINDOW : SWP_HIDEWINDOW;
|
|
if (SWP_SHOWWINDOW & pl->flags) rg.left += (pl->cx + WASABI_API_APP->getScaleX(4));
|
|
break;
|
|
}
|
|
case IDC_STATUS:
|
|
SETLAYOUTPOS(pl, rg.left, rg.top, rg.right - rg.left, (rg.bottom - rg.top));
|
|
pl->flags |= (pl->cx > WASABI_API_APP->getScaleX(16)) ? SWP_SHOWWINDOW : SWP_HIDEWINDOW;
|
|
break;
|
|
case IDC_LIST_TRANSFERS:
|
|
SETLAYOUTPOS(pl, rg.left, rg.top + 1, (rg.right - rg.left) - WASABI_API_APP->getScaleX(2), (rg.bottom - rg.top) - WASABI_API_APP->getScaleY(1));
|
|
break;
|
|
}
|
|
|
|
SETLAYOUTFLAGS(pl, ri);
|
|
if (LAYOUTNEEEDUPDATE(pl))
|
|
{
|
|
if (SWP_NOSIZE == ((SWP_HIDEWINDOW | SWP_SHOWWINDOW | SWP_NOSIZE) & pl->flags) &&
|
|
ri.left == (pl->x + offsetX) && ri.top == (pl->y + offsetY) && !fUpdateAll && IsWindowVisible(pl->hwnd))
|
|
{
|
|
SetRect(&ri, pl->x, pl->y, pl->cx + pl->x, pl->y + pl->cy);
|
|
ValidateRect(hwnd, &ri);
|
|
}
|
|
|
|
pl++;
|
|
}
|
|
else if (!fUpdateAll && (fRedraw || (!offsetX && !offsetY)) && IsWindowVisible(pl->hwnd))
|
|
{
|
|
ValidateRect(hwnd, &ri);
|
|
if (GetUpdateRect(pl->hwnd, NULL, FALSE))
|
|
{
|
|
if (!rgn) rgn = CreateRectRgn(0,0,0,0);
|
|
GetUpdateRgn(pl->hwnd, rgn, FALSE);
|
|
OffsetRgn(rgn, pl->x, pl->y);
|
|
InvalidateRgn(hwnd, rgn, FALSE);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (pl != layout)
|
|
{
|
|
LAYOUT *pc;
|
|
HDWP hdwp = BeginDeferWindowPos((INT)(pl - layout));
|
|
for (pc = layout; pc < pl && hdwp; pc++)
|
|
{
|
|
hdwp = DeferWindowPos(hdwp, pc->hwnd, NULL, pc->x, pc->y, pc->cx, pc->cy, pc->flags);
|
|
}
|
|
if (hdwp) EndDeferWindowPos(hdwp);
|
|
|
|
if (!rgn) rgn = CreateRectRgn(0, 0, 0, 0);
|
|
|
|
if (fRedraw)
|
|
{
|
|
GetUpdateRgn(hwnd, rgn, FALSE);
|
|
for (pc = layout; pc < pl && hdwp; pc++)
|
|
{
|
|
if (pc->rgn)
|
|
{
|
|
OffsetRgn(pc->rgn, pc->x, pc->y);
|
|
CombineRgn(rgn, rgn, pc->rgn, RGN_OR);
|
|
}
|
|
}
|
|
RedrawWindow(hwnd, NULL, rgn, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASENOW | RDW_ALLCHILDREN);
|
|
}
|
|
|
|
if (g_rgnUpdate)
|
|
{
|
|
GetUpdateRgn(hwnd, g_rgnUpdate, FALSE);
|
|
for (pc = layout; pc < pl && hdwp; pc++)
|
|
{
|
|
if (pc->rgn)
|
|
{
|
|
OffsetRgn(pc->rgn, pc->x, pc->y);
|
|
CombineRgn(g_rgnUpdate, g_rgnUpdate, pc->rgn, RGN_OR);
|
|
}
|
|
}
|
|
}
|
|
|
|
for (pc = layout; pc < pl && hdwp; pc++)
|
|
if (pc->rgn) DeleteObject(pc->rgn);
|
|
}
|
|
if (rgn) DeleteObject(rgn);
|
|
ValidateRgn(hwnd, NULL);
|
|
}
|
|
|
|
static void
|
|
TransferView_UpdateFont(HWND hwnd, BOOL redraw)
|
|
{
|
|
TransferView *self;
|
|
HWND elementWindow;
|
|
HDWP hdwp;
|
|
|
|
const int buttonList[] =
|
|
{
|
|
IDC_BUTTON_PAUSETRANSFERS,
|
|
IDC_BUTTONCANCELSELECTED,
|
|
IDC_BUTTON_CLEARFINISHED,
|
|
IDC_BUTTON_REMOVESELECTED,
|
|
IDC_BUTTON_RETRYSELECTED
|
|
};
|
|
|
|
TRANSFERVIEW_RET_VOID(self, hwnd);
|
|
|
|
if (FALSE == Graphics_GetWindowBaseUnits(hwnd, &self->unitSize.cx, &self->unitSize.cy))
|
|
{
|
|
self->unitSize.cx = 6;
|
|
self->unitSize.cy = 13;
|
|
}
|
|
|
|
elementWindow = GetDlgItem(hwnd, IDC_LIST_TRANSFERS);
|
|
if (NULL != elementWindow)
|
|
{
|
|
elementWindow = (HWND)SendMessage(elementWindow, LVM_GETHEADER, 0, 0L);
|
|
if (NULL != elementWindow)
|
|
MLSkinnedHeader_SetHeight(elementWindow, -1);
|
|
}
|
|
|
|
hdwp = BeginDeferWindowPos(ARRAYSIZE(buttonList) + 1);
|
|
if (NULL != hdwp)
|
|
{
|
|
LRESULT idealSize;
|
|
SIZE buttonSize;
|
|
|
|
elementWindow = GetDlgItem(hwnd, IDC_STATUS);
|
|
if (NULL != elementWindow)
|
|
{
|
|
hdwp = DeferWindowPos(hdwp, elementWindow, NULL, 0, 0, 100, self->unitSize.cy,
|
|
SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE | SWP_NOREDRAW);
|
|
}
|
|
|
|
for(size_t index = 0; index < ARRAYSIZE(buttonList) && NULL != hdwp; index++)
|
|
{
|
|
elementWindow = GetDlgItem(hwnd, buttonList[index]);
|
|
if (NULL == elementWindow)
|
|
continue;
|
|
|
|
if (IDC_BUTTON_PAUSETRANSFERS == buttonList[index])
|
|
{
|
|
wchar_t buffer[128] = {0};
|
|
|
|
WASABI_API_LNGSTRINGW_BUF(IDS_RESUME, buffer, ARRAYSIZE(buffer));
|
|
idealSize = MLSkinnedButton_GetIdealSize(elementWindow, buffer);
|
|
buttonSize.cx = LOWORD(idealSize);
|
|
buttonSize.cy = HIWORD(idealSize);
|
|
|
|
WASABI_API_LNGSTRINGW_BUF(IDS_PAUSE, buffer, ARRAYSIZE(buffer));
|
|
idealSize = MLSkinnedButton_GetIdealSize(elementWindow, buffer);
|
|
|
|
if (buttonSize.cx < LOWORD(idealSize))
|
|
buttonSize.cx = LOWORD(idealSize);
|
|
|
|
if (buttonSize.cy < HIWORD(idealSize))
|
|
buttonSize.cy = HIWORD(idealSize);
|
|
}
|
|
else
|
|
{
|
|
idealSize = MLSkinnedButton_GetIdealSize(elementWindow, NULL);
|
|
buttonSize.cx = LOWORD(idealSize);
|
|
buttonSize.cy = HIWORD(idealSize);
|
|
}
|
|
|
|
hdwp = DeferWindowPos(hdwp, elementWindow, NULL, 0, 0, buttonSize.cx, buttonSize.cy,
|
|
SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE | SWP_NOREDRAW);
|
|
}
|
|
|
|
if (NULL != hdwp)
|
|
EndDeferWindowPos(hdwp);
|
|
}
|
|
|
|
TransferView_UpdateLayout(hwnd, redraw);
|
|
}
|
|
|
|
static int
|
|
TransferView_OnInitDialog(HWND hwnd, HWND focusWindow, LPARAM param)
|
|
{
|
|
HWND controlWindow;
|
|
|
|
const int skinList[] =
|
|
{
|
|
IDC_BUTTON_PAUSETRANSFERS,
|
|
IDC_BUTTONCANCELSELECTED,
|
|
IDC_BUTTON_CLEARFINISHED,
|
|
IDC_BUTTON_REMOVESELECTED,
|
|
IDC_BUTTON_RETRYSELECTED,
|
|
IDC_STATUS,
|
|
};
|
|
|
|
TransferView *self = (TransferView*)calloc(1, sizeof(TransferView));
|
|
if (NULL != self)
|
|
{
|
|
if (FALSE == SetViewData(hwnd, self))
|
|
{
|
|
free(self);
|
|
self = NULL;
|
|
}
|
|
}
|
|
|
|
if (NULL == self)
|
|
{
|
|
DestroyWindow(hwnd);
|
|
return 0;
|
|
}
|
|
|
|
device = (DeviceView *)param;
|
|
|
|
transferListContents.Init();
|
|
transferListContents.lock();
|
|
|
|
transferListContents.FullUpdate();
|
|
|
|
listTransfers = new SkinnedListView(&transferListContents,IDC_LIST_TRANSFERS,plugin.hwndLibraryParent, hwnd);
|
|
listTransfers->DialogProc(hwnd,WM_INITDIALOG, (WPARAM)focusWindow, param);
|
|
|
|
transferListContents.unlock();
|
|
SetDlgItemText(hwnd,IDC_BUTTON_PAUSETRANSFERS,
|
|
WASABI_API_LNGSTRINGW((device->transferContext.IsPaused()?IDS_RESUME:IDS_PAUSE)));
|
|
|
|
MLSkinWindow2(plugin.hwndLibraryParent, hwnd, SKINNEDWND_TYPE_DIALOG,
|
|
SWS_USESKINFONT | SWS_USESKINCOLORS | SWS_USESKINCURSORS);
|
|
|
|
for(size_t index = 0; index < ARRAYSIZE(skinList); index++)
|
|
{
|
|
controlWindow = GetDlgItem(hwnd, skinList[index]);
|
|
if (NULL != controlWindow)
|
|
{
|
|
MLSkinWindow2(plugin.hwndLibraryParent, controlWindow,
|
|
(skinList[index] != IDC_STATUS ? SKINNEDWND_TYPE_BUTTON : SKINNEDWND_TYPE_STATIC),
|
|
SWS_USESKINFONT | SWS_USESKINCOLORS | SWS_USESKINCURSORS);
|
|
}
|
|
}
|
|
|
|
TransferView_UpdateFont(hwnd, FALSE);
|
|
|
|
SetTimer(hwnd,1,500,NULL);
|
|
updateStatus(hwnd);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void
|
|
TransferView_OnDestroy(HWND hwnd)
|
|
{
|
|
TransferView *self;
|
|
|
|
self = (TransferView *)RemoveViewData(hwnd);
|
|
if (NULL == self)
|
|
return;
|
|
|
|
KillTimer(hwnd, 1);
|
|
device = 0;
|
|
|
|
SkinnedListView * lt = listTransfers;
|
|
if (NULL != lt)
|
|
{
|
|
transferListContents.lock();
|
|
listTransfers=NULL;
|
|
transferListContents.unlock();
|
|
delete lt;
|
|
}
|
|
|
|
free(self);
|
|
}
|
|
|
|
static void
|
|
TransferView_OnWindowPosChanged(HWND hwnd, WINDOWPOS *windowPos)
|
|
{
|
|
if (NULL == windowPos)
|
|
return;
|
|
|
|
if (SWP_NOSIZE != ((SWP_NOSIZE | SWP_FRAMECHANGED) & windowPos->flags))
|
|
{
|
|
TransferView_UpdateLayout(hwnd, 0 == (SWP_NOREDRAW & windowPos->flags));
|
|
}
|
|
}
|
|
|
|
static void
|
|
TransferView_OnDisplayChanged(HWND hwnd, INT bpp, INT dpi_x, INT dpi_y)
|
|
{
|
|
UpdateWindow(hwnd);
|
|
TransferView_UpdateFont(hwnd, TRUE);
|
|
}
|
|
|
|
static void
|
|
TransferView_OnSetFont(HWND hwnd, HFONT font, BOOL redraw)
|
|
{
|
|
TransferView *self;
|
|
TRANSFERVIEW_RET_VOID(self, hwnd);
|
|
|
|
self->font = font;
|
|
}
|
|
|
|
static HFONT
|
|
TransferView_OnGetFont(HWND hwnd)
|
|
{
|
|
TransferView *self;
|
|
TRANSFERVIEW_RET_VAL(self, hwnd, NULL);
|
|
|
|
return self->font;
|
|
}
|
|
|
|
static void
|
|
TransferView_OnSetUpdateRegion(HWND hwnd, HRGN updateRegion, POINTS regionOffset)
|
|
{
|
|
TransferView *self;
|
|
TRANSFERVIEW_RET_VOID(self, hwnd);
|
|
|
|
self->updateRegion = updateRegion;
|
|
self->updateOffset.x = regionOffset.x;
|
|
self->updateOffset.y = regionOffset.y;
|
|
}
|
|
|
|
INT_PTR CALLBACK pmp_queue_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
|
|
{
|
|
if (NULL != listTransfers)
|
|
{
|
|
INT_PTR processed = listTransfers->DialogProc(hwndDlg,uMsg,wParam,lParam);
|
|
if (0 != processed)
|
|
return processed;
|
|
}
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_INITDIALOG: return TransferView_OnInitDialog(hwndDlg, (HWND)wParam, lParam);
|
|
case WM_DESTROY: TransferView_OnDestroy(hwndDlg); break;
|
|
case WM_WINDOWPOSCHANGED: TransferView_OnWindowPosChanged(hwndDlg, (WINDOWPOS*)lParam); return TRUE;
|
|
case WM_DISPLAYCHANGE: TransferView_OnDisplayChanged(hwndDlg, (INT)wParam, LOWORD(lParam), HIWORD(lParam)); return TRUE;
|
|
case WM_GETFONT: DIALOG_RESULT(hwndDlg, TransferView_OnGetFont(hwndDlg));
|
|
case WM_SETFONT: TransferView_OnSetFont(hwndDlg, (HFONT)wParam, LOWORD(lParam)); return TRUE;
|
|
case WM_TIMER:
|
|
if (wParam == 1)
|
|
{
|
|
updateStatus(hwndDlg);
|
|
/*if (device_update_map[device] == true)
|
|
{
|
|
device_update_map[device] = false;*/
|
|
transferListContents.FullUpdate();
|
|
/*}*/
|
|
}
|
|
break;
|
|
case WM_NOTIFY:
|
|
{
|
|
LPNMHDR l=(LPNMHDR)lParam;
|
|
if (l->idFrom==IDC_LIST_TRANSFERS)
|
|
{
|
|
switch (l->code)
|
|
{
|
|
case NM_RETURN: // enter!
|
|
//case NM_RCLICK: // right click!
|
|
case LVN_KEYDOWN:
|
|
{
|
|
int row = 0;
|
|
C_ItemList items;
|
|
if (!AddSelectedItems(&items, &listTransfers->listview, getTransferQueue(device), row, device))
|
|
return 0;
|
|
if (!AddSelectedItems(&items, &listTransfers->listview, getFinishedTransferQueue(device), row, device))
|
|
return 0;
|
|
|
|
if (items.GetSize())
|
|
{
|
|
// TODO need to check the handling of this...
|
|
/*if (l->code == NM_RCLICK)
|
|
{
|
|
LPNMITEMACTIVATE lva=(LPNMITEMACTIVATE)lParam;
|
|
handleContextMenuResult(showContextMenu(7,l->hwndFrom,device->dev,lva->ptAction),&items,device);
|
|
}
|
|
else*/ if (l->code == NM_RETURN)
|
|
{
|
|
handleContextMenuResult((!GetAsyncKeyState(VK_SHIFT)?ID_TRACKSLIST_PLAYSELECTION:ID_TRACKSLIST_ENQUEUESELECTION),&items,device);
|
|
}
|
|
else if (l->code == LVN_KEYDOWN)
|
|
{
|
|
switch (((LPNMLVKEYDOWN)lParam)->wVKey)
|
|
{
|
|
case VK_DELETE:
|
|
{
|
|
if (!(GetAsyncKeyState(VK_CONTROL)&0x8000) && !(GetAsyncKeyState(VK_SHIFT)&0x8000))
|
|
{
|
|
handleContextMenuResult(ID_TRACKSLIST_DELETE,&items,device);
|
|
}
|
|
}
|
|
break;
|
|
case 0x45: //E
|
|
if ((GetAsyncKeyState(VK_CONTROL)&0x8000) && !(GetAsyncKeyState(VK_SHIFT)&0x8000))
|
|
{
|
|
handleContextMenuResult(ID_TRACKSLIST_EDITSELECTEDITEMS,&items,device);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case IDC_BUTTON_CLEARFINISHED:
|
|
{
|
|
LinkedQueue * finishedTX = getFinishedTransferQueue(device);
|
|
if (finishedTX)
|
|
{
|
|
finishedTX->lock();
|
|
int j=finishedTX->GetSize();
|
|
while (j-- > 0) delete(CopyInst*)finishedTX->Del(j);
|
|
finishedTX->unlock();
|
|
}
|
|
transferListContents.FullUpdate();
|
|
}
|
|
break;
|
|
case IDC_BUTTON_REMOVESELECTED:
|
|
{
|
|
int row = transferListContents.GetNumRows();
|
|
RemoveSelectedItems(device, &listTransfers->listview, getTransferQueue(device), row, false);
|
|
RemoveSelectedItems(device, &listTransfers->listview, getFinishedTransferQueue(device), row, true);
|
|
transferListContents.FullUpdate();
|
|
}
|
|
break;
|
|
case IDC_BUTTON_PAUSETRANSFERS:
|
|
{
|
|
if (false != device->transferContext.IsPaused())
|
|
device->transferContext.Resume();
|
|
else
|
|
device->transferContext.Pause();
|
|
|
|
SetDlgItemText(hwndDlg,IDC_BUTTON_PAUSETRANSFERS,WASABI_API_LNGSTRINGW((device->transferContext.IsPaused()?IDS_RESUME:IDS_PAUSE)));
|
|
TransferView_UpdateLayout(hwndDlg, TRUE);
|
|
}
|
|
break;
|
|
case IDC_BUTTONCANCELSELECTED:
|
|
{
|
|
int row = transferListContents.GetNumRows();
|
|
CancelSelectedItems(device, &listTransfers->listview, &cloudTransferQueue, row);
|
|
transferListContents.FullUpdate();
|
|
}
|
|
break;
|
|
case IDC_BUTTON_RETRYSELECTED:
|
|
{
|
|
int row = transferListContents.GetNumRows();
|
|
RetrySelectedItems(device, &listTransfers->listview, &cloudTransferQueue, &cloudFinishedTransfers, row);
|
|
transferListContents.FullUpdate();
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
// gen_ml flickerless drawing
|
|
case WM_USER + 0x200: DIALOG_RESULT(hwndDlg, 1);
|
|
case WM_USER + 0x201: TransferView_OnSetUpdateRegion(hwndDlg, (HRGN)lParam, MAKEPOINTS(wParam)); return TRUE;
|
|
}
|
|
|
|
return 0;
|
|
} |