2
* =====================================================================================
4
* Filename: channel.cpp
9
* Created: 2007年12月01日 19时25分31秒 CST
13
* Author: lerosua (), lerosua@gmail.com
16
* =====================================================================================
22
#include "MainWindow.h"
23
#include "livePlayer.h"
24
#include "recentchannel.h"
25
#include "bookmarkchannel.h"
26
#include "ChannelsTooltips.h"
28
#include <glib/gi18n.h>
30
Channel::Channel(MainWindow* parent_):parent( parent_)
32
set_flags(Gtk::CAN_FOCUS);
33
set_rules_hint(false);
35
tooltips = new ChannelsTooltips(this);
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);
43
append_column(_("channels"), columns.name);
44
append_column(_("bitrate"), columns.freq);
45
append_column(_("user"), columns.users);
49
set_tooltip_window(*tooltips);
50
signal_query_tooltip().connect(sigc::mem_fun(*this,
51
&Channel::on_tooltip_show));
53
signal_motion_notify_event().
54
connect(sigc::mem_fun(*this, &Channel::on_motion_event),
56
signal_leave_notify_event().
57
connect(sigc::mem_fun(*this, &Channel::on_leave_event),
60
filter->set_visible_func(sigc::mem_fun(*this, &Channel::on_visible_func));
70
Gtk::TreeModel::iterator Channel::getListIter(Gtk::TreeModel::
71
Children children, const std::string& groupname)
73
return find_if(children.begin(),
75
bind2nd(CompareChannel(columns),groupname));
77
Gtk::TreeModel::iterator Channel::addGroup(const Glib::ustring& group)
79
Gtk::TreeModel::iterator iter = m_liststore->append();
80
(*iter)[columns.name] = group;
81
(*iter)[columns.type]=GROUP_CHANNEL;
86
bool Channel::on_button_press_event(GdkEventButton * ev)
88
bool result = Gtk::TreeView::on_button_press_event(ev);
90
Glib::RefPtr < Gtk::TreeSelection > selection =
91
this->get_selection();
92
Gtk::TreeModel::iterator iter = selection->get_selected();
93
if (!selection->count_selected_rows())
96
Gtk::TreeModel::Path path(iter);
97
Gtk::TreeViewColumn * tvc;
99
/** get_path_at_pos() 是为确认鼠标是否在选择行上点击的*/
101
get_path_at_pos((int) ev->x, (int) ev->y, path, tvc, cx, cy))
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);
111
if(this->row_expanded(path))
112
this->collapse_row(path);
114
this->expand_row(path,false);
115
this->scroll_to_row(path);
118
} else if ((ev->type == GDK_BUTTON_PRESS)
119
&& (ev->button == 3)) {
120
if(GROUP_CHANNEL == (*iter)[columns.type])
122
Gtk::Menu* pop_menu =
123
parent->get_channels_pop_menu();
125
pop_menu->popup(ev->button, ev->time);
131
void Channel::play_selection()
133
Glib::RefPtr < Gtk::TreeSelection > selection =
134
this->get_selection();
135
Gtk::TreeModel::iterator iter = selection->get_selected();
136
if (!selection->count_selected_rows()) {
140
if(GROUP_CHANNEL != (*iter)[columns.type]) {
141
parent->get_gmplayer()->set_record(false);
142
play_selection_iter(iter);
148
void Channel::record_selection()
150
Glib::RefPtr < Gtk::TreeSelection > selection =
151
this->get_selection();
152
Gtk::TreeModel::iterator iter = selection->get_selected();
153
if (!selection->count_selected_rows()) {
157
if(GROUP_CHANNEL != (*iter)[columns.type]) {
158
Gtk::FileChooserDialog dlg(*parent,
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())
167
GMplayer* player = parent->get_gmplayer();
168
if (player->recording())
170
player->set_record(true);
171
const Glib::ustring& name= (*iter)[columns.name];
172
player->set_outfilename(outfilename, name);
173
play_selection_iter(iter);
178
std::string Channel::get_stream()
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];
188
void Channel::store_selection()
190
Glib::RefPtr < Gtk::TreeSelection > selection =
191
this->get_selection();
192
Gtk::TreeModel::iterator iter = selection->get_selected();
193
if (!selection->count_selected_rows())
195
TypeChannel page = (*iter)[columns.type];
196
Glib::ustring name = (*iter)[columns.name];
197
std::string stream = (*iter)[columns.stream];
199
BookMarkChannel* bc =
200
dynamic_cast<BookMarkChannel*>(parent->get_bookmark_channel());
202
bc->saveLine(name,stream,page,"TOP");
206
dynamic_cast<RecentChannel*>(parent->get_recent_channel());
208
rc->saveLine(name,stream,page);
212
void Channel::store_selection_group()
214
/** 如果本频道是书签或最近列表,都不启动此功能*/
215
BookMarkChannel* bc =
216
dynamic_cast<BookMarkChannel*>(parent->get_bookmark_channel());
220
dynamic_cast<RecentChannel*>(parent->get_recent_channel());
225
Glib::RefPtr < Gtk::TreeSelection > selection =
226
this->get_selection();
227
Gtk::TreeModel::iterator iter = selection->get_selected();
228
if (!selection->count_selected_rows())
230
/** 利用 *iter 获取 row,然后用row.parent()的方法获取了它的父iter,也就是所在的组
232
Gtk::TreeModel::Row row =*iter ;
233
Gtk::TreeModel::iterator iter_parent = row.parent();
234
Glib::ustring groupname_ = (*iter_parent)[columns.name];
236
Gtk::TreeModel::Children children = iter_parent->children();
237
Gtk::TreeModel::iterator listiter=children.begin();
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_);
249
void Channel::play_selection_iter(Gtk::TreeModel::iterator& iter)
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];
256
if(GROUP_CHANNEL == (*iter)[columns.type]) { // 点在分组名上, 什么也不做
260
LivePlayer* lp = parent->get_live_player();
261
LivePlayer* live_player = get_player(stream, page);
263
parent->set_live_player(live_player, name);
265
dynamic_cast<RecentChannel*>(parent->get_recent_channel());
267
rc->saveLine(name,stream,page);
270
void Channel::play_stream(const std::string& stream_url, TypeChannel stream_type,const std::string& name)
273
LivePlayer* lp = parent->get_live_player();
274
LivePlayer* live_player = get_player(stream_url, stream_type);
276
parent->set_live_player(live_player, name);
277
//RecentChannel* rc =
278
// dynamic_cast<RecentChannel*>(parent->get_recent_channel());
280
// rc->saveLine(name,stream,page);
285
void Channel::search_channel(const Glib::ustring& name_)
287
search_channel_name = name_;
288
Glib::RefPtr<Gtk::TreeModelFilter> filter =
289
Glib::RefPtr<Gtk::TreeModelFilter>::cast_dynamic(get_model());
296
bool Channel::on_visible_func(const Gtk::TreeModel::iterator& iter)
298
if ((*iter)[columns.type] == GROUP_CHANNEL) {
301
const Glib::ustring& name = (*iter)[columns.name];
302
return name.find(search_channel_name, 0) != Glib::ustring::npos;
305
bool Channel::on_leave_event(GdkEventCrossing * ev)
307
if (tipTimeout.connected()) {
308
tipTimeout.disconnect();
313
bool Channel::tooltip_timeout(GdkEventMotion * ev)
315
Gtk::TreeModel::Path path;
316
Gtk::TreeViewColumn * column;
319
get_path_at_pos((int) ev->x, (int) ev->y, path, column, cell_x,
321
Gtk::TreeModel::iterator iter =
322
this->get_model()->get_iter(path);
325
TypeChannel type = (*iter)[columns.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;
339
std::string user=ss.str();
340
std::string stream = (*iter)[columns.stream];
343
if(PPLIVE_CHANNEL == type)
344
text = "<span weight='bold'>" +name +"\n" + _("users:")+user+
345
"\n<span weight='bold'></span>"+_("Type:")+type_+"\n</span>";
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");
351
//tooltips->setImage(logo);
352
tooltips->setLabel(text);
353
tooltips->showTooltip(ev);
358
bool Channel::on_motion_event(GdkEventMotion * ev)
360
Gtk::TreeModel::Path path;
361
Gtk::TreeViewColumn * column;
365
if (tipTimeout.connected()) {
367
tipTimeout.disconnect();
368
tooltips->hideTooltip();
371
get_path_at_pos((int) ev->x, (int) ev->y, path, column, cell_x,
373
Gtk::TreeModel::iterator iter =
374
this->get_model()->get_iter(path);
375
TypeChannel type = (*iter)[columns.type];
376
if (GROUP_CHANNEL != type)
378
Glib::signal_timeout().connect(sigc::bind <
386
tooltips->hideTooltip();
388
tooltips->hideTooltip();
394
bool Channel::on_tooltip_show(int x, int y, bool key_mode, const Glib::RefPtr<Gtk::Tooltip>& tooltip)
396
Gtk::TreeModel::Path path;
397
Gtk::TreeViewColumn * column;
400
get_path_at_pos(x, y, path, column, cell_x,
402
Gtk::TreeModel::iterator iter =
403
this->get_model()->get_iter(path);
407
TypeChannel type = (*iter)[columns.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;
421
std::string user=ss.str();
422
std::string stream = (*iter)[columns.stream];
425
if(PPLIVE_CHANNEL == type){
426
text = "<span weight='bold'>" +name +"\n" + _("users:")+user+
427
"\n<span weight='bold'></span>"+_("Type:")+type_+"\n</span>";
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");
435
//tooltips->setImage(logo);
436
tooltips->setLabel(text);
437
//tooltips->showTooltip(ev);
444
Glib::ustring Channel::user_select_list(const char* title)
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")
451
,Gtk::MESSAGE_QUESTION
452
,Gtk::BUTTONS_OK_CANCEL
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();