/* This file is part of the KDE project
Copyright ( C ) 2005 Cedric Pasteur < cedric . pasteur @ free . fr >
Copyright ( C ) 2004 - 2007 Jaroslaw Staniek < js @ iidea . pl >
This program is free software ; you can redistribute it and / or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation ; either
version 2 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
Library General Public License for more details .
You should have received a copy of the GNU Library General Public License
along with this program ; see the file COPYING . If not , write to
the Free Software Foundation , Inc . , 51 Franklin Street , Fifth Floor ,
* Boston , MA 02110 - 1301 , USA .
*/
# include "kexidbimagebox.h"
# include <tqapplication.h>
# include <tqpixmap.h>
# include <tqstyle.h>
# include <tqclipboard.h>
# include <tqtooltip.h>
# include <tqimage.h>
# include <tqbuffer.h>
# include <tqfiledialog.h>
# include <tqpainter.h>
# include <kdebug.h>
# include <tdepopupmenu.h>
# include <tdelocale.h>
# include <kiconloader.h>
# include <tdefiledialog.h>
# include <kimageio.h>
# include <kstandarddirs.h>
# include <kstaticdeleter.h>
# include <kimageeffect.h>
# include <tdestdaccel.h>
# include <tdemessagebox.h>
# include <kguiitem.h>
# include <widget/utils/kexidropdownbutton.h>
# include <widget/utils/kexicontextmenuutils.h>
# include <kexiutils/utils.h>
# include <kexidb/field.h>
# include <kexidb/utils.h>
# include <kexidb/queryschema.h>
# include <formeditor/widgetlibrary.h>
# ifdef TQ_WS_WIN
# include <win32_utils.h>
# include <tderecentdirs.h>
# endif
# include "kexidbutils.h"
# include "../kexiformpart.h"
static KStaticDeleter < TQPixmap > KexiDBImageBox_pmDeleter ;
static TQPixmap * KexiDBImageBox_pm = 0 ;
static KStaticDeleter < TQPixmap > KexiDBImageBox_pmSmallDeleter ;
static TQPixmap * KexiDBImageBox_pmSmall = 0 ;
KexiDBImageBox : : KexiDBImageBox ( bool designMode , TQWidget * parent , const char * name )
: KexiFrame ( parent , name , TQt : : WNoAutoErase )
, KexiFormDataItemInterface ( )
, m_alignment ( TQt : : AlignAuto | TQt : : AlignTop )
, m_designMode ( designMode )
, m_readOnly ( false )
, m_scaledContents ( false )
, m_keepAspectRatio ( true )
, m_insideSetData ( false )
, m_setFocusOnButtonAfterClosingPopup ( false )
, m_lineWidthChanged ( false )
, m_paintEventEnabled ( true )
, m_dropDownButtonVisible ( true )
, m_insideSetPalette ( false )
{
installEventFilter ( this ) ;
setSizePolicy ( TQSizePolicy : : Expanding , TQSizePolicy : : Preferred ) ;
//setup popup menu
m_popupMenu = new KexiImageContextMenu ( this ) ;
m_popupMenu - > installEventFilter ( this ) ;
if ( m_designMode ) {
m_chooser = 0 ;
}
else {
m_chooser = new KexiDropDownButton ( this ) ;
m_chooser - > setFocusPolicy ( TQ_StrongFocus ) ;
m_chooser - > setPopup ( m_popupMenu ) ;
setFocusProxy ( m_chooser ) ;
m_chooser - > installEventFilter ( this ) ;
// m_chooser->setPalette(tqApp->palette());
// hlyr->addWidget(m_chooser);
}
setBackgroundMode ( TQt : : NoBackground ) ;
setFrameShape ( TQFrame : : Box ) ;
setFrameShadow ( TQFrame : : Plain ) ;
setFrameColor ( TQt : : black ) ;
m_paletteBackgroundColorChanged = false ; //set this here, not before
connect ( m_popupMenu , TQT_SIGNAL ( updateActionsAvailabilityRequested ( bool & , bool & ) ) ,
this , TQT_SLOT ( slotUpdateActionsAvailabilityRequested ( bool & , bool & ) ) ) ;
connect ( m_popupMenu , TQT_SIGNAL ( insertFromFileRequested ( const KURL & ) ) ,
this , TQT_SLOT ( handleInsertFromFileAction ( const KURL & ) ) ) ;
connect ( m_popupMenu , TQT_SIGNAL ( saveAsRequested ( const TQString & ) ) ,
this , TQT_SLOT ( handleSaveAsAction ( const TQString & ) ) ) ;
connect ( m_popupMenu , TQT_SIGNAL ( cutRequested ( ) ) ,
this , TQT_SLOT ( handleCutAction ( ) ) ) ;
connect ( m_popupMenu , TQT_SIGNAL ( copyRequested ( ) ) ,
this , TQT_SLOT ( handleCopyAction ( ) ) ) ;
connect ( m_popupMenu , TQT_SIGNAL ( pasteRequested ( ) ) ,
this , TQT_SLOT ( handlePasteAction ( ) ) ) ;
connect ( m_popupMenu , TQT_SIGNAL ( clearRequested ( ) ) ,
this , TQT_SLOT ( clear ( ) ) ) ;
connect ( m_popupMenu , TQT_SIGNAL ( showPropertiesRequested ( ) ) ,
this , TQT_SLOT ( handleShowPropertiesAction ( ) ) ) ;
// connect(m_popupMenu, TQT_SIGNAL(aboutToHide()), this, TQT_SLOT(slotAboutToHidePopupMenu()));
// if (m_chooser) {
//we couldn't use m_chooser->setPopup() because of drawing problems
// connect(m_chooser, TQT_SIGNAL(pressed()), this, TQT_SLOT(slotChooserPressed()));
// connect(m_chooser, TQT_SIGNAL(released()), this, TQT_SLOT(slotChooserReleased()));
// connect(m_chooser, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(slotToggled(bool)));
// }
setDataSource ( TQString ( ) ) ; //to initialize popup menu and actions availability
}
KexiDBImageBox : : ~ KexiDBImageBox ( )
{
}
KexiImageContextMenu * KexiDBImageBox : : contextMenu ( ) const
{
return m_popupMenu ;
}
TQVariant KexiDBImageBox : : value ( )
{
if ( dataSource ( ) . isEmpty ( ) ) {
//not db-aware
return TQVariant ( ) ;
}
//db-aware mode
return m_value ; //todo
//return TQVariant(); //todo
}
void KexiDBImageBox : : setValueInternal ( const TQVariant & add , bool removeOld , bool loadPixmap )
{
if ( isReadOnly ( ) )
return ;
m_popupMenu - > hide ( ) ;
if ( removeOld )
m_value = add . toByteArray ( ) ;
else //do not add "m_origValue" to "add" as this is TQByteArray
m_value = m_origValue . toByteArray ( ) ;
bool ok = ! m_value . isEmpty ( ) ;
if ( ok ) {
///unused (m_valueMimeType is not available unless the px is inserted) TQString type( KImageIO::typeForMime(m_valueMimeType) );
///ok = KImageIO::canRead( type );
ok = loadPixmap ? m_pixmap . loadFromData ( m_value ) : true ; //, type.latin1());
if ( ! ok ) {
//! @todo inform about error?
}
}
if ( ! ok ) {
m_valueMimeType = TQString ( ) ;
m_pixmap = TQPixmap ( ) ;
}
repaint ( ) ;
}
void KexiDBImageBox : : setInvalidState ( const TQString & displayText )
{
Q_UNUSED ( displayText ) ;
// m_pixmapLabel->setPixmap(TQPixmap());
if ( ! dataSource ( ) . isEmpty ( ) ) {
m_value = TQByteArray ( ) ;
}
// m_pixmap = TQPixmap();
// m_originalFileName = TQString();
//! @todo m_pixmapLabel->setText( displayText );
if ( m_chooser )
m_chooser - > hide ( ) ;
setReadOnly ( true ) ;
}
bool KexiDBImageBox : : valueIsNull ( )
{
return m_value . isEmpty ( ) ;
// return !m_pixmapLabel->pixmap() || m_pixmapLabel->pixmap()->isNull();
}
bool KexiDBImageBox : : valueIsEmpty ( )
{
return false ;
}
bool KexiDBImageBox : : isReadOnly ( ) const
{
return m_readOnly ;
}
void KexiDBImageBox : : setReadOnly ( bool set )
{
m_readOnly = set ;
}
TQPixmap KexiDBImageBox : : pixmap ( ) const
{
if ( dataSource ( ) . isEmpty ( ) ) {
//not db-aware
return m_data . pixmap ( ) ;
}
//db-aware mode
return m_pixmap ;
}
uint KexiDBImageBox : : pixmapId ( ) const
{
if ( dataSource ( ) . isEmpty ( ) ) { // && !m_data.stored()) {
//not db-aware
return m_data . id ( ) ;
}
return 0 ;
}
void KexiDBImageBox : : setPixmapId ( uint id )
{
if ( m_insideSetData ) //avoid recursion
return ;
setData ( KexiBLOBBuffer : : self ( ) - > objectForId ( id , /*unstored*/ false ) ) ;
repaint ( ) ;
}
uint KexiDBImageBox : : storedPixmapId ( ) const
{
if ( dataSource ( ) . isEmpty ( ) & & m_data . stored ( ) ) {
//not db-aware
return m_data . id ( ) ;
}
return 0 ;
}
void KexiDBImageBox : : setStoredPixmapId ( uint id )
{
setData ( KexiBLOBBuffer : : self ( ) - > objectForId ( id , /*stored*/ true ) ) ;
repaint ( ) ;
}
bool KexiDBImageBox : : hasScaledContents ( ) const
{
return m_scaledContents ;
// return m_pixmapLabel->hasScaledContents();
}
/*void KexiDBImageBox::setPixmap(const TQByteArray& pixmap)
{
setValueInternal ( pixmap , true ) ;
// setBackgroundMode(pixmap.isNull() ? TQt::NoBackground : TQt::PaletteBackground);
} */
void KexiDBImageBox : : setScaledContents ( bool set )
{
//todo m_pixmapLabel->setScaledContents(set);
m_scaledContents = set ;
repaint ( ) ;
}
void KexiDBImageBox : : setKeepAspectRatio ( bool set )
{
m_keepAspectRatio = set ;
if ( m_scaledContents )
repaint ( ) ;
}
TQWidget * KexiDBImageBox : : widget ( )
{
//! @todo
// return m_pixmapLabel;
return this ;
}
bool KexiDBImageBox : : cursorAtStart ( )
{
return true ;
}
bool KexiDBImageBox : : cursorAtEnd ( )
{
return true ;
}
TQByteArray KexiDBImageBox : : data ( ) const
{
if ( dataSource ( ) . isEmpty ( ) ) {
//static mode
return m_data . data ( ) ;
}
else {
//db-aware mode
return m_value ;
}
}
void KexiDBImageBox : : insertFromFile ( )
{
m_popupMenu - > insertFromFile ( ) ;
}
void KexiDBImageBox : : handleInsertFromFileAction ( const KURL & url )
{
if ( ! dataSource ( ) . isEmpty ( ) & & isReadOnly ( ) )
return ;
if ( dataSource ( ) . isEmpty ( ) ) {
//static mode
KexiBLOBBuffer : : Handle h = KexiBLOBBuffer : : self ( ) - > insertPixmap ( url ) ;
if ( ! h )
return ;
setData ( h ) ;
repaint ( ) ;
}
else {
//db-aware
TQString fileName ( url . isLocalFile ( ) ? url . path ( ) : url . prettyURL ( ) ) ;
//! @todo download the file if remote, then set fileName properly
TQFile f ( fileName ) ;
if ( ! f . open ( IO_ReadOnly ) ) {
//! @todo err msg
return ;
}
TQByteArray ba = f . readAll ( ) ;
if ( f . status ( ) ! = IO_Ok ) {
//! @todo err msg
f . close ( ) ;
return ;
}
m_valueMimeType = KImageIO : : mimeType ( fileName ) ;
setValueInternal ( ba , true ) ;
}
//! @todo emit signal for setting "dirty" flag within the design
if ( ! dataSource ( ) . isEmpty ( ) ) {
signalValueChanged ( ) ;
}
}
void KexiDBImageBox : : handleAboutToSaveAsAction ( TQString & origFilename , TQString & fileExtension , bool & dataIsEmpty )
{
if ( data ( ) . isEmpty ( ) ) {
kdWarning ( ) < < " KexiDBImageBox::handleAboutToSaveAs(): no pixmap! " < < endl ;
dataIsEmpty = false ;
return ;
}
if ( dataSource ( ) . isEmpty ( ) ) { //for static images filename and mimetype can be available
origFilename = m_data . originalFileName ( ) ;
if ( ! origFilename . isEmpty ( ) )
origFilename = TQString ( " / " ) + origFilename ;
if ( ! m_data . mimeType ( ) . isEmpty ( ) )
fileExtension = KImageIO : : typeForMime ( m_data . mimeType ( ) ) . lower ( ) ;
}
}
void KexiDBImageBox : : handleSaveAsAction ( const TQString & fileName )
{
TQFile f ( fileName ) ;
if ( ! f . open ( IO_WriteOnly ) ) {
//! @todo err msg
return ;
}
f . writeBlock ( data ( ) ) ;
if ( f . status ( ) ! = IO_Ok ) {
//! @todo err msg
f . close ( ) ;
return ;
}
f . close ( ) ;
}
void KexiDBImageBox : : handleCutAction ( )
{
if ( ! dataSource ( ) . isEmpty ( ) & & isReadOnly ( ) )
return ;
handleCopyAction ( ) ;
clear ( ) ;
}
void KexiDBImageBox : : handleCopyAction ( )
{
tqApp - > clipboard ( ) - > setPixmap ( pixmap ( ) , TQClipboard : : Clipboard ) ;
}
void KexiDBImageBox : : handlePasteAction ( )
{
if ( isReadOnly ( ) | | ( ! m_designMode & & ! hasFocus ( ) ) )
return ;
TQPixmap pm ( tqApp - > clipboard ( ) - > pixmap ( TQClipboard : : Clipboard ) ) ;
// if (!pm.isNull())
// setValueInternal(pm, true);
if ( dataSource ( ) . isEmpty ( ) ) {
//static mode
setData ( KexiBLOBBuffer : : self ( ) - > insertPixmap ( pm ) ) ;
}
else {
//db-aware mode
m_pixmap = pm ;
TQByteArray ba ;
TQBuffer buffer ( ba ) ;
buffer . open ( IO_WriteOnly ) ;
if ( m_pixmap . save ( & buffer , " PNG " ) ) { // write pixmap into ba in PNG format
setValueInternal ( ba , true , false /* !loadPixmap */ ) ;
}
else {
setValueInternal ( TQByteArray ( ) , true ) ;
}
}
repaint ( ) ;
if ( ! dataSource ( ) . isEmpty ( ) ) {
// emit pixmapChanged();
signalValueChanged ( ) ;
}
}
void KexiDBImageBox : : clear ( )
{
if ( dataSource ( ) . isEmpty ( ) ) {
//static mode
setData ( KexiBLOBBuffer : : Handle ( ) ) ;
}
else {
if ( isReadOnly ( ) )
return ;
//db-aware mode
setValueInternal ( TQByteArray ( ) , true ) ;
//m_pixmap = TQPixmap();
}
// m_originalFileName = TQString();
//! @todo emit signal for setting "dirty" flag within the design
// m_pixmap = TQPixmap(); //will be loaded on demand
repaint ( ) ;
if ( ! dataSource ( ) . isEmpty ( ) ) {
// emit pixmapChanged();//valueChanged(data());
signalValueChanged ( ) ;
}
}
void KexiDBImageBox : : handleShowPropertiesAction ( )
{
//! @todo
}
void KexiDBImageBox : : slotUpdateActionsAvailabilityRequested ( bool & valueIsNull , bool & valueIsReadOnly )
{
valueIsNull = ! (
( dataSource ( ) . isEmpty ( ) & & ! pixmap ( ) . isNull ( ) ) /*static pixmap available*/
| | ( ! dataSource ( ) . isEmpty ( ) & & ! this - > valueIsNull ( ) ) /*db-aware pixmap available*/
) ;
// read-only if static pixmap or db-aware pixmap for read-only widget:
valueIsReadOnly = ! m_designMode & & dataSource ( ) . isEmpty ( ) | | ! dataSource ( ) . isEmpty ( ) & & isReadOnly ( )
| | m_designMode & & ! dataSource ( ) . isEmpty ( ) ;
}
/*
void KexiDBImageBox : : slotAboutToHidePopupMenu ( )
{
// kexipluginsdbg << "##### slotAboutToHidePopupMenu() " << endl;
m_clickTimer . start ( 50 , true ) ;
if ( m_chooser & & m_chooser - > isOn ( ) ) {
m_chooser - > toggle ( ) ;
if ( m_setFocusOnButtonAfterClosingPopup ) {
m_setFocusOnButtonAfterClosingPopup = false ;
m_chooser - > setFocus ( ) ;
}
}
} */
void KexiDBImageBox : : contextMenuEvent ( TQContextMenuEvent * e )
{
if ( popupMenuAvailable ( ) )
m_popupMenu - > exec ( e - > globalPos ( ) , - 1 ) ;
}
/*void KexiDBImageBox::slotChooserPressed()
{
// if (!m_clickTimer.isActive())
// return;
// m_chooser->setDown( false );
}
void KexiDBImageBox : : slotChooserReleased ( )
{
}
void KexiDBImageBox : : slotToggled ( bool on )
{
return ;
// kexipluginsdbg << "##### slotToggled() " << on << endl;
if ( m_clickTimer . isActive ( ) | | ! on ) {
m_chooser - > disableMousePress = true ;
return ;
}
m_chooser - > disableMousePress = false ;
TQRect screen = tqApp - > desktop ( ) - > availableGeometry ( m_chooser ) ;
TQPoint p ;
if ( TQApplication : : reverseLayout ( ) ) {
if ( ( mapToGlobal ( m_chooser - > rect ( ) . bottomLeft ( ) ) . y ( ) + m_popupMenu - > sizeHint ( ) . height ( ) ) < = screen . height ( ) )
p = m_chooser - > mapToGlobal ( m_chooser - > rect ( ) . bottomRight ( ) ) ;
else
p = m_chooser - > mapToGlobal ( m_chooser - > rect ( ) . topRight ( ) - TQPoint ( 0 , m_popupMenu - > sizeHint ( ) . height ( ) ) ) ;
p . rx ( ) - = m_popupMenu - > sizeHint ( ) . width ( ) ;
}
else {
if ( ( m_chooser - > mapToGlobal ( m_chooser - > rect ( ) . bottomLeft ( ) ) . y ( ) + m_popupMenu - > sizeHint ( ) . height ( ) ) < = screen . height ( ) )
p = m_chooser - > mapToGlobal ( m_chooser - > rect ( ) . bottomLeft ( ) ) ;
else
p = m_chooser - > mapToGlobal ( m_chooser - > rect ( ) . topLeft ( ) - TQPoint ( 0 , m_popupMenu - > sizeHint ( ) . height ( ) ) ) ;
}
if ( ! m_popupMenu - > isVisible ( ) & & on ) {
m_popupMenu - > exec ( p , - 1 ) ;
m_popupMenu - > setFocus ( ) ;
}
//m_chooser->setDown( false );
} */
void KexiDBImageBox : : updateActionStrings ( )
{
if ( ! m_popupMenu )
return ;
if ( m_designMode ) {
/* TQString titleString( i18n("Image Box") );
if ( ! dataSource ( ) . isEmpty ( ) )
titleString . prepend ( dataSource ( ) + " : " ) ;
m_popupMenu - > changeTitle ( m_popupMenu - > idAt ( 0 ) , m_popupMenu - > titlePixmap ( m_popupMenu - > idAt ( 0 ) ) , titleString ) ; */
}
else {
//update title in data view mode, based on the data source
if ( columnInfo ( ) ) {
KexiImageContextMenu : : updateTitle ( m_popupMenu , columnInfo ( ) - > captionOrAliasOrName ( ) ,
KexiFormPart : : library ( ) - > iconName ( className ( ) ) ) ;
}
}
if ( m_chooser ) {
if ( popupMenuAvailable ( ) & & dataSource ( ) . isEmpty ( ) ) { //this may work in the future (see @todo below)
TQToolTip : : add ( m_chooser , i18n ( " Click to show actions for this image box " ) ) ;
} else {
TQString beautifiedImageBoxName ;
if ( m_designMode ) {
beautifiedImageBoxName = dataSource ( ) ;
}
else {
beautifiedImageBoxName = columnInfo ( ) ? columnInfo ( ) - > captionOrAliasOrName ( ) : TQString ( ) ;
/*! @todo look at makeFirstCharacterUpperCaseInCaptions setting [bool]
( see doc / dev / settings . txt ) */
beautifiedImageBoxName = beautifiedImageBoxName [ 0 ] . upper ( ) + beautifiedImageBoxName . mid ( 1 ) ;
}
TQToolTip : : add ( m_chooser , i18n ( " Click to show actions for \" %1 \" image box " ) . arg ( beautifiedImageBoxName ) ) ;
}
}
}
bool KexiDBImageBox : : popupMenuAvailable ( )
{
/*! @todo add kexi-global setting which anyway, allows to show this button
( read - only actions like copy / save as / print can be available ) */
//chooser button can be only visible when data source is specified
return ! dataSource ( ) . isEmpty ( ) ;
}
void KexiDBImageBox : : setDataSource ( const TQString & ds )
{
KexiFormDataItemInterface : : setDataSource ( ds ) ;
setData ( KexiBLOBBuffer : : Handle ( ) ) ;
updateActionStrings ( ) ;
KexiFrame : : setFocusPolicy ( focusPolicy ( ) ) ; //set modified policy
if ( m_chooser ) {
m_chooser - > setEnabled ( popupMenuAvailable ( ) ) ;
if ( m_dropDownButtonVisible & & popupMenuAvailable ( ) ) {
m_chooser - > show ( ) ;
}
else {
m_chooser - > hide ( ) ;
}
}
// update some properties s not changed by user
//! @todo get default line width from global style settings
if ( ! m_lineWidthChanged ) {
KexiFrame : : setLineWidth ( ds . isEmpty ( ) ? 0 : 1 ) ;
}
if ( ! m_paletteBackgroundColorChanged & & parentWidget ( ) ) {
KexiFrame : : setPaletteBackgroundColor (
dataSource ( ) . isEmpty ( ) ? parentWidget ( ) - > paletteBackgroundColor ( ) : palette ( ) . active ( ) . base ( ) ) ;
}
}
TQSize KexiDBImageBox : : sizeHint ( ) const
{
if ( pixmap ( ) . isNull ( ) )
return TQSize ( 80 , 80 ) ;
return pixmap ( ) . size ( ) ;
}
int KexiDBImageBox : : realLineWidth ( ) const
{
if ( frameShape ( ) = = TQFrame : : Box & & ( frameShadow ( ) = = TQFrame : : Sunken | | frameShadow ( ) = = TQFrame : : Raised ) )
return 2 * lineWidth ( ) ;
else
return lineWidth ( ) ;
}
void KexiDBImageBox : : paintEvent ( TQPaintEvent * pe )
{
if ( ! m_paintEventEnabled )
return ;
TQPainter p ( this ) ;
p . setClipRect ( pe - > rect ( ) ) ;
const int m = realLineWidth ( ) + margin ( ) ;
TQColor bg ( eraseColor ( ) ) ;
if ( m_designMode & & pixmap ( ) . isNull ( ) ) {
TQPixmap pm ( size ( ) - TQSize ( m , m ) ) ;
TQPainter p2 ;
p2 . begin ( TQT_TQPAINTDEVICE ( & pm ) , this ) ;
p2 . fillRect ( 0 , 0 , width ( ) , height ( ) , bg ) ;
updatePixmap ( ) ;
TQPixmap * imagBoxPm ;
const bool tooLarge = ( height ( ) - m - m ) < = KexiDBImageBox_pm - > height ( ) ;
if ( tooLarge | | ( width ( ) - m - m ) < = KexiDBImageBox_pm - > width ( ) )
imagBoxPm = KexiDBImageBox_pmSmall ;
else
imagBoxPm = KexiDBImageBox_pm ;
TQImage img ( imagBoxPm - > convertToImage ( ) ) ;
img = KImageEffect : : flatten ( img , bg . dark ( 150 ) ,
tqGray ( bg . rgb ( ) ) < = 20 ? TQColor ( TQt : : gray ) . dark ( 150 ) : bg . light ( 105 ) ) ;
TQPixmap converted ;
converted . convertFromImage ( img ) ;
// if (tooLarge)
// p2.drawPixmap(2, 2, converted);
// else
p2 . drawPixmap ( 2 , height ( ) - m - m - imagBoxPm - > height ( ) - 2 , converted ) ;
TQFont f ( tqApp - > font ( ) ) ;
p2 . setFont ( f ) ;
p2 . setPen ( KexiUtils : : contrastColor ( bg ) ) ;
p2 . drawText ( pm . rect ( ) , TQt : : AlignCenter ,
dataSource ( ) . isEmpty ( )
? TQString : : fromLatin1 ( name ( ) ) + " \n " + i18n ( " Unbound Image Box " , " (unbound) " ) //i18n("No Image")
: dataSource ( ) ) ;
p2 . end ( ) ;
bitBlt ( this , m , m , & pm ) ;
}
else {
TQSize internalSize ( size ( ) ) ;
if ( m_chooser & & m_dropDownButtonVisible & & ! dataSource ( ) . isEmpty ( ) )
internalSize . setWidth ( internalSize . width ( ) - m_chooser - > width ( ) ) ;
//clearing needed here because we may need to draw a pixmap with transparency
p . fillRect ( 0 , 0 , width ( ) , height ( ) , bg ) ;
KexiUtils : : drawPixmap ( p , m , TQRect ( TQPoint ( 0 , 0 ) , internalSize ) , pixmap ( ) , m_alignment ,
m_scaledContents , m_keepAspectRatio ) ;
}
KexiFrame : : drawFrame ( & p ) ;
// if the widget is focused, draw focus indicator rect _if_ there is no chooser button
if ( ! m_designMode & & ! dataSource ( ) . isEmpty ( ) & & hasFocus ( ) & & ( ! m_chooser | | ! m_chooser - > isVisible ( ) ) ) {
style ( ) . tqdrawPrimitive (
TQStyle : : PE_FocusRect , & p , style ( ) . subRect ( TQStyle : : SR_PushButtonContents , this ) ,
palette ( ) . active ( ) ) ;
}
}
/* virtual void KexiDBImageBox::paletteChange ( const TQPalette & oldPalette )
{
TQFrame : : paletteChange ( oldPalette ) ;
if ( oldPalette . active ( ) . background ( ) ! = palette ( ) . active ( ) . background ( ) ) {
delete KexiDBImageBox_pm ;
KexiDBImageBox_pm = 0 ;
repaint ( ) ;
}
} */
void KexiDBImageBox : : updatePixmap ( )
{
if ( ! ( m_designMode & & pixmap ( ) . isNull ( ) ) )
return ;
if ( ! KexiDBImageBox_pm ) {
TQString fname ( locate ( " data " , TQString ( " kexi/pics/imagebox.png " ) ) ) ;
KexiDBImageBox_pmDeleter . setObject ( KexiDBImageBox_pm , new TQPixmap ( fname , " PNG " ) ) ;
TQImage img ( KexiDBImageBox_pm - > convertToImage ( ) ) ;
KexiDBImageBox_pmSmallDeleter . setObject ( KexiDBImageBox_pmSmall ,
new TQPixmap ( img . smoothScale ( img . width ( ) / 2 , img . height ( ) / 2 , TQ_ScaleMin ) ) ) ;
}
}
void KexiDBImageBox : : setAlignment ( int alignment )
{
m_alignment = alignment ;
if ( ! m_scaledContents | | m_keepAspectRatio )
repaint ( ) ;
}
void KexiDBImageBox : : setData ( const KexiBLOBBuffer : : Handle & handle )
{
if ( m_insideSetData ) //avoid recursion
return ;
m_insideSetData = true ;
m_data = handle ;
emit idChanged ( handle . id ( ) ) ;
m_insideSetData = false ;
update ( ) ;
}
void KexiDBImageBox : : resizeEvent ( TQResizeEvent * e )
{
KexiFrame : : resizeEvent ( e ) ;
if ( m_chooser ) {
TQSize s ( m_chooser - > sizeHint ( ) ) ;
TQSize margin ( realLineWidth ( ) , realLineWidth ( ) ) ;
s . setHeight ( height ( ) - 2 * margin . height ( ) ) ;
s = s . boundedTo ( size ( ) - 2 * margin ) ;
m_chooser - > resize ( s ) ;
m_chooser - > move ( TQRect ( TQPoint ( 0 , 0 ) , e - > size ( ) - m_chooser - > size ( ) - margin + TQSize ( 1 , 1 ) ) . bottomRight ( ) ) ;
}
}
/*
bool KexiDBImageBox : : setProperty ( const char * name , const TQVariant & value )
{
const bool ret = TQLabel : : setProperty ( name , value ) ;
if ( p_shadowEnabled ) {
if ( 0 = = qstrcmp ( " indent " , name ) | | 0 = = qstrcmp ( " font " , name ) | | 0 = = qstrcmp ( " margin " , name )
| | 0 = = qstrcmp ( " frameShadow " , name ) | | 0 = = qstrcmp ( " frameShape " , name )
| | 0 = = qstrcmp ( " frameStyle " , name ) | | 0 = = qstrcmp ( " midLineWidth " , name )
| | 0 = = qstrcmp ( " lineWidth " , name ) ) {
p_privateLabel - > setProperty ( name , value ) ;
updatePixmap ( ) ;
}
}
return ret ;
}
*/
void KexiDBImageBox : : setColumnInfo ( KexiDB : : QueryColumnInfo * cinfo )
{
KexiFormDataItemInterface : : setColumnInfo ( cinfo ) ;
//updating strings and title is needed
updateActionStrings ( ) ;
}
bool KexiDBImageBox : : keyPressed ( TQKeyEvent * ke )
{
// Esc key should close the popup
if ( ke - > state ( ) = = Qt : : NoButton & & ke - > key ( ) = = TQt : : Key_Escape ) {
if ( m_popupMenu - > isVisible ( ) ) {
m_setFocusOnButtonAfterClosingPopup = true ;
return true ;
}
}
// else if (ke->state() == TQt::ControlButton && TDEStdAccel::shortcut(TDEStdAccel::Copy).keyCodeTQt() == (ke->key()|TQt::CTRL)) {
// }
return false ;
}
void KexiDBImageBox : : setLineWidth ( int width )
{
m_lineWidthChanged = true ;
KexiFrame : : setLineWidth ( width ) ;
}
void KexiDBImageBox : : setPalette ( const TQPalette & pal )
{
KexiFrame : : setPalette ( pal ) ;
if ( m_insideSetPalette )
return ;
m_insideSetPalette = true ;
setPaletteBackgroundColor ( pal . active ( ) . base ( ) ) ;
setPaletteForegroundColor ( pal . active ( ) . foreground ( ) ) ;
m_insideSetPalette = false ;
}
void KexiDBImageBox : : setPaletteBackgroundColor ( const TQColor & color )
{
kexipluginsdbg < < " KexiDBImageBox::setPaletteBackgroundColor(): " < < TQString ( color . name ( ) ) < < endl ;
m_paletteBackgroundColorChanged = true ;
KexiFrame : : setPaletteBackgroundColor ( color ) ;
if ( m_chooser )
m_chooser - > setPalette ( tqApp - > palette ( ) ) ;
}
bool KexiDBImageBox : : dropDownButtonVisible ( ) const
{
return m_dropDownButtonVisible ;
}
void KexiDBImageBox : : setDropDownButtonVisible ( bool set )
{
//! @todo use global default setting for this property
if ( m_dropDownButtonVisible = = set )
return ;
m_dropDownButtonVisible = set ;
if ( m_chooser ) {
if ( m_dropDownButtonVisible )
m_chooser - > show ( ) ;
else
m_chooser - > hide ( ) ;
}
}
bool KexiDBImageBox : : subwidgetStretchRequired ( KexiDBAutoField * autoField ) const
{
Q_UNUSED ( autoField ) ;
return true ;
}
bool KexiDBImageBox : : eventFilter ( TQObject * watched , TQEvent * e )
{
if ( TQT_BASE_OBJECT ( watched ) = = TQT_BASE_OBJECT ( this ) | | TQT_BASE_OBJECT ( watched ) = = TQT_BASE_OBJECT ( m_chooser ) ) { //we're watching chooser as well because it's a focus proxy even if invisible
if ( e - > type ( ) = = TQEvent : : FocusIn | | e - > type ( ) = = TQEvent : : FocusOut | | e - > type ( ) = = TQEvent : : MouseButtonPress ) {
update ( ) ; //to repaint focus rect
}
}
// hide popup menu as soon as it loses focus
if ( TQT_BASE_OBJECT ( watched ) = = TQT_BASE_OBJECT ( m_popupMenu ) & & e - > type ( ) = = TQEvent : : FocusOut ) {
m_popupMenu - > hide ( ) ;
}
return KexiFrame : : eventFilter ( watched , e ) ;
}
TQ_FocusPolicy KexiDBImageBox : : focusPolicy ( ) const
{
if ( dataSource ( ) . isEmpty ( ) )
return TQ_NoFocus ;
return m_focusPolicyInternal ;
}
TQ_FocusPolicy KexiDBImageBox : : focusPolicyInternal ( ) const
{
return m_focusPolicyInternal ;
}
void KexiDBImageBox : : setFocusPolicy ( TQ_FocusPolicy policy )
{
m_focusPolicyInternal = policy ;
KexiFrame : : setFocusPolicy ( focusPolicy ( ) ) ; //set modified policy
}
# include "kexidbimagebox.moc"