1
/* ============================================================
3
* This file is a part of digiKam project
4
* http://www.digikam.org
7
* Description : a generic widget to display metadata
9
* Copyright (C) 2006-2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
11
* This program is free software; you can redistribute it
12
* and/or modify it under the terms of the GNU General
13
* Public License as published by the Free Software Foundation;
14
* either version 2, or (at your option)
17
* This program is distributed in the hope that it will be useful,
18
* but WITHOUT ANY WARRANTY; without even the implied warranty of
19
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
* GNU General Public License for more details.
22
* ============================================================ */
31
#include <qwhatsthis.h>
33
#include <qhbuttongroup.h>
34
#include <qpushbutton.h>
36
#include <qdragobject.h>
37
#include <qclipboard.h>
38
#include <qsimplerichtext.h>
39
#include <qpaintdevicemetrics.h>
40
#include <qstylesheet.h>
41
#include <qlistview.h>
46
#include <kdialogbase.h>
48
#include <kfiledialog.h>
49
#include <kglobalsettings.h>
52
#include <kiconloader.h>
53
#include <kapplication.h>
58
#include "metadatalistview.h"
59
#include "mdkeylistviewitem.h"
60
#include "searchtextbar.h"
61
#include "metadatawidget.h"
62
#include "metadatawidget.moc"
67
class MetadataWidgetPriv
81
QGridLayout *mainLayout;
83
QHButtonGroup *toolButtons;
84
QHButtonGroup *levelButtons;
90
MetadataListView *view;
92
SearchTextBar *searchBar;
94
DMetadata::MetaDataMap metaDataMap;
97
MetadataWidget::MetadataWidget(QWidget* parent, const char* name)
98
: QWidget(parent, name)
100
d = new MetadataWidgetPriv;
102
d->mainLayout = new QGridLayout(this, 3, 4, KDialog::spacingHint(), KDialog::spacingHint());
103
KIconLoader *iconLoader = KApplication::kApplication()->iconLoader();
105
d->levelButtons = new QHButtonGroup(this);
106
d->levelButtons->setInsideMargin( 0 );
107
d->levelButtons->setExclusive(true);
108
d->levelButtons->setFrameShape(QFrame::NoFrame);
110
QPushButton *simpleLevel = new QPushButton( d->levelButtons );
111
simpleLevel->setPixmap( iconLoader->loadIcon( "ascii", (KIcon::Group)KIcon::Toolbar ) );
112
simpleLevel->setToggleButton(true);
113
QWhatsThis::add( simpleLevel, i18n( "Switch the tags view to a simple human-readable list" ) );
114
QToolTip::add( simpleLevel, i18n( "Simple list" ));
115
d->levelButtons->insert(simpleLevel, SIMPLE);
117
QPushButton *fullLevel = new QPushButton( d->levelButtons );
118
fullLevel->setPixmap( iconLoader->loadIcon( "document", (KIcon::Group)KIcon::Toolbar ) );
119
fullLevel->setToggleButton(true);
120
QWhatsThis::add( fullLevel, i18n( "Switch the tags view to a full list" ) );
121
QToolTip::add( fullLevel, i18n( "Full list" ));
122
d->levelButtons->insert(fullLevel, FULL);
124
d->toolButtons = new QHButtonGroup(this);
125
d->toolButtons->setInsideMargin( 0 );
126
d->toolButtons->setFrameShape(QFrame::NoFrame);
128
QPushButton *saveMetadata = new QPushButton( d->toolButtons );
129
saveMetadata->setPixmap( iconLoader->loadIcon( "filesave", (KIcon::Group)KIcon::Toolbar ) );
130
QWhatsThis::add( saveMetadata, i18n( "Save metadata to a binary file" ) );
131
QToolTip::add( saveMetadata, i18n( "Save metadata" ));
132
d->toolButtons->insert(saveMetadata);
134
QPushButton *printMetadata = new QPushButton( d->toolButtons );
135
printMetadata->setPixmap( iconLoader->loadIcon( "fileprint", (KIcon::Group)KIcon::Toolbar ) );
136
QWhatsThis::add( printMetadata, i18n( "Print metadata to printer" ) );
137
QToolTip::add( printMetadata, i18n( "Print metadata" ));
138
d->toolButtons->insert(printMetadata);
140
QPushButton *copy2ClipBoard = new QPushButton( d->toolButtons );
141
copy2ClipBoard->setPixmap( iconLoader->loadIcon( "editcopy", (KIcon::Group)KIcon::Toolbar ) );
142
QWhatsThis::add( copy2ClipBoard, i18n( "Copy metadata to clipboard" ) );
143
QToolTip::add( copy2ClipBoard, i18n( "Copy metadata to clipboard" ));
144
d->toolButtons->insert(copy2ClipBoard);
146
d->view = new MetadataListView(this);
147
QString barName = QString(name) + "SearchBar";
148
d->searchBar = new SearchTextBar(this, barName.ascii());
150
// -----------------------------------------------------------------
152
d->mainLayout->addMultiCellWidget(d->levelButtons, 0, 0, 0, 1);
153
d->mainLayout->addMultiCellWidget(d->toolButtons, 0, 0, 4, 4);
154
d->mainLayout->addMultiCellWidget(d->view, 1, 1, 0, 4);
155
d->mainLayout->addMultiCellWidget(d->searchBar, 2, 2, 0, 4);
156
d->mainLayout->setRowStretch(1, 10);
157
d->mainLayout->setColStretch(3, 10);
159
// -----------------------------------------------------------------
161
connect(d->levelButtons, SIGNAL(released(int)),
162
this, SLOT(slotModeChanged(int)));
164
connect(copy2ClipBoard, SIGNAL(clicked()),
165
this, SLOT(slotCopy2Clipboard()));
167
connect(printMetadata, SIGNAL(clicked()),
168
this, SLOT(slotPrintMetadata()));
170
connect(saveMetadata, SIGNAL(clicked()),
171
this, SLOT(slotSaveMetadataToFile()));
173
connect(d->searchBar, SIGNAL(signalTextChanged(const QString&)),
174
d->view, SLOT(slotSearchTextChanged(const QString&)));
176
connect(d->view, SIGNAL(signalTextFilterMatch(bool)),
177
d->searchBar, SLOT(slotSearchResult(bool)));
180
MetadataWidget::~MetadataWidget()
185
MetadataListView* MetadataWidget::view()
190
void MetadataWidget::enabledToolButtons(bool b)
192
d->toolButtons->setEnabled(b);
195
bool MetadataWidget::setMetadata(const QByteArray& data)
199
// Cleanup all metadata contents.
202
if (d->metadata.isEmpty())
208
// Try to decode current metadata.
209
if (decodeMetadata())
210
enabledToolButtons(true);
212
enabledToolButtons(false);
214
// Refresh view using decoded metadata.
220
void MetadataWidget::setMetadataEmpty()
223
enabledToolButtons(false);
226
const QByteArray& MetadataWidget::getMetadata()
231
bool MetadataWidget::storeMetadataToFile(const KURL& url)
236
QFile file(url.path());
237
if ( !file.open(IO_WriteOnly) )
240
QDataStream stream( &file );
241
stream.writeRawBytes(d->metadata.data(), d->metadata.size());
246
void MetadataWidget::setMetadataMap(const DMetadata::MetaDataMap& data)
248
d->metaDataMap = data;
251
const DMetadata::MetaDataMap& MetadataWidget::getMetadataMap()
253
return d->metaDataMap;
256
void MetadataWidget::setIfdList(const DMetadata::MetaDataMap &ifds, const QStringList& tagsFilter)
258
d->view->setIfdList(ifds, tagsFilter);
261
void MetadataWidget::setIfdList(const DMetadata::MetaDataMap &ifds, const QStringList& keysFilter,
262
const QStringList& tagsFilter)
264
d->view->setIfdList(ifds, keysFilter, tagsFilter);
267
void MetadataWidget::slotModeChanged(int)
272
void MetadataWidget::slotCopy2Clipboard()
274
QString textmetadata = i18n("File name: %1 (%2)").arg(d->fileName).arg(getMetadataTitle());
275
QListViewItemIterator it( d->view );
277
while ( it.current() )
279
if ( !it.current()->isSelectable() )
281
MdKeyListViewItem *item = dynamic_cast<MdKeyListViewItem *>(it.current());
282
textmetadata.append("\n\n>>> ");
283
textmetadata.append(item->getMdKey());
284
textmetadata.append(" <<<\n\n");
288
QListViewItem *item = it.current();
289
textmetadata.append(item->text(0));
290
textmetadata.append(" : ");
291
textmetadata.append(item->text(1));
292
textmetadata.append("\n");
298
QApplication::clipboard()->setData(new QTextDrag(textmetadata), QClipboard::Clipboard);
301
void MetadataWidget::slotPrintMetadata()
303
QString textmetadata = i18n("<p><big><big><b>File name: %1 (%2)</b></big></big>")
305
.arg(getMetadataTitle());
306
QListViewItemIterator it( d->view );
308
while ( it.current() )
310
if ( !it.current()->isSelectable() )
312
MdKeyListViewItem *item = dynamic_cast<MdKeyListViewItem *>(it.current());
313
textmetadata.append("<br><br><b>");
314
textmetadata.append(item->getMdKey());
315
textmetadata.append("</b><br><br>");
319
QListViewItem *item = it.current();
320
textmetadata.append(item->text(0));
321
textmetadata.append(" : <i>");
322
textmetadata.append(item->text(1));
323
textmetadata.append("</i><br>");
329
textmetadata.append("</p>");
332
printer.setFullPage( true );
334
if ( printer.setup( this ) )
336
QPainter p( &printer );
341
QPaintDeviceMetrics metrics(p.device());
342
int dpiy = metrics.logicalDpiY();
343
int margin = (int) ( (2/2.54)*dpiy ); // 2 cm margins
344
QRect view( margin, margin, metrics.width() - 2*margin, metrics.height() - 2*margin );
345
QFont font(KApplication::font());
346
font.setPointSize( 10 ); // we define 10pt to be a nice base size for printing
347
QSimpleRichText richText( textmetadata, font,
349
QStyleSheet::defaultSheet(),
350
QMimeSourceFactory::defaultFactory(),
352
richText.setWidth( &p, view.width() );
357
richText.draw( &p, margin, margin, view, colorGroup() );
358
view.moveBy( 0, view.height() );
359
p.translate( 0 , -view.height() );
361
p.drawText( view.right() - p.fontMetrics().width( QString::number( page ) ),
362
view.bottom() + p.fontMetrics().ascent() + 5, QString::number( page ) );
364
if ( view.top() - margin >= richText.height() )
374
KURL MetadataWidget::saveMetadataToFile(const QString& caption, const QString& fileFilter)
376
KFileDialog fileSaveDialog(KGlobalSettings::documentPath(),
379
"MetadataFileSaveDialog",
382
fileSaveDialog.setOperationMode(KFileDialog::Saving);
383
fileSaveDialog.setMode(KFile::File);
384
fileSaveDialog.setSelection(d->fileName);
385
fileSaveDialog.setCaption(caption);
386
fileSaveDialog.setFilter(fileFilter);
389
if ( fileSaveDialog.exec() == KFileDialog::Accepted )
390
return fileSaveDialog.selectedURL().path();
395
void MetadataWidget::setMode(int mode)
397
if (d->levelButtons->selectedId() == mode)
400
d->levelButtons->setButton(mode);
404
int MetadataWidget::getMode()
406
int level = d->levelButtons->selectedId();
410
QString MetadataWidget::getCurrentItemKey() const
412
return d->view->getCurrentItemKey();
415
void MetadataWidget::setCurrentItemByKey(const QString& itemKey)
417
d->view->setCurrentItemByKey(itemKey);
420
bool MetadataWidget::loadFromData(const QString& fileName, const QByteArray& data)
422
setFileName(fileName);
423
return(setMetadata(data));
426
QString MetadataWidget::getTagTitle(const QString&)
431
QString MetadataWidget::getTagDescription(const QString&)
436
void MetadataWidget::setFileName(const QString& fileName)
438
d->fileName = fileName;
441
void MetadataWidget::setUserAreaWidget(QWidget *w)
443
QVBoxLayout *vLayout = new QVBoxLayout( KDialog::spacingHint() );
444
vLayout->addWidget(w);
445
vLayout->addStretch();
446
d->mainLayout->addMultiCellLayout(vLayout, 3, 3, 0, 4);
449
void MetadataWidget::buildView()
451
d->view->slotSearchTextChanged(d->searchBar->text());
454
} // namespace Digikam