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         QImage img(m_scaledPixmap.convertToImage());
00137         img = img.smoothScale(r.size()+QSize(0,2), QImage::ScaleMin);
00138         m_scaledPixmap.convertFromImage(img);
00139     }
00140     p->drawPixmap(r.topLeft().x(), //+KPROPEDITOR_ITEM_MARGIN,
00141         r.topLeft().y()+(r.height()-m_scaledPixmap.height())/2+1, m_scaledPixmap);
00142 }
00143 
00144 QString
00145 PixmapEdit::selectPixmapFileName()
00146 {
00147 /*#ifdef PURE_QT
00148     QString url = QFileDialog::getOpenFileName();
00149     if (!url.isEmpty()) {
00150         m_edit->setPixmap(QPixmap(url));
00151         emit valueChanged(this);
00152     }
00153 #endif*/
00154     QString caption( i18n("Insert Image From File (for \"%1\" property)").arg(property()->caption()) );
00155 #ifdef Q_WS_WIN
00156     QString recentDir;
00157     QString fileName = QFileDialog::getOpenFileName(
00158         KFileDialog::getStartURL(":lastVisitedImagePath", recentDir).path(), 
00159         convertKFileDialogFilterToQFileDialogFilter(KImageIO::pattern(KImageIO::Reading)), 
00160         this, 0, caption);
00161 #else
00162     KURL url( KFileDialog::getImageOpenURL(
00163         ":lastVisitedImagePath", this, caption) );
00164     QString fileName = url.isLocalFile() ? url.path() : url.prettyURL();
00165 
00167 #endif
00168     return fileName;
00169 }
00170 
00171 void
00172 PixmapEdit::selectPixmap()
00173 {
00174     QString fileName( selectPixmapFileName() );
00175     if (fileName.isEmpty())
00176         return;
00177 
00178     QPixmap pm;
00179     if (!pm.load(fileName)) {
00181         return;
00182     }
00183     setValue(pm);
00184 
00185 #ifdef Q_WS_WIN
00186     //save last visited path
00187     KURL url(fileName);
00188     if (url.isLocalFile())
00189         KRecentDirs::add(":lastVisitedImagePath", url.directory());
00190 #endif
00191 }
00192 
00193 void
00194 PixmapEdit::resizeEvent(QResizeEvent *e)
00195 {
00196     Widget::resizeEvent(e);
00197     m_edit->move(0,0);
00198     m_edit->resize(e->size()-QSize(m_button->width(),-1));
00199     m_button->move(m_edit->width(),0);
00200     m_button->setFixedSize(m_button->width(), height());
00201 }
00202 
00203 bool
00204 PixmapEdit::eventFilter(QObject *o, QEvent *ev)
00205 {
00206     if(o == m_edit) {
00207         if(ev->type() == QEvent::MouseButtonPress && static_cast<QMouseEvent*>(ev)->button()==LeftButton) {
00208             if(m_previewPixmap.height() <= m_edit->height()
00209                 && m_previewPixmap.width() <= m_edit->width())
00210                 return false;
00211 
00212             m_popup->setPixmap(m_previewPixmap.isNull() ? m_pixmap : m_previewPixmap);
00213             m_popup->resize(m_previewPixmap.size()+QSize(2*3,2*3));
00214             QPoint pos = QCursor::pos()+QPoint(3,15);
00215             QRect screenRect = QApplication::desktop()->availableGeometry( this );
00216             if ((pos.x()+m_popup->width()) > screenRect.width())
00217                 pos.setX(screenRect.width()-m_popup->width());
00218             if ((pos.y()+m_popup->height()) > screenRect.height())
00219                 pos.setY(mapToGlobal(QPoint(0,0)).y()-m_popup->height());
00220             m_popup->move(pos);
00221             m_popup->show();
00222         }
00223         else if(ev->type() == QEvent::MouseButtonRelease || ev->type() == QEvent::Hide) {
00224             if(m_popup->isVisible())
00225                 m_popup->hide();
00226         }
00227         else if(ev->type() == QEvent::KeyPress) {
00228             QKeyEvent* e = static_cast<QKeyEvent*>(ev);
00229             if((e->key() == Key_Enter) || (e->key()== Key_Space) || (e->key() == Key_Return)) {
00230                 m_button->animateClick();
00231                 return true;
00232             }
00233         }
00234     }
00235 
00236     return Widget::eventFilter(o, ev);
00237 }
00238 
00239 void
00240 PixmapEdit::setReadOnlyInternal(bool readOnly)
00241 {
00242     m_button->setEnabled(!readOnly);
00243 }
00244 
00245 #include "pixmapedit.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys