#include "cmd_panel_imp.h" #include "drawset.h" #include "mainframe.h" #include "selection.h" #include "mlsmenu.h" #include "archive.h" #include "ncurses_qcd.h" #include "dialogbox.h" #include using namespace MLS; using namespace MLSUTIL; void CmdPanelImp::UpdateConfig() { } void CmdPanelImp::SaveConfig() { } /// @brief 명령어를 실행한다. /// @param cmd 명령어및 인자 /// @param bPause 명령어를 실행시키고 종료시 잠시 정지시킬지 여부 /// @param bFork Fork할 것인지? /// @return 명령어 실행 결과 int CmdPanelImp::Run( const std::string &cmd, bool bPause, bool bBackground) { // command 창에서 exit, quit 를 치면 종료하게 한다. if (cmd == "exit" || cmd == "quit") { Quit(); return 0; } CursesDestroy(); int status; if (_pPanel->GetReader()->GetReaderName() == "file") { chdir(_pPanel->GetReader()->GetPath().c_str()); } if (bBackground) { cout << "linm $ " << cmd.c_str() << endl; string sCmd = cmd + " > /dev/null 2>&1 &"; status = system(sCmd.c_str()); } else { cout << "linm $ " << cmd.c_str() << endl; status = system(cmd.c_str()); } if (bPause) { cbreak(); noecho(); cout << endl << _("Press any key to return LinM...") << '\r' << endl; getch(); } CursesInit(); Refresh(); return 0; } /// @brief 모든 커맨드 메시지를 관리 /// @param p 실행 시킬 명령어 /// @return 명령어 실행 결과 int CmdPanelImp::ParseAndRun(const string &p, bool Pause) { bool bFlag = false, bPause = Pause, bParam = false, bMcd = false , bConfirm = false, bBackground = false, bRootExe = false; // cd 구현 if (p.substr(0, 2) == "cd") { string sStr; if (p == "cd" || p == "cd ") sStr = _pPanel->GetReader()->GetRealPath("~"); else sStr = _pPanel->GetReader()->GetRealPath(p.substr(3)); sStr = Replace(sStr, "\\", ""); if (sStr != "") { if (_pPanel->Read(sStr) == true) { if (g_tMainFrame.GetScreenSync()) ViewSync(); return 1; } } return 0; } string arg, tmp_name; File tFile; // 파일을 복사 해서 보여주기 위한. { File* pFile = _pPanel->GetCurFile(); if (_pPanel->GetReader()->View(pFile, &tFile) == false) { //MsgBox( _("Error"), _("file reading failure !!!!")); return 0; } } // 파싱 for (string::const_iterator i = p.begin(); i!= p.end(); i++) { if (*i == '%') { bFlag = true; continue; } if (bFlag) { switch(*i) { // 파일을 리턴해줌 case '1': case 'F': arg += addslash(tFile.sFullName); break; case 'N': { if (tFile.sName[0]=='.') return 0; string::size_type p = tFile.sName.rfind('.'); if (p != string::npos) arg += addslash(tFile.sFullName.substr(0, p-1)); else arg += addslash(tFile.sFullName); break; } case 'E': if (tFile.Ext().empty()) return 0; arg += addslash(tFile.Ext()); break; case 'W': bPause = true; break; case '%': arg += '%'; break; case 'S': { Selection tSelection; _pPanel->GetSelection(tSelection); if (tSelection.GetSize() == 0) return 0; bool first = true; for (int t = 0; t< tSelection.GetSize(); t++) { if (first) first= false; else arg += ' '; arg += addslash(tSelection[t]->sFullName); } break; } case 's': { Selection tSelection; _pPanel->GetSelection(tSelection); if (!tSelection.GetSize() == 0) { bool first = true; for (int t = 0; t< tSelection.GetSize(); t++) { if (first) first= false; else arg += ' '; arg += addslash(tSelection[t]->sFullName); } } else { if (tFile.sName == "..") return 0; arg += addslash(tFile.sFullName); } break; } case 'd': arg += addslash(_pPanel->GetPath()); break; case 'D': bMcd = true; break; case 'P': bParam= true; break; case 'R': // root 계정 실행시 bRootExe = true; break; case 'H': arg += addslash(_pPanel->GetReader()->GetRealPath("~")); break; case 'Q': bConfirm = true; break; case 'B': bBackground = true; break; default: break; } bFlag = false; continue; } else arg += *i; } if (bMcd) { /* Mcd mcd(_tPanel); mcd.setCur(_tPanel->GetCurrentPath()); if (!mcd.proc()) return 0; arg += addslash(mcd.getCur()); */ } if (bParam) if (InputBox(_("Edit Parameter"), arg)<0) return 0; if (bConfirm) if (YNBox(_("Question"), _("Do you want to run this operation?"), false) != true) return 0; if (bRootExe) arg = "su - --command=\"" + arg + "\""; // 실행 int nRt = Run(arg, bPause, bBackground); return 0; } void CmdPanelImp::SplitViewSync() { g_tMainFrame.SetScreenSync(!g_tMainFrame.GetScreenSync()); if (g_tMainFrame.GetScreenSync()) { NCurses_Panel* pPanel = g_tMainFrame.GetPanel(1); NCurses_Mcd* pMcd = g_tMainFrame.GetMcd(0); void* pWait = MsgWaitBox( _("Wait"), _("Please wait !!! - Cancel Key [ESC]")); pMcd->Destroy(); pMcd->SetReader(pPanel->GetReader()); pMcd->Rescan(2); pMcd->AddDirectory(pPanel->GetReader()->GetPath()); pMcd->SetCur(pPanel->GetReader()->GetPath()); MsgWaitEnd(pWait); ViewSync(); } } void CmdPanelImp::ViewSync() { int nActive = g_tMainFrame.GetActiveNum(); NCurses_Panel* pPanel = g_tMainFrame.GetPanel(1); NCurses_Mcd* pMcd = g_tMainFrame.GetMcd(0); pMcd->AddDirectory(pPanel->GetReader()->GetPath()); pMcd->SetCur(pPanel->GetReader()->GetPath()); pPanel->_bFocus = true; pMcd->_bFocus = true; g_tMainFrame.Refresh(false); } void CmdPanelImp::Key_Enter() { if (g_tMainFrame.GetScreenSync()) { NCurses_Panel* pPanel = g_tMainFrame.GetPanel(1); NCurses_Mcd* pMcd = g_tMainFrame.GetMcd(0); Reader* pBefReader = pPanel->GetReader(); pPanel->Key_Enter(); if (pPanel->GetReader() != pBefReader) { pMcd->Destroy(); pMcd->SetReader(pPanel->GetReader()); pMcd->Rescan(2); pMcd->AddDirectory(pPanel->GetReader()->GetPath()); pMcd->SetCur(pPanel->GetReader()->GetPath()); pMcd->_bFocus = true; } else { pMcd->AddDirectory(pPanel->GetReader()->GetPath()); pMcd->SetCur(pPanel->GetReader()->GetPath()); } g_tMainFrame.Refresh(false); } else { _pPanel->Key_Enter(); } } void CmdPanelImp::Key_Left() { _pPanel->Key_Left(); if (g_tMainFrame.GetScreenSync()) ViewSync(); } void CmdPanelImp::Key_Right() { _pPanel->Key_Right(); if (g_tMainFrame.GetScreenSync()) ViewSync(); } void CmdPanelImp::Key_Up() { _pPanel->Key_Up(); if (g_tMainFrame.GetScreenSync()) ViewSync(); } void CmdPanelImp::Key_Down() { _pPanel->Key_Down(); if (g_tMainFrame.GetScreenSync()) ViewSync(); } void CmdPanelImp::Key_Home() { _pPanel->Key_Home(); if (g_tMainFrame.GetScreenSync()) ViewSync(); } void CmdPanelImp::Key_End() { _pPanel->Key_End(); if (g_tMainFrame.GetScreenSync()) ViewSync(); } void CmdPanelImp::Key_PageUp() { _pPanel->Key_PageUp(); if (g_tMainFrame.GetScreenSync()) ViewSync(); } void CmdPanelImp::Key_PageDown() { _pPanel->Key_PageDown(); if (g_tMainFrame.GetScreenSync()) ViewSync(); } void CmdPanelImp::Mcd() { g_tMainFrame.SetScreenSync(false); void* pWait = MsgWaitBox( _("Wait"), _("Please wait !!! - Cancel Key [ESC]")); _pMcd->Destroy(); _pMcd->SetReader(_pPanel->GetReader()); if ( _pPanel->GetReader() && _pPanel->GetReader()->GetReaderName() != "archive" ) { string sPath = _pMcd->GetReader()->GetInitType(); sPath = Replace(sPath, "/", "\\"); string sLoadName = g_tCfg.GetValue("Static", "CfgHome") + "McdDirSave/" + sPath; if ( !_pMcd->Load( sLoadName.c_str() ) ) _pMcd->Rescan(2); } else { _pMcd->Rescan(2); } _pMcd->AddDirectory(_pPanel->GetReader()->GetPath()); _pMcd->SetCur(_pPanel->GetReader()->GetPath()); MsgWaitEnd(pWait); g_tMainFrame.SetActiveViewType(MCD); _pMcd->_bFocus = true; } void CmdPanelImp::View() { File* pFile = _pPanel->GetCurFile(); if (pFile == NULL || pFile->bDir == true) { MsgBox(_("Error"), _("Don't directory view.")); return; } if (g_tMainFrame.GetActiveViewType() != PANEL) return; if (g_tCfg.GetValue("Default", "ExtViewer").empty()) { EditorChoice(false); } else { EditorChoice(false, g_tCfg.GetValue("Default", "ExtViewer")); } } void CmdPanelImp::Editor() { File* pFile = _pPanel->GetCurFile(); if (pFile == NULL || pFile->bDir == true) { MsgBox(_("Error"), _("Don't directory edit.")); return; } if (g_tMainFrame.GetActiveViewType() != PANEL) return; if (g_tCfg.GetValue("Default", "ExtEditor").empty()) { EditorChoice(false); } else { EditorChoice(false, g_tCfg.GetValue("Default", "ExtEditor")); } } void CmdPanelImp::ExtEditor() { if (g_tMainFrame.GetActiveViewType() != PANEL) return; if (g_tCfg.GetValue("Default", "ExtEditor").empty()) EditorChoice(false, "vi"); else EditorChoice(false, g_tCfg.GetValue("Default", "ExtEditor")); } void CmdPanelImp::EditorChoice(bool bReadOnly, const string& sEditorCmd, File* pFile) { if ( pFile == NULL ) { pFile = _pPanel->GetCurFile(); if (!pFile) return; } File tFile; if (_pPanel->GetReader()->View(pFile, &tFile) == false) return; bool bExtEditor = false; if (!sEditorCmd.empty()) bExtEditor = true; if (!bExtEditor) { g_tMainFrame.SetScreenSync(false); void* pWait = MsgWaitBox( _("Wait"), _("Please wait !!! - Cancel Key [ESC]")); int nSize = 0; string sSize = g_tCfg.GetValue("Default", "EditorTabSize"); if (sSize.size() == 0) nSize = 8; else nSize = atoi(sSize.c_str()); bool bEditorLineNum = g_tCfg.GetBool("Default", "EditorLineNum"); bool bEditorBackup = g_tCfg.GetBool("Default", "EditorBackup"); const string& sReaderName = _pPanel->GetReader()->GetReaderName(); if (bReadOnly == false) bReadOnly = (sReaderName == "archive") ? true : false; // title 은 원본을 보여준다. string sTitle = sReaderName + ":/" + isKorCode(pFile->sFullName); _pEditor->SetViewTitle( sTitle ); _pEditor->SetEditor(nSize, bEditorBackup, bEditorLineNum); if (_pEditor->Load(&tFile, bReadOnly) == false) { MsgWaitEnd(pWait); MsgBox( _("Error"), _("File loading failure.")); } else { g_tMainFrame.SetActiveViewType(EDITOR); MsgWaitEnd(pWait); _pEditor->_bFocus = true; g_tMainFrame.Refresh(); if ( _pEditor->_bFullScreen ) { MouseDestroy(); _pEditor->_bMouseMode = false; } } } else { g_Log.Write("ParseAndRun !!! [%s]", sEditorCmd.c_str()); if (sEditorCmd.empty()) ParseAndRun("vi " + addslash(tFile.sFullName)); else ParseAndRun(sEditorCmd + " " + addslash(tFile.sFullName)); if (_pPanel->GetReader()->GetReaderName() == "sftp" || _pPanel->GetReader()->GetReaderName() == "ftp" ) { string sPath = tFile.sFullName.substr( 0, tFile.sFullName.size() - tFile.sName.size() ); Selection tSelection; tSelection.Add( &tFile ); tSelection.SetSelectPath( sPath ); _pPanel->GetReader()->Paste( tSelection ); remove( tFile.sFullName.c_str() ); } ReloadConfigChange(); } return; } void CmdPanelImp::ClearRefresh() { ScreenClear(); Refresh(); } void CmdPanelImp::Refresh() { string sFileName1, sFileName2; if (g_tMainFrame.GetPanel(0)->GetCurFile() != NULL) sFileName1 = g_tMainFrame.GetPanel(0)->GetCurFile()->sFullName; if (g_tMainFrame.GetPanel(1)->GetCurFile() != NULL) sFileName2 = g_tMainFrame.GetPanel(1)->GetCurFile()->sFullName; g_tMainFrame.GetPanel(0)->Read(g_tMainFrame.GetPanel(0)->GetPath()); g_tMainFrame.GetPanel(1)->Read(g_tMainFrame.GetPanel(1)->GetPath()); if ( !sFileName1.empty() ) g_tMainFrame.GetPanel(0)->SetCurFileName( sFileName1 ); if ( !sFileName2.empty() ) g_tMainFrame.GetPanel(1)->SetCurFileName( sFileName2 ); g_tMainFrame.Refresh(); } void CmdPanelImp::Menu() { MlsMenu tMlsMenu; vector vDisableList; const string& sReaderName = _pPanel->GetReader()->GetReaderName(); if (sReaderName == "file") { vDisableList.push_back("Cmd_RemoteClose"); } else if (sReaderName == "ftp" || sReaderName == "sftp") { vDisableList.push_back("Cmd_RemoteConnect"); } else { vDisableList.push_back("Cmd_RemoteConnect"); vDisableList.push_back("Cmd_RemoteClose"); } tMlsMenu.SetDisable(vDisableList); tMlsMenu.SetPanel( _pPanel ); tMlsMenu.Create(); tMlsMenu.Do(); g_tMainFrame.Refresh(false); if (tMlsMenu.GetCurCmd().size() != 0) { g_Log.Write("Menu Run [%s]", tMlsMenu.GetCurCmd().c_str()); g_tMainFrame.GetCommand()->Execute(tMlsMenu.GetCurCmd()); } } void CmdPanelImp::Quit() { if (_pPanel->GetReader()->GetReaderName() == "sftp" || _pPanel->GetReader()->GetReaderName() == "ftp") { RemoteClose(); return; } if (g_tCfg.GetBool("Default", "AskMlsExit") == true) { bool bYN = YNBox(_("LinM Quit"), _("Do you really want to quit the LinM ?"), true); if (bYN == false) return; } // 마지막 mls 가 마지막으로 사용한 디렉토리를 저장한다. if (_pPanel->GetReader()->GetReaderName() == "file") { FILE *fp= fopen((g_tCfg.GetValue("CfgHome") + "path").c_str(), "wb"); if (fp) { fputs(_pPanel->GetPath().c_str(), fp); fclose(fp); } } g_tMainFrame.Exit(); } void CmdPanelImp::Split() { g_tMainFrame.Split(); } void CmdPanelImp::NextWindow() { g_tMainFrame.NextWindow(); } void CmdPanelImp::ArchiveFileView() { if (g_tMainFrame.GetActiveViewType() != PANEL) return; File* pFile = _pPanel->GetCurFile(); g_Log.Write("ArchiveFileView [%s]", pFile->sFullName.c_str()); if (pFile->sType.substr(0, 7) == "archive") MsgBox(_("Error"), "Archive file view failure !!!"); else { if (_pPanel->GetReader()->GetReaderName() != "file") _pPanel->PluginOpen(g_tCfg.GetValue("Static", "TmpDir") + pFile->sName, "archive"); else _pPanel->PluginOpen(pFile->sFullName, "archive"); } } void CmdPanelImp::ArchiveFileMake() { if (g_tMainFrame.GetActiveViewType() != PANEL) return; } void CmdPanelImp::RemoteConnect() { if (g_tMainFrame.GetActiveViewType() != PANEL) return; if (_pPanel->GetReader()->GetReaderName() != "file" ) { MsgBox(_("Error"), _("current remote connected.")); return; } string sConnectionInfo; sConnectionInfo = _Config.GetValue("Default", "LastRemoteConnected"); if (InputBox( _("Input sftp(ftp) connect url (sftp://user:pswd@hostname)"), sConnectionInfo) == ERROR) return; if (sConnectionInfo.size() > 6) { if (sConnectionInfo.substr(0, 6) == "ftp://") { sConnectionInfo = sConnectionInfo.substr(6); _pPanel->PluginOpen(sConnectionInfo, "ftp"); } else if (sConnectionInfo.substr(0, 7) == "sftp://") { sConnectionInfo = sConnectionInfo.substr(7); _pPanel->PluginOpen(sConnectionInfo, "sftp"); } else { _pPanel->PluginOpen(sConnectionInfo, "sftp"); } } else MsgBox(_("Error"), _("input url invalid format.")); if (_pPanel->GetReader()->GetReaderName() == "ftp" || _pPanel->GetReader()->GetReaderName() == "sftp") { _Config.SetValue( "Default", "LastRemoteConnected", _pPanel->GetReader()->GetInitType()); } g_tMainFrame.Refresh(); } void CmdPanelImp::RemoteClose() { if (g_tMainFrame.GetActiveViewType() != PANEL) return; if (g_tCfg.GetBool("Default", "AskRemoteExit") == true) { bool bYN = YNBox(_("Remote Close"), _("Do you really want to remote connection close ?"), true); if (bYN == false) return; } _pPanel->PluginClose("file"); Refresh(); } void CmdPanelImp::Remove() { Selection& tMainSelection = *(g_tMainFrame.GetSelection()); tMainSelection.Clear(); _pPanel->GetSelection(tMainSelection); tMainSelection.ExpandDir(_pPanel->GetReader(), false); _pPanel->GetReader()->Remove(tMainSelection); Refresh(); } void CmdPanelImp::CopyClip() { Selection& tMainSelection = *(g_tMainFrame.GetSelection()); tMainSelection.Clear(); _pPanel->GetSelection(tMainSelection); tMainSelection.SetSelectPath(_pPanel->GetReader()->GetPath()); tMainSelection.SetReader(_pPanel->GetReader()); if (tMainSelection.GetSize() == 0) g_tMainFrame.GetClip()->Set(CLIP_NONE); else g_tMainFrame.GetClip()->Set(CLIP_COPY); g_Log.Write("CopyClip [%s]", _pPanel->GetReader()->GetPath().c_str()); } void CmdPanelImp::CutClip() { Selection& tMainSelection = *(g_tMainFrame.GetSelection()); tMainSelection.Clear(); _pPanel->GetSelection(tMainSelection); tMainSelection.SetSelectPath(_pPanel->GetReader()->GetPath()); tMainSelection.SetReader(_pPanel->GetReader()); if (tMainSelection.GetSize() == 0) g_tMainFrame.GetClip()->Set(CLIP_NONE); else g_tMainFrame.GetClip()->Set(CLIP_CUT); g_Log.Write("CutClip [%s]", _pPanel->GetReader()->GetPath().c_str()); } void CmdPanelImp::PasteClip() { ClipState state = g_tMainFrame.GetClip()->GetState(); if (state == CLIP_NONE) return; if (state == CLIP_COPY) { CopyPaste(); } else if (state == CLIP_CUT) { CutPaste(); } Refresh(); } void CmdPanelImp::CopyPaste() { Selection& _tMainSelection = *(g_tMainFrame.GetSelection()); if (_tMainSelection.GetSize() <= 0) return; Selection tSelectionCopy; g_Log.Write("PasteClip Copy Start 1 - [%d] [%s] [%s] !!!", _tMainSelection.GetSize(), _tMainSelection[0]->sType.c_str(), _pPanel->GetReader()->GetInitType().c_str()); // Source 나 Target이 file이면 그대로 이용한다. if (_tMainSelection[0]->sType == "file://" && _pPanel->GetReader()->GetInitType() == "file://") { _tMainSelection.ExpandDir(_tMainSelection.GetReader(), false); // TmpDir 에 복사하고 나서 옮긴다. g_Log.Write("PasteClip Copy Start !!!"); _pPanel->GetReader()->Copy(_tMainSelection); g_Log.Write("PasteClip Copy End !!!"); } else { bool bUseGlobalReaderCtl = false; // 패널이 두개이기 때문에 mainframe 의 panel에서 Type에 맞는 데이터를 읽어 온다. Reader* pReader = g_tMainFrame.GetPanel(0)->GetReader(_tMainSelection[0]->sType); if (pReader == NULL || pReader->GetInitType() != _tMainSelection[0]->sType) { pReader = g_tMainFrame.GetPanel(1)->GetReader(_tMainSelection[0]->sType); if (pReader == NULL || pReader->GetInitType() != _tMainSelection[0]->sType) { // 그래도 없으면 만들서 넣어야 함. string::size_type p = _tMainSelection[0]->sType.find("://"); string sInitName; if (p == string::npos) sInitName = _tMainSelection[0]->sType; else sInitName = _tMainSelection[0]->sType.substr(0, p); // 이때는 g_tReaderCtl로 읽어 들여옴. pReader = g_tReaderCtl.Get(sInitName); if (pReader == NULL) { MsgBox(_("Error"), _("plugin not found.")); return; } g_Log.Write("g_tReaderCtl USE [%p] [%s]", pReader, sInitName.c_str()); bUseGlobalReaderCtl = true; if (p == string::npos) sInitName = _tMainSelection[0]->sType; else sInitName = _tMainSelection[0]->sType.substr(p+3); g_Log.Write("g_tReaderCtl USE [%p] [%s]", pReader, sInitName.c_str()); g_Log.Write("%s", pReader->GetReaderName().c_str()); pReader->Init(sInitName); if (pReader->GetConnected() == false) { pReader->Destroy(); } g_Log.Write("g_tReaderCtl Init [%p] [%s]", pReader, sInitName.c_str()); } } if (pReader->GetConnected() == false) { pReader->Init(_tMainSelection[0]->sType); if (pReader->GetConnected() == false) return; } // 압축은 디렉토리를 선택하면 디렉토리안의 내용도 같이 압축해제 하기 때문에. // 하위디렉토리까지 검사하지 않는다. 하위디렉토리 검사하면 시간이 더걸림. if ( pReader->GetReaderName() != "archive" ) _tMainSelection.ExpandDir(pReader, false); // TmpDir 에 복사하고 나서 옮긴다. if (pReader->Copy(_tMainSelection, g_tCfg.GetValue("Static", "TmpDir"), &tSelectionCopy)) { g_Log.Write("File Copy Complite !!!"); if (_pPanel->GetReader()->GetInitType() == "file://") { g_Log.Write("File Copy Move !!!"); // 파일일 경우는 이동한다. _pPanel->GetReader()->Move(tSelectionCopy); } else { g_Log.Write("File Copy TmpDir Remove !!!"); // 파일이 아닌 경우는 /tmp에서 다른 곳으로 복사 한 후 // /tmp에 있는 내용은 지운다. if (_pPanel->GetReader()->Paste(tSelectionCopy)) if ((pReader=_pPanel->GetReader("file://")) != NULL) pReader->Remove(tSelectionCopy, false); } } if (bUseGlobalReaderCtl == true) pReader->Destroy(); } } void CmdPanelImp::CutPaste() { Selection& _tMainSelection = *(g_tMainFrame.GetSelection()); if (_tMainSelection.GetSize() <= 0) return; g_Log.Write("PasteClip CLIP_CUT Start - [%d] [%s] [%s] !!!", _tMainSelection.GetSize(), _tMainSelection[0]->sType.c_str(), _pPanel->GetReader()->GetInitType().c_str()); if (_tMainSelection[0]->sType == "file://" && _pPanel->GetReader()->GetInitType() == "file://") { _tMainSelection.ExpandDir(_tMainSelection.GetReader(), false); // sType이 file 이면 그냥 옮긴다. _pPanel->GetReader()->Move(_tMainSelection); } else { bool bUseGlobalReaderCtl = false; // 패널이 두개이기 때문에 mainframe 의 panel에서 Type에 맞는 데이터를 읽어 온다. Reader* pReader = g_tMainFrame.GetPanel(0)->GetReader(_tMainSelection[0]->sType); if (pReader == NULL || pReader->GetInitType() != _tMainSelection[0]->sType) { pReader = g_tMainFrame.GetPanel(1)->GetReader(_tMainSelection[0]->sType); if (pReader == NULL || pReader->GetInitType() != _tMainSelection[0]->sType) { // 그래도 없으면 만들서 넣어야 함. string::size_type p = _tMainSelection[0]->sType.find("://"); string sInitName; if (p != string::npos) sInitName = _tMainSelection[0]->sType; else sInitName = _tMainSelection[0]->sType.substr(0, p); // 이때는 g_tReaderCtl로 읽어 들여옴. pReader = g_tReaderCtl.Get(sInitName); if (pReader == NULL) { MsgBox(_("Error"), _("plugin not found.")); return; } bUseGlobalReaderCtl = true; if (p == string::npos) sInitName = _tMainSelection[0]->sType; else sInitName = _tMainSelection[0]->sType.substr(p+3); pReader->Init(sInitName); if (pReader->GetConnected() == false) return; } } if (pReader->GetConnected() == false) { pReader->Init(_tMainSelection[0]->sType); if (pReader->GetConnected() == false) return; } // 압축은 디렉토리를 선택하면 디렉토리안의 내용도 같이 압축해제 하기 때문에. // 하위디렉토리까지 검사하지 않는다. 하위디렉토리 검사하면 시간이 더걸림. if ( pReader->GetReaderName() != "archive" ) _tMainSelection.ExpandDir(pReader, false); Selection tSelectionMove; // TmpDir 에 복사하고 나서 옮긴다. if (pReader->Copy(_tMainSelection, g_tCfg.GetValue("Static", "TmpDir"), &tSelectionMove)) { Reader* pCurReader = _pPanel->GetReader(); if (pCurReader->GetInitType() == "file://") { // 파일일 경우는 이동한다. if (pCurReader->Move(tSelectionMove)) pCurReader->Remove(_tMainSelection, false); // 이동하고 원본 삭제 } else { // 파일이 아닌 경우는 TmpDir 에서 다른 곳으로 복사 한 후 // TmpDir 에 있는 내용은 지운다. if (pCurReader->Paste(tSelectionMove)) if ((pReader = _pPanel->GetReader("file://")) != NULL) { pReader->Remove(tSelectionMove, false); // Tmp 디렉토리 지움. pCurReader->Remove(_tMainSelection, false); // 원본 삭제 } } } if (bUseGlobalReaderCtl == true) pReader->Destroy(); } } void CmdPanelImp::Key_ESC() { if (g_tMainFrame.GetScreenSync()) { g_tMainFrame.SetScreenSync(false); return; } if (_pPanel->GetReader()->GetReaderName() != "file") { if (_pPanel->GetReader()->GetReaderName() == "sftp" || _pPanel->GetReader()->GetReaderName() == "ftp") { RemoteClose(); return; } _pPanel->PluginClose("file"); } else { CursesDestroy(); cbreak(); noecho(); getch(); CursesInit(); } g_tMainFrame.Refresh(false); } void CmdPanelImp::Shell() { if (_pPanel->GetReader()->GetInitType() == "file://") g_tMainFrame.CmdShell(true); else MsgBox("Error", "shell is local file system use only."); } void CmdPanelImp::Rename() { File* pFile = _pPanel->GetCurFile(); _pPanel->GetReader()->Rename( pFile ); string sName = pFile->sFullName; _pPanel->SetCurFileName( sName ); Refresh(); } void CmdPanelImp::Mkdir() { _pPanel->GetReader()->Mkdir(); Refresh(); } void CmdPanelImp::GoRoot() { _pPanel->Read("/"); if (g_tMainFrame.GetScreenSync()) ViewSync(); Refresh(); } void CmdPanelImp::GoHome() { _pPanel->Read("~"); if (g_tMainFrame.GetScreenSync()) ViewSync(); Refresh(); } void CmdPanelImp::GoParent() { _pPanel->Read(".."); if (g_tMainFrame.GetScreenSync()) ViewSync(); Refresh(); } void CmdPanelImp::HiddenFileView() { g_Log.Write("_pPanel->GetHiddenView() [%s]", _pPanel->GetHiddenView() ? "TRUE" : "FALSE"); _pPanel->SetHiddenView(); Refresh(); } void CmdPanelImp::FileOwnerView() { g_Log.Write("_pPanel->GetHiddenView() [%s]", _pPanel->GetHiddenView() ? "TRUE" : "FALSE"); _pPanel->SetViewOwner( !_pPanel->GetViewOwner() ); Refresh(); } // sort void CmdPanelImp::SortChange() { _pPanel->_nSort++; if (_pPanel->_nSort == 5) _pPanel->_nSort=0; switch(_pPanel->_nSort) { case 0: SortName(); break; case 1: SortExt(); break; case 2: SortSize(); break; case 3: SortTime(); break; case 4: SortColor(); break; } } void CmdPanelImp::SortName() { _pPanel->SetSortMethod(SORT_NAME); _pPanel->Sort(); } void CmdPanelImp::SortExt() { _pPanel->SetSortMethod(SORT_EXT); _pPanel->Sort(); } void CmdPanelImp::SortSize() { _pPanel->SetSortMethod(SORT_SIZE); _pPanel->Sort(); } void CmdPanelImp::SortTime() { _pPanel->SetSortMethod(SORT_TIME); _pPanel->Sort(); } void CmdPanelImp::SortColor() { _pPanel->SetSortMethod(SORT_COLOR); _pPanel->Sort(); } void CmdPanelImp::ColumnAuto() { _pPanel->SetViewColumn(0); } void CmdPanelImp::Column1() { _pPanel->SetViewColumn(1); } void CmdPanelImp::Column2() { _pPanel->SetViewColumn(2); } void CmdPanelImp::Column3() { _pPanel->SetViewColumn(3); } void CmdPanelImp::Column4() { _pPanel->SetViewColumn(4); } void CmdPanelImp::DefaultCfgFileChg() { if ( _pPanel->GetReader()->GetReaderName() != "file") { MsgBox(_("Error"), _("Don't execute remote connect or archive file view.")); return; } File tFile; tFile.sFullName = g_tCfg.GetValue("Static", "CfgHome") + "default.cfg"; EditorChoice(false, "", &tFile); _pEditor->_bConfChg = true; } void CmdPanelImp::ColorCfgFileChg() { if ( _pPanel->GetReader()->GetReaderName() != "file") { MsgBox(_("Error"), _("Don't execute remote connect or archive file view.")); return; } File tFile; tFile.sFullName = g_tCfg.GetValue("Static", "CfgHome") + "colorset.cfg"; EditorChoice(false, "", &tFile); _pEditor->_bConfChg = true; } void CmdPanelImp::KeyCfgFileChg() { if ( _pPanel->GetReader()->GetReaderName() != "file") { MsgBox(_("Error"), _("Don't execute remote connect or archive file view.")); return; } File tFile; tFile.sFullName = g_tCfg.GetValue("Static", "CfgHome") + "keyset.cfg"; EditorChoice(false, "", &tFile); _pEditor->_bConfChg = true; } void CmdPanelImp::Copy() { g_tMainFrame.Copy(); } void CmdPanelImp::Move() { g_tMainFrame.Move(); } void CmdPanelImp::MountList() { _pPanel->MountList(); } void CmdPanelImp::SizeInfo() { Selection tSelection; _pPanel->GetSelection(tSelection); void* pWin = MsgWaitBox( _("Wait"), _("Please wait !!! - Cancel Key [ESC]")); tSelection.ExpandDir(_pPanel->GetReader(), true); MsgWaitEnd(pWin); String sMsg; sMsg.Append(_(" Selected files %10s / %10s byte "), toregular(tSelection.GetSize()).c_str(), toregular(tSelection.CalcSize()).c_str()); MsgBox( _("Size info"), sMsg.c_str()); } void CmdPanelImp::Forward() { _pPanel->Forward(); } void CmdPanelImp::Back() { _pPanel->Back(); } void CmdPanelImp::NewFile() { if ( _pPanel->GetReader()->GetReaderName() == "archive" ) { MsgBox("Error", "Don't new file in archive."); return; } string sFilename; if ( InputBox("Input new file name.", sFilename) == -1 ) return; if ( sFilename.size() == 0) return; if ( _pPanel->GetReader()->GetReaderName() == "file" ) sFilename = _pPanel->GetReader()->GetPath() + sFilename; else sFilename = g_tCfg.GetValue("Static", "TmpDir") + sFilename; g_Log.Write("NewFile !!! [%s]", sFilename.c_str()); string sEditorCmd = g_tCfg.GetValue("Default", "ExtEditor"); if ( sEditorCmd.empty() ) { ParseAndRun(sEditorCmd + " " + sFilename); Refresh(); return; } int nSize = 0; string sSize = g_tCfg.GetValue("Default", "EditorTabSize"); if (sSize.size() == 0) nSize = 8; else nSize = atoi(sSize.c_str()); bool bEditorLineNum = g_tCfg.GetBool("Default", "EditorLineNum"); bool bEditorBackup = g_tCfg.GetBool("Default", "EditorBackup"); // title 은 원본을 보여준다. string sTitle = _pPanel->GetReader()->GetReaderName() + ":/" + sFilename; _pEditor->SetViewTitle( sTitle ); _pEditor->SetEditor(nSize, bEditorBackup, bEditorLineNum); _pEditor->New(sFilename); g_tMainFrame.SetActiveViewType(EDITOR); _pEditor->_bFocus = true; g_tMainFrame.Refresh(); if ( _pEditor->_bFullScreen ) { MouseDestroy(); _pEditor->_bMouseMode = false; } } void CmdPanelImp::TouchFile() { if ( _pPanel->GetReader()->GetReaderName() == "archive" ) { MsgBox("Error", "Don't touch file in archive."); return; } string sFilename; if ( InputBox("Input touch file name.", sFilename) == -1 ) return; if ( sFilename.size() == 0) return; if ( _pPanel->GetReader()->GetReaderName() == "file" ) sFilename = _pPanel->GetReader()->GetPath() + sFilename; else sFilename = g_tCfg.GetValue("Static", "TmpDir") + sFilename; sFilename = "touch " + sFilename; system( sFilename.c_str() ); Refresh(); } /// @brief 각 type 에 맞게 현재 선택된 파일을 압축해준다. /// @param nType 0 : tar.gz, 1 : tar.bz2, 2 : zip void CmdPanelImp::FileCompress(int nType) { if ( _pPanel->GetReader()->GetReaderName() != "file" ) { MsgBox("Error", "local file system use only."); return; } string sTitle = _("Input name of the compressed file. [filename]"); string sFileName; switch(nType) { case 0: InputBox((sTitle + ".tar.gz").c_str(), sFileName); if (sFileName == "") return; sFileName = sFileName + ".tar.gz"; break; case 1: InputBox((sTitle + ".tar.bz2").c_str(), sFileName); if (sFileName == "") return; sFileName = sFileName + ".tar.bz2"; break; case 2: InputBox((sTitle + ".zip").c_str(), sFileName); if (sFileName == "") return; sFileName = sFileName + ".zip"; break; default: return; break; } sFileName = _pPanel->GetReader()->GetPath() + sFileName; if (access(sFileName.c_str(), R_OK) == 0) { MsgBox(_("Error"), _("input file used.")); return; } if (access( _pPanel->GetReader()->GetPath().c_str(), W_OK) == -1) { MsgBox(_("Error"), strerror(errno)); return; } string sView = _("Please wait !!! - Compress file [") + sFileName + "]"; void* pWin = MsgWaitBox( _("Wait"), sView); Selection tSelection; _pPanel->GetSelection(tSelection); vector tFileList = tSelection.GetData(); Archive tArchive( sFileName ); tArchive.Compress(tFileList, TAR_APPEND, _pPanel->GetReader()->GetPath()); MsgWaitEnd(pWin); Refresh(); } void CmdPanelImp::ViewClip() { void* pWait = MsgWaitBox( _("Wait"), _("Please wait !!! - Cancel Key [ESC]")); Selection tSelection; _pPanel->GetSelection(tSelection); tSelection.ExpandDir(_pPanel->GetReader(), true); MsgWaitEnd(pWait); Refresh(); vector tFileList = tSelection.GetData(); vector tViewList; String sSize; sSize.Append(_("Selected files %10s / %10s byte "), toregular(tSelection.GetSize()).c_str(), toregular(tSelection.CalcSize()).c_str()); tViewList.push_back(sSize.c_str()); tViewList.push_back(""); string sCurPath = _pPanel->GetPath(); for (uint n = 0; n < tFileList.size(); n++) { File* pFile = tFileList[n]; String sData; string sName; if ( pFile->sFullName.substr(0, sCurPath.size()) == sCurPath ) sName = "./" + pFile->sFullName.substr(sCurPath.size()); else sName = pFile->sFullName; if ( sName.size() > 51 ) { string sCutName = sName.substr( sName.size()-50, 50 ); sData.AppendBlank(50, sCutName.c_str()); } else sData.AppendBlank(50, sName.c_str()); if (pFile->uSize >= 10000000) sData.Append("%9.1fM", (float)pFile->uSize/1048576); else sData.Append("%10s", toregular(pFile->uSize).c_str()); tViewList.push_back(sData.c_str()); } TextListBox( _("Clipboard View"), tViewList, true ); Refresh(); } void CmdPanelImp::Extract() { if ( _pPanel->GetReader()->GetReaderName() == "archive" ) { MsgBox("Error", "Don't touch file in archive."); return; } g_Log.Write("Extract !!!"); File tFile; if (_pPanel->GetReader()->View(_pPanel->GetCurFile(), &tFile) == false) return; string sMsg = _("Compress the select files."); vector q; Archive tArchive( tFile.sFullName ); int nFileinfo = tArchive.GetZipType( tFile.sFullName ); if (_pPanel->GetReader()->GetReaderName() == "file" ) { q.push_back(sMsg + "(tar.gz)"); q.push_back(sMsg + "(tar.bz2)"); q.push_back(sMsg + "(zip)"); if (nFileinfo == ERROR) { q.push_back(_("Cancel")); g_Log.Write("Extract()()()()() !!!"); int nSelect = SelectBox(sMsg.c_str(), q, 0); if (nSelect == -1) return; FileCompress(nSelect); return; } } string sInsertMsg; sInsertMsg = sInsertMsg + _("Current file install.") + "[" + tFile.sName + "]"; q.insert(q.begin(), sInsertMsg); q.push_back(_("Cancel")); int nSelect = SelectBox(sMsg.c_str(), q, 0); if (nSelect == -1) return; if (_pPanel->GetReader()->GetReaderName() == "file" && nFileinfo == SUCCESS) { if (nSelect != 0) { FileCompress(nSelect-1); return; } } else { if (nSelect == q.size()-1) return; } int nZipType = tArchive.GetCurZipType(); string sFilename = tFile.sFullName; switch(nZipType) { case TAR_GZ: case TAR_BZ: case ZIP: case ALZ: case TAR: { g_tMainFrame.SetMcdExeMode(ARCHIVE_COPY, tFile.sFullName); Mcd(); break; } case RPM: { vector q; q.push_back(_("Install")); q.push_back(_("Install Nodeps")); q.push_back(_("Cancel")); int nSelect = SelectBox(tFile.sName.c_str(), q, 0); string sCommand; switch(nSelect ) { case 0: // root 계정으로 실행 sCommand = "rpm -Uvh " + sFilename + " %R %W"; break; case 1: // root 계정으로 실행 sCommand = "rpm -Uvh --nodeps " + sFilename + " %R %W"; break; case 2: return; break; default: return; } ParseAndRun( sCommand, true ); break; } case DEB: { string sMsg = _("Do you want install current file ?"); sMsg = sMsg + "[" + tFile.sName + "]"; if ( YNBox(_("Question"), sMsg.c_str(), false) != true ) { string sCommand = "dpkg -i " + sFilename + " %R %W"; ParseAndRun( sCommand, true ); } break; } default: return; } Refresh(); } void CmdPanelImp::Execute() { File tFile; if (_pPanel->GetReader()->View(_pPanel->GetCurFile(), &tFile) == false) return; vector q; q.push_back(_("Run")); q.push_back(_("Run(root)")); q.push_back(_("Edit")); q.push_back(_("ExtEditor")); q.push_back(_("Parameter")); q.push_back(_("Parameter(root)")); q.push_back(_("Cancel")); int nSelect = SelectBox(_("Execute select"), q, 0); if (nSelect == -1) return; switch(nSelect) { case 0: ParseAndRun(_pPanel->GetCurFile()->sFullName + " %W"); return; case 1: ParseAndRun(_pPanel->GetCurFile()->sFullName + " %R %W"); return; case 2: View(); return; case 3: Editor(); return; case 4: case 5: { string sParam; if (InputBox(_("Input parameter."), sParam) == SUCCESS) if (nSelect == 4) ParseAndRun(_pPanel->GetCurFile()->sFullName + " %W " + sParam); else ParseAndRun(_pPanel->GetCurFile()->sFullName + " %R %W " + sParam); return; } } } void CmdPanelImp::QCD() { Qcd tQCD; tQCD.Size(14, 30); tQCD.Move(MIDDLE, MIDDLE); tQCD.Do(); if (tQCD.GetNum() != -1) { if (g_tMainFrame.GetMcdExeMode().eMcdExeMode == MCD_EXEMODE_NONE) { _pPanel->GetReader()->Read( tQCD.GetData() ); Refresh(); } else { Mcd(); Refresh(); } } } void ModeToBool(mode_t tMode, vector& vBool) { for (int n=0; n< 12;n++) vBool.push_back(false); if (tMode & S_ISUID) vBool[0] = true; if (tMode & S_ISGID) vBool[1] = true; if (tMode & S_ISVTX) vBool[2] = true; if (tMode & S_IRUSR) vBool[3] = true; if (tMode & S_IWUSR) vBool[4] = true; if (tMode & S_IXUSR) vBool[5] = true; if (tMode & S_IRGRP) vBool[6] = true; if (tMode & S_IWGRP) vBool[7] = true; if (tMode & S_IXGRP) vBool[8] = true; if (tMode & S_IROTH) vBool[9] = true; if (tMode & S_IWOTH) vBool[10] = true; if (tMode & S_IXOTH) vBool[11] = true; } mode_t BoolToMode(vector& vBool) { mode_t tMode = 0; if (vBool[0] == true) tMode = tMode | S_ISUID; if (vBool[1] == true) tMode = tMode | S_ISGID; if (vBool[2] == true) tMode = tMode | S_ISVTX; if (vBool[3] == true) tMode = tMode | S_IRUSR; if (vBool[4] == true) tMode = tMode | S_IWUSR; if (vBool[5] == true) tMode = tMode | S_IXUSR; if (vBool[6] == true) tMode = tMode | S_IRGRP; if (vBool[7] == true) tMode = tMode | S_IWGRP; if (vBool[8] == true) tMode = tMode | S_IXGRP; if (vBool[9] == true) tMode = tMode | S_IROTH; if (vBool[10] == true) tMode = tMode | S_IWOTH; if (vBool[11] == true) tMode = tMode | S_IXOTH; return tMode; } void CmdPanelImp::Chmod() { if ( _pPanel->GetReader()->GetReaderName() != "file") { MsgBox(_("Error"), _("chmod local file system only.")); return; } Selection tSelection; _pPanel->GetSelection(tSelection); vector tFileList = tSelection.GetData(); for (int n = 0; n < tFileList.size(); n++) { if (tFileList[n]->bDir) { if ( YNBox(_("Question"), _("subdirectory files permision change ?")) ) { tSelection.ExpandDir(_pPanel->GetReader(), true); tFileList = tSelection.GetData(); } Refresh(); break; } } struct stat t_stat; mode_t mode_1, mode_2; bool bStat = true; for ( int n = 0; n < tFileList.size(); n++ ) { if (stat(tFileList[n]->sFullName.c_str(), &t_stat) == -1) continue; mode_1 = t_stat.st_mode; if (mode_1 != mode_2 && n != 0) { bStat = false; break; } mode_2 = t_stat.st_mode; } vector vViewStr; vector vBool; vViewStr.push_back(_("set user ID on execution")); vViewStr.push_back(_("set group ID on execution")); vViewStr.push_back(_("sticky bit")); vViewStr.push_back(_("read by owner")); vViewStr.push_back(_("write by owner")); vViewStr.push_back(_("execute/search by owner")); vViewStr.push_back(_("read by group")); vViewStr.push_back(_("write by group")); vViewStr.push_back(_("execute/search by group")); vViewStr.push_back(_("read by other")); vViewStr.push_back(_("write by other")); vViewStr.push_back(_("execute/search by other")); ModeToBool(mode_1, vBool); Curses_CheckBox tCheckBox(_("Chmod selected files")); tCheckBox.Size(16, 30); tCheckBox.SetChkData(vViewStr, vBool); tCheckBox.Move(MIDDLE, MIDDLE); tCheckBox.Do(); if ( !tCheckBox.IsYes() ) { Refresh(); return; } vBool = tCheckBox.GetChkList(); mode_1 = BoolToMode(vBool); vViewStr.clear(); // Errstring 역활을 한다. for (int n=0; nsFullName.c_str(), mode_1)==-1) { string sStr = tFileList[n]->sFullName + " - " + strerror(errno); vViewStr.push_back(sStr); } } Refresh(); if (vViewStr.size() != 0) { Curses_TextBox tTextBox(_("Error Info")); int nHeightSize = vViewStr.size(); if ( nHeightSize > LINES-6 && LINES-6 > 0 ) nHeightSize = LINES-6; else nHeightSize = vViewStr.size() + 6; int nMaxWidth = COLS-4; for (uint n = 0; n < vViewStr.size(); n++) { int nSize = scrstrlen( vViewStr[n] ); if ( nSize > nMaxWidth) nMaxWidth = nSize; } tTextBox.backcolor = COLOR_RED; tTextBox.fontcolor = COLOR_WHITE; if ( nMaxWidth+4 > COLS - 8 ) nMaxWidth = COLS-8-4; tTextBox.setCurShow( true ); tTextBox.Size(nHeightSize, nMaxWidth+4); tTextBox.setText( vViewStr ); tTextBox.Move(MIDDLE, MIDDLE); tTextBox.Do(); } }