gtk_search_win.cc
上传用户:psq1974
上传日期:2007-01-06
资源大小:1195k
文件大小:8k
源码类别:

mpeg/mp3

开发平台:

C/C++

  1. /* Copyright (C) 1998, 1999 State University of New York at Stony Brook
  2.    Author: Andrew V. Shuvalov ( andrew@ecsl.cs.sunysb.edu )
  3.    Software license is located in file "COPYING"
  4. */
  5. #include  <stdio.h>
  6. #include  <unistd.h>
  7. #include  <gtk--.h>
  8. #include "session.h"
  9. #include "search.h"
  10. #include "gtk_search_win.h"
  11. const int SearchWindow::topWindowInitSizeX = 600;
  12. const int SearchWindow::topWindowInitSizeY = 400;
  13. const int SearchResults::col0width = 160;
  14. const int SearchResults::col1width = 150;
  15. const int SearchResults::col2width = 320;
  16. const int SearchResults::TextColumns = 3;
  17. SearchItem::SearchItem( Session &s, SearchWindow &w, int pos )
  18.   : session( s ), searchWin( w ), position( pos ), Gtk_HBox( false, 14 )
  19. {
  20.   // populate it
  21.   if( pos == 0 )
  22.     {
  23.       Gtk_Label *lab1 = new Gtk_Label( "Search for specified word:" );
  24.       pack_start( *lab1, FALSE, FALSE, 0 );
  25.       lab1->show();
  26.     }
  27.   set_spacing( 10 );
  28.   GList *cbitems = NULL;
  29.   cbitems = g_list_append( cbitems, "and" );
  30.   cbitems = g_list_append( cbitems, "and not" );
  31.   cbitems = g_list_append( cbitems, "or" );
  32.   cbitems = g_list_append( cbitems, "result and" );
  33.   cbitems = g_list_append( cbitems, "result and not" );
  34.   boolOpEntry = new Gtk_Combo();
  35.   boolOpEntry->set_popdown_strings( cbitems );
  36.   boolOpEntry->set_value_in_list( false, false );
  37.   boolOpEntry->get_entry()->set_editable( false );
  38.   // add it
  39.   pack_start( *boolOpEntry, FALSE, FALSE, 0 );
  40.   boolOpEntry->set_usize( boolOpEntry->width()/2, boolOpEntry->height() );
  41.   textEntry = new Gtk_Combo();
  42.   pack_start( *textEntry, FALSE, FALSE, 0 );
  43.   textEntry->show();
  44.   // open window in combobox
  45.   connect_to_method( textEntry->get_entry()->changed, this,
  46.      &SearchItem::callback_hint );
  47.   // less
  48.   lessButton = new Gtk_Button( "less" );
  49.   pack_start( *lessButton, FALSE, FALSE, 0 );
  50.   // signal
  51.   connect_to_method( lessButton->clicked, &searchWin,
  52.      &SearchWindow::callback_less, position );
  53.   // more
  54.   moreButton = new Gtk_Button( "more" );
  55.   pack_start( *moreButton, FALSE, FALSE, 0 );
  56.   // signal
  57.   connect_to_method( moreButton->clicked, &searchWin,
  58.      &SearchWindow::callback_more, position );
  59.   // search
  60.   searchButton = new Gtk_Button( "Search" );
  61.   pack_start( *searchButton, FALSE, FALSE, 0 );
  62.   // signal
  63.   connect_to_method( searchButton->clicked, &searchWin,
  64.      &SearchWindow::callback_search );
  65.   show();
  66. }
  67. SearchItem::type SearchItem::get_type() const
  68. {
  69.   string text = boolOpEntry->get_entry()->get_text();
  70.   text.c_str();
  71.   if( text == "and" )
  72.     return and;
  73.   if( text == "and not" )
  74.     return andnot;
  75.   if( text == "or" )
  76.     return or;
  77.   if( text == "result and" )
  78.     return resultand;
  79.   if( text == "result and not" )
  80.     return resultandnot;
  81.   return err;
  82. }
  83. void SearchItem::callback_hint()
  84. {
  85.   // first add to list all similar words...
  86.   string text = textEntry->get_entry()->get_text();
  87.   GList *hints = NULL;
  88.   hints = g_list_append( hints, (void*)text.c_str() );
  89.   if( text.length() )
  90.     {      
  91.       session.find_similar_words( text, hints );
  92.     }
  93.   // now let's search for some near-in-string words
  94.   searchWin.find_hint_words( position, hints );
  95.   if( hints )
  96.     {
  97.       textEntry->set_popdown_strings( hints );
  98.       textEntry->show();
  99.     }
  100. }
  101. // --------------------------------------------------------------------------
  102. SearchWindow::SearchWindow( Session &s )
  103.   : session( s )
  104. {
  105.   set_usize( topWindowInitSizeX, topWindowInitSizeY );
  106.   // make vertical box
  107.   Gtk_VBox *top_vbox_layout = new Gtk_VBox();
  108.   top_vbox_layout->set_spacing( 10 );
  109.   {
  110.     searchItemsVBox = new Gtk_VBox();
  111.     searchItemsVBox->set_spacing( 10 );
  112.     {
  113.       SearchItem *si = new SearchItem( session, *this, 0 );
  114.       searchItems.push_back( si );
  115.       si->buttonsVisible( true );
  116.       searchItemsVBox->pack_start( *si, FALSE, FALSE, 0 );
  117.     }
  118.     top_vbox_layout->pack_start( *searchItemsVBox, FALSE, FALSE, 0 );
  119.     searchItemsVBox->show();
  120.     // result window
  121.     searchResults = new SearchResults( session, *this );
  122.     top_vbox_layout->pack_start( *searchResults, TRUE, TRUE, 2 );
  123.     // button box
  124.     Gtk_HButtonBox *hbb = new Gtk_HButtonBox();
  125.     hbb->show();
  126.     Gtk_Button *cb = new Gtk_Button( "Close" );
  127.     cb->show();
  128.     hbb->pack_start( *cb );
  129.     connect_to_method( cb->clicked, this, &SearchWindow::callback_close );
  130.     top_vbox_layout->pack_end( *hbb, FALSE, FALSE, 0 );
  131.   }
  132.   add( top_vbox_layout );
  133.   top_vbox_layout->show();
  134.   set_title( "Video client: Search" );
  135. }
  136. void SearchWindow::find_hint_words( int position, GList *&hints )
  137. {
  138.   if( position == 0 && searchItems.size() <= 1 ) // nothing to do 
  139.     return;
  140.   if( position > 0 )
  141.     {
  142.       const string &word = searchItems[ position - 1 ]->get_text();
  143.       session.get_hint_words( word, hints );
  144.     }
  145. }
  146. void SearchWindow::callback_less( int pos )
  147. {
  148.   if( pos != searchItems.size() - 1 || pos == 0 )
  149.     {
  150.       // ups!
  151.       return;
  152.     }
  153.   // delete
  154.   searchItemsVBox->remove( searchItems.back() );
  155.   delete searchItems.back();
  156.   searchItems.pop_back();
  157.   // adjust the last
  158.   if( searchItems.size() > 1 )
  159.     searchItems.back()->lessButVisible( true );
  160.   searchItems.back()->buttonsVisible( true );
  161. }
  162. void SearchWindow::callback_more( int pos )
  163. {
  164.   if( pos != searchItems.size() - 1 )
  165.     {
  166.       // ups!
  167.       return;
  168.     }
  169.   // adjust old
  170.   searchItems.back()->lessButVisible( false );
  171.   searchItems.back()->buttonsVisible( false );
  172.   // add new
  173.   SearchItem *si = new SearchItem( session, *this, searchItems.size() );
  174.   searchItems.push_back( si );
  175.   
  176.   si->boolOpVisible( true );
  177.   si->buttonsVisible( true );
  178.   si->lessButVisible( true );
  179.   si->callback_hint();
  180.   searchItemsVBox->pack_start( *si, FALSE, FALSE, 0 );
  181. }
  182. void SearchWindow::callback_close()
  183. {
  184.   hide();
  185. }
  186. void SearchWindow::callback_search()
  187. {
  188.   // build search structure from window input
  189.   BoolSearchOperation *head = NULL;
  190.   vector< SearchItem * >::iterator it;
  191.   for( it = searchItems.begin(); it != searchItems.end(); it++ )
  192.     {
  193.       SearchItem &item = *(*it);
  194.       string word = item.get_text();
  195.       word.c_str();                   // insert zero at the end
  196.       if( head == NULL )
  197. {
  198.   const WordOccurencesT &wo = session.find_word( word );
  199.   head = new BoolSearchOperationResult( session.get_word_db(), wo );
  200.   continue;
  201. }
  202.       // not the first argument
  203.       const WordOccurencesT &wo = session.find_word( item.get_text() );
  204.       BoolSearchOperation *right = 
  205. new BoolSearchOperationResult( session.get_word_db(), wo );
  206.       head = head->merge_search_items( head, right, item );
  207.     }
  208.   if( !head )
  209.     return;
  210.   // now compute result
  211.   const WordOccurencesT &result = head->get_result();
  212.   // display results
  213.   searchResults->display_results( result );
  214. }
  215. // --------------------------------------------------------------------------
  216. SearchResults::SearchResults( Session &s, SearchWindow &sw )
  217.   : session( s ), searchWindow( sw ), Gtk_CList( 3 )
  218. {
  219.   set_column_title( 0, "Movie" );
  220.   set_column_title( 1, "Time" );
  221.   set_column_title( 2, "Text" );
  222.   column_titles_show();
  223.   set_column_width( 0, col0width );
  224.   set_column_width( 1, col1width );
  225.   set_column_width( 2, col2width );
  226.   show();
  227.   connect_to_method( select_row, this, &SearchResults::callback_select_row );
  228. }
  229. void SearchResults::display_results( const WordOccurencesT &result )
  230. {
  231.   WordOccurences = result;
  232.   clear();
  233.   freeze();
  234.   WordOccurencesT::const_iterator it;
  235.   for( it = result.begin(); it != result.end(); it++ )
  236.     {
  237.       gchar tbl_text[TextColumns][1];
  238.       const gchar *tbl_texts[TextColumns];
  239.       for( int i = 0; i < TextColumns; i++ )
  240. {
  241.   tbl_texts[i] = tbl_text[i];
  242.   tbl_text[i][0] = '';
  243. }
  244.       int row = append( tbl_texts );
  245.       const WordOccurence &wo = *it;
  246.       const MovieItem &mi = session.get_movie_by_id( wo.get_movie_id() );
  247.       
  248.       set_text( row, 0, mi.get_name().c_str() );
  249.       const TextOfMovieT *text = session.get_movie_text( wo.get_movie_id() );
  250.       const struct tm &tim = (*text)[ wo.get_text_line() ].get_time();
  251.       char buf[100];
  252.       snprintf( buf, sizeof( buf ), "%2d/%2d/%4d %2d:%2d:%2d", 
  253. tim.tm_mday, tim.tm_mon + 1, tim.tm_year + 1900, tim.tm_hour, 
  254. tim.tm_min, tim.tm_sec );
  255.       
  256.       set_text( row, 1, buf );
  257.       set_text( row, 2, (*text)[ wo.get_text_line() ].get_text().c_str() );
  258.     }
  259.   thaw();
  260. }
  261. void SearchResults::callback_select_row( gint row, gint col, 
  262.  GdkEvent *_button )
  263. {
  264.   GdkEventButton *button = (GdkEventButton *)_button;
  265.   const WordOccurence &wo = WordOccurences[ row ];
  266.   session.display_movie_text_window_go_line( wo.get_movie_id(),
  267.      wo.get_text_line() );
  268. }