OSDN Git Service

27dee16eedfdd1ddc07e81463e14b5e8cf748331
[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 QString &srcPath, *m_CopyList) {\r
30         if (isStopRequested()) {\r
31             emit canceled();\r
32             return;\r
33         }\r
34         Listup(srcPath, 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                     QFile(tgtInfo.absoluteFilePath()).remove();\r
105                 }\r
106                 else if (prevCopyMethod == OverWriteDialog::OverWriteIfNew) {\r
107                     if (srcInfo.lastModified() <= tgtInfo.lastModified()) {\r
108                         emit success(tr("スキップ"));\r
109                         skipCount++;\r
110                         break;\r
111                     }\r
112                     QFile(tgtInfo.absoluteFilePath()).remove();\r
113                 }\r
114                 else if (prevCopyMethod == OverWriteDialog::AppendNumber) {\r
115                     QString baseName = tgtInfo.baseName();\r
116                     QString suffix = tgtInfo.completeSuffix();\r
117                     for (int n = 1; ; n++) {\r
118                         QString newName = baseName + tr("%1.").arg(n) + suffix;\r
119                         tgtInfo.setFile(tgtInfo.absolutePath(), newName);\r
120                         if (!tgtInfo.exists()) {\r
121                             break;\r
122                         }\r
123                     }\r
124                     emit operation(tr("=>") + tgtInfo.fileName() + tr("にリネーム"));\r
125                 }\r
126                 else if (prevCopyMethod == OverWriteDialog::Skip) {\r
127                     emit success(tr("スキップ"));\r
128                     skipCount++;\r
129                     break;\r
130                 }\r
131                 else if (prevCopyMethod == OverWriteDialog::Rename) {\r
132                     tgtInfo.setFile(tgtInfo.absolutePath(), alias);\r
133                     emit operation(tr("=>") + tgtInfo.fileName() + tr("にリネーム"));\r
134                 }\r
135             }\r
136 \r
137             ret = QFile::copy(srcInfo.absoluteFilePath(), tgtInfo.absoluteFilePath());\r
138             if (ret) {\r
139                 successCount++;\r
140                 emit success(tr("成功"));\r
141                 if (m_Move) {\r
142                     ret = QFile(srcInfo.absoluteFilePath()).remove();\r
143                     if (!ret) {\r
144                         errDelCount++;\r
145                         emit error("元ファイルの削除に失敗");\r
146                     }\r
147                 }\r
148 \r
149             }\r
150             else {\r
151                 errorCount++;\r
152                 emit error(tr("失敗"));\r
153             }\r
154         } while (0);\r
155 \r
156         msg = tr("%1ファイル成功。").arg(successCount);\r
157         if (skipCount > 0) {\r
158             msg += tr("%1ファイルスキップ。").arg(skipCount);\r
159         }\r
160         if (errorCount > 0) {\r
161             msg += tr("%1ファイル失敗。").arg(errorCount);\r
162         }\r
163         if (errDelCount > 0) {\r
164             msg += tr("%1ファイル削除失敗。").arg(errDelCount);\r
165         }\r
166         m_progressText->setText(msg);\r
167     }\r
168 \r
169     if (m_Move) {\r
170         // フォルダを削除する\r
171         for (it = m_CopyMap.begin(); it != m_CopyMap.end(); it++) {\r
172             if (QFileInfo(it.key()).isDir()) {\r
173                 QDir().rmpath(it.key());\r
174             }\r
175         }\r
176     }\r
177 \r
178     emit finished();\r
179 }\r
180 \r
181 void CopyMoveWorker::Listup(const QString &srcPath, const QString &tgtPath)\r
182 {\r
183     if (isStopRequested()) {\r
184         return;\r
185     }\r
186 \r
187     QFileInfo info(srcPath);\r
188     QDir tgtDir(tgtPath);\r
189 \r
190     m_CopyMap.insert(srcPath, tgtDir.absoluteFilePath(info.fileName()));\r
191 //    qDebug() << srcPath << " -> " << tgtDir.absoluteFilePath(info.fileName());\r
192     if (info.isDir()) {\r
193         QDir srcDir(srcPath);\r
194         foreach (QFileInfo info2, srcDir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst)) {\r
195             Listup(info2.absoluteFilePath(),\r
196                    tgtDir.absoluteFilePath(info.fileName()));\r
197         }\r
198     }\r
199 }\r