Descent3/legacy/hogedit/HogEditView.cpp
2024-06-15 20:13:59 +02:00

1151 lines
32 KiB
C++

/*
* 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 <http://www.gnu.org/licenses/>.
--- 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 <afxtempl.h>
#include <io.h>
#include <direct.h>
#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; j<doc->Library.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;
}