/* -------------------------------------------------------------------------
//MyCell Library - MyCell version 1.0
//
// This file is a part of the MyCell Library.
// The use and distribution terms for this software are covered by the
// Common Public License 1.0 (http://opensource.org/licenses/cpl.php)
// which can be found in the file CPL.txt at this distribution. By using
// this software in any fashion, you are agreeing to be bound by the terms
// of this license. You must not remove this notice, or any other, from
// this software.
//
// Creator: yanxueming
// Email: xueming.yan@gmail.com
// -----------------------------------------------------------------------*/
#include "stdafx.h"
#include "../include/PasteFromClipboard.h"
#include "../include/scanner.h"
#include "../include/Worksheet.h"
#include "../include/Text.h"
//#include <boost/spirit.hpp>
namespace mycell{
typedef Scanner<wchar_t> scan_t;
typedef scan_t::value_type value_t;
struct line_p
{
bool parse(scan_t& scan)
{
begin=scan.GetCurrentPos();
for(end=begin;end<scan.GetEndPos()/*-1*/;end=scan.ForwardOneStep())
{
if(end<scan.GetEndPos()-1 && *end==0x0D && *(end+1)==0x0A)
{
++end;
scan.ForwardOneStep();
scan.ForwardOneStep();
return true;
}
}
end=scan.GetEndPos();
return begin!=end;
}
value_t* begin;
value_t* end;
};
struct column_p
{
bool parse(scan_t& scan)
{
begin=scan.GetCurrentPos();
for(end=begin;end<scan.GetEndPos();end=scan.ForwardOneStep())
{
if(*end==0x09)
{
scan.ForwardOneStep();
//scan.ForwardOneStep();
return true;
}else if(*end==0x0D){
return true;
}
}
return begin!=end++;
}
value_t* begin;
value_t* end;
};
bool Worksheet::CanPaste()
{
bool bCanPaste=false;
if(::OpenClipboard(0)){
UINT format=0;
while(format=EnumClipboardFormats(format))
{
if(CF_UNICODETEXT==format){
bCanPaste=true;
break;
}
}
CloseClipboard();
}
return bCanPaste;
}
HRESULT Worksheet::PasteFromClipboard(/*Worksheet* pSheet,*/int row1,int col1,int row2,int col2)
{
//BOOL bRet=TRUE;
Worksheet* pSheet=this;
HRESULT hr=S_OK;
if(::OpenClipboard(0)){
StyleDesc style;
UINT format=0;
while(format=EnumClipboardFormats(format))
{
if(CF_UNICODETEXT!=format) continue;
HGLOBAL hglb=GetClipboardData(CF_UNICODETEXT);
if(hglb){
wchar_t* lpstr=(wchar_t*)GlobalLock(hglb);
if(lpstr){
scan_t scan(lpstr,lpstr+wcslen(lpstr));
line_p lp;
column_p cp;
//NMOCNCELLDISPINFO disp;
for(;row1<=row2 && lp.parse(scan);row1=pSheet->GetNextRow(row1))
{
scan_t sc(lp.begin,lp.end);
#pragma warning(disable:4244)
int count=std::count(lp.begin,lp.end,0x09)+1;
#pragma warning(default:4244)
if(count>col2-col1+1) count=col2-col1+1;
for(int x=col1;count>=0 && x<=col2;--count){
if(!cp.parse(sc))
continue;
const CCell cell(row1,x);
value_t ch=*cp.end;
*cp.end=0;
CString strText(cp.begin);
*cp.end=ch;
//CString strText(bstrText);
const BOOL bHasReturnChar=Text_HasReturnChar(strText,strText.GetLength());
if(bHasReturnChar){
CString strTmp;
if(strText[0]==_T('"'))
strTmp=strText.Right(strText.GetLength()-1);
if(strText.ReverseFind(_T('"'))==strText.GetLength()-1)
strTmp=strTmp.Left(strTmp.GetLength()-1);
strText=strTmp;
strTmp.Empty();
int i=0;
for(;;){
int iFind=strText.Find(_T('"'),i);
if(iFind<0){
strTmp+=strText.Mid(i,strText.GetLength()-i);
break;
}
if(iFind<strText.GetLength()-1 && strText[iFind+1]==_T('"')){
strTmp+=strText.Mid(i,iFind-i+1);
i=iFind+2;
continue;
}
strTmp+=strText.Mid(i,iFind-i+1);
i=iFind+1;
/*
if(iFind==strText.GetLength()-1){
const int cnt=strText.GetLength()-i-1;
if(cnt>0)
strTmp+=strText.Mid(i,cnt);
break;
}
if(iFind<strText.GetLength()-2 && strText[iFind+1]==_T('"')
&&strText[iFind+2]==_T('"')){
strTmp+=strText.Mid(i,iFind-i+3);
i=iFind+3;
continue;
}
if(iFind<strText.GetLength()-1 && strText[iFind+1]==_T('"')){
strTmp+=strText.Mid(i,iFind-i+2);
i=iFind+2;
continue;
}
if(iFind>i)
strTmp+=strText.Mid(i,iFind-i+1);
i=iFind+1;
*/
}
strText=strTmp;
//strText.Replace(_T("\"\"\""),_T("\""));
//strText.Replace(_T("\"\""),_T("\""));
const CCell cell(row1,x);
style=pSheet->Style_GetCellStyle(cell);
style.Align_SetWrapText(TRUE);
pSheet->Style_SetCellStyle(cell,style);
}
const CMergeCell* pMerge=pSheet->GetMergeCells(cell);
if(!pMerge || pMerge->TopLeft()==cell){
pSheet->SetCellText(cell,CComVariant(strText),FALSE);
RECT rc=GetVisibleCellRectEx(cell);
InvalidateRect(&rc,FALSE);
}else
pSheet->InvalidateCell(cell);
int const newCol=pSheet->GetNextCol(x);
if(newCol==x)
break;
x=newCol;
}
}
UpdateWindow();
}else{
hr=S_FALSE;
//bRet=FALSE;//xm::misc::FormatMessage(hWndListener_);
}
GlobalUnlock(hglb);
}
}
CloseClipboard();
}else{
//bRet=FALSE;
hr=S_FALSE;
}
UpdateWindow();
return hr;
}
}//namespace mycell