lib

pixmapedit.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr>
00003    Copyright (C) 2004 Alexander Dymo <cloudtemple@mskat.net>
00004    Copyright (C) 2005 Jaroslaw Staniek <js@iidea.pl>
00005 
00006    This library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Library General Public
00008    License as published by the Free Software Foundation; either
00009    version 2 of the License, or (at your option) any later version.
00010 
00011    This library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Library General Public License for more details.
00015 
00016    You should have received a copy of the GNU Library General Public License
00017    along with this library; see the file COPYING.LIB.  If not, write to
00018    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019  * Boston, MA 02110-1301, USA.
00020 */
00021 
00022 #include "pixmapedit.h"
00023 #include "editoritem.h"
00024 #include "property.h"
00025 
00026 #include <qlayout.h>
00027 #include <qpainter.h>
00028 #include <qlabel.h>
00029 #include <qcursor.h>
00030 #include <qpushbutton.h>
00031 #include <qfont.h>
00032 #include <qfontmetrics.h>
00033 #include <qimage.h>
00034 #include <qfiledialog.h>
00035 #include <qtooltip.h>
00036 #include <qapplication.h>
00037 
00038 #include <kdebug.h>
00039 #include <kimageio.h>
00040 
00041 #ifdef Q_WS_WIN
00042 #include <win32_utils.h>
00043 #include <krecentdirs.h>
00044 #endif
00045 
00046 #ifndef PURE_QT
00047 #include <kfiledialog.h>
00048 #include <klocale.h>
00049 #include <kfiledialog.h>
00050 #endif
00051 
00052 using namespace KoProperty;
00053 
00054 PixmapEdit::PixmapEdit(Property *property, QWidget *parent, const char *name)
00055  : Widget(property, parent, name)
00056 {
00057     setHasBorders(false);
00058 
00059     m_edit = new QLabel(this, "m_edit");
00060     QToolTip::add(m_edit, i18n("Click to show image preview"));
00061     m_edit->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
00062     m_edit->setMinimumHeight(5);
00063     m_edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
00064     m_edit->setBackgroundMode(Qt::PaletteBase);
00065     m_edit->setMouseTracking(true);
00066     setBackgroundMode(Qt::PaletteBase);
00067 
00068     m_button = new QPushButton(i18n("..."), this, "m_button");
00069     QToolTip::add(m_button, i18n("Insert image from file"));
00070     m_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
00071     QFontMetrics fm(m_button->font());
00072     m_button->setFixedWidth(fm.width(m_button->text()+' '));
00073     m_button->setFocusPolicy(NoFocus);
00074 
00075     m_popup = new QLabel(0, "m_popup", Qt::WStyle_Customize|Qt::WStyle_NoBorder|Qt::WX11BypassWM|WStyle_StaysOnTop);
00076     m_popup->setPaletteBackgroundColor(m_popup->palette().active().base());
00077     m_popup->setFrameStyle(QFrame::Plain|QFrame::Box);
00078     m_popup->setMargin(2);
00079     m_popup->setLineWidth(1);
00080     m_popup->hide();
00081 
00082     setFocusWidget(m_edit);
00083     connect(m_button, SIGNAL(clicked()), this, SLOT(selectPixmap()));
00084 }
00085 
00086 PixmapEdit::~PixmapEdit()
00087 {
00088     delete m_popup;
00089 }
00090 
00091 QVariant
00092 PixmapEdit::value() const
00093 {
00094     return m_pixmap;
00095 }
00096 
00097 void
00098 PixmapEdit::setValue(const QVariant &value, bool emitChange)
00099 {
00100     m_pixmap = value.toPixmap();
00101     if (m_pixmap.isNull() || (m_pixmap.height()<=height())) {
00102         m_edit->setPixmap(m_pixmap);
00103         m_previewPixmap = m_pixmap;
00104     }
00105     else {
00106         QImage img(m_pixmap.convertToImage());
00107         if (!QRect(QPoint(0,0), m_edit->size()*3).contains(m_pixmap.rect())) {
00108             img = img.smoothScale(m_edit->size()*3, QImage::ScaleMin);
00109             m_previewPixmap.convertFromImage(img);//preview pixmap is a bit larger
00110         }
00111         else {
00112             m_previewPixmap = m_pixmap;
00113         }
00114         img = img.smoothScale(m_edit->size(), QImage::ScaleMin);
00115         QPixmap pm;
00116         pm.convertFromImage(img);
00117         m_edit->setPixmap(pm);
00118     }
00119     if (emitChange)
00120         emit valueChanged(this);
00121 }
00122 
00123 void
00124 PixmapEdit::drawViewer(QPainter *p, const QColorGroup &, const QRect &r, const QVariant &value)
00125 {
00126     QRect r2(r);
00127     r2.setHeight(r2.height()+1);
00128     p->setClipRect(r2, QPainter::CoordPainter);
00129     p->setClipping(true);
00130     p->eraseRect(r2);
00131     if (value.toPixmap().isNull())
00132         return;
00133     if (m_recentlyPainted!=value) {
00134         m_recentlyPainted = value;
00135         m_scaledPixmap = value.toPixmap();
00136         if (m_scaledPixmap.height() > r2.height() || m_scaledPixmap.width() > r2.width()) { //scale down
00137             QImage img(m_scaledPixmap.convertToImage());
00138             img = img.smoothScale(r2.size()/*+QSize(0,2)*/, QImage::ScaleMin);
00139             m_scaledPixmap.convertFromImage(img);
00140         }
00141     }
00142     p->drawPixmap(r2.topLeft().x(), //+KPROPEDITOR_ITEM_MARGIN,
00143         r2.topLeft().y()+(r2.height()-m_scaledPixmap.height())/2, m_scaledPixmap);
00144 }
00145 
00146 QString
00147 PixmapEdit::selectPixmapFileName()
00148 {
00149 /*#ifdef PURE_QT
00150     QString url = QFileDialog::getOpenFileName();
00151     if (!url.isEmpty()) {
00152         m_edit->setPixmap(QPixmap(url));
00153         emit valueChanged(this);
00154     }
00155 #endif*/
00156     QString caption( i18n("Insert Image From File (for \"%1\" property)").arg(property()->caption()) );
00157 #ifdef Q_WS_WIN
00158     QString recentDir;
00159     QString fileName = QFileDialog::getOpenFileName(
00160         KFileDialog::getStartURL(":lastVisitedImagePath", recentDir).path(), 
00161         convertKFileDialogFilterToQFileDialogFilter(KImageIO::pattern(KImageIO::Reading)), 
00162         this, 0, caption);
00163 #else
00164     KURL url( KFileDialog::getImageOpenURL(
00165         ":lastVisitedImagePath", this, caption) );
00166     QString fileName = url.isLocalFile() ? url.path() : url.prettyURL();
00167 
00169 #endif
00170     return fileName;
00171 }
00172 
00173 void
00174 PixmapEdit::selectPixmap()
00175 {
00176     QString fileName( selectPixmapFileName() );
00177     if (fileName.isEmpty())
00178         return;
00179 
00180     QPixmap pm;
00181     if (!pm.load(fileName)) {
00183         return;
00184     }
00185     setValue(pm);
00186 
00187 #ifdef Q_WS_WIN
00188     //save last visited path
00189     KURL url(fileName);
00190     if (url.isLocalFile())
00191         KRecentDirs::add(":lastVisitedImagePath", url.directory());
00192 #endif
00193 }
00194 
00195 void
00196 PixmapEdit::resizeEvent(QResizeEvent *e)
00197 {
00198     Widget::resizeEvent(e);
00199     m_edit->move(0,0);
00200     m_edit->resize(e->size()-QSize(m_button->width(),-1));
00201     m_button->move(m_edit->width(),0);
00202     m_button->setFixedSize(m_button->width(), height());
00203 }
00204 
00205 bool
00206 PixmapEdit::eventFilter(QObject *o, QEvent *ev)
00207 {
00208     if(o == m_edit) {
00209         if(ev->type() == QEvent::MouseButtonPress && static_cast<QMouseEvent*>(ev)->button()==LeftButton) {
00210             if(m_previewPixmap.height() <= m_edit->height()
00211                 && m_previewPixmap.width() <= m_edit->width())
00212                 return false;
00213 
00214             m_popup->setPixmap(m_previewPixmap.isNull() ? m_pixmap : m_previewPixmap);
00215             m_popup->resize(m_previewPixmap.size()+QSize(2*3,2*3));
00216             QPoint pos = QCursor::pos()+QPoint(3,15);
00217             QRect screenRect = QApplication::desktop()->availableGeometry( this );
00218             if ((pos.x()+m_popup->width()) > screenRect.width())
00219                 pos.setX(screenRect.width()-m_popup->width());
00220             if ((pos.y()+m_popup->height()) > screenRect.height())
00221                 pos.setY(mapToGlobal(QPoint(0,0)).y()-m_popup->height());
00222             m_popup->move(pos);
00223             m_popup->show();
00224         }
00225         else if(ev->type() == QEvent::MouseButtonRelease || ev->type() == QEvent::Hide) {
00226             if(m_popup->isVisible())
00227                 m_popup->hide();
00228         }
00229         else if(ev->type() == QEvent::KeyPress) {
00230             QKeyEvent* e = static_cast<QKeyEvent*>(ev);
00231             if((e->key() == Key_Enter) || (e->key()== Key_Space) || (e->key() == Key_Return)) {
00232                 m_button->animateClick();
00233                 return true;
00234             }
00235         }
00236     }
00237 
00238     return Widget::eventFilter(o, ev);
00239 }
00240 
00241 void
00242 PixmapEdit::setReadOnlyInternal(bool readOnly)
00243 {
00244     m_button->setEnabled(!readOnly);
00245 }
00246 
00247 #include "pixmapedit.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys