5 #include <QStandardPaths>
7 #include "fileworker.h"
9 Engine::Engine(QObject
*parent
) :
11 m_clipboardContainsCopy(false),
13 m_selectedFilename(""),
16 m_fileWorker
= new FileWorker
;
18 // update progress property when worker progresses
19 connect(m_fileWorker
, SIGNAL(progressChanged(int, QString
)),
20 this, SLOT(setProgress(int, QString
)));
22 // pass worker end signals to QML
23 connect(m_fileWorker
, SIGNAL(done()), this, SIGNAL(workerDone()));
24 connect(m_fileWorker
, SIGNAL(errorOccurred(QString
, QString
)),
25 this, SIGNAL(workerErrorOccurred(QString
, QString
)));
26 connect(m_fileWorker
, SIGNAL(fileDeleted(QString
)), this, SIGNAL(fileDeleted(QString
)));
31 // is this the way to force stop the worker thread?
32 m_fileWorker
->cancel(); // stop possibly running background thread
33 m_fileWorker
->wait(); // wait until thread stops
34 delete m_fileWorker
; // delete it
37 void Engine::deleteFiles(QStringList filenames
)
40 m_fileWorker
->startDeleteFiles(filenames
);
43 void Engine::cutFiles(QStringList filenames
)
45 m_clipboardFiles
= filenames
;
46 m_clipboardContainsCopy
= false;
47 emit
clipboardCountChanged();
48 emit
clipboardContainsCopyChanged();
51 void Engine::copyFiles(QStringList filenames
)
53 m_clipboardFiles
= filenames
;
54 m_clipboardContainsCopy
= true;
55 emit
clipboardCountChanged();
56 emit
clipboardContainsCopyChanged();
59 void Engine::pasteFiles(QString destDirectory
)
61 if (m_clipboardFiles
.isEmpty()) {
62 emit
workerErrorOccurred("No files to paste", "");
66 QStringList files
= m_clipboardFiles
;
69 QDir
dest(destDirectory
);
71 emit
workerErrorOccurred(tr("Destination does not exist"), destDirectory
);
75 foreach (QString filename
, files
) {
76 QFileInfo
fileInfo(filename
);
77 QString newname
= dest
.absoluteFilePath(fileInfo
.fileName());
79 // source and dest filenames are the same?
80 if (filename
== newname
) {
81 emit
workerErrorOccurred(tr("Can't overwrite itself"), newname
);
85 // dest is under source? (directory)
86 if (newname
.startsWith(filename
)) {
87 emit
workerErrorOccurred(tr("Can't move/copy to itself"), filename
);
92 m_clipboardFiles
.clear();
93 emit
clipboardCountChanged();
95 if (m_clipboardContainsCopy
) {
96 m_fileWorker
->startCopyFiles(files
, destDirectory
);
100 m_fileWorker
->startMoveFiles(files
, destDirectory
);
103 void Engine::cancel()
105 m_fileWorker
->cancel();
108 QString
Engine::homeFolder() const
110 return QStandardPaths::writableLocation(QStandardPaths::HomeLocation
);
113 int Engine::startDepth() const
118 bool Engine::exists(QString filename
)
120 return QFile::exists(filename
);
123 QStringList
Engine::diskSpace(QString path
)
125 // run df to get disk space
126 QString blockSize
= "--block-size=1024";
127 QString result
= execute("/bin/df", QStringList() << blockSize
<< path
, false);
128 if (result
.isEmpty())
129 return QStringList();
132 QStringList lines
= result
.split(QRegExp("[\n\r]"));
133 if (lines
.count() < 2)
134 return QStringList();
136 QString line
= lines
.at(1);
137 QStringList columns
= line
.split(QRegExp("\\s+"), QString::SkipEmptyParts
);
138 if (columns
.count() < 5)
139 return QStringList();
141 QString totalString
= columns
.at(1);
142 QString usedString
= columns
.at(2);
143 QString percentageString
= columns
.at(4);
144 qint64 total
= totalString
.toLongLong() * 1024LL;
145 qint64 used
= usedString
.toLongLong() * 1024LL;
147 return QStringList() << percentageString
<< filesizeToString(used
)+"/"+filesizeToString(total
);
150 QStringList
Engine::readFile(QString filename
)
154 int maxBinSize
= 2048;
157 if (access(filename
, R_OK
) == -1)
158 return makeStringList(tr("No permission to read the file\n%1").arg(filename
));
160 QFile
file(filename
);
161 if (!file
.open(QIODevice::ReadOnly
))
162 return makeStringList(tr("Error reading file\n%1").arg(filename
));
164 // read start of file
165 char buffer
[maxSize
+1];
166 qint64 readSize
= file
.read(buffer
, maxSize
);
168 return makeStringList(tr("Error reading file\n%1").arg(filename
));
171 return makeStringList(tr("Empty file"));
173 bool atEnd
= file
.atEnd();
176 // detect binary or text file, it is binary if it contains zeros
178 for (int i
= 0; i
< readSize
; ++i
) {
179 if (buffer
[i
] == 0) {
187 // two different line widths
188 if (readSize
> maxBinSize
) {
189 readSize
= maxBinSize
;
192 QString out8
= createHexDump(buffer
, readSize
, 8);
193 QString out16
= createHexDump(buffer
, readSize
, 16);
197 msg
= tr("--- Binary file preview clipped at %1 kB ---").arg(maxBinSize
/1000);
198 msg
= tr("--- Binary file preview clipped at %1 kB ---").arg(maxBinSize
/1000);
201 return QStringList() << msg
<< out8
<< out16
;
204 // read lines to a string list and join
205 QByteArray
ba(buffer
, readSize
);
209 while (!in
.atEnd() && lineCount
< maxLines
) {
210 QString line
= in
.readLine();
216 if (lineCount
== maxLines
)
217 msg
= tr("--- Text file preview clipped at %1 lines ---").arg(maxLines
);
219 msg
= tr("--- Text file preview clipped at %1 kB ---").arg(maxSize
/1000);
221 return makeStringList(msg
, lines
.join("\n"));
224 QString
Engine::mkdir(QString path
, QString name
)
228 if (!dir
.mkdir(name
)) {
229 if (access(dir
.absolutePath(), W_OK
) == -1)
230 return tr("Cannot create folder %1\nPermission denied").arg(name
);
232 return tr("Cannot create folder %1").arg(name
);
238 QStringList
Engine::rename(QString fullOldFilename
, QString newName
)
240 QFile
file(fullOldFilename
);
241 QFileInfo
fileInfo(fullOldFilename
);
242 QDir dir
= fileInfo
.absoluteDir();
243 QString fullNewFilename
= dir
.absoluteFilePath(newName
);
245 QString errorMessage
;
246 if (!file
.rename(fullNewFilename
)) {
247 QString oldName
= fileInfo
.fileName();
248 errorMessage
= tr("Cannot rename %1\n%2").arg(oldName
).arg(file
.errorString());
251 return QStringList() << fullNewFilename
<< errorMessage
;
254 QString
Engine::chmod(QString path
,
255 bool ownerRead
, bool ownerWrite
, bool ownerExecute
,
256 bool groupRead
, bool groupWrite
, bool groupExecute
,
257 bool othersRead
, bool othersWrite
, bool othersExecute
)
260 QFileDevice::Permissions p
;
261 if (ownerRead
) p
|= QFileDevice::ReadOwner
;
262 if (ownerWrite
) p
|= QFileDevice::WriteOwner
;
263 if (ownerExecute
) p
|= QFileDevice::ExeOwner
;
264 if (groupRead
) p
|= QFileDevice::ReadGroup
;
265 if (groupWrite
) p
|= QFileDevice::WriteGroup
;
266 if (groupExecute
) p
|= QFileDevice::ExeGroup
;
267 if (othersRead
) p
|= QFileDevice::ReadOther
;
268 if (othersWrite
) p
|= QFileDevice::WriteOther
;
269 if (othersExecute
) p
|= QFileDevice::ExeOther
;
270 if (!file
.setPermissions(p
))
271 return tr("Cannot change permissions\n%1").arg(file
.errorString());
276 QString
Engine::readSetting(QString key
, QString defaultValue
)
279 return settings
.value(key
, defaultValue
).toString();
282 void Engine::writeSetting(QString key
, QString value
)
286 // do nothing if value didn't change
287 if (settings
.value(key
) == value
)
290 settings
.setValue(key
, value
);
292 emit
settingsChanged();
295 void Engine::setProgress(int progress
, QString filename
)
297 m_progress
= progress
;
298 m_progressFilename
= filename
;
299 emit
progressChanged();
300 emit
progressFilenameChanged();
303 QString
Engine::createHexDump(char *buffer
, int size
, int bytesPerLine
)
308 for (i
= 0; i
< size
; ++i
) {
309 if ((i
% bytesPerLine
) == 0) { // line change
310 out
+= " "+ascDump
+"\n"+
311 QString("%1").arg(QString::number(i
, 16), 4, QLatin1Char('0'))+": ";
315 out
+= QString("%1").arg(QString::number((unsigned char)buffer
[i
], 16),
316 2, QLatin1Char('0'))+" ";
317 if (buffer
[i
] >= 32 && buffer
[i
] <= 126)
318 ascDump
+= buffer
[i
];
322 // write out remaining asc dump
323 if ((i
% bytesPerLine
) > 0) {
324 int emptyBytes
= bytesPerLine
- (i
% bytesPerLine
);
325 for (int j
= 0; j
< emptyBytes
; ++j
) {
334 QStringList
Engine::makeStringList(QString msg
, QString str
)
337 list
<< msg
<< str
<< str
;
341 void Engine::setSelectedFilename(QString selectedFilename
)
343 m_selectedFilename
= selectedFilename
;
344 emit
selectedFilenameChanged();
347 void Engine::setExtensionFilter(QString extensionFilter
)
349 if (m_extensionFilter
!= extensionFilter
) {
350 m_extensionFilter
= extensionFilter
;
351 emit
extensionFilterChanged();