~ubuntu-branches/ubuntu/maverick/scribus-ng/maverick-backports

1 by Oleksandr Moskalenko
Import upstream version 1.3.3.2.dfsg
1
/*
2
For general Scribus (>=1.3.2) copyright and licensing information please refer
3
to the COPYING file provided with the program. Following this notice may exist
4
a copyright and/or license notice that predates the release of Scribus 1.3.2
5
for which a new license (GPL+exception) is in place.
6
*/
7
#include "filesearch.h"
8
#include "filesearch.moc"
9
#include <qtimer.h>
0.1.1 by Oleksandr Moskalenko
Import upstream version 1.3.4.dfsg+svn20071115
10
#include <qregexp.h>
11
1 by Oleksandr Moskalenko
Import upstream version 1.3.3.2.dfsg
12
13
enum FileSearchStatus
14
{
15
	Status_NotStarted,
16
	Status_Running,
17
	Status_Cancelled,
18
	Status_Failed,
19
	Status_Finished,
20
};
21
0.1.1 by Oleksandr Moskalenko
Import upstream version 1.3.4.dfsg+svn20071115
22
23
FileSearch::FileSearch(QObject* parent, const QString & fileName,const QString & searchBase, int depthLimit, bool caseSensitive) :
1 by Oleksandr Moskalenko
Import upstream version 1.3.3.2.dfsg
24
	DeferredTask(parent),
25
	m_searchBase(searchBase.isNull() ? QDir::homeDirPath() : searchBase),
26
	m_fileName(fileName),
27
	m_depth(0),
28
	m_maxdepth(depthLimit)
29
{
0.1.1 by Oleksandr Moskalenko
Import upstream version 1.3.4.dfsg+svn20071115
30
	m_caseSensitive = caseSensitive;
31
#ifdef _WIN32
32
	// it has no meaning to set case sensitiveness on win
33
	m_caseSensitive = false;
34
#endif
1 by Oleksandr Moskalenko
Import upstream version 1.3.3.2.dfsg
35
	DeferredTask::init();
36
	m_dir.setPath(m_searchBase);
37
	Q_ASSERT(m_dir.exists());
38
	// Give ourselves a useful name for object browsers, etc.
39
	setName(QString("FileSearch for \"%1\"").arg(m_searchBase).local8Bit());
40
}
41
42
FileSearch::~FileSearch()
43
{
44
	DeferredTask::cleanup();
45
}
46
47
const QStringList & FileSearch::matchingFiles() const
48
{
49
	return m_matchingFiles;
50
}
51
52
int FileSearch::foundCount() const
53
{
54
	return m_matchingFiles.count();
55
}
56
57
const QString & FileSearch::fileName() const
58
{
59
	return m_fileName;
60
}
61
62
const QDir & FileSearch::currentDir() const
63
{
64
	return m_dir;
65
}
66
67
void FileSearch::start()
68
{
69
	// Push the list of subdirs for the starting dir onto the stack
70
	pushStack();
71
	// and add the current directory's files to the list
72
	addCurrentDirFiles();
73
	DeferredTask::start();
74
}
75
76
void FileSearch::next()
77
{
78
	// We start off in a directory that has just been examined.
79
	// A list of the names of directories in this directory is at the top of
80
	// m_tree, and m_iter points to the first directory name in that list. The
81
	// files in this directory have already been checked to see if they match,
82
	// and added to the list of matches if they do.
83
	// We need to select the directory to step into, and search its contents.
84
85
	// skip '.', '..'
86
	while ( *(m_iter.top()) == "." || *(m_iter.top()) == ".." )
87
		++m_iter.top();
88
89
	if ( (m_iter.top() == m_tree.top().end()) || (m_depth == m_maxdepth) )
90
	{
91
		// We're at the end of the list of subdirectory names in this directory,
92
		// or we've hit the maximum depth we're allowed to search to.
93
		// Move up to the previous directory.
94
		m_iter.pop();
95
		m_tree.pop();
96
		m_dir.cdUp();
97
		m_depth--;
98
		// Check if we've run out of tree and should finish up
99
		if (m_depth < 0)
100
		{
101
			// We've run out of tree, so we're all done. Kill the timer and
102
			// tell our owner we've finished.
103
			Q_ASSERT(m_iter.count() == 0);
104
			Q_ASSERT(m_tree.count() == 0);
105
			DeferredTask::done();
106
			emit searchComplete(m_matchingFiles, m_fileName);
107
		}
108
		else
109
		{
110
			// As an optimisation, call next() to do a short recursion back to the
111
			// next subdir we actually need to search, so we don't have to wait for
112
			// the timer to get around to firing for this trivial step. We're not
113
			// putting anything on the stack so this should be pretty safe.
114
			next();
115
		}
116
	}
117
	else
118
	{
119
		// There are still subdirectories to search. Select the next one and step
120
		// into it, incrementing the iterator for the current dir in the process.
121
		m_dir.cd(*(m_iter.top()));
122
		++m_iter.top();
123
		m_depth++;
124
		pushStack();
125
		addCurrentDirFiles();
126
	}
127
}
128
129
void FileSearch::pushStack()
130
{
131
	m_tree.push(m_dir.entryList(QDir::Dirs|QDir::NoSymLinks));
132
	m_iter.push(m_tree.top().begin());
133
}
134
135
void FileSearch::addCurrentDirFiles()
136
{
0.1.1 by Oleksandr Moskalenko
Import upstream version 1.3.4.dfsg+svn20071115
137
	const QFileInfoList *filist = m_dir.entryInfoList(m_caseSensitive ? m_fileName : "*", QDir::Files);
1 by Oleksandr Moskalenko
Import upstream version 1.3.3.2.dfsg
138
	QFileInfoListIterator it( *filist );
139
	QFileInfo *fi;
0.1.1 by Oleksandr Moskalenko
Import upstream version 1.3.4.dfsg+svn20071115
140
	// Search files in this dir
141
	if (m_caseSensitive)
142
	{
143
		while ( ( fi = it.current() ) != 0 )
144
		{
145
			++it;
146
			m_matchingFiles.push_back(fi->absFilePath());
147
		}
148
	}
149
	else
150
	{
151
		// unix only, resp. no meaning in windows
152
		QRegExp r(m_fileName, false, true);
153
		while ( ( fi = it.current() ) != 0 )
154
		{
155
			++it;
156
			if (r.exactMatch(fi->fileName()))
157
				m_matchingFiles.push_back(fi->absFilePath());
158
		}
1 by Oleksandr Moskalenko
Import upstream version 1.3.3.2.dfsg
159
	}
160
}