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

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  <assert.h>
  7. #include  <unistd.h>
  8. #include  <sys/types.h>
  9. #include  <stdlib.h>
  10. #include  <vector>
  11. #include  <map>
  12. #include  <gtk--.h>
  13. #include "movie_item.h"
  14. #include "gtk_main_win.h"
  15. #include "session.h"
  16. int main( int argc, char **argv )
  17. {
  18.   Session s( &argc, &argv );
  19.   gtk_debug_flags = 0xffffffff;
  20.   s.run();
  21.   return 0;
  22. }
  23. // ====================== Main window implementation =====================
  24. MainWindow::MainWindow( Session &s ) : session( s ), statusBarContextId( 0 )
  25. {
  26.   // make vertical box
  27.   Gtk_VBox *top_vbox_layout = new Gtk_VBox();
  28.   {
  29.     // create menu bar
  30.     menuBar = new Gtk_MenuBar();
  31.     menuBar->show();
  32.     // create menu 'File'
  33.     Gtk_MenuItem *fileMenuRootItem = new Gtk_MenuItem( "File" );
  34.     menuBar->append( *fileMenuRootItem );
  35.     Gtk_Menu     *fileMenu = new Gtk_Menu();
  36.     fileMenuRootItem->set_submenu( *fileMenu );
  37.     fileMenuRootItem->show();
  38.     
  39.     Gtk_MenuItem *searchMenuItem = new Gtk_MenuItem( "Search" );
  40.     fileMenu->append( *searchMenuItem );
  41.     searchMenuItem->show();
  42.     Gtk_MenuItem *exitMenuItem = new Gtk_MenuItem( "Exit" );
  43.     fileMenu->append( *exitMenuItem );
  44.     exitMenuItem->show();
  45.     
  46.     // connect entries
  47.     connect_to_method( searchMenuItem->activate, &session, 
  48.        &Session::callback_search );
  49.     connect_to_method( exitMenuItem->activate, this, 
  50.        &MainWindow::callback_exit );
  51.     // create menu 'Edit'
  52.     Gtk_MenuItem *editMenuRootItem = new Gtk_MenuItem( "Edit" );
  53.     menuBar->append( *editMenuRootItem );
  54.     // editMenu is the class member. Superuser will use it
  55.     editMenu = new Gtk_Menu();
  56.     editMenuRootItem->set_submenu( *editMenu );
  57.     editMenuRootItem->show();
  58.     
  59.     Gtk_MenuItem *editPrefMenuItem = new Gtk_MenuItem( "Preferences..." );
  60.     editMenu->append( *editPrefMenuItem );
  61.     editPrefMenuItem->show();
  62.     
  63.     // connect entries
  64.     connect_to_method( editPrefMenuItem->activate, this, 
  65.        &MainWindow::callback_preferences );
  66.     // create menu 'Options'
  67.     Gtk_MenuItem *optionsMenuRootItem = new Gtk_MenuItem( "Options" );
  68.     menuBar->append( *optionsMenuRootItem );
  69.     Gtk_Menu     *optionsMenu = new Gtk_Menu();
  70.     optionsMenuRootItem->set_submenu( *optionsMenu );
  71.     optionsMenuRootItem->show();
  72.     Gtk_MenuItem *suMenuItem = 
  73.       new Gtk_MenuItem( "Login as superuser..." );
  74.     optionsMenu->append( *suMenuItem );
  75.     suMenuItem->show();
  76.     // connect entries
  77.     connect_to_method( suMenuItem->activate, &session, 
  78.        &Session::callback_superuser );
  79.     // create menu 'View'
  80.     Gtk_MenuItem *viewMenuRootItem = new Gtk_MenuItem( "View" );
  81.     menuBar->append( *viewMenuRootItem );
  82.     Gtk_Menu     *viewMenu = new Gtk_Menu();
  83.     viewMenuRootItem->set_submenu( *viewMenu );
  84.     viewMenuRootItem->show();
  85.     Gtk_MenuItem *menuItemBr = new Gtk_MenuItem( "Broadcast..." );
  86.     viewMenu->append( *menuItemBr );
  87.     menuItemBr->show();
  88.     
  89.     // connect entries
  90.     connect_to_method( menuItemBr->activate, &session, 
  91.        &Session::callback_broadcast );
  92.     // pack to vbox container
  93.     top_vbox_layout->pack_start( *menuBar, FALSE, FALSE, 0 );
  94.     // status bar
  95.     statusBar = new Gtk_Statusbar();
  96.     top_vbox_layout->pack_end( *statusBar, FALSE, FALSE, 0 );
  97.     statusBar->show();
  98.     // scroll window for log
  99.     Gtk_ScrolledWindow *scrw = new Gtk_ScrolledWindow();
  100.     scrw->set_usize( session.topWindowInitSizeX, 
  101.      session.topWindowInitSizeY/4 );
  102.     scrw->show();
  103.     // log window
  104.     logText = new Gtk_Text();
  105.     logText->set_usize( session.topWindowInitSizeX, 
  106. session.topWindowInitSizeY*10 );
  107.     logText->show();
  108.     logText->set_editable( false );
  109.     scrw->add( logText );
  110.     // make horizontal layout: movies list and short description
  111.     Gtk_HBox *hbox_movie_layout = new Gtk_HBox();
  112.     hbox_movie_layout->show();
  113.     // pack hbox_movie_layout and logText to vertical pane
  114.     Gtk_VPaned *vp = new Gtk_VPaned();
  115.     top_vbox_layout->pack_start( *vp, TRUE, TRUE, 0 );
  116.     vp->show();
  117.     vp->add1( *hbox_movie_layout );
  118.     vp->add2( *scrw );
  119.     // block for hbox_movie_layout
  120.     {
  121.       Gtk_VBox *mov_box = new Gtk_VBox( FALSE, 10 );
  122.       mov_box->set_spacing( 10 );
  123.       mov_box->show();
  124.       // list
  125.       static char *text[movieListColumns] = { "", "Title", "date" };
  126.       GtkWidget *clist;
  127.       clist = gtk_clist_new_with_titles( movieListColumns, text );
  128.       movieList = new Gtk_CList( GTK_CLIST (clist) );
  129.       movieList->set_usize( session.topWindowInitSizeX/2, 
  130.     session.topWindowInitSizeY/2 );
  131.       movieList->set_column_width( 0, 10 );
  132.       movieList->set_column_width( 1, session.topWindowInitSizeX/4 );
  133.       movieList->show();
  134.       // movieList is inside the scrolled window
  135.       Gtk_ScrolledWindow *scrolled_win = new Gtk_ScrolledWindow ();
  136.       scrolled_win->show();
  137.       scrolled_win->set_policy (GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
  138.       scrolled_win->add( *movieList );
  139.       mov_box->pack_start( *scrolled_win, TRUE, TRUE, 0 );
  140.       // callback 
  141.       connect_to_method( movieList->select_row, this, 
  142.  &MainWindow::callback_movie_select_row );
  143.       connect_to_method( movieList->button_press_event, this, 
  144.  &MainWindow::callback_movie_button_press );
  145.       movieList->set_selection_mode( GTK_SELECTION_BROWSE );
  146.       
  147.       // add paned
  148.       Gtk_HPaned *hp = new Gtk_HPaned();
  149.       hbox_movie_layout->pack_start( *hp, TRUE, TRUE, 0 );
  150.       hp->show();
  151.       // the right of paned vbox is located
  152.       Gtk_VBox *vbox = new Gtk_VBox( FALSE, 0 );
  153.       vbox->show();
  154.       // paned childrens attached
  155.       hp->add1( *mov_box );
  156.       hp->add2( *vbox );
  157.       {
  158. // caption
  159. dbNameLabel = new Gtk_Label( "Not connected" );
  160. vbox->pack_start( *dbNameLabel, FALSE, FALSE, 0 );
  161. dbNameLabel->show();
  162. // name
  163. dbMovieName = new Gtk_Text();
  164. dbMovieName->set_usize( session.topWindowInitSizeX/2, 
  165. session.topWindowInitSizeY/12 );
  166. vbox->pack_start( *dbMovieName, FALSE, FALSE, 0 );
  167. dbMovieName->show();
  168. // comments
  169. comments = new Gtk_Text();
  170. comments->set_usize( session.topWindowInitSizeX/2, 
  171. session.topWindowInitSizeY/6 );
  172. vbox->pack_start( *comments, FALSE, FALSE, 0 );
  173. comments->show();
  174. // recorded at
  175. dbStartTime = new Gtk_Label( "" );
  176. vbox->pack_start( *dbStartTime, FALSE, FALSE, 0 );
  177. dbStartTime->show();
  178. // duration
  179. dbDuration = new Gtk_Label( "" );
  180. vbox->pack_start( *dbDuration, FALSE, FALSE, 0 );
  181. dbDuration->show();
  182. // make horizontal layout
  183. Gtk_HBox *hbox_db1 = new Gtk_HBox();
  184. hbox_db1->show();
  185. vbox->pack_start( *hbox_db1, FALSE, FALSE, 0 );
  186. {
  187.   Gtk_Label *l = new Gtk_Label( "Database name" );
  188.   l->show();
  189.   hbox_db1->pack_start( *l, FALSE, FALSE, 0 );
  190.   Gtk_Button *b = new Gtk_Button( "Connect" );
  191.   b->show();
  192.   hbox_db1->pack_end( *b, FALSE, FALSE, 0 );
  193.   connect_to_method( b->clicked, this, 
  194.      &MainWindow::callback_dbname );
  195. }
  196. // make horizontal layout
  197. Gtk_HBox *hbox_db2 = new Gtk_HBox();
  198. hbox_db2->show();
  199. vbox->pack_start( *hbox_db2, FALSE, FALSE, 0 );
  200. {
  201.   // database name 
  202.   dbNameText = new Gtk_Entry();
  203.   dbNameText->set_editable( true );
  204.   dbNameText->show();
  205.   hbox_db2->pack_start( *dbNameText, FALSE, FALSE, 0 );
  206. }
  207. // button to toggle if the log follows the last line
  208. toggleLogAuto = new Gtk_ToggleButton( "Auto scroll" );
  209. toggleLogAuto->show();
  210. toggleLogAuto->set_mode( true );
  211. vbox->pack_end( *toggleLogAuto, FALSE, FALSE, 0 );
  212.       }
  213.     }
  214.     top_vbox_layout->show();
  215.   }
  216.   add( top_vbox_layout );
  217.   top_vbox_layout->show();
  218.   // callback to destroy session
  219.   connect_to_method( destroy, &session, 
  220.      &Session::callback_destroy_session );
  221.   // other...
  222.   movieListCurrentlySelectedMovie = -1;
  223.   set_title( "Video client" );
  224.   // create pixmaps and bitmaps for bullets
  225.   {
  226.     string pmp_name_loaded = session.loadedPixmap.c_str();
  227.     string pmp_name_notloaded = session.notLoadedPixmap.c_str();
  228.     textLoadedPixmap = new Gtk_Pixmap( *movieList, pmp_name_loaded );
  229.     textNotLoadedPixmap = new Gtk_Pixmap( *movieList, pmp_name_notloaded );
  230. //     textLoadedBitmap = new Gdk_Bitmap();
  231. //     textLoadedPixmap = new Gdk_Pixmap( *movieList->get_window(), 
  232. //         *textLoadedBitmap, 
  233. //         Gdk_Color( "white" ), 
  234. //         pmp_name_loaded );
  235. //     textNotLoadedBitmap = new Gdk_Bitmap();
  236. //     textLoadedPixmap = new Gdk_Pixmap( *movieList->get_window(), 
  237. //         *textNotLoadedBitmap,
  238. //         Gdk_Color( "white" ), 
  239. //         pmp_name_notloaded );
  240.   }
  241. }
  242. MainWindow::~MainWindow()
  243. {
  244. }
  245. gint MainWindow::delete_event_impl( GdkEventAny * )
  246. {
  247.   session.cleanup();
  248.   Gtk_Main::instance()->quit(); 
  249.   return 0;
  250. }
  251. void MainWindow::callback_exit()
  252. {
  253.   session.cleanup();
  254.   Gtk_Main::instance()->quit(); 
  255. }
  256. void MainWindow::callback_movie_select_row
  257. ( gint row, gint col, GdkEvent *_button )
  258. {
  259.   GdkEventButton *button = (GdkEventButton *)_button;
  260.   int id = (int) movieList->get_row_data( row );
  261.   const MovieItem &mi = session.get_movie_by_id( id );
  262.   // if user click to first column, insert movie text into search
  263.   // database
  264.   if( col == 0 )
  265.     {
  266.       session.get_movie_text( id );
  267.       update_pixmap( row );
  268.     }
  269.   movieListCurrentlySelectedMovie = id;
  270.   // display this movie info
  271.   dbMovieName->set_point( 0 );
  272.   dbMovieName->forward_delete( dbMovieName->get_length() );
  273.   dbMovieName->insert( Gdk_Font(), Gdk_Color( "black" ), Gdk_Color( "white" ),
  274.        mi.get_name(), mi.get_name().length() );
  275.   // comments
  276.   comments->set_point( 0 );
  277.   comments->forward_delete( comments->get_length() );
  278.   comments->insert( Gdk_Font(), Gdk_Color( "black" ), Gdk_Color( "white" ), 
  279.     mi.get_comments(), mi.get_comments().length() );
  280.   // display time
  281.   const struct tm &t = mi.get_start();
  282.   const struct tm &t2 = mi.get_stop();
  283.   time_t tt1 = mktime( (struct tm *) &t );
  284.   time_t tt2 = mktime( (struct tm *) &t2 );
  285.   string s = string( "Recorded at " ) + asctime( &t );
  286.   dbStartTime->set_text( s );
  287.   int dt = (int) difftime( tt2, tt1 );
  288.   char buf[200];
  289.   sprintf( buf, "Duration is %2dh:%2dm:%2ds", dt / 3600, dt % 3600 / 60,
  290.    dt % 60 );
  291.   dbDuration->set_text( buf );
  292. }
  293. gint MainWindow::callback_movie_button_press( GdkEventButton *event )
  294. {
  295.   if( event->type==GDK_2BUTTON_PRESS )
  296.     {
  297.       session.display_movie_text_window( movieListCurrentlySelectedMovie );
  298.     }
  299.   return FALSE;
  300. }
  301. void MainWindow::callback_preferences()
  302. {
  303.   session.edit_preferences();
  304. }
  305. void MainWindow::callback_dbname()
  306. {
  307.   string dbname = dbNameText->get_text();
  308.   dbname.c_str();
  309.   session.update_movie_list( dbname );
  310. }
  311. // ------------------------------------------------------
  312. void MainWindow::display_database_name( string &dbname )
  313. {
  314.   dbNameLabel->set_text( string("Connected to ") + dbname );
  315.   dbNameText->set_text( dbname );
  316. }
  317. void MainWindow::show_superuser_status( bool status )
  318. {
  319.   if( statusBarContextId == 0 )
  320.     statusBarContextId = statusBar->get_context_id( "superuser" );
  321.   if( status )
  322.     statusBar->push( statusBarContextId, "Superuser" );
  323.   else
  324.     statusBar->pop( statusBarContextId );
  325. }
  326. void MainWindow::status_changed_to_superuser( bool status )
  327. {
  328.   Gtk_MenuItem *menuItem = new Gtk_MenuItem( "Server preferences..." );
  329.   editMenu->append( *menuItem );
  330.   menuItem->show();
  331.     
  332.   // connect entries
  333.   connect_to_method( menuItem->activate, &session, 
  334.      &Session::callback_server_preferences );
  335. }
  336. void MainWindow::update_movie_list( CMapOfMoviesT &movies )
  337. {
  338.   char text[movieListColumns][100];
  339.   const gchar *texts[movieListColumns];
  340.   for( int i = 0; i < movieListColumns; i++ )
  341.     texts[i] = text[i];
  342.   movieList->freeze();
  343.   // destroy
  344.   movieList->clear();
  345.   // add
  346.   CMapOfMoviesT::const_iterator it;
  347.   for( it = movies.begin(); it != movies.end(); it ++ )
  348.     {
  349.       const MovieItem &mi = (*it).second;
  350.       const struct tm &t = mi.get_start();
  351.       // insert new row
  352.       *text[0] = '';
  353.       strcpy( text[1], (char *) mi.get_name().c_str() );
  354.       sprintf( text[2], "%2d/%2d/%2d", t.tm_mon+1, t.tm_mday, t.tm_year );
  355.       int row = movieList->append( texts );
  356.       // pixmap
  357.       Gdk_Pixmap pixmap;
  358.       Gdk_Bitmap bitmap;
  359.       string pmp_name;
  360.       if( session.is_movie_text_loaded( (*it).first ) )
  361. textLoadedPixmap->get( pixmap, bitmap );
  362.       else 
  363. textNotLoadedPixmap->get( pixmap, bitmap );
  364.       movieList->set_pixmap( row, 0, pixmap, bitmap );
  365.       // row data
  366.       movieList->set_row_data( row, (gpointer) (*it).first );
  367.     }
  368.   movieList->thaw();
  369. }
  370. void MainWindow::update_pixmap( int row )
  371. {
  372.   int id = (int) movieList->get_row_data( row );
  373.   
  374.   // pixmap
  375.   Gdk_Pixmap pixmap;
  376.   Gdk_Bitmap bitmap;
  377.   if( !session.is_movie_text_loaded( id ))
  378.     return;
  379.   textLoadedPixmap->get( pixmap, bitmap );
  380.   movieList->set_pixmap( row, 0, pixmap, bitmap );
  381. }
  382. void MainWindow::update_pixmap_by_id( int id )
  383. {
  384.   int row = movieList->find_row_from_data( (gpointer) id );
  385.   if( row >= 0 )
  386.     update_pixmap( row );
  387. }
  388. // ------------------------------------------------------
  389. void MainWindow::display_message( const string &msg )
  390. {
  391.   logText->insert( Gdk_Font(), msg[0]=='#'? msg[1]=='!'? Gdk_Color( "red" ):
  392.    Gdk_Color( "green" ): Gdk_Color( "black" ), 
  393.    Gdk_Color( "white" ), msg, msg.length() );
  394.   if( toggleLogAuto->get_mode() == false )
  395.     return;
  396.   // auto scroll
  397.   logText->set_point( logText->get_length() );
  398. }
  399. void MainWindow::display_messagenl( const string &msg )
  400. {
  401.   display_message( msg );
  402.   if( msg[ msg.length() - 1 ] != 'n' )
  403.     display_message( "n" );
  404. }
  405. void MainWindow::display_messages( const vector< string > &msgs )
  406. {
  407.   for( int i = 0; i < msgs.size(); i++ )
  408.     display_messagenl( msgs[ i ] );
  409. }