21#include "kexidbimagebox.h"
23#include <tqapplication.h>
26#include <tqclipboard.h>
30#include <tqfiledialog.h>
34#include <tdepopupmenu.h>
36#include <kiconloader.h>
37#include <tdefiledialog.h>
39#include <kstandarddirs.h>
40#include <kstaticdeleter.h>
41#include <kimageeffect.h>
42#include <tdestdaccel.h>
43#include <tdemessagebox.h>
46#include <widget/utils/kexidropdownbutton.h>
47#include <widget/utils/kexicontextmenuutils.h>
48#include <kexiutils/utils.h>
49#include <kexidb/field.h>
50#include <kexidb/utils.h>
51#include <kexidb/queryschema.h>
52#include <formeditor/widgetlibrary.h>
55#include <win32_utils.h>
56#include <tderecentdirs.h>
59#include "kexidbutils.h"
60#include "../kexiformpart.h"
62static KStaticDeleter<TQPixmap> KexiDBImageBox_pmDeleter;
63static TQPixmap* KexiDBImageBox_pm = 0;
64static KStaticDeleter<TQPixmap> KexiDBImageBox_pmSmallDeleter;
65static TQPixmap* KexiDBImageBox_pmSmall = 0;
67KexiDBImageBox::KexiDBImageBox(
bool designMode, TQWidget *parent,
const char *name )
68 :
KexiFrame( parent, name, TQt::WNoAutoErase )
70 , m_alignment(TQt::AlignAuto|TQt::AlignTop)
71 , m_designMode(designMode)
73 , m_scaledContents(false)
74 , m_keepAspectRatio(true)
75 , m_insideSetData(false)
76 , m_setFocusOnButtonAfterClosingPopup(false)
77 , m_lineWidthChanged(false)
78 , m_paintEventEnabled(true)
79 , m_dropDownButtonVisible(true)
80 , m_insideSetPalette(false)
82 installEventFilter(
this);
83 setSizePolicy(TQSizePolicy::Expanding, TQSizePolicy::Preferred);
87 m_popupMenu->installEventFilter(
this);
94 m_chooser->setFocusPolicy(TQWidget::StrongFocus);
95 m_chooser->setPopup(m_popupMenu);
96 setFocusProxy(m_chooser);
97 m_chooser->installEventFilter(
this);
102 setBackgroundMode(TQt::NoBackground);
103 setFrameShape(TQFrame::Box);
104 setFrameShadow(TQFrame::Plain);
105 setFrameColor(TQt::black);
107 m_paletteBackgroundColorChanged =
false;
109 connect(m_popupMenu, TQ_SIGNAL(updateActionsAvailabilityRequested(
bool&,
bool&)),
110 this, TQ_SLOT(slotUpdateActionsAvailabilityRequested(
bool&,
bool&)));
111 connect(m_popupMenu, TQ_SIGNAL(insertFromFileRequested(
const KURL&)),
112 this, TQ_SLOT(handleInsertFromFileAction(
const KURL&)));
113 connect(m_popupMenu, TQ_SIGNAL(saveAsRequested(
const TQString&)),
114 this, TQ_SLOT(handleSaveAsAction(
const TQString&)));
115 connect(m_popupMenu, TQ_SIGNAL(cutRequested()),
116 this, TQ_SLOT(handleCutAction()));
117 connect(m_popupMenu, TQ_SIGNAL(copyRequested()),
118 this, TQ_SLOT(handleCopyAction()));
119 connect(m_popupMenu, TQ_SIGNAL(pasteRequested()),
120 this, TQ_SLOT(handlePasteAction()));
121 connect(m_popupMenu, TQ_SIGNAL(clearRequested()),
122 this, TQ_SLOT(clear()));
123 connect(m_popupMenu, TQ_SIGNAL(showPropertiesRequested()),
124 this, TQ_SLOT(handleShowPropertiesAction()));
134 setDataSource( TQString() );
137KexiDBImageBox::~KexiDBImageBox()
165 m_value = m_origValue.toByteArray();
170 ok = loadPixmap ? m_pixmap.loadFromData(
m_value) :
true;
177 m_pixmap = TQPixmap();
184 Q_UNUSED( displayText );
216void KexiDBImageBox::setReadOnly(
bool set)
221TQPixmap KexiDBImageBox::pixmap()
const
225 return m_data.pixmap();
231uint KexiDBImageBox::pixmapId()
const
240void KexiDBImageBox::setPixmapId(uint
id)
248uint KexiDBImageBox::storedPixmapId()
const
250 if (
dataSource().isEmpty() && m_data.stored()) {
257void KexiDBImageBox::setStoredPixmapId(uint
id)
263bool KexiDBImageBox::hasScaledContents()
const
265 return m_scaledContents;
278 m_scaledContents = set;
282void KexiDBImageBox::setKeepAspectRatio(
bool set)
284 m_keepAspectRatio = set;
285 if (m_scaledContents)
310 return m_data.data();
320 m_popupMenu->insertFromFile();
338 TQString fileName( url.isLocalFile() ? url.path() : url.prettyURL() );
342 if (!f.open(IO_ReadOnly)) {
346 TQByteArray ba = f.readAll();
347 if (f.status()!=IO_Ok) {
362void KexiDBImageBox::handleAboutToSaveAsAction(TQString& origFilename, TQString& fileExtension,
bool& dataIsEmpty)
364 if (
data().isEmpty()) {
365 kdWarning() <<
"KexiDBImageBox::handleAboutToSaveAs(): no pixmap!" << endl;
370 origFilename = m_data.originalFileName();
371 if (!origFilename.isEmpty())
372 origFilename = TQString(
"/") + origFilename;
373 if (!m_data.mimeType().isEmpty())
374 fileExtension = KImageIO::typeForMime(m_data.mimeType()).lower();
381 if (!f.open(IO_WriteOnly)) {
385 f.writeBlock(
data() );
386 if (f.status()!=IO_Ok) {
394void KexiDBImageBox::handleCutAction()
402void KexiDBImageBox::handleCopyAction()
404 tqApp->clipboard()->setPixmap(pixmap(), TQClipboard::Clipboard);
407void KexiDBImageBox::handlePasteAction()
409 if (
isReadOnly() || (!m_designMode && !hasFocus()))
411 TQPixmap pm( tqApp->clipboard()->pixmap(TQClipboard::Clipboard) );
422 TQBuffer buffer( ba );
423 buffer.open( IO_WriteOnly );
424 if (m_pixmap.save( &buffer,
"PNG" )) {
470void KexiDBImageBox::slotUpdateActionsAvailabilityRequested(
bool& valueIsNull,
bool& valueIsReadOnly)
473 (
dataSource().isEmpty() && !pixmap().isNull())
495void KexiDBImageBox::contextMenuEvent( TQContextMenuEvent * e )
498 m_popupMenu->exec( e->globalPos(), -1 );
564 TQToolTip::add(m_chooser, i18n(
"Click to show actions for this image box"));
566 TQString beautifiedImageBoxName;
574 beautifiedImageBoxName = beautifiedImageBoxName[0].upper() + beautifiedImageBoxName.mid(1);
576 TQToolTip::add(m_chooser, i18n(
"Click to show actions for \"%1\" image box").arg(beautifiedImageBoxName));
608 if (!m_lineWidthChanged) {
609 KexiFrame::setLineWidth( ds.isEmpty() ? 0 : 1 );
611 if (!m_paletteBackgroundColorChanged && parentWidget()) {
612 KexiFrame::setPaletteBackgroundColor(
613 dataSource().isEmpty() ? parentWidget()->paletteBackgroundColor() : palette().active().base() );
617TQSize KexiDBImageBox::sizeHint()
const
619 if (pixmap().isNull())
620 return TQSize(80, 80);
621 return pixmap().size();
626 if (frameShape()==TQFrame::Box && (frameShadow()==TQFrame::Sunken || frameShadow()==TQFrame::Raised))
632void KexiDBImageBox::paintEvent( TQPaintEvent *pe )
637 p.setClipRect(pe->rect());
639 TQColor bg(eraseColor());
640 if (m_designMode && pixmap().isNull()) {
641 TQPixmap pm(size()-TQSize(m, m));
644 p2.fillRect(0,0,width(),height(), bg);
648 const bool tooLarge = (height()-m-m) <= KexiDBImageBox_pm->height();
649 if (tooLarge || (width()-m-m) <= KexiDBImageBox_pm->width())
650 imagBoxPm = KexiDBImageBox_pmSmall;
652 imagBoxPm = KexiDBImageBox_pm;
653 TQImage img(imagBoxPm->convertToImage());
654 img = KImageEffect::flatten(img, bg.dark(150),
655 tqGray( bg.rgb() ) <= 20 ? TQColor(TQt::gray).dark(150) : bg.light(105));
658 converted.convertFromImage(img);
662 p2.drawPixmap(2, height()-m-m-imagBoxPm->height()-2, converted);
663 TQFont f(tqApp->font());
666 p2.drawText(pm.rect(), TQt::AlignCenter,
668 ? TQString::fromLatin1(name())+
"\n"+i18n(
"Unbound Image Box",
"(unbound)")
671 bitBlt(
this, m, m, &pm);
674 TQSize internalSize(size());
675 if (m_chooser && m_dropDownButtonVisible && !
dataSource().isEmpty())
676 internalSize.setWidth( internalSize.width() - m_chooser->width() );
679 p.fillRect(0,0,width(),height(), bg);
682 m_scaledContents, m_keepAspectRatio );
684 KexiFrame::drawFrame( &p );
687 if (!m_designMode && !
dataSource().isEmpty() && hasFocus() && (!m_chooser || !m_chooser->isVisible())) {
688 style().drawPrimitive(
689 TQStyle::PE_FocusRect, &p, style().subRect(TQStyle::SR_PushButtonContents,
this),
690 palette().active() );
704void KexiDBImageBox::updatePixmap()
706 if (! (m_designMode && pixmap().isNull()) )
709 if (!KexiDBImageBox_pm) {
710 TQString fname( locate(
"data", TQString(
"kexi/pics/imagebox.png")) );
711 KexiDBImageBox_pmDeleter.setObject( KexiDBImageBox_pm,
new TQPixmap(fname,
"PNG") );
712 TQImage img(KexiDBImageBox_pm->convertToImage());
713 KexiDBImageBox_pmSmallDeleter.setObject( KexiDBImageBox_pmSmall,
714 new TQPixmap( img.smoothScale(img.width()/2, img.height()/2, TQImage::ScaleMin) ) );
718void KexiDBImageBox::setAlignment(
int alignment)
720 m_alignment = alignment;
721 if (!m_scaledContents || m_keepAspectRatio)
729 m_insideSetData =
true;
732 m_insideSetData =
false;
736void KexiDBImageBox::resizeEvent( TQResizeEvent * e )
738 KexiFrame::resizeEvent(e);
740 TQSize s( m_chooser->sizeHint() );
742 s.setHeight( height() - 2*margin.height() );
743 s = s.boundedTo( size()-2*margin );
744 m_chooser->resize( s );
745 m_chooser->move( TQRect(TQPoint(0,0), e->size() - m_chooser->size() - margin + TQSize(1,1)).bottomRight() );
776 if (ke->state() == TQt::NoButton && ke->key() == TQt::Key_Escape) {
777 if (m_popupMenu->isVisible()) {
778 m_setFocusOnButtonAfterClosingPopup =
true;
789 m_lineWidthChanged =
true;
790 KexiFrame::setLineWidth(width);
795 KexiFrame::setPalette(pal);
796 if (m_insideSetPalette)
798 m_insideSetPalette =
true;
800 setPaletteForegroundColor(pal.active().foreground());
801 m_insideSetPalette =
false;
806 kexipluginsdbg <<
"KexiDBImageBox::setPaletteBackgroundColor(): " << TQString(color.name()) << endl;
807 m_paletteBackgroundColorChanged =
true;
808 KexiFrame::setPaletteBackgroundColor(color);
810 m_chooser->setPalette( tqApp->palette() );
815 return m_dropDownButtonVisible;
821 if (m_dropDownButtonVisible == set)
823 m_dropDownButtonVisible = set;
825 if (m_dropDownButtonVisible)
838bool KexiDBImageBox::eventFilter( TQObject * watched, TQEvent * e )
840 if (watched==
this || watched==m_chooser) {
841 if (e->type()==TQEvent::FocusIn || e->type()==TQEvent::FocusOut || e->type()==TQEvent::MouseButtonPress) {
846 if (watched==m_popupMenu && e->type()==TQEvent::FocusOut) {
849 return KexiFrame::eventFilter(watched, e);
855 return TQWidget::NoFocus;
870#include "kexidbimagebox.moc"
Object handle used by KexiBLOBBuffer.
Handle insertPixmap(const KURL &url)
static KexiBLOBBuffer * self()
Access to KexiBLOBBuffer singleton.
TQByteArray m_value
for db-aware mode
virtual bool valueIsEmpty()
virtual void setPalette(const TQPalette &pal)
TQWidget::FocusPolicy focusPolicy() const
int realLineWidth() const
TQWidget::FocusPolicy focusPolicyInternal() const
virtual bool isReadOnly() const
virtual bool cursorAtStart()
always true
int lineWidth() const
For overridden property.
virtual bool cursorAtEnd()
always true
TQString m_valueMimeType
for db-aware mode
virtual TQVariant value()
void updateActionStrings()
Updates i18n'd action strings after datasource change.
virtual TQWidget * widget()
void handleInsertFromFileAction(const KURL &url)
virtual bool subwidgetStretchRequired(KexiDBAutoField *autoField) const
Implemented for KexiSubwidgetInterface.
virtual void setInvalidState(const TQString &displayText)
void setDropDownButtonVisible(bool set)
virtual void setColumnInfo(KexiDB::QueryColumnInfo *cinfo)
void handleShowPropertiesAction()
virtual void setDataSource(const TQString &ds)
Sets the datasource to ds.
virtual void setValueInternal(const TQVariant &add, bool removeOld)
Sets value value for a widget.
virtual void setFocusPolicy(TQWidget::FocusPolicy policy)
virtual bool keyPressed(TQKeyEvent *ke)
void insertFromFile()
Forces execution of "insert from file" action.
bool popupMenuAvailable()
bool m_paintEventEnabled
used to disable paintEvent()
TQWidget::FocusPolicy m_focusPolicyInternal
Used for focusPolicyInternal().
virtual void setPaletteBackgroundColor(const TQColor &color)
Reimplemented to override behaviour of "paletteBackgroundColor" property.
virtual void setLineWidth(int width)
Reimplemented to override behaviour of "lineWidth" property.
void setScaledContents(bool set)
void handleSaveAsAction(const TQString &fileName)
bool dropDownButtonVisible() const
virtual bool valueIsNull()
Helper class that assigns additional information for the column in a query.
TQString captionOrAliasOrName() const
virtual void signalValueChanged()
Frame widget for Kexi forms.
KEXIUTILS_EXPORT void drawPixmap(TQPainter &p, int lineWidth, const TQRect &rect, const TQPixmap &pixmap, int alignment, bool scaledContents, bool keepAspectRatio)
KEXIUTILS_EXPORT TQColor contrastColor(const TQColor &c)