OSDN Git Service

8f421877dc0a9019569cb7cc163405c6c7988f98
[tpi/lychee.git] / src / lychee / dlg_process.cpp
1 /*******************************************************************************\r
2   TPI - flexible but useless plug-in framework.\r
3   Copyright (C) 2002-2009 Silky\r
4 \r
5   This library is free software; you can redistribute it and/or modify it under\r
6   the terms of the GNU Lesser General Public License as published by the Free\r
7   Software Foundation; either version 2.1 of the License, or (at your option)\r
8   any later version.\r
9 \r
10   This library is distributed in the hope that it will be useful, but WITHOUT\r
11   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or \r
12   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License\r
13   for more details.\r
14 \r
15   You should have received a copy of the GNU Lesser General Public License along\r
16   with this library; if not, write to the Free Software Foundation, Inc.,\r
17   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r
18 \r
19   $Id$\r
20 *******************************************************************************/\r
21 \r
22 #include "lychee.h"\r
23 #include "dlg_process.h"\r
24 #include "dlg_make.h"\r
25 #include "frm_main.h"\r
26 #include "functions.h"\r
27 \r
28 ProcessDialog * g_procDlg = NULL;\r
29 \r
30 //******************************************************************************\r
31 // ProcessDialog\r
32 //******************************************************************************\r
33 \r
34 ProcessDialog::ProcessDialog(): wxDialog()\r
35 {\r
36         ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_process.xrc"));\r
37         ::wxXmlResource::Get()->LoadDialog(this, this->GetParent(), wxT("dlg_process"));        \r
38 }\r
39 \r
40 ProcessDialog::~ProcessDialog()\r
41 {\r
42         g_procDlg = NULL;\r
43 }\r
44 \r
45 //******************************************************************************\r
46 // Event table.\r
47 //******************************************************************************\r
48 \r
49 BEGIN_EVENT_TABLE(ProcessDialog, wxDialog)\r
50         EVT_INIT_DIALOG(ProcessDialog::OnInit)\r
51         EVT_CLOSE(ProcessDialog::OnClose)\r
52 END_EVENT_TABLE()\r
53 \r
54 //******************************************************************************\r
55 // Event handler.\r
56 //******************************************************************************\r
57 \r
58 void ProcessDialog::OnInit(wxInitDialogEvent &)\r
59 {\r
60         // XRCと結びつけ。\r
61         this->ebTarget          = XRCCTRL(* this, "ebTarget",     wxTextCtrl);\r
62         this->ebSource          = XRCCTRL(* this, "ebSource",     wxTextCtrl);\r
63         this->gFile             = XRCCTRL(* this, "gFile",        wxGauge);\r
64         this->gArchive          = XRCCTRL(* this, "gArchive",     wxGauge);\r
65         this->fCancel           = false;\r
66         this->nOverwriteMode    = wxID_OK;\r
67         g_procDlg = this;\r
68 \r
69         ::wxXmlResource::Get()->Unload(L_DIR_S_XRC wxT("dlg_process.xrc"));\r
70 }\r
71 \r
72 void ProcessDialog::OnClose(wxCloseEvent & e)\r
73 {\r
74         if (e.CanVeto() && ::AskDlg(_("Really do you want to cancel this operation?"), this) == wxYES)\r
75         {\r
76                 this->fCancel = true;\r
77         }\r
78         e.Veto();\r
79 }\r
80 \r
81 int ProcessDialog::CallbackProc(unsigned int _uMsg, void * _pStructure)\r
82 {\r
83         if (_uMsg != TPI_NOTIFY_COMMON)\r
84         {\r
85                 return TPI_CALLBACK_UNSUPPORTED;\r
86         }\r
87 \r
88         TPI_PROCESSINFO * piInfo = (TPI_PROCESSINFO *) _pStructure;\r
89         if (piInfo == NULL || ! this->IsShown())\r
90         {\r
91                 return TPI_CALLBACK_CONTINUE;\r
92         }\r
93 \r
94         switch (piInfo->eMessage)\r
95         {\r
96         case TPI_MESSAGE_STATUS:\r
97         {\r
98                 static int s_nGaugeCounter = 0, s_nInterval = 0;\r
99                 switch (piInfo->eStatus)\r
100                 {\r
101                 case TPI_STATUS_OPENARCHIVE:\r
102                         this->ebSource->ChangeValue(piInfo->fiInfo.fnFileName.GetFullPath());\r
103                         break;\r
104                 case TPI_STATUS_BEGINPROCESS:\r
105                         // 小さなファイルなら表示しない。\r
106                         if (piInfo->fiInfo.nUnpackedSize > 10000)\r
107                         {\r
108                                 this->ebSource->ChangeValue(piInfo->fiInfo.fnFileName.GetFullPath());\r
109                                 this->ebTarget->ChangeValue(piInfo->fnDestination.GetFullPath());\r
110                                 this->gFile->SetRange(piInfo->fiInfo.nUnpackedSize);\r
111                                 this->gFile->SetValue(0);\r
112                                 ::wxSafeYield(this, true);\r
113                         }\r
114                         break;\r
115                 case TPI_STATUS_INPROCESS:\r
116                         if (piInfo->fiInfo.nUnpackedSize > 10000)\r
117                         {\r
118                                 this->gFile->SetValue(piInfo->nProcessedSize);\r
119                                 ::wxSafeYield(this, true);\r
120                         }\r
121                         break;\r
122                 case TPI_STATUS_ENDPROCESS:\r
123                         if (s_nGaugeCounter++ > s_nInterval)\r
124                         {\r
125                                 this->gArchive->SetValue(this->gArchive->GetValue() + s_nInterval);\r
126                                 ::wxSafeYield(this, true);\r
127                                 s_nGaugeCounter = 0;\r
128                         }\r
129                         break;\r
130                 // 書庫ロード時用の独自仕様。\r
131                 case 0x1000:\r
132                         this->ebSource->ChangeValue(piInfo->fiInfo.fnFileName.GetFullPath());\r
133                         this->gArchive->SetRange(piInfo->fiInfo.nUnpackedSize);\r
134                         this->gArchive->SetValue(0);\r
135                         s_nInterval = piInfo->fiInfo.nUnpackedSize / 10;\r
136                         break;\r
137                 case 0x1001:\r
138                         if (piInfo->fiInfo.nUnpackedSize > 10000)\r
139                         {\r
140                                 this->ebTarget->ChangeValue(piInfo->fiInfo.fnFileName.GetFullPath());\r
141                         }\r
142                         if (s_nGaugeCounter++ > s_nInterval)\r
143                         {\r
144                                 this->gArchive->SetValue(piInfo->nProcessedSize);\r
145                                 ::wxSafeYield(this, true);\r
146                                 s_nGaugeCounter = 0;\r
147                         }\r
148                         break;\r
149                 }\r
150                 break;\r
151         }\r
152         case TPI_MESSAGE_ASK:\r
153         {\r
154                 switch (piInfo->eStatus)\r
155                 {\r
156                 case TPI_PARAM_PASSWORD:\r
157                 {\r
158                         static wxFileName fnFormer;\r
159                         static wxString szFormer;\r
160                         if (piInfo->fiInfo.fnFileName == fnFormer)\r
161                         {\r
162                                 piInfo->szParam = ::wxGetPasswordFromUser(_("Password for:\n") + piInfo->fiInfo.fnFileName.GetFullPath(), wxT("Lychee"), wxEmptyString, this);\r
163                                 if (piInfo->szParam.IsEmpty())\r
164                                 {\r
165                                         this->fCancel = true;\r
166                                 }\r
167                                 szFormer = piInfo->szParam;\r
168                         }\r
169                         else\r
170                         {\r
171                                 piInfo->szParam = szFormer;\r
172                                 fnFormer = piInfo->fiInfo.fnFileName;\r
173                         }\r
174                         break;\r
175                 }\r
176                 case TPI_PARAM_NEXTVOLUME:\r
177                 {\r
178                         wxFileDialog fd(this, _("Select next volume of: ") + piInfo->fiInfo.fnFileName.GetFullName());\r
179                         fd.SetWindowStyleFlag(wxFD_FILE_MUST_EXIST);\r
180                         if (fd.ShowModal() == wxID_CANCEL)\r
181                         {\r
182                                 this->fCancel = true;\r
183                         }\r
184                         piInfo->szParam = fd.GetPath();\r
185                         break;\r
186                 }\r
187                 case TPI_PARAM_DEST:\r
188                         if (piInfo->fnDestination.FileExists() || ::wxDirExists(piInfo->fnDestination.GetFullPath()))\r
189                         {\r
190                                 // 上書き確認を行う。\r
191                                 bool bPerm = false;\r
192                                 if (this->nOverwriteMode == wxID_OK)\r
193                                 {\r
194                                         OverwriteDialog odDlg;\r
195                                         odDlg.fnExist = & piInfo->fnDestination;\r
196                                         odDlg.tmWrite = & piInfo->fiInfo.tmModified;\r
197                                         odDlg.nWriteSize = piInfo->fiInfo.nUnpackedSize;\r
198 \r
199                                         this->nOverwriteMode = odDlg.ShowModal();\r
200                                         bPerm = odDlg.cbApplyAll->IsChecked();\r
201                                 }\r
202                                 else\r
203                                 {\r
204                                         bPerm = true;\r
205                                 }\r
206                                 switch (this->nOverwriteMode)\r
207                                 {\r
208                                 case wxID_CANCEL:\r
209                                         this->fCancel = true;\r
210                                         break;\r
211                                 case 0:\r
212                                         // 自動上書き。既存のファイルを削除しておく。\r
213                                         if (piInfo->fnDestination.FileExists())\r
214                                         {\r
215                                                 ::wxRemoveFile(piInfo->fnDestination.GetFullPath());\r
216                                         }\r
217                                         else if (::wxDirExists(piInfo->fnDestination.GetFullPath()))\r
218                                         {\r
219                                                 // TODO: 再帰削除。\r
220                                                 ::wxRmdir(piInfo->fnDestination.GetFullPath());\r
221                                         }\r
222                                         break;\r
223                                 case 1:\r
224                                         // 自動スキップ。\r
225                                         piInfo->fnDestination.Clear();\r
226                                         break;\r
227                                 case 2:\r
228                                         // 自動リネーム。\r
229                                         break;\r
230                                 }\r
231                                 if (! bPerm)\r
232                                 {\r
233                                         this->nOverwriteMode = wxID_OK;\r
234                                 }\r
235                         }\r
236                         break;\r
237                 default:\r
238                         return TPI_CALLBACK_UNSUPPORTED;\r
239                 }\r
240                 break;\r
241         }\r
242         default:\r
243                 return TPI_CALLBACK_UNSUPPORTED;\r
244         }\r
245 \r
246         return this->fCancel ? TPI_CALLBACK_CANCEL : TPI_CALLBACK_CONTINUE;\r
247 }\r
248 //******************************************************************************\r
249 // OverwriteDialog\r
250 //******************************************************************************\r
251 \r
252 OverwriteDialog::OverwriteDialog(): wxDialog()\r
253 {\r
254         ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_overwrite.xrc"));\r
255         ::wxXmlResource::Get()->LoadDialog(this, this->GetParent(), wxT("dlg_overwrite"));      \r
256 }\r
257 \r
258 //******************************************************************************\r
259 // Event table.\r
260 //******************************************************************************\r
261 \r
262 BEGIN_EVENT_TABLE(OverwriteDialog, wxDialog)\r
263         EVT_INIT_DIALOG(OverwriteDialog::OnInit)\r
264         EVT_BUTTON(XRCID("btnOverwrite"), OverwriteDialog::OnBtnOverwrite)\r
265         EVT_BUTTON(XRCID("btnSkip"), OverwriteDialog::OnBtnSkip)\r
266         EVT_BUTTON(XRCID("btnAuto"), OverwriteDialog::OnBtnAuto)\r
267         EVT_BUTTON(XRCID("btnBrowse"), OverwriteDialog::OnBtnBrowse)\r
268         EVT_CLOSE(OverwriteDialog::OnClose)\r
269 END_EVENT_TABLE()\r
270 \r
271 //******************************************************************************\r
272 // Event handler.\r
273 //******************************************************************************\r
274 \r
275 void OverwriteDialog::OnInit(wxInitDialogEvent &)\r
276 {\r
277         // XRCと結びつけ。\r
278         this->ebTarget          = XRCCTRL(* this, "ebTarget",     wxTextCtrl);\r
279         this->cbApplyAll        = XRCCTRL(* this, "cbApplyAll",   wxCheckBox);\r
280         ::wxXmlResource::Get()->Unload(L_DIR_S_XRC wxT("dlg_overwrite.xrc"));\r
281 \r
282         // ファイル情報を設定。\r
283         this->ebTarget->SetValue(this->fnExist->GetFullPath());\r
284         XRCCTRL(* this, "stExistTime", wxStaticText)->SetLabel(this->fnExist->GetModificationTime().Format(_("%Y/%m/%d %H:%M:%S modified, ")));\r
285         XRCCTRL(* this, "stExistSize", wxStaticText)->SetLabel(this->fnExist->GetHumanReadableSize());\r
286         XRCCTRL(* this, "stWriteTime", wxStaticText)->SetLabel(this->tmWrite->Format(_("%Y/%m/%d %H:%M:%S modified, ")));\r
287         XRCCTRL(* this, "stWriteSize", wxStaticText)->SetLabel(wxFileName::GetHumanReadableSize((wxULongLong) this->nWriteSize));\r
288         XRCCTRL(* this, "sbIcon", wxStaticBitmap)->SetIcon(GetFileTypeIcon(* this->fnExist));\r
289 }\r
290 \r
291 void OverwriteDialog::OnClose(wxCloseEvent & e)\r
292 {\r
293         if (e.CanVeto() && ::AskDlg(_("Really do you want to cancel this operation?"), this) == wxYES)\r
294         {\r
295                 this->EndModal(wxID_CANCEL);\r
296         }\r
297         e.Veto();\r
298 }\r
299 \r
300 void OverwriteDialog::OnBtnOverwrite(wxCommandEvent&)\r
301 {\r
302         if (this->fnExist->GetFullPath() != this->ebTarget->GetValue())\r
303         {\r
304                 // 保存先を変えているので、次回もダイアログを表示。\r
305                 this->cbApplyAll->SetValue(false);\r
306                 * this->fnExist = wxFileName(this->ebTarget->GetValue());\r
307         }\r
308         this->EndModal(0);\r
309 }\r
310 \r
311 void OverwriteDialog::OnBtnSkip(wxCommandEvent&)\r
312 {\r
313         this->EndModal(1);\r
314 }\r
315 \r
316 void OverwriteDialog::OnBtnAuto(wxCommandEvent&)\r
317 {\r
318         this->EndModal(2);\r
319 }\r
320 \r
321 void OverwriteDialog::OnBtnBrowse(wxCommandEvent&)\r
322 {\r
323         wxFileDialog fd(this);\r
324         fd.SetWindowStyleFlag(wxFD_SAVE | wxFD_OVERWRITE_PROMPT);\r
325         fd.SetPath(this->ebTarget->GetValue());\r
326         if (fd.ShowModal() == wxID_OK)\r
327         {\r
328                 this->ebTarget->SetValue(fd.GetPath());\r
329         }\r
330 }\r
331 \r
332 //******************************************************************************\r
333 //    ダイアログプロシージャ\r
334 //******************************************************************************\r
335 \r
336 int __stdcall TPICallbackProc(unsigned int _uMsg, void * _pStructure)\r
337 {\r
338         return g_procDlg == NULL ? TPI_CALLBACK_CONTINUE : g_procDlg->CallbackProc(_uMsg, _pStructure);\r
339 }\r