OSDN Git Service

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