#include #include "fiebdc.h" //#include "globalvars.h" // Asumiendo que globalVars está definido aquí #include FIEBDC::FIEBDC(QString filename, Budget* budget) { __budget = budget; __filename = filename; if (__budget != nullptr) { __budget->filename = __filename; } __cancel = false; __format_list = {"FIEBDC-3/95", "FIEBDC-3/98", "FIEBDC-3/2002", "FIEBDC-3/2004", "FIEBDC-3/2007"}; __character_sets_dict = {{"ANSI", "cp1252"}, {"850", "850"}, {"437", "cp437"}}; __file_format = "FIEBDC-3/2007"; //__generator = globalVars.name + " " + globalVars.version; __character_set = "850"; initializePatterns(); } void FIEBDC::initializePatterns() { __pattern = { {"control_tilde", QRegularExpression(R"(((\r\n)| |\t)+~)")}, {"control_vbar", QRegularExpression(R"(((\r\n)| |\t)+\|)")}, {"control_backslash", QRegularExpression(R"(((\r\n)| |\t)+\\)")}, {"valid_code", QRegularExpression(R"([^A-Za-z0-9ñÑ.$#%&_])")}, {"special_char", QRegularExpression(R"([#%&])")}, {"no_float", QRegularExpression(R"([^\-0-9.])")}, {"formula", QRegularExpression(R"(.*[^0123456789\.()\+\-\*/\^abcdp ].*)")}, {"comment", QRegularExpression(R"(#.*\r\n)")}, {"empty_line", QRegularExpression(R"((\r\n) *\r\n)")}, {"space_before_backslash", QRegularExpression(R"(( )+\\)")}, {"space_after_backslash", QRegularExpression(R"(\\( )+)")}, {"start_noend_backslash", QRegularExpression(R"((\r\n\\\.*[^\\\])\r\n)")}, {"end_oper", QRegularExpression(R"((\+|-|\*|/|/^|@|&|<|>|<=|>=|=|!) *\r\n)")}, {"matricial_var", QRegularExpression(R"((\r\n *[%|\$][A-ZÑ].*=.*, ) *\r\n)")}, {"descomposition", QRegularExpression(R"(^([^:]+):(.*)$)")}, {"var", QRegularExpression(R"(^([$%][A-ZÑ][()0-9, ]*)=(.*)$)")}, {"after_first_tilde", QRegularExpression(R"(^[^~]*~)")}, {"end_control", QRegularExpression(R"(((\r\n)| |\t)+$)")} }; } void FIEBDC::cancel() { __cancel = true; } QString FIEBDC::eraseControlCharacters(const QString& input) { // Implementación de la función para eliminar caracteres de control QString string = input; string = string.replace(__pattern["control_tilde"], "~"); string = string.replace(__pattern["control_vbar"], "|"); // Uncomment if control_backslash processing is needed // string = string.replace(__pattern["control_backslash"], "\\"); return string; } bool FIEBDC::validateCode(const QString& code) { // Implementación de la función para validar el código QRegularExpression re("^[A-Z0-9]+$"); return re.match(code).hasMatch(); } QDate FIEBDC::parseDate(const QString& dateStr) { /*parseDate(date) date: in the format: uneven len: add a Leading 0 len = 8 DDMMYYYY len <= 6 DDMMYY “80/20”. >80 -> >1980 <80 -> <2080 len < 5 MMYY len < 3 YY Test date string and return a tuple (YYYY, MM, DD) or None if the date format is invalid */ if (dateStr.isEmpty()) { return QDate(); } QString paddedDate = dateStr; if (dateStr.length() % 2 != 0) { paddedDate.prepend("0"); // Agregar un 0 inicial si la longitud es impar } // Intentar con diferentes formatos según la longitud if (paddedDate.length() == 8) { return QDate::fromString(paddedDate, "ddMMyyyy"); } else if (paddedDate.length() == 6) { QString yearPrefix = paddedDate.right(2).toInt() < 80 ? "20" : "19"; return QDate::fromString(yearPrefix + paddedDate, "yyyyMMdd"); } else if (paddedDate.length() == 4) { QString yearPrefix = paddedDate.right(2).toInt() < 80 ? "20" : "19"; return QDate::fromString(yearPrefix + paddedDate, "yyyyMM"); } else if (paddedDate.length() == 2) { QString yearPrefix = paddedDate.toInt() < 80 ? "20" : "19"; return QDate::fromString(yearPrefix + paddedDate, "yyyy"); } return QDate(); // Fecha inválida } void FIEBDC::parseRecord(const QString& record) { /* parseRecord(record, interface) record: the record line readed from the file whith the format: type|field|field|subfield\\subfield|... [a] nothing or "a" {a} zero or more #-#twice#-# "a" one or more #-#twice#-# "a" Types: V C D Y M N T K L Q J G E X B F A V: Property and Version 1- [File_Owner] 2- Format_Version[\\DDMMYYYY] 3- [Program_Generator] 4- [Header]\\{Title\\} 5- [Chaters_set] 6- [Comment] C: Record: 1- Code{\\Code} 2- [Unit] 3- [Summary] 4- {Price\\} 5- {Date\\} 6- [Type] D or Y: DECOMPOSITION or ADD DECOMPOSITION 1- Parent Code 2- M or N: MEASURE or ADD MEASURE 1- [Parent Code\\]Child Code 2- {Path\} 3- TOTAL MEASURE 4- {Type\\Comment\\Unit\\Length\\Width\\Height\\} 5- [Label] T: Text 1- Code 2- Description text K: Coefficients 1- { DN \\ DD \\ DS \\ DR \\ DI \\ DP \\ DC \\ DM \\ DIVISA \\ } 2- CI \\ GG \\ BI \\ BAJA \\ IVA 3- { DRC \\ DC \\ DRO \\ DFS \\ DRS \\ DFO \\ DUO \\ DI \\ DES \\ DN \\ DD \\ DS \\ DIVISA \\ } 4- [ n ] L: Sheet of Conditions 1 A) 1- Empty 2- {Section Code\\Section Title} B) 1- Record Code 2- {Section Code\\Section Text} 3- {Section Code\\RTF file} 4- {Section Code\\HTM file} Q: Sheet of Conditions 2 1- Record Code 2- {Section Code\\Paragraph key\\{Field key;}\\}| J: Sheet of Conditions 3 1- Paragraph code 2- [Paragraph text] 3- [RTF file] 4- [HTML file] G: Grafic info 1- E: Company 1- company Code 2 [ summary ] 3- [ name ] 4- { [ type ] \\ [ subname ] \\ [ address ] \\ [ postal_code ] \\ [ town ] \\ [ province ] \\ [ country ] \\ { phone; } \\ { fax; } \\ {contact_person; } \\ } 5- [ cif ] \\ [ web ] \\ [ email ] \\ X: Tecnical information A) 1- Empty 2- < TI_Code \\ TI_Descitption \\ TI_Unit > B) 1- Record_code 2- < TI_Code \\ TI_value > F: #-#Adjunto#-# File 1- Record code 2- { Type \\ { Filenames; } \\ [Description] } B: Change code 1- Record Code 2- New code A: Labels 1- Record Code 2- interface: */ QStringList fields = record.split("|"); if (fields.isEmpty()) { return; } QString recordType = fields.at(0); if (recordType == "V") { } else if (recordType == "C") { } else if (recordType == "D" || recordType == "Y") { } else if (recordType == "T") { } else { qDebug() << "Unknown record type:" << recordType << fields; } } void FIEBDC::parseV(QStringList fields) { /* parseV(field_list) field_list: field list of the record 0- V :Property and Version 1- [File_Owner] 2- Format_Version[\DDMMYYYY] 3- [Program_Generator] 4- [Header]\{Title\} 5- [Chaters_set] 6- [Comment] 7- [Data type] 8- [Number budget certificate] 9- [Date budget certificate] */ if (fields.size() < 10) { qWarning() << "Invalid 'V' record, insufficient fields:" << fields; return; } QString owner = fields[1].trimmed(); QString versionDate = fields[2].trimmed(); QString generator = fields[3].trimmed(); QString headerTitle = fields[4].trimmed(); QString characterSet = fields[5].trimmed(); QString comment = fields[6].trimmed(); QString dataType = fields[7].trimmed(); QString numberCertificate = fields[8].trimmed(); QString dateCertificate = fields[9].trimmed(); // Process version and date QStringList versionDateParts = versionDate.split("\\"); if (!versionDateParts.isEmpty()) { auto fileFormat = versionDateParts[0]; qDebug() << "File format set to:" << fileFormat; if (versionDateParts.size() > 1) { QDate parsedDate = parseDate(versionDateParts[1]); if (parsedDate.isValid()) { qDebug() << "Parsed version date:" << parsedDate; } } } /* # _____number of fields_____ # Any INFORMATION after last field separator is ignored if len(field_list) > 10: field_list = field_list[:10] # If there are no sufficient fields, the fields are added # with empty value:"" else: field_list = field_list + [""]*(10-len(field_list)) # control character are erased: end of line, tab, space # only leading and trailing whitespace in owner, generator, comment # _____Fields_____ _record_type = self.delete_control_space(field_list[0]) _owner = field_list[1].strip() _owner = self.delete_control(_owner) _version_date = self.delete_control_space(field_list[2]) _generator = field_list[3].strip() _generator = self.delete_control(_generator) _header_title = field_list[4].strip() _header_title = self.delete_control(_header_title) _character_set = self.delete_control_space(field_list[5]) _comment = field_list[6].strip("\t \n\r") _data_type = self.delete_control_space(field_list[7]) _number_certificate = self.delete_control_space(field_list[8]) __date_certificate = self.delete_control_space(field_list[9]) # _____Owner_____ self.__budget.setOwner(_owner) # _____Version-Date_____ _version_date = _version_date.split("\\") _file_format = _version_date[0] if _file_format in self.__format_list: self.__file_format = _file_format _tuni = _("FIEBDC format: $1") _uni = utils.mapping(_tuni, (_file_format,)) print(_uni) if len(_version_date) > 1: _date = _version_date[1] if _date != "": _parsed_date = self.parseDate(_date) if _parsed_date is not None: self.__budget.setDate(_parsed_date) # _____Generator_____ # ignored field _tuni = _("FIEBDC file generated by $1") _uni = utils.mapping(_tuni, (_generator,)) print(_uni) # _____Header_Title_____ _header_title = _header_title.split("\\") _header_title = [_title.strip() for _title in _header_title] _header = _header_title.pop(0) _title = [ ] for _title_index in _header_title: if _title_index != "": _title.append(_title_index) if _header != "": self.__budget.setTitleList([ _header, _title]) # _____Characters_set_____ # field parsed in readFile method # _____Comment_____ if _comment != "": self.__budget.setComment(_comment) # _____Data type_____ # 1 -> Base data. # 2 -> Budget. # 3 -> Budget certificate. # 4 -> Base date update. try: _data_type = int(_data_type) except ValueError: _data_type = "" if _data_type == 3: # _____Number budget certificate_____ try: _number_certificate = int(_number_certificate) except ValueError: _number_certificate = "" # _____Date budget certificate_____ if _date_certificate != "": _parsed_date_certificate = self.parseDate(_date_certificate) if _parsed_date_certificate is None: _date_certificate = "" else: _date_certificate = _parsed_date_certificate self.__budget.setBudgetype(_data_type) self.__budget.setCertificateOrder(_number_certificate) self.__budget.setCertificateDate(_parsed_date_cerfificate) elif _data_type != "": self.__budget.setBudgeType(_data_type) self.__statistics.valid = self.__statistics.valid + 1 */ } void FIEBDC::readFile(Budget* budget, QString filename) { // Implementación de la función para leer el archivo if (budget != nullptr) { __budget = budget; } if (!filename.isEmpty()) { __filename = filename; } // Lógica para leer el archivo }