blob: d4a9877e136188db0d7a63a1cef4351ec9a724a8 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#include "WordObjects.h"
#include "WordPackage.h"
#include "WordDrawing.h"
#include "WordBookmark.h"
#include "WordCaption.h"
#include "DFDOM.h"
#include "DFString.h"
#include "DFHashTable.h"
#include "DFCommon.h"
#include "DFPlatform.h"
#include <assert.h>
#include <stdlib.h>
////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// WordObjects //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////
struct WordObjects {
WordPackage *package;
DFHashTable *drawingsById;
DFHashTable *bookmarksById;
DFHashTable *bookmarksByName;
DFHashTable *captionsByTarget;
int nextDrawingId;
int nextBookmarkNameNum;
int nextBookmarkId;
};
WordObjects *WordObjectsNew(WordPackage *package)
{
WordObjects *objects = (WordObjects *)xcalloc(1,sizeof(WordObjects));
objects->package = WordPackageRetain(package);
objects->drawingsById = DFHashTableNew((DFCopyFunction)WordDrawingRetain,(DFFreeFunction)WordDrawingRelease);
objects->bookmarksById = DFHashTableNew((DFCopyFunction)WordBookmarkRetain,(DFFreeFunction)WordBookmarkRelease);
objects->bookmarksByName = DFHashTableNew((DFCopyFunction)WordBookmarkRetain,(DFFreeFunction)WordBookmarkRelease);
objects->captionsByTarget = DFHashTableNew((DFCopyFunction)WordCaptionRetain,(DFFreeFunction)WordCaptionRelease);
objects->nextDrawingId = 1;
objects->nextBookmarkNameNum = 0;
objects->nextBookmarkId = 0;
return objects;
}
void WordObjectsFree(WordObjects *objects)
{
DFHashTableRelease(objects->drawingsById);
DFHashTableRelease(objects->bookmarksById);
DFHashTableRelease(objects->bookmarksByName);
DFHashTableRelease(objects->captionsByTarget);
WordPackageRelease(objects->package);
free(objects);
}
static void scanRecursive(WordObjects *objects, DFNode *node)
{
switch (node->tag) {
case WORD_BOOKMARK: {
const char *bookmarkId = DFGetAttribute(node,WORD_ID);
const char *bookmarkName = DFGetAttribute(node,WORD_NAME);
if ((bookmarkId == NULL) ||
(bookmarkName == NULL) ||
(WordObjectsBookmarkWithId(objects,bookmarkId) != NULL) ||
(WordObjectsBookmarkWithName(objects,bookmarkName) != NULL)) {
DFRemoveNode(node);
return;
}
WordBookmark *bookmark = WordObjectsAddBookmarkWithId(objects,bookmarkId,bookmarkName);
bookmark->element = node;
break;
}
case DML_WP_DOCPR: {
const char *drawingId = DFGetAttribute(node,NULL_ID);
if ((drawingId != NULL) && (WordObjectsDrawingWithId(objects,drawingId) == NULL))
WordObjectsAddDrawingWithId(objects,drawingId);
break;
}
}
DFNode *next;
for (DFNode *child = node->first; child != NULL; child = next) {
next = child->next;
scanRecursive(objects,child);
}
}
void WordObjectsScan(WordObjects *objects)
{
scanRecursive(objects,objects->package->document->docNode);
}
WordDrawing *WordObjectsDrawingWithId(WordObjects *objects, const char *drawingId)
{
return DFHashTableLookup(objects->drawingsById,drawingId);
}
WordDrawing *WordObjectsAddDrawingWithId(WordObjects *objects, const char *drawingId)
{
WordDrawing *drawing = WordDrawingNew(drawingId);
DFHashTableAdd(objects->drawingsById,drawingId,drawing);
WordDrawingRelease(drawing);
return drawing;
}
static char *createDrawingId(WordObjects *objects)
{
while (1) {
char *idStr = DFFormatString("%d",objects->nextDrawingId);
if (DFHashTableLookup(objects->drawingsById,idStr) == NULL)
return idStr;
objects->nextDrawingId++;
free(idStr);
}
}
WordDrawing *WordObjectsAddDrawing(WordObjects *objects)
{
char *drawingId = createDrawingId(objects);
WordDrawing *drawing = WordObjectsAddDrawingWithId(objects,drawingId);
free(drawingId);
return drawing;
}
struct WordBookmark *WordObjectsBookmarkWithId(WordObjects *objects, const char *bookmarkId)
{
return DFHashTableLookup(objects->bookmarksById,bookmarkId);
}
struct WordBookmark *WordObjectsBookmarkWithName(WordObjects *objects, const char *bookmarkName)
{
return DFHashTableLookup(objects->bookmarksByName,bookmarkName);
}
struct WordBookmark *WordObjectsAddBookmarkWithId(WordObjects *objects, const char *bookmarkId, const char *bookmarkName)
{
WordBookmark *bookmark = WordBookmarkNew(bookmarkId,bookmarkName);
DFHashTableAdd(objects->bookmarksById,bookmarkId,bookmark);
DFHashTableAdd(objects->bookmarksByName,bookmarkName,bookmark);
WordBookmarkRelease(bookmark);
return bookmark;
}
static char *createBookmarkName(WordObjects *objects)
{
while (1) {
char *nameStr = DFFormatString("uxwrite%d",objects->nextBookmarkNameNum);
if (DFHashTableLookup(objects->bookmarksByName,nameStr) == NULL)
return nameStr;
objects->nextBookmarkNameNum++;
free(nameStr);
}
}
static char *createBookmarkId(WordObjects *objects)
{
while (1) {
char *idStr = DFFormatString("%d",objects->nextBookmarkId);
if (DFHashTableLookup(objects->bookmarksById,idStr) == NULL)
return idStr;
objects->nextBookmarkId++;
free(idStr);
}
}
struct WordBookmark *WordObjectsAddBookmark(WordObjects *objects)
{
char *bookmarkId = createBookmarkId(objects);
char *bookmarkName = createBookmarkName(objects);
WordBookmark *bookmark = WordObjectsAddBookmarkWithId(objects,bookmarkId,bookmarkName);
free(bookmarkId);
free(bookmarkName);
return bookmark;
}
void WordObjectsCollapseBookmarks(WordObjects *objects)
{
WordBookmarks_collapseNew(objects->package->document);
}
void WordObjectsAnalyzeBookmarks(WordObjects *objects, WordSheet *sheet)
{
const char **keys = DFHashTableCopyKeys(objects->bookmarksById);
for (int i = 0; keys[i]; i++) {
WordBookmark *bookmark = DFHashTableLookup(objects->bookmarksById,keys[i]);
WordBookmarkAnalyze(bookmark,sheet);
}
free(keys);
}
void WordObjectsExpandBookmarks(WordObjects *objects)
{
WordBookmarks_expandNew(objects->package->document);
}
struct WordCaption *WordObjectsCaptionForTarget(WordObjects *objects, DFNode *target)
{
assert((target->tag == HTML_TABLE) || (target->tag == HTML_FIGURE));
return DFHashTableLookupInt(objects->captionsByTarget,target->seqNo);
}
void WordObjectsSetCaption(WordObjects *objects, struct WordCaption *caption, DFNode *target)
{
assert((target->tag == HTML_TABLE) || (target->tag == HTML_FIGURE));
DFHashTableAddInt(objects->captionsByTarget,target->seqNo,caption);
}