Changeset 10374


Ignore:
Timestamp:
Mar 14, 2010, 5:13:02 AM (11 years ago)
Author:
charles
Message:

(trunk gtk) first draft of a filterbar experiment

Location:
trunk/gtk
Files:
2 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/gtk/Makefile.am

    r10133 r10374  
    4343    details.h \
    4444    dialogs.h \
     45    filter.h \
    4546    hig.h \
    4647    icons.h \
     
    8081    dialogs.c \
    8182    file-list.c \
     83    filter.c \
    8284    hig.c \
    8385    icons.c \
  • trunk/gtk/details.c

    r10351 r10374  
    20982098            di->trackers = NULL;
    20992099            di->tracker_buffer = NULL;
     2100            tr_core_torrent_changed( di->core, tr_torrentId( tor ) );
    21002101        }
    21012102
  • trunk/gtk/tr-core.c

    r10108 r10374  
    16671667    tr_free( json );
    16681668}
     1669
     1670/***
     1671****
     1672***/
     1673
     1674void
     1675tr_core_torrent_changed( TrCore * core, int id )
     1676{
     1677    GtkTreeIter iter;
     1678    GtkTreeModel * model = tr_core_model( core );
     1679
     1680    if( gtk_tree_model_get_iter_first( model, &iter ) ) do
     1681    {
     1682        tr_torrent * tor;
     1683        gtk_tree_model_get( model, &iter, MC_TORRENT_RAW, &tor, -1 );
     1684        if( tr_torrentId( tor ) == id )
     1685        {
     1686            GtkTreePath * path = gtk_tree_model_get_path( model, &iter );
     1687            gtk_tree_model_row_changed( model, path, &iter );
     1688            gtk_tree_path_free( path );
     1689            break;
     1690        }
     1691    }
     1692    while( gtk_tree_model_iter_next( model, &iter ) );
     1693}
     1694
  • trunk/gtk/tr-core.h

    r10031 r10374  
    186186**/
    187187
     188void tr_core_torrent_changed( TrCore * core, int id );
     189
    188190void tr_core_port_test( TrCore * core );
    189191
  • trunk/gtk/tr-window.c

    r10108 r10374  
    3939#include "actions.h"
    4040#include "conf.h"
     41#include "filter.h"
    4142#include "hig.h"
    4243#include "torrent-cell-renderer.h"
     
    110111PrivateData;
    111112
    112 static const char*
    113 getFilterName( int mode )
    114 {
    115     switch( mode )
    116     {
    117         case FILTER_MODE_ACTIVE:      return "show-active";
    118         case FILTER_MODE_DOWNLOADING: return "show-downloading";
    119         case FILTER_MODE_SEEDING:     return "show-seeding";
    120         case FILTER_MODE_PAUSED:      return "show-paused";
    121         default:                      return "show-all"; /* the fallback */
    122     }
    123 }
    124 static int
    125 getFilterModeFromName( const char * name )
    126 {
    127     if( !strcmp( name, "show-active"      ) ) return FILTER_MODE_ACTIVE;
    128     if( !strcmp( name, "show-downloading" ) ) return FILTER_MODE_DOWNLOADING;
    129     if( !strcmp( name, "show-seeding"     ) ) return FILTER_MODE_SEEDING;
    130     if( !strcmp( name, "show-paused"      ) ) return FILTER_MODE_PAUSED;
    131     return FILTER_MODE_ALL; /* the fallback */
    132 }
    133 
    134113#define PRIVATE_DATA_KEY "private-data"
    135 #define FILTER_MODE_KEY "tr-filter-mode"
    136 #define FILTER_TEXT_MODE_KEY "tr-filter-text-mode"
    137114
    138115static PrivateData*
     
    166143}
    167144
    168 static gboolean is_row_visible( GtkTreeModel *,
    169                                 GtkTreeIter  *,
    170                                 gpointer );
    171 
    172145static GtkWidget*
    173 makeview( PrivateData * p,
    174           TrCore *      core )
     146makeview( PrivateData * p )
    175147{
    176148    GtkWidget *         view;
     
    178150    GtkTreeSelection *  sel;
    179151    GtkCellRenderer *   r;
    180     GtkTreeModel *      filter_model;
    181152
    182153    view = gtk_tree_view_new( );
     
    217188
    218189
    219     filter_model = p->filter_model = gtk_tree_model_filter_new(
    220                        tr_core_model( core ), NULL );
    221 
    222     gtk_tree_model_filter_set_visible_func( GTK_TREE_MODEL_FILTER(
    223                                                 filter_model ),
    224                                             is_row_visible,
    225                                             p, NULL );
    226 
    227     gtk_tree_view_set_model( GTK_TREE_VIEW( view ), filter_model );
     190    gtk_tree_view_set_model( GTK_TREE_VIEW( view ), p->filter_model );
    228191
    229192    return view;
     
    231194
    232195static void syncAltSpeedButton( PrivateData * p );
    233 static void setFilter( PrivateData * p, int mode );
    234196
    235197static void
     
    247209         * for that, but it *does* revalidate when it thinks the style's been tweaked */
    248210        g_signal_emit_by_name( p->view, "style-set", NULL, NULL );
    249     }
    250     else if( !strcmp( key, PREF_KEY_FILTER_MODE ) )
    251     {
    252         setFilter( p, getFilterModeFromName( pref_string_get( key ) ) );
    253211    }
    254212    else if( !strcmp( key, PREF_KEY_STATUSBAR ) )
     
    360318***/
    361319
    362 static int
    363 checkFilterText( filter_text_mode_t    filter_text_mode,
    364                  const tr_info       * inf,
    365                  const char          * text )
    366 {
    367     tr_file_index_t i;
    368     int             ret = 0;
    369     char *          pch;
    370 
    371     switch( filter_text_mode )
    372     {
    373         case FILTER_TEXT_MODE_FILES:
    374             for( i = 0; i < inf->fileCount && !ret; ++i )
    375             {
    376                 pch = g_utf8_casefold( inf->files[i].name, -1 );
    377                 ret = !text || strstr( pch, text ) != NULL;
    378                 g_free( pch );
    379             }
    380             break;
    381 
    382         case FILTER_TEXT_MODE_TRACKER:
    383             if( inf->trackerCount > 0 )
    384             {
    385                 pch = g_utf8_casefold( inf->trackers[0].announce, -1 );
    386                 ret = !text || ( strstr( pch, text ) != NULL );
    387                 g_free( pch );
    388             }
    389             break;
    390 
    391         default: /* NAME */
    392             if( !inf->name )
    393                 ret = TRUE;
    394             else {
    395                 pch = g_utf8_casefold( inf->name, -1 );
    396                 ret = !text || ( strstr( pch, text ) != NULL );
    397                 g_free( pch );
    398             }
    399             break;
    400     }
    401 
    402     return ret;
    403 }
    404 
    405 static int
    406 checkFilterMode( filter_mode_t filter_mode,
    407                  tr_torrent *  tor )
    408 {
    409     int ret = 0;
    410 
    411     switch( filter_mode )
    412     {
    413         case FILTER_MODE_DOWNLOADING:
    414             ret = tr_torrentGetActivity( tor ) == TR_STATUS_DOWNLOAD;
    415             break;
    416 
    417         case FILTER_MODE_SEEDING:
    418             ret = tr_torrentGetActivity( tor ) == TR_STATUS_SEED;
    419             break;
    420 
    421         case FILTER_MODE_PAUSED:
    422             ret = tr_torrentGetActivity( tor ) == TR_STATUS_STOPPED;
    423             break;
    424 
    425         case FILTER_MODE_ACTIVE:
    426         {
    427             const tr_stat * s = tr_torrentStatCached( tor );
    428             ret = s->peersSendingToUs > 0
    429                || s->peersGettingFromUs > 0
    430                || tr_torrentGetActivity( tor ) == TR_STATUS_CHECK;
    431             break;
    432         }
    433 
    434         default: /* all */
    435             ret = 1;
    436     }
    437 
    438     return ret;
    439 }
    440 
    441 static gboolean
    442 is_row_visible( GtkTreeModel * model,
    443                 GtkTreeIter *  iter,
    444                 gpointer       vprivate )
    445 {
    446     PrivateData * p = vprivate;
    447     tr_torrent *  tor;
    448 
    449     gtk_tree_model_get( model, iter, MC_TORRENT_RAW, &tor, -1 );
    450 
    451     return checkFilterMode( p->filter_mode, tor )
    452            && checkFilterText( p->filter_text_mode, tr_torrentInfo( tor ), p->filter_text );
    453 }
    454 
    455 static void updateTorrentCount( PrivateData * p );
    456 
    457 static void
    458 refilter( PrivateData * p )
    459 {
    460     gtk_tree_model_filter_refilter( GTK_TREE_MODEL_FILTER( p->filter_model ) );
    461 
    462     updateTorrentCount( p );
    463 }
    464 
    465 static void
    466 filter_text_toggled_cb( GtkCheckMenuItem * menu_item,
    467                         gpointer           vprivate )
    468 {
    469     if( gtk_check_menu_item_get_active( menu_item ) )
    470     {
    471         PrivateData * p = vprivate;
    472         p->filter_text_mode =
    473             GPOINTER_TO_UINT( g_object_get_data( G_OBJECT( menu_item ),
    474                                                  FILTER_TEXT_MODE_KEY ) );
    475         refilter( p );
    476     }
    477 }
    478 
    479 static void
    480 setFilter( PrivateData * p, int mode )
    481 {
    482     if( mode != (int)p->filter_mode )
    483     {
    484         int i;
    485 
    486         /* refilter */
    487         p->filter_mode = mode;
    488         refilter( p );
    489 
    490         /* update the prefs */
    491         tr_core_set_pref( p->core, PREF_KEY_FILTER_MODE, getFilterName( mode ) );
    492 
    493         /* update the togglebuttons */
    494         for( i=0; i<FILTER_MODE_QTY; ++i )
    495             gtk_toggle_button_set_active( p->filter_toggles[i], i==mode );
    496     }
    497 }
    498 
    499 
    500 static void
    501 filter_toggled_cb( GtkToggleButton * toggle, gpointer vprivate )
    502 {
    503     if( gtk_toggle_button_get_active( toggle ) )
    504     {
    505         PrivateData * p = vprivate;
    506         const int mode = GPOINTER_TO_UINT( g_object_get_data( G_OBJECT( toggle ), FILTER_MODE_KEY ) );
    507         setFilter( p, mode );
    508     }
    509 }
    510 
    511 static void
    512 filter_entry_changed( GtkEditable * e,
    513                       gpointer      vprivate )
    514 {
    515     char *        pch;
    516     PrivateData * p = vprivate;
    517 
    518     pch = gtk_editable_get_chars( e, 0, -1 );
    519     g_free( p->filter_text );
    520     p->filter_text = g_utf8_casefold( pch, -1 );
    521     refilter( p );
    522     g_free( pch );
    523 }
    524 
    525 
    526 #ifdef USE_SEXY
    527 static void
    528 entry_icon_released( SexyIconEntry           * entry  UNUSED,
    529                      SexyIconEntryPosition     icon_pos,
    530                      int                       button UNUSED,
    531                      gpointer                  menu )
    532 {
    533     if( icon_pos == SEXY_ICON_ENTRY_PRIMARY )
    534         gtk_menu_popup( GTK_MENU( menu ), NULL, NULL, NULL, NULL, 0,
    535                         gtk_get_current_event_time( ) );
    536 }
    537 #else
    538 static void
    539 entry_icon_release( GtkEntry              * entry  UNUSED,
    540                     GtkEntryIconPosition    icon_pos,
    541                     GdkEventButton        * event  UNUSED,
    542                     gpointer                menu )
    543 {
    544     if( icon_pos == GTK_ENTRY_ICON_SECONDARY )
    545         gtk_entry_set_text( entry, "" );
    546 
    547     if( icon_pos == GTK_ENTRY_ICON_PRIMARY )
    548         gtk_menu_popup( GTK_MENU( menu ), NULL, NULL, NULL, NULL, 0,
    549                         gtk_get_current_event_time( ) );
    550 }
    551 #endif
    552 
    553320#if GTK_CHECK_VERSION( 2, 12, 0 )
    554321
     
    836603    PrivateData * p;
    837604    GtkWidget   * mainmenu, *toolbar, *filter, *list, *status;
    838     GtkWidget   * vbox, *w, *self, *h, *s, *hbox, *menu;
     605    GtkWidget   * vbox, *w, *self, *h, *hbox, *menu;
    839606    GtkWindow   * win;
    840607    GSList      * l;
    841 
    842     const char *  filter_names[FILTER_MODE_QTY] = {
    843         /* show all torrents */
    844         N_( "A_ll" ),
    845         /* show only torrents that have connected peers */
    846         N_( "_Active" ),
    847         /* show only torrents that are trying to download */
    848         N_( "_Downloading" ),
    849         /* show only torrents that are trying to upload */
    850         N_( "_Seeding" ),
    851         /* show only torrents that are paused */
    852         N_( "_Paused" )
    853     };
    854     const char *  filter_text_names[FILTER_TEXT_MODE_QTY] = {
    855         N_( "Name" ), N_( "Files" ), N_( "Tracker" )
    856     };
    857608
    858609    p = g_new0( PrivateData, 1 );
     
    894645
    895646    /* filter */
    896     h = filter = p->filter = gtk_hbox_new( FALSE, 0 );
     647    h = filter = p->filter = gtr_filter_bar_new( tr_core_model( core ), &p->filter_model );
    897648    gtk_container_set_border_width( GTK_CONTAINER( h ), GUI_PAD_SMALL );
    898     for( i = 0; i < FILTER_MODE_QTY; ++i )
    899     {
    900         const char * mnemonic = _( filter_names[i] );
    901         w = gtk_toggle_button_new_with_mnemonic( mnemonic );
    902         g_object_set_data( G_OBJECT( w ), FILTER_MODE_KEY, GINT_TO_POINTER( i ) );
    903         gtk_button_set_relief( GTK_BUTTON( w ), GTK_RELIEF_NONE );
    904         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( w ), i == FILTER_MODE_ALL );
    905         p->filter_toggles[i] = GTK_TOGGLE_BUTTON( w );
    906         g_signal_connect( w, "toggled", G_CALLBACK( filter_toggled_cb ), p );
    907         gtk_box_pack_start( GTK_BOX( h ), w, FALSE, FALSE, 0 );
    908     }
    909 
    910 #ifdef USE_SEXY
    911     s = sexy_icon_entry_new( );
    912     sexy_icon_entry_add_clear_button( SEXY_ICON_ENTRY( s ) );
    913     w = gtk_image_new_from_stock( GTK_STOCK_FIND, GTK_ICON_SIZE_MENU );
    914     sexy_icon_entry_set_icon( SEXY_ICON_ENTRY( s ),
    915                               SEXY_ICON_ENTRY_PRIMARY,
    916                               GTK_IMAGE( w ) );
    917     g_object_unref( w );
    918     sexy_icon_entry_set_icon_highlight( SEXY_ICON_ENTRY( s ),
    919                                         SEXY_ICON_ENTRY_PRIMARY, TRUE );
    920 #else
    921     s = gtk_entry_new( );
    922     gtk_entry_set_icon_from_stock( GTK_ENTRY( s ),
    923                                    GTK_ENTRY_ICON_PRIMARY,
    924                                    GTK_STOCK_FIND);
    925    gtk_entry_set_icon_from_stock( GTK_ENTRY( s ),
    926                                   GTK_ENTRY_ICON_SECONDARY,
    927                                   GTK_STOCK_CLEAR );
    928 #endif
    929     gtk_box_pack_end( GTK_BOX( h ), s, FALSE, FALSE, 0 );
    930     g_signal_connect( s, "changed", G_CALLBACK( filter_entry_changed ), p );
    931649
    932650    /* status menu */
     
    1007725
    1008726
    1009     menu = gtk_menu_new( );
    1010     l = NULL;
    1011     for( i=0; i<FILTER_TEXT_MODE_QTY; ++i )
    1012     {
    1013         const char * name = _( filter_text_names[i] );
    1014         GtkWidget *  w = gtk_radio_menu_item_new_with_label ( l, name );
    1015         l = gtk_radio_menu_item_get_group( GTK_RADIO_MENU_ITEM( w ) );
    1016         g_object_set_data( G_OBJECT( w ), FILTER_TEXT_MODE_KEY,
    1017                            GINT_TO_POINTER( i ) );
    1018         g_signal_connect( w, "toggled",
    1019                           G_CALLBACK( filter_text_toggled_cb ), p );
    1020         gtk_menu_shell_append( GTK_MENU_SHELL( menu ), w );
    1021         gtk_widget_show( w );
    1022     }
    1023 
    1024 #ifdef USE_SEXY
    1025     g_signal_connect( s, "icon-released", G_CALLBACK( entry_icon_released ), menu );
    1026 #else
    1027     g_signal_connect( s, "icon-release", G_CALLBACK( entry_icon_release ), menu );
    1028 
    1029 #endif
    1030 
    1031727    /* workarea */
    1032     p->view = makeview( p, core );
     728    p->view = makeview( p );
    1033729    w = list = p->scroll = gtk_scrolled_window_new( NULL, NULL );
    1034730    gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( w ),
     
    1090786    tr_sessionSetAltSpeedFunc( tr_core_session( core ), onAltSpeedToggled, p );
    1091787
    1092     filter_entry_changed( GTK_EDITABLE( s ), p );
    1093788    return self;
    1094789}
     
    1209904        updateTorrentCount( p );
    1210905        updateStats( p );
    1211         refilter( p );
     906        gtk_tree_model_filter_refilter( GTK_TREE_MODEL_FILTER( p->filter_model ) );
    1212907    }
    1213908}
Note: See TracChangeset for help on using the changeset viewer.