Files
2022-01-04 09:40:38 +08:00

900 lines
20 KiB
C++

#include "StdAfx.h"
#include "GridBase.h"
#include "GridBody.h"
namespace ui
{
void GridSelRange::Clear() {
bool bFlash = (m_vecRange.size() > 0 || m_mapSelRow.size() > 0 || m_mapSelCol.size() > 0);
if (m_vecRange.size() > 0)
{
m_pBody->_SelRange(m_vecRange[0], false);
m_vecRange.clear();
}
for (auto it = m_mapSelRow.cbegin(); it != m_mapSelRow.cend(); it++)
{
m_pBody->_SelRow(it->first, false);
}
m_mapSelRow.clear();
for (auto it = m_mapSelCol.cbegin(); it != m_mapSelCol.cend(); it++)
{
m_pBody->_SelCol(it->first, false);
}
m_mapSelCol.clear();
m_bSelAll = false;
if (bFlash)
m_pBody->Invalidate();
}
void GridSelRange::ClearContent()
{
int row_count = m_pBody->GetRowCount();
int col_count = m_pBody->GetColCount();
int fixed_row_count = m_pBody->GetFixedRowCount();
int fixed_col_count = m_pBody->GetFixedColCount();
if (fixed_row_count == row_count || fixed_col_count == col_count)
return;
if (m_bSelAll)
{
for (int row = fixed_row_count; row < row_count; row++)
{
GridRow *pRow = m_pBody->m_vecRow[row];
for (int col = fixed_col_count; col < col_count; col++)
{
pRow->at(col)->text = L"";
}
}
m_pBody->Invalidate();
return;
}
bool bFlash = false;
for (auto it = m_mapSelRow.cbegin(); it != m_mapSelRow.cend(); it++)
{
int row_index = it->first;
assert(row_index >= fixed_row_count && row_index < row_count);
if (row_index < fixed_row_count || row_index >= row_count)
continue;
GridRow *pRow = m_pBody->m_vecRow[row_index];
for (int col = fixed_col_count; col < col_count; col++)
{
pRow->at(col)->text = L"";
}
bFlash = true;
}
if (m_mapSelCol.size() > 0)
{
for (int row = fixed_row_count; row < row_count; row++)
{
GridRow *pRow = m_pBody->m_vecRow[row];
for (auto it = m_mapSelCol.cbegin(); it != m_mapSelCol.cend(); it++)
{
int col_index = it->first;
assert(col_index >= fixed_col_count && col_index < col_count);
if (col_index < fixed_col_count || col_index >= col_count)
continue;
pRow->at(col_index)->text = L"";
}
}
bFlash = true;
}
if (m_vecRange.size() > 0)
{
int row_index_start = m_vecRange[0].top;
int col_index_start = m_vecRange[0].left;
int row_index_end = m_vecRange[0].bottom;
int col_index_end = m_vecRange[0].right;
if (row_index_start < fixed_row_count)
row_index_start = fixed_row_count;
if (col_index_start < fixed_col_count)
col_index_start = fixed_col_count;
if (row_index_end >= row_count)
row_index_end = row_count - 1;
if (col_index_end >= col_count)
col_index_end = col_count - 1;
for (int row = row_index_start; row <= row_index_end; row++)
{
GridRow *pRow = m_pBody->m_vecRow[row];
for (int col = col_index_start; col <= col_index_end; col++)
{
GridItem *pItem = pRow->at(col);
if (pItem->IsSelected())
pItem->text = L"";
}
}
bFlash = true;
}
if (bFlash)
m_pBody->Invalidate();
}
void GridSelRange::SetSelAll()
{
if (m_bSelAll)
{
Clear();
}
else
{
m_mapSelRow.clear();
m_mapSelCol.clear();
m_vecRange.clear();
int row_count = m_pBody->GetRowCount();
int col_count = m_pBody->GetColCount();
int fixed_row_count = m_pBody->GetFixedRowCount();
int fixed_col_count = m_pBody->GetFixedColCount();
if (fixed_row_count == row_count || fixed_col_count == col_count)
return;
UiRect rc(fixed_col_count, fixed_row_count, col_count - 1, row_count - 1);
m_vecRange.push_back(rc);
m_pBody->_SelRange(rc, true);
m_bSelAll = true;
}
m_pBody->Invalidate();
}
void GridSelRange::SetSelItem(int row_index, int col_index, bool ctrl, bool shift){
assert(m_vecRange.size() < 2);
GridItem *pItem = m_pBody->GetGridItem(row_index, col_index);
assert(pItem);
if (!pItem)
return;
bool bSelected = pItem->IsSelected();
if (ctrl && shift)
{
ctrl = false;
shift = false;
}
if (ctrl)
{
UiRect rc(-1,-1,-1,-1);
if (m_vecRange.size() > 0)
rc = m_vecRange[0];
bool bInSelRow = false;
bool bInSelCol = false;
if (m_mapSelRow.find(row_index) != m_mapSelRow.end()) //row_index为选中状态
{
assert(bSelected);
bInSelRow = true;
rc.left = m_pBody->GetFixedColCount();
rc.right = m_pBody->GetColCount() - 1;
if (rc.top < row_index)
rc.top = row_index;
if (rc.bottom > row_index)
rc.bottom = row_index;
m_mapSelRow.erase(row_index);
//pItem->SetSelected(false);
}
if (m_mapSelCol.find(col_index) != m_mapSelCol.end()) //col_index为选中状态
{
assert(bSelected);
bInSelCol = true;
rc.top = m_pBody->GetFixedRowCount();
rc.bottom = m_pBody->GetRowCount() - 1;
if (rc.left < col_index)
rc.left = col_index;
if (rc.right > col_index)
rc.left = col_index;
m_mapSelCol.erase(col_index);
//pItem->SetSelected(false);
}
if (rc.left > col_index || rc.right < col_index || rc.top > row_index || rc.bottom < row_index) //不位于rc中
{
//assert(!bSelected);
rc.left = min(rc.left, col_index);
rc.top = min(rc.top, row_index);
rc.right = max(rc.right, col_index);
rc.bottom = max(rc.bottom, row_index);
}
if (m_vecRange.empty())
m_vecRange.push_back(rc);
else
m_vecRange[0] = rc;
pItem->SetSelected(!bSelected);
m_pBody->Invalidate();
}
else if (shift)
{
if (m_vecRange.size() == 0)
{
assert(!bSelected);
UiRect rc(col_index, row_index, col_index, row_index);
m_vecRange.push_back(rc);
m_pBody->_SelItem(row_index, col_index, true);
m_pBody->Invalidate();
}
else
{
UiRect rc = m_vecRange[0];
rc.left = min(rc.left, col_index);
rc.top = min(rc.top, row_index);
rc.right = max(rc.right, col_index);
rc.bottom = max(rc.bottom, row_index);
m_vecRange[0] = rc;
m_pBody->_SelRange(rc, true);
m_pBody->Invalidate();
}
}
else
{
Clear();
m_vecRange.push_back(UiRect(col_index, row_index, col_index, row_index));
m_pBody->_SelItem(row_index, col_index, true);
m_pBody->Invalidate();
}
if (m_bSelAll)
m_bSelAll = false;
}
void GridSelRange::SetSelItemRange(UiRect rc, bool ctrl, bool shift)
{
assert(m_vecRange.size() < 3);
if (ctrl && shift)
{
ctrl = false;
shift = false;
}
if (!ctrl)
{
Clear();
m_vecRange.push_back(rc);
m_pBody->_SelRange(rc, true);
m_pBody->Invalidate();
}
else
{
assert(m_vecRange.size() > 0); //ButtonDown时应该调用了SetSelItem, 给m_vecRange赋值
if (m_vecRange.size() == 0)
{
m_vecRange.push_back(rc);
m_pBody->_SelRange(rc, true);
m_pBody->Invalidate();
}
else
{
if (m_vecRange.size() == 1)
{
m_pBody->_SelRange(rc, true);
m_vecRange.push_back(rc);
}
else if (m_vecRange.size() == 2)
{
m_pBody->_SelRange(m_vecRange[1], false);
//m_pBody->_SelRange(m_vecRange[0], true);
m_pBody->_SelRange(rc, true);
m_vecRange.pop_back();
m_vecRange.push_back(rc);
}
m_pBody->Invalidate();
}
}
if (m_bSelAll)
m_bSelAll = false;
}
void GridSelRange::SetSelRow(int row_index, bool ctrl, bool shift)
{
assert(m_vecRange.size() < 2);
if (ctrl && shift)
{
ctrl = false;
shift = false;
}
if (ctrl)
{
if (m_mapSelRow.find(row_index) == m_mapSelRow.end())
{
m_pBody->_SelRow(row_index, true);
m_mapSelRow[row_index] = nullptr;
}
else
{
m_pBody->_SelRow(row_index, false);
m_mapSelRow.erase(row_index);
}
m_pBody->Invalidate();
}
else if (shift)
{
if (m_mapSelRow.size() == 0)
{
m_pBody->_SelRow(row_index, true);
m_mapSelRow[row_index] = nullptr;
m_pBody->Invalidate();
}
else
{
bool bChange = false;
int min_row_index = 0, max_row_index = 0;
min_row_index = m_mapSelRow.begin()->first;
max_row_index = m_mapSelRow.rbegin()->first;
min_row_index = min(min_row_index, row_index);
max_row_index = max(max_row_index, row_index);
for (int row = min_row_index; row <= max_row_index; row++)
{
if (m_mapSelRow.find(row) == m_mapSelRow.end())
{
bChange = true;
m_pBody->_SelRow(row, true);
m_mapSelRow[row] = nullptr;
}
}
if (bChange)
m_pBody->Invalidate();
}
}
else
{
Clear();
m_pBody->_SelRow(row_index, true);
m_mapSelRow[row_index] = nullptr;
m_pBody->Invalidate();
}
if (m_bSelAll)
m_bSelAll = false;
}
void GridSelRange::SetSelRowRange(int row_index, int row_index_end, bool ctrl, bool shift)
{
assert(m_vecRange.size() < 2);
assert(row_index <= row_index_end);
if (row_index > row_index_end)
return;
if (ctrl || shift) //直接返回不处理了, 搞不清逻辑了
return;
#if 0
if (ctrl && shift)
{
ctrl = false;
shift = false;
}
if (ctrl)
{
bool bChange = false;
for (int row = row_index; row <= row_index_end; row++)
{
if (m_mapSelRow.find(row) == m_mapSelRow.end())
{
bChange = true;
m_pBody->_SelRow(row, true);
m_mapSelRow[row] = nullptr;
}
}
if (bChange)
m_pBody->Invalidate();
}
else if (shift)
{
bool bChange = false;
int min_row_index = 0, max_row_index = 0;
if (m_mapSelRow.size() > 0){
min_row_index = m_mapSelRow.begin()->first;
max_row_index = m_mapSelRow.rbegin()->first;
}
min_row_index = min(min_row_index, row_index);
max_row_index = max(max_row_index, row_index_end);
for (int row = min_row_index; row <= max_row_index; row++)
{
if (m_mapSelRow.find(row) == m_mapSelRow.end())
{
bChange = true;
m_pBody->_SelRow(row, true);
m_mapSelRow[row] = nullptr;
}
}
if (bChange)
m_pBody->Invalidate();
}
else
#endif
{
Clear();
for (int row = row_index; row <= row_index_end; row++)
{
if (m_mapSelRow.find(row) == m_mapSelRow.end())
{
m_pBody->_SelRow(row, true);
m_mapSelRow[row] = nullptr;
}
}
m_pBody->Invalidate();
}
if (m_bSelAll)
m_bSelAll = false;
}
void GridSelRange::SetSelCol(int col_index, bool ctrl, bool shift)
{
assert(m_vecRange.size() < 2);
if (ctrl && shift)
{
ctrl = false;
shift = false;
}
if (ctrl)
{
if (m_mapSelCol.find(col_index) == m_mapSelCol.end())
{
m_pBody->_SelCol(col_index, true);
m_mapSelCol[col_index] = nullptr;
}
else
{
m_pBody->_SelCol(col_index, false);
m_mapSelCol.erase(col_index);
}
m_pBody->Invalidate();
}
else if (shift)
{
if (m_mapSelCol.size() == 0)
{
m_pBody->_SelCol(col_index, true);
m_mapSelCol[col_index] = nullptr;
m_pBody->Invalidate();
}
else
{
bool bChange = false;
int min_col_index = 0, max_col_index = 0;
min_col_index = m_mapSelCol.begin()->first;
max_col_index = m_mapSelCol.rbegin()->first;
min_col_index = min(min_col_index, col_index);
max_col_index = max(max_col_index, col_index);
for (int col = min_col_index; col <= max_col_index; col++)
{
if (m_mapSelCol.find(col) == m_mapSelCol.end())
{
bChange = true;
m_pBody->_SelCol(col, true);
m_mapSelCol[col] = nullptr;
}
}
if (bChange)
m_pBody->Invalidate();
}
}
else
{
Clear();
m_pBody->_SelCol(col_index, true);
m_mapSelCol[col_index] = nullptr;
m_pBody->Invalidate();
}
if (m_bSelAll)
m_bSelAll = false;
}
void GridSelRange::SetSelColRange(int col_index, int col_index_end, bool ctrl, bool shift)
{
assert(m_vecRange.size() < 2);
assert(col_index <= col_index_end);
if (col_index > col_index_end)
return;
if (ctrl || shift) //直接返回不处理了, 搞不清逻辑了
return;
#if 0
if (ctrl && shift)
{
ctrl = false;
shift = false;
}
if (ctrl)
{
bool bChange = false;
for (int col = col_index; col <= col_index_end; col++)
{
if (m_mapSelCol.find(col) == m_mapSelCol.end())
{
bChange = true;
m_pBody->_SelCol(col, true);
m_mapSelCol[col] = nullptr;
}
}
if (bChange)
m_pBody->Invalidate();
}
else if (shift)
{
bool bChange = false;
int min_col_index = 0, max_col_index = 0;
if (m_mapSelCol.size() > 0){
min_col_index = m_mapSelCol.begin()->first;
max_col_index = m_mapSelCol.rbegin()->first;
}
min_col_index = min(min_col_index, col_index);
max_col_index = max(max_col_index, col_index_end);
for (int col = min_col_index; col <= max_col_index; col++)
{
if (m_mapSelCol.find(col) == m_mapSelCol.end())
{
bChange = true;
m_pBody->_SelCol(col, true);
m_mapSelCol[col] = nullptr;
}
}
if (bChange)
m_pBody->Invalidate();
}
else
#endif
{
Clear();
for (int col = col_index; col <= col_index_end; col++)
{
if (m_mapSelCol.find(col) == m_mapSelCol.end())
{
m_pBody->_SelCol(col, true);
m_mapSelCol[col] = nullptr;
}
}
m_pBody->Invalidate();
}
if (m_bSelAll)
m_bSelAll = false;
}
void GridSelRange::MergeRange()
{
assert(m_vecRange.size() < 3);
if (m_vecRange.size() == 2)
{
UiRect rc = m_vecRange[0];
UiRect rc1 = m_vecRange[1];
rc.left = min(rc.left, rc1.left);
rc.top = min(rc.top, rc1.top);
rc.right = max(rc.right, rc1.right);
rc.bottom = max(rc.bottom, rc1.bottom);
m_vecRange.pop_back();
m_vecRange[0] = rc;
}
}
/*bool GridSelRange::IsItemSelected(int row_index, int col_index)
{
if (IsRowSelected(row_index) || IsColSelected(col_index))
return true;
bool ret = false;
CPoint pt(col_index, row_index);
for (auto it = m_vecRange.cbegin(); it != m_vecRange.cend(); it++)
{
UiRect rc = *it;
if (rc.IsPointIn(pt))
{
ret = true;
break;
}
}
return ret;
}*/
bool GridSelRange::IsRowSelected(int row_index)
{
return m_mapSelRow.find(row_index) != m_mapSelRow.cend();
}
bool GridSelRange::IsColSelected(int col_index)
{
return m_mapSelCol.find(col_index) != m_mapSelCol.cend();
}
bool GridSelRange::GetSelRange(UiRect &rc)
{
if (m_vecRange.size() != 1)
return false;
rc = m_vecRange[0];
return true;
}
std::vector<int> GridSelRange::GetSelRows()
{
std::vector<int> vec;
for (auto it = m_mapSelRow.cbegin(); it != m_mapSelRow.cend(); it++)
{
vec.push_back(it->first);
}
return vec;
}
std::vector<int> GridSelRange::GetSelCols()
{
std::vector<int> vec;
for (auto it = m_mapSelCol.cbegin(); it != m_mapSelCol.cend(); it++)
{
vec.push_back(it->first);
}
return vec;
}
bool GridSelRange::MoveSelItem(TCHAR move_key, bool ctrl, bool shift)
{
if (shift)
return false;
int row_count = m_pBody->GetRowCount();
int col_count = m_pBody->GetColCount();
int fixed_row_count = m_pBody->GetFixedRowCount();
int fixed_col_count = m_pBody->GetFixedColCount();
int row_index = fixed_row_count;
int col_index = fixed_col_count;
if (fixed_row_count == row_count || fixed_col_count == col_count)
return false;
if (ctrl)
{
}
else
{
UiRect rc(row_index, col_index, row_index, col_index);
if (m_vecRange.size() > 0)
rc = m_vecRange[0];
switch (move_key)
{
case VK_LEFT:
row_index = rc.top;
col_index = rc.left - 1;
break;
case VK_UP:
row_index = rc.top - 1;
col_index = rc.left;
break;
case VK_RIGHT:
row_index = rc.bottom;
col_index = rc.right + 1;
break;
case VK_DOWN:
row_index = rc.bottom + 1;
col_index = rc.right;
break;
default:
break;
}
if (row_index >= row_count)
row_index = row_count - 1;
if (col_index >= col_count)
col_index = col_count - 1;
if (row_index < fixed_row_count)
row_index = fixed_row_count;
if (col_index < fixed_col_count)
col_index = fixed_col_count;
SetSelItem(row_index, col_index);
}
if (m_bSelAll)
m_bSelAll = false;
}
void GridSelRange::CtrlCorX(bool cut)
{
if (m_vecRange.size() == 0)
return;
int row_count = m_pBody->GetRowCount();
int col_count = m_pBody->GetColCount();
int fixed_row_count = m_pBody->GetFixedRowCount();
int fixed_col_count = m_pBody->GetFixedColCount();
if (fixed_row_count == row_count || fixed_col_count == col_count)
return;
UiRect rc = m_vecRange[0];
if (rc.left < fixed_col_count)
rc.left = fixed_col_count;
if (rc.top < fixed_row_count)
rc.top = fixed_row_count;
if (rc.right >= col_count)
rc.right = col_count - 1;
if (rc.bottom >= row_count)
rc.bottom = row_count - 1;
std::wstring strContent;
GridItem *pItem = nullptr;
for (int row_index = rc.top; row_index <= rc.bottom; row_index++)
{
GridRow *pRow = m_pBody->m_vecRow[row_index];
for (int col_index = rc.left; col_index <= rc.right; col_index++)
{
pItem = pRow->at(col_index);
assert(pItem);
if (pItem && pItem->IsSelected())
strContent += pItem->text;
if (col_index < rc.right)
strContent += L"\t";
}
if (row_index < rc.bottom)
strContent += L"\r\n";
}
if (strContent.empty())
return;
strContent += L"\0";
if (::OpenClipboard(NULL))
{
if (FALSE == ::EmptyClipboard())
{
::CloseClipboard();
return;
}
HGLOBAL hClip = ::GlobalAlloc(GMEM_MOVEABLE, (strContent.length() + 1) * sizeof(wchar_t));
if (NULL == hClip)
{
::CloseClipboard();
return;
}
wchar_t *pBuf = (wchar_t*)::GlobalLock(hClip);
if (NULL == pBuf)
{
::CloseHandle(hClip);
::CloseClipboard();
return;
}
wcscpy(pBuf, strContent.c_str());
::GlobalUnlock(hClip);
if (NULL == ::SetClipboardData(CF_UNICODETEXT, hClip))
{
::CloseHandle(hClip);
::CloseClipboard();
return;
}
::CloseClipboard();
if (cut)
{
for (int row_index = rc.top; row_index <= rc.bottom; row_index++)
{
GridRow *pRow = m_pBody->m_vecRow[row_index];
for (int col_index = rc.left; col_index <= rc.right; col_index++)
{
pItem = pRow->at(col_index);
assert(pItem);
if (pItem && pItem->IsSelected())
pItem->text = L"";
}
}
m_pBody->Invalidate();
}
}
}
void GridSelRange::CtrlV()
{
int row_count = m_pBody->GetRowCount();
int col_count = m_pBody->GetColCount();
int fixed_row_count = m_pBody->GetFixedRowCount();
int fixed_col_count = m_pBody->GetFixedColCount();
int row_index_start = fixed_row_count;
int col_index_start = fixed_col_count;
if (fixed_row_count == row_count || fixed_col_count == col_count)
return;
std::wstring strClipboard;
if (::OpenClipboard(NULL))
{
if (::IsClipboardFormatAvailable(CF_UNICODETEXT))
{
HGLOBAL hClip = GetClipboardData(CF_UNICODETEXT);
if (NULL == hClip)
{
CloseClipboard();
return;
}
wchar_t *pStr = (wchar_t*)GlobalLock(hClip);
strClipboard = pStr;
GlobalUnlock(hClip);
CloseClipboard();
}
else if (::IsClipboardFormatAvailable(CF_TEXT))
{
HGLOBAL hClip = GetClipboardData(CF_TEXT);
if (NULL == hClip)
{
CloseClipboard();
return;
}
char *pStr = (char*)GlobalLock(hClip);
StringHelper::MBCSToUnicode(pStr, strClipboard);
GlobalUnlock(hClip);
CloseClipboard();
}
}
if (strClipboard.empty())
return;
if (m_vecRange.size() > 0)
{
row_index_start = m_vecRange[0].top;
col_index_start = m_vecRange[0].left;
}
bool bFlash = false;
std::wstring strLine;
std::wstring strItem;
std::wstring strLineNext = strClipboard;
//std::wstring strItemNext;
int pos_rn = -1;
int pos_t = -1;
for (int row = row_index_start; row < row_count; row++)
{
if (strLineNext.empty())
break;
pos_rn = strLineNext.find_first_of(L"\r\n");
if (pos_rn == std::wstring::npos)
{
strLine = strLineNext;
strLineNext = L"";
}
else
{
strLine = strLineNext.substr(0, pos_rn);
strLineNext = strLineNext.substr(pos_rn + 2);
}
GridRow *pRow = m_pBody->m_vecRow[row];
for (int col = col_index_start; col < col_count; col++)
{
if (strLine.empty())
break;
pos_t = strLine.find_first_of(L"\t");
if (pos_t == std::wstring::npos)
{
strItem = strLine;
strLine = L"";
}
else
{
strItem = strLine.substr(0, pos_t);
strLine = strLine.substr(pos_t + 1);
}
pRow->at(col)->text = strItem;
bFlash = true;
wprintf(L"GridSelRange::CtrlV row:%d, col:%d, [%s]\n", row, col, strItem.c_str());
}
}
if (bFlash)
m_pBody->Invalidate();
}
}