1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
//Author: Max Howell <max.howell@methylblue.com>, (C) 2003-4
//Copyright: See COPYING file that comes with this distribution
#include <debug.h>
#include "fileTree.h"
#include <tqapplication.h>
#include <tqtimer.h>
#include <tqvaluelist.h>
#include "remoteLister.h"
#include "scan.h"
namespace Filelight
{
//you need to use a single DirLister
//one per directory breaks TDEIO (seemingly) and also uses un-godly amounts of memory!
//TODO delete all this stuff!
struct Store {
typedef TQValueList<Store*> List;
/// location of the directory
const KURL url;
/// the directory on which we are operating
Directory *directory;
/// so we can reference the parent store
Store *parent;
/// directories in this directory that need to be scanned before we can propagate()
List stores;
Store()
: directory( 0 ), parent( 0 ) {}
Store( const KURL &u, const TQString &name, Store *s )
: url( u ), directory( new Directory( name.local8Bit() + '/' ) ), parent( s ) {}
Store*
propagate()
{
/// returns the next store available for scanning
debug() << "propagate: " << url << endl;
if( parent ) {
parent->directory->append( directory );
if( parent->stores.isEmpty() ) {
return parent->propagate();
}
else
return parent;
}
//we reached the root, let's get our next directory scanned
return this;
}
private:
Store( Store& );
Store &operator=( const Store& );
};
RemoteLister::RemoteLister( const KURL &url, TQWidget *parent )
: KDirLister( true /*don't fetch mimetypes*/ )
, m_root( new Store( url, url.url(), 0 ) )
, m_store( m_root )
{
setAutoUpdate( false ); //don't use KDirWatchers
setShowingDotFiles( true ); //stupid KDirLister API function names
setMainWindow( parent );
//use TQT_SIGNAL(result(TDEIO::Job*)) instead and then use Job::error()
connect( this, TQT_SIGNAL(completed()), TQT_SLOT(completed()) );
connect( this, TQT_SIGNAL(canceled()), TQT_SLOT(canceled()) );
//we do this non-recursively - it is the only way!
openURL( url );
}
RemoteLister::~RemoteLister()
{
Directory *tree = isFinished() ? m_store->directory : 0;
TQCustomEvent *e = new TQCustomEvent( 1000 );
e->setData( tree );
TQApplication::postEvent( parent(), e );
delete m_root;
}
void
RemoteLister::completed()
{
debug() << "completed: " << url().prettyURL() << endl;
//as usual KDE documentation didn't suggest I needed to do this at all
//I had to figure it out myself
// -- avoid crash
TQTimer::singleShot( 0, this, TQT_SLOT(_completed()) );
}
void
RemoteLister::canceled()
{
debug() << "canceled: " << url().prettyURL() << endl;
TQTimer::singleShot( 0, this, TQT_SLOT(_completed()) );
}
void
RemoteLister::_completed()
{
//m_directory is set to the directory we should operate on
KFileItemList items = KDirLister::items();
for( KFileItemList::ConstIterator it = items.begin(), end = items.end(); it != end; ++it )
{
if( (*it)->isDir() )
m_store->stores += new Store( (*it)->url(), (*it)->name(), m_store );
else
m_store->directory->append( (*it)->name().local8Bit(), (*it)->size() / 1024 );
ScanManager::s_files++;
}
if( m_store->stores.isEmpty() )
//no directories to scan, so we need to append ourselves to the parent directory
//propagate() will return the next ancestor that has stores left to be scanned, or root if we are done
m_store = m_store->propagate();
if( !m_store->stores.isEmpty() )
{
Store::List::Iterator first = m_store->stores.begin();
const KURL url( (*first)->url );
Store *currentStore = m_store;
//we should operate with this store next time this function is called
m_store = *first;
//we don't want to handle this store again
currentStore->stores.remove( first );
//this returns _immediately_
debug() << "scanning: " << url << endl;
openURL( url );
}
else {
debug() << "I think we're done\n";
Q_ASSERT( m_root == m_store );
delete this;
}
}
}
#include "remoteLister.moc"
|