OSDN Git Service

eae8d1e2722a2d2a09523ec77f5cacb6241c218d
[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(wxWindow * parent, wxULongLong_t n, wxString szPassword): wxDialog(), nFileCount(n), szPassword(szPassword)\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         g_procDlg = this;\r
39         this->hParent = parent;\r
40         this->InitDialog();\r
41 }\r
42 \r
43 ProcessDialog::~ProcessDialog()\r
44 {\r
45         // ウインドウの機能を有効化。\r
46         MainFrame * frm_main = (MainFrame *) this->hParent;\r
47         frm_main->tree_ctrl->Thaw();\r
48         frm_main->list_ctrl->Thaw();\r
49         frm_main->menubar->EnableTop(0, true);\r
50         frm_main->menubar->EnableTop(1, true);\r
51         frm_main->menubar->EnableTop(2, true);\r
52         frm_main->toolbar->Enable();\r
53 \r
54         // 書庫を開く途中に中断した場合、書庫を閉じる処理を行う。\r
55         if (this->fOpen && this->fCancel)\r
56         {\r
57                 wxCommandEvent e;\r
58                 frm_main->OnArcClose(e);\r
59         }\r
60 \r
61 #ifdef __WINDOWS__\r
62         if (this->tlTaskbar != NULL)\r
63         {\r
64                 this->tlTaskbar->SetProgressState(this->hTBWnd, TBPF_NOPROGRESS);\r
65                 this->tlTaskbar->Release();\r
66         }\r
67 #endif\r
68         ((MainFrame *) this->hParent)->gFrame->Show(false);\r
69         g_procDlg = NULL;\r
70 }\r
71 \r
72 //******************************************************************************\r
73 // Event table.\r
74 //******************************************************************************\r
75 \r
76 BEGIN_EVENT_TABLE(ProcessDialog, wxDialog)\r
77         EVT_INIT_DIALOG(ProcessDialog::OnInit)\r
78         EVT_CLOSE(ProcessDialog::OnClose)\r
79 END_EVENT_TABLE()\r
80 \r
81 //******************************************************************************\r
82 // Event handler.\r
83 //******************************************************************************\r
84 \r
85 void ProcessDialog::OnInit(wxInitDialogEvent &)\r
86 {\r
87         // XRCと結びつけ。\r
88         this->ebTarget          = XRCCTRL(* this, "ebTarget",     wxTextCtrl);\r
89         this->ebSource          = XRCCTRL(* this, "ebSource",     wxTextCtrl);\r
90         this->gFile             = XRCCTRL(* this, "gFile",        wxGauge);\r
91         this->gArchive          = XRCCTRL(* this, "gArchive",     wxGauge);\r
92         this->fCancel           = false;\r
93         this->nOverwriteMode    = wxID_OK;\r
94         ::wxXmlResource::Get()->Unload(L_DIR_S_XRC wxT("dlg_process.xrc"));\r
95 \r
96         // コールバックを送信。\r
97         TPI_PROCESSINFO piInfo;\r
98         piInfo.eMessage = TPI_MESSAGE_STATUS;\r
99         piInfo.eStatus = 0x1000;\r
100         piInfo.fiInfo.fnFileName = ((MainFrame *) this->hParent)->fnArchive;\r
101         piInfo.fiInfo.nUnpackedSize = this->nFileCount;\r
102         this->CallbackProc(TPI_NOTIFY_COMMON, & piInfo);\r
103 \r
104         // ウインドウの機能を無効化。\r
105         MainFrame * frm_main = (MainFrame *) this->hParent;\r
106         frm_main->tree_ctrl->Freeze();\r
107         frm_main->list_ctrl->Freeze();\r
108         frm_main->menubar->EnableTop(0, false);\r
109         frm_main->menubar->EnableTop(1, false);\r
110         frm_main->menubar->EnableTop(2, false);\r
111         frm_main->toolbar->Enable(false);\r
112 #ifdef __WINDOWS__\r
113         // タスクバー。\r
114         this->hTBWnd = this->hParent->GetHandle();\r
115 \r
116         ::CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (void **) & this->tlTaskbar);\r
117         if (this->tlTaskbar != NULL)\r
118         {\r
119                 this->tlTaskbar->HrInit();\r
120         }\r
121 #endif\r
122 }\r
123 \r
124 void ProcessDialog::OnClose(wxCloseEvent & e)\r
125 {\r
126         if (e.CanVeto() && ::AskDlg(_("Really do you want to cancel this operation?"), this) == wxYES)\r
127         {\r
128                 this->fCancel = true;\r
129         }\r
130         e.Veto();\r
131 }\r
132 \r
133 int ProcessDialog::CallbackProc(unsigned int _uMsg, void * _pStructure)\r
134 {\r
135         if (_uMsg != TPI_NOTIFY_COMMON)\r
136         {\r
137                 return TPI_CALLBACK_UNSUPPORTED;\r
138         }\r
139 \r
140         TPI_PROCESSINFO * piInfo = (TPI_PROCESSINFO *) _pStructure;\r
141         if (piInfo == NULL)\r
142         {\r
143                 return TPI_CALLBACK_CONTINUE;\r
144         }\r
145 \r
146         switch (piInfo->eMessage)\r
147         {\r
148         case TPI_MESSAGE_STATUS:\r
149         {\r
150                 static int s_nProcess;\r
151 #ifdef __WINDOWS__\r
152                 static int s_nFileCount;\r
153 #endif\r
154                 static wxStopWatch sw;\r
155                 switch (piInfo->eStatus)\r
156                 {\r
157                 case TPI_STATUS_OPENARCHIVE:\r
158                         this->ebSource->ChangeValue(piInfo->fiInfo.fnFileName.GetFullPath());\r
159                         sw.Start();\r
160                         break;\r
161                 case TPI_STATUS_BEGINPROCESS:\r
162                         if (piInfo->fiInfo.nUnpackedSize > 10000)\r
163                         {\r
164                                 this->gFile->SetRange(piInfo->fiInfo.nUnpackedSize);\r
165                         }\r
166                 case TPI_STATUS_INPROCESS:\r
167                         if (sw.Time() > 500)\r
168                         {\r
169                                 if (this->IsShownOnScreen())\r
170                                 {\r
171                                         sw.Start();\r
172                                         this->ebSource->ChangeValue(piInfo->fiInfo.fnFileName.GetFullPath());\r
173                                         this->ebTarget->ChangeValue(piInfo->fnDestination.GetFullPath());\r
174                                         if (piInfo->fiInfo.nUnpackedSize > 10000)\r
175                                         {\r
176                                                 this->gFile->SetValue(piInfo->nProcessedSize);\r
177                                         }\r
178                                         this->gArchive->SetValue(s_nProcess);\r
179                                         this->Update();\r
180                                         ::wxSafeYield(this, true);\r
181                                 }\r
182                                 else\r
183                                 {\r
184                                         ::wxSafeYield(this->hParent, true);\r
185                                 }\r
186                                 ((MainFrame *) this->hParent)->gFrame->SetValue(s_nProcess);\r
187                         }\r
188 #ifdef __WINDOWS__\r
189                         if (this->tlTaskbar != NULL)\r
190                         {\r
191                                 this->tlTaskbar->SetProgressValue(this->hTBWnd, s_nProcess, s_nFileCount);\r
192                         }\r
193 #endif\r
194                         break;\r
195                 case TPI_STATUS_ENDPROCESS:\r
196                         s_nProcess++;\r
197                         break;\r
198                 // Lycheeの独自仕様。\r
199                 case 0x1000: // 初期設定。\r
200                         this->ebSource->ChangeValue(piInfo->fiInfo.fnFileName.GetFullPath());\r
201                         this->Update();\r
202                         ((MainFrame *) this->hParent)->gFrame->Show();\r
203                 case 0x1001: // 閲覧時は最初にファイル数が分からないので、ここで設定。\r
204                         this->gArchive->SetRange(piInfo->fiInfo.nUnpackedSize);\r
205                         ((MainFrame *) this->hParent)->gFrame->SetRange(piInfo->fiInfo.nUnpackedSize);\r
206                         s_nProcess = 0;\r
207 #ifdef __WINDOWS__\r
208                         s_nFileCount = piInfo->fiInfo.nUnpackedSize;\r
209 #endif\r
210                         sw.Start();\r
211                         if (piInfo->eStatus == 0x1001)\r
212                         {\r
213                                 this->fOpen = true;\r
214                         }\r
215                         break;\r
216                 case 0x1002: // 各ファイルの処理を開始。\r
217                         if (sw.Time() > 500)\r
218                         {\r
219                                 if (this->IsShownOnScreen())\r
220                                 {\r
221                                         sw.Start();\r
222                                         this->ebTarget->ChangeValue(piInfo->fiInfo.fnFileName.GetFullPath());\r
223                                         this->gArchive->SetValue(piInfo->nProcessedSize);\r
224                                         this->Update();\r
225                                         ::wxSafeYield(this, true);\r
226                                 }\r
227                                 ::wxSafeYield(this->hParent, true);\r
228                         }\r
229                         ((MainFrame *) this->hParent)->gFrame->SetValue(piInfo->nProcessedSize);\r
230 #ifdef __WINDOWS__\r
231                         if (this->tlTaskbar != NULL)\r
232                         {\r
233                                 this->tlTaskbar->SetProgressValue(this->hTBWnd, piInfo->nProcessedSize, s_nFileCount);\r
234                         }\r
235 #endif\r
236                         break;\r
237                 }\r
238                 break;\r
239         }\r
240         case TPI_MESSAGE_ASK:\r
241         {\r
242 #ifdef __WINDOWS__\r
243                 if (this->tlTaskbar != NULL)\r
244                 {\r
245                         this->tlTaskbar->SetProgressState(this->hTBWnd, TBPF_PAUSED);\r
246                 }\r
247 #endif\r
248                 switch (piInfo->eStatus)\r
249                 {\r
250                 case TPI_PARAM_PASSWORD:\r
251                 {\r
252                         if (piInfo->fiInfo.fnFileName == fnFormer || this->szPassword.IsEmpty())\r
253                         {\r
254                                 piInfo->szParam = ::wxGetPasswordFromUser(_("Password for:\n") + piInfo->fiInfo.fnFileName.GetFullPath(), wxT("Lychee"), wxEmptyString, this);\r
255                                 if (piInfo->szParam.IsEmpty())\r
256                                 {\r
257                                         this->fCancel = true;\r
258                                 }\r
259                                 this->szPassword = piInfo->szParam;\r
260                         }\r
261                         else\r
262                         {\r
263                                 piInfo->szParam = this->szPassword;\r
264                                 fnFormer = piInfo->fiInfo.fnFileName;\r
265                         }\r
266                         break;\r
267                 }\r
268                 case TPI_PARAM_NEXTVOLUME:\r
269                 {\r
270                         wxFileDialog fd(this, _("Choose next volume of: ") + piInfo->fiInfo.fnFileName.GetFullName(), piInfo->fiInfo.fnFileName.GetPath(), wxEmptyString, wxFileSelectorDefaultWildcardStr, wxFD_OPEN | wxFD_FILE_MUST_EXIST);\r
271                         if (fd.ShowModal() == wxID_CANCEL)\r
272                         {\r
273                                 this->fCancel = true;\r
274                         }\r
275                         piInfo->szParam = fd.GetPath();\r
276                         break;\r
277                 }\r
278                 case TPI_PARAM_DEST:\r
279                         if (piInfo->fnDestination.FileExists() || ::wxDirExists(piInfo->fnDestination.GetFullPath()))\r
280                         {\r
281                                 // 上書き確認を行う。\r
282                                 bool bPerm = false;\r
283                                 if (this->nOverwriteMode == wxID_OK)\r
284                                 {\r
285                                         OverwriteDialog odDlg;\r
286                                         odDlg.fnExist = & piInfo->fnDestination;\r
287                                         odDlg.tmWrite = & piInfo->fiInfo.tmModify;\r
288                                         odDlg.nWriteSize = piInfo->fiInfo.nUnpackedSize;\r
289 \r
290                                         this->nOverwriteMode = odDlg.ShowModal();\r
291                                         bPerm = odDlg.cbApplyAll->IsChecked();\r
292                                 }\r
293                                 else\r
294                                 {\r
295                                         bPerm = true;\r
296                                 }\r
297                                 switch (this->nOverwriteMode)\r
298                                 {\r
299                                 case wxID_CANCEL:\r
300                                         this->fCancel = true;\r
301                                         break;\r
302                                 case 0:\r
303                                         // 自動上書き。既存のファイルを削除しておく。\r
304                                         if (piInfo->fnDestination.FileExists())\r
305                                         {\r
306                                                 ::wxRemoveFile(piInfo->fnDestination.GetFullPath());\r
307                                         }\r
308                                         else if (::wxDirExists(piInfo->fnDestination.GetFullPath()))\r
309                                         {\r
310                                                 // TODO: 再帰削除。\r
311                                                 ::wxRmdir(piInfo->fnDestination.GetFullPath());\r
312                                         }\r
313                                         break;\r
314                                 case 1:\r
315                                         // 自動スキップ。\r
316                                         piInfo->fnDestination.Clear();\r
317                                         break;\r
318                                 case 2:\r
319                                         // 自動リネーム。\r
320                                         break;\r
321                                 }\r
322                                 if (! bPerm)\r
323                                 {\r
324                                         this->nOverwriteMode = wxID_OK;\r
325                                 }\r
326                         }\r
327                         break;\r
328                 default:\r
329                         return TPI_CALLBACK_UNSUPPORTED;\r
330                 }\r
331 #ifdef __WINDOWS__\r
332                 if (this->tlTaskbar != NULL)\r
333                 {\r
334                         this->tlTaskbar->SetProgressState(this->hTBWnd, TBPF_NORMAL);\r
335                 }\r
336 #endif\r
337                 break;\r
338         }\r
339         default:\r
340                 return TPI_CALLBACK_UNSUPPORTED;\r
341         }\r
342 \r
343         return this->fCancel ? TPI_CALLBACK_CANCEL : TPI_CALLBACK_CONTINUE;\r
344 }\r
345 //******************************************************************************\r
346 // OverwriteDialog\r
347 //******************************************************************************\r
348 \r
349 OverwriteDialog::OverwriteDialog(): wxDialog()\r
350 {\r
351         ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_overwrite.xrc"));\r
352         ::wxXmlResource::Get()->LoadDialog(this, this->GetParent(), wxT("dlg_overwrite"));      \r
353 }\r
354 \r
355 //******************************************************************************\r
356 // Event table.\r
357 //******************************************************************************\r
358 \r
359 BEGIN_EVENT_TABLE(OverwriteDialog, wxDialog)\r
360         EVT_INIT_DIALOG(OverwriteDialog::OnInit)\r
361         EVT_BUTTON(XRCID("btnOverwrite"), OverwriteDialog::OnBtnOverwrite)\r
362         EVT_BUTTON(XRCID("btnSkip"), OverwriteDialog::OnBtnSkip)\r
363         EVT_BUTTON(XRCID("btnAuto"), OverwriteDialog::OnBtnAuto)\r
364         EVT_BUTTON(XRCID("btnBrowse"), OverwriteDialog::OnBtnBrowse)\r
365         EVT_CLOSE(OverwriteDialog::OnClose)\r
366 END_EVENT_TABLE()\r
367 \r
368 //******************************************************************************\r
369 // Event handler.\r
370 //******************************************************************************\r
371 \r
372 void OverwriteDialog::OnInit(wxInitDialogEvent &)\r
373 {\r
374         // XRCと結びつけ。\r
375         this->ebTarget          = XRCCTRL(* this, "ebTarget",     wxTextCtrl);\r
376         this->cbApplyAll        = XRCCTRL(* this, "cbApplyAll",   wxCheckBox);\r
377         ::wxXmlResource::Get()->Unload(L_DIR_S_XRC wxT("dlg_overwrite.xrc"));\r
378 \r
379         // ファイル情報を設定。\r
380         this->ebTarget->SetValue(this->fnExist->GetFullPath());\r
381         XRCCTRL(* this, "stExistTime", wxStaticText)->SetLabel(this->fnExist->GetModificationTime().Format(_("%Y/%m/%d %H:%M:%S modified, ")));\r
382         XRCCTRL(* this, "stExistSize", wxStaticText)->SetLabel(this->fnExist->GetHumanReadableSize());\r
383         XRCCTRL(* this, "stWriteTime", wxStaticText)->SetLabel(this->tmWrite->Format(_("%Y/%m/%d %H:%M:%S modified, ")));\r
384         XRCCTRL(* this, "stWriteSize", wxStaticText)->SetLabel(wxFileName::GetHumanReadableSize((wxULongLong) this->nWriteSize));\r
385         XRCCTRL(* this, "sbIcon", wxStaticBitmap)->SetIcon(GetFileTypeIcon(* this->fnExist));\r
386 }\r
387 \r
388 void OverwriteDialog::OnClose(wxCloseEvent & e)\r
389 {\r
390         if (e.CanVeto() && ::AskDlg(_("Really do you want to cancel this operation?"), this) == wxYES)\r
391         {\r
392                 this->EndModal(wxID_CANCEL);\r
393         }\r
394         e.Veto();\r
395 }\r
396 \r
397 void OverwriteDialog::OnBtnOverwrite(wxCommandEvent&)\r
398 {\r
399         if (this->fnExist->GetFullPath() != this->ebTarget->GetValue())\r
400         {\r
401                 // 保存先を変えているので、次回もダイアログを表示。\r
402                 this->cbApplyAll->SetValue(false);\r
403                 * this->fnExist = wxFileName(this->ebTarget->GetValue());\r
404         }\r
405         this->EndModal(0);\r
406 }\r
407 \r
408 void OverwriteDialog::OnBtnSkip(wxCommandEvent&)\r
409 {\r
410         this->EndModal(1);\r
411 }\r
412 \r
413 void OverwriteDialog::OnBtnAuto(wxCommandEvent&)\r
414 {\r
415         this->EndModal(2);\r
416 }\r
417 \r
418 void OverwriteDialog::OnBtnBrowse(wxCommandEvent&)\r
419 {\r
420         wxFileName fn(this->ebTarget->GetValue());\r
421         wxFileDialog fd(this, _("Choose a file"), fn.GetPath(), fn.GetFullName(), wxFileSelectorDefaultWildcardStr, wxFD_SAVE | wxFD_OVERWRITE_PROMPT);\r
422         if (fd.ShowModal() == wxID_OK)\r
423         {\r
424                 this->ebTarget->SetValue(fd.GetPath());\r
425         }\r
426 }\r
427 \r
428 //******************************************************************************\r
429 //    ダイアログプロシージャ\r
430 //******************************************************************************\r
431 \r
432 int __stdcall TPICallbackProc(unsigned int _uMsg, void * _pStructure)\r
433 {\r
434         return g_procDlg == NULL ? TPI_CALLBACK_CONTINUE : g_procDlg->CallbackProc(_uMsg, _pStructure);\r
435 }\r