~ubuntu-branches/ubuntu/precise/gmlive/precise

« back to all changes in this revision

Viewing changes to src/channel.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Aron Xu
  • Date: 2010-01-28 10:02:52 UTC
  • Revision ID: james.westby@ubuntu.com-20100128100252-b0yb0n4zm7s85ce7
Tags: upstream-0.22.2
Import upstream version 0.22.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * =====================================================================================
 
3
 *
 
4
 *       Filename:  channel.cpp
 
5
 *
 
6
 *    Description:  频道列表
 
7
 *
 
8
 *        Version:  1.0
 
9
 *        Created:  2007年12月01日 19时25分31秒 CST
 
10
 *       Revision:  none
 
11
 *       Compiler:  gcc
 
12
 *
 
13
 *         Author:  lerosua (), lerosua@gmail.com
 
14
 *        Company:  Cyclone
 
15
 *
 
16
 * =====================================================================================
 
17
 */
 
18
 
 
19
 
 
20
#include <sstream>
 
21
#include "channel.h"
 
22
#include "MainWindow.h"
 
23
#include "livePlayer.h"
 
24
#include "recentchannel.h"
 
25
#include "bookmarkchannel.h"
 
26
#include "ChannelsTooltips.h"
 
27
#include <cassert>
 
28
#include <glib/gi18n.h>
 
29
 
 
30
Channel::Channel(MainWindow* parent_):parent( parent_)
 
31
{
 
32
        set_flags(Gtk::CAN_FOCUS);
 
33
        set_rules_hint(false);
 
34
 
 
35
        tooltips = new ChannelsTooltips(this);
 
36
 
 
37
        m_liststore = Gtk::TreeStore::create(columns);
 
38
        Glib::RefPtr<Gtk::TreeModelFilter> filter = 
 
39
                Gtk::TreeModelFilter::create(m_liststore);
 
40
        //filter->set_visible_column(1);
 
41
        set_model(filter);
 
42
 
 
43
        append_column(_("channels"), columns.name);
 
44
        append_column(_("bitrate"), columns.freq);
 
45
        append_column(_("user"), columns.users);
 
46
 
 
47
        /*
 
48
        set_has_tooltip();
 
49
        set_tooltip_window(*tooltips);
 
50
        signal_query_tooltip().connect(sigc::mem_fun(*this,
 
51
                                &Channel::on_tooltip_show));
 
52
        */
 
53
        signal_motion_notify_event().
 
54
                connect(sigc::mem_fun(*this, &Channel::on_motion_event),
 
55
                                false);
 
56
        signal_leave_notify_event().
 
57
                connect(sigc::mem_fun(*this, &Channel::on_leave_event),
 
58
                                false);
 
59
 
 
60
        filter->set_visible_func(sigc::mem_fun(*this, &Channel::on_visible_func));
 
61
 
 
62
        show();
 
63
}
 
64
 
 
65
Channel::~Channel()
 
66
{
 
67
}
 
68
 
 
69
 
 
70
Gtk::TreeModel::iterator Channel::getListIter(Gtk::TreeModel::
 
71
                Children children, const std::string& groupname)
 
72
{
 
73
        return find_if(children.begin(),
 
74
                        children.end(),
 
75
                        bind2nd(CompareChannel(columns),groupname));
 
76
}
 
77
Gtk::TreeModel::iterator Channel::addGroup(const Glib::ustring& group)
 
78
{
 
79
        Gtk::TreeModel::iterator iter = m_liststore->append();
 
80
        (*iter)[columns.name] = group;
 
81
        (*iter)[columns.type]=GROUP_CHANNEL;
 
82
 
 
83
        return iter;
 
84
}
 
85
 
 
86
bool Channel::on_button_press_event(GdkEventButton * ev)
 
87
{
 
88
        bool result = Gtk::TreeView::on_button_press_event(ev);
 
89
 
 
90
        Glib::RefPtr < Gtk::TreeSelection > selection =
 
91
                this->get_selection();
 
92
        Gtk::TreeModel::iterator iter = selection->get_selected();
 
93
        if (!selection->count_selected_rows())
 
94
                return result;
 
95
 
 
96
        Gtk::TreeModel::Path path(iter);
 
97
        Gtk::TreeViewColumn * tvc;
 
98
        int cx, cy;
 
99
        /** get_path_at_pos() 是为确认鼠标是否在选择行上点击的*/
 
100
        if (!this->
 
101
                        get_path_at_pos((int) ev->x, (int) ev->y, path, tvc, cx, cy))
 
102
                return false;
 
103
 
 
104
        if ((ev->type == GDK_2BUTTON_PRESS ||
 
105
                                ev->type == GDK_3BUTTON_PRESS) && ev->button != 3) {
 
106
                if(GROUP_CHANNEL != (*iter)[columns.type]){
 
107
                        parent->get_gmplayer()->set_record(false);
 
108
                        play_selection_iter(iter);
 
109
                }
 
110
                else {
 
111
                        if(this->row_expanded(path))
 
112
                                this->collapse_row(path);
 
113
                        else{
 
114
                                this->expand_row(path,false);
 
115
                                this->scroll_to_row(path);
 
116
                        }
 
117
                }
 
118
        } else if ((ev->type == GDK_BUTTON_PRESS)
 
119
                        && (ev->button == 3)) {
 
120
                if(GROUP_CHANNEL == (*iter)[columns.type])
 
121
                        return false;
 
122
                Gtk::Menu* pop_menu = 
 
123
                        parent->get_channels_pop_menu();
 
124
                if (pop_menu)
 
125
                        pop_menu->popup(ev->button, ev->time);
 
126
                return true;
 
127
        }
 
128
        return false;
 
129
}
 
130
 
 
131
void Channel::play_selection()
 
132
{
 
133
        Glib::RefPtr < Gtk::TreeSelection > selection =
 
134
                this->get_selection();
 
135
        Gtk::TreeModel::iterator iter = selection->get_selected();
 
136
        if (!selection->count_selected_rows()) {
 
137
                return ;
 
138
        }
 
139
        
 
140
        if(GROUP_CHANNEL != (*iter)[columns.type]) {
 
141
                parent->get_gmplayer()->set_record(false);
 
142
                play_selection_iter(iter);
 
143
        }
 
144
 
 
145
}
 
146
 
 
147
 
 
148
void Channel::record_selection()
 
149
{
 
150
        Glib::RefPtr < Gtk::TreeSelection > selection =
 
151
                this->get_selection();
 
152
        Gtk::TreeModel::iterator iter = selection->get_selected();
 
153
        if (!selection->count_selected_rows()) {
 
154
                return ;
 
155
        }
 
156
 
 
157
        if(GROUP_CHANNEL != (*iter)[columns.type]) {
 
158
                Gtk::FileChooserDialog dlg(*parent,
 
159
                                _("Choose File"), 
 
160
                                Gtk::FILE_CHOOSER_ACTION_SAVE);
 
161
                dlg.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
 
162
                dlg.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK);
 
163
                if (Gtk::RESPONSE_OK == dlg.run()) {
 
164
                        Glib::ustring outfilename = dlg.get_filename();
 
165
                        if (outfilename.empty())
 
166
                                return;
 
167
                        GMplayer* player = parent->get_gmplayer();
 
168
                        if (player->recording())
 
169
                                return;
 
170
                        player->set_record(true);
 
171
                        const Glib::ustring& name= (*iter)[columns.name];
 
172
                        player->set_outfilename(outfilename, name);
 
173
                        play_selection_iter(iter);
 
174
                }
 
175
        }
 
176
}
 
177
 
 
178
std::string Channel::get_stream()
 
179
{
 
180
        Glib::RefPtr < Gtk::TreeSelection > selection =
 
181
                this->get_selection();
 
182
        Gtk::TreeModel::iterator iter = selection->get_selected();
 
183
        if (!selection->count_selected_rows())
 
184
                return std::string();
 
185
        return (*iter)[columns.stream];
 
186
}
 
187
 
 
188
void Channel::store_selection()
 
189
{
 
190
        Glib::RefPtr < Gtk::TreeSelection > selection =
 
191
                this->get_selection();
 
192
        Gtk::TreeModel::iterator iter = selection->get_selected();
 
193
        if (!selection->count_selected_rows())
 
194
                return ;
 
195
        TypeChannel page = (*iter)[columns.type];
 
196
        Glib::ustring name = (*iter)[columns.name];
 
197
        std::string stream = (*iter)[columns.stream];
 
198
 
 
199
        BookMarkChannel* bc =
 
200
                dynamic_cast<BookMarkChannel*>(parent->get_bookmark_channel());
 
201
        if (this != bc)
 
202
                bc->saveLine(name,stream,page,"TOP");
 
203
 
 
204
#if 0
 
205
        RecentChannel* rc =
 
206
                dynamic_cast<RecentChannel*>(parent->get_recent_channel());
 
207
        if (this != rc)
 
208
                rc->saveLine(name,stream,page);
 
209
#endif
 
210
}
 
211
 
 
212
void Channel::store_selection_group()
 
213
{
 
214
        /** 如果本频道是书签或最近列表,都不启动此功能*/
 
215
        BookMarkChannel* bc =
 
216
                dynamic_cast<BookMarkChannel*>(parent->get_bookmark_channel());
 
217
        if (this == bc)
 
218
                return;
 
219
        RecentChannel* rc =
 
220
                dynamic_cast<RecentChannel*>(parent->get_recent_channel());
 
221
        if (this == rc)
 
222
                return;
 
223
 
 
224
 
 
225
        Glib::RefPtr < Gtk::TreeSelection > selection =
 
226
                this->get_selection();
 
227
        Gtk::TreeModel::iterator iter = selection->get_selected();
 
228
        if (!selection->count_selected_rows())
 
229
                return ;
 
230
        /** 利用 *iter 获取 row,然后用row.parent()的方法获取了它的父iter,也就是所在的组
 
231
         *  这就是由当前行获取其父组的方法 */
 
232
        Gtk::TreeModel::Row row =*iter ;
 
233
        Gtk::TreeModel::iterator iter_parent = row.parent();
 
234
        Glib::ustring groupname_ = (*iter_parent)[columns.name];
 
235
 
 
236
        Gtk::TreeModel::Children children = iter_parent->children();
 
237
        Gtk::TreeModel::iterator listiter=children.begin();
 
238
 
 
239
        for(;listiter!=children.end();listiter++){
 
240
                Glib::ustring name_ = (*listiter)[columns.name];
 
241
                //printf(" get channel %s at %s\n",name_.c_str(),groupname.c_str());
 
242
                std::string stream_ = (*listiter)[columns.stream];
 
243
                TypeChannel page = (*listiter)[columns.type];
 
244
                bc->saveLine(name_,stream_,page,groupname_);
 
245
        }
 
246
 
 
247
}
 
248
 
 
249
void Channel::play_selection_iter(Gtk::TreeModel::iterator& iter)
 
250
{
 
251
        //printf("\nplay_selection_iter\n");
 
252
        TypeChannel page = (*iter)[columns.type];
 
253
        Glib::ustring name = (*iter)[columns.name];
 
254
        std::string stream = (*iter)[columns.stream];
 
255
 
 
256
        if(GROUP_CHANNEL == (*iter)[columns.type]) { // 点在分组名上, 什么也不做
 
257
                return;
 
258
        }
 
259
 
 
260
        LivePlayer* lp = parent->get_live_player();
 
261
        LivePlayer* live_player = get_player(stream, page);
 
262
 
 
263
        parent->set_live_player(live_player, name);
 
264
        RecentChannel* rc =
 
265
                dynamic_cast<RecentChannel*>(parent->get_recent_channel());
 
266
        if (this != rc)
 
267
                rc->saveLine(name,stream,page);
 
268
}
 
269
 
 
270
void Channel::play_stream(const std::string& stream_url, TypeChannel stream_type,const std::string& name)
 
271
{
 
272
 
 
273
        LivePlayer* lp = parent->get_live_player();
 
274
        LivePlayer* live_player = get_player(stream_url, stream_type);
 
275
 
 
276
        parent->set_live_player(live_player, name);
 
277
        //RecentChannel* rc =
 
278
        //      dynamic_cast<RecentChannel*>(parent->get_recent_channel());
 
279
        //if (this != rc)
 
280
        //      rc->saveLine(name,stream,page);
 
281
 
 
282
 
 
283
}
 
284
 
 
285
void Channel::search_channel(const Glib::ustring& name_)
 
286
{
 
287
        search_channel_name = name_;
 
288
        Glib::RefPtr<Gtk::TreeModelFilter> filter = 
 
289
                Glib::RefPtr<Gtk::TreeModelFilter>::cast_dynamic(get_model());
 
290
        filter->refilter();
 
291
        if (!name_.empty())
 
292
                expand_all();
 
293
}
 
294
 
 
295
 
 
296
bool Channel::on_visible_func(const Gtk::TreeModel::iterator& iter)
 
297
{
 
298
        if ((*iter)[columns.type] == GROUP_CHANNEL) {
 
299
                return true;
 
300
        }
 
301
        const Glib::ustring& name = (*iter)[columns.name];
 
302
        return name.find(search_channel_name, 0) != Glib::ustring::npos;
 
303
}
 
304
 
 
305
bool Channel::on_leave_event(GdkEventCrossing * ev)
 
306
{
 
307
        if (tipTimeout.connected()) {
 
308
                tipTimeout.disconnect();
 
309
        }
 
310
        return false;
 
311
}
 
312
 
 
313
bool Channel::tooltip_timeout(GdkEventMotion * ev)
 
314
{
 
315
        Gtk::TreeModel::Path path;
 
316
        Gtk::TreeViewColumn * column;
 
317
        int cell_x, cell_y;
 
318
        if (this->
 
319
                        get_path_at_pos((int) ev->x, (int) ev->y, path, column, cell_x,
 
320
                                cell_y)) {
 
321
                Gtk::TreeModel::iterator iter =
 
322
                        this->get_model()->get_iter(path);
 
323
                if (!iter)
 
324
                        return false;
 
325
                TypeChannel type = (*iter)[columns.type];
 
326
                Glib::ustring type_;
 
327
                if(PPLIVE_CHANNEL == type)
 
328
                        type_  = _("PPLive Stream");
 
329
                else if(SOPCAST_CHANNEL == type)
 
330
                        type_ = _("SopCast Stream");
 
331
                else if(MMS_CHANNEL == type)
 
332
                        type_ = _("MMS stream");
 
333
                else if(PPS_CHANNEL == type)
 
334
                        type_ = _("PPS stream");
 
335
                Glib::ustring name = (*iter)[columns.name];
 
336
                int num = (*iter)[columns.users];
 
337
                std::stringstream ss;
 
338
                ss<<num;
 
339
                std::string user=ss.str();
 
340
                std::string stream = (*iter)[columns.stream];
 
341
                Glib::ustring text;
 
342
 
 
343
                if(PPLIVE_CHANNEL == type)
 
344
                        text = "<span weight='bold'>" +name +"\n" + _("users:")+user+
 
345
                                "\n<span weight='bold'></span>"+_("Type:")+type_+"\n</span>";
 
346
                else
 
347
                        text = "<span weight='bold'>" +name +"\n" + _("users:")+user+
 
348
                                "\nURL:</span> " + stream +"\n<span weight='bold'>"+_("Type:")+type_+"\n</span>";
 
349
                //Glib::RefPtr<Gdk::Pixbuf> logo= Gdk::Pixbuf::create_from_file(DATA_DIR"/gmlive.png");
 
350
 
 
351
                //tooltips->setImage(logo);
 
352
                tooltips->setLabel(text);
 
353
                tooltips->showTooltip(ev);
 
354
 
 
355
        }
 
356
        return false;
 
357
}
 
358
bool Channel::on_motion_event(GdkEventMotion * ev)
 
359
{
 
360
        Gtk::TreeModel::Path path;
 
361
        Gtk::TreeViewColumn * column;
 
362
        int cell_x, cell_y;
 
363
        int delay = 600;
 
364
 
 
365
        if (tipTimeout.connected()) {
 
366
 
 
367
                tipTimeout.disconnect();
 
368
                tooltips->hideTooltip();
 
369
        }
 
370
        if (this->
 
371
                        get_path_at_pos((int) ev->x, (int) ev->y, path, column, cell_x,
 
372
                                cell_y)) {
 
373
                Gtk::TreeModel::iterator iter =
 
374
                        this->get_model()->get_iter(path);
 
375
                TypeChannel type = (*iter)[columns.type];
 
376
                if (GROUP_CHANNEL != type)
 
377
                        tipTimeout =
 
378
                                Glib::signal_timeout().connect(sigc::bind <
 
379
                                                GdkEventMotion *
 
380
                                                >(sigc::
 
381
                                                        mem_fun(*this,
 
382
                                                                &Channel::
 
383
                                                                tooltip_timeout),
 
384
                                                        ev), delay);
 
385
                else
 
386
                        tooltips->hideTooltip();
 
387
        } else
 
388
                tooltips->hideTooltip();
 
389
 
 
390
        return true;
 
391
}
 
392
 
 
393
 
 
394
bool Channel::on_tooltip_show(int x, int y, bool key_mode, const Glib::RefPtr<Gtk::Tooltip>& tooltip)
 
395
{
 
396
        Gtk::TreeModel::Path path;
 
397
        Gtk::TreeViewColumn * column;
 
398
        int cell_x, cell_y;
 
399
        if (this->
 
400
                        get_path_at_pos(x, y, path, column, cell_x,
 
401
                                cell_y)) {
 
402
                Gtk::TreeModel::iterator iter =
 
403
                        this->get_model()->get_iter(path);
 
404
                if (!iter){
 
405
                        return false;
 
406
                }
 
407
                TypeChannel type = (*iter)[columns.type];
 
408
                Glib::ustring type_;
 
409
                if(PPLIVE_CHANNEL == type)
 
410
                        type_  = _("PPLive Stream");
 
411
                else if(SOPCAST_CHANNEL == type)
 
412
                        type_ = _("SopCast Stream");
 
413
                else if(MMS_CHANNEL == type)
 
414
                        type_ = _("MMS stream");
 
415
                else if(PPS_CHANNEL == type)
 
416
                        type_ = _("PPS stream");
 
417
                Glib::ustring name = (*iter)[columns.name];
 
418
                int num = (*iter)[columns.users];
 
419
                std::stringstream ss;
 
420
                ss<<num;
 
421
                std::string user=ss.str();
 
422
                std::string stream = (*iter)[columns.stream];
 
423
                Glib::ustring text;
 
424
 
 
425
                if(PPLIVE_CHANNEL == type){
 
426
                        text = "<span weight='bold'>" +name +"\n" + _("users:")+user+
 
427
                                "\n<span weight='bold'></span>"+_("Type:")+type_+"\n</span>";
 
428
 
 
429
                }
 
430
                else
 
431
                        text = "<span weight='bold'>" +name +"\n" + _("users:")+user+
 
432
                                "\nURL:</span> " + stream +"\n<span weight='bold'>"+_("Type:")+type_+"\n</span>";
 
433
                //Glib::RefPtr<Gdk::Pixbuf> logo= Gdk::Pixbuf::create_from_file(DATA_DIR"/gmlive.png");
 
434
 
 
435
                //tooltips->setImage(logo);
 
436
                tooltips->setLabel(text);
 
437
                //tooltips->showTooltip(ev);
 
438
                return true;
 
439
 
 
440
        }
 
441
        return false;
 
442
}
 
443
 
 
444
Glib::ustring Channel::user_select_list(const char* title)
 
445
{
 
446
        //属于读取默认列表不正确的处理
 
447
        std::string filename;
 
448
        Gtk::FileChooserDialog dialog(_("Please select a channel list file"),Gtk::FILE_CHOOSER_ACTION_OPEN);
 
449
        Gtk::MessageDialog askDialog(_("open channles error")
 
450
                        ,false
 
451
                        ,Gtk::MESSAGE_QUESTION
 
452
                        ,Gtk::BUTTONS_OK_CANCEL
 
453
                        );
 
454
        askDialog.set_secondary_text(title);
 
455
        if (askDialog.run() == Gtk::RESPONSE_OK) {
 
456
                //open a file select window
 
457
                dialog.add_button(Gtk::Stock::CANCEL,Gtk::RESPONSE_CANCEL);
 
458
                dialog.add_button(Gtk::Stock::OPEN,Gtk::RESPONSE_OK);
 
459
                if ( dialog.run() == Gtk::RESPONSE_OK)
 
460
                        return dialog.get_filename();
 
461
 
 
462
        }
 
463
        return "";
 
464
}
 
465