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 #include <math.h>
00028 #include <cstring>
00029
00030 #include "notepad_doc.h"
00031 #include "notepad_filestore.h"
00032 #include "notepad_ipc.h"
00033 #include "log.h"
00034 #include "notepad_point.h"
00035
00036
00037 namespace notepad
00038 {
00039 CNotepadDoc::CNotepadDoc()
00040 : doc(0)
00041 , page(0)
00042 , stroke(0)
00043 , dirty(FALSE)
00044 , file_store( new CFileStore() )
00045 {
00046 erscribble_init();
00047 erscribble_doc_disable_autodelete(TRUE);
00048 }
00049
00050 CNotepadDoc::~CNotepadDoc()
00051 {
00052 erscribble_uninit();
00053 delete file_store;
00054 }
00055
00056 np_result CNotepadDoc::open(const gchar* filename)
00057 {
00058 LOGPRINTF("entry");
00059
00060 g_assert(doc == 0);
00061
00062 np_result result = file_store->openFile(filename);
00063 if (result == NP_OK)
00064 {
00065 doc = erscribble_doc_open_with_database(".", file_store->getFile());
00066
00067 if (!doc)
00068 {
00069 result = NP_NO_DOCUMENT;
00070 }
00071 }
00072
00073 LOGPRINTF("exit");
00074 return result;
00075 }
00076
00077 np_result CNotepadDoc::create(const gchar* filename)
00078 {
00079 LOGPRINTF("entry filename='%s'", filename);
00080
00081 g_assert(doc == 0);
00082
00083 np_result result = file_store->createFile(filename);
00084 if (result == NP_OK)
00085 {
00086 doc = erscribble_doc_new_with_database(".", file_store->getFile());
00087
00088 if (!doc)
00089 {
00090 result = NP_NO_DOCUMENT;
00091 }
00092 }
00093 LOGPRINTF("exit");
00094 return result;
00095 }
00096
00097 gboolean CNotepadDoc::get_page_dirty()
00098 {
00099 return dirty;
00100 }
00101
00102 np_result CNotepadDoc::save_page(const int pageno, bool update_last_read)
00103 {
00104 LOGPRINTF("entry");
00105 g_return_val_if_fail(doc != 0, NP_NO_DOCUMENT);
00106
00107 if (dirty == FALSE)
00108 {
00109 LOGPRINTF("exit No changes to save");
00110 return NP_OK;
00111 }
00112
00113 ScbPageId pid;
00114 generate_page_id(pid, pageno);
00115 ScbPagePtr thispage = erscribble_doc_get_page(doc, &pid);
00116 if (NULL == thispage)
00117 {
00118 LOGPRINTF("exit No page");
00119 return NP_OK;
00120 }
00121 if (ER_OK != erscribble_doc_save_page(doc, thispage))
00122 {
00123 LOGPRINTF("exit Saving page failed");
00124 return NP_SAVE_FAILED;
00125 }
00126
00127 if ( update_last_read )
00128 {
00129 (void) set_last_read(pageno);
00130 }
00131
00132
00133
00134 dirty = FALSE;
00135
00136 LOGPRINTF("exit");
00137 return NP_OK;
00138 }
00139
00140 void CNotepadDoc::close()
00141 {
00142 LOGPRINTF("entry");
00143
00144 if (doc)
00145 {
00146 erscribble_doc_free(doc);
00147 file_store->closeFile();
00148 doc = 0;
00149 memset(&path, 0, sizeof(path));
00150 page = 0;
00151 stroke = 0;
00152 }
00153
00154 LOGPRINTF("exit");
00155 }
00156
00157 np_result CNotepadDoc::rename(const gchar* new_shortfilename)
00158 {
00159 LOGPRINTF("entry");
00160 g_return_val_if_fail( (new_shortfilename != 0) && (new_shortfilename[0] != '\0'), NP_NO_FILENAME);
00161
00162 np_result result = file_store->renameFile(new_shortfilename);
00163 gchar* my_filename = file_store->getFileNameFilePartNoExt();
00164 ipc_change_filename(file_store->getFilename(), my_filename);
00165 g_free(my_filename);
00166
00167 LOGPRINTF("exit");
00168 return result;
00169 }
00170
00171 gint CNotepadDoc::get_num_pages()
00172 {
00173 gint num_pages = 0;
00174 if (doc)
00175 {
00176 num_pages = g_list_length((erscribble_doc_get_pages(doc))->pages);
00177 }
00178 return num_pages;
00179 }
00180
00181 gint CNotepadDoc::get_last_read()
00182 {
00183 if (doc)
00184 {
00185 return file_store->get_last_read_location();
00186 }
00187 return -1;
00188 }
00189
00190 gboolean CNotepadDoc::set_last_read(gint value)
00191 {
00192 if (doc)
00193 {
00194 return file_store->set_last_read_location(value);
00195 }
00196 return FALSE;
00197 }
00198
00199 gchar* CNotepadDoc::get_full_filename()
00200 {
00201 return file_store->getFilename();
00202 }
00203
00204 gchar* CNotepadDoc::get_filename_without_dir_and_ext()
00205 {
00206 return file_store->getFileNameFilePartNoExt();
00207 }
00208
00209 CFileStore* CNotepadDoc::getFileStore()
00210 {
00211 return file_store;
00212 }
00213
00214 void CNotepadDoc::generate_page_id(ScbPageId& pid, const int pos)
00215 {
00216 gchar anchor[80];
00217 sprintf(anchor, "%d", pos);
00218 erscribble_page_set_id(&pid, pos, anchor, -1);
00219 LOGPRINTF("id %s, pos %d, anno %lld ", pid.id, pid.position, pid.annotation_id);
00220 }
00221
00222 void CNotepadDoc::add_page(const int pageno)
00223 {
00224 LOGPRINTF("Append Empty Page!!");
00225
00226 page = 0;
00227 page = erscribble_page_new();
00228 ScbPageId pid;
00229 generate_page_id(pid, pageno);
00230 erscribble_page_copy_id(&page->id, &pid);
00231 page->attributes.style.orientation = 0;
00232 erscribble_doc_add_page(doc, page);
00233 page = 0;
00234 stroke = 0;
00235 dirty = TRUE;
00236 }
00237
00238 void CNotepadDoc::insert_page(const int pageno)
00239 {
00240 LOGPRINTF("Insert Empty Page!!");
00241
00242 page = 0;
00243 page = erscribble_page_new();
00244 ScbPageId pid;
00245 generate_page_id(pid, pageno);
00246 erscribble_page_copy_id(&page->id, &pid);
00247 page->attributes.style.orientation = 0;
00248 erscribble_doc_insert_page(doc, page);
00249 page = 0;
00250 stroke = 0;
00251 dirty = TRUE;
00252 }
00253
00254 void CNotepadDoc::delete_page(const int pageno)
00255 {
00256 LOGPRINTF("Deleting page: %d", pageno);
00257
00258 ScbPageId pid;
00259 generate_page_id(pid, pageno);
00260 erscribble_doc_delete_page(doc, &pid);
00261 page = 0;
00262 stroke = 0;
00263 }
00264
00265 void CNotepadDoc::clear_page(const int pageno)
00266 {
00267 ScbPageId pid;
00268 generate_page_id(pid, pageno);
00269 ScbPagePtr thispage = erscribble_doc_get_page(doc, &pid);
00270 if (thispage == 0)
00271 {
00272 LOGPRINTF("no page to erase");
00273 return;
00274 }
00275 erscribble_page_clear_strokes(thispage);
00276 dirty = TRUE;
00277 }
00278
00279
00280
00281
00282 void CNotepadDoc::draw_stroke(GCtx& gctx, GdkImage* image, ScbStrokePtr stroke)
00283 {
00284 g_assert(image != 0);
00285 g_assert(stroke != 0);
00286
00287 int count = erscribble_stroke_get_point_count(stroke);
00288 ScbPointPtr pts = erscribble_stroke_get_point_data(stroke);
00289
00290 gctx.set_color(stroke->attributes.color);
00291
00292 gctx.set_line_attributes(stroke->attributes.size_id);
00293
00294 CNPoint sp1(pts[0]);
00295
00296 for (int i=1; i < count; i++)
00297 {
00298 CNPoint sp2(pts[i]);
00299 gctx.draw_line(image, sp1.windowView(), sp2.windowView());
00300 sp1 = sp2;
00301 }
00302 }
00303
00304 void CNotepadDoc::draw_erased_strokes(GCtx& gctx, GdkImage* image, ScbStrokesPtr strokes)
00305 {
00306 LOGPRINTF("entry");
00307
00308 g_assert(image != 0);
00309
00310
00311 ipc_sys_bg_busy(TRUE);
00312
00313 if (strokes)
00314 {
00315 ScbStrokePtr stroke = NULL;
00316 GList *ptr = g_list_first(strokes->strokes);
00317
00318 while (ptr)
00319 {
00320 stroke = (ScbStrokePtr)ptr->data;
00321 if (stroke)
00322 {
00323
00324 int count = erscribble_stroke_get_point_count(stroke);
00325 stroke->attributes.color = ERSCRIBBLE_DEV_COLOR_WHITE;
00326 gctx.set_color(stroke->attributes.color);
00327 ScbPointPtr pts = erscribble_stroke_get_point_data(stroke);
00328
00329 int erase_offset_x = 0;
00330 int erase_offset_y = 0;
00331
00332
00333
00334
00335 if (gctx.rotation != NP_PORTRAIT)
00336 {
00337 if (gctx.rotation == NP_ANTICLOCKWISE)
00338 {
00339 switch (stroke->attributes.size_id)
00340 {
00341 case 1:
00342 case 3:
00343 case 5:
00344 erase_offset_x = -1;
00345 break;
00346 case 2:
00347 case 4:
00348 erase_offset_x = -1;
00349 erase_offset_y = -1;
00350 break;
00351 default:
00352 break;
00353 }
00354 }
00355 else
00356 {
00357 switch (stroke->attributes.size_id)
00358 {
00359 case 1:
00360 case 3:
00361 case 5:
00362 erase_offset_y = -1;
00363 break;
00364 case 2:
00365 case 4:
00366 erase_offset_x = 1;
00367 erase_offset_y = -1;
00368 break;
00369 default:
00370 break;
00371 }
00372 }
00373 }
00374
00375
00376 for (int i = 0; i < count; i++)
00377 {
00378 CNPoint p(pts[i]);
00379 pts[i].x = p.deviceView().x + erase_offset_x;
00380 pts[i].y = p.deviceView().y + erase_offset_y;
00381 }
00382
00383
00384 erscribble_stroke_driver_draw(stroke);
00385
00386
00387 for (int i = 0; i < count; i++)
00388 {
00389 pts[i].x -= erase_offset_x;
00390 pts[i].y -= erase_offset_y;
00391 }
00392
00393
00394
00395
00396 draw_stroke(gctx, image, stroke);
00397 }
00398 ptr = g_list_next(ptr);
00399 }
00400 }
00401
00402 ipc_sys_bg_busy(FALSE);
00403 LOGPRINTF("exit");
00404 }
00405
00406
00407 void CNotepadDoc::on_scribble_begin(
00408 const int pageno,
00409 GCtx& gctx,
00410 GdkImage* image,
00411 CNPoint& apoint)
00412 {
00413 LOGPRINTF("entry");
00414 g_assert(image);
00415
00416 if ((pageno > 0) && (page == 0) && (stroke == 0))
00417 {
00418 ScbPageId pid;
00419 generate_page_id(pid, pageno);
00420
00421
00422 page = erscribble_doc_get_page(doc, &pid);
00423 if (page == 0)
00424 {
00425
00426 page = erscribble_page_new();
00427 erscribble_page_copy_id(&page->id, &pid);
00428 page->attributes.style.orientation = 0;
00429 LOGPRINTF("created new page %s", pid.id);
00430 }
00431
00432
00433 if (stroke == 0)
00434 {
00435 stroke = erscribble_stroke_new_with_attributes(erscribble_doc_get_current_stroke_attributes(doc));
00436 stroke->attributes.zoom = 100.0;
00437 stroke->attributes.size_id = ipc_get_pensize();
00438 stroke->attributes.color = ERSCRIBBLE_DEV_COLOR_BLACK;
00439 erscribble_page_add_stroke(page, stroke);
00440 LOGPRINTF("Created new stroke");
00441 }
00442
00443
00444 ScbDevPoint point;
00445 point.point = apoint.storageView();
00446 point.pressure = 0;
00447 erscribble_stroke_add_point(stroke, &point);
00448
00449
00450 point.point = apoint.deviceView();
00451 erscribble_stroke_driver_draw_point(stroke, &point, FALSE);
00452 }
00453 }
00454
00455 void CNotepadDoc::on_scribble_move(
00456 const int pageno,
00457 GCtx& gctx,
00458 GdkImage* image,
00459 CNPoint& apoint)
00460 {
00461 g_assert(image);
00462
00463 if (stroke)
00464 {
00465
00466 ScbDevPoint point;
00467 point.point = apoint.storageView();
00468 erscribble_stroke_add_point(stroke, &point);
00469
00470 point.point = apoint.deviceView();
00471 erscribble_stroke_driver_draw_point(stroke, &point, FALSE);
00472 }
00473 }
00474
00475 void CNotepadDoc::on_scribble_end(
00476 const int pageno,
00477 GCtx& gctx,
00478 GdkImage* image,
00479 CNPoint& apoint)
00480 {
00481 LOGPRINTF("End stroke!");
00482
00483 g_assert(image);
00484
00485 if ( (pageno > 0) && stroke && doc && page)
00486 {
00487
00488 ScbDevPoint point;
00489 point.point = apoint.storageView();
00490 erscribble_stroke_add_point(stroke, &point);
00491
00492
00493 point.point = apoint.deviceView();
00494 erscribble_stroke_driver_draw_point(stroke, &point, TRUE);
00495
00496
00497
00498
00499 draw_stroke(gctx, image, stroke);
00500
00501
00502 erscribble_doc_add_page(doc, page);
00503 page = 0;
00504 stroke = 0;
00505 }
00506 dirty = TRUE;
00507 }
00508
00509 void CNotepadDoc::on_erase_begin(
00510 const int pageno,
00511 GCtx& gctx,
00512 GdkImage* image,
00513 CNPoint& apoint)
00514 {
00515 LOGPRINTF("entry");
00516
00517 g_assert(image);
00518
00519 if (pageno > 0)
00520 {
00521
00522 ScbPageId pid;
00523 generate_page_id(pid, pageno);
00524
00525 page = erscribble_doc_get_page(doc, &pid);
00526 if (page == 0)
00527 {
00528 return;
00529 }
00530
00531
00532 erscribble_page_erase_init(&erase_context);
00533
00534 ScbDevPoint point;
00535 point.point = apoint.storageView();
00536 erase_context.zoom = 100.0;
00537 ScbStrokesPtr strokes = erscribble_page_erase_hit_test(page, &point, &erase_context);
00538 if (strokes)
00539 {
00540 LOGPRINTF("Erase strokes!");
00541
00542
00543 draw_erased_strokes(gctx, image, strokes);
00544
00545
00546 erscribble_strokes_free(strokes);
00547
00548 dirty = TRUE;
00549 }
00550 }
00551 }
00552
00553 void CNotepadDoc::on_erase_move(
00554 const int pageno,
00555 GCtx& gctx,
00556 GdkImage* image,
00557 CNPoint& apoint )
00558 {
00559 g_assert(image);
00560
00561 ScbDevPoint point;
00562 point.point = apoint.storageView();
00563
00564
00565
00566 ScbStrokesPtr strokes = erscribble_page_erase_hit_test(page, &point, &erase_context);
00567 if (strokes)
00568 {
00569 LOGPRINTF("Erase strokes!");
00570
00571 draw_erased_strokes(gctx, image, strokes);
00572
00573
00574 erscribble_strokes_free(strokes);
00575
00576 dirty = TRUE;
00577 }
00578 }
00579
00580 void CNotepadDoc::on_erase_end(
00581 const int pageno,
00582 GCtx& gctx,
00583 GdkImage* image,
00584 CNPoint& apoint)
00585 {
00586 g_assert(image);
00587
00588 ScbDevPoint point;
00589 point.point = apoint.storageView();
00590 ScbStrokesPtr strokes = erscribble_page_erase_hit_test(page, &point, &erase_context);
00591
00592
00593 page = 0;
00594 if (strokes)
00595 {
00596 LOGPRINTF("Erase strokes!");
00597
00598 draw_erased_strokes(gctx, image, strokes);
00599
00600
00601 erscribble_strokes_free(strokes);
00602
00603 dirty = TRUE;
00604 }
00605 }
00606
00607 void CNotepadDoc::draw_scribble_page(const int pageno, GCtx& gctx, GdkImage* image)
00608 {
00609 LOGPRINTF("entry");
00610
00611 g_assert(image);
00612
00613
00614 ScbPageId pid;
00615 generate_page_id(pid, pageno);
00616
00617 ScbPagePtr thispage = erscribble_doc_get_page(doc, &pid);
00618 if (thispage == 0)
00619 {
00620 LOGPRINTF("page %s not found!", pid.id);
00621 return;
00622 }
00623
00624
00625 ipc_sys_bg_busy(TRUE);
00626
00627 ScbStrokesPtr strokes = erscribble_page_get_strokes(thispage);
00628
00629 if (strokes)
00630 {
00631 ScbStrokePtr stroke = NULL;
00632 GList *pstroke = g_list_first(strokes->strokes);
00633 while (pstroke)
00634 {
00635 stroke = (ScbStrokePtr)pstroke->data;
00636 if (stroke)
00637 {
00638 draw_stroke(gctx, image, stroke);
00639
00640
00641
00642
00643
00644
00645 }
00646 pstroke = g_list_next(pstroke);
00647 }
00648 }
00649
00650 ipc_sys_bg_busy(FALSE);
00651
00652 LOGPRINTF("exit");
00653 }
00654
00655 }
00656