OSDN Git Service

ファイル読込の中止処理を修正
[gefu/Gefu.git] / copymoveworker.cpp
1 #include "copymoveworker.h"\r
2 #include "overwritedialog.h"\r
3 #include <QDir>\r
4 #include <QFileInfo>\r
5 #include <QDebug>\r
6 #include <QDateTime>\r
7 #include <QThread>\r
8 \r
9 const int SLEEP_TIME = 1;\r
10 \r
11 CopyMoveWorker::CopyMoveWorker() :\r
12     OperationWorker(),\r
13     m_CopyList(),\r
14     m_tgtDir(),\r
15     m_CopyMap(),\r
16     m_AskingMutex(),\r
17     m_Asking(false),\r
18     m_Move(false)\r
19 {\r
20 }\r
21 \r
22 void CopyMoveWorker::Listup(const QString &srcPath, const QString &tgtPath)\r
23 {\r
24     if (isAborted()) {\r
25         return;\r
26     }\r
27     this->thread()->msleep(SLEEP_TIME);\r
28 \r
29     QFileInfo info(srcPath);\r
30     QDir tgtDir(tgtPath);\r
31 \r
32     m_CopyMap.insert(srcPath, tgtDir.absoluteFilePath(info.fileName()));\r
33     if (!info.isDir()) {\r
34         return;\r
35      }\r
36 \r
37     QDir srcDir(srcPath);\r
38     QFileInfoList list = srcDir.entryInfoList(QDir::NoDotAndDotDot |\r
39                                               QDir::System |\r
40                                               QDir::Hidden |\r
41                                               QDir::AllDirs |\r
42                                               QDir::Files,\r
43                                               QDir::DirsFirst);\r
44     foreach (QFileInfo info2, list) {\r
45         Listup(info2.absoluteFilePath(),\r
46                tgtDir.absoluteFilePath(info.fileName()));\r
47     }\r
48 }\r
49 \r
50 ///////////////////////////////////////////////////////////////////////////////\r
51 /// \brief CopyMoveWorker::run\r
52 ///\r
53 void CopyMoveWorker::run()\r
54 {\r
55     foreach (const QString &path, m_CopyList) {\r
56         if (isAborted()) {\r
57             emit finished(true);\r
58             return;\r
59         }\r
60         Listup(path, m_tgtDir);\r
61     }\r
62 \r
63     bool ret;\r
64     int successCount = 0;\r
65     int skipCount = 0;\r
66     int errorCount = 0;\r
67     int errDelCount = 0;\r
68     const QString operation = (m_Move) ? tr("移動:%1 -> %2") :\r
69                                          tr("コピー:%1 -> %2");\r
70     QString msg;\r
71     QString copyMethod;\r
72     QString alias;\r
73     StringMap::iterator it;\r
74     for (it = m_CopyMap.begin(); it != m_CopyMap.end(); it++) {\r
75         this->thread()->msleep(SLEEP_TIME);\r
76         if (isAborted()) {\r
77             emit finished(true);\r
78             return;\r
79         }\r
80         QFileInfo srcInfo(it.key());\r
81         QFileInfo tgtInfo(it.value());\r
82 \r
83         emit progress(operation\r
84                       .arg(srcInfo.absoluteFilePath())\r
85                       .arg(tgtInfo.absoluteFilePath()));\r
86 \r
87         if (srcInfo.isDir()) {\r
88             if (tgtInfo.exists()) {\r
89                 emit success(tr("すでに存在"));\r
90             }\r
91             else if (QDir().mkdir(it.value())) {\r
92                 emit success("フォルダ作成");\r
93             }\r
94             else {\r
95                 emit error("フォルダの作成に失敗");\r
96             }\r
97             continue;\r
98         }\r
99 \r
100         do {    // コピーをスキップするのにbreakを使うがためのdo-while\r
101             if (tgtInfo.exists()) {\r
102                 // 解決方法を選択\r
103                 m_Asking = true;\r
104                 emit askOverWrite(&copyMethod,\r
105                                   &alias,\r
106                                   srcInfo.absoluteFilePath(),\r
107                                   tgtInfo.absoluteFilePath());\r
108 \r
109                 while (isAsking()) {\r
110                     thread()->msleep(100);\r
111                 }\r
112 \r
113                 // キャンセルされた?\r
114                 if (isAborted()) {\r
115                     msg = tr("%1個のファイルをコピーしました。").arg(successCount);\r
116                     if (skipCount > 0) {\r
117                         msg += tr("%1個のファイルをスキップしました。").arg(skipCount);\r
118                     }\r
119                     if (errorCount > 0) {\r
120                         msg += tr("%1個のファイルをコピーできませんでした。").arg(errorCount);\r
121                     }\r
122                     emit progress(msg);\r
123                     emit finished(true);\r
124                     return;\r
125                 }\r
126 \r
127                 if (copyMethod == "rbOverWrite") {\r
128                     if (srcInfo.absoluteFilePath() == tgtInfo.absoluteFilePath()) {\r
129                         emit success(tr("同一ファイルへの操作のためスキップ"));\r
130                         skipCount++;\r
131                         break;\r
132                     }\r
133                     QFile(tgtInfo.absoluteFilePath()).remove();\r
134                 }\r
135                 else if (copyMethod == "rbOverWriteIfNew") {\r
136                     if (srcInfo.lastModified() <= tgtInfo.lastModified()) {\r
137                         emit success(tr("古いファイルのためスキップ"));\r
138                         skipCount++;\r
139                         break;\r
140                     }\r
141                     if (srcInfo.absoluteFilePath() == tgtInfo.absoluteFilePath()) {\r
142                         emit success(tr("同一ファイルへの操作のためスキップ"));\r
143                         skipCount++;\r
144                         break;\r
145                     }\r
146                     QFile(tgtInfo.absoluteFilePath()).remove();\r
147                 }\r
148                 else if (copyMethod == "rbAppendNumber") {\r
149                     QString baseName = tgtInfo.baseName();\r
150                     QString suffix = tgtInfo.completeSuffix();\r
151                     for (int n = 1; ; n++) {\r
152                         QString newName = baseName + tr("%1.").arg(n) + suffix;\r
153                         tgtInfo.setFile(tgtInfo.absolutePath(), newName);\r
154                         if (!tgtInfo.exists()) {\r
155                             break;\r
156                         }\r
157                     }\r
158                     emit progress(tr("=> %1 にリネーム").arg(tgtInfo.fileName()));\r
159                 }\r
160                 else if (copyMethod == "rbSkip") {\r
161                     emit success(tr("スキップ"));\r
162                     skipCount++;\r
163                     break;\r
164                 }\r
165                 else if (copyMethod == "rbRename") {\r
166                     tgtInfo.setFile(tgtInfo.absolutePath(), alias);\r
167                     emit progress(tr("=> %1 にリネーム").arg(tgtInfo.fileName()));\r
168                 }\r
169                 else {\r
170                     qDebug() << "Unknown method : " << copyMethod;\r
171                     Q_ASSERT(false);\r
172                 }\r
173             }\r
174 \r
175             ret = QFile::copy(srcInfo.absoluteFilePath(), tgtInfo.absoluteFilePath());\r
176             if (ret) {\r
177                 successCount++;\r
178                 emit success(tr("成功"));\r
179                 if (m_Move && srcInfo.absoluteFilePath() != tgtInfo.absoluteFilePath()) {\r
180                     ret = QFile(srcInfo.absoluteFilePath()).remove();\r
181                     if (!ret) {\r
182                         errDelCount++;\r
183                         emit error("元ファイルの削除に失敗");\r
184                     }\r
185                 }\r
186             }\r
187             else {\r
188                 errorCount++;\r
189                 emit error(tr("失敗"));\r
190             }\r
191         } while (0);\r
192 \r
193         msg = tr("%1ファイル成功。").arg(successCount);\r
194         if (skipCount > 0) {\r
195             msg += tr("%1ファイルスキップ。").arg(skipCount);\r
196         }\r
197         if (errorCount > 0) {\r
198             msg += tr("%1ファイル失敗。").arg(errorCount);\r
199         }\r
200         if (errDelCount > 0) {\r
201             msg += tr("%1ファイル削除失敗。").arg(errDelCount);\r
202         }\r
203         emit information(msg);\r
204     }\r
205 \r
206     if (m_Move) {\r
207         // フォルダを削除する\r
208         for (it = m_CopyMap.begin(); it != m_CopyMap.end(); it++) {\r
209             if (QFileInfo(it.key()).isDir()) {\r
210                 QDir().rmpath(it.key());\r
211             }\r
212         }\r
213     }\r
214 \r
215     emit finished();\r
216 }\r
217 \r
218 QString CopyMoveWorker::initialText() const\r
219 {\r
220     if (m_Move) {\r
221         return tr("移動準備中...");\r
222     }\r
223     else {\r
224         return tr("コピー準備中...");\r
225     }\r
226 }\r