00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #define _GNU_SOURCE
00029
00030
00031
00032
00033
00034
00035 #include <fcntl.h>
00036 #include <string.h>
00037 #include <assert.h>
00038
00039 #ifdef WIN32
00040 #include <windows.h>
00041 #else
00042 #include <sys/time.h>
00043 #endif
00044
00045 #include <glib.h>
00046 #include <glib/gprintf.h>
00047
00048
00049
00050
00051 #include "scbdoc.h"
00052 #include "scblog.h"
00053 #include "scbpage.h"
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 #define METADB_FILE_POSITION "file_position"
00066 #define METADB_START_ANCHOR "start_anchor"
00067 #define METADB_END_ANCHOR "end_anchor"
00068 #define METADB_ANNOTATION_ID "annotation_id"
00069 #define METADB_DATA "data"
00070
00071
00072
00073
00074
00075
00076
00077
00078 static gboolean g_enable_autodelete = TRUE;
00079
00080
00081
00082
00083
00084 static void update_timestamp (ScbPagePtr page);
00085 static void remove_oldest_page_scribbles (ScbDocPtr doc);
00086 static gboolean load_application_data (ScbDocPtr doc);
00087 static gboolean save_application_data (ScbDocPtr doc);
00088 static void load_pages_basic_data (const ScbDocPtr doc,
00089 const metadata_table *table);
00090 static metadata_table *load_document_data (const ScbDocPtr doc);
00091 static gboolean load_page_data (ScbDocPtr doc,
00092 ScbPagePtr page);
00093
00094 #ifdef SAVE_TO_FILE
00095 static ScbStreamPtr doc_load_page_file (const ScbPageIdPtr id);
00096 static gboolean doc_save_page_file (const ScbPageIdPtr id,
00097 ScbStreamPtr stream);
00098 #else
00099 static gboolean save_page_data (const ScbDocPtr doc,
00100 const ScbPagePtr page,
00101 const ScbStreamPtr stream,
00102 gboolean *need_free_stream);
00103 #endif
00104
00105
00106
00107
00108
00109 void erscribble_doc_init_context(ScbDocPtr ptr)
00110 {
00111 LOGPRINTF("entry");
00112
00113 ptr->context.table = g_array_sized_new(FALSE, TRUE,
00114 sizeof(ScbTBSItem), ERSCRIBBLE_DEF_CMD_ACT_SIZE);
00115 ptr->context.curState = ERSCRIBBLE_TBS_SCRIBBLE;
00116 ptr->context.curStrokeAttr.color = ERSCRIBBLE_DEV_COLOR_BLACK;
00117 ptr->context.curStrokeAttr.layer = ERSCRIBBLE_DEF_STROKE_LAYER;
00118 ptr->context.curStrokeAttr.points_number = 0;
00119 ptr->context.curStrokeAttr.shape_id = ERSCRIBBLE_DEF_SHAPE_LINE;
00120 ptr->context.curStrokeAttr.zoom = ERSCRIBBLE_DEF_ZOOM_FACTOR;
00121
00122 ptr->context.appId = -1;
00123
00124
00125 ptr->context.need_save_app = TRUE;
00126 LOGPRINTF("exit");
00127 }
00128
00129
00130 void erscribble_doc_free_context(ScbDocPtr ptr)
00131 {
00132 LOGPRINTF("entry");
00133 if (ptr->context.table != NULL)
00134 {
00135 g_array_free(ptr->context.table, TRUE);
00136 ptr->context.table = NULL;
00137 }
00138 LOGPRINTF("exit");
00139 }
00140
00141
00142 ScbDocPtr erscribble_doc_new(const ScbPathPtr target_doc_path)
00143 {
00144 LOGPRINTF("entry");
00145 g_return_val_if_fail((target_doc_path && target_doc_path->document_path != '\0'), NULL);
00146
00147 gchar *path = g_path_get_dirname(target_doc_path->document_path);
00148 erMetadb db = ermetadb_local_open(path, TRUE);
00149 g_free(path);
00150 if (db == NULL) return NULL;
00151
00152 gchar *name = g_path_get_basename(target_doc_path->document_path);
00153 ScbDocPtr doc = erscribble_doc_new_with_database(name, db);
00154 g_free(name);
00155 if (doc == NULL) {
00156 ermetadb_close(db);
00157 }
00158 LOGPRINTF("exit");
00159 return doc;
00160 }
00161
00162
00163 ScbDocPtr erscribble_doc_new_with_database(const char *target_file_name, erMetadb metadata_db)
00164 {
00165
00166 LOGPRINTF("entry");
00167 g_return_val_if_fail((target_file_name && *target_file_name), NULL);
00168
00169 ScbDocPtr doc = g_new0(ScbDoc, 1);
00170 if (NULL == doc)
00171 {
00172 ERRORPRINTF("Not enough memory!");
00173 return NULL;
00174 }
00175
00176 if (!erscribble_pages_new(&doc->pages))
00177 {
00178 g_free(doc);
00179 return NULL;
00180 }
00181
00182 erscribble_doc_init_context(doc);
00183
00184
00185 doc->version.version_number.major = ERSCRIBBLE_LIB_VERSION_MAJOR;
00186 doc->version.version_number.minor = ERSCRIBBLE_LIB_VERSION_MINOR;
00187 doc->version.company = g_string_new(ERSCRIBBLE_LIB_ORG);
00188
00189
00190 doc->screen.dpi = ERSCRIBBLE_DEF_SCREEN_DPI;
00191 doc->screen.units = g_string_new(ERSCRIBBLE_DEF_SCREEN_UNITS);
00192
00193
00194 doc->metadata_db = metadata_db;
00195
00196
00197 strcpy(doc->path.document_path, target_file_name);
00198
00199 LOGPRINTF("exit");
00200 return doc;
00201 }
00202
00203
00204 void erscribble_doc_free(ScbDocPtr ptr)
00205 {
00206 LOGPRINTF("entry");
00207 if (NULL == ptr)
00208 {
00209 return;
00210 }
00211
00212 erscribble_doc_free_context(ptr);
00213 erscribble_pages_free(&ptr->pages);
00214
00215 if (ptr->version.company != NULL)
00216 {
00217 g_string_free(ptr->version.company, TRUE);
00218 }
00219
00220 if (ptr->screen.units != NULL)
00221 {
00222 g_string_free(ptr->screen.units, TRUE);
00223 }
00224
00225 g_free(ptr);
00226 LOGPRINTF("exit");
00227 }
00228
00229
00230 void erscribble_doc_free_without_database(ScbDocPtr ptr)
00231 {
00232 LOGPRINTF("entry");
00233 if (NULL == ptr)
00234 {
00235 return;
00236 }
00237
00238
00239 ermetadb_close(ptr->metadata_db);
00240 ptr->metadata_db = NULL;
00241
00242
00243 erscribble_doc_free(ptr);
00244 LOGPRINTF("exit");
00245 }
00246
00247
00248 ScbDocPtr erscribble_doc_open(const ScbPathPtr target_doc_path)
00249 {
00250 LOGPRINTF("entry");
00251 g_return_val_if_fail((target_doc_path && target_doc_path->document_path != '\0'), NULL);
00252
00253 gchar *path = g_path_get_dirname(target_doc_path->document_path);
00254 erMetadb db = ermetadb_local_open(path, FALSE);
00255 g_free(path);
00256 if (db == NULL) return NULL;
00257
00258 gchar *name = g_path_get_basename(target_doc_path->document_path);
00259 ScbDocPtr doc = erscribble_doc_open_with_database(name, db);
00260 g_free(name);
00261 if (doc == NULL)
00262 {
00263 ermetadb_close(db);
00264 }
00265 LOGPRINTF("exit");
00266 return doc;
00267 }
00268
00269
00270 ScbDocPtr erscribble_doc_open_with_database(const char *target_file_name, erMetadb metadata_db)
00271 {
00272 LOGPRINTF("entry");
00273 ScbDocPtr doc = NULL;
00274 gboolean ok;
00275
00276 g_return_val_if_fail((target_file_name && *target_file_name), NULL);
00277
00278 doc = g_new0(ScbDoc, 1);
00279 if (NULL == doc)
00280 {
00281 ERRORPRINTF("Not enough memory!");
00282 return NULL;
00283 }
00284
00285 doc->metadata_db = metadata_db;
00286
00287
00288 strcpy(doc->path.document_path, target_file_name);
00289
00290 ok = load_application_data(doc);
00291 if (ok)
00292 {
00293
00294
00295
00296 doc->context.need_save_app = FALSE;
00297
00298 ok = erscribble_pages_new(&doc->pages);
00299 }
00300
00301 if (ok)
00302 {
00303
00304 ok = (NULL != load_document_data(doc));
00305 }
00306
00307 if (ok)
00308 {
00309 erscribble_doc_init_context(doc);
00310 }
00311
00312 if (!ok)
00313 {
00314
00315 erscribble_doc_free(doc);
00316 doc = NULL;
00317 }
00318 LOGPRINTF("exit");
00319 return doc;
00320 }
00321
00322
00323 ScbPagesPtr erscribble_doc_get_pages(ScbDocPtr ptr)
00324 {
00325 LOGPRINTF("entry");
00326 if (ptr)
00327 {
00328 return &ptr->pages;
00329 }
00330 return NULL;
00331 }
00332
00333
00334 ScbStrokeAttributesPtr erscribble_doc_get_current_stroke_attributes(ScbDocPtr doc)
00335 {
00336 LOGPRINTF("entry");
00337 return &doc->context.curStrokeAttr;
00338 }
00339
00340
00341 ScbPagePtr erscribble_doc_get_page(ScbDocPtr doc, const ScbPageIdPtr id)
00342 {
00343 LOGPRINTF("entry");
00344 ScbPagesPtr pages = erscribble_doc_get_pages(doc);
00345 if (NULL == pages)
00346 {
00347 ERRORPRINTF("Pages list is not constructed!");
00348 return NULL;
00349 }
00350
00351
00352 ScbPagePtr page = erscribble_pages_get_page(pages, id);
00353
00354 if (page != NULL)
00355 {
00356
00357 update_timestamp(page);
00358
00359
00360
00361 load_page_data(doc, page);
00362 }
00363 else
00364 {
00365 #ifdef SAVE_TO_FILE
00366
00367 page = erscribble_page_new();
00368
00369 ScbStreamPtr stream = doc_load_page_file(id);
00370 if (stream != NULL)
00371 {
00372 erscribble_page_load(page, stream);
00373 }
00374
00375 erscribble_page_copy_id(&page->id, id);
00376
00377 erscribble_pages_add_page(&doc->pages, page);
00378 #else
00379
00380 page = erscribble_page_new();
00381
00382 erscribble_page_copy_id(&page->id, id);
00383
00384 erscribble_pages_add_page(pages, page);
00385
00386
00387 update_timestamp(page);
00388 #endif
00389 }
00390
00391 assert(page != NULL);
00392
00393 LOGPRINTF("exit");
00394 return page;
00395 }
00396
00397
00398 gboolean erscribble_doc_save_page(ScbDocPtr doc, ScbPagePtr page)
00399 {
00400 LOGPRINTF("entry");
00401 if (doc->context.need_save_app)
00402 {
00403 gboolean ok = save_application_data(doc);
00404 if (!ok)
00405 {
00406 LOGPRINTF("save_application_data NOK");
00407 return FALSE;
00408 }
00409 doc->context.need_save_app = FALSE;
00410 }
00411
00412 int page_len = erscribble_page_get_length(page);
00413 LOGPRINTF("page_len %d page %s", page_len, page->id.id);
00414
00415 gboolean need_free_stream_buffer = TRUE;
00416
00417
00418 ScbStreamPtr stream = erscribble_create_stream(page_len + 128);
00419
00420 if (NULL == stream)
00421 {
00422 LOGPRINTF("creation of stream failed");
00423 return FALSE;
00424 }
00425
00426
00427 erscribble_page_set_minor_version_number(page, doc->version.version_number.minor);
00428 LOGPRINTF("minor version number %d", doc->version.version_number.minor);
00429
00430
00431 gboolean ret = erscribble_page_write_stream(page, stream);
00432 if (ret)
00433 {
00434 #ifdef SAVE_TO_FILE
00435 ret = doc_save_page_file(&page->id, stream);
00436 #else
00437 ret = save_page_data(doc, page, stream, &need_free_stream_buffer);
00438 #endif
00439 }
00440
00441
00442 if (!need_free_stream_buffer)
00443 {
00444
00445
00446
00447
00448 erscribble_free_stream(stream, FALSE);
00449 }
00450 else
00451 {
00452
00453
00454
00455
00456 erscribble_free_stream(stream, TRUE);
00457 }
00458
00459 LOGPRINTF("exit %d", ret);
00460 return ret;
00461 }
00462
00463
00464 gboolean erscribble_doc_add_page(ScbDocPtr doc, ScbPagePtr page)
00465 {
00466 LOGPRINTF("entry");
00467 ScbPagesPtr pages = erscribble_doc_get_pages(doc);
00468 if (NULL == pages) return FALSE;
00469 LOGPRINTF("exit");
00470 return erscribble_pages_add_page(pages, page);
00471 }
00472
00473 static gboolean erscribble_doc_insert_page_impl(ScbDocPtr doc, ScbPagesPtr pages, ScbPagePtr page)
00474 {
00475 LOGPRINTF("entry");
00476
00477 ERSCRIBBLE_RET_FALSE_IF(NULL == doc || NULL == pages || NULL == page, "Invalid pages or page pointer!");
00478
00479 int result = ER_OK;
00480 ScbPagePtr cur_page = NULL;
00481 GList* ptr = g_list_first(pages->pages);
00482 while (ptr)
00483 {
00484 cur_page = (ScbPagePtr)ptr->data;
00485 if (cur_page && (cur_page->id.position >= page->id.position))
00486 {
00487
00488
00489 update_timestamp(cur_page);
00490
00491
00492 load_page_data(doc, cur_page);
00493
00494 cur_page->id.position += 1;
00495 gint64 my_id = 0;
00496 my_id = g_ascii_strtoll(cur_page->id.id, NULL, 10);
00497 my_id += 1;
00498 g_sprintf(cur_page->id.id, "%lld", my_id);
00499 result = erscribble_doc_save_page(doc, cur_page);
00500 LOGPRINTF("incremented page id to %s(%d) res: %d", cur_page->id.id, cur_page->id.position, result);
00501 if (result != ER_OK) break;
00502 }
00503 ptr = g_list_next(ptr);
00504 }
00505
00506
00507 if (result == ER_OK )
00508 {
00509 pages->pages = g_list_append(pages->pages, page);
00510 result = erscribble_doc_save_page(doc, page);
00511 }
00512
00513 LOGPRINTF("exit %d", result);
00514 return (gboolean)( result == ER_OK );
00515 }
00516
00517 gboolean erscribble_doc_insert_page(ScbDocPtr doc, ScbPagePtr page)
00518 {
00519 LOGPRINTF("entry");
00520 ScbPagesPtr pages = erscribble_doc_get_pages(doc);
00521 if (NULL == pages)
00522 return FALSE;
00523 LOGPRINTF("exit");
00524 return erscribble_doc_insert_page_impl(doc, pages, page);
00525 }
00526
00527 static gboolean erscribble_doc_delete_page_impl(ScbDocPtr doc, ScbPagesPtr pages, ScbPageIdPtr pid)
00528 {
00529 LOGPRINTF("entry");
00530 ERSCRIBBLE_RET_FALSE_IF(NULL == doc || NULL == pages || NULL == pid, "Invalid pages or page pointer!");
00531
00532 int result = -1;
00533 gboolean ok = FALSE;
00534 ScbPagePtr page = erscribble_pages_get_page(pages, pid);
00535
00536 if (page != NULL)
00537 {
00538
00539 update_timestamp(page);
00540
00541
00542
00543 erscribble_page_clear_strokes(page);
00544 page->is_blob_loaded = FALSE;
00545 load_page_data(doc, page);
00546 }
00547
00548 ermetadb_local_remove_annotation(doc->metadata_db, page->id.annotation_id);
00549 page = NULL ;
00550 erscribble_pages_free(&doc->pages);
00551
00552 ok = erscribble_pages_new(&doc->pages);
00553
00554 if (ok)
00555 {
00556
00557 ok = (NULL != load_document_data(doc));
00558 }
00559
00560 GList* ptr = g_list_first((&doc->pages)->pages);
00561 ScbPagePtr cur_page = (ScbPagePtr)ptr->data;
00562
00563 if (ok)
00564 {
00565 while (ptr)
00566 {
00567 cur_page = (ScbPagePtr)ptr->data;
00568 if (cur_page && (cur_page->id.position > pid->position))
00569 {
00570
00571 update_timestamp(cur_page);
00572 load_page_data(doc, cur_page);
00573
00574 cur_page->id.position -= 1;
00575 gint64 my_id = 0;
00576 my_id = g_ascii_strtoll(cur_page->id.id, NULL, 10 );
00577 my_id -= 1;
00578 g_sprintf(cur_page->id.id, "%lld", my_id);
00579
00580 result = erscribble_doc_save_page(doc, cur_page);
00581 if (result != ER_OK ) break;
00582 }
00583 ptr = g_list_next(ptr);
00584 }
00585 }
00586 else
00587 {
00588 result = -1;
00589 }
00590
00591 LOGPRINTF("exit");
00592 return (gboolean)( result == ER_OK );
00593 }
00594
00595
00596 gboolean erscribble_doc_delete_page(ScbDocPtr doc, ScbPageIdPtr pid)
00597 {
00598 LOGPRINTF("entry");
00599 ScbPagesPtr pages = erscribble_doc_get_pages(doc);
00600 if (NULL == pages)
00601 return FALSE;
00602 LOGPRINTF("exit");
00603 return erscribble_doc_delete_page_impl(doc, pages, pid);
00604 }
00605
00606
00607 void erscribble_doc_add_map_item(ScbDocPtr doc, const ScbTBSItemPtr ptr)
00608 {
00609 LOGPRINTF("entry");
00610
00611 g_array_append_val(doc->context.table, *ptr);
00612 LOGPRINTF("exit");
00613 }
00614
00615
00616 ScbTBState erscribble_doc_get_current_state(ScbDocPtr doc)
00617 {
00618 if (NULL == doc) return ERSCRIBBLE_TBS_INVALID;
00619 return doc->context.curState;
00620 }
00621
00622
00623 gboolean erscribble_state_is_scribble(ScbDocPtr doc)
00624 {
00625 return ERSCRIBBLE_TBS_SCRIBBLE == erscribble_doc_get_current_state(doc);
00626 }
00627
00628
00629 gboolean erscribble_state_is_erase(ScbDocPtr doc)
00630 {
00631 return ERSCRIBBLE_TBS_ERASE == erscribble_doc_get_current_state(doc);
00632 }
00633
00634
00635 void erscribble_doc_dump(ScbDocPtr ptr)
00636 {
00637 if (ptr)
00638 {
00639 erscribble_pages_dump(&ptr->pages);
00640 }
00641 }
00642
00643
00644
00645
00646
00647
00648 static void update_timestamp(ScbPagePtr page)
00649 {
00650 int now;
00651 #ifdef WIN32
00652 now = GetTickCount();
00653 #else
00654 struct timeval cur_time_struct;
00655 gettimeofday(&cur_time_struct, 0);
00656 now = cur_time_struct.tv_sec;
00657 #endif
00658 page->timestamp = now;
00659 }
00660
00661
00662 static void remove_oldest_page_scribbles(ScbDocPtr doc)
00663 {
00664 LOGPRINTF("entry");
00665 gboolean ret_clear = FALSE;
00666 while (!ret_clear)
00667 {
00668 ret_clear = remove_oldest_page_data(&doc->pages);
00669 }
00670 LOGPRINTF("exit");
00671 }
00672
00673
00674 static gboolean load_application_data(ScbDocPtr doc)
00675 {
00676 LOGPRINTF("entry");
00677 if (doc->metadata_db == NULL)
00678 {
00679 ERRORPRINTF("Document is not ready");
00680 return FALSE;
00681 }
00682
00683
00684
00685
00686 metadata_table *name_table = metadata_table_new();
00687
00688 if (name_table == NULL)
00689 {
00690 return FALSE;
00691 }
00692
00693
00694 metadata_table_add_column(name_table, ERSCRIBBLE_VERSION_MAJOR);
00695 metadata_table_add_column(name_table, ERSCRIBBLE_VERSION_MINOR);
00696 metadata_table_add_column(name_table, ERSCRIBBLE_VERSION_COMPANY);
00697 metadata_table_add_column(name_table, ERSCRIBBLE_SCREEN_DPI);
00698 metadata_table_add_column(name_table, ERSCRIBBLE_SCREEN_UNITS);
00699
00700
00701 metadata_table *results_table = NULL;
00702 int ret = ermetadb_local_get_application_data(doc->metadata_db
00703 , doc->path.document_path
00704 , name_table
00705 , &results_table);
00706 metadata_table_free(name_table);
00707
00708 if (results_table == NULL)
00709 {
00710 return FALSE;
00711 }
00712
00713 if (ret == ER_OK)
00714 {
00715 const metadata_cell *cell = NULL;
00716
00717 int index = metadata_table_find_column(results_table, ERSCRIBBLE_VERSION_MAJOR);
00718 if (index >= 0)
00719 {
00720 cell = metadata_table_get_cell(results_table, index);
00721 if (cell != NULL)
00722 {
00723 sscanf(cell->value.v_text->str, "%hd", &doc->version.version_number.major);
00724
00725 cell = NULL;
00726 }
00727 }
00728
00729
00730 index = metadata_table_find_column(results_table, ERSCRIBBLE_VERSION_MINOR);
00731 if (index >= 0)
00732 {
00733 cell = metadata_table_get_cell(results_table, index);
00734 if (cell != NULL)
00735 {
00736 sscanf(cell->value.v_text->str, "%hd", &doc->version.version_number.minor);
00737
00738 cell = NULL;
00739 }
00740 }
00741
00742
00743 index = metadata_table_find_column(results_table, ERSCRIBBLE_VERSION_COMPANY);
00744 if (index >= 0)
00745 {
00746 cell = metadata_table_get_cell(results_table, index);
00747 if (cell != NULL)
00748 {
00749 doc->version.company = g_string_new(cell->value.v_text->str);
00750 cell = NULL;
00751 }
00752 }
00753
00754
00755 index = metadata_table_find_column(results_table, ERSCRIBBLE_SCREEN_DPI);
00756 if (index >= 0)
00757 {
00758 cell = metadata_table_get_cell(results_table, index);
00759 if (cell != NULL)
00760 {
00761 sscanf(cell->value.v_text->str, "%d", &doc->screen.dpi);
00762
00763 cell = NULL;
00764 }
00765 }
00766
00767
00768 index = metadata_table_find_column(results_table, ERSCRIBBLE_SCREEN_UNITS);
00769 if (index >= 0)
00770 {
00771 cell = metadata_table_get_cell(results_table, index);
00772 if (cell != NULL)
00773 {
00774 doc->screen.units = g_string_new(cell->value.v_text->str);
00775 cell = NULL;
00776 }
00777 }
00778 }
00779
00780
00781 metadata_table_free(results_table);
00782
00783 LOGPRINTF("exit");
00784 return (ret == ER_OK);
00785 }
00786
00787
00788 static gboolean save_application_data(ScbDocPtr doc)
00789 {
00790 LOGPRINTF("entry");
00791 if (doc->metadata_db == NULL)
00792 {
00793 ERRORPRINTF("Document is not ready");
00794 return FALSE;
00795 }
00796
00797
00798
00799
00800
00801 metadata_table *value_table = metadata_table_new();
00802
00803 if (value_table == NULL)
00804 {
00805 return FALSE;
00806 }
00807
00808
00809 metadata_table_add_column(value_table, ERSCRIBBLE_VERSION_MAJOR);
00810 metadata_table_add_column(value_table, ERSCRIBBLE_VERSION_MINOR);
00811 metadata_table_add_column(value_table, ERSCRIBBLE_VERSION_COMPANY);
00812 metadata_table_add_column(value_table, ERSCRIBBLE_SCREEN_DPI);
00813 metadata_table_add_column(value_table, ERSCRIBBLE_SCREEN_UNITS);
00814
00815
00816 GString *value_str = g_string_new("");
00817
00818 int index = metadata_table_find_column(value_table, ERSCRIBBLE_VERSION_MAJOR);
00819 if (index >= 0)
00820 {
00821 g_string_printf(value_str, "%d", doc->version.version_number.major);
00822 if (metadata_table_set_text(value_table, index, value_str->str)
00823 != ER_OK)
00824 {
00825 ERRORPRINTF("Cannot write major version number");
00826 }
00827 }
00828
00829 index = metadata_table_find_column(value_table, ERSCRIBBLE_VERSION_MINOR);
00830 if (index >= 0)
00831 {
00832 g_string_printf(value_str, "%d", doc->version.version_number.minor);
00833 if (metadata_table_set_text(value_table, index, value_str->str)
00834 != ER_OK)
00835 {
00836 ERRORPRINTF("Cannot write minor version number");
00837 }
00838 }
00839
00840 index = metadata_table_find_column(value_table, ERSCRIBBLE_VERSION_COMPANY);
00841 if (index >= 0)
00842 {
00843 if (metadata_table_set_text(value_table, index, doc->version.company->str)
00844 != ER_OK)
00845 {
00846 ERRORPRINTF("Cannot write company name");
00847 }
00848 }
00849
00850 index = metadata_table_find_column(value_table, ERSCRIBBLE_SCREEN_DPI);
00851 if (index >= 0)
00852 {
00853 g_string_printf(value_str, "%d", doc->screen.dpi);
00854 if (metadata_table_set_text(value_table, index, value_str->str)
00855 != ER_OK)
00856 {
00857 ERRORPRINTF("Cannot write DPI");
00858 }
00859 }
00860
00861 index = metadata_table_find_column(value_table, ERSCRIBBLE_SCREEN_UNITS);
00862 if (index >= 0)
00863 {
00864 if (metadata_table_set_text(value_table, index, doc->screen.units->str)
00865 != ER_OK)
00866 {
00867 ERRORPRINTF("Cannot write screen units");
00868 }
00869 }
00870
00871
00872 int ret = ermetadb_local_set_application_data(doc->metadata_db, doc->path.document_path, value_table);
00873 metadata_table_free(value_table);
00874
00875 LOGPRINTF("exit");
00876 return ret == ER_OK;
00877 }
00878
00879
00880 static void load_pages_basic_data(const ScbDocPtr doc, const metadata_table *table)
00881 {
00882 LOGPRINTF("entry");
00883
00884
00885
00886 if (table == NULL || table->cell_data->len <= 0)
00887 {
00888 LOGPRINTF("Empty table of scribble");
00889 return;
00890 }
00891
00892 gint64 position = 0;
00893 gint64 anno_id = 0;
00894 guint idx = 0;
00895 for (; idx < table->n_rows; ++idx)
00896 {
00897
00898 int cell_idx = metadata_table_find_column(table, METADB_FILE_POSITION);
00899 assert(cell_idx >= 0);
00900 const metadata_cell* cell = metadata_table_get_cell(table,
00901 metadata_table_cell_index(table, idx, cell_idx));
00902 assert(cell->type == METADATA_INT64);
00903 position = cell->value.v_int64;
00904
00905
00906 cell_idx = metadata_table_find_column(table, METADB_ANNOTATION_ID);
00907 assert(cell_idx >= 0);
00908 cell = metadata_table_get_cell(table,
00909 metadata_table_cell_index(table, idx, cell_idx));
00910 assert(cell->type == METADATA_INT64);
00911 anno_id = cell->value.v_int64;
00912
00913
00914 cell_idx = metadata_table_find_column(table, METADB_START_ANCHOR);
00915 assert(cell_idx >= 0);
00916 cell = metadata_table_get_cell(table,
00917 metadata_table_cell_index(table, idx, cell_idx));
00918 assert(cell->type == METADATA_TEXT);
00919
00920 ScbPagePtr page = erscribble_page_new();
00921 if (page != NULL)
00922 {
00923
00924 if (!erscribble_pages_add_page(&doc->pages, page))
00925 {
00926 erscribble_page_free(page);
00927 }
00928 else
00929 {
00930
00931 erscribble_page_set_id(&page->id, position, cell->value.v_text->str, anno_id);
00932 }
00933 }
00934 }
00935
00936 LOGPRINTF("exit");
00937 }
00938
00939
00940 static metadata_table *load_document_data(const ScbDocPtr doc)
00941 {
00942 LOGPRINTF("entry");
00943 if (doc->metadata_db == NULL)
00944 {
00945 ERRORPRINTF("Document is not ready");
00946 return NULL;
00947 }
00948
00949 metadata_table *results = NULL;
00950 int ret = ermetadb_local_select_annotations(
00951 doc->metadata_db,
00952 doc->path.document_path,
00953 ERSCRIBBLE_ANNOTATION_TYPE,
00954 NULL,
00955 -1,
00956 -1,
00957 &results);
00958 if (ret == ER_OK)
00959 {
00960
00961 load_pages_basic_data(doc, results);
00962 }
00963 else
00964 {
00965 metadata_table_free(results);
00966 results = NULL;
00967 }
00968
00969 LOGPRINTF("exit");
00970 return results;
00971 }
00972
00973
00974 static gboolean load_page_data(ScbDocPtr doc, ScbPagePtr page)
00975 {
00976 LOGPRINTF("entry");
00977 if (doc->metadata_db == NULL)
00978 {
00979 ERRORPRINTF("Document is not ready");
00980 return FALSE;
00981 }
00982
00983 if (page->is_blob_loaded)
00984 {
00985
00986
00987 return FALSE;
00988 }
00989
00990 if (erscribble_page_get_stroke_count(page) > 0)
00991 {
00992
00993 return FALSE;
00994 }
00995
00996 if (page->id.annotation_id < 0)
00997 {
00998
00999 return FALSE;
01000 }
01001
01002
01003
01004 page->is_blob_loaded = TRUE;
01005
01006
01007
01008 gint64 anno_list[1];
01009 anno_list[0] = page->id.annotation_id;
01010
01011 metadata_table *value = NULL;
01012 int ret = ermetadb_local_get_annotations(doc->metadata_db,
01013 &anno_list[0], 1, &value);
01014
01015 if (ret != ER_OK || value == NULL)
01016 {
01017 ERRORPRINTF("Cannot retrieve BLOB of page %s", page->id.id);
01018 return FALSE;
01019 }
01020
01021
01022 guint idx = 0;
01023 for (; idx < value->n_rows; ++idx)
01024 {
01025 int cell_idx = metadata_table_find_column(value, METADB_DATA);
01026 const metadata_cell *cell =
01027 metadata_table_get_cell(value, metadata_table_cell_index(value, idx, cell_idx));
01028 assert(cell->type == METADATA_BLOB);
01029 gsize length = cell->value.v_blob.len;
01030
01031
01032
01033 ScbStreamPtr stream = erscribble_create_stream(length);
01034 if (stream != NULL)
01035 {
01036
01037 if (erscribble_write_stream(stream, (void*)cell->value.v_blob.data, length))
01038 {
01039 erscribble_reset_offset(stream);
01040
01041
01042 if (!erscribble_page_load(page, stream))
01043 {
01044 ERRORPRINTF("Error happens when loading page:%s",
01045 page->id.id);
01046
01047 erscribble_page_clear_strokes(page);
01048 return FALSE;
01049 }
01050
01051
01052 remove_oldest_page_scribbles(doc);
01053 }
01054
01055 erscribble_free_stream(stream, TRUE);
01056 stream = NULL;
01057 }
01058 else
01059 {
01060 ERRORPRINTF("Not enough memory to create a new stream");
01061 return FALSE;
01062 }
01063 }
01064
01065 LOGPRINTF("exit");
01066 return TRUE;
01067 }
01068
01069
01070 #ifdef SAVE_TO_FILE
01071
01072 static ScbStreamPtr doc_load_page_file(const ScbPageIdPtr id)
01073 {
01074 LOGPRINTF("entry");
01075 FILE *f_read = fopen(id->id, "rb");
01076
01077 if (NULL == f_read)
01078 {
01079
01080 return NULL;
01081 }
01082
01083
01084 fseek(f_read , 0 , SEEK_END);
01085 long size = ftell(f_read);
01086
01087 ScbStreamPtr stream = erscribble_create_stream(size);
01088 if (NULL == stream)
01089 {
01090 fclose(f_read);
01091 return NULL;
01092 }
01093
01094 fseek(f_read, 0, SEEK_SET);
01095 long ret = fread(stream->buffer, 1, size, f_read);
01096 if (ret != size)
01097 {
01098 erscribble_free_stream(stream, TRUE);
01099 stream = NULL;
01100 }
01101
01102 fclose(f_read);
01103 LOGPRINTF("exit");
01104 return stream;
01105 }
01106
01107
01108 static gboolean doc_save_page_file(const ScbPageIdPtr id, ScbStreamPtr stream)
01109 {
01110 LOGPRINTF("entry");
01111 FILE *f_write = fopen(id->id, "wb");
01112 if (NULL == f_write)
01113 {
01114
01115 return FALSE;
01116 }
01117
01118 if (fwrite(stream->buffer, 1, stream->offset, f_write) != stream->offset)
01119 {
01120 return FALSE;
01121 }
01122
01123 fclose(f_write);
01124
01125 LOGPRINTF("exit");
01126 return TRUE;
01127 }
01128
01129 #else
01130
01131 static gboolean save_page_data(const ScbDocPtr doc,
01132 const ScbPagePtr page,
01133 const ScbStreamPtr stream,
01134 gboolean *need_free_stream)
01135 {
01136 LOGPRINTF("entry");
01137 if (doc == NULL || page == NULL || stream == NULL)
01138 {
01139 return FALSE;
01140 }
01141
01142 if (doc->metadata_db == NULL)
01143 {
01144 ERRORPRINTF("document is not ready");
01145 return FALSE;
01146 }
01147
01148 int ret = ER_FAIL;
01149 *need_free_stream = TRUE;
01150
01151 if (page->id.annotation_id < 0)
01152 {
01153
01154
01155
01156 gboolean do_create = FALSE;
01157 if (g_enable_autodelete)
01158 do_create = erscribble_page_get_stroke_count(page) > 0 ? TRUE : FALSE;
01159 else
01160 do_create = erscribble_page_get_stroke_count(page) >= 0 ? TRUE : FALSE;
01161
01162 if (do_create)
01163 {
01164 ret = ermetadb_local_create_annotation (doc->metadata_db,
01165 doc->path.document_path,
01166 &page->id.annotation_id,
01167 ERSCRIBBLE_ANNOTATION_TYPE,
01168 "",
01169 page->id.position,
01170 NULL,
01171 page->id.id,
01172 NULL,
01173 (gchar*)stream->buffer,
01174 stream->offset);
01175
01176 if (ret == ER_OK)
01177 {
01178 *need_free_stream = FALSE;
01179 }
01180 }
01181 }
01182 else
01183 {
01184
01185
01186
01187
01188 gboolean do_update = FALSE;
01189 if (g_enable_autodelete)
01190 do_update = erscribble_page_get_stroke_count(page) > 0 ? TRUE : FALSE;
01191 else
01192 do_update = erscribble_page_get_stroke_count(page) >= 0 ? TRUE : FALSE;
01193
01194 if (do_update)
01195 {
01196 ret = ermetadb_local_set_annotation(doc->metadata_db,
01197 page->id.annotation_id,
01198 ERSCRIBBLE_ANNOTATION_TYPE,
01199 "",
01200 page->id.position,
01201 NULL,
01202 page->id.id,
01203 NULL,
01204 (gchar*)stream->buffer,
01205 stream->offset);
01206 if (ret == ER_OK)
01207 {
01208 *need_free_stream = FALSE;
01209 }
01210 }
01211 else
01212 {
01213
01214 ret = ermetadb_local_remove_annotation(doc->metadata_db,
01215 page->id.annotation_id);
01216
01217 page->id.annotation_id = -1;
01218 }
01219 }
01220
01221 if (page->id.annotation_id >= 0)
01222 {
01223
01224
01225 page->is_blob_loaded = TRUE;
01226
01227
01228 remove_oldest_page_scribbles(doc);
01229 }
01230
01231 LOGPRINTF("exit");
01232 return ret;
01233 }
01234
01235 void erscribble_doc_disable_autodelete(gboolean do_disable)
01236 {
01237 g_enable_autodelete = !do_disable ;
01238 }
01239
01240
01241
01242 #endif