OSDN Git Service

書庫を複製する機能を追加。
[tpi/lychee.git] / src / lychee / dlg_process.cpp
index 16675f3..c95d544 100644 (file)
@@ -21,6 +21,9 @@
 \r
 #include "lychee.h"\r
 #include "dlg_process.h"\r
+#include "dlg_make.h"\r
+#include "frm_main.h"\r
+#include "functions.h"\r
 \r
 ProcessDialog * g_procDlg = NULL;\r
 \r
@@ -45,7 +48,7 @@ ProcessDialog::~ProcessDialog()
 \r
 BEGIN_EVENT_TABLE(ProcessDialog, wxDialog)\r
        EVT_INIT_DIALOG(ProcessDialog::OnInit)\r
-       EVT_CLOSE(      ProcessDialog::OnClose)\r
+       EVT_CLOSE(ProcessDialog::OnClose)\r
 END_EVENT_TABLE()\r
 \r
 //******************************************************************************\r
@@ -55,10 +58,13 @@ END_EVENT_TABLE()
 void ProcessDialog::OnInit(wxInitDialogEvent &)\r
 {\r
        // XRCと結びつけ。\r
-       this->ebSource          = XRCCTRL(* this, "ebSource",     wxTextCtrl);\r
        this->ebTarget          = XRCCTRL(* this, "ebTarget",     wxTextCtrl);\r
-       this->gauge             = XRCCTRL(* this, "gauge",        wxGauge);\r
+       this->ebSource          = XRCCTRL(* this, "ebSource",     wxTextCtrl);\r
+       this->gFile             = XRCCTRL(* this, "gFile",        wxGauge);\r
+       this->gArchive          = XRCCTRL(* this, "gArchive",     wxGauge);\r
        this->fCancel           = false;\r
+       this->nOverwriteMode    = wxID_OK;\r
+       this->Update();\r
        g_procDlg = this;\r
 \r
        ::wxXmlResource::Get()->Unload(L_DIR_S_XRC wxT("dlg_process.xrc"));\r
@@ -81,58 +87,65 @@ int ProcessDialog::CallbackProc(unsigned int _uMsg, void * _pStructure)
        }\r
 \r
        TPI_PROCESSINFO * piInfo = (TPI_PROCESSINFO *) _pStructure;\r
-       if (piInfo == NULL || ! g_procDlg->IsShown())\r
+       if (piInfo == NULL || ! this->IsShown())\r
        {\r
                return TPI_CALLBACK_CONTINUE;\r
        }\r
 \r
-       switch (piInfo->uMessage)\r
+       switch (piInfo->eMessage)\r
        {\r
        case TPI_MESSAGE_STATUS:\r
        {\r
-               static int s_nGaugeCounter = 0;\r
-               switch (piInfo->uStatus)\r
+               static int s_nGaugeCounter = 0, s_nInterval = 0;\r
+               switch (piInfo->eStatus)\r
                {\r
                case TPI_STATUS_OPENARCHIVE:\r
                        this->ebSource->ChangeValue(piInfo->fiInfo.fnFileName.GetFullPath());\r
                        break;\r
                case TPI_STATUS_BEGINPROCESS:\r
-                       this->ebSource->ChangeValue(piInfo->fiInfo.fnFileName.GetFullPath());\r
-                       this->ebTarget->ChangeValue(piInfo->fnDestination.GetFullPath());\r
-                       if (piInfo->fiInfo.llUnpackedSize > 10000)\r
+                       // 小さなファイルなら表示しない。\r
+                       if (piInfo->fiInfo.nUnpackedSize > 10000)\r
                        {\r
-                               this->gauge->SetRange(piInfo->fiInfo.llUnpackedSize);\r
-                               this->gauge->SetValue(0);\r
+                               this->ebSource->ChangeValue(piInfo->fiInfo.fnFileName.GetFullPath());\r
+                               this->ebTarget->ChangeValue(piInfo->fnDestination.GetFullPath());\r
+                               this->gFile->SetRange(piInfo->fiInfo.nUnpackedSize);\r
+                               this->gFile->SetValue(0);\r
+                               ::wxSafeYield(this, true);\r
                        }\r
-                       ::wxSafeYield(this, true);\r
                        break;\r
                case TPI_STATUS_INPROCESS:\r
-                       if (s_nGaugeCounter++ > 100)\r
+                       if (piInfo->fiInfo.nUnpackedSize > 10000)\r
                        {\r
-                               if (piInfo->fiInfo.llUnpackedSize > 10000)\r
-                               {\r
-                                       this->gauge->SetValue(piInfo->llProcessedSize);\r
-                               }\r
+                               this->gFile->SetValue(piInfo->nProcessedSize);\r
                                ::wxSafeYield(this, true);\r
-                               s_nGaugeCounter = 0;\r
                        }\r
                        break;\r
                case TPI_STATUS_ENDPROCESS:\r
-//                     this->gauge->SetValue(piInfo->fiInfo.llUnpackedSize.ToULong());\r
+                       if (s_nGaugeCounter++ > s_nInterval)\r
+                       {\r
+                               this->gArchive->SetValue(this->gArchive->GetValue() + s_nInterval);\r
+                               ::wxSafeYield(this, true);\r
+                               s_nGaugeCounter = 0;\r
+                       }\r
                        break;\r
                // 書庫ロード時用の独自仕様。\r
                case 0x1000:\r
                        this->ebSource->ChangeValue(piInfo->fiInfo.fnFileName.GetFullPath());\r
-                       this->gauge->SetRange(piInfo->fiInfo.llUnpackedSize);\r
-                       this->gauge->SetValue(0);\r
+                       this->gArchive->SetRange(piInfo->fiInfo.nUnpackedSize);\r
+                       this->gArchive->SetValue(0);\r
+                       this->Update();\r
+                       s_nInterval = piInfo->fiInfo.nUnpackedSize / 10;\r
                        break;\r
                case 0x1001:\r
-                       // 更新しすぎると低速なので100ファイル毎に更新する。\r
-                       if (piInfo->llProcessedSize > (unsigned) (this->gauge->GetValue() + 100))\r
+                       if (piInfo->fiInfo.nUnpackedSize > 10000)\r
                        {\r
                                this->ebTarget->ChangeValue(piInfo->fiInfo.fnFileName.GetFullPath());\r
-                               this->gauge->SetValue(piInfo->llProcessedSize);\r
+                       }\r
+                       if (s_nGaugeCounter++ > s_nInterval)\r
+                       {\r
+                               this->gArchive->SetValue(piInfo->nProcessedSize);\r
                                ::wxSafeYield(this, true);\r
+                               s_nGaugeCounter = 0;\r
                        }\r
                        break;\r
                }\r
@@ -140,19 +153,31 @@ int ProcessDialog::CallbackProc(unsigned int _uMsg, void * _pStructure)
        }\r
        case TPI_MESSAGE_ASK:\r
        {\r
-               switch (piInfo->uStatus)\r
+               switch (piInfo->eStatus)\r
                {\r
                case TPI_PARAM_PASSWORD:\r
-                       piInfo->szParam = ::wxGetPasswordFromUser(_("Password for:\n") + piInfo->fiInfo.fnFileName.GetFullPath(), wxT("Lychee"), wxEmptyString, this);\r
-                       if (piInfo->szParam.IsEmpty())\r
+               {\r
+                       static wxFileName fnFormer;\r
+                       static wxString szFormer;\r
+                       if (piInfo->fiInfo.fnFileName == fnFormer)\r
                        {\r
-                               this->fCancel = true;\r
+                               piInfo->szParam = ::wxGetPasswordFromUser(_("Password for:\n") + piInfo->fiInfo.fnFileName.GetFullPath(), wxT("Lychee"), wxEmptyString, this);\r
+                               if (piInfo->szParam.IsEmpty())\r
+                               {\r
+                                       this->fCancel = true;\r
+                               }\r
+                               szFormer = piInfo->szParam;\r
+                       }\r
+                       else\r
+                       {\r
+                               piInfo->szParam = szFormer;\r
+                               fnFormer = piInfo->fiInfo.fnFileName;\r
                        }\r
                        break;\r
+               }\r
                case TPI_PARAM_NEXTVOLUME:\r
                {\r
-                       wxFileDialog fd(this, _("Select next volume of: ") + piInfo->fiInfo.fnFileName.GetFullName());\r
-                       fd.SetWindowStyleFlag(wxFD_FILE_MUST_EXIST);\r
+                       wxFileDialog fd(this, _("Choose next volume of: ") + piInfo->fiInfo.fnFileName.GetFullName(), piInfo->fiInfo.fnFileName.GetPath(), wxEmptyString, wxFileSelectorDefaultWildcardStr, wxFD_OPEN | wxFD_FILE_MUST_EXIST);\r
                        if (fd.ShowModal() == wxID_CANCEL)\r
                        {\r
                                this->fCancel = true;\r
@@ -160,6 +185,56 @@ int ProcessDialog::CallbackProc(unsigned int _uMsg, void * _pStructure)
                        piInfo->szParam = fd.GetPath();\r
                        break;\r
                }\r
+               case TPI_PARAM_DEST:\r
+                       if (piInfo->fnDestination.FileExists() || ::wxDirExists(piInfo->fnDestination.GetFullPath()))\r
+                       {\r
+                               // 上書き確認を行う。\r
+                               bool bPerm = false;\r
+                               if (this->nOverwriteMode == wxID_OK)\r
+                               {\r
+                                       OverwriteDialog odDlg;\r
+                                       odDlg.fnExist = & piInfo->fnDestination;\r
+                                       odDlg.tmWrite = & piInfo->fiInfo.tmModified;\r
+                                       odDlg.nWriteSize = piInfo->fiInfo.nUnpackedSize;\r
+\r
+                                       this->nOverwriteMode = odDlg.ShowModal();\r
+                                       bPerm = odDlg.cbApplyAll->IsChecked();\r
+                               }\r
+                               else\r
+                               {\r
+                                       bPerm = true;\r
+                               }\r
+                               switch (this->nOverwriteMode)\r
+                               {\r
+                               case wxID_CANCEL:\r
+                                       this->fCancel = true;\r
+                                       break;\r
+                               case 0:\r
+                                       // 自動上書き。既存のファイルを削除しておく。\r
+                                       if (piInfo->fnDestination.FileExists())\r
+                                       {\r
+                                               ::wxRemoveFile(piInfo->fnDestination.GetFullPath());\r
+                                       }\r
+                                       else if (::wxDirExists(piInfo->fnDestination.GetFullPath()))\r
+                                       {\r
+                                               // TODO: 再帰削除。\r
+                                               ::wxRmdir(piInfo->fnDestination.GetFullPath());\r
+                                       }\r
+                                       break;\r
+                               case 1:\r
+                                       // 自動スキップ。\r
+                                       piInfo->fnDestination.Clear();\r
+                                       break;\r
+                               case 2:\r
+                                       // 自動リネーム。\r
+                                       break;\r
+                               }\r
+                               if (! bPerm)\r
+                               {\r
+                                       this->nOverwriteMode = wxID_OK;\r
+                               }\r
+                       }\r
+                       break;\r
                default:\r
                        return TPI_CALLBACK_UNSUPPORTED;\r
                }\r
@@ -171,6 +246,88 @@ int ProcessDialog::CallbackProc(unsigned int _uMsg, void * _pStructure)
 \r
        return this->fCancel ? TPI_CALLBACK_CANCEL : TPI_CALLBACK_CONTINUE;\r
 }\r
+//******************************************************************************\r
+// OverwriteDialog\r
+//******************************************************************************\r
+\r
+OverwriteDialog::OverwriteDialog(): wxDialog()\r
+{\r
+       ::wxXmlResource::Get()->Load(L_DIR_S_XRC wxT("dlg_overwrite.xrc"));\r
+       ::wxXmlResource::Get()->LoadDialog(this, this->GetParent(), wxT("dlg_overwrite"));      \r
+}\r
+\r
+//******************************************************************************\r
+// Event table.\r
+//******************************************************************************\r
+\r
+BEGIN_EVENT_TABLE(OverwriteDialog, wxDialog)\r
+       EVT_INIT_DIALOG(OverwriteDialog::OnInit)\r
+       EVT_BUTTON(XRCID("btnOverwrite"), OverwriteDialog::OnBtnOverwrite)\r
+       EVT_BUTTON(XRCID("btnSkip"), OverwriteDialog::OnBtnSkip)\r
+       EVT_BUTTON(XRCID("btnAuto"), OverwriteDialog::OnBtnAuto)\r
+       EVT_BUTTON(XRCID("btnBrowse"), OverwriteDialog::OnBtnBrowse)\r
+       EVT_CLOSE(OverwriteDialog::OnClose)\r
+END_EVENT_TABLE()\r
+\r
+//******************************************************************************\r
+// Event handler.\r
+//******************************************************************************\r
+\r
+void OverwriteDialog::OnInit(wxInitDialogEvent &)\r
+{\r
+       // XRCと結びつけ。\r
+       this->ebTarget          = XRCCTRL(* this, "ebTarget",     wxTextCtrl);\r
+       this->cbApplyAll        = XRCCTRL(* this, "cbApplyAll",   wxCheckBox);\r
+       ::wxXmlResource::Get()->Unload(L_DIR_S_XRC wxT("dlg_overwrite.xrc"));\r
+\r
+       // ファイル情報を設定。\r
+       this->ebTarget->SetValue(this->fnExist->GetFullPath());\r
+       XRCCTRL(* this, "stExistTime", wxStaticText)->SetLabel(this->fnExist->GetModificationTime().Format(_("%Y/%m/%d %H:%M:%S modified, ")));\r
+       XRCCTRL(* this, "stExistSize", wxStaticText)->SetLabel(this->fnExist->GetHumanReadableSize());\r
+       XRCCTRL(* this, "stWriteTime", wxStaticText)->SetLabel(this->tmWrite->Format(_("%Y/%m/%d %H:%M:%S modified, ")));\r
+       XRCCTRL(* this, "stWriteSize", wxStaticText)->SetLabel(wxFileName::GetHumanReadableSize((wxULongLong) this->nWriteSize));\r
+       XRCCTRL(* this, "sbIcon", wxStaticBitmap)->SetIcon(GetFileTypeIcon(* this->fnExist));\r
+}\r
+\r
+void OverwriteDialog::OnClose(wxCloseEvent & e)\r
+{\r
+       if (e.CanVeto() && ::AskDlg(_("Really do you want to cancel this operation?"), this) == wxYES)\r
+       {\r
+               this->EndModal(wxID_CANCEL);\r
+       }\r
+       e.Veto();\r
+}\r
+\r
+void OverwriteDialog::OnBtnOverwrite(wxCommandEvent&)\r
+{\r
+       if (this->fnExist->GetFullPath() != this->ebTarget->GetValue())\r
+       {\r
+               // 保存先を変えているので、次回もダイアログを表示。\r
+               this->cbApplyAll->SetValue(false);\r
+               * this->fnExist = wxFileName(this->ebTarget->GetValue());\r
+       }\r
+       this->EndModal(0);\r
+}\r
+\r
+void OverwriteDialog::OnBtnSkip(wxCommandEvent&)\r
+{\r
+       this->EndModal(1);\r
+}\r
+\r
+void OverwriteDialog::OnBtnAuto(wxCommandEvent&)\r
+{\r
+       this->EndModal(2);\r
+}\r
+\r
+void OverwriteDialog::OnBtnBrowse(wxCommandEvent&)\r
+{\r
+       wxFileName fn(this->ebTarget->GetValue());\r
+       wxFileDialog fd(this, _("Choose a file"), fn.GetPath(), fn.GetFullName(), wxFileSelectorDefaultWildcardStr, wxFD_SAVE | wxFD_OVERWRITE_PROMPT);\r
+       if (fd.ShowModal() == wxID_OK)\r
+       {\r
+               this->ebTarget->SetValue(fd.GetPath());\r
+       }\r
+}\r
 \r
 //******************************************************************************\r
 //    ダイアログプロシージャ\r