Changeset View
Changeset View
Standalone View
Standalone View
krusader/Synchronizer/synchronizertask.cpp
Show All 15 Lines | |||||
16 | * * | 16 | * * | ||
17 | * You should have received a copy of the GNU General Public License * | 17 | * You should have received a copy of the GNU General Public License * | ||
18 | * along with Krusader. If not, see [http://www.gnu.org/licenses/]. * | 18 | * along with Krusader. If not, see [http://www.gnu.org/licenses/]. * | ||
19 | *****************************************************************************/ | 19 | *****************************************************************************/ | ||
20 | 20 | | |||
21 | #include "synchronizertask.h" | 21 | #include "synchronizertask.h" | ||
22 | 22 | | |||
23 | // QtCore | 23 | // QtCore | ||
24 | #include <QTimer> | | |||
25 | #include <QFile> | 24 | #include <QFile> | ||
25 | #include <QTimer> | ||||
26 | 26 | | |||
27 | #include <KI18n/KLocalizedString> | 27 | #include <KI18n/KLocalizedString> | ||
28 | #include <KWidgetsAddons/KMessageBox> | 28 | #include <KWidgetsAddons/KMessageBox> | ||
29 | 29 | | |||
30 | #include "synchronizer.h" | 30 | #include "synchronizer.h" | ||
31 | #include "synchronizerfileitem.h" | | |||
32 | #include "synchronizerdirlist.h" | 31 | #include "synchronizerdirlist.h" | ||
32 | #include "synchronizerfileitem.h" | ||||
33 | #include "../FileSystem/filesystem.h" | 33 | #include "../FileSystem/filesystem.h" | ||
34 | 34 | | |||
35 | CompareTask::CompareTask(SynchronizerFileItem *parentIn, const QString &leftURL, | 35 | CompareTask::CompareTask(SynchronizerFileItem *parentIn, const QUrl &left, const QUrl &right, | ||
36 | const QString &rightURL, const QString &leftDir, | 36 | const QString &leftDir, const QString &rightDir, bool hidden) | ||
37 | const QString &rightDir, bool hidden) : SynchronizerTask(), m_parent(parentIn), | 37 | : SynchronizerTask(), m_parent(parentIn), m_url(left), m_dir(leftDir), m_otherUrl(right), | ||
38 | m_url(leftURL), m_dir(leftDir), m_otherUrl(rightURL), | 38 | m_otherDir(rightDir), m_duplicate(true), m_dirList(0), m_otherDirList(0) | ||
39 | m_otherDir(rightDir), m_duplicate(true), | | |||
40 | m_dirList(0), m_otherDirList(0) | | |||
41 | { | 39 | { | ||
42 | ignoreHidden = hidden; | 40 | ignoreHidden = hidden; | ||
43 | } | 41 | } | ||
44 | 42 | | |||
45 | CompareTask::CompareTask(SynchronizerFileItem *parentIn, const QString &urlIn, | 43 | CompareTask::CompareTask(SynchronizerFileItem *parentIn, const QUrl &url, const QString &dir, | ||
46 | const QString &dirIn, bool isLeftIn, bool hidden) : SynchronizerTask(), | 44 | bool isLeftIn, bool hidden) | ||
47 | m_parent(parentIn), m_url(urlIn), m_dir(dirIn), | 45 | : SynchronizerTask(), m_parent(parentIn), m_url(url), m_dir(dir), m_isLeft(isLeftIn), | ||
48 | m_isLeft(isLeftIn), m_duplicate(false), | 46 | m_duplicate(false), m_dirList(0), m_otherDirList(0) | ||
49 | m_dirList(0), m_otherDirList(0) | | |||
50 | { | 47 | { | ||
51 | ignoreHidden = hidden; | 48 | ignoreHidden = hidden; | ||
52 | } | 49 | } | ||
53 | 50 | | |||
54 | CompareTask::~CompareTask() | 51 | CompareTask::~CompareTask() | ||
55 | { | 52 | { | ||
56 | if (m_dirList) { | 53 | if (m_dirList) { | ||
57 | delete m_dirList; | 54 | delete m_dirList; | ||
58 | m_dirList = 0; | 55 | m_dirList = 0; | ||
59 | } | 56 | } | ||
60 | if (m_otherDirList) { | 57 | if (m_otherDirList) { | ||
61 | delete m_otherDirList; | 58 | delete m_otherDirList; | ||
62 | m_otherDirList = 0; | 59 | m_otherDirList = 0; | ||
63 | } | 60 | } | ||
64 | } | 61 | } | ||
65 | 62 | | |||
66 | void CompareTask::start() | 63 | void CompareTask::start() | ||
67 | { | 64 | { | ||
68 | if (m_state == ST_STATE_NEW) { | 65 | if (m_state == ST_STATE_NEW) { | ||
69 | m_state = ST_STATE_PENDING; | 66 | m_state = ST_STATE_PENDING; | ||
70 | m_loadFinished = m_otherLoadFinished = false; | 67 | m_loadFinished = m_otherLoadFinished = false; | ||
71 | 68 | | |||
72 | m_dirList = new SynchronizerDirList(parentWidget, ignoreHidden); | 69 | m_dirList = new SynchronizerDirList(parentWidget, ignoreHidden); | ||
73 | connect(m_dirList, SIGNAL(finished(bool)), this, SLOT(slotFinished(bool))); | 70 | connect(m_dirList, &SynchronizerDirList::finished, this, &CompareTask::slotFinished); | ||
74 | m_dirList->load(m_url, false); | 71 | m_dirList->load(m_url, false); | ||
75 | 72 | | |||
76 | if (m_duplicate) { | 73 | if (m_duplicate) { | ||
77 | m_otherDirList = new SynchronizerDirList(parentWidget, ignoreHidden); | 74 | m_otherDirList = new SynchronizerDirList(parentWidget, ignoreHidden); | ||
78 | connect(m_otherDirList, SIGNAL(finished(bool)), this, SLOT(slotOtherFinished(bool))); | 75 | connect(m_otherDirList, &SynchronizerDirList::finished, this, &CompareTask::slotOtherFinished); | ||
79 | m_otherDirList->load(m_otherUrl, false); | 76 | m_otherDirList->load(m_otherUrl, false); | ||
80 | } | 77 | } | ||
81 | } | 78 | } | ||
82 | } | 79 | } | ||
83 | 80 | | |||
84 | void CompareTask::slotFinished(bool result) | 81 | void CompareTask::slotFinished(bool result) | ||
85 | { | 82 | { | ||
86 | if (!result) { | 83 | if (!result) { | ||
87 | m_state = ST_STATE_ERROR; | 84 | m_state = ST_STATE_ERROR; | ||
88 | return; | 85 | return; | ||
89 | } | 86 | } | ||
90 | m_loadFinished = true; | 87 | m_loadFinished = true; | ||
91 | 88 | | |||
92 | if (m_otherLoadFinished || !m_duplicate) | 89 | if (m_otherLoadFinished || !m_duplicate) | ||
93 | m_state = ST_STATE_READY; | 90 | m_state = ST_STATE_READY; | ||
94 | } | 91 | } | ||
95 | 92 | | |||
96 | | ||||
97 | void CompareTask::slotOtherFinished(bool result) | 93 | void CompareTask::slotOtherFinished(bool result) | ||
98 | { | 94 | { | ||
99 | if (!result) { | 95 | if (!result) { | ||
100 | m_state = ST_STATE_ERROR; | 96 | m_state = ST_STATE_ERROR; | ||
101 | return; | 97 | return; | ||
102 | } | 98 | } | ||
103 | m_otherLoadFinished = true; | 99 | m_otherLoadFinished = true; | ||
104 | 100 | | |||
105 | if (m_loadFinished) | 101 | if (m_loadFinished) | ||
106 | m_state = ST_STATE_READY; | 102 | m_state = ST_STATE_READY; | ||
107 | } | 103 | } | ||
108 | 104 | | |||
109 | CompareContentTask::CompareContentTask(Synchronizer *syn, SynchronizerFileItem *itemIn, const QUrl &leftURLIn, | 105 | CompareContentTask::CompareContentTask(Synchronizer *syn, SynchronizerFileItem *itemIn, | ||
110 | const QUrl &rightURLIn, KIO::filesize_t sizeIn) : SynchronizerTask(), | 106 | const QUrl &left, const QUrl &right, KIO::filesize_t sizeIn) | ||
111 | leftURL(leftURLIn), rightURL(rightURLIn), | 107 | : SynchronizerTask(), left(left), right(right), size(sizeIn), | ||
112 | size(sizeIn), errorPrinted(false), leftReadJob(0), | 108 | errorPrinted(false), leftReadJob(0), rightReadJob(0), compareArray(), owner(-1), item(itemIn), | ||
113 | rightReadJob(0), compareArray(), owner(-1), item(itemIn), timer(0), | 109 | timer(0), leftFile(0), rightFile(0), received(0), sync(syn) | ||
114 | leftFile(0), rightFile(0), received(0), sync(syn) | | |||
115 | { | 110 | { | ||
116 | } | 111 | } | ||
117 | 112 | | |||
118 | CompareContentTask::~CompareContentTask() | 113 | CompareContentTask::~CompareContentTask() | ||
119 | { | 114 | { | ||
120 | abortContentComparing(); | 115 | abortContentComparing(); | ||
121 | 116 | | |||
122 | if (timer) | 117 | if (timer) | ||
123 | delete timer; | 118 | delete timer; | ||
124 | if (leftFile) | 119 | if (leftFile) | ||
125 | delete leftFile; | 120 | delete leftFile; | ||
126 | if (rightFile) | 121 | if (rightFile) | ||
127 | delete rightFile; | 122 | delete rightFile; | ||
128 | } | 123 | } | ||
129 | 124 | | |||
130 | void CompareContentTask::start() | 125 | void CompareContentTask::start() | ||
131 | { | 126 | { | ||
132 | m_state = ST_STATE_PENDING; | 127 | m_state = ST_STATE_PENDING; | ||
133 | 128 | | |||
134 | if (leftURL.isLocalFile() && rightURL.isLocalFile()) { | 129 | if (left.isLocalFile() && right.isLocalFile()) { | ||
135 | leftFile = new QFile(leftURL.path()); | 130 | leftFile = new QFile(left.path()); | ||
136 | if (!leftFile->open(QIODevice::ReadOnly)) { | 131 | if (!leftFile->open(QIODevice::ReadOnly)) { | ||
137 | KMessageBox::error(parentWidget, i18n("Error at opening %1.", leftURL.path())); | 132 | KMessageBox::error(parentWidget, i18n("Error at opening %1.", left.path())); | ||
138 | m_state = ST_STATE_ERROR; | 133 | m_state = ST_STATE_ERROR; | ||
139 | return; | 134 | return; | ||
140 | } | 135 | } | ||
141 | 136 | | |||
142 | rightFile = new QFile(rightURL.path()); | 137 | rightFile = new QFile(right.path()); | ||
143 | if (!rightFile->open(QIODevice::ReadOnly)) { | 138 | if (!rightFile->open(QIODevice::ReadOnly)) { | ||
144 | KMessageBox::error(parentWidget, i18n("Error at opening %1.", rightURL.path())); | 139 | KMessageBox::error(parentWidget, i18n("Error at opening %1.", right.path())); | ||
145 | m_state = ST_STATE_ERROR; | 140 | m_state = ST_STATE_ERROR; | ||
146 | return; | 141 | return; | ||
147 | } | 142 | } | ||
148 | 143 | | |||
149 | timer = new QTimer(this); | 144 | timer = new QTimer(this); | ||
150 | connect(timer, SIGNAL(timeout()), this, SLOT(sendStatusMessage())); | 145 | connect(timer, SIGNAL(timeout()), this, SLOT(sendStatusMessage())); | ||
151 | timer->setSingleShot(true); | 146 | timer->setSingleShot(true); | ||
152 | timer->start(1000); | 147 | timer->start(1000); | ||
153 | 148 | | |||
154 | localFileCompareCycle(); | 149 | localFileCompareCycle(); | ||
155 | } else { | 150 | } else { | ||
156 | leftReadJob = KIO::get(leftURL, KIO::NoReload, KIO::HideProgressInfo); | 151 | leftReadJob = KIO::get(left, KIO::NoReload, KIO::HideProgressInfo); | ||
157 | rightReadJob = KIO::get(rightURL, KIO::NoReload, KIO::HideProgressInfo); | 152 | rightReadJob = KIO::get(right, KIO::NoReload, KIO::HideProgressInfo); | ||
158 | 153 | | |||
159 | connect(leftReadJob, SIGNAL(data(KIO::Job*,QByteArray)), | 154 | connect(leftReadJob, SIGNAL(data(KIO::Job *, QByteArray)), this, | ||
160 | this, SLOT(slotDataReceived(KIO::Job*,QByteArray))); | 155 | SLOT(slotDataReceived(KIO::Job *, QByteArray))); | ||
161 | connect(rightReadJob, SIGNAL(data(KIO::Job*,QByteArray)), | 156 | connect(rightReadJob, SIGNAL(data(KIO::Job *, QByteArray)), this, | ||
162 | this, SLOT(slotDataReceived(KIO::Job*,QByteArray))); | 157 | SLOT(slotDataReceived(KIO::Job *, QByteArray))); | ||
163 | connect(leftReadJob, SIGNAL(result(KJob*)), | 158 | connect(leftReadJob, SIGNAL(result(KJob *)), this, SLOT(slotFinished(KJob *))); | ||
164 | this, SLOT(slotFinished(KJob*))); | 159 | connect(rightReadJob, SIGNAL(result(KJob *)), this, SLOT(slotFinished(KJob *))); | ||
165 | connect(rightReadJob, SIGNAL(result(KJob*)), | | |||
166 | this, SLOT(slotFinished(KJob*))); | | |||
167 | 160 | | |||
168 | rightReadJob->suspend(); | 161 | rightReadJob->suspend(); | ||
169 | 162 | | |||
170 | timer = new QTimer(this); | 163 | timer = new QTimer(this); | ||
171 | connect(timer, SIGNAL(timeout()), this, SLOT(sendStatusMessage())); | 164 | connect(timer, SIGNAL(timeout()), this, SLOT(sendStatusMessage())); | ||
172 | timer->setSingleShot(true); | 165 | timer->setSingleShot(true); | ||
173 | timer->start(1000); | 166 | timer->start(1000); | ||
174 | } | 167 | } | ||
175 | } | 168 | } | ||
176 | 169 | | |||
177 | void CompareContentTask::localFileCompareCycle() | 170 | void CompareContentTask::localFileCompareCycle() | ||
178 | { | 171 | { | ||
179 | 172 | | |||
180 | bool different = false; | 173 | bool different = false; | ||
181 | 174 | | |||
182 | char leftBuffer[ 1440 ]; | 175 | char leftBuffer[1440]; | ||
183 | char rightBuffer[ 1440 ]; | 176 | char rightBuffer[1440]; | ||
184 | 177 | | |||
185 | QTime timer; | 178 | QTime timer; | ||
186 | timer.start(); | 179 | timer.start(); | ||
187 | 180 | | |||
188 | int cnt = 0; | 181 | int cnt = 0; | ||
189 | 182 | | |||
190 | while (!leftFile->atEnd() && !rightFile->atEnd()) { | 183 | while (!leftFile->atEnd() && !rightFile->atEnd()) { | ||
191 | int leftBytes = leftFile->read(leftBuffer, sizeof(leftBuffer)); | 184 | int leftBytes = leftFile->read(leftBuffer, sizeof(leftBuffer)); | ||
Show All 28 Lines | 212 | if (leftFile->atEnd() && rightFile->atEnd()) { | |||
220 | sync->compareContentResult(item, true); | 213 | sync->compareContentResult(item, true); | ||
221 | m_state = ST_STATE_READY; | 214 | m_state = ST_STATE_READY; | ||
222 | return; | 215 | return; | ||
223 | } | 216 | } | ||
224 | 217 | | |||
225 | QTimer::singleShot(0, this, SLOT(localFileCompareCycle())); | 218 | QTimer::singleShot(0, this, SLOT(localFileCompareCycle())); | ||
226 | } | 219 | } | ||
227 | 220 | | |||
228 | | ||||
229 | void CompareContentTask::slotDataReceived(KIO::Job *job, const QByteArray &data) | 221 | void CompareContentTask::slotDataReceived(KIO::Job *job, const QByteArray &data) | ||
230 | { | 222 | { | ||
231 | int jobowner = (job == leftReadJob) ? 1 : 0; | 223 | int jobowner = (job == leftReadJob) ? 1 : 0; | ||
232 | int bufferLen = compareArray.size(); | 224 | int bufferLen = compareArray.size(); | ||
233 | int dataLen = data.size(); | 225 | int dataLen = data.size(); | ||
234 | 226 | | |||
235 | if (job == leftReadJob) | 227 | if (job == leftReadJob) | ||
236 | received += dataLen; | 228 | received += dataLen; | ||
237 | 229 | | |||
238 | if (jobowner == owner) { | 230 | if (jobowner == owner) { | ||
239 | compareArray.append(data); | 231 | compareArray.append(data); | ||
240 | return; | 232 | return; | ||
241 | } | 233 | } | ||
242 | 234 | | |||
243 | do { | 235 | do { | ||
244 | if (bufferLen == 0) { | 236 | if (bufferLen == 0) { | ||
245 | compareArray = QByteArray(data.data(), dataLen); | 237 | compareArray = QByteArray(data.data(), dataLen); | ||
246 | owner = jobowner; | 238 | owner = jobowner; | ||
247 | break; | 239 | break; | ||
248 | } | 240 | } | ||
249 | 241 | | |||
250 | int minSize = (dataLen < bufferLen) ? dataLen : bufferLen; | 242 | int minSize = (dataLen < bufferLen) ? dataLen : bufferLen; | ||
251 | 243 | | |||
252 | for (int i = 0; i != minSize; i++) | 244 | for (int i = 0; i != minSize; i++) | ||
253 | if (data[i] != compareArray[i]) { | 245 | if (data[i] != compareArray[i]) { | ||
254 | abortContentComparing(); | 246 | abortContentComparing(); | ||
255 | return; | 247 | return; | ||
256 | } | 248 | } | ||
257 | 249 | | |||
258 | if (minSize == bufferLen) { | 250 | if (minSize == bufferLen) { | ||
Show All 38 Lines | 279 | { | |||
297 | 289 | | |||
298 | if (job->error()) { | 290 | if (job->error()) { | ||
299 | timer->stop(); | 291 | timer->stop(); | ||
300 | abortContentComparing(); | 292 | abortContentComparing(); | ||
301 | } | 293 | } | ||
302 | 294 | | |||
303 | if (job->error() && job->error() != KIO::ERR_USER_CANCELED && !errorPrinted) { | 295 | if (job->error() && job->error() != KIO::ERR_USER_CANCELED && !errorPrinted) { | ||
304 | errorPrinted = true; | 296 | errorPrinted = true; | ||
305 | KMessageBox::error(parentWidget, i18n("I/O error while comparing file %1 with %2.", | 297 | KMessageBox::detailedError(parentWidget, i18n("I/O error while comparing file %1 with %2.", | ||
306 | leftURL.toDisplayString(QUrl::PreferLocalFile), | 298 | left.toDisplayString(QUrl::PreferLocalFile), | ||
307 | rightURL.toDisplayString(QUrl::PreferLocalFile))); | 299 | right.toDisplayString(QUrl::PreferLocalFile)), | ||
300 | job->errorString()); | ||||
308 | } | 301 | } | ||
309 | 302 | | |||
310 | if (leftReadJob == 0 && rightReadJob == 0) { | 303 | if (leftReadJob == 0 && rightReadJob == 0) { | ||
311 | if (!compareArray.size()) | 304 | if (!compareArray.size()) | ||
312 | sync->compareContentResult(item, true); | 305 | sync->compareContentResult(item, true); | ||
313 | else | 306 | else | ||
314 | sync->compareContentResult(item, false); | 307 | sync->compareContentResult(item, false); | ||
315 | 308 | | |||
Show All 16 Lines | 314 | { | |||
332 | 325 | | |||
333 | m_state = ST_STATE_READY; | 326 | m_state = ST_STATE_READY; | ||
334 | } | 327 | } | ||
335 | 328 | | |||
336 | void CompareContentTask::sendStatusMessage() | 329 | void CompareContentTask::sendStatusMessage() | ||
337 | { | 330 | { | ||
338 | double perc = (size == 0) ? 1. : (double)received / (double)size; | 331 | double perc = (size == 0) ? 1. : (double)received / (double)size; | ||
339 | int percent = (int)(perc * 10000. + 0.5); | 332 | int percent = (int)(perc * 10000. + 0.5); | ||
340 | QString statstr = QString("%1.%2%3").arg(percent / 100).arg((percent / 10) % 10).arg(percent % 10) + '%'; | 333 | QString statstr = | ||
341 | setStatusMessage(i18n("Comparing file %1 (%2)...", leftURL.fileName(), statstr)); | 334 | QString("%1.%2%3").arg(percent / 100).arg((percent / 10) % 10).arg(percent % 10) + '%'; | ||
335 | setStatusMessage(i18n("Comparing file %1 (%2)...", left.fileName(), statstr)); | ||||
342 | timer->setSingleShot(true); | 336 | timer->setSingleShot(true); | ||
343 | timer->start(500); | 337 | timer->start(500); | ||
344 | } | 338 | } | ||
345 | |