/*! * Append all styles from the Psion Word Styles Section. */ UT_Error IE_Imp_Psion::applyStyles(const psiconv_word_styles_section style_sec) { UT_UTF8String props; int i; gchar *stylename; psiconv_word_style style; UT_Error res; // Iterate through all defined styles. // Index -1 is misused to represent the default "Normal" style. for (i = -1; i < (int) psiconv_list_length(style_sec->styles); i++) { if (i == -1) style = style_sec->normal; else if (!(style = (psiconv_word_style) psiconv_list_get(style_sec->styles,i))) return UT_IE_IMPORTERROR; // Get the style paragraph and character attributes. props.clear(); if ((res = getParagraphAttributes(style->paragraph,props))) return res; if ((res = getCharacterAttributes(style->character,props))) return res; // Not yet implemented: hotkey // Not yet implemented: built_in // Not yet implemented: outline_level // The three unimplemented features above are not yet available // within AbiWord. // Get the style name. if (i == -1) stylename = (gchar *) strdup("Normal"); else stylename = prepare_style_name(style->name); if (!stylename) return UT_IE_NOMEMORY; UT_DEBUGMSG(("PSION: Importing style %s\n",stylename)); UT_DEBUGMSG(("PSION: Style attributes: %s\n",props.utf8_str())); const PP_PropertyVector propsArray = { "props", props.utf8_str(), "name", stylename, // All Psion styles are based upon the Normal style "basedon", "Normal" }; if (!(getDoc()->appendStyle(propsArray))) { UT_DEBUGMSG(("PSION: AppendStyle failed...\n")); free(stylename); return UT_IE_IMPORTERROR; } free(stylename); } return UT_OK; }
static void set_col_widths (Sheet *sheet, psiconv_sheet_grid_size_list widths) { psiconv_u32 i; psiconv_sheet_grid_size psi_width; for (i = 0; i < psiconv_list_length(widths); i++) { if ((psi_width = psiconv_list_get (widths, i))) sheet_col_set_size_pts (sheet, psi_width->line_number, cm2pts (psi_width->size), TRUE); } }
static void set_row_heights (Sheet *sheet, psiconv_sheet_grid_size_list heights) { psiconv_u32 i; psiconv_sheet_grid_size psi_height; for (i = 0; i < psiconv_list_length(heights); i++) { if ((psi_height = psiconv_list_get (heights, i))) sheet_row_set_size_pts (sheet, psi_height->line_number, cm2pts (psi_height->size), TRUE); } }
static void add_cells(Sheet *sheet, const psiconv_sheet_cell_list psi_cells, const psiconv_formula_list psi_formulas, const GnmStyle *default_style) { psiconv_u32 i; psiconv_sheet_cell psi_cell; /* psiconv_lists are actually arrays, so this isn't inefficient. */ for (i = 0; i < psiconv_list_length(psi_cells); i++) { /* If psiconv_list_get fails, something is very wrong... */ if ((psi_cell = psiconv_list_get(psi_cells,i))) add_cell(sheet,psi_cell,psi_formulas, default_style); } }
static void add_workbook(Workbook *wb, psiconv_sheet_workbook_section psi_workbook) { psiconv_u32 i; psiconv_sheet_worksheet psi_worksheet; /* TODO: Perhaps add formulas and share them? */ for (i = 0; i < psiconv_list_length(psi_workbook->worksheets); i++) { /* If psiconv_list_get fails, something is very wrong... */ if ((psi_worksheet = psiconv_list_get (psi_workbook->worksheets,i))) add_worksheet(wb,psi_worksheet,i, psi_workbook->formulas); } workbook_queue_all_recalc (wb); }
/*! * Get all paragraph-related attributes and append them to props. * * If props is not empty, we start with '; ', else we do not. */ UT_Error IE_Imp_Psion::getParagraphAttributes(const psiconv_paragraph_layout layout, UT_UTF8String &props) { UT_return_val_if_fail(layout != NULL, true /* perhaps should be false, but we want loading to proceed */); UT_UTF8String buffer; psiconv_length_t indent_left,indent_first; int i; psiconv_tab tab; // Compute the indent_left and indent_first settings. Note that // indent_first is always relative to indent_left. There are a few // special cases related to bullets; see the psiconv docs for details. if (layout->bullet && layout->bullet->on && layout->bullet->indent && (layout->indent_first > 0)) indent_left = layout->indent_left + layout->indent_first; else indent_left = layout->indent_left; if (layout->bullet && layout->bullet->on && (layout->indent_first > 0)) if (layout->bullet->indent) indent_first = -layout->indent_first; else indent_first = 0; else indent_first = layout->indent_first; // Append a semicolon if there is already text in the props if (props.length()) props += ";"; // Left indent UT_UTF8String_sprintf(buffer,"margin-left:%6.3fcm",indent_left); props += buffer; // Right indent UT_UTF8String_sprintf(buffer,"; margin-right:%6.3fcm",layout->indent_right); props += buffer; // First line indent UT_UTF8String_sprintf(buffer,"; text-indent:%6.3fcm",indent_first); props += buffer; // Horizontal justify UT_UTF8String_sprintf(buffer,"; text-align:%s", layout->justify_hor==psiconv_justify_left ? "left" : layout->justify_hor==psiconv_justify_right ? "right": layout->justify_hor==psiconv_justify_centre? "center": "justify"); props += buffer; // Vertical justify: ignored (never used in Word documents) // Background color UT_UTF8String_sprintf(buffer, "; bgcolor: %02x%02x%02x", layout->back_color->red, layout->back_color->green, layout->back_color->blue); props += buffer; #if 0 // Linespacing (gives trouble at the moment, so we disable it) UT_UTF8String_sprintf(buffer, "; line-height: %dpt",(int) layout->linespacing); props += buffer; if (! layout->linespacing_exact) props += "+"; #endif // Space above UT_UTF8String_sprintf(buffer,"; margin-top:%dpt",(int) layout->space_above); props += buffer; // Space below UT_UTF8String_sprintf(buffer,"; margin-bottom:%dpt",(int) layout->space_below); props += buffer; // Keep together UT_UTF8String_sprintf(buffer,"; keep-together:%s",layout->keep_together?"yes":"no"); props += buffer; // Keep with next UT_UTF8String_sprintf(buffer,"; keep-with-next:%s",layout->keep_with_next?"yes":"no"); props += buffer; // On next page // This is not yet implemented in AbiWord. We use a hack in // applyParagraphAttributes; styles are out of luck in this. // Last checked 20040229: Dialog is available, but no property yet. // Widow control // I'm not quite sure about the difference between setting widows and // orphans?!? UT_UTF8String_sprintf(buffer,"; widows:%d; orphans:%d", layout->no_widow_protection?0:2, layout->no_widow_protection?0:2); props += buffer; // Default tab interval. UT_UTF8String_sprintf(buffer,"; default-tab-interval:%6.3fcm",layout->tabs->normal); props += buffer; // Other tabs if (psiconv_list_length(layout->tabs->extras)) { props += "; tabstops:"; for (i = 0; i < (int) psiconv_list_length(layout->tabs->extras); i++) { if (!(tab = (psiconv_tab) psiconv_list_get(layout->tabs->extras, i))) { UT_ASSERT(tab != NULL); return(UT_IE_IMPORTERROR); } UT_UTF8String_sprintf(buffer, "%s%6.3fcm/%c", i==0?"":",", tab->location, tab->kind == psiconv_tab_centre?'C': tab->kind == psiconv_tab_right? 'R': 'L'); props += buffer; } } // Bullets. I don't think there is a general way to do this yet. // For now, we will hardcode all bullets to type 'Bullet List', // because we might get into real trouble. Note that we hack // this together in applyParagraphAttributes. // Not yet implemented: borders // These are not yet available in AbiWord. return UT_OK; }
/*! * Add the page attributes to the documents * * Set all page (section) attributes, and do an appendStrux(PTX_Section,...) * These settings are global for the whole document: Psion documents * contain only one single section. */ UT_Error IE_Imp_Psion::applyPageAttributes(const psiconv_page_layout_section layout, bool &with_header, bool &with_footer) { UT_return_val_if_fail(layout != NULL, true /* perhaps should be false, but we want loading to proceed */); UT_UTF8String props,buffer; // Determine whether we have a header and a footer. We can't append them // here, because they have to come after the main section (or AbiWord will // become very confused). with_header = layout->header && layout->header->text && layout->header->text->paragraphs && psiconv_list_length(layout->header->text->paragraphs); with_footer = layout->footer && layout->footer->text && layout->footer->text->paragraphs && psiconv_list_length(layout->footer->text->paragraphs); const PP_PropertyVector propsArray = { // Page width "width", UT_std_string_sprintf("%6.3f", layout->page_width), // Page height "height", UT_std_string_sprintf("%6.3f", layout->page_width), // Units of width/height "units", "cm", // Orientation "orientation", layout->landscape ? "landscape" : "portrait", // Page type (we should check for common ones here!) "pagetype", "Custom" }; if (!(getDoc()->setPageSizeFromFile(propsArray))) return UT_IE_IMPORTERROR; // First page number not yet implemented // On first page not yet implemented // left margin UT_UTF8String_sprintf(buffer,"page-margin-left:%6.3fcm",layout->left_margin); props += buffer; // right margin UT_UTF8String_sprintf(buffer,"; page-margin-right:%6.3fcm",layout->right_margin); props += buffer; // top margin UT_UTF8String_sprintf(buffer,"; page-margin-top:%6.3fcm",layout->top_margin); props += buffer; // bottom margin UT_UTF8String_sprintf(buffer,"; page-margin-bottom:%6.3fcm",layout->bottom_margin); props += buffer; // header distance UT_UTF8String_sprintf(buffer,"; page-margin-header:%6.3fcm",layout->header_dist); props += buffer; // footer distance UT_UTF8String_sprintf(buffer,"; page-margin-footer:%6.3fcm",layout->footer_dist); props += buffer; // Now actually append the properties in a PTX_Section strux to the document UT_DEBUGMSG(("PSION: Page: %s\n",props.utf8_str())); PP_PropertyVector propsArray2 = { "props", props.utf8_str() }; if (with_header) { propsArray2.push_back("header"); propsArray2.push_back("1"); } if (with_footer) { propsArray2.push_back("footer"); propsArray2.push_back("2"); } if (!(appendStrux(PTX_Section,propsArray2))) { return UT_IE_IMPORTERROR; } return UT_OK; }
/*! * Read all Psion paragraphs and add them to the document. */ UT_Error IE_Imp_Psion::readParagraphs(const psiconv_text_and_layout psiontext, const psiconv_word_styles_section style_sec) // psiconv_list embobjlst) { unsigned int i,inline_nr; int loc; psiconv_paragraph paragraph; psiconv_in_line_layout in_line; UT_UCS4String text; psiconv_word_style style; const gchar *stylename; UT_Error res; // Iterate through all paragraphs for (i=0; i < psiconv_list_length(psiontext); i++) { UT_DEBUGMSG(("PSION: Importing paragraph %d\n",i)); if (!(paragraph = (psiconv_paragraph) psiconv_list_get(psiontext,i))) { // Something is really wrong... UT_ASSERT(paragraph != NULL); return UT_IE_IMPORTERROR; } // Determine the style name; set it to Normal if it is not available if (!style_sec || !(style = psiconv_get_style(style_sec,paragraph->base_style)) || (!style->name) || !(stylename = prepare_style_name(style->name))) stylename = (const gchar *) strdup("Normal"); if (!stylename) return UT_IE_NOMEMORY; UT_DEBUGMSG(("PSION: paragraph %d: style %s\n",i,stylename)); // Add all paragraph attributes to the document if ((res = applyParagraphAttributes(paragraph->base_paragraph,stylename))) return res; // Iterate through all Psion inlines. These contain the character // layout information, together with the number of characters they // apply to. loc = 0; for(inline_nr=0; inline_nr < psiconv_list_length(paragraph->in_lines); inline_nr++) { UT_DEBUGMSG(("Psion: paragraph %d inline %d\n",i,inline_nr)); if (!(in_line = (psiconv_in_line_layout) psiconv_list_get(paragraph->in_lines,inline_nr))) { // Something is really wrong... UT_ASSERT(in_line != NULL); return UT_IE_IMPORTERROR; } // This may be an object, which needs special handling. // Objects have layout associated with them, but we will ignore // it. I am not sure how it would apply anyway. We will also ignore // all text. It should just be a single character \016, which is the // object marker. if (in_line->object) { if ((res = insertObject(in_line))) return res; } else { // Put all characters belonging to the current inline into text text.clear(); if ((res = prepareCharacters(paragraph->text + loc,in_line->length, text))) return res; // Yes, text may be empty! if (text.length()) { // Add the character layout and the text itself to the document if ((res = applyCharacterAttributes(in_line->layout))) return res; if (!(appendSpan((text.ucs4_str()),text.length()))) return UT_IE_IMPORTERROR; } } loc += in_line->length; } // There may be text left after iterating through all inlines. // This remaining text gets the paragraph base_character layout. if (loc < psiconv_unicode_strlen(paragraph->text)) { // Get the remaining characters into text text.clear(); if ((res = prepareCharacters(paragraph->text+loc, psiconv_unicode_strlen(paragraph->text - loc),text))) return res; // Yes, text may be empty! if (text.length()) { // Add the character layout and the text itself to the document. if ((res = applyCharacterAttributes(paragraph->base_character))) return res; if (!appendSpan(text.ucs4_str(),text.length())) return UT_IE_IMPORTERROR; } } } return UT_OK; }