diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Binary/CompoundFile.cpp b/ASCOfficeXlsFile2/source/XlsFormat/Binary/CompoundFile.cpp index 5736e3a74f..1406b64c39 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Binary/CompoundFile.cpp +++ b/ASCOfficeXlsFile2/source/XlsFormat/Binary/CompoundFile.cpp @@ -115,17 +115,33 @@ void CompoundFile::copy_stream(std::wstring streamNameOpen, std::wstring streamN POLE::Stream *streamNew = new POLE::Stream(storageOut, streamNameCreate, true, size_stream); if (!streamNew) return; - unsigned char* data_stream = new unsigned char[size_stream + 64]; - memset(data_stream, 0, size_stream + 64); - if (data_stream) + unsigned char buffer[4096]; + int bytesRead = 0; + + while(true) { - stream->read(data_stream, size_stream); - - streamNew->write(data_stream, size_stream); - - delete []data_stream; - data_stream = NULL; + int bytesToRead = size_stream - bytesRead; + if (bytesToRead <= 0) + break; + if (bytesToRead > 4096) + bytesToRead = 4096; + + stream->read(buffer, bytesToRead); + streamNew->write(buffer, bytesToRead); + + bytesRead += bytesToRead; } + //unsigned char* data_stream = new unsigned char[size_stream + 64]; + //memset(data_stream, 0, size_stream + 64); + //if (data_stream) + //{ + // stream->read(data_stream, size_stream); + + // streamNew->write(data_stream, size_stream); + + // delete []data_stream; + // data_stream = NULL; + //} streamNew->flush(); @@ -152,25 +168,26 @@ void CompoundFile::copy( int indent, std::wstring path, POLE::Storage * storageO entries_files.push_front(*it); } } + for( std::list::iterator it = entries_dir.begin(); it != entries_dir.end(); it++ ) { std::wstring fullname = path + *it; copy( indent + 1, fullname + L"/", storageOut, bWithRoot, bSortFiles ); } - //if (bSortFiles) - entries_files.sort(); + + //entries_files.sort(); for( std::list::iterator it = entries_files.begin(); it != entries_files.end(); it++ ) { - std::wstring createName = path + *it; + std::wstring createName = path + *it; std::wstring openName; if (it->at(0) < 32) openName = path + it->substr(1); else openName = path + *it; - + copy_stream(openName, createName, storageOut, bWithRoot); - } + } } CFStreamPtr CompoundFile::getWorkbookStream() { diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/DConn.cpp b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/DConn.cpp index 2d44f3681a..81794124db 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/DConn.cpp +++ b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_records/DConn.cpp @@ -98,7 +98,10 @@ void DConn::readFields(CFRecord& record) grbitDbt->load(record); record >> bVerDbqueryEdit >> bVerDbqueryRefreshed >> bVerDbqueryRefreshableMin >> wRefreshInterval >> wHtmlFmt >> rcc >> credMethod >> reserved3; - +//wHtmlFmt +//0x0001 No formatting is applied +//0x0002 Rich text formatting only +//0x0003 Full HTML formatting, including cell formatting if (dbt == 5) { record >> rgchSourceDataFile; @@ -140,12 +143,12 @@ void DConn::readFields(CFRecord& record) record >> rgbSQL; } - if (dbt == 1) + if (dbt == 1 || dbt == 5)//7183958.xls { record >> rgbSQLSav; } - if (dbt == 4) + if (dbt == 4 || dbt == 5) { record >> rgbEditWebPage; } diff --git a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_structures/DConnConnectionOleDb.cpp b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_structures/DConnConnectionOleDb.cpp index 8d74d52fe8..f5b399ec77 100644 --- a/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_structures/DConnConnectionOleDb.cpp +++ b/ASCOfficeXlsFile2/source/XlsFormat/Logic/Biff_structures/DConnConnectionOleDb.cpp @@ -59,9 +59,11 @@ void DConnConnectionOleDb::load(CFRecord& record) record >> val; rgIOleDbValid.push_back(val); } - int skip_unused = 2 * (4 - cOleDb) + 2; + int skip_unused = 2 * (4 - cOleDb); record.skipNunBytes(skip_unused); + + record.skipNunBytes(2); for (unsigned short i = 0; i < cOleDb; i++) { diff --git a/ASCOfficeXlsFile2/source/XlsXlsxConverter/ShapeType.h b/ASCOfficeXlsFile2/source/XlsXlsxConverter/ShapeType.h index 987aaaf9ce..2b187b61a1 100644 --- a/ASCOfficeXlsFile2/source/XlsXlsxConverter/ShapeType.h +++ b/ASCOfficeXlsFile2/source/XlsXlsxConverter/ShapeType.h @@ -276,6 +276,7 @@ namespace oox case msosptRoundRectangle : return L"roundRect"; case msosptEllipse : return L"ellipse"; case msosptPictureFrame : return L"rect"; + case msosptHostControl : return L"rect"; //case msosptDiamond : return L"diamond"; case msosptIsocelesTriangle : return L"triangle"; //case msosptRightTriangle : return L"rtTriangle"; diff --git a/ASCOfficeXlsFile2/source/XlsXlsxConverter/XlsConverter.cpp b/ASCOfficeXlsFile2/source/XlsXlsxConverter/XlsConverter.cpp index a6c2230ad0..c046d6539b 100644 --- a/ASCOfficeXlsFile2/source/XlsXlsxConverter/XlsConverter.cpp +++ b/ASCOfficeXlsFile2/source/XlsXlsxConverter/XlsConverter.cpp @@ -1033,9 +1033,7 @@ void XlsConverter::convert(XLS::OBJECTS* objects, XLS::WorksheetSubstream * shee } //----------------------------------------------------------------------------- - if (type_object < 0)continue; - - ODRAW::OfficeArtSpContainer *sp = NULL; + if (type_object < 0) continue; if (type_object == 0) { @@ -1043,12 +1041,16 @@ void XlsConverter::convert(XLS::OBJECTS* objects, XLS::WorksheetSubstream * shee if (group_objects.back().ind < group_objects.back().spgr->child_records.size()) { gr.spgr = dynamic_cast(group_objects.back().spgr->child_records[group_objects.back().ind++].get()); - gr.count = gr.spgr->child_records.size(); + gr.count = gr.spgr ? gr.spgr->child_records.size() : 0; group_objects.push_back(gr); } else //сюда попадать не должно !!!! continue; } + if (obj->cmo.fUIObj) continue; // automatically inserted by the application + + ODRAW::OfficeArtSpContainer *sp = NULL; + if ((group_objects.size() > 0) && (group_objects.back().spgr ) && ( group_objects.back().ind < group_objects.back().count)) { sp = dynamic_cast(group_objects.back().spgr->child_records[group_objects.back().ind++].get()); @@ -1944,23 +1946,22 @@ void XlsConverter::convert(XLS::Obj * obj) } if (obj->pictFlags.fCtl && obj->pictFlags.fPrstm)//Controls Storage { - xlsx_context->start_activeX(); - xlsx_context->get_mediaitems().create_activeX_path(xlsx_path); - //binary data - std::wstring target; - std::wstring objectId = xlsx_context->get_mediaitems().add_activeX(target); + xlsx_context->get_mediaitems().create_activeX_path(xlsx_path); + + std::wstring target_bin; + std::wstring objectId_bin = xlsx_context->get_mediaitems().add_control_activeX(target_bin); NSFile::CFileBinary file; - if ( file.CreateFileW(xlsx_context->get_mediaitems().activeX_path() + target) ) + if ( file.CreateFileW(xlsx_context->get_mediaitems().activeX_path() + target_bin) ) { file.WriteFile(xls_global_info->controls_data.first.get() + obj->pictFmla.lPosInCtlStm, obj->pictFmla.cbBufInCtlStm); file.CloseFile(); } - - xlsx_context->get_drawing_context().set_control(objectId); + std::wstring objectId_xml = xlsx_context->start_activeX(); + xlsx_context->get_drawing_context().set_control_activeX(objectId_xml); - xlsx_context->current_activeX().setDataBinRid(objectId, target); + xlsx_context->current_activeX().setDataBinRid(objectId_bin, target_bin); xlsx_context->current_activeX().setProgId(info); xlsx_context->current_activeX().setLicense(obj->pictFmla.key.keyBuf); @@ -1994,6 +1995,16 @@ void XlsConverter::convert(XLS::Obj * obj) xlsx_context->get_drawing_context().set_ole_object(objectId, info); } } + if (obj->pictFmla.key.fmlaLinkedCell.bFmlaExist) + { + std::wstring link = obj->pictFmla.key.fmlaLinkedCell.fmla.getAssembledFormula(true); + xlsx_context->get_drawing_context().set_object_link(link); + } + if (obj->pictFmla.key.fmlaListFillRange.bFmlaExist) + { + std::wstring link = obj->pictFmla.key.fmlaListFillRange.fmla.getAssembledFormula(true); + xlsx_context->get_drawing_context().set_object_fmlaRange(link); + } } if (obj->sbs.fExist) { diff --git a/ASCOfficeXlsFile2/source/XlsXlsxConverter/external_items.cpp b/ASCOfficeXlsFile2/source/XlsXlsxConverter/external_items.cpp index 43740a2cbb..0a0499a9af 100644 --- a/ASCOfficeXlsFile2/source/XlsXlsxConverter/external_items.cpp +++ b/ASCOfficeXlsFile2/source/XlsXlsxConverter/external_items.cpp @@ -63,6 +63,8 @@ std::wstring static get_default_file_name(external_items::Type type) return L"media"; case external_items::typeActiveX: return L"activeX"; + case external_items::typeControlProps: + return L"ctrlProp"; default: return L""; } @@ -92,7 +94,20 @@ std::wstring external_items::add_chart(std::wstring & oox_target) return rId; } -std::wstring external_items::add_activeX(std::wstring & oox_target) +std::wstring external_items::add_control_activeX(std::wstring & oox_target_bin) +{ + const bool isMediaInternal = true; + + count_activeX++; + + std::wstring rId = std::wstring(L"ocxId") + std::to_wstring(count_activeX); + + oox_target_bin = std::wstring(L"activeX") + std::to_wstring(count_activeX) + L".bin"; + + items_.push_back( item(oox_target_bin, typeActiveX, isMediaInternal, -1, rId) ); + return rId; +} +std::wstring external_items::add_control_props(std::wstring & oox_target) { const bool isMediaInternal = true; @@ -100,12 +115,11 @@ std::wstring external_items::add_activeX(std::wstring & oox_target) std::wstring rId = std::wstring(L"ctrlId") + std::to_wstring(count_controls); - oox_target = std::wstring(L"activeX") + std::to_wstring(count_controls) + L".bin"; + oox_target = std::wstring(L"ctrlProp") + std::to_wstring(count_controls) + L".xml"; - items_.push_back( item(oox_target, typeActiveX, isMediaInternal, -1, rId) ); + items_.push_back( item(oox_target, typeControlProps, isMediaInternal, -1, rId) ); return rId; } - std::wstring external_items::add_embedding(std::wstring & oox_target, const std::wstring & info) { const bool isMediaInternal = true; diff --git a/ASCOfficeXlsFile2/source/XlsXlsxConverter/external_items.h b/ASCOfficeXlsFile2/source/XlsXlsxConverter/external_items.h index 5cb915821a..902e579ad1 100644 --- a/ASCOfficeXlsFile2/source/XlsXlsxConverter/external_items.h +++ b/ASCOfficeXlsFile2/source/XlsXlsxConverter/external_items.h @@ -55,7 +55,8 @@ public: typeExternalLink, typeOleObject, typeActiveX, - typeControl + typeControl, + typeControlProps }; external_items() @@ -100,8 +101,10 @@ public: //std::wstring add_or_find(const std::wstring & href, Type type, bool & isInternal);//возможны ссылки на один и тот же объект std::wstring add_image (const std::wstring & file_name, int bin_id); std::wstring add_chart (std::wstring & oox_target); - std::wstring add_activeX (std::wstring & oox_target); std::wstring add_embedding (std::wstring & oox_target, const std::wstring & info); + + std::wstring add_control_activeX(std::wstring & oox_target); + std::wstring add_control_props (std::wstring & oox_target); std::wstring find_image (int id, std::wstring & oox_target, bool & isExternal); std::wstring find_image ( const std::wstring & oox_target, bool & isExternal); diff --git a/ASCOfficeXlsFile2/source/XlsXlsxConverter/mediaitems_utils.cpp b/ASCOfficeXlsFile2/source/XlsXlsxConverter/mediaitems_utils.cpp index e090ecac9a..69a7b26fbe 100644 --- a/ASCOfficeXlsFile2/source/XlsXlsxConverter/mediaitems_utils.cpp +++ b/ASCOfficeXlsFile2/source/XlsXlsxConverter/mediaitems_utils.cpp @@ -32,11 +32,6 @@ #include "mediaitems_utils.h" -#include -#include -#include - -#include "../../../Common/DocxFormat/Source/Base/Base.h" #include "../../../DesktopEditor/common/Directory.h" namespace oox { @@ -64,22 +59,12 @@ std::wstring get_rel_type(external_items::Type type) return L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/externalLinkPath"; case external_items::typeActiveX: return L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/control"; + case external_items::typeControlProps: + return L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/ctrlProp"; default: return L""; } } - - - -std::wstring replace_extension(const std::wstring & ext) -{ - // TODO - if (ext == L"jpg") - return L"jpeg"; - else - return ext; -} - } } diff --git a/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_activeX_context.cpp b/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_activeX_context.cpp index 6a879aa9fa..281b7aafc2 100644 --- a/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_activeX_context.cpp +++ b/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_activeX_context.cpp @@ -205,6 +205,10 @@ void oox_activeX_context::write_to(std::wostream & strm) classId = L"{8BD21D10-EC42-11CE-9E0D-00AA006002F3}"; } } + else if (std::wstring::npos != impl_->progId.find(L"ShockwaveFlash.")) + { + classId = L"{D27CDB6E-AE6D-11CF-96B8-444553540000}"; + } #if defined(_WIN32) || defined(_WIN64) if (classId.empty()) { diff --git a/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_chart_context.cpp b/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_chart_context.cpp index 17f2114cfa..8d1714e1bb 100644 --- a/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_chart_context.cpp +++ b/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_chart_context.cpp @@ -67,7 +67,16 @@ public: for (size_t i = 0; i < chartRels_.size(); i++) { rel_ & r = chartRels_[i]; - if (r.type_ == external_items::typeImage) + if (r.type_ == external_items::typeHyperlink) + { + Rels.add(relationship( + r.rid_, + L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink", + r.target_, + L"External") + ); + } + else { Rels.add(relationship( r.rid_, @@ -77,15 +86,6 @@ public: ) ); } - 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") - ); - } } } diff --git a/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_conversion_context.cpp b/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_conversion_context.cpp index 26564e89c1..bf538589c4 100644 --- a/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_conversion_context.cpp +++ b/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_conversion_context.cpp @@ -149,16 +149,19 @@ void xlsx_conversion_context::start_chart() } -void xlsx_conversion_context::start_activeX() +std::wstring xlsx_conversion_context::start_activeX() { activeXs_.push_back(oox_activeX_context::create()); size_t index = activeXs_.size(); - current_sheet().sheet_rels().add(oox::relationship(L"ctrlId" + std::to_wstring(index), + std::wstring rid = L"ocxId" + std::to_wstring(index); + + current_sheet().sheet_rels().add(oox::relationship(rid, L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/control", L"../activeX/activeX" + std::to_wstring(index) +L".xml")); - + + return rid; } void xlsx_conversion_context::start_external() { @@ -171,8 +174,9 @@ void xlsx_conversion_context::end_external() void xlsx_conversion_context::end_table() { - get_table_context().serialize_ole_objects(current_sheet().ole_objects()); - get_table_context().serialize_activeXs_controls(current_sheet().activeXs()); + get_table_context().serialize_ole_objects (current_sheet().ole_objects()); + get_table_context().serialize_controls (current_sheet().activeXs()); + get_table_context().dump_rels_drawing(current_sheet().sheet_rels()); get_table_context().serialize_hyperlinks(current_sheet().hyperlinks()); @@ -186,16 +190,25 @@ xlsx_drawing_context_handle & xlsx_conversion_context::get_drawing_context_handl return xlsx_drawing_context_handle_; } -void xlsx_conversion_context::add_connections(std::wstring connections) +void xlsx_conversion_context::add_connections(const std::wstring & connections) { if (connections.empty()) return; connections_ = connections; } -void xlsx_conversion_context::add_query_table (std::wstring query_table) +void xlsx_conversion_context::add_query_table (const std::wstring & query_table) { if (query_table.empty()) return; - query_tables_.push_back(query_table); + + std::wstring target = L"queryTable" + std::to_wstring(query_tables_.size() + 1) + L".xml"; + + query_tables_.insert(std::make_pair(target, query_table)); +} + +void xlsx_conversion_context::add_control_props(const std::wstring & target, const std::wstring & props) +{ + if (props.empty()) return; + control_props_.insert(std::make_pair(target, props)); } void xlsx_conversion_context::end_document() @@ -299,12 +312,15 @@ void xlsx_conversion_context::end_document() } output_document_->get_xl_files().set_connections( package::simple_element::create(L"connections.xml", strm.str()) ); } - for (size_t i = 0; i < query_tables_.size(); i++) + for (std::map::iterator it = query_tables_.begin(); it != query_tables_.end(); it++) { - std::wstring file_name = L"queryTable" + std::to_wstring(i+1) + L".xml"; - output_document_->get_xl_files().add_query_table( package::simple_element::create(file_name, query_tables_[i]) ); + output_document_->get_xl_files().add_query_table( package::simple_element::create(it->first, it->second) ); } - //workbook_content << L""; + for (std::map::iterator it = control_props_.begin(); it != control_props_.end(); it++) + { + output_document_->get_xl_files().add_control_props( package::simple_element::create(it->first, it->second) ); + } + //workbook_content << L""; output_document_->get_xl_files().set_sharedStrings( package::simple_element::create(L"sharedStrings.xml", xlsx_shared_strings_.str()) ); diff --git a/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_conversion_context.h b/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_conversion_context.h index 0bebbbbc0d..af6fa2b348 100644 --- a/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_conversion_context.h +++ b/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_conversion_context.h @@ -74,7 +74,7 @@ public: void start_chart(); void end_chart(){} - void start_activeX(); + std::wstring start_activeX(); void end_activeX(){} void start_external(); @@ -102,9 +102,9 @@ public: external_items & get_mediaitems() { return mediaitems_; } - void add_exteranal_content (std::wstring content); - void add_connections (std::wstring connections); - void add_query_table (std::wstring query_table); + void add_connections (const std::wstring & connections); + void add_query_table (const std::wstring & query_table); + void add_control_props (const std::wstring & target, const std::wstring &props); private: void create_new_sheet(std::wstring const & name); @@ -112,8 +112,7 @@ private: package::xlsx_document *output_document_; external_items mediaitems_; - xlsx_table_context - table_context_; + xlsx_table_context table_context_; xlsx_text_context text_context_; xlsx_pivots_context pivots_context_; @@ -125,7 +124,8 @@ private: std::vector sheets_; std::wstring connections_; - std::vector query_tables_; + std::mapquery_tables_; + std::mapcontrol_props_; std::wstringstream xlsx_shared_strings_; std::wstringstream xlsx_defined_names_; diff --git a/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_drawing_context.cpp b/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_drawing_context.cpp index f83e7f7430..3420bf6a6e 100644 --- a/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_drawing_context.cpp +++ b/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_drawing_context.cpp @@ -523,7 +523,7 @@ void xlsx_drawing_context::start_comment() current_drawing_states->back()->shape_id = MSOSPT::msosptRectangle; current_drawing_states->back()->type_control = 0x0019; - current_drawing_states->back()->object.visible = false; + current_drawing_states->back()->object.bVisible = false; count_object++; @@ -665,7 +665,7 @@ void xlsx_drawing_context::set_object_visible(bool val) if (current_drawing_states == NULL) return; if (current_drawing_states->empty()) return; - current_drawing_states->back()->object.visible = val; + current_drawing_states->back()->object.bVisible = val; } void xlsx_drawing_context::set_object_anchor(int col, int row) { @@ -802,51 +802,33 @@ void xlsx_drawing_context::end_drawing(_drawing_state_ptr & drawing_state) if (!drawing_state->fill.texture_target.empty()) { bool isIternal = false; - std::wstring rId = handle_.impl_->get_mediaitems().find_image( drawing_state->fill.texture_target, isIternal); + drawing_state->objectId = handle_.impl_->get_mediaitems().find_image( drawing_state->fill.texture_target, isIternal); - serialize_pic(drawing_state, rId); + serialize_pic(drawing_state); if (drawing_state->vml_HF_mode_) { - vml_HF_rels_->add(isIternal, rId , drawing_state->fill.texture_target, drawing_state->type); + vml_HF_rels_->add(isIternal, drawing_state->objectId , drawing_state->fill.texture_target, drawing_state->type); } else { - rels_->add(isIternal, rId , drawing_state->fill.texture_target, drawing_state->type); + rels_->add(isIternal, drawing_state->objectId , drawing_state->fill.texture_target, drawing_state->type); } } else drawing_state->type = external_items::typeShape; } - if ( drawing_state->type == external_items::typeOleObject ) - { - serialize_shape(drawing_state); - drawing_states_objects.push_back(drawing_state); // for serialize in sheet - } - if ( drawing_state->type == external_items::typeActiveX) - { - context_.end_activeX(); - - serialize_shape(drawing_state); - drawing_states_activeX.push_back(drawing_state); // for serialize in sheet - } if ( drawing_state->type == external_items::typeChart ) { - //функциональная часть - context_.end_chart(); - + context_.end_chart(); in_chart_ = false; -//отобразительная часть - drawing_state->type = external_items::typeChart; - - bool isIternal = true; std::wstring target; - std::wstring rId = handle_.impl_->get_mediaitems().add_chart(target); + drawing_state->objectId = handle_.impl_->get_mediaitems().add_chart(target); - serialize_chart(drawing_state, rId); + serialize_chart(drawing_state); - rels_->add( isIternal, rId, target, drawing_state->type); + rels_->add( true, drawing_state->objectId, target, drawing_state->type); } if ( drawing_state->type == external_items::typeComment ) { @@ -860,13 +842,34 @@ void xlsx_drawing_context::end_drawing(_drawing_state_ptr & drawing_state) { serialize_shape(drawing_state); } - if ( drawing_state->type == external_items::typeControl) + if ( drawing_state->type == external_items::typeOleObject ) + { + serialize_shape(drawing_state); + drawing_states_objects.push_back(drawing_state); // for serialize in sheet + } + if ( drawing_state->type == external_items::typeActiveX) // объекты управления с бинарными свойствами + { + context_.end_activeX(); + + serialize_shape(drawing_state); + drawing_states_controls.push_back(drawing_state); // for serialize in sheet + } + if ( drawing_state->type == external_items::typeControl)// объекты управления с xml свойствами { serialize_control(drawing_state); - if (!drawing_state->objectId.empty()) + if (drawing_state->objectId.empty()) { - drawing_states_activeX.push_back(drawing_state); // for serialize in sheet + std::wstring target; + drawing_state->objectId = context_.get_mediaitems().add_control_props(target); + + sheet_rels_->add(true, drawing_state->objectId, L"ctrlProps/" + target, external_items::typeControlProps); + + std::wstringstream strm; + serialize_control_props(strm, drawing_state); + + context_.add_control_props(target, strm.str()); } + drawing_states_controls.push_back(drawing_state); // for serialize in sheet } } @@ -953,7 +956,7 @@ void xlsx_drawing_context::serialize_vml_shape(_drawing_state_ptr & drawing_stat strmStyle << L"height:" << std::to_wstring(drawing_state->child_anchor.cy / 12700.) << L"pt;"; strmStyle << L"z-index:" << std::to_wstring(drawing_state->id) << L";"; - if (drawing_state->object.visible == false) + if (drawing_state->object.bVisible == false) strmStyle << L"visibility:hidden;"; CP_XML_NODE(L"v:shape") @@ -1118,7 +1121,7 @@ void xlsx_drawing_context::serialize_vml_shape(_drawing_state_ptr & drawing_stat CP_XML_NODE(L"x:Row") {CP_XML_CONTENT(drawing_state->object.row);} CP_XML_NODE(L"x:Column") {CP_XML_CONTENT(drawing_state->object.col);} - if (drawing_state->object.visible) CP_XML_NODE(L"x:Visible"); + if (drawing_state->object.bVisible) CP_XML_NODE(L"x:Visible"); if (!drawing_state->object.macro.empty()) { @@ -1193,7 +1196,7 @@ void xlsx_drawing_context::serialize_vml_shape(_drawing_state_ptr & drawing_stat } drawing_state->vml_shape = strm.str(); } -void xlsx_drawing_context::serialize_vml_pic(_drawing_state_ptr & drawing_state, std::wstring rId) +void xlsx_drawing_context::serialize_vml_pic(_drawing_state_ptr & drawing_state) { std::wstringstream strm; @@ -1220,17 +1223,17 @@ void xlsx_drawing_context::serialize_vml_pic(_drawing_state_ptr & drawing_state, CP_XML_NODE(L"v:imagedata") { - CP_XML_ATTR(L"o:relid", rId); + CP_XML_ATTR(L"o:relid", drawing_state->objectId); } } } drawing_state->vml_shape = strm.str(); } -void xlsx_drawing_context::serialize_pic(_drawing_state_ptr & drawing_state, std::wstring rId) +void xlsx_drawing_context::serialize_pic(_drawing_state_ptr & drawing_state) { if (drawing_state->vml_HF_mode_) - return serialize_vml_pic(drawing_state, rId); + return serialize_vml_pic(drawing_state); std::wstringstream strm; @@ -1246,7 +1249,7 @@ void xlsx_drawing_context::serialize_pic(_drawing_state_ptr & drawing_state, std { CP_XML_ATTR(L"id", drawing_state->id); if (drawing_state->name.empty()) - drawing_state->name = L"Picture_" + rId.substr(5); + drawing_state->name = L"Picture_" + drawing_state->objectId.substr(5); CP_XML_ATTR(L"name", drawing_state->name); if (!drawing_state->description.empty()) @@ -1277,7 +1280,7 @@ void xlsx_drawing_context::serialize_pic(_drawing_state_ptr & drawing_state, std } } drawing_state->fill.texture_mode = textureStretch; - serialize_bitmap_fill(CP_XML_STREAM(), drawing_state->fill, rId, L"xdr:"); + serialize_bitmap_fill(CP_XML_STREAM(), drawing_state->fill, drawing_state->objectId, L"xdr:"); CP_XML_NODE(L"xdr:spPr") { @@ -1297,7 +1300,7 @@ void xlsx_drawing_context::serialize_pic(_drawing_state_ptr & drawing_state, std drawing_state->shape = strm.str(); } -void xlsx_drawing_context::serialize_chart(_drawing_state_ptr & drawing_state, std::wstring rId) +void xlsx_drawing_context::serialize_chart(_drawing_state_ptr & drawing_state) { std::wstringstream strm; @@ -1340,7 +1343,7 @@ void xlsx_drawing_context::serialize_chart(_drawing_state_ptr & drawing_state, s CP_XML_NODE(L"c:chart") { CP_XML_ATTR(L"xmlns:c", L"http://schemas.openxmlformats.org/drawingml/2006/chart"); - CP_XML_ATTR(L"r:id", rId); + CP_XML_ATTR(L"r:id", drawing_state->objectId); } } } @@ -2273,7 +2276,7 @@ void xlsx_drawing_context::serialize(std::wostream & stream, _drawing_state_ptr } } } -void xlsx_drawing_context::serialize_activeX_control(std::wostream & stream, _drawing_state_ptr & drawing_state) +void xlsx_drawing_context::serialize_control(std::wostream & strm, _drawing_state_ptr & drawing_state) { if (drawing_state->type != external_items::typeActiveX && drawing_state->type != external_items::typeControl) return; @@ -2305,7 +2308,7 @@ void xlsx_drawing_context::serialize_activeX_control(std::wostream & stream, _dr drawing_state->type_anchor = 1; } - CP_XML_WRITER(stream) + CP_XML_WRITER(strm) { CP_XML_NODE(L"control") { @@ -2320,8 +2323,9 @@ void xlsx_drawing_context::serialize_activeX_control(std::wostream & stream, _dr CP_XML_NODE(L"controlPr") { CP_XML_ATTR(L"defaultSize", 0); - //CP_XML_ATTR(L"autoPict", 0); - CP_XML_ATTR(L"autoLine", 0); + CP_XML_ATTR(L"autoLine", drawing_state->object.bAutoLine); + CP_XML_ATTR(L"autoPict", drawing_state->object.bAutoPict); + if (!drawing_state->object.link.empty()) { CP_XML_ATTR(L"linkedCell", drawing_state->object.link); @@ -2350,6 +2354,92 @@ void xlsx_drawing_context::serialize_activeX_control(std::wostream & stream, _dr } } } +void xlsx_drawing_context::serialize_control_props(std::wostream & strm, _drawing_state_ptr & drawing_state) +{ + if (drawing_state == NULL) return; + + if (drawing_state->type != external_items::typeActiveX && + drawing_state->type != external_items::typeControl) return; + + CP_XML_WRITER(strm) + { + CP_XML_NODE(L"formControlPr") + { + CP_XML_ATTR(L"xmlns", L"http://schemas.microsoft.com/office/spreadsheetml/2009/9/main" ); + + switch(drawing_state->type_control) + { + case 0x0000: CP_XML_ATTR(L"objectType", L"Group"); break; + case 0x0001: CP_XML_ATTR(L"objectType", L"Shape"); break; // Line + case 0x0002: CP_XML_ATTR(L"objectType", L"Rect"); break; + case 0x0003: CP_XML_ATTR(L"objectType", L"Shape"); break; // Oval + case 0x0004: CP_XML_ATTR(L"objectType", L"Shape"); break; // Arc + case 0x0006: CP_XML_ATTR(L"objectType", L"Shape"); break; // Text + case 0x0007: CP_XML_ATTR(L"objectType", L"Button"); break; + case 0x0008: CP_XML_ATTR(L"objectType", L"Pict"); break; + case 0x0009: CP_XML_ATTR(L"objectType", L"Shape"); break; // Polygon: + case 0x000B: CP_XML_ATTR(L"objectType", L"Checkbox"); break; + case 0x000C: CP_XML_ATTR(L"objectType", L"Radio"); break; + case 0x000D: CP_XML_ATTR(L"objectType", L"Edit"); break; + case 0x000E: CP_XML_ATTR(L"objectType", L"Label"); break; + case 0x000F: CP_XML_ATTR(L"objectType", L"Dialog"); break; + case 0x0010: CP_XML_ATTR(L"objectType", L"Spin"); break; + case 0x0012: CP_XML_ATTR(L"objectType", L"List"); break; + case 0x0013: CP_XML_ATTR(L"objectType", L"GBox"); break; + case 0x0011: CP_XML_ATTR(L"objectType", L"Scroll"); break; + case 0x0014: CP_XML_ATTR(L"objectType", L"Drop"); break; + case 0x001E: CP_XML_ATTR(L"objectType", L"Shape"); break; // OfficeArt object + case 0x0019: CP_XML_ATTR(L"objectType", L"Note"); break; + default: break; + } + if (drawing_state->object.drop_style) + { + switch(*drawing_state->object.drop_style) + { + case 0: + default: + CP_XML_ATTR(L"dropStyle", L"combo"); + } + } + if (!drawing_state->object.link.empty() ) + { + CP_XML_ATTR(L"fmlaLink", drawing_state->object.link); + } + if (!drawing_state->object.fmlaRange.empty() ) + { + CP_XML_ATTR(L"fmlaRange", drawing_state->object.fmlaRange); + } + if (drawing_state->object.x_min) + { + CP_XML_ATTR(L"min", *drawing_state->object.x_min); + } + if (drawing_state->object.x_max) + { + CP_XML_ATTR(L"max", *drawing_state->object.x_max); + } + if (drawing_state->object.x_inc) + { + CP_XML_ATTR(L"inc", *drawing_state->object.x_inc); + } + if (drawing_state->object.x_page) + { + CP_XML_ATTR(L"page", *drawing_state->object.x_page); + } + if (drawing_state->object.x_sel) + { + CP_XML_ATTR(L"sel", *drawing_state->object.x_sel); + } + if (drawing_state->object.x_val) + { + CP_XML_ATTR(L"val", *drawing_state->object.x_val); + } + if (drawing_state->object.drop_lines) + { + CP_XML_ATTR(L"dropLines", *drawing_state->object.drop_lines); + } + } + } +} void xlsx_drawing_context::serialize_object(std::wostream & stream, _drawing_state_ptr & drawing_state) { @@ -2444,10 +2534,11 @@ void xlsx_drawing_context::set_ole_object(const std::wstring & id, const std::ws if (current_drawing_states == NULL) return; current_drawing_states->back()->type = external_items::typeOleObject; - current_drawing_states->back()->objectId = id; - current_drawing_states->back()->objectProgId = info; + + current_drawing_states->back()->objectId = id; + current_drawing_states->back()->objectProgId = info; } -void xlsx_drawing_context::set_control(const std::wstring & rid) +void xlsx_drawing_context::set_control_activeX(const std::wstring & rid) { if (current_drawing_states == NULL) return; @@ -3225,13 +3316,13 @@ void xlsx_drawing_context::serialize_objects(std::wostream & strm) } drawing_states_objects.clear(); } -void xlsx_drawing_context::serialize_activeXs_controls(std::wostream & strm) +void xlsx_drawing_context::serialize_controls(std::wostream & strm) { - for (size_t i = 0; i < drawing_states_activeX.size(); i++) + for (size_t i = 0; i < drawing_states_controls.size(); i++) { - serialize_activeX_control(strm, drawing_states_activeX[i]); + serialize_control(strm, drawing_states_controls[i]); } - drawing_states_activeX.clear(); + drawing_states_controls.clear(); } //------------------------------------------------------------------------------------------------------------------- void xlsx_drawing_context::serialize_vml_HF(std::wostream & strm) diff --git a/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_drawing_context.h b/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_drawing_context.h index b8e52bcb5f..60fdabe71f 100644 --- a/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_drawing_context.h +++ b/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_drawing_context.h @@ -295,11 +295,12 @@ public: }line; struct _object { - _object() {visible = true; col = row = 0; id = 0;} - int id; - bool visible; - int col; - int row; + int id = 0; + bool bVisible = true; + int col = 0; + int row = 0; + bool bAutoLine = false; + bool bAutoPict = false; std::wstring macro; std::wstring link; _CP_OPT(int) x_val; @@ -365,7 +366,7 @@ public: void set_description (const std::wstring & str); void set_macro (const std::wstring & str); void set_ole_object (const std::wstring & id, const std::wstring & info); - void set_control (const std::wstring & id); + void set_control_activeX (const std::wstring & id); void set_crop_top (double val); void set_crop_bottom (double val); @@ -464,22 +465,22 @@ public: //------------------------------------------------------------------------------ void serialize_group (); void serialize_shape (_drawing_state_ptr & drawing_state); - void serialize_chart (_drawing_state_ptr & drawing_state, std::wstring rId ); - void serialize_pic (_drawing_state_ptr & drawing_state, std::wstring rId ); - void serialize_object (_drawing_state_ptr & drawing_state, std::wstring rId ); + void serialize_chart (_drawing_state_ptr & drawing_state); + void serialize_pic (_drawing_state_ptr & drawing_state); void serialize_control (_drawing_state_ptr & drawing_state); //----------------------------------------------------------------------------------- void serialize_vml_shape (_drawing_state_ptr & drawing_state); - void serialize_vml_pic (_drawing_state_ptr & drawing_state, std::wstring rId ); + void serialize_vml_pic (_drawing_state_ptr & drawing_state); //----------------------------------------------------------------------------------- void serialize_fill (std::wostream & strm, _drawing_state_ptr & drawing_state); void serialize_fill (std::wostream & strm); //----------------------------------------------------------------------------------- void serialize (std::wostream & strm, _drawing_state_ptr & drawing_state); void serialize_object (std::wostream & strm, _drawing_state_ptr & drawing_state); - void serialize_activeX_control(std::wostream & strm, _drawing_state_ptr & drawing_state); + void serialize_control (std::wostream & strm, _drawing_state_ptr & drawing_state); + void serialize_control_props(std::wostream & strm, _drawing_state_ptr & drawing_state); //----------------------------------------------------------------------------------- - void serialize_activeXs_controls(std::wostream & strm); + void serialize_controls (std::wostream & strm); void serialize_objects (std::wostream & strm); void serialize_vml_HF (std::wostream & strm); void serialize_vml (std::wostream & strm); @@ -511,7 +512,7 @@ private: std::vector<_drawing_state_ptr>* current_drawing_states; std::vector<_drawing_state_ptr> drawing_states_objects;//копии для сериализации ole - std::vector<_drawing_state_ptr> drawing_states_activeX;//копии для сериализации activeX + std::vector<_drawing_state_ptr> drawing_states_controls;//копии для сериализации control void end_drawing (_drawing_state_ptr & drawing_state); void reset_fill_pattern (_drawing_state_ptr & drawing_state); diff --git a/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_drawings.cpp b/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_drawings.cpp index 211fcf9548..698413b7a4 100644 --- a/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_drawings.cpp +++ b/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_drawings.cpp @@ -84,7 +84,16 @@ public: { BOOST_FOREACH(rel_ const & r, rels_) { - if (r.type_ == external_items::typeChart) + if (r.type_ == external_items::typeHyperlink) + { + Rels.add(relationship( + r.rid_, + L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink", + r.target_, + (r.is_internal_ ? L"" : L"External")) + ); + } + else { Rels.add(relationship( r.rid_, @@ -94,25 +103,6 @@ public: ) ); } - else if (r.type_ == external_items::typeImage) - { - Rels.add(relationship( - r.rid_, - utils::media::get_rel_type(r.type_), - r.is_internal_ ? std::wstring(L"../") + r.target_ : r.target_, - (r.is_internal_ ? L"" : L"External") - ) - ); - } - else if (r.type_ == external_items::typeHyperlink) - { - Rels.add(relationship( - r.rid_, - L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink", - r.target_, - (r.is_internal_ ? L"" : L"External")) - ); - } } } diff --git a/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_output_xml.cpp b/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_output_xml.cpp index 42b610ccf4..833dc558ad 100644 --- a/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_output_xml.cpp +++ b/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_output_xml.cpp @@ -249,6 +249,9 @@ void xlsx_xml_worksheet::write_to(std::wostream & strm) CP_XML_STREAM() << impl_->ole_objects_.str(); } } + + CP_XML_STREAM() << impl_->picture_background_.str(); + if (!impl_->activeXs_.str().empty()) { CP_XML_NODE(L"controls") @@ -256,7 +259,6 @@ void xlsx_xml_worksheet::write_to(std::wostream & strm) CP_XML_STREAM() << impl_->activeXs_.str(); } } - CP_XML_STREAM() << impl_->picture_background_.str(); //CP_XML_NODE(L"rowBreaks){} diff --git a/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_package.cpp b/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_package.cpp index da1416155b..0420f637a8 100644 --- a/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_package.cpp +++ b/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_package.cpp @@ -210,11 +210,14 @@ void xl_files::write(const std::wstring & RootPath) sheets_files_.set_main_document( this->get_main_document() ); sheets_files_.write(path); } + { + control_props_files_.set_main_document( this->get_main_document() ); + control_props_files_.write(path); + } { query_tables_files_.set_main_document( this->get_main_document() ); query_tables_files_.write(path); } - if (sharedStrings_) { sharedStrings_->write(path); @@ -368,6 +371,10 @@ void xl_files::add_query_table (simple_element_ptr element) { query_tables_files_.add_query_table(element); } +void xl_files::add_control_props (simple_element_ptr element) +{ + control_props_files_.add_control_props(element); +} //---------------------------------------------------------------------------------------- void xl_pivot_cache_files::add_pivot_cache(pivot_cache_content_ptr pivot_cache) { @@ -597,7 +604,33 @@ void xl_query_table_files::write(const std::wstring & RootPath) query_tables_[i]->write(path); } } +//---------------------------------------------------------------------------------------- +void xl_control_props_files::add_control_props(simple_element_ptr query_table) +{ + control_props_.push_back(query_table); +} +void xl_control_props_files::write(const std::wstring & RootPath) +{ + if (control_props_.empty()) return; + std::wstring path = RootPath + FILE_SEPARATOR_STR + L"ctrlProps"; + + NSDirectory::CreateDirectory(path); + + content_type & contentTypes = this->get_main_document()->content_type().get_content_type(); + static const std::wstring kWSConType = L"application/vnd.ms-excel.controlproperties+xml"; + + for (size_t i = 0; i < control_props_.size(); i++) + { + if (!control_props_[i])continue; + + const std::wstring fileName = control_props_[i]->get_filename(); + + contentTypes.add_override(std::wstring(L"/xl/ctrlProps/") + fileName, kWSConType); + + control_props_[i]->write(path); + } +} //---------------------------------------------------------------------------------------- xl_drawings_ptr xl_drawings::create(const std::vector & elms) { diff --git a/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_package.h b/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_package.h index a68b776163..d225102fc3 100644 --- a/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_package.h +++ b/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_package.h @@ -170,6 +170,16 @@ public: std::vector query_tables_; }; +class xl_control_props_files : public element +{ +public: + xl_control_props_files(){} + + void add_control_props(simple_element_ptr props); + virtual void write(const std::wstring & RootPath); + + std::vector control_props_; +}; class xl_externals_files : public element { public: @@ -212,8 +222,6 @@ public: rels_files * rels_; }; -/////////////////////////////////////////////////////////// - class xl_comments; typedef _CP_PTR(xl_comments) xl_comments_ptr; @@ -283,7 +291,7 @@ public: void add_pivot_cache (pivot_cache_content_ptr cache); void add_pivot_table (pivot_table_content_ptr table); void add_query_table (simple_element_ptr element); - + void add_control_props (simple_element_ptr element); void add_vba_project (); private: rels_files rels_files_; @@ -294,6 +302,7 @@ private: xl_pivot_table_files pivot_table_files_; xl_activeX_files activeXs_files_; xl_query_table_files query_tables_files_; + xl_control_props_files control_props_files_; element_ptr theme_; element_ptr workbook_; diff --git a/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_tablecontext.cpp b/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_tablecontext.cpp index 1cb8ac27e4..0c92764198 100644 --- a/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_tablecontext.cpp +++ b/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_tablecontext.cpp @@ -160,8 +160,8 @@ void xlsx_table_context::serialize_ole_objects(std::wostream & strm) { state()->drawing_context_.serialize_objects(strm); } -void xlsx_table_context::serialize_activeXs_controls(std::wostream & strm) +void xlsx_table_context::serialize_controls(std::wostream & strm) { - state()->drawing_context_.serialize_activeXs_controls(strm); + state()->drawing_context_.serialize_controls(strm); } } diff --git a/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_tablecontext.h b/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_tablecontext.h index 2be987e624..f708712575 100644 --- a/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_tablecontext.h +++ b/ASCOfficeXlsFile2/source/XlsXlsxConverter/xlsx_tablecontext.h @@ -69,11 +69,12 @@ public: table_state_ptr & state(); std::wstring add_hyperlink(std::wstring const & ref, std::wstring const & target, std::wstring const & display, bool bExternal); - void dump_rels_hyperlinks(rels & Rels); void serialize_hyperlinks(std::wostream & _Wostream); + void dump_rels_hyperlinks(rels & Rels); void serialize_ole_objects(std::wostream & _Wostream); - void serialize_activeXs_controls(std::wostream & _Wostream); + void serialize_controls(std::wostream & _Wostream); + void dump_rels_drawing(rels & Rels); private: xlsx_conversion_context & context_; diff --git a/Common/3dParty/pole/testbed.cpp b/Common/3dParty/pole/testbed.cpp index 42a05249ac..dca7df6fb0 100644 --- a/Common/3dParty/pole/testbed.cpp +++ b/Common/3dParty/pole/testbed.cpp @@ -19,44 +19,44 @@ POLE::Storage* storage = 0; -bool DirectoryExists( const char* dirname ){ +bool DirectoryExists( const wchar_t* dirname ){ - if( _access( dirname, 0 ) == 0 ){ + if( _waccess( dirname, 0 ) == 0 ){ - struct stat status; - stat( dirname, &status ); + struct _stat32 status; + _wstat32( dirname, &status ); return (status.st_mode & S_IFDIR) != 0; } return false; } -void visit( int indent, POLE::Storage* storage, std::string path ) +void visit( int indent, POLE::Storage* storage, std::wstring path ) { - std::list entries; + std::list entries; entries = storage->entries( path ); - std::list::iterator it; + std::list::iterator it; for( it = entries.begin(); it != entries.end(); ++it ) { - std::string name = *it; - std::string fullname = path + name; + std::wstring name = *it; + std::wstring fullname = path + name; for( int j = 0; j < indent; j++ ) std::cout << " "; POLE::Stream* ss = new POLE::Stream( storage, fullname ); - std::cout << name; + std::wcout << name; if( ss ) if( !ss->fail() )std::cout << " (" << ss->size() << ")"; std::cout << std::endl; delete ss; if( storage->isDirectory( fullname ) ) - visit( indent+1, storage, fullname + "/" ); + visit( indent+1, storage, fullname + L"/" ); } } -bool extract( POLE::Storage* storage, const char* stream_name, const char* outfile ) +bool extract( POLE::Storage* storage, const wchar_t* stream_name, const wchar_t* outfile ) { POLE::Stream* stream = new POLE::Stream( storage, stream_name ); if( !stream ) @@ -86,29 +86,29 @@ bool extract( POLE::Storage* storage, const char* stream_name, const char* outfi return true; } -void extractDir(POLE::Storage* storage, std::string outDir, std::string path, int &nFolders, int &nFiles) +void extractDir(POLE::Storage* storage, std::wstring outDir, std::wstring path, int &nFolders, int &nFiles) { - const char *cOutDir = outDir.c_str(); + const wchar_t *cOutDir = outDir.c_str(); if (DirectoryExists(cOutDir)) { std::cout << "You should not specify a directory for output that already exists." << std::endl; return; } - _mkdir(cOutDir); + _wmkdir(cOutDir); nFolders++; - std::list entries; + std::list entries; entries = storage->entries( path ); - std::list::iterator it; + std::list::iterator it; for( it = entries.begin(); it != entries.end(); ++it ) { - std::string name = *it; - std::string fullname = path + name; + std::wstring name = *it; + std::wstring fullname = path + name; if (storage->isDirectory(fullname)) { - std::string outdirchild = outDir + name; - extractDir(storage, outdirchild + "/", fullname + "/", nFolders, nFiles); + std::wstring outdirchild = outDir + name; + extractDir(storage, outdirchild + L"/", fullname + L"/", nFolders, nFiles); } else { @@ -124,8 +124,8 @@ void extractDir(POLE::Storage* storage, std::string outDir, std::string path, in return; } std::ofstream file; - std::string outfname = outDir + name; - const char *coutfname = outfname.c_str(); + std::wstring outfname = outDir + name; + const wchar_t *coutfname = outfname.c_str(); file.open(coutfname, std::ios::binary|std::ios::out); unsigned long bytesLeft = stream->size(); unsigned char buffer[4096]; @@ -147,10 +147,10 @@ void extractDir(POLE::Storage* storage, std::string outDir, std::string path, in } } -bool AddFile2Storage(POLE::Storage* storage, std::string inFile, std::string name) +bool AddFile2Storage(POLE::Storage* storage, std::wstring inFile, std::wstring name) { std::ifstream file; - const char *cinfname = inFile.c_str(); + const wchar_t *cinfname = inFile.c_str(); file.open(cinfname, std::ios::binary|std::ios::in); // find size of input file file.seekg( 0, std::ios::end ); @@ -189,17 +189,17 @@ bool AddFile2Storage(POLE::Storage* storage, std::string inFile, std::string nam return true; } -void AddDir2Storage(POLE::Storage* storage, std::string inDir, std::string name, int &nFolders, int &nFiles) +void AddDir2Storage(POLE::Storage* storage, std::wstring inDir, std::wstring name, int &nFolders, int &nFiles) { - WIN32_FIND_DATAA ffd; + WIN32_FIND_DATAW ffd; HANDLE h; - std::string inDirLcl = inDir + "*"; - std::string outNameLcl = name; + std::wstring inDirLcl = inDir + L"*"; + std::wstring outNameLcl = name; - const char *cInDir = inDirLcl.c_str(); - h = FindFirstFileA(cInDir, &ffd); + const wchar_t *cInDir = inDirLcl.c_str(); + h = FindFirstFileW(cInDir, &ffd); if (h == INVALID_HANDLE_VALUE) return; nFolders++; @@ -207,22 +207,22 @@ void AddDir2Storage(POLE::Storage* storage, std::string inDir, std::string name, { if (ffd.cFileName[0] == '.') { - if (ffd.cFileName[1] == 0 || (ffd.cFileName[1] == '.' && ffd.cFileName[2] == 0)) + if (ffd.cFileName[1] == 0 || (ffd.cFileName[1] == L'.' && ffd.cFileName[2] == 0)) continue; } outNameLcl = name + ffd.cFileName; if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - outNameLcl += "/"; + outNameLcl += L"/"; inDirLcl = inDir + ffd.cFileName; - inDirLcl += "\\"; + inDirLcl += L"\\"; AddDir2Storage(storage, inDirLcl, outNameLcl, nFolders, nFiles); } else { std::ifstream file; - std::string infname = inDir + ffd.cFileName; - const char *cinfname = infname.c_str(); + std::wstring infname = inDir + ffd.cFileName; + const wchar_t *cinfname = infname.c_str(); file.open(cinfname, std::ios::binary|std::ios::in); // find size of input file file.seekg( 0, std::ios::end ); @@ -249,12 +249,12 @@ void AddDir2Storage(POLE::Storage* storage, std::string inDir, std::string name, nFiles++; } } - while (FindNextFileA(h, &ffd) != 0); + while (FindNextFileW(h, &ffd) != 0); } -void cmdOpen(std::list &entries) +void cmdOpen(std::list &entries) { if (entries.size() < 1) std::cout << "You must enter the name of an existing file formatted as structured storage." << std::endl; @@ -262,7 +262,7 @@ void cmdOpen(std::list &entries) { if (storage != 0) storage->close(); - std::string ssName = entries.front(); + std::wstring ssName = entries.front(); entries.pop_front(); std::wstring sName(ssName.begin(), ssName.end()); @@ -272,13 +272,13 @@ void cmdOpen(std::list &entries) bool bCreate = false; if (entries.size() > 0) { - std::string modifiers = entries.front(); + std::wstring modifiers = entries.front(); for (unsigned idx = 0; idx < modifiers.size(); idx++) { - char c = modifiers[idx]; - if (c == 'c') + wchar_t c = modifiers[idx]; + if (c == L'c') bCreate = true; - else if (c == 'w') + else if (c == L'w') bWrite = true; } } @@ -302,7 +302,7 @@ void cmdOpen(std::list &entries) } } -void cmdClose(std::list &entries) +void cmdClose(std::list &entries) { if (storage) { @@ -312,7 +312,7 @@ void cmdClose(std::list &entries) } } -void cmdStats(std::list &entries) +void cmdStats(std::list &entries) { if (storage) { @@ -324,7 +324,7 @@ void cmdStats(std::list &entries) } } -void cmdVisit(std::list &entries) +void cmdVisit(std::list &entries) { if (!storage) std::cout << "No storage is opened." << std::endl; @@ -333,11 +333,11 @@ void cmdVisit(std::list &entries) if (entries.size() > 0) visit(0, storage, entries.front()); else - visit(0, storage, "/"); + visit(0, storage, L"/"); } } -void cmdExtract(std::list &entries) +void cmdExtract(std::list &entries) { if (!storage) std::cout << "No storage is opened." << std::endl; @@ -345,17 +345,17 @@ void cmdExtract(std::list &entries) std::cout << "You must specify a path in the open storage to be extracted, and a destination file or folder." << std::endl; else { - std::string ssPath = entries.front(); + std::wstring ssPath = entries.front(); entries.pop_front(); - std::string filePath = entries.front(); + std::wstring filePath = entries.front(); if (storage->isDirectory(ssPath)) { - if (filePath[filePath.size()-1] != '/') - filePath += '/'; - if (ssPath[0] != '/') - ssPath = '/' + ssPath; - if (ssPath[ssPath.size()-1] != '/') - ssPath += '/'; + if (filePath[filePath.size()-1] != L'/') + filePath += L'/'; + if (ssPath[0] != L'/') + ssPath = L'/' + ssPath; + if (ssPath[ssPath.size()-1] != L'/') + ssPath += L'/'; int nFiles = 0; int nFolders = 0; extractDir(storage, filePath, ssPath, nFolders, nFiles); @@ -369,7 +369,7 @@ void cmdExtract(std::list &entries) } } -void cmdAdd(std::list &entries) +void cmdAdd(std::list &entries) { if (!storage) std::cout << "No storage is opened." << std::endl; @@ -377,21 +377,21 @@ void cmdAdd(std::list &entries) std::cout << "You must specify a path in the open storage to be created or modified, and a source file or folder." << std::endl; else if (!storage->isWriteable()) std::cout << "The open storage cannot be modified." << std::endl; - else if (entries.front() != "/" && storage->exists(entries.front())) + else if (entries.front() != L"/" && storage->exists(entries.front())) std::cout << "The specified storage node already exists - to save it again, first delete it." << std::endl; else { - std::string ssPath = entries.front(); + std::wstring ssPath = entries.front(); entries.pop_front(); - std::string filePath = entries.front(); + std::wstring filePath = entries.front(); if (DirectoryExists(filePath.c_str())) { - if (filePath[filePath.size()-1] != '/') - filePath += '/'; - if (ssPath[0] != '/') - ssPath = '/' + ssPath; - if (ssPath[ssPath.size()-1] != '/') - ssPath += '/'; + if (filePath[filePath.size()-1] != L'/') + filePath += L'/'; + if (ssPath[0] != L'/') + ssPath = L'/' + ssPath; + if (ssPath[ssPath.size()-1] != L'/') + ssPath += L'/'; int nFiles = 0; int nFolders = 0; AddDir2Storage(storage, filePath, ssPath, nFolders, nFiles); @@ -405,7 +405,7 @@ void cmdAdd(std::list &entries) } } -void cmdDelete(std::list &entries) +void cmdDelete(std::list &entries) { if (!storage) std::cout << "No storage is opened." << std::endl; @@ -422,13 +422,13 @@ void cmdDelete(std::list &entries) } } -bool cmdQuit(std::list &entries) +bool cmdQuit(std::list &entries) { cmdClose(entries); return true; } -void cmdHelp(std::list &entries) +void cmdHelp(std::list &entries) { std::cout << "You can enter any of the following commands. Note that they are case sensitive." << std::endl; std::cout << "open filePath [modifier] - modifiers can be any combination of r, w, or c (create)" << std::endl; @@ -484,7 +484,7 @@ std::list clineParse(std::string inCmd) return outWords; } -int main(int argc, char* argv[]) +int wmain(int argc, wchar_t* argv[]) { //if( argc > 1 ) //{ @@ -492,16 +492,16 @@ int main(int argc, char* argv[]) // std::cout << argv[0] << " This takes no arguments - type help in the console window for information. " << std::endl; // return 0; //} - std::list entries; + std::list entries; - entries.push_back("open"); + entries.push_back(L"open"); entries.push_back(argv[2]); - entries.push_back("cw"); + entries.push_back(L"cw"); - entries.push_back("add"); - entries.push_back("/"); + entries.push_back(L"add"); + entries.push_back(L"/"); entries.push_back(argv[1]); - entries.push_back("close"); + entries.push_back(L"close"); std::string command; while (true) @@ -510,23 +510,23 @@ int main(int argc, char* argv[]) //std::list entries = clineParse(command); if (entries.size() == 0) continue; - std::string cmdWord = entries.front(); + std::wstring cmdWord = entries.front(); entries.pop_front(); - if (cmdWord.compare("open") == 0) + if (cmdWord.compare(L"open") == 0) cmdOpen(entries); - else if (cmdWord.compare("visit") == 0) + else if (cmdWord.compare(L"visit") == 0) cmdVisit(entries); - else if (cmdWord.compare("extract") == 0) + else if (cmdWord.compare(L"extract") == 0) cmdExtract(entries); - else if (cmdWord.compare("add") == 0) + else if (cmdWord.compare(L"add") == 0) cmdAdd(entries); - else if (cmdWord.compare("delete") == 0) + else if (cmdWord.compare(L"delete") == 0) cmdDelete(entries); - else if (cmdWord.compare("stats") == 0) + else if (cmdWord.compare(L"stats") == 0) cmdStats(entries); - else if (cmdWord.compare("close") == 0) + else if (cmdWord.compare(L"close") == 0) cmdClose(entries); - else if (cmdWord.compare("quit") == 0) + else if (cmdWord.compare(L"quit") == 0) { if (cmdQuit(entries)) break; @@ -557,4 +557,5 @@ close visit(0, storage, "/"); storage->close(); #endif + return 0; } \ No newline at end of file