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