⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 browsertree.cpp

📁 FreeAMP(MP3播放)程序源代码-用来研究MP3解码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*____________________________________________________________________________

        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 + -