kexi

kexidbimagebox.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2005 Cedric Pasteur <cedric.pasteur@free.fr>
00003    Copyright (C) 2004-2006 Jaroslaw Staniek <js@iidea.pl>
00004 
00005    This program is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this program; see the file COPYING.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include "kexidbimagebox.h"
00022 
00023 #include <qapplication.h>
00024 #include <qpixmap.h>
00025 #include <qstyle.h>
00026 #include <qclipboard.h>
00027 #include <qtooltip.h>
00028 #include <qimage.h>
00029 #include <qbuffer.h>
00030 #include <qfiledialog.h>
00031 #include <qpainter.h>
00032 
00033 #include <kdebug.h>
00034 #include <kpopupmenu.h>
00035 #include <klocale.h>
00036 #include <kiconloader.h>
00037 #include <kfiledialog.h>
00038 #include <kimageio.h>
00039 #include <kstandarddirs.h>
00040 #include <kstaticdeleter.h>
00041 #include <kimageeffect.h>
00042 #include <kstdaccel.h>
00043 #include <kmessagebox.h>
00044 #include <kguiitem.h>
00045 
00046 #include <widget/utils/kexidropdownbutton.h>
00047 #include <kexiutils/utils.h>
00048 #include <kexidb/field.h>
00049 #include <kexidb/queryschema.h>
00050 #include <formeditor/widgetlibrary.h>
00051 
00052 #ifdef Q_WS_WIN
00053 #include <win32_utils.h>
00054 #include <krecentdirs.h>
00055 #endif
00056 
00057 #include "kexidbutils.h"
00058 #include "../kexiformpart.h"
00059 
00060 static KStaticDeleter<QPixmap> KexiDBImageBox_pmDeleter;
00061 static QPixmap* KexiDBImageBox_pm = 0;
00062 
00063 KexiDBImageBox::KexiDBImageBox( bool designMode, QWidget *parent, const char *name )
00064     : KexiFrame( parent, name, Qt::WNoAutoErase )
00065     , KexiFormDataItemInterface()
00066     , m_alignment(Qt::AlignAuto|Qt::AlignTop)
00067     , m_designMode(designMode)
00068     , m_readOnly(false)
00069     , m_scaledContents(false)
00070     , m_keepAspectRatio(true)
00071     , m_insideSetData(false)
00072     , m_setFocusOnButtonAfterClosingPopup(false)
00073     , m_lineWidthChanged(false)
00074     , m_paletteBackgroundColorChanged(false)
00075     , m_paintEventEnabled(true)
00076     , m_dropDownButtonVisible(true)
00077 {
00078     installEventFilter(this);
00079     setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
00080     setBackgroundMode(Qt::NoBackground);
00081     setFrameShape(QFrame::Box);
00082     setFrameShadow(QFrame::Plain);
00083     setFrameColor(Qt::black);
00084 
00085     //setup popup menu
00086     m_popupMenu = new KexiImageContextMenu(this);
00087 
00088     if (m_designMode) {
00089         m_chooser = 0;
00090     }
00091     else {
00092         m_chooser = new KexiDropDownButton(this);
00093         m_chooser->setFocusPolicy(StrongFocus);
00094         m_chooser->setPopup(m_popupMenu);
00095         setFocusProxy(m_chooser);
00096         m_chooser->installEventFilter(this);
00097 //      m_chooser->setPalette(qApp->palette());
00098 //      hlyr->addWidget(m_chooser);
00099     }
00100 
00101     connect(m_popupMenu, SIGNAL(updateActionsAvailabilityRequested(bool&, bool&)), 
00102         this, SLOT(slotUpdateActionsAvailabilityRequested(bool&, bool&)));
00103     connect(m_popupMenu, SIGNAL(insertFromFileRequested(const KURL&)),
00104         this, SLOT(handleInsertFromFileAction(const KURL&)));
00105     connect(m_popupMenu, SIGNAL(saveAsRequested(const QString&)),
00106         this, SLOT(handleSaveAsAction(const QString&)));
00107     connect(m_popupMenu, SIGNAL(cutRequested()),
00108         this, SLOT(handleCutAction()));
00109     connect(m_popupMenu, SIGNAL(copyRequested()),
00110         this, SLOT(handleCopyAction()));
00111     connect(m_popupMenu, SIGNAL(pasteRequested()),
00112         this, SLOT(handlePasteAction()));
00113     connect(m_popupMenu, SIGNAL(clearRequested()),
00114         this, SLOT(clear()));
00115     connect(m_popupMenu, SIGNAL(showPropertiesRequested()),
00116         this, SLOT(handleShowPropertiesAction()));
00117 
00118 //  connect(m_popupMenu, SIGNAL(aboutToHide()), this, SLOT(slotAboutToHidePopupMenu()));
00119 //  if (m_chooser) {
00120         //we couldn't use m_chooser->setPopup() because of drawing problems
00121 //      connect(m_chooser, SIGNAL(pressed()), this, SLOT(slotChooserPressed()));
00122 //      connect(m_chooser, SIGNAL(released()), this, SLOT(slotChooserReleased()));
00123 //      connect(m_chooser, SIGNAL(toggled(bool)), this, SLOT(slotToggled(bool)));
00124 //  }
00125 
00126     setDataSource( QString::null ); //to initialize popup menu and actions availability
00127 }
00128 
00129 KexiDBImageBox::~KexiDBImageBox()
00130 {
00131 }
00132 
00133 KexiImageContextMenu* KexiDBImageBox::contextMenu() const
00134 {
00135     return m_popupMenu;
00136 }
00137 
00138 QVariant KexiDBImageBox::value()
00139 {
00140     if (dataSource().isEmpty()) {
00141         //not db-aware
00142         return QVariant();
00143     }
00144     //db-aware mode
00145     return m_value; //todo
00146     //return QVariant(); //todo
00147 }
00148 
00149 void KexiDBImageBox::setValueInternal( const QVariant& add, bool removeOld, bool loadPixmap )
00150 {
00151     if (isReadOnly())
00152         return;
00153 //  const bool valueWasEmpty = m_value.isEmpty();
00154     if (removeOld) 
00155         m_value = add.toByteArray();
00156     else //do not add "m_origValue" to "add" as this is QByteArray
00157         m_value = m_origValue.toByteArray();
00158     bool ok = !m_value.isEmpty();
00159     if (ok) {
00162         ok = loadPixmap ? m_pixmap.loadFromData(m_value) : true; //, type.latin1());
00163         if (!ok) {
00165         }
00166     }
00167     if (!ok) {
00168         m_valueMimeType = QString::null;
00169         m_pixmap = QPixmap();
00170     }
00171     repaint();
00172 //  if (m_value.isEmpty() != valueWasEmpty)
00173 //      emit pixmapChanged();//valueChanged(m_value);
00174 }
00175 
00176 void KexiDBImageBox::setInvalidState( const QString& displayText )
00177 {
00178     Q_UNUSED( displayText );
00179 
00180 //  m_pixmapLabel->setPixmap(QPixmap());
00181     if (!dataSource().isEmpty()) {
00182         m_value = QByteArray();
00183     }
00184 //  m_pixmap = QPixmap();
00185 //  m_originalFileName = QString::null;
00186 
00188 
00189     if (m_chooser)
00190         m_chooser->hide();
00191     setReadOnly(true);
00192 }
00193 
00194 bool KexiDBImageBox::valueIsNull()
00195 {
00196     return m_value.isEmpty();
00197 //  return !m_pixmapLabel->pixmap() || m_pixmapLabel->pixmap()->isNull();
00198 }
00199 
00200 bool KexiDBImageBox::valueIsEmpty()
00201 {
00202     return false;
00203 }
00204 
00205 bool KexiDBImageBox::isReadOnly() const
00206 {
00207     return m_readOnly;
00208 }
00209 
00210 void KexiDBImageBox::setReadOnly(bool set)
00211 {
00212     m_readOnly = set;
00213 }
00214 
00215 QPixmap KexiDBImageBox::pixmap() const
00216 {
00217     if (dataSource().isEmpty()) {
00218         //not db-aware
00219         return m_data.pixmap();
00220     }
00221     //db-aware mode
00222     return m_pixmap;
00223 }
00224 
00225 uint KexiDBImageBox::pixmapId() const
00226 {
00227     if (dataSource().isEmpty()) {// && !m_data.stored()) {
00228         //not db-aware
00229         return m_data.id();
00230     }
00231     return 0;
00232 }
00233 
00234 void KexiDBImageBox::setPixmapId(uint id)
00235 {
00236     if (m_insideSetData) //avoid recursion
00237         return;
00238     setData(KexiBLOBBuffer::self()->objectForId( id, /*unstored*/false ));
00239     repaint();
00240 }
00241 
00242 uint KexiDBImageBox::storedPixmapId() const
00243 {
00244     if (dataSource().isEmpty() && m_data.stored()) {
00245         //not db-aware
00246         return m_data.id();
00247     }
00248     return 0;
00249 }
00250 
00251 void KexiDBImageBox::setStoredPixmapId(uint id)
00252 {
00253     setData(KexiBLOBBuffer::self()->objectForId( id, /*stored*/true ));
00254     repaint();
00255 }
00256 
00257 bool KexiDBImageBox::hasScaledContents() const
00258 {
00259     return m_scaledContents;
00260 //  return m_pixmapLabel->hasScaledContents();
00261 }
00262 
00263 /*void KexiDBImageBox::setPixmap(const QByteArray& pixmap)
00264 {
00265     setValueInternal(pixmap, true);
00266 //  setBackgroundMode(pixmap.isNull() ? Qt::NoBackground : Qt::PaletteBackground);
00267 }*/
00268 
00269 void KexiDBImageBox::setScaledContents(bool set)
00270 {
00271 //todo  m_pixmapLabel->setScaledContents(set);
00272     m_scaledContents = set;
00273     repaint();
00274 }
00275 
00276 void KexiDBImageBox::setKeepAspectRatio(bool set)
00277 {
00278     m_keepAspectRatio = set;
00279     if (m_scaledContents)
00280         repaint();
00281 }
00282 
00283 QWidget* KexiDBImageBox::widget()
00284 {
00286 //  return m_pixmapLabel;
00287     return this;
00288 }
00289 
00290 bool KexiDBImageBox::cursorAtStart()
00291 {
00292     return true;
00293 }
00294 
00295 bool KexiDBImageBox::cursorAtEnd()
00296 {
00297     return true;
00298 }
00299 
00300 QByteArray KexiDBImageBox::data() const
00301 {
00302     if (dataSource().isEmpty()) {
00303         //static mode
00304         return m_data.data();
00305     }
00306     else {
00307         //db-aware mode
00308         return m_value;
00309     }
00310 }
00311 
00312 void KexiDBImageBox::insertFromFile()
00313 {
00314     m_popupMenu->insertFromFile();
00315 }
00316 
00317 void KexiDBImageBox::handleInsertFromFileAction(const KURL& url)
00318 {
00319     if (!dataSource().isEmpty() && isReadOnly())
00320         return;
00321 
00322     if (dataSource().isEmpty()) {
00323         //static mode
00324         KexiBLOBBuffer::Handle h = KexiBLOBBuffer::self()->insertPixmap( url );
00325         if (!h)
00326             return;
00327         setData(h);
00328         repaint();
00329     }
00330     else {
00331         //db-aware
00332         QString fileName( url.isLocalFile() ? url.path() : url.prettyURL() );
00333 
00335         QFile f(fileName);
00336         if (!f.open(IO_ReadOnly)) {
00338             return;
00339         }
00340         QByteArray ba = f.readAll();
00341         if (f.status()!=IO_Ok) {
00343             f.close();
00344             return;
00345         }
00346         m_valueMimeType = KImageIO::mimeType( fileName ); 
00347         setValueInternal( ba, true );
00348     }
00349 
00351     if (!dataSource().isEmpty()) {
00352         signalValueChanged();
00353     }
00354 }
00355 
00356 void KexiDBImageBox::handleAboutToSaveAsAction(QString& origFilename, QString& fileExtension, bool& dataIsEmpty)
00357 {
00358     if (data().isEmpty()) {
00359         kdWarning() << "KexiDBImageBox::handleAboutToSaveAs(): no pixmap!" << endl;
00360         dataIsEmpty = false;
00361         return;
00362     }
00363     if (dataSource().isEmpty()) { //for static images filename and mimetype can be available
00364         origFilename = m_data.originalFileName();
00365         if (!origFilename.isEmpty())
00366             origFilename = QString("/") + origFilename;
00367         if (!m_data.mimeType().isEmpty())
00368             fileExtension = KImageIO::typeForMime(m_data.mimeType()).lower();
00369     }
00370 }
00371 
00372 void KexiDBImageBox::handleSaveAsAction(const QString& fileName)
00373 {
00374     QFile f(fileName);
00375     if (!f.open(IO_WriteOnly)) {
00377         return;
00378     }
00379     f.writeBlock( data() );
00380     if (f.status()!=IO_Ok) {
00382         f.close();
00383         return;
00384     }
00385     f.close();
00386 }
00387 
00388 void KexiDBImageBox::handleCutAction()
00389 {
00390     if (!dataSource().isEmpty() && isReadOnly())
00391         return;
00392     handleCopyAction();
00393     clear();
00394 }
00395 
00396 void KexiDBImageBox::handleCopyAction()
00397 {
00398     qApp->clipboard()->setPixmap(pixmap(), QClipboard::Clipboard);
00399 }
00400 
00401 void KexiDBImageBox::handlePasteAction()
00402 {
00403     if (isReadOnly() || (!m_designMode && !hasFocus()))
00404         return;
00405     QPixmap pm( qApp->clipboard()->pixmap(QClipboard::Clipboard) );
00406 //  if (!pm.isNull())
00407 //      setValueInternal(pm, true);
00408     if (dataSource().isEmpty()) {
00409         //static mode
00410         setData(KexiBLOBBuffer::self()->insertPixmap( pm ));
00411     }
00412     else {
00413         //db-aware mode
00414         m_pixmap = pm;
00415     QByteArray ba;
00416     QBuffer buffer( ba );
00417     buffer.open( IO_WriteOnly );
00418         if (m_pixmap.save( &buffer, "PNG" )) {// write pixmap into ba in PNG format
00419             setValueInternal( ba, true, false/* !loadPixmap */ );
00420         }
00421         else {
00422             setValueInternal( QByteArray(), true );
00423         }
00424     }
00425     
00426     repaint();
00427     if (!dataSource().isEmpty()) {
00428 //      emit pixmapChanged();
00429         signalValueChanged();
00430     }
00431 }
00432 
00433 void KexiDBImageBox::clear()
00434 {
00435     if (dataSource().isEmpty()) {
00436         //static mode
00437         setData(KexiBLOBBuffer::Handle());
00438     }
00439     else {
00440         if (isReadOnly())
00441             return;
00442         //db-aware mode
00443         setValueInternal(QByteArray(), true);
00444         //m_pixmap = QPixmap();
00445     }
00446 
00447 //  m_originalFileName = QString::null;
00448 
00450 
00451 //  m_pixmap = QPixmap(); //will be loaded on demand
00452     repaint();
00453     if (!dataSource().isEmpty()) {
00454 //      emit pixmapChanged();//valueChanged(data());
00455         signalValueChanged();
00456     }
00457 }
00458 
00459 void KexiDBImageBox::handleShowPropertiesAction()
00460 {
00462 }
00463 
00464 void KexiDBImageBox::slotUpdateActionsAvailabilityRequested(bool& valueIsNull, bool& valueIsReadOnly)
00465 {
00466     valueIsNull = !(
00467            (dataSource().isEmpty() && !pixmap().isNull()) /*static pixmap available*/
00468         || (!dataSource().isEmpty() && !this->valueIsNull())  /*db-aware pixmap available*/
00469     );
00470     // read-only if static pixmap or db-aware pixmap for read-only widget:
00471     valueIsReadOnly = !m_designMode && dataSource().isEmpty() || !dataSource().isEmpty() && isReadOnly()
00472         || m_designMode && !dataSource().isEmpty();
00473 }
00474 
00475 /*
00476 void KexiDBImageBox::slotAboutToHidePopupMenu()
00477 {
00478 //  kexipluginsdbg << "##### slotAboutToHidePopupMenu() " << endl;
00479     m_clickTimer.start(50, true);
00480     if (m_chooser && m_chooser->isOn()) {
00481         m_chooser->toggle();
00482         if (m_setFocusOnButtonAfterClosingPopup) {
00483             m_setFocusOnButtonAfterClosingPopup = false;
00484             m_chooser->setFocus();
00485         }
00486     }
00487 }*/
00488 
00489 void KexiDBImageBox::contextMenuEvent( QContextMenuEvent * e )
00490 {
00491     if (popupMenuAvailable())
00492         m_popupMenu->exec( e->globalPos(), -1 );
00493 }
00494 
00495 /*void KexiDBImageBox::slotChooserPressed()
00496 {
00497 //  if (!m_clickTimer.isActive())
00498 //      return;
00499 //  m_chooser->setDown( false );
00500 }
00501 
00502 void KexiDBImageBox::slotChooserReleased()
00503 {
00504 }
00505 
00506 void KexiDBImageBox::slotToggled(bool on)
00507 {
00508     return;
00509 
00510 //  kexipluginsdbg << "##### slotToggled() " << on << endl;
00511     if (m_clickTimer.isActive() || !on) {
00512         m_chooser->disableMousePress = true;
00513         return;
00514     }
00515     m_chooser->disableMousePress = false;
00516     QRect screen = qApp->desktop()->availableGeometry( m_chooser );
00517     QPoint p;
00518     if ( QApplication::reverseLayout() ) {
00519         if ( (mapToGlobal( m_chooser->rect().bottomLeft() ).y() + m_popupMenu->sizeHint().height()) <= screen.height() )
00520             p = m_chooser->mapToGlobal( m_chooser->rect().bottomRight() );
00521         else
00522             p = m_chooser->mapToGlobal( m_chooser->rect().topRight() - QPoint( 0, m_popupMenu->sizeHint().height() ) );
00523         p.rx() -= m_popupMenu->sizeHint().width();
00524     }
00525     else {
00526         if ( (m_chooser->mapToGlobal( m_chooser->rect().bottomLeft() ).y() + m_popupMenu->sizeHint().height()) <= screen.height() )
00527             p = m_chooser->mapToGlobal( m_chooser->rect().bottomLeft() );
00528         else
00529             p = m_chooser->mapToGlobal( m_chooser->rect().topLeft() - QPoint( 0, m_popupMenu->sizeHint().height() ) );
00530     }
00531     if (!m_popupMenu->isVisible() && on) {
00532         m_popupMenu->exec( p, -1 );
00533         m_popupMenu->setFocus();
00534     }
00535     //m_chooser->setDown( false );
00536 }*/
00537 
00538 void KexiDBImageBox::updateActionStrings()
00539 {
00540     if (!m_popupMenu)
00541         return;
00542     if (m_designMode) {
00543 /*      QString titleString( i18n("Image Box") );
00544         if (!dataSource().isEmpty())
00545             titleString.prepend(dataSource() + " : ");
00546         m_popupMenu->changeTitle(m_popupMenu->idAt(0), m_popupMenu->titlePixmap(m_popupMenu->idAt(0)), titleString);*/
00547     }
00548     else {
00549         //update title in data view mode, based on the data source
00550         if (columnInfo()) {
00551             KexiImageContextMenu::updateTitle( m_popupMenu, columnInfo()->captionOrAliasOrName(),
00552                 KexiFormPart::library()->iconName(className()) );
00553         }
00554     }
00555 
00556     if (m_chooser) {
00557         if (popupMenuAvailable() && dataSource().isEmpty()) { //this may work in the future (see @todo below)
00558             QToolTip::add(m_chooser, i18n("Click to show actions for this image box"));
00559         } else {
00560             QString beautifiedImageBoxName;
00561             if (m_designMode) {
00562                 beautifiedImageBoxName = dataSource();
00563             }
00564             else {
00565                 beautifiedImageBoxName = columnInfo() ? columnInfo()->captionOrAliasOrName() : QString::null;
00568                 beautifiedImageBoxName = beautifiedImageBoxName[0].upper() + beautifiedImageBoxName.mid(1);
00569             }
00570             QToolTip::add(m_chooser, i18n("Click to show actions for \"%1\" image box").arg(beautifiedImageBoxName));
00571         }
00572     }
00573 }
00574 
00575 bool KexiDBImageBox::popupMenuAvailable()
00576 {
00579     //chooser button can be only visible when data source is specified
00580     return !dataSource().isEmpty();
00581 }
00582 
00583 void KexiDBImageBox::setDataSource( const QString &ds )
00584 {
00585     KexiFormDataItemInterface::setDataSource( ds );
00586     setData(KexiBLOBBuffer::Handle());
00587     updateActionStrings();
00588     KexiFrame::setFocusPolicy( focusPolicy() ); //set modified policy
00589 
00590     if (m_chooser) {
00591         m_chooser->setEnabled(popupMenuAvailable());
00592         if (m_dropDownButtonVisible && popupMenuAvailable()) {
00593             m_chooser->show();
00594         }
00595         else {
00596             m_chooser->hide();
00597         }
00598     }
00599 
00600     // update some properties s not changed by user
00602     if (!m_lineWidthChanged) {
00603         KexiFrame::setLineWidth( ds.isEmpty() ? 0 : 1 );
00604     }
00605     if (!m_paletteBackgroundColorChanged && parentWidget()) {
00606         KexiFrame::setPaletteBackgroundColor( 
00607             dataSource().isEmpty() ? parentWidget()->paletteBackgroundColor() : palette().active().base() );
00608     }
00609 }
00610 
00611 QSize KexiDBImageBox::sizeHint() const
00612 {
00613     if (pixmap().isNull())
00614         return QSize(80, 80);
00615     return pixmap().size();
00616 }
00617 
00618 int KexiDBImageBox::realLineWidth() const
00619 {
00620     if (frameShape()==QFrame::Box && (frameShadow()==QFrame::Sunken || frameShadow()==QFrame::Raised))
00621         return 2 * lineWidth();
00622     else
00623         return lineWidth();
00624 }
00625 
00626 void KexiDBImageBox::paintEvent( QPaintEvent *pe )
00627 {
00628     if (!m_paintEventEnabled)
00629         return;
00630     QPainter p(this);
00631     p.setClipRect(pe->rect());
00632     const int m = realLineWidth();
00633     QColor bg(eraseColor());
00634     if (m_designMode && pixmap().isNull()) {
00635         QPixmap pm(size()-QSize(m, m));
00636         QPainter p2;
00637         p2.begin(&pm, this);
00638         p2.fillRect(0,0,width(),height(), bg);
00639 
00640         updatePixmap();
00641         QImage img(KexiDBImageBox_pm->convertToImage());
00642         img = KImageEffect::flatten(img, bg.dark(150),
00643             qGray( bg.rgb() ) <= 20 ? QColor(Qt::gray).dark(150) : bg.light(105));
00644 
00645         QPixmap converted;
00646         converted.convertFromImage(img);
00647         p2.drawPixmap(2, height()-m-m-KexiDBImageBox_pm->height()-2, converted);
00648         QFont f(qApp->font());
00649         p2.setFont(f);
00650         p2.setPen( KexiUtils::contrastColor( bg ) );
00651         ; 
00652 
00653         p2.drawText(pm.rect(), Qt::AlignCenter|Qt::WordBreak, 
00654             dataSource().isEmpty() 
00655                 ? QString::fromLatin1(name())+"\n"+i18n("Unbound Image Box", "(unbound)") //i18n("No Image")
00656                 : dataSource());
00657         p2.end();
00658         bitBlt(this, m, m, &pm);
00659     }
00660     else {
00661         QSize internalSize(size());
00662         if (m_chooser && m_dropDownButtonVisible && !dataSource().isEmpty())
00663             internalSize.setWidth( internalSize.width() - m_chooser->width() );
00664         
00665         //clearing needed here because we may need to draw a pixmap with transparency
00666         p.fillRect(0,0,width(),height(), bg);
00667 
00668         KexiUtils::drawPixmap( p, m, QRect(QPoint(0,0), internalSize), pixmap(), m_alignment, 
00669             m_scaledContents, m_keepAspectRatio );
00670     }
00671     KexiFrame::drawFrame( &p );
00672 
00673     // if the widget is focused, draw focus indicator rect _if_ there is no chooser button
00674     if (!m_designMode && !dataSource().isEmpty() && hasFocus() && (!m_chooser || !m_chooser->isVisible())) {
00675         style().drawPrimitive(
00676             QStyle::PE_FocusRect, &p, style().subRect(QStyle::SR_PushButtonContents, this), 
00677             palette().active() );
00678     }
00679 }
00680 
00681 /*      virtual void KexiDBImageBox::paletteChange ( const QPalette & oldPalette )
00682 {
00683     QFrame::paletteChange(oldPalette);
00684     if (oldPalette.active().background()!=palette().active().background()) {
00685         delete KexiDBImageBox_pm;
00686         KexiDBImageBox_pm = 0;
00687         repaint();
00688     }
00689 }*/
00690 
00691 void KexiDBImageBox::updatePixmap() {
00692     if (! (m_designMode && pixmap().isNull()) )
00693         return;
00694 
00695 //          if (KexiDBImageBox_pm) {
00696 //              QSize size = KexiDBImageBox_pm->size();
00697 //              if ((KexiDBImageBox_pm->width() > (width()/2) || KexiDBImageBox_pm->height() > (height()/2))) {
00698 //                  int maxSize = QMAX(width()/2, height()/2);
00699 //                  size = QSize(maxSize,maxSize);
00700 //                  delete KexiDBImageBox_pm;
00701 //                  KexiDBImageBox_pm = 0;
00702 //              }
00703 //          }
00704     if (!KexiDBImageBox_pm) {
00705         QString fname( locate("data", QString("kexi/pics/imagebox.png")) );
00706         KexiDBImageBox_pmDeleter.setObject( KexiDBImageBox_pm, new QPixmap(fname, "PNG") );
00707     }
00708 }
00709 
00710 void KexiDBImageBox::setAlignment(int alignment)
00711 {
00712     m_alignment = alignment;
00713     if (!m_scaledContents || m_keepAspectRatio)
00714         repaint();
00715 }
00716 
00717 void KexiDBImageBox::setData(const KexiBLOBBuffer::Handle& handle)
00718 {
00719     if (m_insideSetData) //avoid recursion
00720         return;
00721     m_insideSetData = true;
00722     m_data = handle;
00723     emit idChanged(handle.id());
00724     m_insideSetData = false;
00725     update();
00726 }
00727 
00728 void KexiDBImageBox::resizeEvent( QResizeEvent * e )
00729 {
00730     KexiFrame::resizeEvent(e);
00731     if (m_chooser) {
00732         QSize s( m_chooser->sizeHint() );
00733         QSize margin( realLineWidth(), realLineWidth() );
00734         s.setHeight( height() - 2*margin.height() );
00735         s = s.boundedTo( size()-2*margin );
00736         m_chooser->resize( s );
00737         m_chooser->move( QRect(QPoint(0,0), e->size() - m_chooser->size() - margin + QSize(1,1)).bottomRight() );
00738     }
00739 }
00740 
00741 /*
00742 bool KexiDBImageBox::setProperty( const char * name, const QVariant & value )
00743 {
00744     const bool ret = QLabel::setProperty(name, value);
00745     if (p_shadowEnabled) {
00746         if (0==qstrcmp("indent", name) || 0==qstrcmp("font", name) || 0==qstrcmp("margin", name)
00747             || 0==qstrcmp("frameShadow", name) || 0==qstrcmp("frameShape", name)
00748             || 0==qstrcmp("frameStyle", name) || 0==qstrcmp("midLineWidth", name)
00749             || 0==qstrcmp("lineWidth", name)) {
00750             p_privateLabel->setProperty(name, value);
00751             updatePixmap();
00752         }
00753     }
00754     return ret;
00755 }
00756 */
00757 
00758 void KexiDBImageBox::setColumnInfo(KexiDB::QueryColumnInfo* cinfo)
00759 {
00760     KexiFormDataItemInterface::setColumnInfo(cinfo);
00761     //updating strings and title is needed
00762     updateActionStrings();
00763 }
00764 
00765 bool KexiDBImageBox::keyPressed(QKeyEvent *ke)
00766 {
00767     // Esc key should close the popup
00768     if (ke->state() == Qt::NoButton && ke->key() == Qt::Key_Escape) {
00769         if (m_popupMenu->isVisible()) {
00770             m_setFocusOnButtonAfterClosingPopup = true;
00771             return true;
00772         }
00773     }
00774 //  else if (ke->state() == Qt::ControlButton && KStdAccel::shortcut(KStdAccel::Copy).keyCodeQt() == (ke->key()|Qt::CTRL)) {
00775 //  }
00776     return false;
00777 }
00778 
00779 void KexiDBImageBox::setLineWidth( int width )
00780 {
00781     m_lineWidthChanged = true;
00782     KexiFrame::setLineWidth(width);
00783 }
00784 
00785 void KexiDBImageBox::setPaletteBackgroundColor( const QColor & color )
00786 {
00787     m_paletteBackgroundColorChanged = true;
00788     KexiFrame::setPaletteBackgroundColor(color);
00789     if (m_chooser)
00790         m_chooser->setPalette( qApp->palette() );
00791 }
00792 
00793 bool KexiDBImageBox::dropDownButtonVisible() const
00794 {
00795     return m_dropDownButtonVisible;
00796 }
00797 
00798 void KexiDBImageBox::setDropDownButtonVisible( bool set )
00799 {
00801     if (m_dropDownButtonVisible == set)
00802         return;
00803     m_dropDownButtonVisible = set;
00804     if (m_chooser) {
00805         if (m_dropDownButtonVisible)
00806             m_chooser->show();
00807         else
00808             m_chooser->hide();
00809     }
00810 }
00811 
00812 bool KexiDBImageBox::subwidgetStretchRequired(KexiDBAutoField* autoField) const
00813 {
00814     Q_UNUSED(autoField);
00815     return true;
00816 }
00817 
00818 bool KexiDBImageBox::eventFilter( QObject * watched, QEvent * e )
00819 {
00820     if (watched==this || watched==m_chooser) { //we're watching chooser as well because it's a focus proxy even if invisible
00821         if (e->type()==QEvent::FocusIn || e->type()==QEvent::FocusOut || e->type()==QEvent::MouseButtonPress) {
00822             update(); //to repaint focus rect
00823         }
00824     }
00825     return KexiFrame::eventFilter(watched, e);
00826 }
00827 
00828 QWidget::FocusPolicy KexiDBImageBox::focusPolicy() const
00829 {
00830     if (dataSource().isEmpty())
00831         return NoFocus;
00832     return m_focusPolicyInternal;
00833 }
00834 
00835 QWidget::FocusPolicy KexiDBImageBox::focusPolicyInternal() const
00836 {
00837     return m_focusPolicyInternal;
00838 }
00839 
00840 void KexiDBImageBox::setFocusPolicy( FocusPolicy policy )
00841 {
00842     m_focusPolicyInternal = policy;
00843     KexiFrame::setFocusPolicy( focusPolicy() ); //set modified policy
00844 }
00845 
00846 #include "kexidbimagebox.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys