3
#include "queueview_failed.h"
4
#include "queueview_successful.h"
6
CQueueItem::CQueueItem()
8
m_visibleOffspring = 0;
10
m_maxCachedIndex = -1;
13
CQueueItem::~CQueueItem()
15
std::vector<CQueueItem*>::iterator iter;
16
for (iter = m_children.begin(); iter != m_children.end(); iter++)
20
void CQueueItem::SetPriority(enum QueuePriority priority)
22
std::vector<CQueueItem*>::iterator iter;
23
for (iter = m_children.begin(); iter != m_children.end(); iter++)
24
(*iter)->SetPriority(priority);
27
void CQueueItem::AddChild(CQueueItem* item)
29
item->m_indent = m_indent + _T(" ");
30
m_children.push_back(item);
32
m_visibleOffspring += 1 + item->m_visibleOffspring;
33
m_maxCachedIndex = -1;
34
CQueueItem* parent = GetParent();
37
parent->m_visibleOffspring += 1 + item->m_visibleOffspring;
38
parent->m_maxCachedIndex = -1;
39
parent = parent->GetParent();
43
CQueueItem* CQueueItem::GetChild(unsigned int item, bool recursive /*=true*/)
45
std::vector<CQueueItem*>::iterator iter;
48
if (item >= m_children.size())
50
iter = m_children.begin();
55
if ((int)item <= m_maxCachedIndex)
58
iter = m_children.begin();
59
iter += m_lookupCache[item].child;
60
item -= m_lookupCache[item].index;
64
return (*iter)->GetChild(item - 1);
69
iter = m_children.begin();
70
if (m_maxCachedIndex == -1)
77
// Start with loop with the last cached item index
78
iter += m_lookupCache[m_maxCachedIndex].child + 1;
79
item -= m_maxCachedIndex + 1;
80
index = m_maxCachedIndex + 1;
81
child = m_lookupCache[m_maxCachedIndex].child + 1;
84
for (; iter != m_children.end(); iter++, child++)
89
unsigned int count = (*iter)->GetChildrenCount(true);
92
if (m_maxCachedIndex == -1 && m_lookupCache.size() < (unsigned int)m_visibleOffspring)
93
m_lookupCache.resize(m_visibleOffspring);
94
for (unsigned int k = index; k <= index + count; k++)
96
m_lookupCache[k].child = child;
97
m_lookupCache[k].index = index;
99
m_maxCachedIndex = index + count;
105
return (*iter)->GetChild(item - 1);
110
unsigned int CQueueItem::GetChildrenCount(bool recursive)
113
return m_children.size();
115
return m_visibleOffspring;
118
bool CQueueItem::RemoveChild(CQueueItem* pItem, bool destroy /*=true*/)
120
int oldVisibleOffspring = m_visibleOffspring;
121
std::vector<CQueueItem*>::iterator iter;
122
bool deleted = false;
123
for (iter = m_children.begin(); iter != m_children.end(); iter++)
127
m_visibleOffspring -= 1;
128
m_visibleOffspring -= pItem->m_visibleOffspring;
131
m_children.erase(iter);
137
int visibleOffspring = (*iter)->m_visibleOffspring;
138
if ((*iter)->RemoveChild(pItem, destroy))
140
m_visibleOffspring -= visibleOffspring - (*iter)->m_visibleOffspring;
141
if (!(*iter)->m_children.size())
143
m_visibleOffspring -= 1;
145
m_children.erase(iter);
155
m_maxCachedIndex = -1;
157
// Propagate new children count to parent
158
CQueueItem* parent = GetParent();
161
parent->m_maxCachedIndex = -1;
162
parent->m_visibleOffspring -= oldVisibleOffspring - m_visibleOffspring;
163
parent = parent->GetParent();
169
bool CQueueItem::TryRemoveAll()
171
const int oldVisibleOffspring = m_visibleOffspring;
172
std::vector<CQueueItem*>::iterator iter;
173
std::vector<CQueueItem*> keepChildren;
174
m_visibleOffspring = 0;
175
for (iter = m_children.begin(); iter != m_children.end(); iter++)
177
CQueueItem* pItem = *iter;
178
if (pItem->TryRemoveAll())
182
keepChildren.push_back(pItem);
183
m_visibleOffspring++;
184
m_visibleOffspring += pItem->GetChildrenCount(true);
187
m_children = keepChildren;
188
m_maxCachedIndex = -1;
190
CQueueItem* parent = GetParent();
193
parent->m_maxCachedIndex = -1;
194
parent->m_visibleOffspring -= oldVisibleOffspring - m_visibleOffspring;
195
parent = parent->GetParent();
198
return m_children.empty();
201
CQueueItem* CQueueItem::GetTopLevelItem()
206
CQueueItem* newParent = m_parent;
207
CQueueItem* parent = 0;
211
newParent = newParent->GetParent();
217
const CQueueItem* CQueueItem::GetTopLevelItem() const
222
const CQueueItem* newParent = m_parent;
223
const CQueueItem* parent = 0;
227
newParent = newParent->GetParent();
233
int CQueueItem::GetItemIndex() const
235
const CQueueItem* pParent = GetParent();
240
for (std::vector<CQueueItem*>::const_iterator iter = pParent->m_children.begin(); iter != pParent->m_children.end(); iter++)
245
index += (*iter)->GetChildrenCount(true) + 1;
248
return index + pParent->GetItemIndex();
251
CFileItem::CFileItem(CServerItem* parent, bool queued, bool download, const wxString& localFile,
252
const wxString& remoteFile, const CServerPath& remotePath, wxLongLong size)
255
m_priority = priority_normal;
257
m_download = download;
258
m_localFile = localFile;
259
m_remoteFile = remoteFile;
260
m_remotePath = remotePath;
262
m_itemState = ItemState_Wait;
268
m_defaultFileExistsAction = -1;
271
CFileItem::~CFileItem()
275
void CFileItem::SetPriority(enum QueuePriority priority)
277
if (priority == m_priority)
280
CServerItem* parent = (CServerItem*)m_parent;
281
parent->SetChildPriority(this, m_priority, priority);
282
m_priority = priority;
285
void CFileItem::SetPriorityRaw(enum QueuePriority priority)
287
m_priority = priority;
290
enum ItemState CFileItem::GetItemState() const
295
void CFileItem::SetItemState(const enum ItemState itemState)
297
m_itemState = itemState;
300
enum QueuePriority CFileItem::GetPriority() const
305
void CFileItem::SetActive(const bool active)
307
if (active && !m_active)
309
AddChild(new CStatusItem);
311
else if (!active && m_active)
313
CQueueItem* pItem = m_children.front();
319
void CFileItem::SaveItem(TiXmlElement* pElement) const
321
if (GetItemState() == ItemState_Complete)
324
//TODO: Save error items?
325
TiXmlElement file("File");
327
AddTextElement(&file, "LocalFile", m_localFile);
328
AddTextElement(&file, "RemoteFile", m_remoteFile);
329
AddTextElement(&file, "RemotePath", m_remotePath.GetSafePath());
330
AddTextElement(&file, "Download", m_download ? _T("1") : _T("0"));
332
AddTextElement(&file, "Size", m_size.ToString());
334
AddTextElement(&file, "ErrorCount", m_errorCount);
335
AddTextElement(&file, "Priority", m_priority);
337
AddTextElement(&file, "ItemState", m_itemState);
338
AddTextElement(&file, "TransferMode", m_transferSettings.binary ? _T("1") : _T("0"));
340
pElement->InsertEndChild(file);
343
bool CFileItem::TryRemoveAll()
352
CFolderItem::CFolderItem(CServerItem* parent, bool queued, const wxString& localFile)
353
: CFileItem(parent, queued, true, localFile, _T(""), CServerPath(), -1)
357
CFolderItem::CFolderItem(CServerItem* parent, bool queued, const CServerPath& remotePath, const wxString& remoteFile)
358
: CFileItem(parent, queued, false, _T(""), remoteFile, remotePath, -1)
362
void CFolderItem::SaveItem(TiXmlElement* pElement) const
364
if (GetItemState() == ItemState_Complete ||
365
GetItemState() == ItemState_Error)
368
TiXmlElement file("Folder");
371
AddTextElement(&file, "LocalFile", m_localFile);
374
AddTextElement(&file, "RemoteFile", m_remoteFile);
375
AddTextElement(&file, "RemotePath", m_remotePath.GetSafePath());
377
AddTextElement(&file, "Download", m_download ? _T("1") : _T("0"));
379
pElement->InsertEndChild(file);
382
void CFolderItem::SetActive(const bool active)
387
CServerItem::CServerItem(const CServer& server)
393
CServerItem::~CServerItem()
397
const CServer& CServerItem::GetServer() const
402
wxString CServerItem::GetName() const
404
return m_server.FormatServer();
407
void CServerItem::AddChild(CQueueItem* pItem)
409
CQueueItem::AddChild(pItem);
410
if (pItem->GetType() == QueueItemType_File ||
411
pItem->GetType() == QueueItemType_Folder)
412
AddFileItemToList((CFileItem*)pItem);
415
void CServerItem::AddFileItemToList(CFileItem* pItem)
420
m_fileList[pItem->m_queued ? 0 : 1][pItem->GetPriority()].push_back(pItem);
423
void CServerItem::RemoveFileItemFromList(CFileItem* pItem)
425
std::list<CFileItem*>& fileList = m_fileList[pItem->m_queued ? 0 : 1][pItem->GetPriority()];
426
for (std::list<CFileItem*>::iterator iter = fileList.begin(); iter != fileList.end(); iter++)
430
fileList.erase(iter);
434
wxFAIL_MSG(_T("File item not deleted from m_fileList"));
437
void CServerItem::SetDefaultFileExistsAction(int action, const enum TransferDirection direction)
439
for (std::vector<CQueueItem*>::iterator iter = m_children.begin(); iter != m_children.end(); iter++)
441
CQueueItem *pItem = *iter;
442
if (pItem->GetType() == QueueItemType_File)
444
CFileItem* pFileItem = ((CFileItem *)pItem);
445
if (direction == upload && pFileItem->Download())
447
else if (direction == download && !pFileItem->Download())
449
pFileItem->m_defaultFileExistsAction = action;
451
else if (pItem->GetType() == QueueItemType_FolderScan)
453
if (direction == download)
455
((CFolderScanItem *)pItem)->m_defaultFileExistsAction = action;
460
CFileItem* CServerItem::GetIdleChild(bool immediateOnly, enum TransferDirection direction)
463
for (i = (PRIORITY_COUNT - 1); i >= 0; i--)
465
std::list<CFileItem*>& fileList = m_fileList[1][i];
466
for (std::list<CFileItem*>::iterator iter = fileList.begin(); iter != fileList.end(); iter++)
468
CFileItem* item = *iter;
469
if (item->IsActive())
472
if (direction == both)
475
if (direction == download)
477
if (item->Download())
480
else if (!item->Download())
487
for (i = (PRIORITY_COUNT - 1); i >= 0; i--)
489
std::list<CFileItem*>& fileList = m_fileList[0][i];
490
for (std::list<CFileItem*>::iterator iter = fileList.begin(); iter != fileList.end(); iter++)
492
CFileItem* item = *iter;
493
if (item->IsActive())
496
if (direction == both)
499
if (direction == download)
501
if (item->Download())
504
else if (!item->Download())
512
bool CServerItem::RemoveChild(CQueueItem* pItem, bool destroy /*=true*/)
517
if (pItem->GetType() == QueueItemType_File || pItem->GetType() == QueueItemType_Folder)
519
CFileItem* pFileItem = reinterpret_cast<CFileItem*>(pItem);
520
RemoveFileItemFromList(pFileItem);
523
return CQueueItem::RemoveChild(pItem, destroy);
526
void CServerItem::QueueImmediateFiles()
528
for (int i = 0; i < PRIORITY_COUNT; i++)
530
std::list<CFileItem*> activeList;
531
std::list<CFileItem*>& fileList = m_fileList[1][i];
532
for (std::list<CFileItem*>::reverse_iterator iter = fileList.rbegin(); iter != fileList.rend(); iter++)
534
CFileItem* item = *iter;
535
wxASSERT(!item->m_queued);
536
if (item->IsActive())
537
activeList.push_front(item);
540
item->m_queued = true;
541
m_fileList[0][i].push_front(item);
544
fileList = activeList;
548
void CServerItem::QueueImmediateFile(CFileItem* pItem)
553
std::list<CFileItem*>& fileList = m_fileList[1][pItem->GetPriority()];
554
for (std::list<CFileItem*>::iterator iter = fileList.begin(); iter != fileList.end(); iter++)
559
pItem->m_queued = true;
560
fileList.erase(iter);
561
m_fileList[0][pItem->GetPriority()].push_front(pItem);
567
void CServerItem::SaveItem(TiXmlElement* pElement) const
569
TiXmlElement server("Server");
570
SetServer(&server, m_server);
572
for (std::vector<CQueueItem*>::const_iterator iter = m_children.begin(); iter != m_children.end(); iter++)
573
(*iter)->SaveItem(&server);
575
pElement->InsertEndChild(server);
578
wxLongLong CServerItem::GetTotalSize(int& filesWithUnknownSize, int& queuedFiles, int& folderScanCount) const
580
wxLongLong totalSize = 0;
581
for (int i = 0; i < PRIORITY_COUNT; i++)
583
for (int j = 0; j < 2; j++)
585
const std::list<CFileItem*>& fileList = m_fileList[j][i];
586
for (std::list<CFileItem*>::const_iterator iter = fileList.begin(); iter != fileList.end(); iter++)
588
const CFileItem* item = *iter;
589
if (item->GetItemState() != ItemState_Complete)
591
wxLongLong size = item->GetSize();
595
filesWithUnknownSize++;
601
for (std::vector<CQueueItem*>::const_iterator iter = m_children.begin(); iter != m_children.end(); iter++)
603
if ((*iter)->GetType() == QueueItemType_File ||
604
(*iter)->GetType() == QueueItemType_Folder)
606
else if ((*iter)->GetType() == QueueItemType_FolderScan)
613
bool CServerItem::TryRemoveAll()
615
const int oldVisibleOffspring = m_visibleOffspring;
616
std::vector<CQueueItem*>::iterator iter;
617
std::vector<CQueueItem*> keepChildren;
618
m_visibleOffspring = 0;
619
for (iter = m_children.begin(); iter != m_children.end(); iter++)
621
CQueueItem* pItem = *iter;
622
if (pItem->TryRemoveAll())
624
if (pItem->GetType() == QueueItemType_File || pItem->GetType() == QueueItemType_Folder)
626
CFileItem* pFileItem = reinterpret_cast<CFileItem*>(pItem);
627
RemoveFileItemFromList(pFileItem);
633
keepChildren.push_back(pItem);
634
m_visibleOffspring++;
635
m_visibleOffspring += pItem->GetChildrenCount(true);
638
m_children = keepChildren;
640
CQueueItem* parent = GetParent();
643
parent->m_visibleOffspring -= oldVisibleOffspring - m_visibleOffspring;
644
parent = parent->GetParent();
647
return m_children.empty();
650
void CServerItem::DetachChildren()
652
wxASSERT(!m_activeCount);
655
m_visibleOffspring = 0;
656
m_maxCachedIndex = -1;
658
for (int i = 0; i < 2; i++)
659
for (int j = 0; j < PRIORITY_COUNT; j++)
660
m_fileList[i][j].clear();
663
void CServerItem::SetPriority(enum QueuePriority priority)
665
std::vector<CQueueItem*>::iterator iter;
666
for (iter = m_children.begin(); iter != m_children.end(); iter++)
668
if ((*iter)->GetType() == QueueItemType_File)
669
((CFileItem*)(*iter))->SetPriorityRaw(priority);
671
(*iter)->SetPriority(priority);
674
for (int i = 0; i < 2; i++)
675
for (int j = 0; j < PRIORITY_COUNT; j++)
677
m_fileList[i][priority].splice(m_fileList[i][priority].end(), m_fileList[i][j]);
680
void CServerItem::SetChildPriority(CFileItem* pItem, enum QueuePriority oldPriority, enum QueuePriority newPriority)
682
int i = pItem->Queued() ? 0 : 1;
684
for (std::list<CFileItem*>::iterator iter = m_fileList[i][oldPriority].begin(); iter != m_fileList[i][oldPriority].end(); iter++)
689
m_fileList[i][oldPriority].erase(iter);
690
m_fileList[i][newPriority].push_back(pItem);
697
CFolderScanItem::CFolderScanItem(CServerItem* parent, bool queued, bool download, const wxString& localPath, const CServerPath& remotePath)
701
m_download = download;
702
m_localPath = localPath;
703
m_remotePath = remotePath;
709
pair.localPath = localPath.c_str();
710
pair.remotePath.SetSafePath(remotePath.GetSafePath().c_str());
711
m_dirsToCheck.push_back(pair);
713
m_defaultFileExistsAction = -1;
716
bool CFolderScanItem::TryRemoveAll()
729
BEGIN_EVENT_TABLE(CQueueViewBase, wxListCtrl)
730
EVT_ERASE_BACKGROUND(CQueueViewBase::OnEraseBackground)
731
EVT_NAVIGATION_KEY(CQueueViewBase::OnNavigationKey)
732
EVT_CHAR(CQueueViewBase::OnChar)
735
CQueueViewBase::CQueueViewBase(CQueue* parent, int index, const wxString& title)
736
: wxListCtrl(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxCLIP_CHILDREN | wxLC_REPORT | wxLC_VIRTUAL | wxSUNKEN_BORDER | wxTAB_TRAVERSAL),
737
m_pageIndex(index), m_title(title)
740
m_insertionStart = -1;
741
m_insertionCount = 0;
743
m_allowBackgroundErase = true;
746
m_folderScanCount = 0;
747
m_fileCountChanged = false;
748
m_folderScanCountChanged = false;
750
// Create and assign the image list for the queue
751
wxImageList* pImageList = new wxImageList(16, 16);
753
pImageList->Add(wxArtProvider::GetBitmap(_T("ART_SERVER"), wxART_OTHER, wxSize(16, 16)));
754
pImageList->Add(wxArtProvider::GetBitmap(_T("ART_FILE"), wxART_OTHER, wxSize(16, 16)));
755
pImageList->Add(wxArtProvider::GetBitmap(_T("ART_FOLDERCLOSED"), wxART_OTHER, wxSize(16, 16)));
756
pImageList->Add(wxArtProvider::GetBitmap(_T("ART_FOLDER"), wxART_OTHER, wxSize(16, 16)));
758
AssignImageList(pImageList, wxIMAGE_LIST_SMALL);
761
CQueueViewBase::~CQueueViewBase()
763
for (std::vector<CServerItem*>::iterator iter = m_serverList.begin(); iter != m_serverList.end(); iter++)
767
CQueueItem* CQueueViewBase::GetQueueItem(unsigned int item)
769
std::vector<CServerItem*>::iterator iter;
770
for (iter = m_serverList.begin(); iter != m_serverList.end(); iter++)
775
unsigned int count = (*iter)->GetChildrenCount(true);
782
return (*iter)->GetChild(item - 1);
787
int CQueueViewBase::GetItemIndex(const CQueueItem* item)
789
const CQueueItem* pTopLevelItem = item->GetTopLevelItem();
792
for (std::vector<CServerItem*>::const_iterator iter = m_serverList.begin(); iter != m_serverList.end(); iter++)
794
if (pTopLevelItem == *iter)
797
index += (*iter)->GetChildrenCount(true) + 1;
800
return index + item->GetItemIndex();
803
void CQueueViewBase::OnEraseBackground(wxEraseEvent& event)
805
if (m_allowBackgroundErase)
809
wxString CQueueViewBase::OnGetItemText(long item, long column) const
811
CQueueViewBase* pThis = const_cast<CQueueViewBase*>(this);
813
CQueueItem* pItem = pThis->GetQueueItem(item);
817
switch (pItem->GetType())
819
case QueueItemType_Server:
821
CServerItem* pServerItem = reinterpret_cast<CServerItem*>(pItem);
823
return pServerItem->GetName();
826
case QueueItemType_File:
828
CFileItem* pFileItem = reinterpret_cast<CFileItem*>(pItem);
832
return pFileItem->GetIndent() + pFileItem->GetLocalFile();
834
if (pFileItem->Download())
835
if (pFileItem->Queued())
840
if (pFileItem->Queued())
846
return pFileItem->GetRemotePath().FormatFilename(pFileItem->GetRemoteFile());
849
wxLongLong size = pFileItem->GetSize();
851
return size.ToString();
856
switch (pFileItem->GetPriority())
872
return pFileItem->m_statusMessage;
878
case QueueItemType_FolderScan:
880
CFolderScanItem* pFolderItem = reinterpret_cast<CFolderScanItem*>(pItem);
884
return _T(" ") + pFolderItem->GetLocalPath();
886
if (pFolderItem->Download())
887
if (pFolderItem->Queued())
892
if (pFolderItem->Queued())
898
return pFolderItem->GetRemotePath().GetPath();
900
return pFolderItem->m_statusMessage;
906
case QueueItemType_Folder:
908
CFileItem* pFolderItem = reinterpret_cast<CFolderItem*>(pItem);
912
if (pFolderItem->Download())
913
return pFolderItem->GetIndent() + pFolderItem->GetLocalFile();
916
if (pFolderItem->Download())
917
if (pFolderItem->Queued())
922
if (pFolderItem->Queued())
928
if (!pFolderItem->Download())
930
if (pFolderItem->GetRemoteFile() == _T(""))
931
return pFolderItem->GetRemotePath().GetPath();
933
return pFolderItem->GetRemotePath().FormatFilename(pFolderItem->GetRemoteFile());
937
switch (pFolderItem->GetPriority())
953
return pFolderItem->m_statusMessage;
966
int CQueueViewBase::OnGetItemImage(long item) const
968
CQueueViewBase* pThis = const_cast<CQueueViewBase*>(this);
970
CQueueItem* pItem = pThis->GetQueueItem(item);
974
switch (pItem->GetType())
976
case QueueItemType_Server:
978
case QueueItemType_File:
980
case QueueItemType_FolderScan:
981
case QueueItemType_Folder:
990
void CQueueViewBase::UpdateSelections_ItemAdded(int added)
992
// This is the fastest algorithm I can think of to move all
993
// selections. Though worst case is still O(n), as with every algorithm to
996
// Go through all items, keep record of the previous selected item
997
int item = GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
998
while (item != -1 && item < added)
999
item = GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
1006
if (prevItem + 1 != item)
1008
// Previous selected item was not the direct predecessor
1009
// That means we have to select the successor of prevItem
1010
// and unselect current item
1011
SetItemState(prevItem + 1, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
1012
SetItemState(item, 0, wxLIST_STATE_SELECTED);
1017
// First selected item, no predecessor yet. We have to unselect
1018
SetItemState(item, 0, wxLIST_STATE_SELECTED);
1022
item = GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
1024
if (prevItem != -1 && prevItem < m_itemCount - 1)
1026
// Move the very last selected item
1027
SetItemState(prevItem + 1, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
1030
SetItemState(added, 0, wxLIST_STATE_SELECTED);
1033
void CQueueViewBase::UpdateSelections_ItemRangeAdded(int added, int count)
1035
std::list<int> itemsToSelect;
1037
// Go through all selected items
1038
int item = GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
1039
while (item != -1 && item < added)
1040
item = GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
1044
// Select new items preceeding to current one
1045
while (!itemsToSelect.empty() && itemsToSelect.front() < item)
1047
SetItemState(itemsToSelect.front(), wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
1048
itemsToSelect.pop_front();
1050
if (itemsToSelect.empty())
1051
SetItemState(item, 0, wxLIST_STATE_SELECTED);
1052
else if (itemsToSelect.front() == item)
1053
itemsToSelect.pop_front();
1055
itemsToSelect.push_back(item + count);
1057
item = GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
1059
for (std::list<int>::const_iterator iter = itemsToSelect.begin(); iter != itemsToSelect.end(); iter++)
1060
SetItemState(*iter, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
1063
void CQueueViewBase::UpdateSelections_ItemRemoved(int removed)
1065
SetItemState(removed, 0, wxLIST_STATE_SELECTED);
1068
int item = GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
1069
while (item != -1 && item < removed)
1070
item = GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
1076
if (prevItem + 1 != item)
1078
// Previous selected item was not the direct predecessor
1079
// That means we have to select our predecessor and unselect
1081
SetItemState(prevItem, 0, wxLIST_STATE_SELECTED);
1082
SetItemState(item - 1, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
1087
// First selected item, no predecessor yet. We have to unselect
1088
SetItemState(item - 1, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
1092
item = GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
1096
SetItemState(prevItem, 0, wxLIST_STATE_SELECTED);
1100
void CQueueViewBase::UpdateSelections_ItemRangeRemoved(int removed, int count)
1102
SetItemState(removed, 0, wxLIST_STATE_SELECTED);
1104
std::list<int> itemsToUnselect;
1106
int item = GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
1107
while (item != -1 && item < removed)
1108
item = GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
1112
// Unselect new items preceeding to current one
1113
while (!itemsToUnselect.empty() && itemsToUnselect.front() < item - count)
1115
SetItemState(itemsToUnselect.front(), 0, wxLIST_STATE_SELECTED);
1116
itemsToUnselect.pop_front();
1119
if (itemsToUnselect.empty())
1120
SetItemState(item - count, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
1121
else if (itemsToUnselect.front() == item - count)
1122
itemsToUnselect.pop_front();
1124
SetItemState(item - count, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
1126
itemsToUnselect.push_back(item);
1128
item = GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
1130
for (std::list<int>::const_iterator iter = itemsToUnselect.begin(); iter != itemsToUnselect.end(); iter++)
1131
SetItemState(*iter, 0, wxLIST_STATE_SELECTED);
1134
void CQueueViewBase::CreateColumns(const wxString& lastColumnName)
1136
InsertColumn(0, _("Server / Local file"), wxLIST_FORMAT_LEFT, 150);
1137
InsertColumn(1, _("Direction"), wxLIST_FORMAT_CENTER, 60);
1138
InsertColumn(2, _("Remote file"), wxLIST_FORMAT_LEFT, 150);
1139
InsertColumn(3, _("Size"), wxLIST_FORMAT_RIGHT, 70);
1140
InsertColumn(4, _("Priority"), wxLIST_FORMAT_LEFT, 60);
1141
if (lastColumnName != _T(""))
1142
InsertColumn(5, lastColumnName, wxLIST_FORMAT_LEFT, 150);
1145
CServerItem* CQueueViewBase::GetServerItem(const CServer& server)
1147
for (std::vector<CServerItem*>::iterator iter = m_serverList.begin(); iter != m_serverList.end(); iter++)
1149
if ((*iter)->GetServer() == server)
1155
CServerItem* CQueueViewBase::CreateServerItem(const CServer& server)
1157
CServerItem* pItem = GetServerItem(server);
1161
pItem = new CServerItem(server);
1162
m_serverList.push_back(pItem);
1165
wxASSERT(m_insertionStart == -1);
1166
wxASSERT(m_insertionCount == 0);
1168
m_insertionStart = GetItemIndex(pItem);
1169
m_insertionCount = 1;
1175
void CQueueViewBase::CommitChanges()
1177
SetItemCount(m_itemCount);
1179
if (m_insertionStart != -1)
1181
wxASSERT(m_insertionCount != 0);
1182
if (m_insertionCount == 1)
1183
UpdateSelections_ItemAdded(m_insertionStart);
1185
UpdateSelections_ItemRangeAdded(m_insertionStart, m_insertionCount);
1187
m_insertionStart = -1;
1188
m_insertionCount = 0;
1191
if (m_fileCountChanged || m_folderScanCountChanged)
1192
DisplayNumberQueuedFiles();
1195
void CQueueViewBase::DisplayNumberQueuedFiles()
1198
if (m_fileCount > 0)
1200
if (!m_folderScanCount)
1201
str.Printf(m_title + _T(" (%d)"), m_fileCount);
1203
str.Printf(m_title + _T(" (%d+)"), m_fileCount);
1207
if (m_folderScanCount)
1208
str.Printf(m_title + _T(" (0+)"), m_fileCount);
1212
m_pQueue->SetPageText(m_pageIndex, str);
1214
m_fileCountChanged = false;
1215
m_folderScanCountChanged = false;
1218
void CQueueViewBase::InsertItem(CServerItem* pServerItem, CQueueItem* pItem)
1220
pServerItem->AddChild(pItem);
1223
if (m_insertionStart == -1)
1224
m_insertionStart = GetItemIndex(pItem);
1227
if (pItem->GetType() == QueueItemType_File || pItem->GetType() == QueueItemType_Folder)
1230
m_fileCountChanged = true;
1232
else if (pItem->GetType() == QueueItemType_FolderScan)
1234
m_folderScanCount++;
1235
m_folderScanCountChanged = true;
1239
bool CQueueViewBase::RemoveItem(CQueueItem* pItem, bool destroy, bool updateItemCount /*=true*/, bool updateSelections /*=true*/)
1241
if (pItem->GetType() == QueueItemType_File || pItem->GetType() == QueueItemType_Folder)
1243
wxASSERT(m_fileCount > 0);
1245
m_fileCountChanged = true;
1247
else if (pItem->GetType() == QueueItemType_FolderScan)
1249
wxASSERT(m_folderScanCount > 0);
1250
m_folderScanCount--;
1251
m_folderScanCountChanged = true;
1256
if (updateSelections)
1257
index = GetItemIndex(pItem);
1259
CQueueItem* topLevelItem = pItem->GetTopLevelItem();
1261
int count = topLevelItem->GetChildrenCount(true);
1262
topLevelItem->RemoveChild(pItem, destroy);
1264
bool didRemoveParent;
1266
int oldCount = m_itemCount;
1267
if (!topLevelItem->GetChild(0))
1269
std::vector<CServerItem*>::iterator iter;
1270
for (iter = m_serverList.begin(); iter != m_serverList.end(); iter++)
1272
if (*iter == topLevelItem)
1275
if (iter != m_serverList.end())
1276
m_serverList.erase(iter);
1278
UpdateSelections_ItemRangeRemoved(GetItemIndex(topLevelItem), count + 1);
1280
delete topLevelItem;
1282
m_itemCount -= count + 1;
1283
if (updateItemCount)
1284
SetItemCount(m_itemCount);
1286
didRemoveParent = true;
1290
count -= topLevelItem->GetChildrenCount(true);
1292
if (updateSelections)
1293
UpdateSelections_ItemRangeRemoved(index, count);
1295
m_itemCount -= count;
1296
if (updateItemCount)
1297
SetItemCount(m_itemCount);
1299
didRemoveParent = false;
1302
if (updateItemCount)
1304
if (m_fileCountChanged || m_folderScanCountChanged)
1305
DisplayNumberQueuedFiles();
1306
if (oldCount > m_itemCount)
1308
bool eraseBackground = GetTopItem() + GetCountPerPage() + 1 >= m_itemCount;
1309
Refresh(eraseBackground);
1310
if (eraseBackground)
1315
return didRemoveParent;
1318
void CQueueViewBase::RefreshItem(const CQueueItem* pItem)
1321
int index = GetItemIndex(pItem);
1323
wxListCtrl::RefreshItem(index);
1326
void CQueueViewBase::OnNavigationKey(wxNavigationKeyEvent& event)
1328
event.SetEventObject(m_pQueue);
1329
m_pQueue->ProcessEvent(event);
1332
void CQueueViewBase::OnChar(wxKeyEvent& event)
1334
const int code = event.GetKeyCode();
1335
if (code != WXK_LEFT && code != WXK_RIGHT)
1341
int selection = m_pQueue->GetSelection();
1342
if (selection > 0 && code == WXK_LEFT)
1344
else if (selection < (int)m_pQueue->GetPageCount() - 1 && code == WXK_RIGHT)
1349
m_pQueue->SetSelection(selection);
1356
CQueue::CQueue(wxWindow* parent, CMainFrame *pMainFrame, CAsyncRequestQueue *pAsyncRequestQueue)
1358
Create(parent, -1, wxDefaultPosition, wxDefaultSize, wxNO_BORDER | wxAUI_NB_BOTTOM);
1361
m_pQueueView = new CQueueView(this, 0, pMainFrame, pAsyncRequestQueue);
1362
AddPage(m_pQueueView, m_pQueueView->GetTitle());
1364
m_pQueueView_Failed = new CQueueViewFailed(this, 1);
1365
AddPage(m_pQueueView_Failed, m_pQueueView_Failed->GetTitle());
1366
m_pQueueView_Successful = new CQueueViewSuccessful(this, 2);
1367
AddPage(m_pQueueView_Successful, m_pQueueView_Successful->GetTitle());
1369
RemoveExtraBorders();
1371
m_pQueueView->LoadQueue();
1374
void CQueue::SetFocus()
1376
GetPage(GetSelection())->SetFocus();