OSDN Git Service

Ver0.21
[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     AbstractWorker(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 successCount = 0;\r
39     int skipCount = 0;\r
40     int errorCount = 0;\r
41     int errDelCount = 0;\r
42     QString msg;\r
43     QString copyMethod;\r
44     QString alias;\r
45     StringMap::iterator it;\r
46     for (it = m_CopyMap.begin(); it != m_CopyMap.end(); it++) {\r
47         if (isStopRequested()) {\r
48             emit canceled();\r
49             return;\r
50         }\r
51         QFileInfo srcInfo(it.key());\r
52         QFileInfo tgtInfo(it.value());\r
53 \r
54         emit operation((m_Move ? tr("移動") : tr("コピー:"))\r
55                      + srcInfo.absoluteFilePath()\r
56                      + tr(" -> ")\r
57                      + tgtInfo.absoluteFilePath());\r
58 \r
59         if (srcInfo.isDir()) {\r
60             if (tgtInfo.exists()) {\r
61                 emit success(tr("すでに存在"));\r
62             }\r
63             else if (QDir().mkdir(it.value())) {\r
64                 emit success("フォルダ作成");\r
65             }\r
66             else {\r
67                 emit error("フォルダの作成に失敗");\r
68             }\r
69             continue;\r
70         }\r
71 \r
72         do {    // コピーをスキップするのにbreakを使うがためのdo-while\r
73             if (tgtInfo.exists()) {\r
74                 // 解決方法を選択\r
75                 m_Asking = true;\r
76                 emit askOverWrite(&copyMethod,\r
77                                   &alias,\r
78                                   srcInfo.absoluteFilePath(),\r
79                                   tgtInfo.absoluteFilePath());\r
80 \r
81                 while (isAsking()) {\r
82                     thread()->msleep(100);\r
83                 }\r
84 \r
85                 // キャンセルされた?\r
86                 if (isStopRequested()) {\r
87                     msg = tr("%1個のファイルをコピーしました。").arg(successCount);\r
88                     if (skipCount > 0) {\r
89                         msg += tr("%1個のファイルをスキップしました。").arg(skipCount);\r
90                     }\r
91                     if (errorCount > 0) {\r
92                         msg += tr("%1個のファイルをコピーできませんでした。").arg(errorCount);\r
93                     }\r
94                     m_progressText->setText(msg);\r
95                     emit canceled();\r
96                     return;\r
97                 }\r
98 \r
99                 if (copyMethod == "rbOverWrite") {\r
100                     if (srcInfo.absoluteFilePath() == tgtInfo.absoluteFilePath()) {\r
101                         emit success(tr("同一ファイルへの操作のためスキップ"));\r
102                         skipCount++;\r
103                         break;\r
104                     }\r
105                     QFile(tgtInfo.absoluteFilePath()).remove();\r
106                 }\r
107                 else if (copyMethod == "rbOverWriteIfNew") {\r
108                     if (srcInfo.lastModified() <= tgtInfo.lastModified()) {\r
109                         emit success(tr("古いファイルのためスキップ"));\r
110                         skipCount++;\r
111                         break;\r
112                     }\r
113                     if (srcInfo.absoluteFilePath() == tgtInfo.absoluteFilePath()) {\r
114                         emit success(tr("同一ファイルへの操作のためスキップ"));\r
115                         skipCount++;\r
116                         break;\r
117                     }\r
118                     QFile(tgtInfo.absoluteFilePath()).remove();\r
119                 }\r
120                 else if (copyMethod == "rbAppendNumber") {\r
121                     QString baseName = tgtInfo.baseName();\r
122                     QString suffix = tgtInfo.completeSuffix();\r
123                     for (int n = 1; ; n++) {\r
124                         QString newName = baseName + tr("%1.").arg(n) + suffix;\r
125                         tgtInfo.setFile(tgtInfo.absolutePath(), newName);\r
126                         if (!tgtInfo.exists()) {\r
127                             break;\r
128                         }\r
129                     }\r
130                     emit operation(tr("=>") + tgtInfo.fileName() + tr("にリネーム"));\r
131                 }\r
132                 else if (copyMethod == "rbSkip") {\r
133                     emit success(tr("スキップ"));\r
134                     skipCount++;\r
135                     break;\r
136                 }\r
137                 else if (copyMethod == "rbRename") {\r
138                     tgtInfo.setFile(tgtInfo.absolutePath(), alias);\r
139                     emit operation(tr("=>") + tgtInfo.fileName() + tr("にリネーム"));\r
140                 }\r
141                 else {\r
142                     qDebug() << "Unknown method : " << copyMethod;\r
143                     Q_ASSERT(false);\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             else {\r
160                 errorCount++;\r
161                 emit error(tr("失敗"));\r
162             }\r
163         } while (0);\r
164 \r
165         msg = tr("%1ファイル成功。").arg(successCount);\r
166         if (skipCount > 0) {\r
167             msg += tr("%1ファイルスキップ。").arg(skipCount);\r
168         }\r
169         if (errorCount > 0) {\r
170             msg += tr("%1ファイル失敗。").arg(errorCount);\r
171         }\r
172         if (errDelCount > 0) {\r
173             msg += tr("%1ファイル削除失敗。").arg(errDelCount);\r
174         }\r
175         m_progressText->setText(msg);\r
176     }\r
177 \r
178     if (m_Move) {\r
179         // フォルダを削除する\r
180         for (it = m_CopyMap.begin(); it != m_CopyMap.end(); it++) {\r
181             if (QFileInfo(it.key()).isDir()) {\r
182                 QDir().rmpath(it.key());\r
183             }\r
184         }\r
185     }\r
186 \r
187     emit finished();\r
188 }\r
189 \r
190 void CopyMoveWorker::Listup(const QString &srcPath, const QString &tgtPath)\r
191 {\r
192     if (isStopRequested()) {\r
193         return;\r
194     }\r
195 \r
196     QFileInfo info(srcPath);\r
197     QDir tgtDir(tgtPath);\r
198 \r
199     m_CopyMap.insert(srcPath, tgtDir.absoluteFilePath(info.fileName()));\r
200     qDebug() << srcPath << " -> " << tgtDir.absoluteFilePath(info.fileName());\r
201     if (info.isDir()) {\r
202         QDir srcDir(srcPath);\r
203         foreach (QFileInfo info2, srcDir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst)) {\r
204             Listup(info2.absoluteFilePath(),\r
205                    tgtDir.absoluteFilePath(info.fileName()));\r
206         }\r
207     }\r
208 }\r