/* * 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 . --- HISTORICAL COMMENTS FOLLOW --- * $Logfile: /DescentIII/Main/hogedit/HogEditView.cpp $ * $Revision: 1.1.1.1 $ * $Date: 2003-08-26 03:57:56 $ * $Author: kevinb $ * * * * $Log: not supported by cvs2svn $ * * 17 5/05/99 12:53p Nate * Added support for multiple file extraction * * 16 2/10/99 1:03p Nate * Fixed infinite loop when importing duplicate directories * * 15 12/03/98 10:38a Nate * Added support for loading/saving hogs with extensions other than '.hog' * * 14 10/30/98 11:15a Nate * Added support for modification of hog files. * * 13 10/28/98 11:24a Nate * Added command line auto-processing (create hog from a rib) * * 12 10/15/98 2:53p Nate * Fixed title bar filename bug * * 11 9/17/98 4:29p Nate * Added Import Directory option. * * 10 8/16/98 4:22p Nate * Added message deferal and new hog info dialog * * 9 8/14/98 7:47p Nate * Removed "duplicate file" error message (upon File Inserts) * * 8 8/14/98 6:04p Nate * Added number of files field to status bar. * * 7 8/14/98 4:38p Nate * Fixed a few minor bugs and added better error reporting * * 6 8/14/98 1:01p Nate * Added better error reporting for the HogEditor * * 5 7/22/98 2:38p Nate * Added Modified File prompt when exiting * * 4 7/22/98 2:10p Nate * Added MB field to Hog Create message prompt * * 3 7/20/98 3:35p Nate * Added more Editing functionality * * 2 7/15/98 12:31p Nate * Initial version * * $NoKeywords: $ */ // HogEditView.cpp : implementation of the CHogEditView class // #include "stdafx.h" #include #include #include #include "HogEdit.h" #include "hogfile.h" #include "HogEditDoc.h" #include "listvwex.h" #include "HogEditView.h" #include "HogInfo.h" #include "DirDialog.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CHogEditView IMPLEMENT_DYNCREATE(CHogEditView, CListView) BEGIN_MESSAGE_MAP(CHogEditView, CListView) //{{AFX_MSG_MAP(CHogEditView) ON_COMMAND(ID_FILE_NEW, OnFileNew) ON_COMMAND(ID_ACTION_INSERT, OnActionInsert) ON_COMMAND(ID_FILE_OPEN, OnFileOpen) ON_COMMAND(ID_FILE_SAVE, OnFileSave) ON_COMMAND(ID_FILE_SAVE_AS, OnFileSaveAs) ON_COMMAND(ID_ACTION_DELETE, OnActionDelete) ON_COMMAND(ID_ACTION_CREATE, OnActionCreate) ON_COMMAND(ID_VIEW_FULL_ROW, OnViewFullRow) ON_UPDATE_COMMAND_UI(ID_VIEW_FULL_ROW, OnUpdateViewFullRow) ON_COMMAND(ID_ACTION_UPDATE, OnActionUpdate) ON_COMMAND(ID_ACTION_EXTRACT, OnActionExtract) ON_UPDATE_COMMAND_UI(ID_ACTION_DELETE, OnUpdateActionDelete) ON_UPDATE_COMMAND_UI(ID_ACTION_EXTRACT, OnUpdateActionExtract) ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnColumnclick) ON_COMMAND(ID_ACTION_IMPORT, OnActionImport) ON_MESSAGE(WM_STRAIGHT_TO_FILE_OPEN, OnStraightToFileOpen) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CHogEditView construction/destruction CHogEditView::CHogEditView() { // TODO: add construction code here } CHogEditView::~CHogEditView() {} BOOL CHogEditView::PreCreateWindow(CREATESTRUCT &cs) { // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs cs.style |= LVS_SHOWSELALWAYS | LVS_REPORT | LVS_SORTASCENDING; // | LVS_NOSORTHEADER; return CListView::PreCreateWindow(cs); } ///////////////////////////////////////////////////////////////////////////// // CHogEditView drawing void CHogEditView::OnDraw(CDC *pDC) { CHogEditDoc *pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here } void CHogEditView::OnInitialUpdate() { CListView::OnInitialUpdate(); // TODO: You may populate your ListView with items by directly accessing // its list control through a call to GetListCtrl(). CListCtrl &lcp = GetListCtrl(); // Add column names lcp.InsertColumn(FILE_NAME_COLUMN, FILE_NAME_TITLE, LVCFMT_LEFT, -1, FILE_NAME_COLUMN); lcp.InsertColumn(FILE_TYPE_COLUMN, FILE_TYPE_TITLE, LVCFMT_LEFT, -1, FILE_TYPE_COLUMN); lcp.InsertColumn(FILE_DIR_COLUMN, FILE_DIR_TITLE, LVCFMT_LEFT, -1, FILE_DIR_COLUMN); lcp.InsertColumn(FILE_SIZE_COLUMN, FILE_SIZE_TITLE, LVCFMT_RIGHT, -1, FILE_SIZE_COLUMN); lcp.InsertColumn(FILE_TIME_COLUMN, FILE_TIME_TITLE, LVCFMT_RIGHT, -1, FILE_TIME_COLUMN); SetColumnWidths(); OutputDebugString("Posting Message...\n"); if (DoAutoProcess) { PostMessage(WM_STRAIGHT_TO_FILE_OPEN); } } // Calculates column widths and sets them void CHogEditView::SetColumnWidths(void) { CListCtrl &lcp = GetListCtrl(); uint32_t w0, w1, w2, w3, w4; RECT rect; lcp.GetClientRect(&rect); w0 = uint32_t(rect.right * FILE_NAME_COLUMN_WIDTH); w1 = uint32_t(rect.right * FILE_TYPE_COLUMN_WIDTH); w2 = uint32_t(rect.right * FILE_DIR_COLUMN_WIDTH); w3 = uint32_t(rect.right * FILE_SIZE_COLUMN_WIDTH); w4 = rect.right - (w0 + w1 + w2 + w3); lcp.SetColumnWidth(FILE_NAME_COLUMN, w0); lcp.SetColumnWidth(FILE_TYPE_COLUMN, w1); lcp.SetColumnWidth(FILE_DIR_COLUMN, w2); lcp.SetColumnWidth(FILE_SIZE_COLUMN, w3); lcp.SetColumnWidth(FILE_TIME_COLUMN, w4); } ///////////////////////////////////////////////////////////////////////////// // CHogEditView diagnostics #ifdef _DEBUG void CHogEditView::AssertValid() const { CListView::AssertValid(); } void CHogEditView::Dump(CDumpContext &dc) const { CListView::Dump(dc); } CHogEditDoc *CHogEditView::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CHogEditDoc))); return (CHogEditDoc *)m_pDocument; } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CHogEditView message handlers void CHogEditView::OnFileNew() { // TODO: Add your command handler code here CHogEditDoc *doc = GetDocument(); CListCtrl &list = GetListCtrl(); // Set full row selection SetFullRowSel(m_bFullRowSel); // If current file has been modified, check with user first... if (ModifiedPrompt(this) == IDNO) return; // Display Wait Cursor CWaitCursor wc; // Clear out the document's information doc->OnNewDocument(); // Wipeout the CtrlList items list.DeleteAllItems(); // Put new doc name on title bar UpdateTitle(doc->m_DocumentName, DocModified); UpdateTotalFiles(list.GetItemCount()); } // Returns a type string for the given filename extension void CHogEditView::GetFileType(char *type, char *filename) { char ext[PSFILENAME_LEN + 1]; _splitpath(filename, NULL, NULL, NULL, ext); if (!strcmp(ext, ".ogf")) { strcpy(type, "Outrage Graphics File"); return; } if (!strcmp(ext, ".oof")) { strcpy(type, "Outrage Object File"); return; } if (!strcmp(ext, ".oaf")) { strcpy(type, "Outrage Animation File"); return; } if (!strcmp(ext, ".orf")) { strcpy(type, "Outrage Room File"); return; } if (!strcmp(ext, ".wav")) { strcpy(type, "Sound File"); return; } if (!strcmp(ext, ".scr")) { strcpy(type, "Script File"); return; } if (!strcmp(ext, ".d3x")) { strcpy(type, "D3X Object Code"); return; } if (!strcmp(ext, ".inf")) { strcpy(type, "Misc Config File"); return; } // Default strcpy(type, "Unknown"); } void CHogEditView::OnActionInsert() { // TODO: Add your command handler code here CListCtrl &list = GetListCtrl(); CHogEditDoc *doc = GetDocument(); hog_library_entry entry; int rv; CString path; char title[] = "Add Files"; char *filename_buffer; // Set full row selection SetFullRowSel(m_bFullRowSel); CString filter = "All files (*.*)|*.*||"; CFileDialog dlg_open(TRUE, NULL, NULL, OFN_ALLOWMULTISELECT | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST, filter.GetBuffer(0), this); filename_buffer = new char[MAX_FILENAME_BUFFER]; if (!filename_buffer) { OutputDebugString("Could not allocate filename buffer!\n"); return; } memset(filename_buffer, '\0', MAX_FILENAME_BUFFER); dlg_open.m_ofn.lpstrTitle = title; dlg_open.m_ofn.lpstrFileTitle = NULL; dlg_open.m_ofn.lpstrFile = filename_buffer; dlg_open.m_ofn.nMaxFile = MAX_FILENAME_BUFFER; rv = dlg_open.DoModal(); if (rv == IDCANCEL) { char error_type[50]; int err = CommDlgExtendedError(); sprintf(error_type, "Error: %d", err); if (err != 0) MessageBox(error_type); delete[] filename_buffer; return; } if (rv == 0) { MessageBox("Unknown error has occurred!"); delete[] filename_buffer; return; } // Display wait cursor CWaitCursor wc; ProcessMessages(); wc.Restore(); // iterate through filename list. POSITION pos; pos = dlg_open.GetStartPosition(); while (pos != NULL) { path = dlg_open.GetNextPathName(pos); rv = doc->AddFile(path, &entry); if (rv == ADDFILE_OK) { InsertItem(0, &entry); UpdateTotalFiles(list.GetItemCount()); wc.Restore(); // Get the Wait cursor back } else { char msg[1024]; switch (rv) { case ADDFILE_LONG_FNAME_ERROR: sprintf(msg, "The following filename exceeded %d characters:\n", PSFILENAME_LEN); break; case ADDFILE_DUP_FILE_ERROR: continue; // sprintf(msg,"The following filename is already in the list:\n"); // break; case ADDFILE_STAT_ERROR: sprintf(msg, "Could not get stats for following file:\n"); break; default: sprintf(msg, "An unidentified error has occurred with the following file:\n"); break; } strcat(msg, path); strcat(msg, "\n\nThis file will not be added to the file list."); MessageBox(msg, "Insert File Error!"); wc.Restore(); // Get the Wait cursor back } } delete[] filename_buffer; // Update title bar if (DocModified) UpdateTitle(doc->m_DocumentName, DocModified); UpdateTotalFiles(list.GetItemCount()); } // Inserts the given entry data into the CListCtrl bool CHogEditView::InsertItem(int index, hog_library_entry *entry) { CListCtrl &list = GetListCtrl(); int p; char str[256]; if ((p = list.InsertItem(index, entry->name)) == -1) OutputDebugString("Didn't work!"); list.SetItem(p, FILE_DIR_COLUMN, LVIF_TEXT, entry->path, 0, 0, 0, 0); sprintf(str, "%.1fk", double(entry->length / 1024.0)); list.SetItem(p, FILE_SIZE_COLUMN, LVIF_TEXT, str, 0, 0, 0, 0); struct tm *newtime; newtime = localtime(&entry->timestamp); /* Convert time to struct */ sprintf(str, "%s", asctime(newtime)); str[strlen(str) - 1] = '\0'; // Get rid of trailing newline list.SetItem(p, FILE_TIME_COLUMN, LVIF_TEXT, str, 0, 0, 0, 0); GetFileType(str, entry->name); list.SetItem(p, FILE_TYPE_COLUMN, LVIF_TEXT, str, 0, 0, 0, 0); return true; } // Inserts all items from the document Library into CListCtrl void CHogEditView::UpdateList(void) { CHogEditDoc *doc = GetDocument(); POSITION pos; hog_library_entry entry; // Insert an item into the list for every entry in the document's library pos = doc->Library.filelist.GetHeadPosition(); while (pos) { entry = doc->Library.filelist.GetNext(pos); InsertItem(0, &entry); } } // Put the title and current document on the title bar void CHogEditView::UpdateTitle(CString &path, bool mod_flag) { CFrameWnd *main_window; char filename[PSFILENAME_LEN + 1], ext[12]; char title[_MAX_PATH + 1]; _splitpath(path.GetBuffer(0), NULL, NULL, filename, ext); sprintf(title, "%s (%s%s%s)", HOG_EDIT_TITLE, filename, ext, (mod_flag) ? "*" : ""); if ((main_window = GetParentFrame()) != NULL) main_window->SetWindowText(title); else OutputDebugString("Can't get main window!\n"); } void CHogEditView::OnFileOpen() { // TODO: Add your command handler code here CHogEditDoc *doc = GetDocument(); CListCtrl &list = GetListCtrl(); CString open_filename; // Set full row selection SetFullRowSel(m_bFullRowSel); // If current file has been modified, check with user first... if (ModifiedPrompt(this) == IDNO) return; if (!DoAutoProcess) { // Create Open File Box CString filter = "Outrage hog template (*.rib)|*.rib|Outrage hogfiles (*.hog)|*.hog|All Files (*.*)|*.*||"; CFileDialog dlg_open(TRUE, NULL, NULL, OFN_FILEMUSTEXIST, (LPCTSTR)filter, this); if (dlg_open.DoModal() == IDCANCEL) { return; } open_filename = dlg_open.GetPathName(); } else { open_filename = AutoRibFilename; } // Display Wait Cursor CWaitCursor wc; // Clear out the document's information doc->OnNewDocument(); // Wipeout the CtrlList items list.DeleteAllItems(); // Load the document, and fill the control list with the new entries if (!doc->LoadDocument(open_filename)) MessageBox("The file was not opened successfully.", "File Read Error"); // Refresh the CListCtrl with the new loaded items UpdateList(); // Put new doc name on title bar doc->m_DocumentName = open_filename; doc->m_NoNameChosen = FALSE; UpdateTitle(doc->m_DocumentName, DocModified); UpdateTotalFiles(list.GetItemCount()); // If we're automatically processing the rib file, go straight to the // hog file creation process if (DoAutoProcess) OnActionCreate(); } void CHogEditView::OnFileSave() { // TODO: Add your command handler code here CHogEditDoc *doc = GetDocument(); CListCtrl &list = GetListCtrl(); // If the current document is a hog file, then call the hog // creation routine to save it if (doc->m_StaticHog) { UseCurrentHogFilename = TRUE; OnActionCreate(); UseCurrentHogFilename = FALSE; return; } // If a filename has not yet been specified by the user, // Make them do a "Save As" instead if (doc->m_NoNameChosen) { OnFileSaveAs(); return; } // Display Wait Cursor CWaitCursor wc; if (!doc->SaveDocument(doc->m_DocumentName)) { MessageBox("The file was not written successfully.", "File Write Error"); return; } DocModified = false; UpdateTitle(doc->m_DocumentName, DocModified); UpdateTotalFiles(list.GetItemCount()); } void CHogEditView::OnFileSaveAs() { // TODO: Add your command handler code here CHogEditDoc *doc = GetDocument(); CListCtrl &list = GetListCtrl(); // If the current document is a hog file, then call the hog // creation routine to save it if (doc->m_StaticHog) { OnActionCreate(); return; } CString filter = "Outrage hog template (*.rib)|*.rib||"; CFileDialog dlg_save(FALSE, ".rib", NULL, 0, (LPCTSTR)filter, this); if (dlg_save.DoModal() == IDCANCEL) { return; } // Display Wait Cursor CWaitCursor wc; // save out rib if (!doc->SaveDocument(dlg_save.GetPathName())) { MessageBox("The file was not written successfully.", "File Write Error"); return; } // name dialog doc->m_DocumentName = dlg_save.GetPathName(); // Put new doc name on title bar doc->m_NoNameChosen = FALSE; DocModified = FALSE; UpdateTitle(doc->m_DocumentName, DocModified); UpdateTotalFiles(list.GetItemCount()); } void CHogEditView::OnActionDelete() { // TODO: Add your command handler code here CHogEditDoc *doc = GetDocument(); CListCtrl &list = GetListCtrl(); int j, num_items; LV_ITEM item_info; POSITION pos, last_pos; hog_library_entry entry; char name[PSFILENAME_LEN + 1]; char path[_MAX_PATH + 1]; // Display Wait Cursor CWaitCursor wc; // How many items in the control list? num_items = list.GetItemCount(); j = 0; while (j < num_items) { // Grab the info for item #j item_info.iItem = j; item_info.iSubItem = 0; item_info.mask = LVIF_TEXT | LVIF_STATE; item_info.stateMask = LVIS_SELECTED; item_info.pszText = name; item_info.cchTextMax = PSFILENAME_LEN + 1; list.GetItem(&item_info); // Is item at index j selected? if (item_info.state & LVIS_SELECTED) { // yes, delete it // Get Directory name for item #j item_info.iSubItem = FILE_DIR_COLUMN; item_info.pszText = path; item_info.cchTextMax = _MAX_PATH; list.GetItem(&item_info); // Search for and remove corresponding entry from Document Library pos = doc->Library.filelist.GetHeadPosition(); while (pos != NULL) { last_pos = pos; entry = doc->Library.filelist.GetNext(pos); if (!stricmp(entry.name, name) && !stricmp(entry.path, path)) { doc->Library.filelist.RemoveAt(last_pos); break; } } // Delete entry/item from control list list.DeleteItem(j); num_items = list.GetItemCount(); // Document has been modified DocModified = true; } else j++; } // Update title bar if (DocModified) UpdateTitle(doc->m_DocumentName, DocModified); UpdateTotalFiles(list.GetItemCount()); } void CHogEditView::OnActionCreate() { // TODO: Add your command handler code here CListCtrl &list = GetListCtrl(); CHogEditDoc *doc = GetDocument(); char **hog_filenames; int ret, num_files; char title[] = "Save Hog File As"; CString hog_name; bool check_name; num_files = doc->Library.filelist.GetCount(); if (num_files <= 0) return; check_name = FALSE; if (!DoAutoProcess) { if (!UseCurrentHogFilename) { CString filter = "Outrage hog file (*.hog)|*.hog|All files (*.*)|*.*||"; CFileDialog dlg_save(FALSE, NULL, doc->Library.filename, 0, (LPCTSTR)filter, this); dlg_save.m_ofn.lpstrTitle = title; // Hog file name box if (dlg_save.DoModal() == IDCANCEL) { return; } hog_name = dlg_save.GetPathName(); // If no extension was specified, add ".hog" by default if (strchr(hog_name.GetBuffer(0), '.') == NULL) hog_name += ".hog"; check_name = TRUE; } else { hog_name = doc->m_DocumentName; UseCurrentHogFilename = FALSE; } // Fill and display the Hog Info dialog CHogInfo info_dlg; info_dlg.m_NumFiles.Format("%d", num_files); info_dlg.m_SizeBytes.Format("%d bytes", doc->CalcHogFileSize()); info_dlg.m_SizeMB.Format("(%.2f MB)", double(doc->CalcHogFileSize()) / double(1024 * 1024)); info_dlg.m_Location.Format("%s", hog_name); if (info_dlg.DoModal() == IDCANCEL) return; } else { hog_name = AutoHogFilename; } // Display Wait Cursor CWaitCursor wc; if (check_name) { if (stricmp(doc->Library.filename, hog_name.GetBuffer(0)) != 0) { DocModified = TRUE; UpdateTitle(doc->m_DocumentName, DocModified); } } // name dialog strcpy(doc->Library.filename, hog_name.GetBuffer(0)); // Create the list of filenames (w/full paths) to be in the hog file if (!doc->CreateFilenameList(&hog_filenames)) return; // Sort the filenames doc->SortFilenameList(hog_filenames); /* // Display the list of names (to check sorting) for(int j=0; jLibrary.num_entries; j++) { char full_name[_MAX_PATH]; sprintf(full_name,"%d <-> %s\n",j,hog_filenames[j]); OutputDebugString(full_name); } */ // Try to create the hog file and display results in message WaitCursor = &wc; ret = doc->CreateNewHogFromCurrentHog(doc->m_DocumentName.GetBuffer(0), doc->Library.filename, doc->Library.num_entries, (const char **)hog_filenames, UpdateStatusBar); /* ret=CreateNewHogFile( doc->Library.filename, doc->Library.num_entries, (const char **)hog_filenames, UpdateStatusBar); */ WaitCursor = NULL; if (ret != HOGMAKER_OK) { char msg[1024]; switch (ret) { case HOGMAKER_ERROR: sprintf(msg, "No files were chosen for the HOG file!\n"); break; case HOGMAKER_MEMORY: sprintf(msg, "Out of memory error!\n"); break; case HOGMAKER_OPENOUTFILE: sprintf(msg, "\"%s\" could not be opened!\n", hogerr_filename); break; case HOGMAKER_OUTFILE: sprintf(msg, "An error occurred writing to \"%s\"!\n", hogerr_filename); sprintf(msg, ""); break; case HOGMAKER_INFILE: sprintf(msg, "The file \"%s\" could not be opened!\n", hogerr_filename); break; case HOGMAKER_COPY: sprintf(msg, "An error occurred copying from \"%s\"!\n", hogerr_filename); break; default: sprintf(msg, "An unidentified error has occurred!\n"); break; } strcat(msg, "\nThe HOG file could not be created."); MessageBox(msg, "HOG File Error!"); } else if (!DoAutoProcess) MessageBox("The HOG file was created successfully.\n", "HOG File Created"); // Cleanup the filename list doc->DeleteFilenameList(hog_filenames); UpdateTotalFiles(list.GetItemCount()); // If a hog has been saved, reload it and update the title bar if (doc->m_StaticHog) { CString current_filename = doc->Library.filename; CWaitCursor wc; // Clear out the document's information doc->OnNewDocument(); // Wipeout the CtrlList items list.DeleteAllItems(); // Set the document's name doc->m_DocumentName = current_filename; // Load the document, and fill the control list with the new entries if (!doc->LoadDocument(doc->m_DocumentName)) MessageBox("The file was not opened successfully.", "File Read Error"); // Refresh the CListCtrl with the new loaded items UpdateList(); // Put new doc name on title bar DocModified = FALSE; UpdateTitle(doc->m_DocumentName, DocModified); UpdateTotalFiles(list.GetItemCount()); } // Close down hogedit if auto-processing if (DoAutoProcess) { CFrameWnd *main_window; if ((main_window = GetParentFrame()) != NULL) main_window->PostMessage(WM_CLOSE); } } void CHogEditView::OnViewFullRow() { // TODO: Add your command handler code here m_bFullRowSel = (m_bFullRowSel) ? false : true; SetFullRowSel(m_bFullRowSel); } void CHogEditView::OnUpdateViewFullRow(CCmdUI *pCmdUI) { // TODO: Add your command update UI handler code here pCmdUI->SetCheck(m_bFullRowSel); } // will notify user if any files in .rib have been modified (may need to rebuild .hog) void CHogEditView::OnActionUpdate() { // TODO: Add your command handler code here CHogEditDoc *doc = GetDocument(); CListCtrl &list = GetListCtrl(); POSITION pos, prev_pos; hog_library_entry temp_entry; int res; char msg[256]; char full_name[_MAX_PATH]; int missing; int modified; bool show_mod_msgs, show_gone_msgs; // Check each file in the hog entry library missing = 0; modified = 0; show_mod_msgs = true; show_gone_msgs = true; // Display wait cursor CWaitCursor wc; pos = doc->Library.filelist.GetHeadPosition(); while (pos != NULL) { prev_pos = pos; temp_entry = doc->Library.filelist.GetNext(pos); res = doc->UpdatedFileCheck(&temp_entry); sprintf(full_name, "%s%s", temp_entry.path, temp_entry.name); if (res == FILE_IS_GONE) { if (show_gone_msgs) { sprintf(msg, "The following file could not be found:\n\n%s", full_name); if (MessageBox(msg, "Warning! File Missing", MB_OKCANCEL) == IDCANCEL) show_gone_msgs = false; wc.Restore(); } missing++; } else if (res == FILE_HAS_CHANGED) { if (show_mod_msgs) { sprintf(msg, "The following file has been modified:\n\n%s", full_name); if (MessageBox(msg, "A File Has Changed", MB_OKCANCEL) == IDCANCEL) show_mod_msgs = false; wc.Restore(); } doc->Library.filelist.SetAt(prev_pos, temp_entry); modified++; } } // Refresh list display if necessary if (modified) { list.DeleteAllItems(); UpdateList(); DocModified = true; } // Display update status message char str[_MAX_PATH]; sprintf(str, "%s\n\n%s%d\n\n%s%d", "Here are the results for the update:", "Missing file(s):\t\t", missing, "Modified file(s):\t\t", modified); MessageBox(str, "Update Results"); // Update title bar if (DocModified) UpdateTitle(doc->m_DocumentName, DocModified); UpdateTotalFiles(list.GetItemCount()); } // Copies a file from the hogfile to disk void CHogEditView::OnActionExtract() { // TODO: Add your command handler code here CHogEditDoc *doc = GetDocument(); CListCtrl &list = GetListCtrl(); int j, num_items; LV_ITEM item_info; POSITION pos; hog_library_entry entry; char name[PSFILENAME_LEN + 1]; static CString default_dir_path = ""; CDirDialog dir_dialog; char current_dir[_MAX_PATH + 1]; CString output_msg, output_title; int num_errors; // Setup and display the directory selection dialog if (!default_dir_path.IsEmpty()) dir_dialog.m_strSelDir = default_dir_path; dir_dialog.m_strWindowTitle = "Destination Directory"; dir_dialog.m_strTitle = "Select the directory that you would like to extract the selected files into:"; if (dir_dialog.DoBrowse(this) == FALSE) return; // Try to change to the specified directory _getcwd(current_dir, _MAX_PATH); if (_chdir(dir_dialog.m_strPath)) { CString error_msg; error_msg.Format("Unable to find directory: %s", dir_dialog.m_strPath); MessageBox(error_msg, "Error", MB_ICONHAND); _chdir(current_dir); return; } // Display Wait Cursor CWaitCursor wc; // How many items in the control list? num_items = list.GetItemCount(); num_errors = 0; j = 0; while (j < num_items) { // Grab the info for item #j item_info.iItem = j; item_info.iSubItem = 0; item_info.mask = LVIF_TEXT | LVIF_STATE; item_info.stateMask = LVIS_SELECTED; item_info.pszText = name; item_info.cchTextMax = PSFILENAME_LEN + 1; list.GetItem(&item_info); // Is item at index j selected? if (item_info.state & LVIS_SELECTED) { // Search for corresponding entry in Document Library pos = doc->Library.filelist.GetHeadPosition(); while (pos != NULL) { entry = doc->Library.filelist.GetNext(pos); if (!stricmp(entry.name, name)) { if (!doc->ExtractFile(entry.offset, entry.length, entry.name)) { if (num_errors == 0) { output_msg.Format("The following files were not successfully extracted:\n\n%s", entry.name); } else { CString temp_str; temp_str.Format(", %s", entry.name); output_msg += temp_str; } num_errors++; } /* // Prompt user for file name char title[]="Save Extracted File As"; CString filter = "All files (*.*)|*.*||"; CFileDialog dlg_save(FALSE, NULL, name,0, (LPCTSTR)filter, this); dlg_save.m_ofn.lpstrTitle=title; if (dlg_save.DoModal() == IDCANCEL) { break; } wc.Restore(); CString out_fname = dlg_save.GetPathName(); if(doc->ExtractFile(entry.offset,entry.length,out_fname.GetBuffer(0))) MessageBox( "The file was extracted successfully.", "File Extraction Successful"); else MessageBox( "The file could not be extracted.", "File Extraction Error"); break; wc.Restore(); */ } } } j++; } // Save the selected dir for next time default_dir_path = dir_dialog.m_strPath; // Change back to the original directory _chdir(current_dir); // Display the results if (num_errors == 0) { output_msg = "The selected files were extracted successfully."; output_title = "File Extraction Successful"; } else { output_title = "File Extraction Error"; } MessageBox(output_msg, output_title); } void CHogEditView::OnUpdateActionDelete(CCmdUI *pCmdUI) { // TODO: Add your command update UI handler code here CHogEditDoc *doc = GetDocument(); CListCtrl &list = GetListCtrl(); pCmdUI->Enable(/*!doc->m_StaticHog &&*/ list.GetSelectedCount() > 0); } void CHogEditView::OnUpdateActionExtract(CCmdUI *pCmdUI) { // TODO: Add your command update UI handler code here CHogEditDoc *doc = GetDocument(); CListCtrl &list = GetListCtrl(); pCmdUI->Enable(doc->m_StaticHog && list.GetSelectedCount() > 0); } void CHogEditView::OnColumnclick(NMHDR *pNMHDR, LRESULT *pResult) { NM_LISTVIEW *pNMListView = (NM_LISTVIEW *)pNMHDR; // TODO: Add your control notification handler code here // OutputDebugString("A column was clicked\n"); *pResult = 0; } void CHogEditView::OnActionImport() { // TODO: Add your command handler code here static CString default_dir_path = ""; CDirDialog dir_dialog; // Setup and display the directory selection dialog if (!default_dir_path.IsEmpty()) dir_dialog.m_strSelDir = default_dir_path; dir_dialog.m_strWindowTitle = "Import Directory"; dir_dialog.m_strTitle = "Select the directory which contains all the files that you would like to import:"; if (dir_dialog.DoBrowse(this) == FALSE) return; OutputDebugString(dir_dialog.m_strPath); OutputDebugString("\n"); // Process the directory CListCtrl &list = GetListCtrl(); CHogEditDoc *doc = GetDocument(); hog_library_entry entry; int rv; CString path; // Set full row selection SetFullRowSel(m_bFullRowSel); // Display wait cursor CWaitCursor wc; ProcessMessages(); wc.Restore(); struct _finddata_t cfiletype; int hfile; int findnext_ret; char current_dir[_MAX_PATH + 1]; // Check and see if the directory is valid _getcwd(current_dir, _MAX_PATH); if (_chdir(dir_dialog.m_strPath)) { CString error_msg; error_msg.Format("Unable to find directory: %s", dir_dialog.m_strPath); MessageBox(error_msg, "Error", MB_ICONHAND); _chdir(current_dir); return; } // Get the first file hfile = _findfirst("*.*", &cfiletype); if (hfile == -1) return; // iterate through filename list. findnext_ret = 0; while (findnext_ret == 0) { // If it's current/previous dir, then get next file if (!strcmp(cfiletype.name, ".") || !strcmp(cfiletype.name, "..")) { findnext_ret = _findnext(hfile, &cfiletype); continue; } // If it's a sub dir, then get next file if (cfiletype.attrib & _A_SUBDIR) { findnext_ret = _findnext(hfile, &cfiletype); continue; } // Create the full file path path.Format("%s\\%s", dir_dialog.m_strPath, cfiletype.name); // Add the file to the list rv = doc->AddFile(path, &entry); if (rv == ADDFILE_OK) { InsertItem(0, &entry); UpdateTotalFiles(list.GetItemCount()); wc.Restore(); // Get the Wait cursor back } else { char msg[1024]; switch (rv) { case ADDFILE_LONG_FNAME_ERROR: sprintf(msg, "The following filename exceeded %d characters:\n", PSFILENAME_LEN); break; case ADDFILE_DUP_FILE_ERROR: findnext_ret = _findnext(hfile, &cfiletype); continue; // sprintf(msg,"The following filename is already in the list:\n"); // break; case ADDFILE_STAT_ERROR: sprintf(msg, "Could not get stats for following file:\n"); break; default: sprintf(msg, "An unidentified error has occurred with the following file:\n"); break; } strcat(msg, path); strcat(msg, "\n\nThis file will not be added to the file list."); MessageBox(msg, "Insert File Error!"); wc.Restore(); // Get the Wait cursor back } // Get the next file findnext_ret = _findnext(hfile, &cfiletype); } _findclose(hfile); _chdir(current_dir); default_dir_path = dir_dialog.m_strPath; // Update title bar if (DocModified) UpdateTitle(doc->m_DocumentName, DocModified); UpdateTotalFiles(list.GetItemCount()); } LONG CHogEditView::OnStraightToFileOpen(UINT, LONG) { OnFileOpen(); return 0; }