|
|
/***************************************************************************
|
|
|
img_saver.cpp - description
|
|
|
-------------------
|
|
|
begin : Mon Dec 27 1999
|
|
|
copyright : (C) 1999 by Klaas Freitag
|
|
|
email : freitag@suse.de
|
|
|
***************************************************************************/
|
|
|
|
|
|
/***************************************************************************
|
|
|
* *
|
|
|
* This file may be distributed and/or modified under the terms of the *
|
|
|
* GNU General Public License version 2 as published by the Free Software *
|
|
|
* Foundation and appearing in the file COPYING included in the *
|
|
|
* packaging of this file. *
|
|
|
*
|
|
|
* As a special exception, permission is given to link this program *
|
|
|
* with any version of the KADMOS ocr/icr engine of reRecognition GmbH, *
|
|
|
* Kreuzlingen and distribute the resulting executable without *
|
|
|
* including the source code for KADMOS in the source distribution. *
|
|
|
*
|
|
|
* As a special exception, permission is given to link this program *
|
|
|
* with any edition of TQt, and distribute the resulting executable, *
|
|
|
* without including the source code for TQt in the source distribution. *
|
|
|
* *
|
|
|
***************************************************************************/
|
|
|
|
|
|
#include <sys/stat.h>
|
|
|
#include <sys/types.h>
|
|
|
#include <fcntl.h>
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
|
#include <kglobal.h>
|
|
|
#include <kconfig.h>
|
|
|
#include <kdialog.h>
|
|
|
#include <kimageio.h>
|
|
|
#include <kseparator.h>
|
|
|
#include <klocale.h>
|
|
|
#include <kmessagebox.h>
|
|
|
#include <kdebug.h>
|
|
|
#include <kio/jobclasses.h>
|
|
|
#include <kio/file.h>
|
|
|
#include <kio/job.h>
|
|
|
#include <kio/netaccess.h>
|
|
|
#include <ktempfile.h>
|
|
|
#include <kinputdialog.h>
|
|
|
|
|
|
#include <tqdir.h>
|
|
|
#include <layout.h>
|
|
|
#include <tqfileinfo.h>
|
|
|
#include <tqimage.h>
|
|
|
#include <tqmessagebox.h>
|
|
|
#include <tqvbox.h>
|
|
|
#include <tqbuttongroup.h>
|
|
|
|
|
|
#include "resource.h"
|
|
|
#include "img_saver.h"
|
|
|
#include "previewer.h"
|
|
|
#include "kookaimage.h"
|
|
|
|
|
|
FormatDialog::FormatDialog( TQWidget *parent, const TQString&, const char *name )
|
|
|
:KDialogBase( parent, name, true,
|
|
|
/* Tabbed,*/ i18n( "Kooka Save Assistant" ),
|
|
|
Ok|Cancel, Ok )
|
|
|
|
|
|
{
|
|
|
buildHelp();
|
|
|
// readConfig();
|
|
|
// TQFrame *page = addPage( TQString( "Save the image") );
|
|
|
TQFrame *page = new TQFrame( this );
|
|
|
page->setFrameStyle( TQFrame::Box | TQFrame::Sunken );
|
|
|
Q_CHECK_PTR( page );
|
|
|
setMainWidget( page );
|
|
|
|
|
|
TQVBoxLayout *bigdad = new TQVBoxLayout( page, marginHint(), spacingHint());
|
|
|
Q_CHECK_PTR(bigdad);
|
|
|
|
|
|
// some nice words
|
|
|
TQLabel *l0 = new TQLabel( page );
|
|
|
Q_CHECK_PTR(l0);
|
|
|
l0->setText( i18n( "<B>Save Assistant</B><P>Select an image format to save the scanned image." ));
|
|
|
bigdad->addWidget( l0 );
|
|
|
|
|
|
KSeparator* sep = new KSeparator( KSeparator::HLine, page);
|
|
|
bigdad->addWidget( sep );
|
|
|
|
|
|
// Layout-Boxes
|
|
|
// TQHBoxLayout *hl1= new TQHBoxLayout( ); // Caption
|
|
|
TQHBoxLayout *lhBigMiddle = new TQHBoxLayout( spacingHint() ); // Big middle
|
|
|
Q_CHECK_PTR(lhBigMiddle);
|
|
|
bigdad->addLayout( lhBigMiddle );
|
|
|
TQVBoxLayout *lvFormatSel = new TQVBoxLayout( spacingHint() ); // Selection List
|
|
|
Q_CHECK_PTR(lvFormatSel);
|
|
|
lhBigMiddle->addLayout( lvFormatSel );
|
|
|
|
|
|
// Insert Scrolled List for formats
|
|
|
TQLabel *l1 = new TQLabel( page );
|
|
|
Q_CHECK_PTR(l1);
|
|
|
l1->setText( i18n( "Available image formats:" ));
|
|
|
|
|
|
lb_format = new TQListBox( page, "ListBoxFormats" );
|
|
|
Q_CHECK_PTR(lb_format);
|
|
|
|
|
|
#ifdef USE_KIMAGEIO
|
|
|
TQStringList fo = KImageIO::types();
|
|
|
#else
|
|
|
TQStringList fo = TQImage::outputFormatList();
|
|
|
#endif
|
|
|
kdDebug(28000) << "#### have " << fo.count() << " image types" << endl;
|
|
|
lb_format->insertStringList( fo );
|
|
|
connect( lb_format, TQT_SIGNAL( highlighted(const TQString&)),
|
|
|
TQT_SLOT( showHelp(const TQString&)));
|
|
|
|
|
|
// Insert label for helptext
|
|
|
l_help = new TQLabel( page );
|
|
|
Q_CHECK_PTR(l_help);
|
|
|
l_help->setFrameStyle( TQFrame::Panel|TQFrame::Sunken );
|
|
|
l_help->setText( i18n("-No format selected-" ));
|
|
|
l_help->setAlignment( AlignVCenter | AlignHCenter );
|
|
|
l_help->setMinimumWidth(230);
|
|
|
|
|
|
// Insert Selbox for subformat
|
|
|
l2 = new TQLabel( page );
|
|
|
Q_CHECK_PTR(l2);
|
|
|
l2->setText( i18n( "Select the image sub-format" ));
|
|
|
cb_subf = new TQComboBox( page, "ComboSubFormat" );
|
|
|
Q_CHECK_PTR( cb_subf );
|
|
|
|
|
|
// Checkbox to store setting
|
|
|
cbDontAsk = new TQCheckBox(i18n("Don't ask again for the save format if it is defined."),
|
|
|
page );
|
|
|
Q_CHECK_PTR( cbDontAsk );
|
|
|
|
|
|
TQFrame *hl = new TQFrame(page);
|
|
|
Q_CHECK_PTR( hl );
|
|
|
hl->setFrameStyle( TQFrame::HLine|TQFrame::Sunken );
|
|
|
|
|
|
// bigdad->addWidget( l_caption, 1 );
|
|
|
lvFormatSel->addWidget( l1, 1 );
|
|
|
lvFormatSel->addWidget( lb_format, 6 );
|
|
|
lvFormatSel->addWidget( l2, 1 );
|
|
|
lvFormatSel->addWidget( cb_subf, 1 );
|
|
|
|
|
|
lhBigMiddle->addWidget( l_help, 2 );
|
|
|
//bigdad->addStretch(1);
|
|
|
bigdad->addWidget( hl, 1 );
|
|
|
bigdad->addWidget( cbDontAsk , 2 );
|
|
|
|
|
|
bigdad->activate();
|
|
|
|
|
|
}
|
|
|
|
|
|
void FormatDialog::showHelp( const TQString& item )
|
|
|
{
|
|
|
TQString helptxt = format_help[ item ];
|
|
|
|
|
|
if( !helptxt.isEmpty() ) {
|
|
|
// Set the hint
|
|
|
l_help->setText( helptxt );
|
|
|
|
|
|
// and check subformats
|
|
|
check_subformat( helptxt );
|
|
|
} else {
|
|
|
l_help->setText( i18n("-no hint available-" ));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void FormatDialog::check_subformat( const TQString & format )
|
|
|
{
|
|
|
// not yet implemented
|
|
|
kdDebug(28000) << "This is format in check_subformat: " << format << endl;
|
|
|
cb_subf->setEnabled( false );
|
|
|
// l2 = Label "select subformat" ->bad name :-|
|
|
|
l2->setEnabled( false );
|
|
|
}
|
|
|
|
|
|
void FormatDialog::setSelectedFormat( TQString fo )
|
|
|
{
|
|
|
TQListBoxItem *item = lb_format->findItem( fo );
|
|
|
|
|
|
if( item )
|
|
|
{
|
|
|
// Select it.
|
|
|
lb_format->setSelected( lb_format->index(item), true );
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
TQString FormatDialog::getFormat( ) const
|
|
|
{
|
|
|
int item = lb_format->currentItem();
|
|
|
|
|
|
if( item > -1 )
|
|
|
{
|
|
|
const TQString f = lb_format->text( item );
|
|
|
return( f );
|
|
|
}
|
|
|
return( "BMP" );
|
|
|
}
|
|
|
|
|
|
|
|
|
TQCString FormatDialog::getSubFormat( ) const
|
|
|
{
|
|
|
// Not yet...
|
|
|
return( "" );
|
|
|
}
|
|
|
|
|
|
#include "formathelp.h"
|
|
|
void FormatDialog::buildHelp( void )
|
|
|
{
|
|
|
format_help.insert( TQString::fromLatin1("BMP"), HELP_BMP );
|
|
|
format_help.insert( TQString::fromLatin1("PNM"), HELP_PNM );
|
|
|
format_help.insert( TQString::fromLatin1("JPEG"), HELP_JPG );
|
|
|
format_help.insert( TQString::fromLatin1("JPG"), HELP_JPG );
|
|
|
format_help.insert( TQString::fromLatin1("EPS"), HELP_EPS );
|
|
|
}
|
|
|
|
|
|
|
|
|
/* ********************************************************************** */
|
|
|
|
|
|
ImgSaver::ImgSaver( TQWidget *parent, const KURL dir_name )
|
|
|
: TQObject( parent )
|
|
|
{
|
|
|
|
|
|
if( dir_name.isEmpty() || dir_name.protocol() != "file" )
|
|
|
{
|
|
|
kdDebug(28000) << "ImageServer initialised with wrong dir " << dir_name.url() << endl;
|
|
|
directory = Previewer::galleryRoot();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
/* A path was given */
|
|
|
if( dir_name.protocol() != "file" )
|
|
|
{
|
|
|
kdDebug(28000) << "ImgSaver: Can only save local image, sorry !" << endl;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
directory = dir_name.directory(true, false);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
kdDebug(28000) << "ImageSaver uses dir <" << directory << endl;
|
|
|
createDir( directory );
|
|
|
readConfig();
|
|
|
|
|
|
last_file = "";
|
|
|
last_format ="";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
ImgSaver::ImgSaver( TQWidget *parent )
|
|
|
:TQObject( parent )
|
|
|
{
|
|
|
directory = Previewer::galleryRoot();
|
|
|
createDir( directory );
|
|
|
|
|
|
readConfig();
|
|
|
|
|
|
last_file = "";
|
|
|
last_format ="";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
/* Needs a full qualified directory name */
|
|
|
void ImgSaver::createDir( const TQString& dir )
|
|
|
{
|
|
|
KURL url( dir );
|
|
|
|
|
|
if( ! KIO::NetAccess::exists(url, false, 0) )
|
|
|
{
|
|
|
kdDebug(28000) << "Wrn: Directory <" << dir << "> does not exist -> try to create !" << endl;
|
|
|
// if( mkdir( TQFile::encodeName( dir ), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH ) != 0 )
|
|
|
if( KIO::mkdir( KURL(dir)))
|
|
|
{
|
|
|
KMessageBox::sorry(0, i18n("The folder\n%1\n does not exist and could not be created;\n"
|
|
|
"please check the permissions.").arg(dir));
|
|
|
}
|
|
|
}
|
|
|
#if 0
|
|
|
if( ! fi.isWritable() )
|
|
|
{
|
|
|
KMessageBox::sorry(0, i18n("The directory\n%1\n is not writeable;\nplease check the permissions.")
|
|
|
.arg(dir));
|
|
|
}
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* This function asks the user for a filename or creates
|
|
|
* one by itself, depending on the settings
|
|
|
**/
|
|
|
ImgSaveStat ImgSaver::saveImage( TQImage *image )
|
|
|
{
|
|
|
ImgSaveStat stat;
|
|
|
picType imgType;
|
|
|
|
|
|
if( !image ) return( ISS_ERR_PARAM );
|
|
|
|
|
|
/* Find out what kind of image it is */
|
|
|
if( image->depth() > 8 )
|
|
|
{
|
|
|
imgType = PT_HICOLOR_IMAGE;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if( image->depth() == 1 || image->numColors() == 2 )
|
|
|
{
|
|
|
kdDebug(28000) << "This is black And White!" << endl;
|
|
|
imgType = PT_BW_IMAGE;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
imgType = PT_COLOR_IMAGE;
|
|
|
if( image->allGray() )
|
|
|
{
|
|
|
imgType = PT_GRAY_IMAGE;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
TQString format = findFormat( imgType );
|
|
|
TQString subformat = findSubFormat( format );
|
|
|
// Call save-Function with this params
|
|
|
|
|
|
if( format.isEmpty() )
|
|
|
{
|
|
|
kdDebug(28000) << "Save canceled by user -> no save !" << endl;
|
|
|
return( ISS_SAVE_CANCELED );
|
|
|
}
|
|
|
|
|
|
kdDebug(28000) << "saveImage: Directory is " << directory << endl;
|
|
|
TQString filename = createFilename( format );
|
|
|
|
|
|
KConfig *konf = KGlobal::config ();
|
|
|
konf->setGroup( OP_FILE_GROUP );
|
|
|
|
|
|
if( konf->readBoolEntry( OP_ASK_FILENAME, false ) )
|
|
|
{
|
|
|
bool ok;
|
|
|
TQString text = KInputDialog::getText( i18n( "Filename" ), i18n("Enter filename:"),
|
|
|
filename, &ok );
|
|
|
|
|
|
if(ok)
|
|
|
{
|
|
|
filename = text;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
TQString fi = directory + "/" + filename;
|
|
|
|
|
|
if( extension(fi).isEmpty() )
|
|
|
{
|
|
|
if( ! fi.endsWith( "." ) )
|
|
|
{
|
|
|
fi+= ".";
|
|
|
}
|
|
|
fi+=format.lower();
|
|
|
}
|
|
|
|
|
|
|
|
|
kdDebug(28000) << "saveImage: saving file <" << fi << ">" << endl;
|
|
|
stat = save( image, fi, format, subformat );
|
|
|
|
|
|
return( stat );
|
|
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* This member creates a filename for the image to save.
|
|
|
* This is done by numbering all existing files and adding
|
|
|
* one
|
|
|
**/
|
|
|
TQString ImgSaver::createFilename( TQString format )
|
|
|
{
|
|
|
if( format.isNull() || format.isEmpty() ) return( 0 );
|
|
|
|
|
|
TQString s = "kscan_*." + format.lower();
|
|
|
TQDir files( directory, s );
|
|
|
long c = 1;
|
|
|
|
|
|
TQString num;
|
|
|
num.setNum(c);
|
|
|
TQString fname = "kscan_" + num.rightJustify(4, '0') + "." + format.lower();
|
|
|
|
|
|
while( files.exists( fname ) ) {
|
|
|
num.setNum(++c);
|
|
|
fname = "kscan_" + num.rightJustify(4, '0') + "." + format.lower();
|
|
|
}
|
|
|
|
|
|
return( fname );
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* This function gets a filename from the parent. The filename must not be relative.
|
|
|
**/
|
|
|
ImgSaveStat ImgSaver::saveImage( TQImage *image, const KURL& filename, const TQString& imgFormat )
|
|
|
{
|
|
|
TQString format = imgFormat;
|
|
|
|
|
|
/* Check if the filename is local */
|
|
|
if( !filename.isLocalFile())
|
|
|
{
|
|
|
kdDebug(29000) << "ImgSaver: Can only save local image, sorry !" << endl;
|
|
|
return( ISS_ERR_PROTOCOL );
|
|
|
}
|
|
|
|
|
|
TQString localFilename;
|
|
|
localFilename = filename.directory( false, true) + filename.fileName();
|
|
|
|
|
|
kdDebug(28000) << "saveImage: Saving "<< localFilename << " in format " << format << endl;
|
|
|
if( format.isEmpty() )
|
|
|
format = "BMP";
|
|
|
|
|
|
return( save( image, localFilename, format, "" ) );
|
|
|
}
|
|
|
|
|
|
|
|
|
/*
|
|
|
* findFormat does all the stuff with the dialog.
|
|
|
*/
|
|
|
TQString ImgSaver::findFormat( picType type )
|
|
|
{
|
|
|
TQString format;
|
|
|
KConfig *konf = KGlobal::config ();
|
|
|
konf->setGroup( OP_FILE_GROUP );
|
|
|
|
|
|
if( type == PT_THUMBNAIL )
|
|
|
{
|
|
|
return( "BMP" );
|
|
|
}
|
|
|
|
|
|
// real images
|
|
|
switch( type )
|
|
|
{
|
|
|
case PT_THUMBNAIL:
|
|
|
format = konf->readEntry( OP_FORMAT_THUMBNAIL, "BMP" );
|
|
|
kdDebug( 28000) << "Format for Thumbnails: " << format << endl;
|
|
|
break;
|
|
|
case PT_PREVIEW:
|
|
|
format = konf->readEntry( OP_PREVIEW_FORMAT, "BMP" );
|
|
|
kdDebug( 28000) << "Format for Preview: " << format << endl;
|
|
|
break;
|
|
|
case PT_COLOR_IMAGE:
|
|
|
format = konf->readEntry( OP_FORMAT_COLOR, "nothing" );
|
|
|
kdDebug( 28000 ) << "Format for Color: " << format << endl;
|
|
|
break;
|
|
|
case PT_GRAY_IMAGE:
|
|
|
format = konf->readEntry( OP_FORMAT_GRAY, "nothing" );
|
|
|
kdDebug( 28000 ) << "Format for Gray: " << format << endl;
|
|
|
break;
|
|
|
case PT_BW_IMAGE:
|
|
|
format = konf->readEntry( OP_FORMAT_BW, "nothing" );
|
|
|
kdDebug( 28000 ) << "Format for BlackAndWhite: " << format << endl;
|
|
|
break;
|
|
|
case PT_HICOLOR_IMAGE:
|
|
|
format = konf->readEntry( OP_FORMAT_HICOLOR, "nothing" );
|
|
|
kdDebug( 28000 ) << "Format for HiColorImage: " << format << endl;
|
|
|
break;
|
|
|
default:
|
|
|
format = "nothing";
|
|
|
kdDebug( 28000 ) << "ERR: Could not find image type !" << endl;
|
|
|
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
if( type != PT_PREVIEW ) /* Use always bmp-Default for preview scans */
|
|
|
{
|
|
|
if( format == "nothing" || ask_for_format )
|
|
|
{
|
|
|
format = startFormatDialog( type );
|
|
|
}
|
|
|
}
|
|
|
return( format );
|
|
|
|
|
|
}
|
|
|
|
|
|
TQString ImgSaver::picTypeAsString( picType type ) const
|
|
|
{
|
|
|
TQString res;
|
|
|
|
|
|
switch( type )
|
|
|
{
|
|
|
case PT_COLOR_IMAGE:
|
|
|
res = i18n( "palleted color image (16 or 24 bit depth)" );
|
|
|
break;
|
|
|
case PT_GRAY_IMAGE:
|
|
|
res = i18n( "palleted gray scale image (16 bit depth)" );
|
|
|
break;
|
|
|
case PT_BW_IMAGE:
|
|
|
res = i18n( "lineart image (black and white, 1 bit depth)" );
|
|
|
break;
|
|
|
case PT_HICOLOR_IMAGE:
|
|
|
res = i18n( "high (or true-) color image, not palleted" );
|
|
|
break;
|
|
|
default:
|
|
|
res = i18n( "Unknown image type" );
|
|
|
break;
|
|
|
}
|
|
|
return( res );
|
|
|
}
|
|
|
|
|
|
|
|
|
TQString ImgSaver::startFormatDialog( picType type)
|
|
|
{
|
|
|
|
|
|
FormatDialog fd( 0, picTypeAsString( type ), "FormatDialog" );
|
|
|
|
|
|
// set default values
|
|
|
if( type != PT_PREVIEW )
|
|
|
{
|
|
|
TQString defFormat = getFormatForType( type );
|
|
|
fd.setSelectedFormat( defFormat );
|
|
|
}
|
|
|
|
|
|
TQString format;
|
|
|
if( fd.exec() )
|
|
|
{
|
|
|
format = fd.getFormat();
|
|
|
kdDebug(28000) << "Storing to format <" << format << ">" << endl;
|
|
|
bool ask = fd.askForFormat();
|
|
|
kdDebug(28000)<< "Store askFor is " << ask << endl;
|
|
|
storeFormatForType( type, format, ask );
|
|
|
subformat = fd.getSubFormat();
|
|
|
}
|
|
|
return( format );
|
|
|
}
|
|
|
|
|
|
|
|
|
/*
|
|
|
* This method returns true if the image format given in format is remembered
|
|
|
* for that image type.
|
|
|
*/
|
|
|
bool ImgSaver::isRememberedFormat( picType type, TQString format ) const
|
|
|
{
|
|
|
if( getFormatForType( type ) == format )
|
|
|
{
|
|
|
return( true );
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return( false );
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TQString ImgSaver::getFormatForType( picType type ) const
|
|
|
{
|
|
|
KConfig *konf = KGlobal::config ();
|
|
|
Q_CHECK_PTR( konf );
|
|
|
konf->setGroup( OP_FILE_GROUP );
|
|
|
|
|
|
TQString f;
|
|
|
|
|
|
switch( type )
|
|
|
{
|
|
|
case PT_COLOR_IMAGE:
|
|
|
f = konf->readEntry( OP_FORMAT_COLOR, "BMP" );
|
|
|
break;
|
|
|
case PT_GRAY_IMAGE:
|
|
|
f = konf->readEntry( OP_FORMAT_GRAY, "BMP" );
|
|
|
break;
|
|
|
case PT_BW_IMAGE:
|
|
|
f = konf->readEntry( OP_FORMAT_BW, "BMP" );
|
|
|
break;
|
|
|
case PT_HICOLOR_IMAGE:
|
|
|
f = konf->readEntry( OP_FORMAT_HICOLOR, "BMP" );
|
|
|
break;
|
|
|
default:
|
|
|
f = "BMP";
|
|
|
break;
|
|
|
}
|
|
|
return( f );
|
|
|
}
|
|
|
|
|
|
|
|
|
void ImgSaver::storeFormatForType( picType type, TQString format, bool ask )
|
|
|
{
|
|
|
KConfig *konf = KGlobal::config ();
|
|
|
Q_CHECK_PTR( konf );
|
|
|
konf->setGroup( OP_FILE_GROUP );
|
|
|
|
|
|
konf->writeEntry( OP_FILE_ASK_FORMAT, ask );
|
|
|
ask_for_format = ask;
|
|
|
|
|
|
switch( type )
|
|
|
{
|
|
|
case PT_COLOR_IMAGE:
|
|
|
konf->writeEntry( OP_FORMAT_COLOR, format );
|
|
|
break;
|
|
|
case PT_GRAY_IMAGE:
|
|
|
konf->writeEntry( OP_FORMAT_GRAY, format );
|
|
|
break;
|
|
|
case PT_BW_IMAGE:
|
|
|
konf->writeEntry( OP_FORMAT_BW, format );
|
|
|
break;
|
|
|
case PT_HICOLOR_IMAGE:
|
|
|
konf->writeEntry( OP_FORMAT_HICOLOR, format );
|
|
|
break;
|
|
|
default:
|
|
|
kdDebug(28000) << "Wrong Type - cant store format setting" << endl;
|
|
|
break;
|
|
|
}
|
|
|
konf->sync();
|
|
|
}
|
|
|
|
|
|
|
|
|
TQString ImgSaver::findSubFormat( TQString format )
|
|
|
{
|
|
|
kdDebug(28000) << "Searching Subformat for " << format << endl;
|
|
|
return( subformat );
|
|
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
private save() does the work to save the image.
|
|
|
the filename must be complete and local.
|
|
|
**/
|
|
|
ImgSaveStat ImgSaver::save( TQImage *image, const TQString &filename,
|
|
|
const TQString &format,
|
|
|
const TQString &subformat )
|
|
|
{
|
|
|
|
|
|
bool result = false;
|
|
|
kdDebug(28000) << "in ImgSaver::save: saving " << filename << endl;
|
|
|
if( ! format || !image )
|
|
|
{
|
|
|
kdDebug(28000) << "ImgSaver ERROR: Wrong parameter Format <" << format << "> or image" << endl;
|
|
|
return( ISS_ERR_PARAM );
|
|
|
}
|
|
|
|
|
|
if( image )
|
|
|
{
|
|
|
// remember the last processed file - only the filename - no path
|
|
|
TQFileInfo fi( filename );
|
|
|
TQString dirPath = fi.dirPath();
|
|
|
TQDir dir = TQDir( dirPath );
|
|
|
|
|
|
if( ! dir.exists() )
|
|
|
{
|
|
|
/* The dir to save in always should exist, except in the first preview save */
|
|
|
kdDebug(28000) << "Creating dir " << dirPath << endl;
|
|
|
if( !dir.mkdir( dirPath ) )
|
|
|
{
|
|
|
kdDebug(28000) << "ERR: Could not create directory" << endl;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if( fi.exists() && !fi.isWritable() )
|
|
|
{
|
|
|
kdDebug(28000) << "Cant write to file <" << filename << ">, cant save !" << endl;
|
|
|
result = false;
|
|
|
return( ISS_ERR_PERM );
|
|
|
}
|
|
|
|
|
|
/* Check the format, is it writable ? */
|
|
|
#ifdef USE_KIMAGEIO
|
|
|
if( ! KImageIO::canWrite( format ) )
|
|
|
{
|
|
|
kdDebug(28000) << "Cant write format <" << format << ">" << endl;
|
|
|
result = false;
|
|
|
return( ISS_ERR_FORMAT_NO_WRITE );
|
|
|
}
|
|
|
#endif
|
|
|
kdDebug(28000) << "ImgSaver: saving image to <" << filename << "> as <" << format << "/" << subformat <<">" << endl;
|
|
|
|
|
|
result = image->save( filename, format.latin1() );
|
|
|
|
|
|
|
|
|
last_file = fi.absFilePath();
|
|
|
last_format = format.latin1();
|
|
|
}
|
|
|
|
|
|
if( result )
|
|
|
return( ISS_OK );
|
|
|
else {
|
|
|
last_file = "";
|
|
|
last_format = "";
|
|
|
return( ISS_ERR_UNKNOWN );
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
void ImgSaver::readConfig( void )
|
|
|
{
|
|
|
|
|
|
KConfig *konf = KGlobal::config ();
|
|
|
Q_CHECK_PTR( konf );
|
|
|
konf->setGroup( OP_FILE_GROUP );
|
|
|
ask_for_format = konf->readBoolEntry( OP_FILE_ASK_FORMAT, true );
|
|
|
|
|
|
TQDir home = TQDir::home();
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TQString ImgSaver::errorString( ImgSaveStat stat )
|
|
|
{
|
|
|
TQString re;
|
|
|
|
|
|
switch( stat ) {
|
|
|
case ISS_OK: re = i18n( " image save OK " ); break;
|
|
|
case ISS_ERR_PERM: re = i18n( " permission error " ); break;
|
|
|
case ISS_ERR_FILENAME: re = i18n( " bad filename " ); break;
|
|
|
case ISS_ERR_NO_SPACE: re = i18n( " no space on device " ); break;
|
|
|
case ISS_ERR_FORMAT_NO_WRITE: re = i18n( " could not write image format " ); break;
|
|
|
case ISS_ERR_PROTOCOL: re = i18n( " can not write file using that protocol "); break;
|
|
|
case ISS_SAVE_CANCELED: re = i18n( " user canceled saving " ); break;
|
|
|
case ISS_ERR_UNKNOWN: re = i18n( " unknown error " ); break;
|
|
|
case ISS_ERR_PARAM: re = i18n( " parameter wrong " ); break;
|
|
|
|
|
|
default: re = "";
|
|
|
}
|
|
|
return( re );
|
|
|
|
|
|
}
|
|
|
|
|
|
TQString ImgSaver::extension( const KURL& url )
|
|
|
{
|
|
|
TQString extension = url.fileName();
|
|
|
|
|
|
int dotPos = extension.findRev( '.' );
|
|
|
if( dotPos > 0 )
|
|
|
{
|
|
|
int len = extension.length();
|
|
|
extension = extension.right( len - dotPos -1 );
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
/* No extension was supplied */
|
|
|
extension = TQString();
|
|
|
}
|
|
|
return extension;
|
|
|
}
|
|
|
|
|
|
|
|
|
bool ImgSaver::renameImage( const KURL& fromUrl, KURL& toUrl, bool askExt, TQWidget *overWidget )
|
|
|
{
|
|
|
/* Check if the provided filename has a extension */
|
|
|
TQString extTo = extension( toUrl );
|
|
|
TQString extFrom = extension( fromUrl );
|
|
|
KURL targetUrl( toUrl );
|
|
|
|
|
|
if( extTo.isEmpty() && !extFrom.isEmpty() )
|
|
|
{
|
|
|
/* Ask if the extension should be added */
|
|
|
int result = KMessageBox::Yes;
|
|
|
TQString fName = toUrl.fileName();
|
|
|
if( ! fName.endsWith( "." ) )
|
|
|
{
|
|
|
fName += ".";
|
|
|
}
|
|
|
fName += extFrom;
|
|
|
|
|
|
if( askExt )
|
|
|
{
|
|
|
|
|
|
TQString s;
|
|
|
s = i18n("The filename you supplied has no file extension.\nShould the correct one be added automatically? ");
|
|
|
s += i18n( "That would result in the new filename: %1" ).arg( fName);
|
|
|
|
|
|
result = KMessageBox::questionYesNo(overWidget, s, i18n( "Extension Missing"),
|
|
|
i18n("Add Extension"), i18n("Do Not Add"),
|
|
|
"AutoAddExtensions" );
|
|
|
}
|
|
|
|
|
|
if( result == KMessageBox::Yes )
|
|
|
{
|
|
|
targetUrl.setFileName( fName );
|
|
|
kdDebug(28000) << "Rename file to " << targetUrl.prettyURL() << endl;
|
|
|
}
|
|
|
}
|
|
|
else if( !extFrom.isEmpty() && extFrom != extTo )
|
|
|
{
|
|
|
if( ! ((extFrom.lower() == "jpeg" && extTo.lower() == "jpg") ||
|
|
|
(extFrom.lower() == "jpg" && extTo.lower() == "jpeg" )))
|
|
|
{
|
|
|
/* extensions differ -> TODO */
|
|
|
KMessageBox::error( overWidget,
|
|
|
i18n("Format changes of images are currently not supported."),
|
|
|
i18n("Wrong Extension Found" ));
|
|
|
return(false);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
bool success = false;
|
|
|
|
|
|
if( KIO::NetAccess::exists( targetUrl, false,0 ) )
|
|
|
{
|
|
|
kdDebug(28000)<< "Target already exists - can not copy" << endl;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if( KIO::file_move(fromUrl, targetUrl) )
|
|
|
{
|
|
|
success = true;
|
|
|
}
|
|
|
}
|
|
|
return( success );
|
|
|
}
|
|
|
|
|
|
|
|
|
TQString ImgSaver::tempSaveImage( KookaImage *img, const TQString& format, int colors )
|
|
|
{
|
|
|
|
|
|
KTempFile *tmpFile = new KTempFile( TQString(), "."+format.lower());
|
|
|
tmpFile->setAutoDelete( false );
|
|
|
tmpFile->close();
|
|
|
|
|
|
KookaImage tmpImg;
|
|
|
|
|
|
if( colors != -1 && img->numColors() != colors )
|
|
|
{
|
|
|
// Need to convert image
|
|
|
if( colors == 1 || colors == 8 || colors == 24 || colors == 32 )
|
|
|
{
|
|
|
tmpImg = img->convertDepth( colors );
|
|
|
img = &tmpImg;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
kdDebug(29000) << "ERROR: Wrong color depth requested: " << colors << endl;
|
|
|
img = 0;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
TQString name;
|
|
|
if( img )
|
|
|
{
|
|
|
name = tmpFile->name();
|
|
|
|
|
|
if( ! img->save( name, format.latin1() ) ) name = TQString();
|
|
|
}
|
|
|
delete tmpFile;
|
|
|
return name;
|
|
|
}
|
|
|
|
|
|
bool ImgSaver::copyImage( const KURL& fromUrl, const KURL& toUrl, TQWidget *overWidget )
|
|
|
{
|
|
|
|
|
|
/* Check if the provided filename has a extension */
|
|
|
TQString extTo = extension( toUrl );
|
|
|
TQString extFrom = extension( fromUrl );
|
|
|
KURL targetUrl( toUrl );
|
|
|
|
|
|
if( extTo.isEmpty() && !extFrom.isEmpty())
|
|
|
{
|
|
|
/* Ask if the extension should be added */
|
|
|
int result = KMessageBox::Yes;
|
|
|
TQString fName = toUrl.fileName();
|
|
|
if( ! fName.endsWith( "." ))
|
|
|
fName += ".";
|
|
|
fName += extFrom;
|
|
|
|
|
|
TQString s;
|
|
|
s = i18n("The filename you supplied has no file extension.\nShould the correct one be added automatically? ");
|
|
|
s += i18n( "That would result in the new filename: %1" ).arg( fName);
|
|
|
|
|
|
result = KMessageBox::questionYesNo(overWidget, s, i18n( "Extension Missing"),
|
|
|
i18n("Add Extension"), i18n("Do Not Add"),
|
|
|
"AutoAddExtensions" );
|
|
|
|
|
|
if( result == KMessageBox::Yes )
|
|
|
{
|
|
|
targetUrl.setFileName( fName );
|
|
|
}
|
|
|
}
|
|
|
else if( !extFrom.isEmpty() && extFrom != extTo )
|
|
|
{
|
|
|
/* extensions differ -> TODO */
|
|
|
if( ! ((extFrom.lower() == "jpeg" && extTo.lower() == "jpg") ||
|
|
|
(extFrom.lower() == "jpg" && extTo.lower() == "jpeg" )))
|
|
|
{
|
|
|
KMessageBox::error( overWidget, i18n("Format changes of images are currently not supported."),
|
|
|
i18n("Wrong Extension Found" ));
|
|
|
return(false);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
KIO::Job *copyjob = KIO::copy( fromUrl, targetUrl, false );
|
|
|
|
|
|
return( copyjob ? true : false );
|
|
|
}
|
|
|
|
|
|
|
|
|
/* extension needs to be added */
|
|
|
|
|
|
#include "img_saver.moc"
|