// MyCell - version 1.1
// Written by Yanxueming <yanxm2003@hotmail.com>
// Copyright (C) 2006-2007
// All rights reserved.
//
// The code and information is provided "as-is" without
// warranty of any kind, either expressed or implied.
#include "stdafx.h"
#include "../include/Selections.h"
#include "../include/Worksheet.h"
namespace mycell{
/*
void merge_row(vector<RowPair>& vec,int row)
{
for(vector<RowPair>::iterator it=vec.begin();it!=vec.end();++it){
_ASSERT(it->first<=it->second);
if(row>=it->first && row<=it->second){
return;
}else if(row==it->first-1){
--(it->first);
return;
}else if(row==it->second+1){
++(it->second);
return;
}
}
vec.push_back(RowPair(row,row));
}
*/
bool Selections::IsOneCell(CCell& cell)const
{
if(1==vecSelection_.size()){
const CCellRange& cr=*vecSelection_.begin();
if(cr.TopLeft()==cr.RightBottom()){
cell=cr.TopLeft();
return true;
}
}
return false;
}
void Selections::SetActiveSelection(const CCellRange& newActiveSelection)//int leftCol,int topRow,int rightCol,int bottomRow)
{
clear();
_ASSERT(newActiveSelection.IsNormalize());
//CCellRange cr(newActiveSelection);
////cr.set(topRow,leftCol,bottomRow,rightCol);
//cr.Normalize();
//vector<CCellRange>::iterator it=find(vecSelection_.begin(),vecSelection_.end(),newActiveSelection);
//if(it==vecSelection_.end()){
vecSelection_.push_back(newActiveSelection);
nActiveSelectionPos_=0;//static_cast<int>(vecSelection_.size())-1;
//}else
// nActiveSelectionPos_=static_cast<int>(it-vecSelection_.begin());
}
//bool Selections::IsSelectAll()const
//{
// /*
// const CCellRange acr=GetActiveSelection();
// const RowHeader& rh=pSheet_->get_RowHeader();
// const ColHeader& ch=pSheet_->get_ColHeader();
// return HEADER_ROW==acr.TopRow() && HEADER_COL==acr.LeftCol()
// && acr.BottomRow()==rh.get_rows()-1 && acr.RightCol()==ch.get_cols()-1;
// */
// return bSelectAll_;
//}
void Selections::SelectAll(bool AppendSelection)
{
const RowHeader& rh=pSheet_->get_RowHeader();
const ColHeader& ch=pSheet_->get_ColHeader();
const CCellRange cr(CCellRange(HEADER_ROW,HEADER_COL,rh.get_rows()-1,ch.get_cols()-1));
if(AppendSelection)
AddSelection(cr,true);
else{
SetActiveSelection(cr);
}
pSheet_->SetActiveCell<false>(rh.IsFreezeRowVisible()?rh.get_FreezeTopRow():rh.get_TopVisScrollRow()
,ch.IsFreezeColVisible()?ch.get_FreezeLeftCol():ch.get_LeftVisScrollCol());
bSelectAll_=true;
if(pSheet_ && pSheet_->IsWindow()){
pSheet_->RedrawWindow();
}
}
bool Selections::CellInSelections(int row,int col)const
{
for(vector<CCellRange>::const_iterator it=vecSelection_.begin();it!=vecSelection_.end();++it)
{
if((*it).Inside/*<true>*/(row,col))
return true;
}
return false;
}
bool Selections::RowInSelections(int row)const
{
for(vector<CCellRange>::const_iterator it=vecSelection_.begin();it!=vecSelection_.end();++it)
{
if(it->RowInside(row))
return true;
}
return false;
}
bool Selections::ColInSelections(int col)const
{
for(vector<CCellRange>::const_iterator it=vecSelection_.begin();it!=vecSelection_.end();++it)
{
if(it->ColInside(col))
return true;
}
return false;
}
/*
//void Selections::xor(const Selections& rhs,vector<CCell>& vec)const
void Selections::Subtract(const Selections& rhs,vector<CCell>& vec,const CCellRange* pClip)const
{
CCell cell;
CCellRange cr;
for(vector<CCellRange>::const_iterator it=vecSelection_.begin();it!=vecSelection_.end();++it)
{
//const CCellRange& cr=*it;
if(!pClip->GetInterset(*it,cr))
continue;
int minr=cr.TopLeft().row,maxr=cr.RightBottom().row,
minc=cr.TopLeft().col,maxc=cr.RightBottom().col;
//MinMax<int>(cr.first.row,cr.second.row,minr,maxr);
//MinMax<int>(cr.first.col,cr.second.col,minc,maxc);
for(int r=minr;r<=maxr;++r){
for(int c=minc;c<=maxc;++c){
if(!rhs.CellInSelections(r,c)){
cell.set(r,c);
vec.push_back(cell);
}
}
}
}
}
*/
void Selections::Xor(const Selections& rhs,CRgnLight& rgn,const CCellRange* pClip)const
{
CCellRange cr;
CRgnLight rgn1,rgn2;
vector<CCellRange>::const_iterator it;
for(it=vecSelection_.begin();it!=vecSelection_.end();++it)
{
if(!pClip->GetInterset(*it,cr))
continue;
rgn1.AddRect(pSheet_->get_RangeRect(cr));
}
for(it=rhs.vecSelection_.begin();it!=rhs.vecSelection_.end();++it)
{
if(!pClip->GetInterset(*it,cr))
continue;
rgn2.AddRect(pSheet_->get_RangeRect(cr));
}
rgn.Copy(rgn1);
rgn.Substract(rgn2);
rgn2.Substract(rgn1);
rgn.Combine(rgn2);
}
/*
//��߽������
void Selections::AdjoinEdge(const Selections& rhs,CRgnLight& rgn,const CCellRange* pClip)const
{
Selections ss(pSheet_),ss1(pSheet_);
vector<CCellRange> vtmp;
for(vector<CCellRange>::const_iterator it=vecSelection_.begin();it!=vecSelection_.end();++it)
{
it->GetEdges(vtmp);
ss.vecSelection_.insert(ss.vecSelection_.end(),vtmp.begin(),vtmp.end());
vtmp.clear();
}
vector<CCell> vec;
ss.Clip(*pClip,vec);
for(vector<CCellRange>::const_iterator it=rhs.vecSelection_.begin();it!=rhs.vecSelection_.end();++it)
{
it->GetEdges(vtmp);
ss1.vecSelection_.insert(ss1.vecSelection_.end(),vtmp.begin(),vtmp.end());
vtmp.clear();
}
int const rows=pSheet_->get_RowHeader().get_rows();
int const cols=pSheet_->get_ColHeader().get_cols();
for(vector<CCell>::const_iterator it=vec.begin();it!=vec.end();++it){
if(it->row<rows-1){
CCell cell={it->row+1,it->col};
if(!ss.CellInSelections(cell) && ss1.CellInSelections(cell)){
rgn.AddRect(pSheet_->raw_GetCellRect(*it));
}
}
if(it->row>0){
CCell cell={it->row-1,it->col};
if(!ss.CellInSelections(cell) && ss1.CellInSelections(cell)){
rgn.AddRect(pSheet_->raw_GetCellRect(*it));
}
}
if(it->col<cols-1){
CCell cell={it->row,it->col+1};
if(!ss.CellInSelections(cell) && ss1.CellInSelections(cell)){
rgn.AddRect(pSheet_->raw_GetCellRect(*it));
}
}
if(it->col>0){
CCell cell={it->row,it->col-1};
if(!ss.CellInSelections(cell) && ss1.CellInSelections(cell)){
rgn.AddRect(pSheet_->raw_GetCellRect(*it));
}
}
}
}
//-------------------------------------------------------------------------//
//��ѡ��cr��ñ�ѡ����µ�ѡ��retval
//-------------------------------------------------------------------------//
void Selections::Clip(const CCellRange& cr,vector<CCell>& vec)const
{
CCellRange tmp;
for(vector<CCellRange>::const_iterator it=vecSelection_.begin();it!=vecSelection_.end();++it)
{
if(cr.GetInterset(*it,tmp)){
tmp.Extract(vec);
}
}
}
*/
//void Selections::EnumSelection(vector<CCellRange>& vec,Int2Type<true>)const
//{
// vec=vecSelection_;
// for(vector<CCellRange>::iterator it=vec.begin();it!=vec.end();++it)
// pSheet_->AdjustSelection(*it);
//}
//�����Ǻϲ���Ԫ����������˸÷�������
//�Ͳ�ε��ã�����ʹ��Ӧ���Ǻϲ���Ԫ������
ECellBGShrinkState Selections::get_CellBGShrinkState(int row,int col)const
{
_ASSERT(row>=0);
_ASSERT(col>=0);
if(!CellInSelections(row,col))
return ECBSS_SHRINK_NONE;
const RowHeader& rh=pSheet_->get_RowHeader();
const ColHeader& ch=pSheet_->get_ColHeader();
int const rows=rh.get_rows();
int const cols=ch.get_cols();
_ASSERT(row<rows);
_ASSERT(col<cols);
int ecs=0;
Selections ss(pSheet_);
for(vector<CCellRange>::const_iterator it=vecSelection_.begin();it!=vecSelection_.end();++it)
{
if(it->Inside(row,col))
ss.AddSelection(*it,false);
}
if(0==col || !ss.CellInSelections(row,col-1)){
ecs|=ECBSS_SHRINK_LEFT;
}
if(0==row || !ss.CellInSelections(row-1,col)){
ecs|=ECBSS_SHRINK_TOP;
}
if(cols-1==col || !ss.CellInSelections(row,col+1)){
ecs|=ECBSS_SHRINK_RIGHT;
}
if(rows-1==row || !ss.CellInSelections(row+1,col)){
ecs|=ECBSS_SHRINK_BOTTOM;
}
if(!(ECBSS_SHRINK_LEFT&ecs)&&!(ECBSS_SHRINK_TOP&ecs)
&&!ss.CellInSelections(row-1,col-1))
{
ecs|=ECBSS_SHRINK_LEFTTOP;
}
if(!(ECBSS_SHRINK_RIGHT&ecs)&&!(ECBSS_SHRINK_TOP&ecs)
&&!ss.CellInSelections(row-1,col+1)){
ecs|=ECBSS_SHRINK_RIGHTTOP;
}
//
if(!(ECBSS_SHRINK_LEFT&ecs)&&!(ECBSS_SHRINK_LEFTBOTTOM&ecs)
&&!ss.CellInSelections(row+1,col-1)){
ecs|=ECBSS_SHRINK_LEFTBOTTOM;
}
if(!(ECBSS_SHRINK_RIGHT&ecs)&&!(ECBSS_SHRINK_LEFTBOTTOM&ecs)
&&!ss.CellInSelections(row+1,col+1)){
ecs|=ECBSS_SHRINK_RIGHTBOTTOM;
}
return (ECellBGShrinkState)ecs;
}
//[beg,end]
void Selections::OnColDelete(int beg,int end)
{
/*
int const cols=pSheet_->get_ColHeader().get_cols();
for(vector<CCellRange>::iterator it=vecSelection_.begin();it!=vecSelection_.end();++it){
int const leftCol=it->TopRow();
if(HEADER_COL==leftCol || it->RightCol()>=cols){
const int rightCol=cols-1;
if(leftCol>rightCol)
it->SetLeftCol(rightCol);
it->SetRightCol(rightCol);
}
}
*/
}
//[beg,end]
void Selections::OnRowDelete(int beg,int end)
{
/*
//if(pSheet_->IsWindow())
{
int const rows=pSheet_->get_RowHeader().get_rows();
for(vector<CCellRange>::iterator it=vecSelection_.begin();it!=vecSelection_.end();++it){
int const topRow=it->TopRow();
if(HEADER_ROW==topRow || it->BottomRow()>=rows){
const int bottomRow=rows-1;
if(topRow>bottomRow)
it->SetTopRow(bottomRow);
it->SetBottomRow(bottomRow);
}
}
}
*/
}
void Selections::OnRowInsertFront(int beg,int nCount)
{
/*
if(pSheet_->IsWindow())
{
int const rows=pSheet_->get_RowHeader().get_rows();
for(vector<CCellRange>::reverse_iterator it=vecSelection_.rbegin();it!=vecSelection_.rend();++it){
int const topRow=it->TopRow();
if(HEADER_ROW==topRow || it->BottomRow()>=rows){
it->SetBottomRow(rows-1);
}
if(topRow<=rows && HEADER_ROW!=topRow){
vecSelection_.pop_back();
}
}
}
*/
}
void Selections::OnMergeCells(int minR,int minC,int maxR,int maxC)
{
//const Selections oss=this;
const CCellRange mcr(minR,minC,maxR,maxC);
_ASSERT(mcr.IsNormalize());
for(vector<CCellRange>::iterator it=vecSelection_.begin();it!=vecSelection_.end();++it){
_ASSERT(it->IsNormalize());
if(it->IsIntersect(mcr)){
if(it->LeftCol()>minC)
it->SetLeftCol(minC);
if(it->RightCol()<maxC)
it->SetRightCol(maxC);
if(it->TopRow()>minR)
it->SetTopRow(minR);
if(it->BottomRow()<maxR)
it->SetBottomRow(maxR);
}
}
//InvalidateContent(pSheet_->GetActiveCell(),oss);
}
void Selections::ValidateSelections()
{
int const rows=pSheet_->get_RowHeader().get_rows();
int const cols=pSheet_->get_ColHeader().get_cols();
for(vector<CCellRange>::reverse_iterator it=vecSelection_.rbegin();it!=vecSelection_.rend();++it){
int const topRow=it->TopRow();
int const leftCol=it->LeftCol();
if(HEADER_ROW==topRow || it->BottomRow()>=rows){
it->SetBottomRow(rows-1);
}
if(topRow>=rows && HEADER_ROW!=topRow){
vecSelection_.pop_back();
continue;
}
if(HEADER_COL==leftCol || it->RightCol()>=cols){
it->SetRightCol(cols-1);
}
if(leftCol>=cols && HEADER_COL!=leftCol){
vecSelection_.pop_back();
}
}
CCell acell=pSheet_->GetActiveCell();
if(acell.row>=rows)
acell.row=min(0,rows-1);
if(acell.col>=cols)
acell.col=min(0,cols-1);
if(vecSelection_.empty()){
vecSelection_.push_back(CCellRange(acell));
}
if(nActiveSelectionPos_<int(vecSelection_.size())){
nActiveSelectionPos_=0;
}
}
/*
ECellState Selections::get_CellState(int row,int col)const
{
int ecs=0;
vector<ECellState> vecCellState;
for(vector<CCellRange>::const_iterator it=vecSelection_.begin();it!=vecSelection_.end();++it)
{
ECellState e=it->get_CellState(row,col);
if(ECS_FULLINNER&e)
return ECS_FULLINNER;
ecs|=e;
if(it->Inside(row,col))
vecCellState.push_back(e);
}
if(ECS_OUTOF_SELECTION==ecs)
return (ECellState)ecs;
//bool bInnerLeft=ECS_INNER_LEFT&ecs;
//bool bInnerRight=ECS_INNER_RIGHT&ecs;
//bool bInnerTop=ECS_INNER_TOP&ecs;
//bool bInnerBottom=ECS_INNER_BOTTOM&ecs;
for(vector<ECellState>::const_iterator it=vecCellState.begin();it!=vecCellState.end();++it){
if(!(ECS_INNER_LEFT&(*it))){
ecs&=~ECS_INNER_LEFT;
//bInnerLeft=false;
}
if(!(ECS_INNER_RIGHT&(*it)))
ecs&=~ECS_INNER_RIGHT;
//bInnerRight=false;
if(!(ECS_INNER_TOP&(*it)))
ecs&=~ECS_INNER_TOP;
//bInnerTop=false;
if(!(ECS_INNER_BOTTOM&(*it)))
ecs&=~ECS_INNER_BOTTOM;
//bInnerBottom=false;
}
//ECS_OUTOF_SELECTION=1<<0,//��Ԫ����ȫ��ѡ���Ⲣ����ѡ���ı߿�����
//ECS_FULLINNER=1<<1,//��Ԫ����ȫ��ѡ���ڲ�����ѡ���ı߿�����
//ECS_INNER_LEFT=1<<2,//��Ԫ����ѡ���ڲ���ѡ����߿�����
//ECS_INNER_TOP=1<<3,//ѡ���ڿ���
//ECS_INNER_RIGHT=1<<4,//ѡ���ڿ���
//ECS_INNER_BOTTOM=1<<5,//ѡ���ڿ���
//ECS_OUTER_LEFT=1<<6,//ѡ������ѡ����߿�����
//ECS_OUTER_TOP=1<<7,//ѡ������ѡ���ϱ߿�����
//ECS_OUTER_RIGHT=1<<8,//ѡ������ѡ���ұ߿�����
//ECS_OUTER_BOTTOM=1<<9,//ѡ������ѡ���±߿�����
//if((ECS_INNER_LEFT & ecs) && (ECS_OUTER_LEFT & ecs)){
// ecs&=~(ECS_INNER_LEFT|ECS_OUTER_LEFT);
//}
return static_cast<ECellState>(ecs);
}
*/
}//namespace mycell