bool fp_FieldTOCHeadingRun::calculateValue(void)
{
    UT_UCSChar sz_ucs_FieldValue[FPFIELD_MAX_LENGTH + 1];
//
// First get owning TOC.
//
    UT_ASSERT(getLength() == 0);
    fl_TOCLayout * pTOCL = static_cast<fl_TOCLayout *>(getBlock()->myContainingLayout());
    UT_ASSERT(pTOCL->getContainerType() == FL_CONTAINER_TOC);
    UT_UCS4String str = pTOCL->getTOCHeading().ucs4_str();
    if(str.size() == 0)
    {
        sz_ucs_FieldValue[0] = 0;
        return _setValue(sz_ucs_FieldValue);
    }
    UT_sint32 i = 0;
    bool bStop = false;

    for(i=0; (i<FPFIELD_MAX_LENGTH) && !bStop; i++)
    {
        sz_ucs_FieldValue[i] = static_cast<UT_UCSChar>(str[i]);
        if(str[i] == 0)
        {
            bStop = true;
        }
    }
    return _setValue(sz_ucs_FieldValue);
}
Exemple #2
0
//
// AbiGoogle_invoke
// -------------------
//   This is the function that we actually call to invoke the on-line dictionary.
//   It should be called when the user selects from the context menu
//
static bool 
AbiGoogle_invoke(AV_View* /*v*/, EV_EditMethodCallData * /*d*/)
{
  // Get the current view that the user is in.
  XAP_Frame *pFrame = XAP_App::getApp()->getLastFocussedFrame();
  FV_View* pView = static_cast<FV_View*>(pFrame->getCurrentView());
  
  // If the user is on a word, but does not have it selected, we need
  // to go ahead and select that word so that the search/replace goes
  // correctly.
  if (pView->isSelectionEmpty()) {
    pView->moveInsPtTo(FV_DOCPOS_EOW_MOVE);
    pView->moveInsPtTo(FV_DOCPOS_BOW);
    pView->extSelTo(FV_DOCPOS_EOW_SELECT);   
  }

  // Now we will figure out what word to look up
  UT_UTF8String url ("http://www.google.com/search?hl=en&ie=UTF-8&oe=UTF-8&q=");
  
  // url escaping should be moved somewhere more generic
  UT_UCS4Char *ucs4ST;
  pView->getSelectionText(*&ucs4ST);
  UT_UCS4String data (ucs4ST);
  bool last_was_space = false;
  for (size_t i = 0; i < data.length (); i++) {
    UT_UCS4Char ch = data[i];
    if (!UT_UCS4_isspace (ch)) {
      url.appendUCS4 (&ch, 1);
      last_was_space = false;
    }
    else if (!last_was_space) {
      ch = '+';
      url.appendUCS4 (&ch, 1);
      last_was_space = true;
    }
  }

  XAP_App::getApp()->openURL( url.utf8_str() ); 
  FREEP(ucs4ST);

  return true;
}
Exemple #3
0
/* Read characters from input and append them to text
 *
 * You must insure the input has at least length characters!
 * We handle special Psion markup tokens here. Except object markers,
 * they are handled in readParagraphs.
 */
UT_Error IE_Imp_Psion::prepareCharacters(const psiconv_ucs2 *input, int length,
                                        UT_UCS4String &text)
//                                        psiconv_list embobjlst)
{
	int i;
	UT_UCS4Char uc;

	for (i = 0; i < length; i++) {
		// Note that we may actually encounter an '\000' here too. This
		// is a psiconv left-over: the line ending sign may have
		// layout too, so the layout applies to typically one character
		// more than the paragraph length we see here.
		if (input[i] == '\006')      // New paragraph (should never happen)
			continue;
		else if (input[i] == '\007') // New line (is this right?)
			uc = UCS_LF;
		else if (input[i] == '\010') // Hard page
			uc = UCS_FF;
		else if (input[i] == '\011') // Tab
			uc = UCS_TAB;
		else if (input[i] == '\012') // Unbreakable tab (not implemented?)
			uc = UCS_TAB;
		else if (input[i] == '\013') // Unbreakable dash (is this right?)
			uc = UCS_EN_DASH;
		else if (input[i] == '\014') // Potential hyphen (do we have it?)
			continue;
		else if (input[i] == '\015') // Unknown functionality
			continue;
		else if (input[i] == '\017') // Visible space. Handle as normal space.
			uc = UCS_SPACE;
		else if (input[i] < 32) // Not implemented
			continue;
		else // More or less normal character
			uc = input[i];
		text += uc;
	}
	UT_DEBUGMSG(("PSION: text: %s\n",text.utf8_str()));
	return UT_OK;
}
Exemple #4
0
/*!
 * 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;
}
bool ODe_MetaDataWriter::writeMetaData(PD_Document* pDoc, GsfOutfile* oo) {
    
    GsfOutput* meta = gsf_outfile_new_child (oo, "meta.xml", FALSE);

    static const UT_UTF8String preamble =
        UT_UTF8String("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
        "<office:document-meta"
            " xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\""
            " xmlns:xlink=\"http://www.w3.org/1999/xlink\""
            " xmlns:dc=\"http://purl.org/dc/elements/1.1/\""
            " xmlns:meta=\"urn:oasis:names:tc:opendocument:xmlns:meta:1.0\""
            " xmlns:ooo=\"http://openoffice.org/2004/office\""
            " office:version=\"1.1\">\n"
        "<office:meta>\n"
        "<meta:generator>AbiWord/") + PACKAGE_VERSION + " (" + PLATFORM + ", " + TOOLKIT + ")</meta:generator>\n";

    static const char * const postamble [] = {
        "</office:meta>\n",
        "</office:document-meta>\n"
    };

    ODe_writeUTF8String(meta, preamble);

    UT_UTF8String meta_val, val;
    
#define WRITE_METADATA_ELEMENT(abiwordKey, odElementName) if (pDoc->getMetaDataProp(abiwordKey, meta_val) && meta_val.size()) { \
                                                               meta_val.escapeXML(); \
                                                               val = UT_UTF8String_sprintf("<%s>%s</%s>\n", odElementName, meta_val.utf8_str(), odElementName); \
                                                               ODe_writeUTF8String (meta, val); \
                                                          }
    
    WRITE_METADATA_ELEMENT(PD_META_KEY_TITLE, "dc:title");
    WRITE_METADATA_ELEMENT(PD_META_KEY_DESCRIPTION, "dc:description");
    WRITE_METADATA_ELEMENT(PD_META_KEY_SUBJECT, "dc:subject");

    //Each keyword needs to be exported individually:

    UT_UTF8String keywords;
    if (pDoc->getMetaDataProp (PD_META_KEY_KEYWORDS, keywords) && keywords.size())
    {
        UT_UTF8String buf = "";
        UT_UCS4String keyword = keywords.utf8_str();

        for(UT_uint32 i = 0;i < keyword.length(); i++)
        {
            if(keyword[i] != ' ')
            {
                buf += keyword[i];
            }
            else
            {
                if(buf.empty())  //only blank space encountered
                    continue;

                buf.escapeXML();
                val = UT_UTF8String_sprintf("<meta:keyword>%s</meta:keyword>\n", buf.utf8_str());
                ODe_writeUTF8String(meta, val);
                buf.clear();
            }
        }

        if(buf.length())  //there may only be one keyword (i.e. no spaces encountered)
        {
            buf.escapeXML();
            val = UT_UTF8String_sprintf("<meta:keyword>%s</meta:keyword>\n", buf.utf8_str());
            ODe_writeUTF8String(meta, val);
        }
    }

    // Should have a PD_META_KEY_INITIAL_CREATOR macro for this one, but only
    // if it gets implemented on the document properties dialog.
    WRITE_METADATA_ELEMENT("meta:initial-creator", "meta:initial-creator");
    
    WRITE_METADATA_ELEMENT(PD_META_KEY_CREATOR, "dc:creator");
    
    WRITE_METADATA_ELEMENT("meta:printed-by", "meta:printed-by");
    
    // ATTENTION: I'm assuming that dc.date is used by AbiWord as
    // the document creation date & time.
    WRITE_METADATA_ELEMENT(PD_META_KEY_DATE, "meta:creation-date");
    
    // Note that, for the OpenDocument standard, dc.date
    // is the last modification date & time.
    WRITE_METADATA_ELEMENT(PD_META_KEY_DATE_LAST_CHANGED, "dc:date");
    
    WRITE_METADATA_ELEMENT("meta:print-date", "meta:print-date");
    
    WRITE_METADATA_ELEMENT(PD_META_KEY_LANGUAGE, "dc:language");
    
#undef WRITE_METADATA_ELEMENT

    ODe_writeToStream(meta, postamble, G_N_ELEMENTS(postamble));

    ODe_gsf_output_close(meta);

    return true;
}
UT_Error IE_Imp_StarOffice::_loadFile(GsfInput * input)
{
	try {
		UT_DEBUGMSG(("SDW: Starting import\n"));
		mOle = GSF_INFILE (gsf_infile_msole_new(input, NULL));
		if (!mOle)
			return UT_IE_BOGUSDOCUMENT;

		// firstly, load metadata
		SDWDocInfo::load(mOle, getDoc());

		mDocStream = gsf_infile_child_by_name(mOle, "StarWriterDocument");
		if (!mDocStream)
			return UT_IE_BOGUSDOCUMENT;

		gsf_off_t size = gsf_input_size(mDocStream);

		if (!appendStrux(PTX_Section, PP_NOPROPS))
			return UT_IE_NOMEMORY;

		UT_DEBUGMSG(("SDW: Attempting to load DocHdr...\n"));
		mDocHdr.load(mDocStream);
		UT_DEBUGMSG(("SDW: ...success\n"));

		// Ask for and verify the password
		if (mDocHdr.cryptor) {
			if (!mDocHdr.cryptor->SetPassword(GetPassword().c_str())) {
				UT_DEBUGMSG(("SDW: Wrong password\n"));
				return UT_IE_PROTECTED;
			}
		}

		// do the actual reading
		char type;
		bool done = false;
		UT_uint32 recSize;
		while (!done) {
			if (gsf_input_tell(mDocStream) == size)
				break;
			readChar(mDocStream, type);
			gsf_off_t eor;
			readRecSize(mDocStream, recSize, &eor);

			switch (type) {
				case SWG_CONTENTS: {
					gsf_off_t flagsEnd = 0;
					UT_uint32 nNodes;
					// sw/source/core/sw3io/sw3sectn.cxx#L129
					if (mDocHdr.nVersion >= SWG_LAYFRAMES) {
						UT_uint8 flags;
						readFlagRec(mDocStream, flags, &flagsEnd);
					}
					if (mDocHdr.nVersion >= SWG_LONGIDX)
						streamRead(mDocStream, nNodes);
					else {
						if (mDocHdr.nVersion >= SWG_LAYFRAMES) {
							UT_uint16 sectidDummy;
							streamRead(mDocStream, sectidDummy);
						}
						UT_uint16 nodes16;
						streamRead(mDocStream, nodes16);
						nNodes = (UT_uint32)nodes16;
					}
					if (flagsEnd) {
						UT_ASSERT(flagsEnd >= gsf_input_tell(mDocStream));
						if (gsf_input_tell(mDocStream) != flagsEnd) {
							UT_DEBUGMSG(("SDW: have not read all flags\n"));
							if (gsf_input_seek(mDocStream, flagsEnd, G_SEEK_SET))
								return UT_IE_BOGUSDOCUMENT;
						}
					}
					bool done2 = false;
					UT_uint32 size2;
					while (!done2) {
						readChar(mDocStream, type);
						gsf_off_t eor2;
						readRecSize(mDocStream, size2, &eor2);

						switch (type) {
							case SWG_TEXTNODE: { // sw/source/core/sw3io/sw3nodes.cxx#L788
								UT_DEBUGMSG(("SDW: Found Textnode! (start at 0x%08llX end at 0x%08llX)\n", 
											 (long long)gsf_input_tell(mDocStream), 
											 (long long)eor2));
								UT_uint8 flags;
								gsf_off_t newPos;
								readFlagRec(mDocStream, flags, &newPos);
								// XXX check flags
								if (gsf_input_seek(mDocStream, newPos, G_SEEK_SET))
									return UT_IE_BOGUSDOCUMENT;

								// Read the actual text
								UT_UCS4Char* str;
								readByteString(mDocStream, str);
								UT_UCS4String textNode(str);
								free(str);
								UT_DEBUGMSG(("SDW: ...length=%zu contents are: |%s|\n", textNode.length(), textNode.utf8_str()));

								// now get the attributes
								UT_String attrs;
								UT_String pAttrs;
								UT_Vector charAttributes;
								while (gsf_input_tell(mDocStream) < eor2) {
									char attVal;
									streamRead(mDocStream, attVal);
									UT_uint32 attSize;
									gsf_off_t eoa; // end of attribute
									readRecSize(mDocStream, attSize, &eoa);
									if (attVal == SWG_ATTRIBUTE) {
										TextAttr* a = new TextAttr;
										streamRead(mDocStream, *a, eoa);
										UT_DEBUGMSG(("SDW: ...found text-sub-node, which=0x%x, ver=0x%x, start=%u, end=%u - data:%s len:%llu data is:",
													 a->which, a->ver, a->start,
													 a->end, a->data?"Yes":"No",
													 (long long unsigned)a->dataLen));
#ifdef DEBUG
										hexdump(a->data, a->dataLen);
                    putc('\n', stderr);
#endif
										charAttributes.addItem(a);
									}
									else if (attVal == SWG_ATTRSET) {
									  // bah, yet another loop
										UT_DEBUGMSG(("SDW: ...paragraph attributes found\n"));
										while (gsf_input_tell(mDocStream) < eoa) {
											// reusing attVal and attSize
											streamRead(mDocStream, attVal);
											gsf_off_t eoa2; // end of attribute
											readRecSize(mDocStream, attSize, &eoa2);
											if (attVal == SWG_ATTRIBUTE) {
												TextAttr a;
												streamRead(mDocStream, a, eoa2);
                        if (!a.attrVal.empty()) {
  												if (a.isPara)
	  												UT_String_setProperty(pAttrs, a.attrName, a.attrVal);
		  										else
			  										UT_String_setProperty(attrs, a.attrName, a.attrVal);
                        }
						UT_DEBUGMSG(("SDW: ......found paragraph attr, which=0x%x, ver=0x%x, start=%u, end=%u (string now %s) Data:%s Len=%lld Data:", a.which, a.ver, (a.startSet?a.start:0), (a.endSet?a.end:0), attrs.c_str(), (a.data ? "Yes" : "No"), (long long)a.dataLen));
#ifdef DEBUG
												hexdump(a.data, a.dataLen);
                        putc('\n', stderr);
#endif
											}
											if (gsf_input_seek(mDocStream, eoa2, G_SEEK_SET))
												return UT_IE_BOGUSDOCUMENT;
										}
									}
									else {
										UT_DEBUGMSG(("SDW: ...unknown attribute '%c' found (start=%" GSF_OFF_T_FORMAT " end=%" GSF_OFF_T_FORMAT ")\n", attVal, gsf_input_tell(mDocStream), eoa));
									}
									if (gsf_input_seek(mDocStream, eoa, G_SEEK_SET))
										return UT_IE_BOGUSDOCUMENT;
								}

								PP_PropertyVector attributes = {
									"props",
									pAttrs.c_str()
								};
								// first, insert the paragraph
								if (!appendStrux(PTX_Block, attributes))
									return UT_IE_NOMEMORY;

								UT_String pca(attrs); // character attributes for the whole paragraph
								// now insert the spans of text
								UT_uint32 len = textNode.length();
								UT_uint32 lastInsPos = 0;
								for (UT_uint32 i = 1; i < len; i++) {
									bool doInsert = false; // whether there was an attribute change
									for (UT_sint32 j = 0; j < charAttributes.getItemCount(); j++) {
										const TextAttr* a = reinterpret_cast<const TextAttr*>(charAttributes[j]);
										// clear the last attribute, if set
										if (a->endSet && a->end == (i - 1)) {
											if (a->isOff) {
												UT_String propval = UT_String_getPropVal(pca, a->attrName);
												UT_String_setProperty(attrs, a->attrName, propval);
											}
											else
												UT_String_removeProperty(attrs, a->attrName);
										}

										// now set new attribute, if needed
										if (a->startSet && a->start == (i - 1)) {
											if (a->isPara)
												UT_String_setProperty(pAttrs, a->attrName, a->attrVal);
											else if (a->isOff)
												UT_String_removeProperty(attrs, a->attrName);
											else
												UT_String_setProperty(attrs, a->attrName, a->attrVal);
										}

										// insert if this is the last character, or if there was a format change
										if ((a->endSet && a->end == i) || (a->startSet && a->start == i))
											doInsert = true;
									}
									if (doInsert || i == (len - 1)) {
										attributes[1] = attrs.c_str();
										UT_DEBUGMSG(("SDW: Going to appendFmt with %s\n", attributes[1].c_str()));
										if (!appendFmt(attributes))
											return UT_IE_NOMEMORY; /* leave cast alone! */
										UT_DEBUGMSG(("SDW: About to insert %u-%u\n", lastInsPos, i));
										size_t spanLen = i - lastInsPos;
										if (i == (len - 1)) spanLen++;
										UT_UCS4String span = textNode.substr(lastInsPos, spanLen);
										appendSpan(span.ucs4_str(), spanLen);
										lastInsPos = i;
									}
								}

								UT_VECTOR_PURGEALL(TextAttr*, charAttributes);
								break;

							}
							case SWG_JOBSETUP: {
								// flags are apparently unused here. no idea why they are there.
								gsf_off_t newpos;
								UT_uint8 flags;
								readFlagRec(mDocStream, flags, &newpos);
								if (gsf_input_seek(mDocStream, newpos, G_SEEK_SET))
									return UT_IE_BOGUSDOCUMENT;
								UT_uint16 len, system;
								streamRead(mDocStream, len);
								streamRead(mDocStream, system);
								char printerName[64];
								streamRead(mDocStream, printerName, 64);
								char deviceName[32], portName[32], driverName[32];
								streamRead(mDocStream, deviceName, 32);
								streamRead(mDocStream, portName, 32);
								streamRead(mDocStream, driverName, 32);
								UT_DEBUGMSG(("SDW: Jobsetup: len %u sys 0x%x printer |%.64s| device |%.32s| port |%.32s| driver |%.32s|\n", len, system, printerName, deviceName, portName, driverName));

								if (system == JOBSET_FILE364_SYSTEM || system == JOBSET_FILE605_SYSTEM) {
									UT_uint16 len2, system2;
									streamRead(mDocStream, len2);
									streamRead(mDocStream, system2);
									UT_uint32 ddl; // driver data length
									streamRead(mDocStream, ddl);
									// now the interesting data
									UT_uint16 orient; // 0=portrait 1=landscape
									streamRead(mDocStream, orient);
									UT_uint16 paperBin;
									streamRead(mDocStream, paperBin);
									UT_uint16 paperFormat;
									streamRead(mDocStream, paperFormat);
									UT_uint32 width, height;
									streamRead(mDocStream, width);
									streamRead(mDocStream, height);
									UT_DEBUGMSG(("SDW: orient %u bin %u format %u width %u height %u\n", orient, paperBin, paperFormat, width, height));
									// rest of the data is ignored, seems to be printer specific anyway.
									// Use A4, Portrait by default
									PP_PropertyVector attributes = {
										"pagetype", "a4", // A4/Letter/...
										"orientation", "portrait",
										"width", "210",
										"height", "297",
										"units", "mm"
									};
									const char* sdwPaperToAbi[] = {
										"A3",
										"A4",
										"A5",
										"B4",
										"B5",
										"Letter",
										"Legal",
										"Tabloid/Ledger",
										"Custom"
									};
									if (paperFormat < sizeof(sdwPaperToAbi)/sizeof(*sdwPaperToAbi)) {
										attributes[1] = sdwPaperToAbi[paperFormat];
                                    }
									const char* sdwOrientToAbi[] = {
										"portrait",
										"landscape"
									};
									if (orient < sizeof(sdwOrientToAbi)/sizeof(*sdwOrientToAbi)) {
										attributes[3] = sdwOrientToAbi[orient];
                                    }
									attributes[5] = UT_std_string_sprintf("%f", static_cast<double>(width)/100);
									attributes[7] = UT_std_string_sprintf("%f", static_cast<double>(height)/100);

									getDoc()->setPageSizeFromFile(attributes);
								}
								break;

							}
							case SWG_EOF:
								done2 = true;
								break;
							default:
								UT_DEBUGMSG(("SDW: SWG_CONTENT: Skipping %u bytes for record type '%c' (starting at 0x%08llX)\n",
											 size2, type,
											 (long long)gsf_input_tell(mDocStream)));
						}
						if (gsf_input_seek(mDocStream, eor2, G_SEEK_SET))
							return UT_IE_BOGUSDOCUMENT;
					}
					break;
				}
				case SWG_STRINGPOOL:
				{
					if (mDocHdr.nVersion <= SWG_POOLIDS) {
						UT_ASSERT_HARMLESS(UT_NOT_IMPLEMENTED);
						break;
					}
					UT_uint8 encoding;
					streamRead(mDocStream, encoding);
					UT_iconv_t cd = findConverter(encoding);
					if (!UT_iconv_isValid(cd))
						throw UT_IE_IMPORTERROR;
					UT_uint16 count;
					streamRead(mDocStream, count);
					while (count--) {
						UT_uint16 id;
						streamRead(mDocStream, id);
						char* str;
						UT_uint16 len;
						::readByteString(mDocStream, str, &len);
						if (id == IDX_NOCONV_FF) {
							UT_ASSERT_HARMLESS(UT_NOT_IMPLEMENTED);
						}
						// FIXME: find a way to not have to copy and free 
						// the result of UT_convert_cd.... --hub
						UT_DEBUGMSG(("SDW: StringPool: found 0x%04x <-> %.*s\n", id, len, str));
						UT_UCS4Char* convertedString = reinterpret_cast<UT_UCS4Char*>(UT_convert_cd(str, len + 1, cd, NULL, NULL));
						mStringPool.insert(stringpool_map::value_type(id, convertedString));
						FREEP(convertedString);
                        delete [] str;
					}
                    UT_iconv_close(cd);
					break;
				}
				case SWG_COMMENT: // skip over comments
					break;
				case SWG_EOF:
					done = true;
					break;
				default:
					UT_DEBUGMSG(("SDW: Skipping %u bytes for record type '%c' (starting at 0x%08llX)\n", recSize, type, (long long)gsf_input_tell(mDocStream)));
			}
			// Seek to the end of the record, in case it wasn't read completely
			if (gsf_input_seek(mDocStream, eor, G_SEEK_SET))
				return UT_IE_BOGUSDOCUMENT;
		}

		UT_DEBUGMSG(("SDW: Done\n"));

		return UT_OK;
	}
	catch(UT_Error e) {
		UT_DEBUGMSG(("SDW: error %d\n", e));
		return e;
	}
	catch(...) {
		UT_DEBUGMSG(("SDW: Unknown error\n"));
		return UT_IE_BOGUSDOCUMENT;
	}
}
/*!
 * Take a packet, interpret it's contents and apply the implied operations on the document.
 */
bool ABI_Collab_Import::_import(const SessionPacket& packet, UT_sint32 iImportAdjustment, BuddyPtr pCollaborator, bool inGlob)
{
	UT_DEBUGMSG(("ABI_Collab_Import::_import() - packet class type: %d, iImportAdjustment: %d\n", packet.getClassType(), iImportAdjustment));
	UT_return_val_if_fail(pCollaborator, false);

	switch (packet.getClassType())
	{
		case PCT_GlobSessionPacket:
			{
				const GlobSessionPacket* gp = static_cast<const GlobSessionPacket*>(&packet);
				UT_return_val_if_fail(gp->getPackets().size() > 0, false);

				// store the last seen revision from this collaborator (it is immediately used by the export)
				m_remoteRevs[pCollaborator] = gp->getRev();

				for (UT_uint32 j = 0; j < gp->getPackets().size(); j++)
				{
					SessionPacket* pGlobPacket = gp->getPackets()[j];
					if (pGlobPacket)
					{
						bool res = _import(*pGlobPacket, iImportAdjustment, pCollaborator, true); // yay for recursion :)
						if (!res)
						{
							UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
						}
					}
				}

				return true;
			}
		
		case PCT_SignalSessionPacket:
			{
				const SignalSessionPacket* sp = static_cast<const SignalSessionPacket*>(&packet);
				m_pDoc->signalListeners(sp->getSignalType());
				return true;
			}

		case PCT_RevertSessionPacket:
			{
				const RevertSessionPacket* rrp = static_cast<const RevertSessionPacket*>(&packet);
				UT_DEBUGMSG(("Revert packet seen on import for rev: %d\n", rrp->getRev()));

				if (m_iAlreadyRevertedRevs.size() == 0 || m_iAlreadyRevertedRevs.front() != rrp->getRev())
				{
					UT_DEBUGMSG(("Incoming revert for revision %d, which we didn't detect locally (m_iAlreadyRevertedRev: %d)!\n", rrp->getRev(), m_iAlreadyRevertedRevs.front()));
					UT_DEBUGMSG(("DOCUMENT OUT OF SYNC DETECTED!!!!\n"));
					UT_ASSERT_HARMLESS(UT_NOT_IMPLEMENTED);
					return false;
				}	

				m_iAlreadyRevertedRevs.pop_front();
				return true;
			}
		case PCT_RevertAckSessionPacket:
			{
				UT_DEBUGMSG(("RevertAck packet seen on import for rev: %d\n", static_cast<const RevertAckSessionPacket*>(&packet)->getRev()));

				// remove this collaborator from our revert ack list; he can play again...
				for (std::vector<std::pair<BuddyPtr, UT_sint32> >::iterator it = m_revertSet.begin(); it != m_revertSet.end(); it++)
				{
					if ((*it).first == pCollaborator)
					{
						UT_DEBUGMSG(("Found collaborator %s on our revert ack list with rev %d! Removing him from the list...\n", (*it).first->getDescription().utf8_str(), (*it).second));
						UT_ASSERT_HARMLESS((*it).second == static_cast<const RevertAckSessionPacket*>(&packet)->getRev());
						m_revertSet.erase(it);
						return true;
					}
				}

				UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
				return false;
			}

		default:
			// silly C++ can't switch on ranges
			if (packet.getClassType() >= _PCT_FirstChangeRecord && packet.getClassType() <= _PCT_LastChangeRecord)
			{
				const ChangeRecordSessionPacket* crp = static_cast<const ChangeRecordSessionPacket*>(&packet);
				UT_DEBUGMSG(("It's safe to import this packet\n"));

				UT_DEBUGMSG(("For CR number %d requested point %d adjustment %d \n",  crp->getRev(), crp->getPos(), iImportAdjustment));

				PT_DocPosition pos = static_cast<PT_DocPosition>(crp->getPos() + iImportAdjustment);
				UT_ASSERT(pos <= getEndOfDoc());

				if (!inGlob)
				{
					// store the last seen revision from this collaborator (it is immediately used by the export)
					// NOTE: if this changerecord is part of a glob, then we don't do this; we'll have
					// already set the revision of the glob itself as the last seen one
					m_remoteRevs[pCollaborator] = crp->getRev();
				}

				// todo: remove these temp vars
				PT_DocPosition iPos2 = 0;

				// process the packet
				switch(crp->getPXType())
				{
					case PX_ChangeRecord::PXT_GlobMarker:
					{
						UT_DEBUGMSG(("Found GLOB marker (ignoring)\n"));
						return true;
					}
					case PX_ChangeRecord::PXT_InsertSpan:
					{
						const InsertSpan_ChangeRecordSessionPacket* icrsp = static_cast<const InsertSpan_ChangeRecordSessionPacket*>( crp );
						UT_UCS4String UCSChars = const_cast<UT_UTF8String&>(icrsp->m_sText).ucs4_str();	// ugly, ucs4_str should be const func!
						PP_AttrProp attrProp;
						attrProp.setAttributes(const_cast<const gchar**>(icrsp->getAtts()));
						attrProp.setProperties(const_cast<const gchar**>(icrsp->getProps()));
						m_pDoc->insertSpan(pos,UCSChars.ucs4_str(),UCSChars.length(), &attrProp);
						break;
					}
					case PX_ChangeRecord::PXT_DeleteSpan:
					{
						iPos2 = pos + crp->getLength();
						PP_AttrProp *p_AttrProp_Before = NULL;
						UT_uint32 icnt = 0;
						m_pDoc->deleteSpan(pos,iPos2,p_AttrProp_Before,icnt,true);
						break;
					}
					case PX_ChangeRecord::PXT_ChangeSpan:
					{
						const Props_ChangeRecordSessionPacket* pcrsp = static_cast<const Props_ChangeRecordSessionPacket*>( crp );
						gchar** szAtts = pcrsp->getAtts();
						gchar** szProps = pcrsp->getProps();
						iPos2 = pos + pcrsp->getLength();
						if((szProps == NULL) && (szAtts == NULL))
						{
							//
							// This happens if we remove all formats
							// we have to handle this seperately
							//
							// Get style of containing block
							//
							pf_Frag_Strux* sdh = NULL;
							m_pDoc->getStruxOfTypeFromPosition(pos,PTX_Block,&sdh);
							if(!sdh)
							{
								UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
								return false;
							}
							PD_Style * pStyle = m_pDoc->getStyleFromSDH(sdh);
							if(!pStyle)
							{
								UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
								return false;
							}
							const gchar * szName =  pStyle->getName();
							const gchar * atts[3] = {PT_STYLE_ATTRIBUTE_NAME,szName,NULL};
							m_pDoc->changeSpanFmt(PTC_SetExactly, pos, iPos2, atts, const_cast<const gchar**>( szProps ) );
						}
						else
						{
							m_pDoc->changeSpanFmt(PTC_SetExactly, pos, iPos2, const_cast<const gchar**>(szAtts), const_cast<const gchar**>( szProps ) );
						}
						break;
					}
					case PX_ChangeRecord::PXT_InsertStrux:
					{
						const ChangeStrux_ChangeRecordSessionPacket* pcrsp = static_cast<const ChangeStrux_ChangeRecordSessionPacket*>( crp );
						PTStruxType pts = pcrsp->m_eStruxType;
						gchar** szAtts = pcrsp->getAtts();
						gchar** szProps = pcrsp->getProps();
						
						if((szProps != NULL) || (szAtts != NULL))
						{
							m_pDoc->insertStrux( pos, pts, const_cast<const gchar**>( szAtts ), const_cast<const gchar**>( szProps ) );
						}
						else
						{
							m_pDoc->insertStrux(pos, pts);
						}
						break;
					}
					case PX_ChangeRecord::PXT_DeleteStrux:
					{
						const DeleteStrux_ChangeRecordSessionPacket* pcrsp = static_cast<const DeleteStrux_ChangeRecordSessionPacket*>( crp );
						PTStruxType pts = pcrsp->m_eStruxType;
						m_pDoc->deleteStrux(pos,pts,true);
						break;
					}
					case PX_ChangeRecord::PXT_ChangeStrux:
					{
						const ChangeStrux_ChangeRecordSessionPacket* pcrsp = static_cast<const ChangeStrux_ChangeRecordSessionPacket*>( crp );
						PTStruxType pts = pcrsp->m_eStruxType;
						gchar** szAtts = pcrsp->getAtts();
						gchar** szProps = pcrsp->getProps();
						UT_return_val_if_fail(szProps != NULL || szAtts != NULL, false);

						UT_DEBUGMSG(("Executing ChangeStrux pos= %d \n",pos));
						m_pDoc->changeStruxFmt(PTC_SetExactly, pos, pos, const_cast<const gchar**>( szAtts ), const_cast<const gchar**>( szProps ), pts);
						
						// TODO: this mask is waaaay to generic
						XAP_Frame *pFrame = XAP_App::getApp()->getLastFocussedFrame();
						if (pFrame)
						{
							FV_View* pView = static_cast<FV_View*>(pFrame->getCurrentView());
							if (pView)
								pView->notifyListeners(AV_CHG_TYPING | AV_CHG_FMTCHAR | AV_CHG_FMTBLOCK | AV_CHG_PAGECOUNT | AV_CHG_FMTSTYLE );
						}
						break;
					}
					case PX_ChangeRecord::PXT_InsertObject:
					{
						const Object_ChangeRecordSessionPacket* ocrsp = static_cast<const Object_ChangeRecordSessionPacket*>( crp );
						PTObjectType pto = ocrsp->getObjectType();
						gchar** szAtts = ocrsp->getAtts();
						gchar** szProps = ocrsp->getProps();
						
						if((szProps == NULL) && (szAtts == NULL))
						{
							UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
							return false;
						}
						m_pDoc->insertObject(pos, pto, const_cast<const gchar**>( szAtts ), const_cast<const gchar**>( szProps ) );
						break;
					}
					case PX_ChangeRecord::PXT_DeleteObject:
					{
						iPos2 = pos + 1;
						PP_AttrProp *p_AttrProp_Before = NULL;
						UT_uint32 icnt = 0;
						m_pDoc->deleteSpan(pos, iPos2, p_AttrProp_Before, icnt, true);
						break;
					}
					case PX_ChangeRecord::PXT_ChangeObject:
					{
						const Object_ChangeRecordSessionPacket* ccrsp = static_cast<const Object_ChangeRecordSessionPacket*>( crp );
						//PTObjectType pto = ccrsp->m_eObjectType;
						gchar** szAtts = ccrsp->getAtts();
						gchar** szProps = ccrsp->getProps();
						
						if ((szProps == NULL) && (szAtts == NULL))
						{
							UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
							return false;
						}
						m_pDoc->changeSpanFmt(PTC_SetExactly, pos, pos + 1, const_cast<const gchar**>( szAtts ), const_cast<const gchar**>( szProps ));
						break;
					}
                    case PX_ChangeRecord::PXT_ChangeDocRDF:
                    {
                        // down cast crp to get dcrp
						const RDF_ChangeRecordSessionPacket* dcrp = static_cast<const RDF_ChangeRecordSessionPacket*>( crp );
						gchar** szAtts = dcrp->getAtts();
						gchar** szProps = dcrp->getProps();

						if ((szProps == NULL) && (szAtts == NULL))
						{
							UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
							return false;
						}

                        {
                            // update the local document RDF to remove
                            // szAtts RDF and then add the szProps RDF
                            m_pDoc->getDocumentRDF()->handleCollabEvent( szAtts, szProps );
                        }                        
                        break;
                    }
					case PX_ChangeRecord::PXT_InsertFmtMark:
					{
						const Props_ChangeRecordSessionPacket* pcrsp = static_cast<const Props_ChangeRecordSessionPacket*>( crp );
						gchar** szAtts = pcrsp->getAtts();
						gchar** szProps = pcrsp->getProps();
						
						if((szProps == NULL) && (szAtts == NULL))
						{
							// nothing to do here, please move along
							
							// NOTE: why does this happen anyway? 
							// This happens when for example when sending over tables:
							UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
							return false;
						}
						return m_pDoc->changeSpanFmt(PTC_SetExactly, pos, pos, const_cast<const gchar**>( szAtts ), const_cast<const gchar**>( szProps ));
					}
					case PX_ChangeRecord::PXT_DeleteFmtMark:
					{
						return m_pDoc->deleteFmtMark(pos);
					}
					case PX_ChangeRecord::PXT_ChangeFmtMark:
					{
						const Props_ChangeRecordSessionPacket* pcrsp = static_cast<const Props_ChangeRecordSessionPacket*>( crp );
						gchar** szAtts = pcrsp->getAtts();
						gchar** szProps = pcrsp->getProps();
						
						if ((szProps == NULL) && (szAtts == NULL))
						{
							UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
							return false;
						}
						return m_pDoc->changeSpanFmt(PTC_SetExactly, pos, pos, const_cast<const gchar**>( szAtts ), const_cast<const gchar**>( szProps ));
					}
					case PX_ChangeRecord::PXT_ChangePoint:
					{
						UT_DEBUGMSG(("Change Point CR \n"));
						return m_pDoc->createAndSendCR(pos, crp->getPXType(), true, 0);
					}
					case PX_ChangeRecord::PXT_ListUpdate:
					{
						UT_DEBUGMSG(("ListUpdate CR \n"));
						return m_pDoc->createAndSendCR(pos, crp->getPXType(), true,0);
					}
					case PX_ChangeRecord::PXT_StopList:
					{
						UT_DEBUGMSG(("StopList CR \n"));
						return m_pDoc->createAndSendCR(pos, crp->getPXType(), true,0);
					}
					case PX_ChangeRecord::PXT_UpdateField:
					{
						UT_DEBUGMSG(("UpdateFiled CR \n"));
						return m_pDoc->createAndSendCR(pos, crp->getPXType(), true,0);
					}
					case PX_ChangeRecord::PXT_RemoveList:
					{
						UT_DEBUGMSG(("RemoveList CR \n"));
						return m_pDoc->createAndSendCR(pos, crp->getPXType(), true,0);
					}
					case PX_ChangeRecord::PXT_UpdateLayout:
					{
						UT_DEBUGMSG(("UpdateLayout CR \n"));
						return m_pDoc->createAndSendCR(pos, crp->getPXType(), true,0);
					}
					case PX_ChangeRecord::PXT_CreateDataItem:
					{
						const Data_ChangeRecordSessionPacket* dp = static_cast<const Data_ChangeRecordSessionPacket*>( crp );
						const char * szNameV = g_strdup(dp->getAttribute(PT_DATAITEM_ATTRIBUTE_NAME));
						PD_DataItemHandle pHandle = NULL;
						std::string sToken = dp->m_bTokenSet ? dp->m_sToken : "";
						UT_ByteBuf * pBuf= new UT_ByteBuf();
						UT_DEBUGMSG(("PXT_CreateDataItem: append image buffer @ 0x%p, %lu bytes, sToken %s\n", &dp->m_vecData[0], (long unsigned)dp->m_vecData.size(), sToken.c_str()));
						pBuf->append(reinterpret_cast<const UT_Byte *>( &dp->m_vecData[0] ), dp->m_vecData.size() );
						bool res = m_pDoc->createDataItem(szNameV,false,pBuf,sToken,&pHandle);
						delete pBuf;
						return res;
					}
					case PX_ChangeRecord::PXT_ChangeDocProp:
					{
						UT_DEBUGMSG(("ChangeDocProp CR \n"));
						const Props_ChangeRecordSessionPacket* pcrsp = static_cast<const Props_ChangeRecordSessionPacket*>( crp );
						//
						// Assemble the Attributes for different properties
						//
						const gchar** szAtts = const_cast<const gchar **>(pcrsp->getAtts());
						const gchar** szProps = const_cast<const gchar **>(pcrsp->getProps());
						//
						// Now direct the document to make the changes
						//
						return m_pDoc->changeDocPropeties(szAtts,szProps);
					}
					default:
					{
						UT_DEBUGMSG(("Unimplemented crp->getPXType(): %d\n", crp->getPXType()));
						UT_ASSERT_HARMLESS(UT_NOT_IMPLEMENTED);
						break;
					}
				}
				
				return true;
			}
			else
			{
				UT_DEBUGMSG(("ABI_Collab_Import::import called with unhandled packet class type: %d!\n", packet.getClassType()));
				return false;
			}
			break;		
	}

	return false;
}
bool ev_UnixKeyboard::charDataEvent(AV_View* pView, EV_EditBits state, const char * text, size_t len)
{
    EV_EditEventMapperResult result;
    EV_EditMethod * pEM;

    /*
    do some sanity checking, since:
    - delete_surrounding commits a 0 length string in some IMs
    - some IMs state a length of 1, while the text being "" (for example the
    Amharic IM for keystrokes that have no secondary character (eg. shift-R)
    */
    if (!text || *text == '\0' || !len)
        return true;

    UT_UCS4String ucs (text, len);

    UT_uint32 charData = static_cast<UT_uint32>(ucs[0]);

    xxx_UT_DEBUGMSG(("DOM: charData: %d | length: %d | string: '%s'\n", charData, len, text));
    if (charData == 32)
        charData = 'a'; // HACK!!! for space bar not working. investigate more....

    if(charData>0xff || charData == 0)
        result = m_pEEM->Keystroke(EV_EKP_PRESS|state|'a',&pEM);
    else
        result = m_pEEM->Keystroke(EV_EKP_PRESS|state|charData,&pEM);

    switch (result)
    {
    case EV_EEMR_BOGUS_START:
        // If it is a bogus key and we don't have a sequence in
        // progress, we should let the system handle it
        // (this lets things like ALT-F4 work).
        return false;

    case EV_EEMR_BOGUS_CONT:
        // If it is a bogus key but in the middle of a sequence,
        // we should silently eat it (this is to prevent things
        // like Control-X ALT-F4 from killing us -- if they want
        // to kill us, fine, but they shouldn't be in the middle
        // of a sequence).
        return true;

    case EV_EEMR_COMPLETE:
    {
        UT_ASSERT(pEM);

        invokeKeyboardMethod(pView,pEM,
                             ucs.ucs4_str(), static_cast<UT_uint32>(ucs.size()));
        return true;
    }
    case EV_EEMR_INCOMPLETE:
        return true;

    default:
        UT_ASSERT(0);
        return true;
    }

    return false;
}
Exemple #9
0
bool ev_EditMethod_invoke (const EV_EditMethod * pEM, const UT_UCS4String & data)
{
  EV_EditMethodCallData callData ( data.ucs4_str(), static_cast<UT_uint32>(data.size()) ) ;
  return ev_EditMethod_invoke ( pEM, &callData ) ;
}
UT_UTF8String::UT_UTF8String (const UT_UCS4String & rhs) :
	pimpl(new UT_UTF8Stringbuf)
{
	if (rhs.size ()) appendUCS4 (rhs.ucs4_str (), rhs.size ());
}
bool operator<(const UT_UCS4String& s1, const UT_UCS4String& s2)
{
	return UT_UCS4_strcmp(s1.ucs4_str(), s2.ucs4_str()) < 0;
}
bool operator==(const UT_UCS4String& s1, const UT_UCS4Char* s2)
{
	return UT_UCS4_strcmp(s1.ucs4_str(), s2) == 0;
}
bool operator==(const UT_UCS4String& s1, const UT_UCS4String& s2)
{
        if (s1.size() != s2.size()) return false;
	return UT_UCS4_strcmp(s1.ucs4_str(), s2.ucs4_str()) == 0;
}
void ODe_AbiDocListener::_insertMath(PT_AttrPropIndex api) {

    const gchar* szMath = NULL;
    szMath = _getObjectKey(api, static_cast<const gchar*>("dataid"));

    UT_return_if_fail(szMath);

    const UT_ByteBuf * pByteBuf = NULL;
    bool bOK = m_pDocument->getDataItemDataByName(szMath, const_cast<const UT_ByteBuf **>(&pByteBuf), NULL, NULL);

    UT_return_if_fail(bOK);

    UT_UCS4_mbtowc myWC;
    UT_UTF8String sMathML;
    sMathML.appendBuf(*pByteBuf, myWC);

    UT_return_if_fail(!sMathML.empty());

    UT_UCS4String buf = sMathML.utf8_str();
    UT_UTF8String output = "";

    const PP_AttrProp * pAP = NULL;
    bool bHaveProp = m_pDocument->getAttrProp(api,&pAP);
    UT_LocaleTransactor t(LC_NUMERIC, "C");
    UT_UTF8String dimension;
    double dInch;

    UT_return_if_fail(bHaveProp && pAP);

    _openSpan(api);

    if(pAP->getProperty("width", szMath)) {
        dInch = static_cast<double>(atoi(szMath))/UT_LAYOUT_RESOLUTION;
        UT_UTF8String_sprintf(dimension,"%fin",dInch);
        output += "<draw:frame svg:width=\"";
        output += dimension;
        output += "\" svg:height=\"";
    } else {
        UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
        _closeSpan();
        return;
    }

    if(pAP->getProperty("height", szMath)) {
        dInch = static_cast<double>(atoi(szMath))/UT_LAYOUT_RESOLUTION;
        dimension.clear();
        UT_UTF8String_sprintf(dimension,"%fin",dInch);
        output += dimension;
        output += "\"><draw:object>";
    } else {
        UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
        _closeSpan();
        return;
    }

    for (UT_uint32 i = 0; i < buf.length(); i++) {
        if (buf[i] == '<') {
            if (((i + 1) < buf.length()) && (buf[i+1] == '/')) {
                output += "</math:";
                i++; // skip the '/'
            } else if ((i + 1) < buf.length()) {
                output += "<math:";
            } else {
                UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN);
            }
        } else {
            output += buf[i];
        }
    }
    output += "</draw:object></draw:frame>";
    m_pCurrentImpl->insertText(output);
    _closeSpan();
}