Commit d392ee1b authored by Elen.Subbotina's avatar Elen.Subbotina Committed by Alexander Trofimov

XlsFormat - гиперлинки внутри таблицы с графических объектов, правильная...

XlsFormat - гиперлинки внутри таблицы с графических объектов, правильная конвертация с кодировкой 1200 (половинчатая wchar_t) Cálculo De Horas Extras (Completa).xls

git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@67746 954022d7-b5bf-4e40-9824-e11837661b57
parent 00ccca6c
......@@ -533,30 +533,28 @@ const std::string toStdString(std::wstring wide_string, const unsigned int code_
#endif
}
const std::wstring toStdWString(std::string ansi_string, const unsigned int code_page)
{
#if defined (_WIN32) || defined (_WIN64)
const int nSize = MultiByteToWideChar(code_page, 0, ansi_string.c_str(), ansi_string.size(), NULL, 0);
const std::wstring toStdWString(char* ansi, int size, const unsigned int code_page)
{
#if defined (_WIN32) || defined (_WIN64)
const int nSize = MultiByteToWideChar(code_page, 0, ansi, size, NULL, 0);
wchar_t *sTemp = new wchar_t[nSize];
if (!sTemp)
return std::wstring();
int size = MultiByteToWideChar(code_page, 0, ansi_string.c_str(), ansi_string.size(), sTemp, nSize);
int size_out = MultiByteToWideChar(code_page, 0, ansi, size, sTemp, nSize);
std::wstring sResult(sTemp, size);
std::wstring sResult(sTemp, size_out);
delete []sTemp;
return sResult;
#else
bool ansi = true;
bool bAnsi = true;
size_t insize = ansi_string.length();
size_t insize = size;
std::wstring w_out;
char *inptr = (char*)ansi_string.c_str();
char *inptr = ansi;
if (code_page >= 0)
{
......@@ -576,17 +574,25 @@ const std::wstring toStdWString(std::string ansi_string, const unsigned int code
insize = ansi_string.length();
((wchar_t*)out_str)[insize] = 0;
w_out = std::wstring((wchar_t*)out_str, insize);
ansi = false;
bAnsi = false;
}
iconv_close(ic);
delete []out_str;
}
}
if (ansi)
if (bAnsi)
{
std::string ansi_string(ansi, size);
w_out = std::wstring(ansi_string.begin(), ansi_string.end());
}
return w_out;
#endif
}
const std::wstring toStdWString(std::string ansi_string, const unsigned int code_page)
{
return toStdWString((char*)ansi_string.c_str(), (int)ansi_string.length(), code_page);
}
#endif
......
......@@ -58,6 +58,7 @@ namespace STR
const std::string toStdString (std::wstring wide_string, const unsigned int code_page);
const std::wstring toStdWString(std::string ansi_string, const unsigned int code_page);
const std::wstring toStdWString(char* ansi, int size, const unsigned int code_page);
};
namespace XMLSTUFF
......
......@@ -22,14 +22,8 @@ public:
static const ElementType type = typeCountry;
//-----------------------------
BIFF_WORD iCountryDef;
BIFF_WORD iCountryWinIni;
public:
//BO_ATTRIB_MARKUP_BEGIN
//BO_ATTRIB_MARKUP_ATTRIB(iCountryDef)
//BO_ATTRIB_MARKUP_ATTRIB(iCountryWinIni)
//BO_ATTRIB_MARKUP_END
};
......
......@@ -22,11 +22,6 @@ public:
void readFields(CFRecord& record);
//-----------------------------
BIFF_WORD codePage;
public:
//BO_ATTRIB_MARKUP_BEGIN
//BO_ATTRIB_MARKUP_ATTRIB(codePage)
//BO_ATTRIB_MARKUP_END
};
} // namespace XLS
......@@ -86,16 +86,36 @@ void BiffString::load(CFRecord& record, const size_t cch1, const bool is_wide1)
if(is_wide)
{
#if defined(_WIN32) || defined(_WIN64)
std::wstring int_str(record.getCurData<wchar_t>(), cch);
str_ = int_str.c_str();
std::wstring inp_str(record.getCurData<wchar_t>(), cch);
str_ = inp_str.c_str();
#else
str_= convertUtf16ToWString(record.getCurData<UTF16>(), cch);
#endif
}
else
{
std::string int_str(record.getCurData<char>(), cch);
str_ = STR::toStdWString(int_str, record.getGlobalWorkbookInfo()->CodePage).c_str();
std::string inp_str(record.getCurData<char>(), cch);
if (record.getGlobalWorkbookInfo()->CodePage == 1200)
{
int inp_str_size = inp_str.length();
wchar_t *out_str = new wchar_t[inp_str_size + 1];
char* out_str_char = (char*) out_str;
for (int i = 0; i < inp_str_size; i++)
{
out_str_char[2*i+0] = inp_str.c_str()[i];
out_str_char[2*i+1] = 0;
}
out_str[inp_str_size] = 0;
str_ = std::wstring(out_str, inp_str_size);
delete []out_str;
}
else
{
str_ = STR::toStdWString(inp_str, record.getGlobalWorkbookInfo()->CodePage).c_str();
}
}
record.skipNunBytes(raw_length);
}
......
......@@ -21,6 +21,7 @@ XLUnicodeRichExtendedString::XLUnicodeRichExtendedString(std::list<CFRecordPtr>&
fHighByte(true),
extRst(cont_recs)
{
code_page_ = 0;
}
const bool XLUnicodeRichExtendedString::appendNextContinue(CFRecord& record, const bool read_high_byte)
......@@ -60,7 +61,11 @@ const bool XLUnicodeRichExtendedString::appendNextContinue(CFRecord& record, con
XLUnicodeRichExtendedString::~XLUnicodeRichExtendedString()
{
code_page_ = 0;
}
void XLUnicodeRichExtendedString::set_code_page(short cp)
{
code_page_ = cp;
}
......@@ -304,8 +309,27 @@ void XLUnicodeRichExtendedString::loadSymbols(CFRecord& record, const size_t cch
}
else
{
std::string int_str(record.getCurData<char>(), cch);
str_ = STR::toStdWString(int_str, record.getGlobalWorkbookInfo()->CodePage).c_str();
std::string inp_str(record.getCurData<char>(), cch);
if (record.getGlobalWorkbookInfo()->CodePage == 1200)
{
int inp_str_size = inp_str.length();
wchar_t *out_str = new wchar_t[inp_str_size + 1];
char* out_str_char = (char*) out_str;
for (int i = 0; i < inp_str_size; i++)
{
out_str_char[2*i+0] = inp_str.c_str()[i];
out_str_char[2*i+1] = 0;
}
out_str[inp_str_size] = 0;
str_ = std::wstring(out_str, inp_str_size);
delete []out_str;
}
else
{
str_ = STR::toStdWString(inp_str, record.getGlobalWorkbookInfo()->CodePage).c_str();
}
}
record.skipNunBytes(raw_length);
}
......
......@@ -26,7 +26,7 @@ public:
int serialize (std::wostream & _stream);
int serialize_rPr (std::wostream & _stream, int iFmt);
void set_code_page(short cp) {code_page_ = cp;}
void set_code_page(short cp) ;
virtual void load (CFRecord& record);
virtual void store (CFRecord& record);
......
......@@ -134,7 +134,18 @@ const bool GlobalsSubstream::loadContent(BinProcessor& proc)
proc.mandatory<INTERFACE_T>();
proc.mandatory<WriteAccess>();
proc.optional<FileSharing>();
proc.mandatory<CodePage>();
if (proc.mandatory<CodePage>())
{
m_CodePage = elements_.back();
elements_.pop_back();
CodePage *CodePage_ = dynamic_cast<CodePage*>(m_CodePage.get());
if ((CodePage_) && (CodePage_->cv != 0/* && CodePage_->cv != 1200*/))
code_page_ = CodePage_->cv;
proc.getGlobalWorkbookInfo()->CodePage = code_page_;
}
proc.repeated<Lel>(0, 2047);
proc.mandatory<DSF>();
proc.optional<Excel9File>();
......@@ -156,7 +167,20 @@ const bool GlobalsSubstream::loadContent(BinProcessor& proc)
proc.mandatory<CalcPrecision>();
proc.mandatory<RefreshAll>();
proc.mandatory<BookBool>();
proc.optional<Country>(); // OpenOffice Calc stored files workaround
if (proc.optional<Country>()) // OpenOffice Calc stored files workaround
{
m_Country = elements_.back();
elements_.pop_back();
Country *Country_ = dynamic_cast<Country*>(m_Country.get());
if (Country_)
{
int countryDef = Country_->iCountryDef;
int countryWinIni = Country_->iCountryWinIni;
proc.getGlobalWorkbookInfo()->CodePage;
}
}
proc.optional<UsesELFs>(); // OpenOffice Calc stored files workaround
proc.optional<RecalcId>(); // OpenOffice Calc stored files workaround
proc.repeated<Window1>(0, 0); // OpenOffice Calc stored files workaround
......@@ -183,7 +207,20 @@ const bool GlobalsSubstream::loadContent(BinProcessor& proc)
proc.optional<MTRSettings>();
proc.optional<ForceFullCalculation>();
proc.optional<Country>();
if (proc.optional<Country>())
{
m_Country = elements_.back();
elements_.pop_back();
Country *Country_ = dynamic_cast<Country*>(m_Country.get());
if (Country_)
{
int countryDef = Country_->iCountryDef;
int countryWinIni = Country_->iCountryWinIni;
proc.getGlobalWorkbookInfo()->CodePage;
}
}
proc.repeated<SUPBOOK>(0, 0);
count = proc.repeated<LBL>(0, 0);
......
......@@ -29,6 +29,8 @@ public:
BaseObjectPtr m_Formating;
BaseObjectPtr m_Template;
BaseObjectPtr m_SHAREDSTRINGS;
BaseObjectPtr m_CodePage;
BaseObjectPtr m_Country;
std::vector<BaseObjectPtr> m_arHFPicture;
std::vector<BaseObjectPtr> m_arLBL;
......
#include "CodePageOle.h"
#include <Binary/CFStream.h>
#include <Auxiliary/HelpFunc.h>
namespace OLEPS
{
CodePageOle::CodePageOle(const unsigned short value_type, XLS::CFStreamPtr stream)
PropertyCodePage::PropertyCodePage(const unsigned short value_type, XLS::CFStreamPtr stream)
{
//ASSERT(value_type == Property::VT_I2);
*stream >> code_page;
}
PropertyTitle::PropertyTitle(const unsigned short value_type, XLS::CFStreamPtr stream)
{
//ASSERT(value_type == Property::VT_LPSTR);
_UINT32 size;
*stream >> size;
if (size > 0)
{
char *s = new char[size];
stream->read(s,size);
title = STR::toStdWString(s, size, 0);
delete []s;
}
}
PropertySubject::PropertySubject(const unsigned short value_type, XLS::CFStreamPtr stream)
{
//ASSERT(value_type == Property::VT_LPSTR);
_UINT32 size;
*stream >> size;
if (size > 0)
{
char *s = new char[size];
stream->read(s,size);
subject = STR::toStdWString(s, size, 0);
delete []s;
}
}
PropertyAuthor::PropertyAuthor(const unsigned short value_type, XLS::CFStreamPtr stream)
{
//ASSERT(value_type == Property::VT_LPSTR);
_UINT32 size;
*stream >> size;
if (size > 0)
{
char *s = new char[size];
stream->read(s, size);
author = STR::toStdWString(std::string(s,size), 0);
delete []s;
}
}
PropertyKeywords::PropertyKeywords(const unsigned short value_type, XLS::CFStreamPtr stream)
{
//ASSERT(value_type == Property::VT_LPSTR);
_UINT32 size;
*stream >> size;
if (size > 0)
{
char *s = new char[size];
stream->read(s,size);
keywords = STR::toStdWString(std::string(s,size), 0);
delete []s;
}
}
const unsigned short CodePageOle::GetCodePage()
PropertyComments::PropertyComments(const unsigned short value_type, XLS::CFStreamPtr stream)
{
return code_page;
//ASSERT(value_type == Property::VT_LPSTR);
_UINT32 size;
*stream >> size;
if (size > 0)
{
char *s = new char[size];
stream->read(s,size);
comments = STR::toStdWString(s, size, 0);
delete []s;
}
}
PropertyDateCreate::PropertyDateCreate(const unsigned short value_type, XLS::CFStreamPtr stream)
{
//ASSERT(value_type == Property::VT_FILETIME);
_UINT32 dwLowDateTime, dwHighDateTime;
*stream >> dwLowDateTime >> dwHighDateTime;
}
} // namespace OLEPS
......@@ -6,21 +6,73 @@
namespace OLEPS
{
class CodePageOle : public Property
class PropertyCodePage : public Property
{
public:
CodePageOle(const unsigned short value_type, XLS::CFStreamPtr stream);
PropertyCodePage(const unsigned short value_type, XLS::CFStreamPtr stream);
static const unsigned int Type = 0x0001;
static const unsigned short DefaultCodePage = 1250;
const unsigned short GetCodePage();
private:
unsigned short code_page;
};
typedef boost::shared_ptr<PropertyCodePage> PropertyCodePagePtr;
//-----------------------------------------------------------------------------------------
class PropertyTitle : public Property
{
public:
PropertyTitle(const unsigned short value_type, XLS::CFStreamPtr stream);
static const unsigned int Type = 0x0002;
typedef boost::shared_ptr<CodePageOle> CodePagePropertyPtr;
std::wstring title;
};
typedef boost::shared_ptr<PropertyTitle> PropertyTitlePtr;
//-----------------------------------------------------------------------------------------
class PropertySubject : public Property
{
public:
PropertySubject(const unsigned short value_type, XLS::CFStreamPtr stream);
static const unsigned int Type = 0x0003;
std::wstring subject;
};
typedef boost::shared_ptr<PropertySubject> PropertySubjectPtr;
//-----------------------------------------------------------------------------------------
class PropertyAuthor : public Property
{
public:
PropertyAuthor(const unsigned short value_type, XLS::CFStreamPtr stream);
static const unsigned int Type = 0x0004;
std::wstring author;
};
typedef boost::shared_ptr<PropertyAuthor> PropertyAuthorPtr;
//-----------------------------------------------------------------------------------------
class PropertyKeywords : public Property
{
public:
PropertyKeywords(const unsigned short value_type, XLS::CFStreamPtr stream);
static const unsigned int Type = 0x0005;
std::wstring keywords;
};
typedef boost::shared_ptr<PropertyKeywords> PropertyKeywordsPtr;
//-----------------------------------------------------------------------------------------
class PropertyComments : public Property
{
public:
PropertyComments(const unsigned short value_type, XLS::CFStreamPtr stream);
static const unsigned int Type = 0x0006;
std::wstring comments;
};
typedef boost::shared_ptr<PropertyComments> PropertyCommentsPtr;
//-----------------------------------------------------------------------------------------
class PropertyDateCreate : public Property
{
public:
PropertyDateCreate(const unsigned short value_type, XLS::CFStreamPtr stream);
static const unsigned int Type = 0x000c;
std::wstring dateCreate;
};
typedef boost::shared_ptr<PropertyDateCreate> PropertyDateCreatesPtr;
} // namespace OLEPS
......@@ -21,8 +21,20 @@ PropertyPtr PropertyFactory::ReadProperty(const unsigned int prop_type, XLS::CFS
switch(prop_type)
{
case CodePageOle::Type:
return PropertyPtr(new CodePageOle(value_type, stream));
case 0x01://CodePage::Type:
return PropertyPtr(new PropertyCodePage(value_type, stream));
case 0x02://TITLE
return PropertyPtr(new PropertyTitle(value_type, stream));
case 0x03://SUBJECT
return PropertyPtr(new PropertySubject(value_type, stream));
case 0x04://AUTHOR
return PropertyPtr(new PropertyAuthor(value_type, stream));
case 0x05://KEYWORDS
return PropertyPtr(new PropertyKeywords(value_type, stream));
case 0x06://COMMENTS
return PropertyPtr(new PropertyComments(value_type, stream));
case 0x0C://CREATE_DTM
return PropertyPtr(new PropertyDateCreate(value_type, stream));
default:
return PropertyPtr();
......
......@@ -26,7 +26,7 @@ PropertySet::PropertySet(XLS::CFStreamPtr stream, const unsigned int property_se
prop_offsets.push_back(prop_offset);
}
code_page = CodePageOle::DefaultCodePage;
code_page = PropertyCodePage::DefaultCodePage;
for(unsigned int i = 0; i < NumProperties; ++i)
{
PropertyPtr next_property = PropertyFactory::ReadProperty(prop_offsets[i].PropertyIdentifier, stream, property_set_offset + prop_offsets[i].Offset);
......@@ -34,10 +34,10 @@ PropertySet::PropertySet(XLS::CFStreamPtr stream, const unsigned int property_se
{
properties.push_back(next_property);
CodePagePropertyPtr code_page_property = boost::dynamic_pointer_cast<CodePageOle>(next_property);
if(code_page_property)
PropertyCodePagePtr property_CodePage = boost::dynamic_pointer_cast<PropertyCodePage>(next_property);
if(property_CodePage)
{
code_page = code_page_property->GetCodePage();
code_page = property_CodePage->code_page;
}
}
}
......
......@@ -21,7 +21,7 @@ public:
virtual const bool loadContent(BinProcessor& proc);
static const unsigned short DefaultCodePage = OLEPS::CodePageOle::DefaultCodePage;
static const unsigned short DefaultCodePage = OLEPS::PropertyCodePage::DefaultCodePage;
void set_code_page(const unsigned short code_page);
......
......@@ -104,15 +104,14 @@ XlsConverter::XlsConverter(const std::wstring & xls_file, const std::wstring & _
if(summary)
{
OLEPS::SummaryInformation summary_info(summary);
workbook_code_page = summary_info.GetCodePage();
workbook_code_page = summary_info.GetCodePage(); //from software last open
}
else if(doc_summary)
if(doc_summary)
{
OLEPS::SummaryInformation doc_summary_info(doc_summary);
workbook_code_page = doc_summary_info.GetCodePage();
workbook_code_page = doc_summary_info.GetCodePage();
}
if(1200/* UTF-16 */ == workbook_code_page || 0/*error*/ == workbook_code_page)
if( 0/*error*/ == workbook_code_page)//|| 65001 /*UTF-8*/ == workbook_code_page || 1200/* UTF-16 */ == workbook_code_page
{
workbook_code_page = XLS::WorkbookStreamObject::DefaultCodePage;
}
......@@ -1143,8 +1142,23 @@ void XlsConverter::convert_group_shape(std::vector<ODRAW::OfficeArtFOPTEPtr> & p
ODRAW::pihlShape *pihlShape = dynamic_cast<ODRAW::pihlShape*>(props[i].get());
if (pihlShape)
{
std::wstring target = GetTargetMoniker(pihlShape->IHlink_complex.hyperlink.oleMoniker.data.get());
xlsx_context->get_drawing_context().set_hyperlink(target);
std::wstring sTarget;
bool bExternal = false;
if (pihlShape->IHlink_complex.hyperlink.hlstmfHasMoniker)
{
sTarget = GetTargetMoniker(pihlShape->IHlink_complex.hyperlink.oleMoniker.data.get());
bExternal = true;
}
else if (pihlShape->IHlink_complex.hyperlink.hlstmfHasLocationStr)
{
sTarget = pihlShape->IHlink_complex.hyperlink.location.value();
}
std::wstring sDisplay = pihlShape->IHlink_complex.hyperlink.displayName;
if (sDisplay.empty()) sDisplay = sTarget;
xlsx_context->get_drawing_context().set_hyperlink( sTarget, sDisplay, bExternal);
}
}break;
}
......
......@@ -1318,20 +1318,21 @@ void xlsx_drawing_context::set_line_width (int val)
current_drawing_states->back()->line.width = val;
}
void xlsx_drawing_context::set_hyperlink(const std::wstring & str)
void xlsx_drawing_context::set_hyperlink(const std::wstring & link, const std::wstring & display, bool is_external)
{
if (current_drawing_states == NULL) return;
std::wstring hId=std::wstring(L"hId") + boost::lexical_cast<std::wstring>(hlinks_.size()+1);
std::wstring href_correct = xml::utils::replace_text_to_xml(str);
std::wstring sId = std::wstring(L"hId") + boost::lexical_cast<std::wstring>(hlinks_.size()+1);
std::wstring link_correct = link;
_hlink_desc desc = {hId, href_correct};
if (!is_external) link_correct = std::wstring(L"#") + link_correct;
_hlink_desc desc = {sId, link_correct, display, is_external};
hlinks_.push_back(desc);
current_drawing_states->back()->hyperlink = hId;
current_drawing_states->back()->hyperlink = sId;
xlsx_drawings_->add( false, hId , href_correct, external_items::typeHyperlink);
xlsx_drawings_->add( !is_external, sId , link_correct, external_items::typeHyperlink);
}
void xlsx_drawing_context::set_path (const std::wstring & path)
......
......@@ -191,8 +191,10 @@ public:
};
struct _hlink_desc
{
std::wstring hId;
std::wstring hRef;
std::wstring sId;
std::wstring sLink;
std::wstring sDisplay;
bool bExternal;
};
class xlsx_drawing_context
......@@ -249,7 +251,7 @@ public:
bool is_anchor ();
void set_properties (const std::wstring & str);
void set_hyperlink (const std::wstring & str);
void set_hyperlink (const std::wstring & link, const std::wstring & display, bool is_external);
void set_path_rect (_rect & rect);
void set_path (const std::wstring & path);
......
......@@ -76,7 +76,7 @@ public:
{
BOOST_FOREACH(rel_ const & r, xlsx_drawing_rels_)
{
if (r.type_ == external_items::typeChart)// -
if (r.type_ == external_items::typeChart)
{
Rels.add(relationship(
r.rid_,
......@@ -96,14 +96,13 @@ public:
)
);
}
//typeShape -
else if (r.type_ == external_items::typeHyperlink)// ... ... ..
else if (r.type_ == external_items::typeHyperlink)
{
Rels.add(relationship(
r.rid_,
L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
r.target_,
L"External")
(r.is_internal_ ? L"" : L"External"))
);
}
}
......
......@@ -283,12 +283,10 @@ void xl_drawings::write(const std::wstring & RootPath)
rels_files relFiles;
rels_file_ptr r = rels_file::create(e.filename + L".rels");
e.drawings->dump_rels(r->get_rels());
relFiles.add_rel_file(r);
relFiles.write(path);
content_type & contentTypes = this->get_main_document()->content_type().get_content_type();
const std::wstring kDrawingCT = L"application/vnd.openxmlformats-officedocument.drawing+xml";
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment