21#include "kexiblobtableedit.h"
25#include <tqdatastream.h>
27#include <tqpopupmenu.h>
28#include <tqtextedit.h>
30#include <tqstatusbar.h>
36#include <tqapplication.h>
37#include <tqclipboard.h>
41#include <tdetempfile.h>
43#include <kmimemagic.h>
44#include <kuserprofile.h>
49#include <karrowbutton.h>
51#include <tdefiledialog.h>
54#include <kiconloader.h>
55#include <tdepopupmenu.h>
56#include <tdestdaccel.h>
58#include <kexiutils/utils.h>
59#include <widget/utils/kexidropdownbutton.h>
60#include <widget/utils/kexicontextmenuutils.h>
63class KexiBlobTableEdit::Private
69 , setValueInternalEnabled(true)
74 KexiDropDownButton *button;
76 KexiImageContextMenu *popup;
78 bool setValueInternalEnabled : 1;
87 setName(
"KexiBlobTableEdit");
90 m_hasFocusableWidget =
false;
93 TQToolTip::add(d->button, i18n(
"Click to show available actions for this cell"));
96 d->popup->installEventFilter(
this);
101 d->button->setPopup( d->popup );
106 connect(d->popup, TQ_SIGNAL(updateActionsAvailabilityRequested(
bool&,
bool&)),
107 this, TQ_SLOT(slotUpdateActionsAvailabilityRequested(
bool&,
bool&)));
109 connect(d->popup, TQ_SIGNAL(insertFromFileRequested(
const KURL&)),
110 this, TQ_SLOT(handleInsertFromFileAction(
const KURL&)));
111 connect(d->popup, TQ_SIGNAL(saveAsRequested(
const TQString&)),
112 this, TQ_SLOT(handleSaveAsAction(
const TQString&)));
113 connect(d->popup, TQ_SIGNAL(cutRequested()),
114 this, TQ_SLOT(handleCutAction()));
115 connect(d->popup, TQ_SIGNAL(copyRequested()),
116 this, TQ_SLOT(handleCopyAction()));
117 connect(d->popup, TQ_SIGNAL(pasteRequested()),
118 this, TQ_SLOT(handlePasteAction()));
119 connect(d->popup, TQ_SIGNAL(clearRequested()),
120 this, TQ_SLOT(clear()));
121 connect(d->popup, TQ_SIGNAL(showPropertiesRequested()),
122 this, TQ_SLOT(handleShowPropertiesAction()));
125KexiBlobTableEdit::~KexiBlobTableEdit()
129 kdDebug() <<
"KexiBlobTableEdit: Cleaning up..." << endl;
131 m_tempFile->unlink();
136 kdDebug() <<
"KexiBlobTableEdit: Ready." << endl;
141void KexiBlobTableEdit::setValueInternal(
const TQVariant& add,
bool removeOld)
143 if (!d->setValueInternalEnabled)
146 d->value = add.toByteArray();
148 d->value = m_origValue.toByteArray();
151 TQByteArray val = m_origValue.toByteArray();
152 kdDebug() <<
"KexiBlobTableEdit: Size of BLOB: " << val.size() << endl;
153 m_tempFile =
new KTempFile();
154 m_tempFile->setAutoDelete(
true);
155 kdDebug() <<
"KexiBlobTableEdit: Creating temporary file: " << m_tempFile->name() << endl;
156 m_tempFile->dataStream()->writeRawBytes(val.data(), val.size());
161 KMimeMagicResult* mmr = KMimeMagic::self()->findFileType(m_tempFile->name());
162 kdDebug() <<
"KexiBlobTableEdit: Mimetype = " << mmr->mimeType() << endl;
172 return d->value.isEmpty();
178 return d->value.isEmpty();
189 if(m_content && m_content->isModified())
191 return TQVariant(m_content->text());
194 TQFile f( m_tempFile->name() );
196 TQDataStream stream(&f);
197 char* data = (
char*) malloc(f.size());
198 value.resize(f.size());
199 stream.readRawBytes(data, f.size());
200 value.duplicate(data, f.size());
202 kdDebug() <<
"KexiBlobTableEdit: Size of BLOB: " << value.size() << endl;
203 return TQVariant(value);
207void KexiBlobTableEdit::paintFocusBorders( TQPainter *p, TQVariant &,
int x,
int y,
int w,
int h )
210 if (!d->readOnly && w > d->button->width())
211 w -= d->button->width();
212 p->drawRect(x, y, w, h);
216KexiBlobTableEdit::setupContents( TQPainter *p,
bool focused,
const TQVariant& val,
217 TQString &txt,
int &align,
int &x,
int &y_offset,
int &w,
int &h )
228 if (p && val.canCast(TQVariant::ByteArray) && pixmap.loadFromData(val.toByteArray())) {
230 pixmap, TQt::AlignCenter,
true,
true);
244void KexiBlobTableEdit::handleInsertFromFileAction(
const KURL& url)
249 TQString fileName( url.isLocalFile() ? url.path() : url.prettyURL() );
253 if (!f.open(IO_ReadOnly)) {
257 TQByteArray ba = f.readAll();
258 if (f.status()!=IO_Ok) {
265 setValueInternal( ba,
true );
266 signalEditRequested();
270void KexiBlobTableEdit::handleAboutToSaveAsAction(TQString& origFilename, TQString& fileExtension,
bool& dataIsEmpty)
272 Q_UNUSED(origFilename);
273 Q_UNUSED(fileExtension);
278void KexiBlobTableEdit::handleSaveAsAction(
const TQString& fileName)
281 if (!f.open(IO_WriteOnly)) {
285 f.writeBlock( d->value );
286 if (f.status()!=IO_Ok) {
294void KexiBlobTableEdit::handleCutAction()
302void KexiBlobTableEdit::handleCopyAction()
304 executeCopyAction(d->value);
307void KexiBlobTableEdit::executeCopyAction(
const TQByteArray& data)
310 if (!pixmap.loadFromData(data))
312 tqApp->clipboard()->setPixmap(pixmap, TQClipboard::Clipboard);
315void KexiBlobTableEdit::handlePasteAction()
319 TQPixmap pm( tqApp->clipboard()->pixmap(TQClipboard::Clipboard) );
321 TQBuffer buffer( ba );
322 buffer.open( IO_WriteOnly );
323 if (pm.save( &buffer,
"PNG" )) {
324 setValueInternal( ba,
true );
327 setValueInternal( TQByteArray(),
true );
329 signalEditRequested();
336 setValueInternal( TQByteArray(),
true );
337 signalEditRequested();
342void KexiBlobTableEdit::handleShowPropertiesAction()
347void KexiBlobTableEdit::showFocus(
const TQRect& r,
bool readOnly )
349 d->readOnly = readOnly;
359void KexiBlobTableEdit::resize(
int w,
int h)
361 d->totalSize = TQSize(w,h);
362 const int addWidth = d->readOnly ? 0 : d->button->width();
363 TQWidget::resize(w - addWidth, h);
365 d->button->resize( h, h );
366 m_rightMarginWhenFocused = m_rightMargin + addWidth;
367 TQRect r( pos().x(), pos().y(), w+1, h+1 );
375void KexiBlobTableEdit::updateFocus(
const TQRect& r )
378 if (d->button->width() > r.width())
379 moveChild(d->button, r.right() + 1, r.top());
381 moveChild(d->button, r.right() - d->button->width(), r.top() );
395void KexiBlobTableEdit::slotUpdateActionsAvailabilityRequested(
bool& valueIsNull,
bool& valueIsReadOnly)
397 emit editRequested();
399 valueIsReadOnly = d->readOnly ||
isReadOnly();
402void KexiBlobTableEdit::signalEditRequested()
404 d->setValueInternalEnabled =
false;
405 emit editRequested();
406 d->setValueInternalEnabled =
true;
409bool KexiBlobTableEdit::handleKeyPress( TQKeyEvent* ke,
bool editorActive )
411 Q_UNUSED(editorActive);
413 const int k = ke->key();
416 if ((ke->state()==TQt::NoButton && k==TQt::Key_F4)
417 || (ke->state()==TQt::AltButton && k==TQt::Key_Down)) {
418 d->button->animateClick();
419 TQMouseEvent me( TQEvent::MouseButtonPress, TQPoint(2,2), TQt::LeftButton, TQt::NoButton );
420 TQApplication::sendEvent( d->button, &me );
422 else if ((ke->state()==TQt::NoButton && (k==TQt::Key_F2 || k==TQt::Key_Space || k==TQt::Key_Enter || k==TQt::Key_Return))) {
423 d->popup->insertFromFile();
435 d->popup->insertFromFile();
439void KexiBlobTableEdit::handleCopyAction(
const TQVariant& value,
const TQVariant& visibleValue)
442 executeCopyAction(value.toByteArray());
445void KexiBlobTableEdit::handleAction(
const TQString& actionName)
447 if (actionName==
"edit_paste") {
450 else if (actionName==
"edit_cut") {
451 emit editRequested();
456bool KexiBlobTableEdit::eventFilter( TQObject *o, TQEvent *e )
458 if (o == d->popup && e->type()==TQEvent::KeyPress) {
459 TQKeyEvent* ke =
static_cast<TQKeyEvent*
>(e);
460 const int state = ke->state();
461 const int k = ke->key();
462 if ( (state==TQt::NoButton && (k==TQt::Key_Tab || k==TQt::Key_Left || k==TQt::Key_Right))
463 || (state==TQt::ShiftButton && k==TQt::Key_Backtab)
467 TQApplication::sendEvent(
this, ke );
474KEXI_CELLEDITOR_FACTORY_ITEM_IMPL(KexiBlobEditorFactoryItem, KexiBlobTableEdit)
480class KexiTDEIconTableEdit::Private
484 : pixmapCache(17, 17, false)
488 TQVariant currentValue;
490 TQCache<TQPixmap> pixmapCache;
497 setName(
"KexiTDEIconTableEdit");
501KexiTDEIconTableEdit::~KexiTDEIconTableEdit()
506void KexiTDEIconTableEdit::init()
508 m_hasFocusableWidget =
false;
509 d->pixmapCache.setAutoDelete(
true);
514 d->currentValue = m_origValue;
519 return d->currentValue.isNull();
524 return d->currentValue.isNull();
529 return d->currentValue;
534 d->currentValue = TQVariant();
548 TQString &,
int &,
int &,
int &y_offset,
int &w,
int &h )
550 Q_UNUSED( y_offset );
558 int s = TQMAX(h - 5, 12);
561 TQRect r( TQMAX( w/2 - s/2, 0 ) , h/2 - s/2 , s, s);
562 p->setPen(TQPen(colorGroup().text(), 1));
565 p->drawLine(r.x(), r.y(), r.right(), r.bottom());
566 p->drawLine(r.x(), r.bottom(), r.right(), r.y());
570 TQString key = val.toString();
572 if (!key.isEmpty() && !(pix = d->pixmapCache[ key ])) {
574 TQPixmap pm = TDEGlobal::iconLoader()->loadIcon( key, TDEIcon::Small,
575 0, TDEIcon::DefaultState, 0L,
true );
577 pix =
new TQPixmap(pm);
578 d->pixmapCache.insert(key, pix);
583 p->drawPixmap( (w-pix->width())/2, (h-pix->height())/2, *pix );
595#include "kexiblobtableedit.moc"
TQString captionOrAliasOrName() const
virtual bool cursorAtEnd()=0
virtual bool cursorAtStart()=0
virtual bool isReadOnly() const
virtual TQVariant value()=0
virtual bool valueIsNull()=0
virtual bool valueIsEmpty()=0
virtual void clear()=0
clears item's data, so the data will contain NULL data
virtual TQVariant visibleValue()
Cell editor for displaying kde icon (using icon name provided as string). Read only.
virtual bool cursorAtEnd()
virtual bool valueIsNull()
virtual void setValueInternal(const TQVariant &add, bool removeOld)
initializes this editor with add value
virtual bool cursorAtStart()
virtual void handleCopyAction(const TQVariant &value, const TQVariant &visibleValue)
virtual bool valueIsEmpty()
virtual void clear()
clears item's data, so the data will contain NULL data
virtual TQVariant value()
virtual void setupContents(TQPainter *p, bool focused, const TQVariant &val, TQString &txt, int &align, int &x, int &y_offset, int &w, int &h)
Abstract class for a cell editor. Handles cell painting and displaying the editor widget.
virtual TQSize totalSize()
void repaintRelatedCell()
void setViewWidget(TQWidget *v)
void moveChild(TQWidget *child, int x, int y)
TQScrollView * m_scrollView
may be 0 if the parent is not a scrollview
virtual bool handleDoubleClick()
KexiDB::QueryColumnInfo * columnInfo
KEXIUTILS_EXPORT void drawPixmap(TQPainter &p, int lineWidth, const TQRect &rect, const TQPixmap &pixmap, int alignment, bool scaledContents, bool keepAspectRatio)