OnFileSaveAs/OnFileSaveFrameAs version 2
URISaveAs now called with second parameter TRUE which is bDocument flag
within URISaveAs function. This is used so that these functions can use the
save as web page complete code (bSaveAll) while OnSaveLinkAs/OnSaveImageAs
do not, these two functions may need to be called with FALSE but I think that's
the default if no parameter is specified. The code from the old OnFileSaveAs from
BOOL bSaveAll = FALSE; to the end of the if block has been incorporated into
URISaveAs and bDocument added to the if condition so that OnSaveLinkAs and
OnSaveImageAs will never have save as web page complete as an option. After
that parts of the old OnFileSaveAs were incorporated into URISaveAs which
should display the progress dialog from OnSaveLinkAs/OnSaveImageAs
(bDocument = FALSE) and not display it for OnFileSaveAs/OnFileSaveFrameAs
(bDocument = TRUE) and call SaveDocument if web page complete was selected.
I'm not sure what the difference is in the calls to SaveURI with the first parameter,
in case it has a value aURI in the other it is nsnull so I preserved the original
usage in each case.
BrowserView.cpp
---------------
BEGIN_MESSAGE_MAP(CBrowserView, CWnd)
...
ON_COMMAND(ID_FILE_SAVE_FRAME_AS, OnFileSaveFrameAs)
void CBrowserView:

nFileSaveAs()
{
// Try to get the file name part from the URL
// To do that we first construct an obj which supports
// nsIRUI interface. Makes it easy to extract portions
// of a URL like the filename, scheme etc. + We'll also
// use it while saving this link to a file
nsresult rv = NS_OK;
nsCOMPtr<nsIURI> currentURI;
rv = mWebNav->GetCurrentURI(getter_AddRefs(currentURI));
if(NS_FAILED(rv) || !currentURI)
return;
URISaveAs(currentURI, TRUE);
}
void CBrowserView:

nFileSaveFrameAs()
{
if(! mCtxMenuCurrentFrameURL.Length())
return;
// Try to get the file name part from the URL
// To do that we first construct an obj which supports
// nsIRUI interface. Makes it easy to extract portions
// of a URL like the filename, scheme etc. + We'll also
// use it while saving this link to a file
nsresult rv = NS_OK;
nsCOMPtr<nsIURI> frameURI;
rv = NS_NewURI(getter_AddRefs(linkURI), mCtxMenuCurrentFrameURL);
if(NS_FAILED(rv))
return;
URISaveAs(frameURI, TRUE);
}
BrowserViewUtils.cpp
--------------------
NS_IMETHODIMP CBrowserView::URISaveAs(nsIURI* aURI, bool bDocument)
{
NS_ENSURE_ARG_POINTER(aURI);
// Get the "path" portion (see nsIURI.h for more info
// on various parts of a URI)
nsCAutoString path;
aURI->GetPath(path);
char sDefault[] = "default.htm";
char *pFileName = sDefault;
char *pBuf = NULL;
if (strlen(path.get()) > 1) {
// The path may have the "/" char in it - strip those
pBuf = new char[strlen(path.get()) + 5]; // +5 for ".htm" to be safely appended, if necessary
strcpy(pBuf, path.get());
char* slash = strrchr(pBuf, '/');
if (slash) {
if (strlen(slash) > 1)
pFileName = slash+1; // filename = file.ext
else {
while ((slash > pBuf) && (strlen(slash) <= 1)) { // strip off extra /es
*slash = 0;
slash--;
slash = strrchr(pBuf, '/');
}
if (slash && (strlen(slash) > 0)) {
pFileName=slash+1; // filename = directory.htm
strcat(pFileName, ".htm");
}
}
}
else {
// if there is no slash, then it's probably an invalid url (javascript: link, etc)
MessageBox((CString)("Cannot Save URL ") + path.get());
return NS_ERROR_FAILURE;
}
}
else {
aURI->GetHost(path);
if (strlen(path.get()) >= 1) {
pBuf = new char[strlen(path.get()) + 5]; // +5 for ".htm" to be safely appended, if necessary
strcpy(pBuf, path.get());
pFileName = pBuf;
for (int x=strlen(pBuf)-1; x>=0; x--)
if (pBuf[x] == '.') pBuf[x] = '_';
strcat(pBuf, ".htm"); // filename = www_host_com.htm
}
}
// This is so saving cgi-scripts doesn't produce invalid filenames
char *questionMark = strchr(pFileName, '?');
if (questionMark)
*questionMark = 0;
char *extension = strrchr(pFileName, '.');
if (!extension) {
extension = strrchr(sDefault, '.');
strcat(pFileName, extension);
}
extension++;
char lpszFilter[256];
strcpy(lpszFilter, extension);
strcat(lpszFilter, " Files (*.");
strcat(lpszFilter, extension);
strcat(lpszFilter, ")|*.");
strcat(lpszFilter, extension);
strcat(lpszFilter, "|");
strcat(lpszFilter, "Web Page, HTML Only (*.htm;*.html)|*.htm;*.html|");
if (bDocument)
strcat(lpszFilter, "Web Page, Complete (*.htm;*.html)|*.htm;*.html|");
strcat(lpszFilter,"Text File (*.txt)|*.txt|"
"All Files (*.*)|*.*||");
CFileDialog cf(FALSE, extension, pFileName, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
lpszFilter, this);
cf.m_ofn.lpstrInitialDir = theApp.preferences.saveDir;
if(cf.DoModal() == IDOK) {
CString strFullPath = cf.GetPathName(); // Will be like: c:\tmp\junk.htm
theApp.preferences.saveDir = cf.GetPathName();
int idxSlash;
idxSlash = theApp.preferences.saveDir.ReverseFind('\\');
theApp.preferences.saveDir = theApp.preferences.saveDir.Mid(0, idxSlash+1);
BOOL bSaveAll = FALSE;
CString strDataPath;
char *pStrDataPath = NULL;
if(bDocument && cf.m_ofn.nFilterIndex == 2)
{
// cf.m_ofn.nFilterIndex == 2 indicates
// user want to save the complete document including
// all frames, images, scripts, stylesheets etc.
bSaveAll = TRUE;
int idxPeriod = strFullPath.ReverseFind('.');
strDataPath = strFullPath.Mid(0, idxPeriod);
strDataPath += "_files";
// At this stage strDataPath will be of the form
// c:\tmp\junk_files - assuming we're saving to a file
// named junk.htm
// Any images etc in the doc will be saved to a dir
// with the name c:\tmp\junk_files
pStrDataPath = strDataPath.GetBuffer(0); // Get char * for later use
}
// Get the persist interface that we'll use for saving the file(s)
nsCOMPtr<nsIWebBrowserPersist> persist(do_QueryInterface(mWebBrowser));
if(!persist)
return NS_ERROR_FAILURE;
nsString filename;
filename.AssignWithConversion(strFullPath.GetBuffer(0));
nsCOMPtr<nsILocalFile> file;
NS_NewNativeLocalFile(nsDependentCString(T2A(strFullPath.GetBuffer(0))), TRUE, getter_AddRefs(file));
nsCOMPtr<nsILocalFile> dataPath;
if (pStrDataPath)
{
NS_NewNativeLocalFile(nsDependentCString(pStrDataPath), TRUE, getter_AddRefs(dataPath));
}
if(!bDocument) {
CProgressDialog *progress = new CProgressDialog(FALSE);
progress->InitPersist(aURI, file, persist, TRUE);
persist->SaveURI(aURI, nsnull, file);
}
else
if(bSaveAll)
persist->SaveDocument(nsnull, file, dataPath, nsnull, 0, 0);
else
persist->SaveURI(nsnull, nsnull, file);
}
if (pBuf)
delete pBuf;
return NS_OK;
}