OSDN Git Service

書庫を開いたときやDnDから書庫の作成を試みたときにLycheeのウインドウを前面に出すよう変更。
[tpi/lychee.git] / src / lychee / dlg_make.cpp
index 0630947..026f13c 100644 (file)
@@ -36,7 +36,7 @@ WX_DEFINE_OBJARRAY(ArrayTPI_FORMATINFO);
 \r
 MakeDialog::MakeDialog(): wxDialog()\r
 {\r
-       this->bIsMake = true;\r
+       this->uCommand = TPI_COMMAND_CREATE;\r
 }\r
 \r
 //******************************************************************************\r
@@ -76,61 +76,35 @@ void MakeDialog::OnInit(wxInitDialogEvent&)
        // "Config"タブ\r
        this->scLevel           = XRCCTRL(* this, "scLevel",      wxSpinCtrl);\r
        this->scRR              = XRCCTRL(* this, "scRR",         wxSpinCtrl);\r
-       this->tcPassword        = XRCCTRL(* this, "tcPassword",   wxTextCtrl);\r
-       this->tcKeyfile         = XRCCTRL(* this, "tcKeyfile",    wxTextCtrl);\r
-       this->cbSplitSize       = XRCCTRL(* this, "cbSplitSize",  wxComboBox);\r
-       this->cbUnmask          = XRCCTRL(* this, "cbUnmask",     wxCheckBox);\r
-       this->cbEncryptHeader   = XRCCTRL(* this, "cbEncryptHeader", wxCheckBox);\r
        this->cbSolid           = XRCCTRL(* this, "cbSolid",      wxCheckBox);\r
        this->cbMMOptimize      = XRCCTRL(* this, "cbMMOptimize", wxCheckBox);\r
+       this->cbCompressHeader  = XRCCTRL(* this, "cbCompressHeader", wxCheckBox);\r
        this->cbMakeSFX         = XRCCTRL(* this, "cbMakeSFX",    wxCheckBox);\r
        // "Comment"タブ\r
        this->tcComment         = XRCCTRL(* this, "tcComment",    wxTextCtrl);\r
+       // "Encryption"タブ\r
+       this->tcPassword        = XRCCTRL(* this, "tcPassword",   wxTextCtrl);\r
+       this->tcKeyfile         = XRCCTRL(* this, "tcKeyfile",    wxTextCtrl);\r
+       this->cbSplitSize       = XRCCTRL(* this, "cbSplitSize",  wxComboBox);\r
+       this->cbUnmask          = XRCCTRL(* this, "cbUnmask",     wxCheckBox);\r
+       this->cbEncryptHeader   = XRCCTRL(* this, "cbEncryptHeader", wxCheckBox);\r
+       this->chEncryptMethod   = XRCCTRL(* this, "chEncryptMethod", wxChoice);\r
        // "Files"タブ\r
-       this->lcFiles           = XRCCTRL(* this, "lcFiles",      wxListCtrl);\r
-\r
-       // 2回目以降は無視。\r
-       if (! this->cbDir->GetValue().IsEmpty())\r
-       {\r
-               return;\r
-       }\r
+       this->lcFiles           = XRCCTRL(* this, "lcFiles",      myListCtrl2);\r
 \r
        // ListCtrlに列を追加。\r
+       // wxGTKでは直接wxLC_VIRTUALを指定しないと反映されない。\r
+       this->lcFiles->SetSingleStyle(wxLC_VIRTUAL);\r
        this->lcFiles->InsertColumn(0, _("Input"),  wxLIST_FORMAT_LEFT,  150);\r
-       this->lcFiles->InsertColumn(1, _("Output"), wxLIST_FORMAT_LEFT,  300);\r
+       this->lcFiles->InsertColumn(1, _("Output"), wxLIST_FORMAT_LEFT,  290);\r
+       this->lcFiles->asInput = & this->files;\r
+       this->lcFiles->atDangerItem.SetTextColour(* wxRED);\r
 \r
        ::wxXmlResource::Get()->Unload(L_DIR_S_XRC wxT("dlg_make.xrc"));\r
 \r
        // 事前準備。\r
        MainFrame * frm_main = (MainFrame *) this->GetParent();\r
-       wxString szArcPath = frm_main->fnArchive.GetPath(), szArcName = frm_main->fnArchive.GetName();\r
-\r
-       // 展開時は各種コントロールの状態を変更する。\r
-       if (! this->bIsMake)\r
-       {\r
-               this->cbFileName->Disable();\r
-               this->chType->Disable();\r
-               this->chDirMake->Enable();\r
-               this->scLevel->Disable();\r
-               this->scRR->Disable();\r
-               this->cbSplitSize->Disable();\r
-               this->cbEncryptHeader->Disable();\r
-               this->cbSolid->Disable();\r
-               this->cbMMOptimize->Disable();\r
-               this->cbMakeSFX->Disable();\r
-               this->tcComment->SetEditable(false);\r
-\r
-               // 初期値を設定。\r
-               this->tcComment->SetValue(frm_main->szComment);\r
-\r
-               // 展開先を予測。ただしDTVスキャンに時間がかかる場合はスキップ可能。\r
-               if (this->files.GetCount() < 3000 || ::AskDlg(_("This archive contains so many files that it takes long to check Directory Traversal Vulnerability(DTV) problem. If you are sure this archive is safe, you can skip this scanning process. Do you want to scan for DTV problem?"), this) == wxYES)\r
-               {\r
-                       wxNotebookEvent e;\r
-                       e.SetSelection(-3);\r
-                       this->OnTabChanged(e);\r
-               }\r
-       }\r
+       wxString szArcPath = frm_main->fnArchive.GetPath();\r
 \r
        // パス履歴読み込み。\r
        for (size_t i = 0; i < frm_main->conf.GetHistoryCount(CONF_HISTORY_PATH); i++)\r
@@ -143,7 +117,6 @@ void MakeDialog::OnInit(wxInitDialogEvent&)
 \r
                this->cbDir->Append(sz);\r
        }\r
-\r
        // 書庫名履歴読み込み。\r
        for (size_t i = 0; i < frm_main->conf.GetHistoryCount(CONF_HISTORY_NAME); i++)\r
        {\r
@@ -159,53 +132,121 @@ void MakeDialog::OnInit(wxInitDialogEvent&)
        // パスを設定。\r
        this->cbDir->SetValue(szArcPath);\r
 \r
-       if (! this->bIsMake)\r
+       // コマンド別の処理。\r
+       switch (this->uCommand)\r
        {\r
-               // 書庫名を設定。\r
-               this->cbFileName->SetValue(szArcName);\r
+       case TPI_COMMAND_EXTRACT:\r
+               // 初期値を設定。\r
+               this->SetTitle(_("Extract"));\r
+               this->tcComment->SetValue(frm_main->aiArchive.szComment);\r
 \r
-               // 展開時の処理はここまで。\r
-               return;\r
-       }\r
+               // コントロールを無効化。\r
+               this->scLevel->Disable();\r
+               this->scRR->Disable();\r
+               this->cbSolid->Disable();\r
+               this->cbMMOptimize->Disable();\r
+               this->tcComment->SetEditable(false);\r
+               this->cbEncryptHeader->Disable();\r
+               this->chEncryptMethod->Disable();\r
+       case TPI_COMMAND_ADD:\r
+               // コントロールを無効化(展開時も)。\r
+               this->cbFileName->Disable();\r
+               this->chType->Disable();\r
+               this->chDirMake->Enable();\r
+               this->cbSplitSize->Disable();\r
+               this->cbCompressHeader->Disable();\r
+               this->cbMakeSFX->Disable();\r
 \r
-       // 書庫名を設定。初期化の都合上.を付加しておく\r
-       this->cbFileName->SetValue(szArcName + wxT('.'));\r
+               // 書庫名を設定\r
+               this->cbFileName->SetValue(frm_main->fnArchive.GetFullName());\r
 \r
-       // ライブラリを検索。\r
-       TPIHandle tpi;\r
-       wxFileSystem fs;\r
-       fs.ChangePathTo(L_DIR_B_LIB, true);\r
-       wxString szTPIName = fs.FindFirst(wxT("*" TPI_EXT), wxFILE);\r
-       while (! szTPIName.IsEmpty())\r
-       {\r
-               // ロード。\r
-               if (tpi.InitLibrary(szTPIName, wxEmptyString, 0))\r
+               // 書庫形式欄を設定。\r
+               this->afInfo.Add(frm_main->aiArchive.fiInfo);\r
+               this->chType->Append(frm_main->aiArchive.fiInfo.szTypeName);\r
+               this->chType->SetSelection(0);\r
+               {\r
+                       wxCommandEvent e;\r
+                       e.SetInt(0);\r
+                       this->OnChoice(e);\r
+               }\r
+\r
+               if (this->uCommand != TPI_COMMAND_ADD)\r
+               {\r
+                       break;\r
+               }\r
+               this->SetTitle(_("Add"));\r
+\r
+               // コントロールを無効化(追加時のみ)。\r
+               this->cbDir->Disable();\r
+               this->chDirMake->Disable();\r
+               XRCCTRL(* this, "btnDefault", wxButton)->Disable();\r
+               XRCCTRL(* this, "btnDesktop", wxButton)->Disable();\r
+               XRCCTRL(* this, "btnCurrent", wxButton)->Disable();\r
+               XRCCTRL(* this, "btnBrowse",  wxButton)->Disable();\r
+               break;\r
+       case TPI_COMMAND_CREATE:\r
+               this->SetTitle(_("Create"));\r
+\r
+               // 書庫名を設定。初期化の都合上.を付加しておく。\r
+               this->cbFileName->SetValue(frm_main->fnArchive.GetName() + wxT('.'));\r
+\r
+               // ライブラリを検索。\r
+               TPIHandle tpi;\r
+               wxDir fs(L_DIR_B_LIB);\r
+               wxString szTPIName;\r
+               if (fs.GetFirst(& szTPIName,wxT("*" TPI_EXT)))\r
                {\r
-                       // 対応する形式名を取得。\r
-                       TPI_FORMATINFO fiInfo;\r
-                       if (tpi.GetFormatInformation(& fiInfo, true))\r
+                       do\r
                        {\r
-                               do\r
+                               // ロード。\r
+                               wxString szLibName = L_DIR_B_LIB + szTPIName;\r
+                               if (tpi.InitLibrary(szLibName, wxEmptyString, 0))\r
                                {\r
-                                       if (fiInfo.llSupportedCommand & TPI_COMMAND_CREATE && (this->files.GetCount() == 1 || fiInfo.fArchive))\r
+                                       // 対応する形式名を取得。\r
+                                       TPI_FORMATINFO fiInfo;\r
+                                       if (tpi.GetFormatInformation(& fiInfo, true))\r
                                        {\r
-                                               fiInfo.szTPIName = szTPIName;\r
-                                               this->afInfo.Add(fiInfo);\r
-                                               this->chType->Append(fiInfo.szTypeName);\r
+                                               do\r
+                                               {\r
+                                                       if (fiInfo.eSupportedCommand & TPI_COMMAND_CREATE && (this->lcFiles->asInput->GetCount() == 1 || fiInfo.fArchive))\r
+                                                       {\r
+                                                               fiInfo.szTPIName = szLibName;\r
+                                                               this->afInfo.Add(fiInfo);\r
+                                                               this->chType->Append(fiInfo.szTypeName);\r
+                                                       }\r
+                                               }\r
+                                               while (tpi.GetFormatInformation(& fiInfo, false));\r
                                        }\r
+                                       tpi.FreeLibrary();\r
                                }\r
-                               while (tpi.GetFormatInformation(& fiInfo, false));\r
                        }\r
-                       tpi.FreeLibrary();\r
+                       while (fs.GetNext(& szTPIName));\r
                }\r
-               szTPIName = fs.FindNext();\r
+\r
+               if (this->chType->GetCount() == 0)\r
+               {\r
+                       // 形式の候補が一つもない場合。\r
+                       XRCCTRL(* this, "btnOK", wxButton)->Disable();\r
+                       break;\r
+               }\r
+\r
+               // とりあえず最初の形式にしておく。\r
+               this->chType->SetSelection(0);\r
+               wxCommandEvent e;\r
+               e.SetInt(0);\r
+               this->OnChoice(e);\r
+               break;\r
        }\r
 \r
-       // とりあえず最初の形式にしておく。\r
-       this->chType->SetSelection(0);\r
-       wxCommandEvent e;\r
-       e.SetInt(0);\r
-       this->OnChoice(e);\r
+       // 展開/格納先を予測。ただしDTVスキャンに時間がかかる場合はスキップ可能。\r
+       if (this->lcFiles->asInput->GetCount() < 3000 || ::AskDlg(_("This archive contains so many files that it takes long to check Directory Traversal Vulnerability(DTV) problem. If you are sure this archive is safe, you can skip this scanning process. Do you want to scan for DTV problem?"), this) == wxYES)\r
+       {\r
+               wxNotebookEvent e;\r
+               e.SetSelection(3);\r
+               this->OnTabChanged(e);\r
+       }\r
+\r
+       this->Raise();\r
 }\r
 \r
 void MakeDialog::OnBtnDefault(wxCommandEvent&)\r
@@ -247,12 +288,14 @@ void MakeDialog::OnBtnBrowseKF(wxCommandEvent&)
 void MakeDialog::OnBtnOK(wxCommandEvent&)\r
 {\r
        // 履歴書き込み。\r
-       MainFrame * frm_main = (MainFrame *) this->GetParent();\r
-       wxFileName fnCurrent(this->cbDir->GetValue(), this->bIsMake ? this->cbFileName->GetValue() : (wxString) wxEmptyString);\r
-       frm_main->conf.WriteHistory(CONF_HISTORY_FULL, fnCurrent.GetFullPath());\r
-       frm_main->conf.WriteHistory(CONF_HISTORY_PATH, fnCurrent.GetPath());\r
-       frm_main->conf.WriteHistory(CONF_HISTORY_NAME, fnCurrent.GetFullName());\r
-\r
+       if (this->uCommand != TPI_COMMAND_ADD)\r
+       {\r
+               MainFrame * frm_main = (MainFrame *) this->GetParent();\r
+               wxFileName fnCurrent(this->cbDir->GetValue(), this->uCommand == TPI_COMMAND_CREATE ? this->cbFileName->GetValue() : (wxString) wxEmptyString);\r
+               frm_main->conf.WriteHistory(CONF_HISTORY_FULL, fnCurrent.GetFullPath());\r
+               frm_main->conf.WriteHistory(CONF_HISTORY_PATH, fnCurrent.GetPath());\r
+               frm_main->conf.WriteHistory(CONF_HISTORY_NAME, fnCurrent.GetFullName());\r
+       }\r
        this->EndModal(wxID_OK);\r
 }\r
 \r
@@ -265,21 +308,37 @@ void MakeDialog::OnChoice(wxCommandEvent& e)
 {\r
        TPI_FORMATINFO * fiInfo = & this->afInfo[e.GetInt()];\r
        // 形式が各種設定に対応しているか。\r
-       this->scLevel->SetRange(fiInfo->sCompressLevelMin, fiInfo->sCompressLevelMax);\r
-       this->scLevel->SetValue(fiInfo->sCompressLevelMax);\r
-       this->scLevel->Enable(fiInfo->sCompressLevelMin != fiInfo->sCompressLevelMax);\r
-       this->scRR->SetRange(fiInfo->sRecoveryRecordMin, fiInfo->sRecoveryRecordMax);\r
-       this->scRR->SetValue(fiInfo->sRecoveryRecordMin);\r
-       this->scRR->Enable(fiInfo->sRecoveryRecordMin != fiInfo->sRecoveryRecordMax);\r
-       this->cbSplitSize->Enable(fiInfo->fMultiVolume);\r
+       // 作成時/追加時/展開時設定。\r
        this->tcPassword->Enable(fiInfo->fEncryptPassword);\r
-       this->cbUnmask->Enable(fiInfo->fEncryptPassword);\r
        this->tcKeyfile->Enable(fiInfo->fEncryptKeyFile);\r
+       this->cbUnmask->Enable(fiInfo->fEncryptPassword);\r
+       this->chEncryptMethod->Enable(fiInfo->fEncryptPassword || fiInfo->fEncryptKeyFile);\r
+       XRCCTRL(* this, "btnBrowseKF", wxButton)->Enable(fiInfo->fEncryptKeyFile);\r
+       if (this->uCommand == TPI_COMMAND_EXTRACT)\r
+       {\r
+               return;\r
+       }\r
+\r
+       // 作成時/追加時設定。\r
+       this->scLevel->SetRange(fiInfo->nCompressLevelMin, fiInfo->nCompressLevelMax);\r
+       this->scLevel->SetValue(fiInfo->nCompressLevelMax);\r
+       this->scLevel->Enable(fiInfo->nCompressLevelMin != fiInfo->nCompressLevelMax);\r
+       this->scRR->SetRange(fiInfo->nRecoveryRecordMin, fiInfo->nRecoveryRecordMax);\r
+       this->scRR->SetValue(fiInfo->nRecoveryRecordMin);\r
+       this->scRR->Enable(fiInfo->nRecoveryRecordMin != fiInfo->nRecoveryRecordMax);\r
        this->cbEncryptHeader->Enable(fiInfo->fEncryptHeader);\r
-       this->cbMakeSFX->Enable(fiInfo->fSFX);\r
+       this->cbCompressHeader->Enable(fiInfo->fCompressHeader);\r
        this->cbSolid->Enable(fiInfo->fSolid);\r
        this->cbMMOptimize->Enable(fiInfo->fMMOptimize);\r
        this->tcComment->Enable(fiInfo->fComment);\r
+       if (this->uCommand == TPI_COMMAND_ADD)\r
+       {\r
+               return;\r
+       }\r
+\r
+       // 作成時設定。\r
+       this->cbSplitSize->Enable(fiInfo->fMultiVolume);\r
+       this->cbMakeSFX->Enable(fiInfo->fSFX);\r
 \r
        wxFileName fn(this->cbFileName->GetValue());\r
        fn.SetExt(this->cbMakeSFX->IsEnabled() && this->cbMakeSFX->IsChecked() ? EXE_EXT : fiInfo->szSuffix.BeforeFirst(wxT(';')));\r
@@ -302,71 +361,87 @@ void MakeDialog::OnCbMakeSFX(wxCommandEvent&)
 void MakeDialog::OnTabChanged(wxNotebookEvent& e)\r
 {\r
        // "Files"タブのときは処理。\r
-       bool bReallyShow = e.GetSelection() == 3;\r
-       if (abs(e.GetSelection()) != 3)\r
+       if (e.GetSelection() != 4)\r
        {\r
                return;\r
        }\r
+       this->lcFiles->DeleteAllItems();\r
+       this->lcFiles->asOutput.Clear();\r
+       this->lcFiles->apItem.Clear();\r
 \r
-       // "Files"タブを表示する初回かどうか。\r
-       if (bReallyShow && this->lcFiles->GetItemCount() == 0)\r
+       switch (this->uCommand)\r
        {\r
-               // ファイルリストを追加。\r
-               for (size_t i = 0; i < this->files.GetCount(); i++)\r
-               {\r
-                       this->lcFiles->InsertItem(i, this->files[i]);\r
-               }\r
-       }\r
-\r
-       if (bIsMake)\r
-       {\r
-               // 格納パスを推測。\r
-               for (size_t i = 0; i < this->files.GetCount(); i++)\r
-               {\r
-                       if (bReallyShow)\r
-                       {\r
-                               this->lcFiles->SetItem(i, 1, this->files[i]);\r
-                       }\r
-               }\r
-       }\r
-       else\r
+       case TPI_COMMAND_EXTRACT:\r
        {\r
                // ファイルの出力先を推測。\r
                wxString szOutputRootDir = WillMakeDirByArcName((MainFrame *) this->GetParent(), this) ? MakeDirPath(wxFileName::DirName(this->cbDir->GetValue()), wxFileName(this->cbFileName->GetValue()).GetName(), false).GetPath() : this->cbDir->GetValue();\r
 \r
                // 各ファイルにパスを付加。\r
                bool fDTVWarning = false;\r
-               for (size_t i = 0; i < this->files.GetCount(); i++)\r
+               for (size_t i = 0; i < this->lcFiles->asInput->GetCount(); i++)\r
                {\r
                        wxString szOutputFile = szOutputRootDir + wxFileName::GetPathSeparator();\r
-                       wxFileName fnStored(this->files[i]);\r
+                       wxFileName fnStored(this->lcFiles->asInput->Item(i));\r
                        if (! this->cbIgnorePath->IsChecked())\r
                        {\r
                                szOutputFile += fnStored.GetPathWithSep();\r
                        }\r
-                       szOutputFile += fnStored.GetFullName();\r
-                       wxFileName fnOutput(szOutputFile);\r
-                       if (! fnOutput.Normalize() || ! fnOutput.GetFullPath().StartsWith(szOutputRootDir))\r
+                       wxFileName fnOutput(szOutputFile + fnStored.GetFullName());\r
+                       if (! fnOutput.Normalize(wxPATH_NORM_DOTS | wxPATH_NORM_ABSOLUTE | wxPATH_NORM_LONG) || ! fnOutput.GetFullPath().StartsWith(szOutputRootDir))\r
                        {\r
                                fDTVWarning = true;\r
-                               if (bReallyShow)\r
-                               {\r
-                                       this->lcFiles->SetItemTextColour(i, * wxRED);\r
-                               }\r
+                               this->lcFiles->apItem.Add(& this->lcFiles->atDangerItem);\r
                        }\r
-                       if (bReallyShow)\r
+                       else\r
                        {\r
-                               this->lcFiles->SetItem(i, 1, fnOutput.GetFullPath());\r
+                               this->lcFiles->apItem.Add(NULL);\r
                        }\r
+                       this->lcFiles->asOutput.Add(fnOutput.GetFullPath());\r
                }\r
 \r
                if (fDTVWarning && ::AskDlg(_("This archive may have Directory Traversal Vulnerability(DTV) problem, and some danger files may be extracted to the unexpected system directory! It is strongly recommended to ignore file path. Would you like to do so?"), this) == wxYES)\r
                {\r
                        this->cbIgnorePath->SetValue(true);\r
-                       if (bReallyShow)\r
-                       {\r
-                               this->OnTabChanged(e);\r
-                       }\r
+                       this->OnTabChanged(e);\r
                }\r
+               break;\r
+       }\r
+       case TPI_COMMAND_ADD:\r
+       case TPI_COMMAND_CREATE:\r
+               // TODO : 格納パスを推測。\r
+               this->lcFiles->asOutput = * this->lcFiles->asInput;\r
+               this->lcFiles->apItem.SetCount(this->lcFiles->asInput->GetCount(), NULL);\r
+               break;\r
+       }\r
+\r
+       // リストビューに表示。\r
+       this->lcFiles->SetItemCount(this->lcFiles->asInput->GetCount());\r
+}\r
+\r
+//******************************************************************************\r
+// myListCtrl2\r
+//******************************************************************************\r
+\r
+IMPLEMENT_DYNAMIC_CLASS(myListCtrl2, wxListView)\r
+\r
+//******************************************************************************\r
+// Event handler.\r
+//******************************************************************************\r
+wxString myListCtrl2::OnGetItemText(long i, long column) const\r
+{\r
+       // リストビューに項目を追加。\r
+       switch (column)\r
+       {\r
+       case 0:\r
+               return this->asInput->Item(i);\r
+       case 1:\r
+               return this->asOutput[i];\r
+       default:\r
+               return wxEmptyString;\r
        }\r
 }\r
+\r
+wxListItemAttr * myListCtrl2::OnGetItemAttr(long i) const\r
+{\r
+       return (wxListItemAttr *) this->apItem[i];\r
+}\r