aboutsummaryrefslogtreecommitdiff
path: root/Src/Plugins/Library/ml_pmp/DeviceView.h
blob: a930834ed7a278dea4d8bf81c967c2e829e5592f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
#ifndef __DEVICEVIEW_H_
#define __DEVICEVIEW_H_

//#define _WIN32_WINNT 0x0400

#include <windows.h>
#include <windowsx.h>
#include <stdio.h>
#include <shlobj.h>
#include <shellapi.h>
#include "..\..\General\gen_ml/ml.h"
#include "..\..\General\gen_ml/itemlist.h"
#include "..\..\General\gen_ml/childwnd.h"
#include "../winamp/wa_ipc.h"
#include "../winamp/ipc_pe.h"
#include "LinkedQueue.h"
#include "pmp.h"
#include "resource1.h"
#include "config.h"
#include "transfer_thread.h"
#include "api__ml_pmp.h"
#include "..\..\General\gen_ml/ml_ipc_0313.h"

#include <bfc/platform/types.h>
#include "../devices/ifc_device.h"
#include "../devices/ifc_deviceactivity.h"
#include "pmp.h"
#include <bfc/multipatch.h>
#include <vector>

#define COMMITTIMERID 0x2345

extern C_Config * gen_mlconfig;
extern LinkedQueue cloudTransferQueue, cloudFinishedTransfers;
extern int cloudTransferProgress;
extern winampMediaLibraryPlugin plugin;

wchar_t *guessTitles(const wchar_t *filename, int *tracknum,wchar_t **artist, wchar_t **album,wchar_t **title); // free result after using artist, etc
wchar_t* GetDefaultSaveToFolder(wchar_t* path_to_store);

#define AVERAGEBASIS 3
class TransferContext
{
public:
	TransferContext() : dev(0), transfer_thread(NULL)
	{
		numTransfers=0;
		start=0; 
		end=0;
		InitializeCriticalSection(&transfer_lock);
		killer = CreateEvent(NULL, TRUE, FALSE, 0);
		notifier = CreateEvent(NULL, FALSE, FALSE, 0);
		paused = 0;
		ZeroMemory(&times,sizeof(times));
	}

	~TransferContext()
	{
		DeleteCriticalSection(&transfer_lock);
		CloseHandle(killer);
		CloseHandle(notifier);
	}

	void WaitForKill()
	{
		SetEvent(notifier);
		WaitForSingleObject(killer, INFINITE);
	}
	void DoOneTransfer(HANDLE handle);
	bool IsPaused();
	void Pause();
	void Resume();
	
	static bool IsAllPaused();
	static void PauseAll();
	static void ResumeAll();
	
	int numTransfers;
	int times[AVERAGEBASIS];
	time_t start, end;
	DeviceView *dev;
	volatile size_t paused;
	HANDLE killer, notifier;
	CRITICAL_SECTION transfer_lock;
	ThreadID *transfer_thread;

	static volatile size_t paused_all;
};

enum
{
	PATCH_IFC_DEVICE,
	PATCH_IFC_DEVICEACTIVITY,
};

class DeviceView : public MultiPatch<PATCH_IFC_DEVICE, ifc_device>,
	public MultiPatch<PATCH_IFC_DEVICEACTIVITY, ifc_deviceactivity>
{
public://protected:
	HNAVITEM treeItem, videoTreeItem, queueTreeItem;
	int queueActiveIcon;
	int isCloudDevice;
	std::vector<HNAVITEM> playlistTreeItems;
	LinkedQueue finishedTransfers;
	
	HNAVITEM AddPlaylistNode(int id);
	int AddTrackToTransferQueue(DeviceView * device, itemRecordW * item, bool dupeCheck, bool forceDupe=false); // true on success
	int AddTrackToTransferQueue(CopyInst * inst);
public:
	TransferContext transferContext;
	int videoView;
	int SyncConnectionDefault;
	prefsDlgRecW devPrefsPage;
	int currentTransferProgress; // percentage
	double transferRate;
	int threadKillswitch;
	LinkedQueue transferQueue;
	bool commitNeeded;
	C_Config * config;
	Device * dev;
	int metadata_fields;
	DeviceView(Device *dev);

	void SetVideoView(BOOL enabled);
	bool GetTransferFromMlSupported(int dataType);
	intptr_t TransferFromML(int type,void* data, int unsupportedReturn, int supportedReturn, int playlist=0);
	intptr_t TransferFromDrop(HDROP hDrop, int playlist=0);
	intptr_t MessageProc(int message_type, intptr_t param1, intptr_t param2, intptr_t param3);
	void DevicePropertiesChanges();
	int CreatePlaylist(wchar_t * name=NULL, bool silent=false);
	void RenamePlaylist(int id);
	bool DeletePlaylist(int playlistId, bool deleteFiles, bool verbal);
	int AddFileListToTransferQueue(char ** files, int num, int playlist=0);
	int AddFileListToTransferQueue(wchar_t ** files, int num, int playlist=0);
	int AddItemListToTransferQueue(itemRecordListW * items, int playlist=0);
	int AddItemListToTransferQueue(C_ItemList * items, int playlist=0);
	void TransferPlaylist(wchar_t * file, wchar_t * name=NULL); // name=NULL when its from the ML and we must find out ourself...
	int TransferTracksToPlaylist(C_ItemList *itemRecords, int plid);
	void TransferAddCloudPlaylist(wchar_t * file, wchar_t * name0);
	int DeleteTracks(C_ItemList * tracks, HWND centerWindow);
	void Sync(bool silent = false);
	void CloudSync(bool silent = false);
	void Autofill();
	void Eject();
	bool PlayTracks(C_ItemList * tracks, int startPlaybackAt, bool enqueue, bool msgIfImpossible, HWND parent=NULL); // returns false if failed/unsupported
	bool PlayPlaylist(int playlistId, bool enqueue, bool msgIfImpossible, HWND parent=NULL);
	void CopyTracksToHardDrive(songid_t * tracks, int numTracks);
	void CopyTracksToHardDrive(C_ItemList * tracks);
	void CopyPlaylistToLibrary(int plnum);
	void OnActivityStarted();
	void OnActivityChanged();
	void OnActivityFinished();
	void OnNameChanged(const wchar_t *new_name);
//private:
	void RegisterViews(HNAVITEM parent);
	void Unregister();

	BOOL DisplayDeviceContextMenu(HNAVITEM item, HWND hostWindow, POINT pt);
	BOOL DisplayPlaylistContextMenu(int playlistId, HNAVITEM item, HWND hostWindow, POINT pt);

// navigation
	BOOL Navigation_IsPlaylistItem(HNAVITEM item, int *playlistId);
	HWND Navigation_CreateViewCb(HNAVITEM item, HWND parentWindow);
	BOOL Navigation_ShowContextMenuCb(HNAVITEM item, HWND hostWindow, POINT pt);
	BOOL Navigation_ClickCb(HNAVITEM item, int actionType, HWND hostWindow);
	int Navigation_DropTargetCb(HNAVITEM item, unsigned int dataType, void *data);
	BOOL Navigation_TitleEditBeginCb(HNAVITEM item);
	BOOL Navigation_TitleEditEndCb(HNAVITEM item, const wchar_t *title);
	BOOL Navigation_KeyDownCb(HNAVITEM item, NMTVKEYDOWN *keyData, HWND hwnd);

	size_t GetPlaylistName(wchar_t *buffer, size_t bufferSize, int playlistId, const wchar_t *defaultName, BOOL quoteSpaces);

public:
	/* ifc_device */
	int QueryInterface(GUID interface_guid, void **object);
	const char *GetName(); 
	HRESULT GetIcon(wchar_t *buffer, size_t bufferSize, int width, int height);
	HRESULT GetDisplayName(wchar_t *buffer, size_t bufferSize);

	const char *GetType();
	const char *GetDisplayType();
	const char *GetConnection();

	BOOL GetHidden();
	
	HRESULT GetTotalSpace(uint64_t *size);
	HRESULT GetUsedSpace(uint64_t *size);

	BOOL GetAttached();
	HRESULT Attach(HWND hostWindow);
	HRESULT Detach(HWND hostWindow);
	
	HRESULT EnumerateCommands(ifc_devicesupportedcommandenum **enumerator, DeviceCommandContext context);
	HRESULT SendCommand(const char *command, HWND hostWindow, ULONG_PTR param);
	HRESULT GetCommandFlags(const char *command, DeviceCommandFlags *flags);

	HRESULT GetActivity(ifc_deviceactivity **activity);

	HRESULT Advise(ifc_deviceevent *handler);
	HRESULT Unadvise(ifc_deviceevent *handler);

	HWND CreateView(HWND parentWindow);
	void SetNavigationItem(void *navigationItem); 

	HRESULT GetDropSupported(unsigned int dataType);
	HRESULT Drop(void *data, unsigned int dataType);

	HRESULT SetDisplayName(const wchar_t *displayName, bool force);

	HRESULT GetModel(wchar_t *buffer, size_t bufferSize);
	HRESULT GetStatus(wchar_t *buffer, size_t bufferSize);

	void UpdateActivityState();
	void UpdateSpaceInfo(BOOL updateUsedSpace, BOOL notifyChanges);

	/* ifc_deviceactivity */
	BOOL GetActive();
	BOOL GetCancelable();
	HRESULT GetProgress(unsigned int *percentCompleted);
	HRESULT Activity_GetDisplayName(wchar_t *buffer, size_t bufferMax);
	HRESULT Activity_GetStatus(wchar_t *buffer, size_t bufferMax);
	HRESULT Cancel(HWND hostWindow);

	/* Dispatchable */
		size_t AddRef()
	{
		return InterlockedIncrement((LONG*)&ref_count);
	}

	size_t Release()
	{
		if (0 == ref_count)
			return ref_count;

		LONG r = InterlockedDecrement((LONG*)&ref_count);
		if (0 == r)
			delete(this);

		return r;
	}

private:
	RECVS_MULTIPATCH;
	std::vector<ifc_deviceevent*> event_handlers;
	char name[128];
	size_t ref_count;
	~DeviceView();
	const char *connection_type;
	const char *display_type;
	BOOL navigationItemCreated;
	BOOL activityRunning;
	unsigned int currentProgress;
	uint64_t usedSpace;
	uint64_t totalSpace;
};

#endif