text::TextModel Class Reference

#include <text_model.h>

Collaboration diagram for text::TextModel:
Collaboration graph
[legend]

Data Structures

struct  Paragraph

Public Member Functions

 TextModel ()
 Constructors and destructors.
 ~TextModel ()
PluginStatus open (const std::string &path)
 Open specified document with default encoding.
PluginStatus open (const std::string &path, const std::string &encoding)
 Open document with specified encoding.
bool is_open () const
 Check if document is already open.
void close ()
 Close document.
const std::string & get_encoding () const
 Get current encoding.
const std::string & get_path () const
unsigned int get_paragraph_count () const
 Get number of paragraphs.
const std::string * get_paragraph (unsigned int index) const
 Get 1 paragraph.
bool search (std::vector< Range > &result_ranges, SearchContext *sc)
 Search specified pattern given by search criteria.
bool has_anchor (const Position &pos)
 Check if the document contains the anchor or not.
bool get_file_pos_from_anchor (size_t &file_pos, const Position &pos)
 Get absolute file position from anchor.
bool get_word_from_anchor (const Position &pos, Position &word_start_pos, Position &word_end_pos)
 Get a word from specified document position.
bool get_words_from_range (const Position &range_start, const Position &range_end, Position &words_start, Position &words_end)
 Get the words from range, the range will be extended/shrinked to words boundary.
bool get_text_from_range (std::string &result, const Position &start_pos, const Position &end_pos)
 Get the text between start_pos and end_pos.
void dump ()
 Dump the content to disk file.
void set_aborting_search_task_id (unsigned int id)
 Abort specified search task.
unsigned int get_aborting_search_task_id ()

Data Fields

utils::Signal< const
std::vector< Range > &, const
SearchContext * > 
search_done_signal
 Signals.

Detailed Description

Definition at line 44 of file text_model.h.


Constructor & Destructor Documentation

text::TextModel::TextModel (  ) 

Constructors and destructors.

Definition at line 44 of file text_model.cpp.

00045 : file_p(0)
00046 , encoding("")
00047 , path()
00048 , b_open(false)
00049 , aborting_search_task_id(0)
00050 , incomplete_line(false)
00051 {
00052 }

text::TextModel::~TextModel (  ) 

Definition at line 54 of file text_model.cpp.

References close().

00055 {
00056     if (b_open)
00057     {
00058         close();
00059     }
00060 }

Here is the call graph for this function:


Member Function Documentation

void text::TextModel::close (  ) 

Close document.

Definition at line 111 of file text_model.cpp.

Referenced by open(), and ~TextModel().

00112 {
00113     clear();
00114     fclose(file_p);
00115     file_p = NULL;
00116     b_open = false;
00117     encoding.clear();
00118 }

Here is the caller graph for this function:

void text::TextModel::dump (  ) 

Dump the content to disk file.

Definition at line 647 of file text_model.cpp.

00648 {
00649     // Generate the dump file.
00650     std::string dump_path = path + ".converted";
00651     FILE* fp = fopen(dump_path.c_str(), "w");
00652     
00653     if (fp != NULL)
00654     {
00655         for (unsigned int i=0; i<doc.size(); i++)
00656         {
00657             fputs(doc[i].text->c_str(), fp);
00658         }
00659 
00660         fclose(fp);
00661     }
00662 }

unsigned int text::TextModel::get_aborting_search_task_id (  )  [inline]

Definition at line 131 of file text_model.h.

Referenced by text::SearchTask::execute().

00132     {
00133         return aborting_search_task_id;
00134     }

Here is the caller graph for this function:

const std::string& text::TextModel::get_encoding (  )  const [inline]

Get current encoding.

Definition at line 68 of file text_model.h.

Referenced by text::TextView::TextView().

00069     {
00070         return encoding;
00071     }

Here is the caller graph for this function:

bool text::TextModel::get_file_pos_from_anchor ( size_t &  file_pos,
const Position pos 
)

Get absolute file position from anchor.

Definition at line 477 of file text_model.cpp.

References text::Position::offset, and text::Position::paragraph.

00478 {
00479     // Sanity check.
00480     if (pos.paragraph >= doc.size() || pos.offset >= doc[pos.paragraph].text->size())
00481     {
00482         return false;
00483     }
00484 
00485     file_pos = doc[pos.paragraph].start_file_pos + pos.offset;
00486     return true;
00487 }

const std::string* text::TextModel::get_paragraph ( unsigned int  index  )  const [inline]

Get 1 paragraph.

Definition at line 85 of file text_model.h.

Referenced by text::TextView::calculate_next_page_pos(), text::TextView::calculate_prev_page_pos(), main(), text::TextView::map_doc_pos_to_view_pos(), text::TextView::map_view_pos_to_doc_pos(), text::TextView::render(), and widget_event_handler().

00086     {
00087         assert(index < doc.size());
00088         return doc[index].text;
00089     }

Here is the caller graph for this function:

unsigned int text::TextModel::get_paragraph_count (  )  const [inline]

Get number of paragraphs.

Definition at line 79 of file text_model.h.

Referenced by text::TextView::calculate_next_page_pos(), main(), and text::TextView::map_view_pos_to_doc_pos().

00080     {
00081         return static_cast<unsigned int>(doc.size());
00082     }

Here is the caller graph for this function:

const std::string& text::TextModel::get_path (  )  const [inline]

Definition at line 73 of file text_model.h.

00074     {
00075         return path;
00076     }

bool text::TextModel::get_text_from_range ( std::string &  result,
const Position start_pos,
const Position end_pos 
)

Get the text between start_pos and end_pos.

Definition at line 614 of file text_model.cpp.

References text::Position::offset, and text::Position::paragraph.

00617 {
00618     unsigned int start_paragraph = start_pos.paragraph;
00619     unsigned int end_paragraph = end_pos.paragraph;
00620 
00621     for (unsigned int i = start_paragraph; 
00622             (i <= end_paragraph) && (i < doc.size()); 
00623             i++)
00624     {
00625         if (doc[i].text)
00626         {
00627             const char* start_p = doc[i].text->c_str();
00628             if (i == start_paragraph)
00629             {
00630                 start_p += start_pos.offset;
00631             }
00632 
00633             size_t len = doc[i].text->length();
00634             if (i == end_paragraph)
00635             {
00636                 const char* p = doc[i].text->c_str() + end_pos.offset;
00637                 len = g_utf8_next_char(p) - start_p;
00638             }
00639 
00640             result.append(start_p, len);
00641         }
00642     }
00643 
00644     return true;
00645 }

bool text::TextModel::get_word_from_anchor ( const Position pos,
Position word_start_pos,
Position word_end_pos 
)

Get a word from specified document position.

Definition at line 510 of file text_model.cpp.

References text::Position::offset, and text::Position::paragraph.

Referenced by get_words_from_range().

00513 {
00514     
00515     const char* paragraph = doc[pos.paragraph].text->c_str();
00516     word_start_pos.paragraph = word_end_pos.paragraph = pos.paragraph;
00517 
00518     const char* p = paragraph + pos.offset;
00519 
00520     // Check if the character at pos is a seperator.
00521     if (is_seperator(p))
00522     {
00523         // Then there is no word at pos.
00524         word_start_pos.offset = word_end_pos.offset = pos.offset;
00525         return false;
00526     }
00527 
00528     // Find the first space before pos.
00529     for (; p > paragraph; p = g_utf8_prev_char(p))
00530     {
00531         if (is_seperator(p))
00532         {
00533             p = g_utf8_next_char(p);
00534             break;
00535         }
00536     }
00537     word_start_pos.offset = static_cast<int>(p - paragraph);
00538 
00539     // Find the first space after pos.
00540     for (p = paragraph + pos.offset; *p != 0; p = g_utf8_next_char(p))
00541     {
00542         if (is_seperator(p))
00543         {
00544             p = g_utf8_prev_char(p);
00545             break;
00546         }
00547     }
00548     word_end_pos.offset = static_cast<int>(p - paragraph);
00549 
00550     return true;
00551 }

Here is the caller graph for this function:

bool text::TextModel::get_words_from_range ( const Position range_start,
const Position range_end,
Position words_start,
Position words_end 
)

Get the words from range, the range will be extended/shrinked to words boundary.

Definition at line 553 of file text_model.cpp.

References ERRORPRINTF, get_word_from_anchor(), text::Position::offset, text::Position::paragraph, and text::Position::to_string().

00557 {
00558     if (range_end < range_start)
00559     {
00560         ERRORPRINTF("Invalid range, range_start = %s, range_end = %s",
00561             range_start.to_string().c_str(),
00562             range_end.to_string().c_str());
00563         return false;
00564     }
00565 
00566     Position tmp;
00567 
00568     // Get the object range the range_start anchor points to.
00569     get_word_from_anchor(range_start, words_start, tmp);
00570 
00571     // Get the object range the range_end anchor points to.
00572     get_word_from_anchor(range_end, tmp, words_end);
00573 
00574     // Strip any leading seperators.
00575     const char* start_paragraph = 0;
00576     const char* p = 0;
00577     while (true)
00578     {
00579         start_paragraph = doc[words_start.paragraph].text->c_str();
00580         for (p = start_paragraph + words_start.offset; *p != 0; p = g_utf8_next_char(p))
00581         {
00582             if (!is_seperator(p))
00583             {
00584                 break;
00585             }
00586         }
00587 
00588         if (*p == 0)
00589         {
00590             words_start.paragraph++;
00591             words_start.offset = 0;
00592         }
00593         else
00594         {
00595             break;
00596         }
00597     }
00598     words_start.offset = static_cast<int>(p - start_paragraph);
00599 
00600     // Strip any trailing seperators.
00601     const char* end_paragraph = doc[words_end.paragraph].text->c_str();
00602     for (p = end_paragraph + words_end.offset; p > end_paragraph; p = g_utf8_prev_char(p))
00603     {
00604         if (!is_seperator(p))
00605         {
00606             break;
00607         }
00608     }
00609     words_end.offset = static_cast<int>(p - end_paragraph);
00610 
00611     return words_end >= words_start;
00612 }

Here is the call graph for this function:

bool text::TextModel::has_anchor ( const Position pos  ) 

Check if the document contains the anchor or not.

Definition at line 466 of file text_model.cpp.

References text::Position::offset, and text::Position::paragraph.

00467 {
00468     // Sanity check.
00469     if (pos.paragraph >= doc.size() || pos.offset >= doc[pos.paragraph].text->size())
00470     {
00471         return false;
00472     }
00473 
00474     return true;
00475 }

bool text::TextModel::is_open (  )  const [inline]

Check if document is already open.

Definition at line 59 of file text_model.h.

00060     {
00061         return b_open;
00062     }

PluginStatus text::TextModel::open ( const std::string &  path,
const std::string &  encoding 
)

Open document with specified encoding.

Definition at line 67 of file text_model.cpp.

References close(), PLUGIN_FAIL, and PLUGIN_OK.

00069 {
00070     PluginStatus result = PLUGIN_FAIL;
00071 
00072     // The document was opened already, close it first.
00073     if (b_open)
00074     {
00075         close();
00076     }
00077 
00078     // Try to open specified file.
00079     file_p = fopen(doc_path.c_str(), "r");
00080     if (file_p == NULL)
00081     {
00082         return PLUGIN_FAIL;
00083     }
00084 
00085     // Detect encodings if necessary.
00086     if (encoding.empty())
00087     {
00088         detect_encoding();
00089     }
00090 
00091     // Update document information.
00092     path = doc_path;
00093     b_open = true;
00094 
00095     // Build up paragraphs.
00096     result = read_text();
00097     if (result != PLUGIN_OK)
00098     {
00099         close();
00100         return result;
00101     }
00102 
00103     if (doc.empty())
00104     {
00105         doc.push_back(Paragraph(0, new std::string(" ")));
00106     }
00107 
00108     return result;
00109 }

Here is the call graph for this function:

PluginStatus text::TextModel::open ( const std::string &  path  ) 

Open specified document with default encoding.

Definition at line 62 of file text_model.cpp.

Referenced by main().

00063 {
00064     return open(doc_path, "");
00065 }

Here is the caller graph for this function:

bool text::TextModel::search ( std::vector< Range > &  result_ranges,
SearchContext sc 
)

Search specified pattern given by search criteria.

Parameters:
result_ranges Output range collection.
search_context Search criteria.
Returns:
Return true if search is complete (i.e. we reach the start/end of the document, or find an occurrence if SearchType is SEARCH_NEXT), otherwise false is returned, user needs to call this function again to get the search procedure complete.

Definition at line 345 of file text_model.cpp.

References text::SearchContext::case_sensitive, e, text::Range::end, text::SearchContext::forward, text::SearchContext::from, is_whole_word(), text::SearchContext::match_whole_word, text::Position::offset, text::Position::paragraph, text::SearchContext::pattern, text::SEARCH_NEXT, text::SearchContext::search_type, text::Range::start, utf8_strrstr(), and utf8_strstr().

Referenced by text::SearchTask::execute().

00346 {
00347     // Exact search type and search criteria from search context.
00348     SearchType search_type      = sc->search_type;
00349     Position   &from            = sc->from;
00350     const char *pattern         = sc->pattern.c_str();
00351     bool       case_sensitive   = sc->case_sensitive;
00352     bool       forward          = sc->forward;
00353     bool       match_whole_word = sc->match_whole_word;
00354 
00355     size_t pattern_len = strlen(pattern);
00356     const char *paragraph_head = doc[from.paragraph].text->c_str();
00357 
00358     bool new_search = is_new_search(sc);
00359     
00360     // Remember last search context.
00361     last_sc = *sc;
00362 
00363     // Clear the last search result range.
00364     Position s(0, 0), e(0,0);
00365     last_search_result.start = s;
00366     last_search_result.end = e;
00367 
00368     if (forward)
00369     {
00370         const char *p = paragraph_head + from.offset;
00371         if (p && !new_search)
00372         {
00373             // It's searching next again, move the start position of searching one character.
00374             // Otherwize, searching one letter results in deadlock.
00375             //
00376             // See more in  0003861: [UDS TXT plugin] TXT Search next 
00377             // for single character word does not work.
00378             // 
00379             // The solution is very dirty. But txt plugin has low priority 
00380             // which is not specified for dr1000 and dr800. 
00381             // And redefinition what is range takes much more time and has more effects.
00382             p++;
00383         }
00384         while (true)
00385         {
00386             const char* find = utf8_strstr(p, pattern, case_sensitive);
00387             if (find)
00388             {
00389                 // See if matching whole word.
00390                 if (!match_whole_word || is_whole_word(paragraph_head, find, pattern_len))
00391                 {
00392                     // Pattern found.
00393                     Position start(from.paragraph, static_cast<unsigned int>(find - paragraph_head));
00394                     const char* last_char = g_utf8_prev_char(find + pattern_len);
00395                     Position end(from.paragraph, static_cast<unsigned int>(last_char - paragraph_head));
00396                     result_ranges.push_back(Range(start, end));
00397                     
00398                     if (search_type == SEARCH_NEXT)
00399                     {
00400                         // Remember last search result.
00401                         last_search_result.start = start;
00402                         last_search_result.end = end;
00403 
00404                          // Search complete.
00405                         return true;
00406                     }
00407 
00408                     // If SEARCH_ALL we must continue with current paragraph.
00409                 }
00410 
00411                 p = find + pattern_len;
00412             }
00413             else
00414             {
00415                 // Can't find any match in current paragraph.
00416                 from.offset = 0;
00417                 return ++(from.paragraph) == doc.size();
00418             }
00419         }
00420     }
00421     else
00422     {
00423         // Backward search.
00424         int len = static_cast<int>(from.offset);
00425         while (true)
00426         {
00427             const char *find = utf8_strrstr(paragraph_head, len, pattern, case_sensitive);
00428             if (find)
00429             {
00430                 // See if matching whole word.
00431                 if (!match_whole_word || is_whole_word(paragraph_head, find, pattern_len))
00432                 {
00433                     // Pattern found.
00434                     Position start(from.paragraph, static_cast<unsigned int>(find - paragraph_head));
00435                     const char* last_char = g_utf8_prev_char(find + pattern_len);
00436                     Position end(from.paragraph, static_cast<unsigned int>(last_char - paragraph_head));
00437                     result_ranges.push_back(Range(start, end));
00438 
00439                     // Remember last search result.
00440                     last_search_result.start = start;
00441                     last_search_result.end = end;
00442 
00443                     return true;
00444                 }
00445 
00446                 len = static_cast<int>(find - paragraph_head);
00447             }
00448             else
00449             {
00450                 // Can't find any match in current paragraph.
00451                 if (from.paragraph == 0)
00452                 {
00453                     return true;
00454                 }
00455                 else
00456                 {
00457                     from.paragraph--;
00458                     from.offset = static_cast<unsigned int>(doc[from.paragraph].text->size());
00459                     return false;
00460                 }
00461             }
00462         }
00463     }
00464 }

Here is the call graph for this function:

Here is the caller graph for this function:

void text::TextModel::set_aborting_search_task_id ( unsigned int  id  )  [inline]

Abort specified search task.

Definition at line 126 of file text_model.h.

00127     {
00128         aborting_search_task_id = id;
00129     }


Field Documentation

Signals.

Definition at line 138 of file text_model.h.

Referenced by text::SearchTask::execute(), main(), and text::PluginDocImpl::PluginDocImpl().


The documentation for this class was generated from the following files:
Generated by  doxygen 1.6.2-20100208