зеркало из https://github.com/mozilla/pjs.git
325 строки
7.9 KiB
C++
325 строки
7.9 KiB
C++
/* $Id: saving.cpp,v 1.1 1998-09-25 18:01:41 ramiro%netscape.com Exp $
|
|
*
|
|
* The contents of this file are subject to the Netscape Public License
|
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
|
* http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
|
* for the specific language governing rights and limitations under the
|
|
* NPL.
|
|
*
|
|
* The Initial Developer of this code under the NPL is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. Portions
|
|
* created by Warwick Allison, Kalle Dalheimer, Eirik Eng, Matthias
|
|
* Ettrich, Arnt Gulbrandsen, Haavard Nord and Paul Olav Tvete are
|
|
* Copyright (C) 1998 Warwick Allison, Kalle Dalheimer, Eirik Eng,
|
|
* Matthias Ettrich, Arnt Gulbrandsen, Haavard Nord and Paul Olav
|
|
* Tvete. All Rights Reserved.
|
|
*/
|
|
|
|
#include "QtBrowserContext.h"
|
|
#include "DialogPool.h"
|
|
#include "SaveAsDialog.h"
|
|
#include "streaming.h"
|
|
|
|
#include <fe_proto.h>
|
|
#include <xlate.h>
|
|
#include <xpgetstr.h>
|
|
#include <xp_str.h>
|
|
|
|
#include <qdialog.h>
|
|
#include <qmainwindow.h>
|
|
|
|
extern void fe_RaiseSynchronousURLDialog (MWContext *context, QWidget* parent,
|
|
const char *title);
|
|
extern int fe_AwaitSynchronousURL( MWContext* context );
|
|
void fe_LowerSynchronousURLDialog (MWContext *context);
|
|
bool QTFE_StatReadWrite( const char *file_name, bool isFileP, bool existsP );
|
|
void fe_save_as_complete( PrintSetup* ps );
|
|
|
|
extern int QTFE_ERROR_READ_ONLY;
|
|
extern int QTFE_ERROR_OPENING_FILE;
|
|
|
|
#if defined(_CC_MSVC_)
|
|
#define stat _stat
|
|
#endif
|
|
|
|
|
|
static char* get_URLBasename(const char* url);
|
|
|
|
|
|
void QtBrowserContext::cmdSaveAs()
|
|
{
|
|
int res;
|
|
char* basename = 0;
|
|
URL_Struct* url = SHIST_CreateWysiwygURLStruct(mwContext(),
|
|
SHIST_GetCurrent (&mwContext()->hist));
|
|
if( !dialogpool->saveasdialog )
|
|
dialogpool->saveasdialog = new SaveAsDialog( this, browserWidget );
|
|
if (url)
|
|
basename = get_URLBasename(url->address);
|
|
#ifdef DEBUG
|
|
fprintf( stderr, "Setting as suggested name: %s\n", basename );
|
|
#endif
|
|
dialogpool->saveasdialog->setSelection(basename);
|
|
res = dialogpool->saveasdialog->exec();
|
|
free(basename);
|
|
if(res == QDialog::Accepted)
|
|
{
|
|
save_as_data* sad = make_save_as_data(mwContext(), false,
|
|
dialogpool->saveasdialog->type(),
|
|
url,
|
|
dialogpool->saveasdialog->selectedFile() );
|
|
if (sad)
|
|
fe_save_as_nastiness (this, url, sad, TRUE);
|
|
else
|
|
goto error_exit;
|
|
}
|
|
else
|
|
goto error_exit;
|
|
return;
|
|
error_exit:
|
|
NET_FreeURLStruct (url);
|
|
}
|
|
|
|
|
|
void fe_save_as_complete( PrintSetup* ps )
|
|
{
|
|
MWContext* context = (MWContext*) ps->carg;
|
|
|
|
fclose( ps->out );
|
|
|
|
fe_LowerSynchronousURLDialog( context );
|
|
|
|
free( ps->filename );
|
|
NET_FreeURLStruct( ps->url );
|
|
}
|
|
|
|
|
|
// Note: isFileP - if true and the file_name is a directory,
|
|
// we return False...
|
|
//
|
|
// existsP - if true, the file_name must exist or we return False,
|
|
// otherwise we just make sure we can read/write into the
|
|
// directory specified in file_name...
|
|
//
|
|
bool
|
|
QTFE_StatReadWrite( const char *file_name, bool isFileP, bool existsP )
|
|
{
|
|
// NOTE: let's get the directory that this file resides in...
|
|
//
|
|
XP_StatStruct dir_info;
|
|
XP_StatStruct file_info;
|
|
bool isDir = false;
|
|
char* p;
|
|
char* base_name = (char *) XP_ALLOC(XP_STRLEN(file_name) + 1);
|
|
|
|
p = XP_STRRCHR(file_name, '/');
|
|
|
|
if (p) {
|
|
if (p == file_name) {
|
|
XP_STRCPY(base_name, "/");
|
|
}
|
|
else {
|
|
uint32 len = p - file_name;
|
|
|
|
if (len == XP_STRLEN(file_name)) {
|
|
isDir = true;
|
|
XP_STRCPY(base_name, file_name);
|
|
}
|
|
else {
|
|
XP_MEMCPY(base_name, file_name, len);
|
|
base_name[len] = '\0';
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
// WARNING... [ we may get into some trouble with this one ]
|
|
//
|
|
XP_STRCPY(base_name, ".");
|
|
}
|
|
|
|
// NOTE: we need to verify that we can read/write the directory
|
|
// before we check the file...
|
|
//
|
|
// - need to check all three mode groups... [ owner, group, other ]
|
|
//
|
|
if ( stat(base_name, &dir_info) >= 0 ) {
|
|
bool gotcha = false;
|
|
|
|
if ( isFileP &&
|
|
isDir
|
|
) {
|
|
// NOTE: the specifed file_name is a directory... [ fail ]
|
|
//
|
|
XP_FREE(base_name);
|
|
|
|
return false;
|
|
}
|
|
|
|
#if defined(XP_UNIX)
|
|
if (dir_info.st_uid == getuid()) {
|
|
if ((dir_info.st_mode & S_IRUSR) &&
|
|
(dir_info.st_mode & S_IWUSR)) {
|
|
gotcha = true;
|
|
}
|
|
}
|
|
|
|
if (!gotcha) {
|
|
if (dir_info.st_gid == getgid()) {
|
|
if ((dir_info.st_mode & S_IRGRP) &&
|
|
(dir_info.st_mode & S_IWGRP)) {
|
|
gotcha = true;
|
|
}
|
|
}
|
|
|
|
if (!gotcha) {
|
|
if ((dir_info.st_mode & S_IROTH) &&
|
|
(dir_info.st_mode & S_IWOTH)) {
|
|
gotcha = true;
|
|
}
|
|
}
|
|
}
|
|
#elif defined(XP_WIN)
|
|
gotcha = TRUE;
|
|
#endif
|
|
if (gotcha) {
|
|
if (isDir) {
|
|
// NOTE: we're done... [ we can read/write this directory ]
|
|
//
|
|
XP_FREE(base_name);
|
|
|
|
return true;
|
|
}
|
|
else {
|
|
// NOTE: let's do the same thing for the file...
|
|
//
|
|
if ( stat(file_name, &file_info) >= 0 ) {
|
|
gotcha = false;
|
|
|
|
if (isFileP &&
|
|
(file_info.st_mode & S_IFDIR)) {
|
|
// NOTE: the specifed file_name is a directory...
|
|
//
|
|
XP_FREE(base_name);
|
|
|
|
return false;
|
|
}
|
|
|
|
#if defined(XP_UNIX)
|
|
if (file_info.st_uid == getuid()) {
|
|
if ((file_info.st_mode & S_IRUSR) &&
|
|
(file_info.st_mode & S_IWUSR)) {
|
|
gotcha = true;
|
|
}
|
|
}
|
|
|
|
if (!gotcha) {
|
|
if (file_info.st_gid == getgid()) {
|
|
if ((file_info.st_mode & S_IRGRP) &&
|
|
(file_info.st_mode & S_IWGRP)) {
|
|
gotcha = true;
|
|
}
|
|
}
|
|
|
|
if (!gotcha) {
|
|
if ((file_info.st_mode & S_IROTH) &&
|
|
(file_info.st_mode & S_IWOTH)) {
|
|
gotcha = true;
|
|
}
|
|
}
|
|
}
|
|
#elif defined(XP_WIN)
|
|
gotcha = TRUE;
|
|
#endif
|
|
if (gotcha) {
|
|
// NOTE: we can read/write this directory/file...
|
|
//
|
|
XP_FREE(base_name);
|
|
|
|
return true;
|
|
}
|
|
else {
|
|
// NOTE: we failed the file check...
|
|
//
|
|
XP_FREE(base_name);
|
|
|
|
return false;
|
|
}
|
|
}
|
|
else {
|
|
if (existsP) {
|
|
// NOTE: failed to stat the file...
|
|
//
|
|
XP_FREE(base_name);
|
|
|
|
return false;
|
|
}
|
|
else {
|
|
// NOTE: we can read/write this directory...
|
|
//
|
|
XP_FREE(base_name);
|
|
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
// NOTE: we failed the directory check...
|
|
//
|
|
XP_FREE(base_name);
|
|
|
|
return false;
|
|
}
|
|
}
|
|
else {
|
|
// NOTE: failed to stat the directory...
|
|
//
|
|
XP_FREE(base_name);
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Strips URL address from path and returns the basename
|
|
// Warning, allocates string that must be deallocated.
|
|
static char* get_URLBasename(const char* url)
|
|
{
|
|
const char* def;
|
|
char* basename;
|
|
char* tail;
|
|
|
|
if (url==0)
|
|
return 0; // No address given, return immediately.
|
|
|
|
if ((def = strrchr (url, '/')))
|
|
def++;
|
|
else
|
|
def = url;
|
|
basename = strdup(def);
|
|
|
|
// Grab the file name part and map out the characters which ought not go into file names.
|
|
// Also, terminate the file name at ? or #, since those aren't
|
|
// really a part of the URL's file, but are modifiers to it.
|
|
for (tail = basename; *tail; tail++)
|
|
{
|
|
if (*tail == '?' || *tail == '#')
|
|
{
|
|
*tail = 0;
|
|
break;
|
|
}
|
|
else if (*tail < '+' || *tail > 'z' ||
|
|
*tail == ':' || *tail == ';' ||
|
|
*tail == '<' || *tail == '>' ||
|
|
*tail == '\\' || *tail == '^' ||
|
|
*tail == '\'' || *tail == '`' ||
|
|
*tail == ',')
|
|
*tail = '_';
|
|
}
|
|
return basename;
|
|
}
|