1
/***************************************************************************
2
 * copyright            : (C) 2007-2008 Ian Monroe <ian@monroe.nu>
3
 *
4
 * This program is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU General Public License as
6
 * published by the Free Software Foundation; either version 2 of
7
 * the License or (at your option) version 3 or any later version
8
 * accepted by the membership of KDE e.V. (or its successor approved
9
 * by the membership of KDE e.V.), which shall act as a proxy
10
 * defined in Section 14 of version 3 of the license.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
 **************************************************************************/
20
21
#include "DirectoryLoader.h"
22
23
#include "Debug.h"
24
#include "CollectionManager.h"
25
#include "meta/PlaylistFileSupport.h"
26
#include "playlist/PlaylistController.h"
27
#include "playlistmanager/PlaylistManager.h"
28
29
#include <kio/job.h> // KIO::listRecursive
30
31
32
DirectoryLoader::DirectoryLoader()
33
    : QObject( 0 )
34
        , m_listOperations( 0 )
35
        , m_localConnection( false )
36
        , m_row( 0 )
37
{}
38
39
DirectoryLoader::~DirectoryLoader()
40
{}
41
42
void
43
DirectoryLoader::insertAtRow( int row )
44
{
45
    m_row = row;
46
    m_localConnection = true;
47
    connect( this, SIGNAL( finished( const Meta::TrackList& ) ), this, SLOT( doInsertAtRow() ) );
48
}
49
50
void
51
DirectoryLoader::doInsertAtRow()
52
{
53
    The::playlistController()->insertTracks( m_row, m_tracks );
54
    deleteLater();
55
}
56
57
void
58
DirectoryLoader::init( const QList<QUrl>& qurls )
59
{
60
    QList<KUrl> kurls;
61
    foreach( const QUrl &qurl, qurls )
62
        kurls << KUrl( qurl );
63
64
    init( kurls );
65
}
66
67
void
68
DirectoryLoader::init( const QList<KUrl>& urls )
69
{
70
    //drop from an external source or the file browser
71
    debug() << "Drop from external source or file browser";
72
    QList<KIO::ListJob*> jobs;
73
74
    foreach( const KUrl &kurl, urls )
75
    {
76
        KFileItem kitem( KFileItem::Unknown, KFileItem::Unknown, kurl, true );
77
        if( kitem.isDir() )
78
        {
79
            m_listOperations++;
80
            KIO::ListJob* lister = KIO::listRecursive( kurl ); //kjob's delete themselves
81
            connect( lister, SIGNAL( finished( KJob*) ),
82
                     SLOT( listJobFinished( KJob*) ) );
83
            connect( lister, SIGNAL( entries( KIO::Job*, const KIO::UDSEntryList& ) ),
84
                     SLOT( directoryListResults( KIO::Job*, const KIO::UDSEntryList& ) ) );
85
        }
86
        else
87
        {
88
            if( PlaylistManager::isPlaylist( kurl ) )
89
            {
90
                Meta::PlaylistPtr playlist = Meta::loadPlaylist( kurl );
91
                if( playlist )
92
                    m_tracks << playlist->tracks();
93
            }
94
            else
95
            {
96
                Meta::TrackPtr track = CollectionManager::instance()->trackForUrl( kurl );
97
                if( track )
98
                    m_tracks << track;
99
            }
100
        }
101
        //else TODO: notify user if can't decode, see also MyDirLister::matchesFilter       
102
    }
103
    if( m_listOperations == 0 )
104
    {
105
        finishUrlList();
106
    }
107
}
108
109
void
110
DirectoryLoader::directoryListResults( KIO::Job *job, const KIO::UDSEntryList &list )
111
{
112
    DEBUG_BLOCK
113
    //dfaure says that job->redirectionUrl().isValid() ? job->redirectionUrl() : job->url(); might be needed
114
    //but to wait until an issue is actually found, since it might take more work
115
    const KUrl dir = static_cast<KIO::SimpleJob*>( job )->url();
116
    foreach( const KIO::UDSEntry &entry, list )
117
    {
118
        KFileItem item( entry, dir, true, true );
119
        m_expanded.append( item );
120
    }
121
}
122
123
void
124
DirectoryLoader::listJobFinished(KJob*)
125
{
126
    m_listOperations--;
127
    if( m_listOperations < 1 )
128
        finishUrlList();
129
}
130
131
void
132
DirectoryLoader::finishUrlList()
133
{
134
    if( !m_expanded.isEmpty() )
135
    {
136
        qStableSort( m_expanded.begin(), m_expanded.end(), DirectoryLoader::directorySensitiveLessThan );
137
        foreach( const KFileItem& item, m_expanded )
138
        {
139
            if( !item.isDir() )
140
            {
141
                Meta::TrackPtr track = CollectionManager::instance()->trackForUrl( item.url() );
142
                if( track )
143
                    m_tracks.append( track );
144
            }
145
        }
146
        qStableSort( m_tracks.begin(), m_tracks.end(), Meta::Track::lessThan );
147
    }
148
    emit finished( m_tracks );
149
    if( !m_localConnection )
150
        deleteLater();
151
}
152
153
bool
154
DirectoryLoader::directorySensitiveLessThan( const KFileItem& item1, const KFileItem& item2 )
155
{
156
    QString dir1 =  item1.url().directory();
157
    QString dir2 =  item2.url().directory();
158
159
    debug() << "dir1: " << dir1;
160
    debug() << "dir2: " << dir2;
161
    if(dir1 == dir2)
162
    {
163
        debug() << "dir1==dir2";
164
        return item1.url().url() < item2.url().url();
165
    }
166
    else if( dir1 < dir2 )
167
    {
168
        debug() << "dir1<dir2";
169
        return true;
170
    } else {
171
        debug() << "dir1>dir2";
172
        return false;
173
    }
174
}