kexi

kexiblobtableedit.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2002   Peter Simonsson <psn@linux.se>
00003    Copyright (C) 2004 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 "kexiblobtableedit.h"
00022 
00023 #include <stdlib.h>
00024 
00025 #include <qdatastream.h>
00026 #include <qfile.h>
00027 #include <qpopupmenu.h>
00028 #include <qtextedit.h>
00029 #include <qlayout.h>
00030 #include <qstatusbar.h>
00031 #include <qlabel.h>
00032 #include <qpixmap.h>
00033 #include <qimage.h>
00034 #include <qpainter.h>
00035 
00036 #include <kdebug.h>
00037 #include <ktempfile.h>
00038 #include <kmimetype.h>
00039 #include <kmimemagic.h>
00040 #include <kuserprofile.h>
00041 #include <kservice.h>
00042 #include <kprocess.h>
00043 #include <kopenwith.h>
00044 #include <kurl.h>
00045 #include <karrowbutton.h>
00046 #include <klocale.h>
00047 #include <kfiledialog.h>
00048 #include <kio/job.h>
00049 #include <kglobal.h>
00050 #include <kiconloader.h>
00051 
00052 
00053 //KexiBlobTableEdit::KexiBlobTableEdit(KexiDB::Field &f, QScrollView *parent)
00054 KexiBlobTableEdit::KexiBlobTableEdit(KexiTableViewColumn &column, QScrollView *parent)
00055  : KexiTableEdit(column, parent,"KexiBlobTableEdit")
00056 {
00057     m_proc = 0;
00058     m_content = 0;
00059 }
00060 
00061 KexiBlobTableEdit::~KexiBlobTableEdit()
00062 {
00063     kdDebug() << "KexiBlobTableEdit: Cleaning up..." << endl;
00064     if (m_tempFile) {
00065         m_tempFile->unlink();
00066         //todo
00067     }
00068     delete m_proc;
00069     m_proc = 0;
00070     kdDebug() << "KexiBlobTableEdit: Ready." << endl;
00071 }
00072 
00074 void KexiBlobTableEdit::setValueInternal(const QVariant& /*add*/, bool /*removeOld*/)
00075 {
00076     QByteArray val = m_origValue.toByteArray();
00077     kdDebug() << "KexiBlobTableEdit: Size of BLOB: " << val.size() << endl;
00078     m_tempFile = new KTempFile();
00079     m_tempFile->setAutoDelete(true);
00080     kdDebug() << "KexiBlobTableEdit: Creating temporary file: " << m_tempFile->name() << endl;
00081     m_tempFile->dataStream()->writeRawBytes(val.data(), val.size());
00082     m_tempFile->close();
00083     delete m_tempFile;
00084     m_tempFile = 0;
00085 
00086     KMimeMagicResult* mmr = KMimeMagic::self()->findFileType(m_tempFile->name());
00087     kdDebug() << "KexiBlobTableEdit: Mimetype = " << mmr->mimeType() << endl;
00088 
00089     setViewWidget( new QWidget(this) );
00090 /*js: TODO
00091     QGridLayout *g = new QGridLayout(m_view);
00092 
00093     if(mmr->mimeType().contains("text/") || val.size() == 0)
00094     {
00095         m_content = new QTextEdit(m_view);
00096         m_content->setTextFormat(PlainText);
00097         m_content->setText(QString(val));
00098         g->addWidget(m_content, 0, 0);
00099     }
00100     else
00101     {
00102         QLabel *l = new QLabel("", this);
00103 //      g->addMultiCellWidget(l, 0, 1, 0, 1);
00104         g->addMultiCellWidget(l, 0, 2, 0, 1);
00105         if(mmr->mimeType().contains("image/"))
00106         {
00107             //sale the image to the maximal allowed size by optaining the aspect ratio
00108             QImage pix(m_tempFile->name());
00109             pix = pix.smoothScale(m_view->width(), l->height(), QImage::ScaleMin);
00110 
00111             l->setScaledContents(true);
00112             l->setPixmap(QPixmap(pix));
00113         }
00114         else
00115         {
00116             l->setPixmap(KMimeType::pixmapForURL(KURL(m_tempFile->name())));
00117         }
00118 
00119 //      QLabel *l = new QLabel(this);
00120         QLabel *lsize = new QLabel(i18n("Size:"), this);
00121         QLabel *size = new QLabel(QString::number(val.size()) + " bytes", this);
00122         g->addMultiCellWidget(lsize, 2, 2, 0, 0);
00123         g->addMultiCellWidget(size, 2, 2, 1, 1);
00124     }
00125 
00126     KArrowButton *menu = new KArrowButton(m_view, Qt::DownArrow, "Menu button");
00127     g->addWidget(menu, 3, 0);
00128     connect(menu, SIGNAL(clicked()), SLOT(menu()));
00129 */
00130 }
00131 
00132 bool KexiBlobTableEdit::valueIsNull()
00133 {
00134 //TODO
00135     return m_content->text().isNull();
00136 }
00137 
00138 bool KexiBlobTableEdit::valueIsEmpty()
00139 {
00140 //TODO
00141     return m_content->text().isEmpty();
00142 }
00143 
00144 QVariant
00145 KexiBlobTableEdit::value()
00146 {
00147     //todo
00148 //  ok = true;
00149 
00150     if(m_content && m_content->isModified())
00151     {
00152         return QVariant(m_content->text());
00153     }
00154     QByteArray value;
00155     QFile f( m_tempFile->name() );
00156     f.open(IO_ReadOnly);
00157     QDataStream stream(&f);
00158     char* data = (char*) malloc(f.size());
00159     value.resize(f.size());
00160     stream.readRawBytes(data, f.size());
00161     value.duplicate(data, f.size());
00162     free(data);
00163     kdDebug() << "KexiBlobTableEdit: Size of BLOB: " << value.size() << endl;
00164     return QVariant(value);
00165 }
00166 
00167 void
00168 KexiBlobTableEdit::slotFinished(KProcess* /*p*/)
00169 {
00170     kdDebug() << "Prorgam is finished!" << endl;
00171 
00172 
00173     // No need for m_proc now that the app has exited
00174     delete m_proc;
00175     m_proc = 0;
00176 }
00177 
00178 QString
00179 KexiBlobTableEdit::openWithDlg(const QString& file)
00180 {
00181     KURL::List ul;
00182     KURL url;
00183     url.setPath(file);
00184     ul.append(url);
00185     QString exec = QString::null;
00186 
00187     KOpenWithDlg* dlg = new KOpenWithDlg(ul, this);
00188 
00189     if(dlg->exec() == QDialog::Accepted)
00190     {
00191         exec = dlg->text().section(' ', 0, 0);
00192     }
00193 
00194     delete dlg;
00195     dlg = 0;
00196 
00197     return exec;
00198 }
00199 
00200 void
00201 KexiBlobTableEdit::execute(const QString& app, const QString& file)
00202 {
00203     kdDebug() << "KexiBlobTableEdit: App = " << app << "File = " << file << endl;
00204 
00205     // only execute if there isn't any other app already running
00206     if(!m_proc)
00207     {
00208         m_proc = new KProcess();
00209         *m_proc << app;
00210         *m_proc << file;
00211         connect(m_proc, SIGNAL(processExited(KProcess *)), SLOT(slotFinished(KProcess *)));
00212         m_proc->start();
00213     }
00214 }
00215 
00216 void
00217 KexiBlobTableEdit::open()
00218 {
00219     KMimeMagicResult* mmr = KMimeMagic::self()->findFileType(m_tempFile->name());
00220     kdDebug() << "KexiBlobTableEdit: Mimetype = " << mmr->mimeType() << endl;
00221     KService::Ptr ptr = KServiceTypeProfile::preferredService(mmr->mimeType(), "Application");
00222     QString exec;
00223 
00224     if(!ptr.data())
00225     {
00226         exec = openWithDlg(m_tempFile->name());
00227     }
00228     else
00229     {
00230         exec = ptr->exec().section(' ', 0, 0);
00231     }
00232 
00233     if(!exec.isEmpty())
00234     {
00235         execute(exec, m_tempFile->name());
00236     }
00237 }
00238 
00239 void
00240 KexiBlobTableEdit::openWith()
00241 {
00242     QString exec = openWithDlg(m_tempFile->name());
00243 
00244     if(!exec.isEmpty())
00245     {
00246         execute(exec, m_tempFile->name());
00247     }
00248 }
00249 
00250 void
00251 KexiBlobTableEdit::menu()
00252 {
00253     QPopupMenu* menu = new QPopupMenu(this, "BLOB Menu");
00254 
00255     menu->insertItem(i18n("Open"), this, SLOT(open()));
00256     menu->insertItem(i18n("Open With..."), this, SLOT(openWith()));
00257     menu->insertSeparator();
00258     menu->insertItem(i18n("Load From File..."), this, SLOT(loadFile()));
00259     menu->insertItem(i18n("Save to File..."), this, SLOT(saveFile()));
00260 
00261     QPoint pos = mapToGlobal(widget()->pos());
00262     pos.setY(pos.y() + widget()->height());
00263     menu->move(pos);
00264     menu->exec();
00265 
00266     delete menu;
00267     menu = 0;
00268 }
00269 
00270 void
00271 KexiBlobTableEdit::loadFile()
00272 {
00273     QString file = KFileDialog::getOpenFileName();
00274 
00275     if(!file.isEmpty())
00276     {
00277         /*KIO::FileCopyJob* job =*/(void) KIO::file_copy(KURL(file), KURL(m_tempFile->name()), -1, true);
00278     }
00279 }
00280 
00281 void
00282 KexiBlobTableEdit::saveFile()
00283 {
00284     QString file = KFileDialog::getSaveFileName();
00285 
00286     if(!file.isEmpty())
00287     {
00288         /*KIO::FileCopyJob* job =*/ (void)KIO::file_copy(KURL(m_tempFile->name()), KURL(file), -1, true);
00289     }
00290 }
00291 
00292 bool KexiBlobTableEdit::cursorAtStart()
00293 {
00294     //TODO?
00295     return false;
00296 }
00297 
00298 bool KexiBlobTableEdit::cursorAtEnd()
00299 {
00300     //TODO?
00301     return false;
00302 }
00303 
00304 void KexiBlobTableEdit::clear()
00305 {
00306     //TODO??
00307 }
00308 
00309 //======================================================
00310 
00311 KexiBlobEditorFactoryItem::KexiBlobEditorFactoryItem()
00312 {
00313 }
00314 
00315 KexiBlobEditorFactoryItem::~KexiBlobEditorFactoryItem()
00316 {
00317 }
00318 
00319 KexiTableEdit* KexiBlobEditorFactoryItem::createEditor(
00320     KexiTableViewColumn & /*column*/, QScrollView* /*parent*/)
00321 {
00323 //DISABLED
00324 //  return new KexiBlobTableEdit(f, parent);
00325     return 0;
00326 }
00327 
00328 
00329 //=======================
00330 //This class is temporarily here:
00331 
00332 
00333 KexiKIconTableEdit::KexiKIconTableEdit(KexiTableViewColumn &column, QScrollView *parent)
00334  : KexiTableEdit(column, parent, "KexiKIconTableEdit")
00335  , m_pixmapCache(17, 17, false)
00336 {
00337     init();
00338 }
00339 
00340 KexiKIconTableEdit::~KexiKIconTableEdit()
00341 {
00342 }
00343 
00344 void KexiKIconTableEdit::init()
00345 {
00346     m_hasFocusableWidget = false;
00347     m_pixmapCache.setAutoDelete(true);
00348 }
00349     
00350 void KexiKIconTableEdit::setValueInternal(const QVariant& /*add*/, bool /*removeOld*/)
00351 {
00352     m_currentValue = m_origValue;
00353 }
00354 
00355 bool KexiKIconTableEdit::valueIsNull()
00356 {
00357     return m_currentValue.isNull();
00358 }
00359 
00360 bool KexiKIconTableEdit::valueIsEmpty()
00361 {
00362     return m_currentValue.isNull();
00363 }
00364 
00365 QVariant KexiKIconTableEdit::value()
00366 {
00367     return m_currentValue;
00368 }
00369 
00370 void KexiKIconTableEdit::clear()
00371 {
00372     m_currentValue = QVariant();
00373 }
00374 
00375 bool KexiKIconTableEdit::cursorAtStart()
00376 {
00377     return true;
00378 }
00379 
00380 bool KexiKIconTableEdit::cursorAtEnd()
00381 {
00382     return true;
00383 }
00384 
00385 void KexiKIconTableEdit::setupContents( QPainter *p, bool /*focused*/, QVariant val, 
00386     QString &/*txt*/, int &/*align*/, int &/*x*/, int &y_offset, int &w, int &h  )
00387 {
00388     Q_UNUSED( y_offset );
00389 
00390 #if 0
00391 #ifdef Q_WS_WIN
00392     y_offset = -1;
00393 #else
00394     y_offset = 0;
00395 #endif
00396     int s = QMAX(h - 5, 12);
00397     s = QMIN( h-3, s );
00398     s = QMIN( w-3, s );//avoid too large box
00399     QRect r( QMAX( w/2 - s/2, 0 ) , h/2 - s/2 /*- 1*/, s, s);
00400     p->setPen(QPen(colorGroup().text(), 1));
00401     p->drawRect(r);
00402     if (val.asBool()) {
00403         p->drawLine(r.x(), r.y(), r.right(), r.bottom());
00404         p->drawLine(r.x(), r.bottom(), r.right(), r.y());
00405     }
00406 #endif
00407 
00408     QString key = val.toString();
00409     QPixmap *pix = 0;
00410     if (!key.isEmpty() && !(pix = m_pixmapCache[ key ])) {
00411         //cache pixmap
00412         QPixmap p = KGlobal::iconLoader()->loadIcon( key, KIcon::Small, 
00413             0, KIcon::DefaultState, 0L, true/*canReturnNull*/ );
00414         if (!p.isNull()) {
00415             pix = new QPixmap(p);
00416             m_pixmapCache.insert(key, pix);
00417         }
00418     }
00419 
00420     if (pix) {
00421         p->drawPixmap( (w-pix->width())/2, (h-pix->height())/2, *pix );
00422     }
00423 }
00424 
00425 KEXI_CELLEDITOR_FACTORY_ITEM_IMPL(KexiKIconTableEditorFactoryItem, KexiKIconTableEdit)
00426 
00427 #include "kexiblobtableedit.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys