/* * Descent 3 * Copyright (C) 2024 Parallax Software * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // FilePageAddDlg.cpp : implementation file // #include "stdafx.h" #include "editor.h" #include "FilePageAddDlg.h" #include "ddio.h" #include "mem.h" #include #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CFilePageAddDlg dialog CFilePageAddDlg::CFilePageAddDlg(CWnd *pParent /*=NULL*/) : CDialog(CFilePageAddDlg::IDD, pParent) { //{{AFX_DATA_INIT(CFilePageAddDlg) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT m_NumberOfSelectedFiles = 0; m_SelectedFiles = NULL; m_SelectedDestDir = NULL; initial_path = ""; } CFilePageAddDlg::~CFilePageAddDlg(void) { if (m_SelectedFiles) { for (int i = 0; i < m_NumberOfSelectedFiles; i++) { if (m_SelectedFiles[i]) mem_free(m_SelectedFiles[i]); } mem_free(m_SelectedFiles); } if (m_SelectedDestDir) { mem_free(m_SelectedDestDir); } } void CFilePageAddDlg::SetInitialPath(char *path) { char olddir[_MAX_PATH]; ddio_GetWorkingDir(olddir, _MAX_PATH); if (ddio_SetWorkingDir(path)) { if (path[1] == ':') initial_path = path; } ddio_SetWorkingDir(olddir); } void CFilePageAddDlg::DoDataExchange(CDataExchange *pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CFilePageAddDlg) // NOTE: the ClassWizard will add DDX and DDV calls here //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CFilePageAddDlg, CDialog) //{{AFX_MSG_MAP(CFilePageAddDlg) ON_CBN_SELCHANGE(IDC_LIST_DRIVES, OnSelchangeListDrives) ON_LBN_SELCHANGE(IDC_LIST_FOLDERS, OnSelchangeListFolders) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CFilePageAddDlg message handlers // CFileList CFileList::CFileList() {} CFileList::~CFileList() {} BEGIN_MESSAGE_MAP(CFileList, CListBox) //{{AFX_MSG_MAP(CFileList) ON_CONTROL_REFLECT(LBN_DBLCLK, OnDblclk) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CFileList message handlers // fills the list-box with the appropriate information // either files, directories or drives // in this case system and/or hidden files are not shown BOOL CFileList::FillBox() { WIN32_FIND_DATA FileData; HANDLE hSearch; CString csString; BOOL check_dir; SetRedraw(FALSE); if (m_nFlag == DRIVES) { Dir(0x4000, m_csPath); } else { // resets the list-box; parent-function ResetContent(); // construct the path and mask for displaying csString = m_csPath; csString += m_csFileMask; hSearch = FindFirstFile(csString, &FileData); if (hSearch == INVALID_HANDLE_VALUE) return FALSE; check_dir = (m_nFlag == DIRECTORIES ? TRUE : FALSE); CheckEntry(FileData.cFileName, FileData.dwFileAttributes, check_dir); while (1) { if (!FindNextFile(hSearch, &FileData)) { SetRedraw(); InvalidateRect(NULL); // Close the search handle. if (!FindClose(hSearch)) return FALSE; return TRUE; } else CheckEntry(FileData.cFileName, FileData.dwFileAttributes, check_dir); } } SetRedraw(); InvalidateRect(NULL); return TRUE; } BOOL CFileList::InitBox(UINT res, CWnd *parent, LPSTR lpszPath, LPSTR lpszFileMask, UINT flags, UINT msg, void (*cb)(char *)) { m_nFlag = flags; m_csPath = lpszPath; m_csFileMask = lpszFileMask; m_nMsg = msg; m_cwndParent = parent; callback = cb; // let's check if a \ is the last letter in the path if (m_nFlag == DRIVES || m_nFlag == DIRECTORIES) { if (m_csPath.Right(1) != "\\") m_csPath += "\\"; } // subclassing the dialog-template listbox if (SubclassDlgItem(res, parent) == FALSE) return FALSE; return FillBox(); } // by double-clicking .. in a drive-box the // path will get longer and longer such as // c:\inn\pics\..\html\..\..\windows\system\..\..\det.log // the proper path in this example should be // c:\det.log void CFileList::OnDblclk() { // TODO: Add your control notification handler code here CString temp_string, temp_string2; GetText(GetCurSel(), temp_string); switch (m_nFlag) { case DRIVES: // is the drive available // temp_string2=temp_string; temp_string.MakeUpper(); if (!_chdrive(temp_string[2] - 'A' + 1)) { m_csPath.Format("%c:\\", temp_string[2]); m_cwndParent->PostMessage(m_nMsg, DRIVES, 0); } else { SetCurSel(-1); temp_string2.Empty(); temp_string2.Format("Drive %c is not available", temp_string[2]); MessageBox(temp_string2); } break; case DIRECTORIES: // if we dblclk a .. then we move up one level if (temp_string == "..") { m_csPath = m_csPath.Left(m_csPath.ReverseFind('\\')); m_csPath = m_csPath.Left(m_csPath.ReverseFind('\\')); m_csPath += '\\'; } else // otherwise we just add another sub-dir to the path m_csPath = m_csPath + temp_string + '\\'; FillBox(); // notify mama about an update m_cwndParent->PostMessage(m_nMsg, DIRECTORIES, 0); break; case FILES: m_cwndParent->PostMessage(m_nMsg, FILES, 0); break; } } // get and set functions inline CString CFileList::getPath() { return m_csPath; } inline CString CFileList::getFileMask() { return m_csFileMask; } inline void CFileList::setFileMask(CString mask) { m_csFileMask = (LPCTSTR)mask; } inline BOOL CFileList::RefreshMask(CString mask) { m_csFileMask = mask; return FillBox(); } // let's check if we display the right entries // we don't want any hidden, system, temporary and/or directories (for a file-box) inline void CFileList::CheckEntry(LPSTR name, DWORD flag, BOOL dir) { // we don't want to display a .; that is the current directory, or // a ..(previous directory) in a filebox if (name[0] == '.') if (!dir) return; if (name[1] == '\0') return; // we don't want to show any system and/or hidden files/directories if (flag & FILE_ATTRIBUTE_HIDDEN) return; if (flag & FILE_ATTRIBUTE_SYSTEM) return; // we don't want any directories in a file-box if (dir) { if (!(flag & FILE_ATTRIBUTE_DIRECTORY)) return; } //... or files in a dir-box else { if (flag & FILE_ATTRIBUTE_DIRECTORY) return; } AddString(name); } inline BOOL CFileList::RefreshBox(CString path, CString mask) { setPath(path); setFileMask(mask); return FillBox(); } inline BOOL CFileList::RefreshBox(CString path) { setPath(path); return FillBox(); } inline void CFileList::setPath(CString path) { CString temp = path; char *buffer; // check for valid entry if (temp.Right(1) != "\\") temp += "\\"; buffer = (char *)mem_malloc(temp.GetLength() + 1); if (!buffer) return; // ddio_CleanPath(buffer,temp.GetBuffer(0)); strcpy(buffer, temp.GetBuffer(0)); m_csPath = buffer; if (callback) (*callback)(buffer); mem_free(buffer); } BOOL CFilePageAddDlg::OnInitDialog() { CDialog::OnInitDialog(); // TODO: Add extra initialization here // register a personal, user-defined msg so that our boxes can post msg's for // interaction m_nBoxMsg = RegisterWindowMessage("FilePageDlgAdd"); // init the boxes // the definition of: // BOOL InitBox(UINT res_from_template, // CWnd *parent, // LPSTR lpszPath, // LPSTR lpszFileMask, // UINT flags, // UINT msg); if (initial_path.IsEmpty()) initial_path = "c:\\"; m_cflDrive.InitBox(IDC_LIST_DRIVES, this, initial_path.GetBuffer(0), "*.*", DRIVES, m_nBoxMsg); m_cflDir.InitBox(IDC_LIST_FOLDERS, this, initial_path.GetBuffer(0), "*.*", DIRECTORIES, m_nBoxMsg); m_cflFile.InitBox(IDC_LIST_FILES, this, initial_path.GetBuffer(0), "*.*", FILES, m_nBoxMsg); // Add the drives to the drive list CComboBox *combo = (CComboBox *)GetDlgItem(IDC_LIST_DRIVES); char *root_drives[256]; int root_count = ddio_GetFileSysRoots(root_drives, 256); int i, c_drive = 0; char initial_d[3]; strncpy(initial_d, initial_path.GetBuffer(0), 2); initial_d[2] = '\0'; for (i = 0; i < root_count; i++) { if (!strnicmp(root_drives[i], initial_d, 2)) c_drive = i; combo->AddString(root_drives[i]); mem_free(root_drives[i]); } combo->SetCurSel(c_drive); combo = (CComboBox *)GetDlgItem(IDC_DIRS); for (i = 0; i < NumDirectoryNames; i++) { combo->AddString(DirectoryNames[i]); } combo->SetCurSel(0); return TRUE; } LRESULT CFilePageAddDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { // TODO: Add your specialized code here and/or call the base class ... // process the user-defined msg if (message == m_nBoxMsg) { // update the dir-box and file-box if we change drive if (wParam == DRIVES) { m_cflDir.RefreshBox(m_cflDrive.getPath()); m_cflFile.RefreshBox(m_cflDrive.getPath()); } // update the file-box if we change directory else if (wParam == DIRECTORIES) { m_cflFile.RefreshBox(m_cflDir.getPath()); } } return CDialog::WindowProc(message, wParam, lParam); } void CFilePageAddDlg::OnSelchangeListDrives() { CComboBox *combo = (CComboBox *)GetDlgItem(IDC_LIST_DRIVES); int sel = combo->GetCurSel(); CString drive; combo->GetLBText(sel, drive); m_cflDrive.setPath(drive); m_cflDir.RefreshBox(m_cflDrive.getPath()); m_cflFile.RefreshBox(m_cflDrive.getPath()); } void CFilePageAddDlg::OnSelchangeListFolders() {} bool CFilePageAddDlg::Quit(void) { char buffer[_MAX_PATH]; int cur_sel; CComboBox *combo = (CComboBox *)GetDlgItem(IDC_DIRS); cur_sel = combo->GetCurSel(); combo->GetLBText(cur_sel, buffer); char temp[1024]; sprintf(temp, "Are you sure you want to add these files to the data\\%s directory?", buffer); if (MessageBox(temp, NULL, MB_YESNO) != IDYES) { return false; } m_SelectedDestDir = mem_strdup(buffer); CListBox *list = (CListBox *)GetDlgItem(IDC_LIST_FILES); m_NumberOfSelectedFiles = list->GetSelCount(); if (m_NumberOfSelectedFiles == 0) { m_SelectedFiles = NULL; } else { m_SelectedFiles = (char **)mem_malloc(m_NumberOfSelectedFiles * sizeof(char *)); if (!m_SelectedFiles) { m_SelectedFiles = NULL; m_NumberOfSelectedFiles = 0; return true; } int *sel_items = (int *)mem_malloc(sizeof(int) * m_NumberOfSelectedFiles); if (!sel_items) { mem_free(m_SelectedFiles); m_SelectedFiles = NULL; m_NumberOfSelectedFiles = 0; return true; } list->GetSelItems(m_NumberOfSelectedFiles, sel_items); char temp[_MAX_PATH]; char drive[_MAX_PATH]; strcpy(drive, m_cflFile.getPath()); for (int i = 0; i < m_NumberOfSelectedFiles; i++) { cur_sel = sel_items[i]; list->GetText(cur_sel, temp); // ummm, figure out real path here ddio_MakePath(buffer, drive, temp, NULL); m_SelectedFiles[i] = mem_strdup(buffer); } } return true; } void CFilePageAddDlg::OnOK() { if (!Quit()) return; CDialog::OnOK(); }