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 <cassert>
00028 #include "document_impl.h"
00029 #include "view_impl.h"
00030 #include "collection_impl.h"
00031 #include "string_impl.h"
00032 #include "marker_entry_impl.h"
00033 #include "log.h"
00034
00035 namespace images
00036 {
00037
00038 utils::ObjectTable<PluginDocImpl> PluginDocImpl::g_instances_table;
00039
00040 PluginDocImpl::PluginDocImpl()
00041 {
00042 LOGPRINTF("entry");
00043
00044
00045 query_interface = query_interface_impl;
00046 release = release_impl;
00047
00048
00049 open = open_impl;
00050 is_open = is_open_impl;
00051 close = close_impl;
00052 create_view = create_view_impl;
00053
00054
00055 get_initial_anchor = get_initial_anchor_impl;
00056 get_object_from_anchor = get_object_from_anchor_impl;
00057 get_type_of_object = get_type_of_object_impl;
00058 get_words_from_range = get_words_from_range_impl;
00059 get_text_from_range = get_text_from_range_impl;
00060 is_anchor_in_current_document = is_anchor_in_current_document_impl;
00061 get_file_name_from_anchor = get_file_name_from_anchor_impl;
00062 get_file_position_from_anchor = get_file_position_from_anchor_impl;
00063 compare_anchor_location = compare_anchor_location_impl;
00064
00065
00066 get_attribute = get_attribute_impl;
00067 set_attribute = set_attribute_impl;
00068
00069
00070 add_event_receiver = add_event_receiver_impl;
00071 remove_event_receiver = remove_event_receiver_impl;
00072
00073
00074 is_hyperlink = is_hyperlink_impl;
00075 get_target_from_hyperlink = get_target_from_hyperlink_impl;
00076
00077
00078 is_dictionary = is_dictionary_impl;
00079
00080
00081 get_supported_marker_types = get_supported_marker_types_impl;
00082 request_marker_trees = request_marker_trees_impl;
00083
00084
00085 g_instances_table.add_interface<IPluginUnknown>(this);
00086 g_instances_table.add_interface<IPluginDocument>(this);
00087 g_instances_table.add_interface<IPluginDocNavigator>(this);
00088 g_instances_table.add_interface<IPluginDocAttributes>(this);
00089 g_instances_table.add_interface<IPluginEventBroadcaster>(this);
00090 g_instances_table.add_interface<IPluginDocHyperlink>(this);
00091 g_instances_table.add_interface<IPluginDocDictionary>(this);
00092
00093
00094 init_doc_attributes();
00095 }
00096
00097 void PluginDocImpl::init_doc_attributes()
00098 {
00099 doc_attr_map.insert(std::make_pair("fixed-page", "yes"));
00100 doc_attr_map.insert(std::make_pair("virtual-document", "yes"));
00101 doc_attr_map.insert(std::make_pair("disable-directory-scanning", "no"));
00102 }
00103
00104 PluginDocImpl::~PluginDocImpl()
00105 {
00106 LOGPRINTF("entry");
00107
00108 remove_slots();
00109 g_instances_table.remove(this);
00110 }
00111
00112 unsigned int PluginDocImpl::get_page_count()
00113 {
00114 LOGPRINTF("%d", document.page_count());
00115
00116 return document.page_count();
00117 }
00118
00119 unsigned int PluginDocImpl::get_page_number(const std::string & anchor)
00120 {
00121 LOGPRINTF("%s", anchor.c_str());
00122
00123 return document.get_position(anchor);
00124 }
00125
00126 bool PluginDocImpl::get_page_name(const std::string & anchor,
00127 std::string & name)
00128 {
00129 return document.get_page_name(anchor, name);
00130 }
00131
00132 int PluginDocImpl::get_page(const std::string & anchor)
00133 {
00134 unsigned int page_number = get_page_number(anchor);
00135
00136 LOGPRINTF("%s %d", anchor.c_str(), page_number);
00137
00138 return page_number;
00139 }
00140
00141 bool PluginDocImpl::get_anchor_of_page(const unsigned int page_number,
00142 std::string & anchor)
00143 {
00144 LOGPRINTF("%d", page_number);
00145
00146 return document.get_anchor_of_page(page_number, anchor);
00147 }
00148
00149 bool PluginDocImpl::get_prev_page(std::string & anchor)
00150 {
00151 LOGPRINTF("%s", anchor.c_str());
00152
00153 return document.get_prev_page(anchor);
00154 }
00155
00156 bool PluginDocImpl::get_next_page(std::string & anchor)
00157 {
00158 LOGPRINTF("%s", anchor.c_str());
00159
00160 return document.get_next_page(anchor);
00161 }
00162
00163 ImagesDocument * PluginDocImpl::get_doc(void)
00164 {
00165 LOGPRINTF("entry");
00166
00167 return &document;
00168 }
00169
00170 bool PluginDocImpl::get_original_size(const std::string &anchor,
00171 unsigned int &width,
00172 unsigned int &height)
00173 {
00174 return document.get_original_size(anchor, width, height);
00175 }
00176
00177 bool PluginDocImpl::get_original_rotation(const std::string &anchor,
00178 PluginRotationDegree &rotation)
00179 {
00180 return document.get_original_rotation(anchor, rotation);
00181 }
00182
00183 PluginStatus
00184 PluginDocImpl::query_interface_impl(IPluginUnknown *thiz,
00185 const UDSString *id,
00186 void **ptr )
00187 {
00188 LOGPRINTF("entry");
00189
00190
00191 PluginDocImpl *instance = g_instances_table.get_object(thiz);
00192
00193
00194 if (g_instances_table.query_interface(instance,
00195 id->get_buffer(id),
00196 ptr))
00197 {
00198 return PLUGIN_OK;
00199 }
00200 return PLUGIN_FAIL;
00201 }
00202
00203 int
00204 PluginDocImpl::release_impl(IPluginUnknown *thiz )
00205 {
00206 LOGPRINTF("entry");
00207
00208
00209 PluginDocImpl *instance = g_instances_table.get_object(thiz);
00210 instance->release_signal.safe_broadcast(instance);
00211 return 0;
00212 }
00213
00214
00215 PluginStatus
00216 PluginDocImpl::open_impl(IPluginUnknown *thiz,
00217 const UDSString *path)
00218 {
00219 LOGPRINTF("%s", path->get_buffer(path));
00220
00221
00222 PluginDocImpl *instance = g_instances_table.get_object(thiz);
00223
00224
00225 assert(!instance->document.is_open());
00226
00227 bool disable_directory_scanning = false;
00228
00229 const StringImpl key("disable-directory-scanning");
00230 StringImpl value;
00231 if (get_attribute_impl(thiz, &key, &value) == PLUGIN_OK)
00232 {
00233 const StringImpl tmp("yes");
00234 disable_directory_scanning = (value == tmp);
00235 }
00236
00237 if (instance->document.open_document(path->get_buffer(path),
00238 !disable_directory_scanning))
00239 {
00240 return PLUGIN_OK;
00241 }
00242 return PLUGIN_FAIL;
00243 }
00244
00245 PluginBool
00246 PluginDocImpl::is_open_impl(IPluginUnknown *thiz)
00247 {
00248 LOGPRINTF("entry");
00249
00250
00251 PluginDocImpl *instance = g_instances_table.get_object(thiz);
00252
00253
00254 if (instance->document.is_open())
00255 {
00256 return PLUGIN_TRUE;
00257 }
00258 return PLUGIN_FALSE;
00259 }
00260
00261 PluginStatus
00262 PluginDocImpl::close_impl(IPluginUnknown *thiz)
00263 {
00264 LOGPRINTF("entry");
00265
00266
00267 PluginDocImpl *instance = g_instances_table.get_object(thiz);
00268
00269
00270 ViewsIter begin = instance->views.begin();
00271 ViewsIter end = instance->views.end();
00272 for(ViewsIter iter = begin; iter != end; ++iter)
00273 {
00274 (*iter)->stop_renderer();
00275 }
00276
00277
00278 assert(instance->document.is_open());
00279 if (instance->document.close_document())
00280 {
00281 return PLUGIN_OK;
00282 }
00283 return PLUGIN_FAIL;
00284 }
00285
00286 IPluginUnknown *
00287 PluginDocImpl::create_view_impl(IPluginUnknown *thiz)
00288 {
00289 LOGPRINTF("entry");
00290
00291
00292 PluginDocImpl *instance = g_instances_table.get_object(thiz);
00293
00294
00295 ViewPtr ptr = new PluginViewImpl(instance);
00296 assert(ptr);
00297 instance->views.push_back(ptr);
00298 ptr->release_signal.add_slot(instance,
00299 &PluginDocImpl::on_view_released);
00300 return static_cast<IPluginUnknown *>(ptr);
00301 }
00302
00303 PluginStatus
00304 PluginDocImpl::get_initial_anchor_impl(IPluginUnknown *thiz,
00305 UDSString *anchor)
00306 {
00307 LOGPRINTF("entry");
00308
00309 PluginDocImpl *instance = g_instances_table.get_object(thiz);
00310
00311
00312 int page_num = instance->document.get_initial_page_num();
00313
00314 std::string temp;
00315 if (instance->document.get_anchor_of_page(page_num, temp))
00316 {
00317 anchor->assign(anchor, temp.c_str());
00318 return PLUGIN_OK;
00319 }
00320 return PLUGIN_FAIL;
00321 }
00322
00323 PluginStatus
00324 PluginDocImpl::get_object_from_anchor_impl(IPluginUnknown *thiz,
00325 const UDSString *anchor,
00326 PluginRange *range)
00327 {
00328 LOGPRINTF("entry");
00329
00330
00331 return PLUGIN_FAIL;
00332 }
00333
00334 PluginDocObjectType
00335 PluginDocImpl::get_type_of_object_impl(IPluginUnknown *thiz,
00336 const PluginRange *range)
00337 {
00338 LOGPRINTF("entry");
00339
00340 return PLUGIN_DOC_OBJECT_IMAGE;
00341 }
00342
00343 PluginStatus
00344 PluginDocImpl::get_words_from_range_impl(IPluginUnknown *thiz,
00345 const PluginRange *chars_range,
00346 PluginRange *words_range )
00347 {
00348 LOGPRINTF("entry");
00349 return PLUGIN_NOT_SUPPORTED;
00350 }
00351
00352 PluginStatus
00353 PluginDocImpl::get_text_from_range_impl(IPluginUnknown *thiz,
00354 const PluginRange *range,
00355 UDSString *result)
00356 {
00357 LOGPRINTF("entry");
00358
00359 return PLUGIN_FAIL;
00360 }
00361
00362 PluginBool
00363 PluginDocImpl::is_anchor_in_current_document_impl(IPluginUnknown *thiz,
00364 const UDSString *anchor)
00365 {
00366 LOGPRINTF("entry");
00367
00368
00369 PluginDocImpl *instance = g_instances_table.get_object(thiz);
00370
00371 if (instance->document.has_anchor(anchor->get_buffer(anchor)))
00372 {
00373 return PLUGIN_TRUE;
00374 }
00375 return PLUGIN_FALSE;
00376 }
00377
00378 PluginStatus
00379 PluginDocImpl::get_file_name_from_anchor_impl(IPluginUnknown *thiz,
00380 const UDSString *anchor,
00381 UDSString *file_name)
00382 {
00383 if (!thiz || !anchor || !file_name)
00384 {
00385 return PLUGIN_FAIL;
00386 }
00387
00388 if (is_anchor_in_current_document_impl(thiz, anchor) == PLUGIN_FALSE)
00389 {
00390 return PLUGIN_FAIL;
00391 }
00392
00393 PluginDocImpl *instance = g_instances_table.get_object(thiz);
00394
00395 std::string temp;
00396 if (instance->get_page_name(anchor->get_buffer(anchor), temp))
00397 {
00398 file_name->assign(file_name, temp.c_str());
00399 return PLUGIN_OK;
00400 }
00401
00402 return PLUGIN_FAIL;
00403 }
00404
00405 PluginStatus
00406 PluginDocImpl::get_file_position_from_anchor_impl(IPluginUnknown *thiz,
00407 const UDSString *anchor,
00408 signed long long *position)
00409 {
00410 if (!thiz || !anchor || !position)
00411 {
00412 return PLUGIN_FAIL;
00413 }
00414
00415 if (is_anchor_in_current_document_impl(thiz, anchor) == PLUGIN_FALSE)
00416 {
00417 return PLUGIN_FAIL;
00418 }
00419
00420 *position = 0;
00421 return PLUGIN_OK;
00422 }
00423
00424 int
00425 PluginDocImpl::compare_anchor_location_impl(IPluginUnknown *thiz,
00426 const UDSString *anchor_a,
00427 const UDSString *anchor_b)
00428 {
00429 LOGPRINTF("entry");
00430
00431
00432 PluginDocImpl *instance = g_instances_table.get_object(thiz);
00433
00434 return instance->document.compare_anchor(anchor_a->get_buffer(anchor_a),
00435 anchor_a->get_buffer(anchor_b));
00436 }
00437
00438
00439 PluginStatus
00440 PluginDocImpl::get_attribute_impl(IPluginUnknown *thiz,
00441 const UDSString *key,
00442 UDSString *value )
00443 {
00444 PluginDocImpl *instance = g_instances_table.get_object(thiz);
00445
00446
00447 if (instance->doc_attr_map.find(key->get_buffer(key))
00448 == instance->doc_attr_map.end())
00449 {
00450 return PLUGIN_NOT_SUPPORTED;
00451 }
00452 value->assign(value, instance->doc_attr_map[key->get_buffer(key)].c_str());
00453 return PLUGIN_OK;
00454 }
00455
00456 PluginStatus
00457 PluginDocImpl::set_attribute_impl(IPluginUnknown *thiz,
00458 const UDSString *key,
00459 const UDSString *value )
00460 {
00461 PluginDocImpl *instance = g_instances_table.get_object(thiz);
00462
00463 const char* key_cstr = key->get_buffer(key);
00464 DocAttrMapIter iter = instance->doc_attr_map.find(key_cstr);
00465 if (iter == instance->doc_attr_map.end())
00466 {
00467 return PLUGIN_NOT_SUPPORTED;
00468 }
00469
00470 iter->second = value->get_buffer(value);
00471 return PLUGIN_OK;
00472 }
00473
00474 PluginStatus
00475 PluginDocImpl::add_event_receiver_impl(IPluginUnknown *thiz,
00476 const PluginEvent plugin_event,
00477 EventFunc callback,
00478 void *user_data,
00479 unsigned long *handler_id)
00480 {
00481 LOGPRINTF("entry");
00482
00483 PluginDocImpl *instance = g_instances_table.get_object(thiz);
00484 assert(handler_id);
00485 *handler_id =
00486 instance->listeners.add_listener(plugin_event, callback, user_data);
00487 return PLUGIN_OK;
00488 }
00489
00490 PluginStatus
00491 PluginDocImpl::remove_event_receiver_impl(IPluginUnknown *thiz,
00492 unsigned long handler_id )
00493 {
00494 LOGPRINTF("entry");
00495
00496 PluginDocImpl *instance = g_instances_table.get_object(thiz);
00497 if (instance->listeners.remove_listener(handler_id))
00498 {
00499 return PLUGIN_OK;
00500 }
00501 return PLUGIN_FAIL;
00502 }
00503
00504 PluginBool
00505 PluginDocImpl::is_hyperlink_impl(IPluginUnknown *thiz,
00506 const PluginRange *range )
00507 {
00508 LOGPRINTF("entry");
00509
00510
00511 return PLUGIN_FALSE;
00512 }
00513
00514 PluginStatus
00515 PluginDocImpl::get_target_from_hyperlink_impl(IPluginUnknown *thiz,
00516 const PluginRange *range,
00517 UDSString *anchor )
00518 {
00519 LOGPRINTF("entry");
00520
00521 return PLUGIN_FAIL;
00522 }
00523
00524 PluginBool
00525 PluginDocImpl::is_dictionary_impl(IPluginUnknown *thiz )
00526 {
00527 LOGPRINTF("entry");
00528
00529 return PLUGIN_FALSE;
00530 }
00531
00532
00533 IPluginUnknown*
00534 PluginDocImpl::get_supported_marker_types_impl(IPluginUnknown *thiz )
00535 {
00536 LOGPRINTF("entry");
00537
00538
00539
00540
00541
00542 PluginCollectionImpl *collection =
00543 new PluginCollectionImpl;
00544 collection->create<PluginMarkerType>();
00545 collection->take_data_ref<PluginMarkerType>().push_back(MARKER_TOC);
00546
00547
00548
00549
00550 return static_cast<IPluginUnknown *>(collection);
00551 }
00552
00553
00554
00555
00556
00557
00558 PluginStatus
00559 PluginDocImpl::request_marker_trees_impl(IPluginUnknown *thiz,
00560 const unsigned int uds_private_size )
00561 {
00562 LOGPRINTF("entry");
00563
00564 PluginDocImpl *instance = g_instances_table.get_object(thiz);
00565
00566
00567 PluginCollectionImpl *collection = new PluginCollectionImpl;
00568 collection->create<MarkerEntry *>();
00569
00570
00571 MarkerEntry * prev_entry = 0;
00572 unsigned int count = instance->document.page_count();
00573 for(unsigned int i = 1; i <= count; ++i)
00574 {
00575 std::string anchor;
00576 if (instance->document.get_anchor_of_page(i, anchor))
00577 {
00578 MarkerEntry * entry = marker_entry_new(uds_private_size);
00579 entry->type = MARKER_TOC;
00580 entry->anchor = new StringImpl(anchor);
00581 entry->text = new StringImpl(anchor);
00582 entry->uds_private_size = uds_private_size;
00583
00584 if (i == 1)
00585 {
00586 collection->take_data_ref<MarkerEntry *>().push_back(entry);
00587 }
00588
00589
00590 if (prev_entry)
00591 {
00592 prev_entry->sibling = entry;
00593 }
00594 prev_entry = entry;
00595 }
00596 }
00597
00598
00599 PluginEventAttrs event_data;
00600 event_data.marker_ready.result = static_cast<IPluginUnknown *>(collection);
00601 instance->listeners.broadcast(thiz, EVENT_MARKER_READY, &event_data);
00602 return PLUGIN_OK;
00603 }
00604
00605 void PluginDocImpl::on_view_released(ViewPtr view)
00606 {
00607 LOGPRINTF("entry");
00608
00609 ViewsIter iter = std::find(views.begin(), views.end(), view);
00610 if (iter != views.end())
00611 {
00612 delete *iter;
00613 views.erase(iter);
00614 }
00615 }
00616
00617 void PluginDocImpl::remove_slots(void)
00618 {
00619 for (ViewsIter iter = views.begin(); iter != views.end(); ++iter)
00620 {
00621 if (*iter)
00622 {
00623 LOGPRINTF("Removing the slot of release signal of PluginViewImpl");
00624 (*iter)->release_signal.remove_slot(this,
00625 &PluginDocImpl::on_view_released);
00626 }
00627 }
00628 }
00629
00630 }
00631
00632