📄 browsertree.cpp
字号:
/*____________________________________________________________________________
FreeAmp - The Free MP3 Player
Portions Copyright (C) 1999-2000 EMusic.com
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: browsertree.cpp,v 1.41 2001/02/21 04:19:08 ijr Exp $
____________________________________________________________________________*/
#include "config.h"
#include <gtk/gtk.h>
#ifdef WIN32
#include <io.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#endif
#ifdef __QNX__
#include <strings.h>
#endif
#if defined(unix) || defined(__BEOS__)
#define SOCKET int
#endif
#if defined(unix)
#include <arpa/inet.h>
#define closesocket(x) close(x)
#define O_BINARY 0
#endif
#include "gtkmusicbrowser.h"
#include "gtkmessagedialog.h"
#include "eventdata.h"
#include "Http.h"
#include "../res/album_pix.xpm"
#include "../res/all_pix.xpm"
#include "../res/artist_pix.xpm"
#include "../res/catalog_pix.xpm"
#include "../res/playlist_pix.xpm"
#include "../res/track_pix.xpm"
#include "../res/uncatagorized_pix.xpm"
#include "../res/cd_pix.xpm"
#include "../res/streams_pix.xpm"
#include "../res/favorites_pix.xpm"
const string streamURL = "http://www.freeamp.org/streams.xml";
void kill_treedata(TreeData *dead)
{
delete dead;
}
TreeData *GTKMusicBrowser::NewTreeData(TreeNodeType type, MusicCatalog *cat,
ArtistList *art, AlbumList *alb,
PlaylistItem *tr, char *pname,
char *message,
vector<PlaylistItem *> *cdlist)
{
TreeData *data = new TreeData;
data->type = type;
data->catalog = cat;
data->artist = art;
data->album = alb;
data->track = tr;
if (pname)
data->playlistname = pname;
else
data->playlistname = "";
if (message)
data->message = message;
else
data->message = "";
data->cdtracks = cdlist;
return data;
}
vector<PlaylistItem *> *GTKMusicBrowser::GetTreeSelection(void)
{
vector<PlaylistItem *> *newlist = new vector<PlaylistItem *>;
vector<TreeData *>::iterator iter = mbSelections->begin();
for (; iter != mbSelections->end(); iter++) {
TreeData *data = *iter;
if (!data)
return newlist;
switch (data->type) {
case kTreeMyMusic:
case kTreeAll: {
MusicCatalog *cat = data->catalog;
if (!cat)
return newlist;
vector<ArtistList *> *artistList =
(vector<ArtistList *>*)cat->GetMusicList();
vector<PlaylistItem *> *unsorted =
(vector<PlaylistItem *>*)cat->GetUnsortedMusic();
vector<ArtistList *>::iterator h = artistList->begin();
for (; h != artistList->end(); h++) {
vector<AlbumList *>::iterator i = (*h)->m_albumList->begin();
for (; i != (*h)->m_albumList->end(); i++) {
vector<PlaylistItem *>::iterator j = (*i)->m_trackList->begin();
for (; j != (*i)->m_trackList->end(); j++) {
PlaylistItem *item = new PlaylistItem(*(PlaylistItem *)*j);
newlist->push_back(item);
}
}
}
vector<PlaylistItem *>::iterator k = unsorted->begin();
for (; k != unsorted->end(); k++) {
PlaylistItem *item = new PlaylistItem(*(PlaylistItem *)*k);
newlist->push_back(item);
}
break; }
case kTreeArtist: {
ArtistList *list = data->artist;
vector<AlbumList *>::iterator i = list->m_albumList->begin();
for (; i != list->m_albumList->end(); i++) {
vector<PlaylistItem *>::iterator j = (*i)->m_trackList->begin();
for (; j != (*i)->m_trackList->end(); j++) {
PlaylistItem *item = new PlaylistItem(*(PlaylistItem *)*j);
newlist->push_back(item);
}
}
break; }
case kTreeAlbum: {
AlbumList *list = data->album;
vector<PlaylistItem *>::iterator j = list->m_trackList->begin();
for (; j != list->m_trackList->end(); j++) {
PlaylistItem *item = new PlaylistItem(*(PlaylistItem *)*j);
newlist->push_back(item);
}
break; }
case kTreeCD:
case kTreeStream:
case kTreeFavStream:
case kTreeTrack: {
PlaylistItem *i = new PlaylistItem(*(data->track));
newlist->push_back(i);
break; }
case kTreePlaylist: {
char *fname = (char *)data->playlistname.c_str();
m_plm->ReadPlaylist(fname, newlist);
break; }
case kTreeUncat: {
MusicCatalog *cat = data->catalog;
vector<PlaylistItem *> *unsorted =
(vector<PlaylistItem *>*)cat->GetUnsortedMusic();
vector<PlaylistItem *>::iterator k = unsorted->begin();
for (; k != unsorted->end(); k++) {
PlaylistItem *item = new PlaylistItem(*(PlaylistItem *)*k);
newlist->push_back(item);
}
break; }
case kTreeCDHead: {
vector<PlaylistItem *> *cd = data->cdtracks;
vector<PlaylistItem *>::iterator k = cd->begin();
for (; k != cd->end(); k++) {
PlaylistItem *item = new PlaylistItem(*(PlaylistItem *)*k);
newlist->push_back(item);
}
break; }
default:
break;
}
}
return newlist;
}
static gint nocase_compare(GtkCList *clist, gconstpointer ptr1,
gconstpointer ptr2)
{
char *text1 = NULL;
char *text2 = NULL;
TreeData *data1 = NULL;
TreeData *data2 = NULL;
GtkCListRow *row1 = (GtkCListRow *) ptr1;
GtkCListRow *row2 = (GtkCListRow *) ptr2;
data1 = (TreeData *)row1->data;
data2 = (TreeData *)row2->data;
switch (row1->cell[clist->sort_column].type) {
case GTK_CELL_TEXT:
text1 = GTK_CELL_TEXT (row1->cell[clist->sort_column])->text;
break;
case GTK_CELL_PIXTEXT:
text1 = GTK_CELL_PIXTEXT (row1->cell[clist->sort_column])->text;
break;
default:
break;
}
switch (row2->cell[clist->sort_column].type) {
case GTK_CELL_TEXT:
text2 = GTK_CELL_TEXT (row2->cell[clist->sort_column])->text;
break;
case GTK_CELL_PIXTEXT:
text2 = GTK_CELL_PIXTEXT (row2->cell[clist->sort_column])->text;
break;
default:
break;
}
if (!text2)
return (text1 != NULL);
if (!text1)
return -1;
if (data1->type == kTreeTrack && data2->type == kTreeTrack) {
uint32 tnum1 = data1->track->GetMetaData().Track();
uint32 tnum2 = data2->track->GetMetaData().Track();
if (tnum1 == tnum2)
return strcasecmp(text1, text2);
if (tnum1 == 0)
return 1;
if (tnum2 == 0)
return -1;
return (tnum1 < tnum2) ? -1 : 1;
}
return strcasecmp (text1, text2);
}
static gint TreeDataCompare(TreeData *a, TreeData *b)
{
bool retvalue = true;
if (!a && !b)
retvalue = false;
else if (!a || !b)
retvalue = true;
else if ((a->type == b->type) && (a->catalog == b->catalog) &&
(a->artist == b->artist) && (a->album == b->album) &&
(a->track == b->track) && (a->playlistname == b->playlistname))
retvalue = false;
return retvalue;
}
GtkCTreeNode *GTKMusicBrowser::FindNode(TreeNodeType type, ArtistList *artist,
AlbumList *album, PlaylistItem *item,
GtkCTreeNode *searchFrom)
{
TreeData *data = NewTreeData(type, NULL, artist, album, item);
GtkCTreeNode *retnode;
retnode = gtk_ctree_find_by_row_data_custom(musicBrowserTree, searchFrom,
data,
(GCompareFunc)TreeDataCompare);
delete data;
return retnode;
}
void GTKMusicBrowser::AddCatTrack(ArtistList *artist, AlbumList *album,
PlaylistItem *item, bool expand)
{
char *name[1];
TreeData *data;
gtk_clist_freeze(GTK_CLIST(musicBrowserTree));
if (!artist) {
GtkCTreeNode *treeItem;
MetaData mdata = item->GetMetaData();
name[0] = (char *)mdata.Title().c_str();
treeItem = gtk_ctree_insert_node(musicBrowserTree, uncatTree,
NULL, name, 5,
track_pmap, track_mask, track_pmap,
track_mask, true,
false);
data = NewTreeData(kTreeTrack, NULL, NULL, NULL, item);
gtk_ctree_node_set_row_data_full(musicBrowserTree, treeItem, data,
(GtkDestroyNotify)kill_treedata);
if (expand) {
gtk_ctree_expand(musicBrowserTree, uncatTree);
gtk_ctree_select(musicBrowserTree, treeItem);
gtk_ctree_node_moveto(musicBrowserTree, treeItem, 0, 0.5, 0);
}
treeItem = gtk_ctree_insert_node(musicBrowserTree, allTree,
NULL, name, 5, track_pmap, track_mask,
track_pmap,
track_mask, true, false);
data = NewTreeData(kTreeTrack, NULL, NULL, NULL, item);
gtk_ctree_node_set_row_data_full(musicBrowserTree, treeItem, data,
(GtkDestroyNotify)kill_treedata);
gtk_ctree_sort_recursive(musicBrowserTree, allTree);
gtk_ctree_sort_recursive(musicBrowserTree, uncatTree);
gtk_clist_thaw(GTK_CLIST(musicBrowserTree));
return;
}
GtkCTreeNode *artTree, *albTree, *newItem;
albTree = FindNode(kTreeAlbum, artist, album, NULL);
if (!albTree) {
artTree = FindNode(kTreeArtist, artist, NULL, NULL);
if (!artTree) {
name[0] = (char *)artist->name.c_str();
GtkCTreeNode *sib = GTK_CTREE_ROW(mainTree)->children;
/* skip uncat and all subtrees */
sib = GTK_CTREE_ROW(sib)->sibling;
sib = GTK_CTREE_ROW(sib)->sibling;
while (sib) {
GtkCListRow *row = (GtkCListRow *)GTK_CTREE_ROW(sib);
char *sibtext = GTK_CELL_PIXTEXT(row->cell[0])->text;
if (strcasecmp(name[0], sibtext) < 0)
break;
sib = GTK_CTREE_ROW(sib)->sibling;
}
artTree = gtk_ctree_insert_node(musicBrowserTree, mainTree,
sib, name, 5, artist_pmap,
artist_mask,
artist_pmap, artist_mask, false,
false);
data = NewTreeData(kTreeArtist, NULL, artist);
gtk_ctree_node_set_row_data_full(musicBrowserTree, artTree, data,
(GtkDestroyNotify)kill_treedata);
if (expand)
gtk_ctree_expand(musicBrowserTree, artTree);
gtk_ctree_sort_node(musicBrowserTree, artTree);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -