OSDN Git Service

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