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