~ubuntu-branches/ubuntu/intrepid/digikam/intrepid

« back to all changes in this revision

Viewing changes to digikam/libs/widgets/metadata/metadatawidget.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Mark Purcell
  • Date: 2008-07-17 20:25:39 UTC
  • mfrom: (1.3.2 upstream) (37 hardy)
  • mto: This revision was merged to the branch mainline in revision 39.
  • Revision ID: james.westby@ubuntu.com-20080717202539-1bw3w3nrsso7yj4z
* New upstream release
  - digiKam 0.9.4 Release Plan (KDE3) ~ 13 July 08 (Closes: #490144)
* DEB_CONFIGURE_EXTRA_FLAGS := --without-included-sqlite3
* Debhelper compatibility level V7
* Install pixmaps in debian/*.install
* Add debian/digikam.lintian-overrides

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ============================================================
 
2
 *
 
3
 * This file is a part of digiKam project
 
4
 * http://www.digikam.org
 
5
 *
 
6
 * Date        : 2006-02-22
 
7
 * Description : a generic widget to display metadata
 
8
 *
 
9
 * Copyright (C) 2006-2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
 
10
 *
 
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)
 
15
 * any later version.
 
16
 *
 
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.
 
21
 *
 
22
 * ============================================================ */
 
23
 
 
24
// Qt includes.
 
25
 
 
26
#include <qlayout.h>
 
27
#include <qmap.h>
 
28
#include <qfile.h> 
 
29
#include <qmime.h>
 
30
#include <qheader.h>
 
31
#include <qwhatsthis.h>
 
32
#include <qpainter.h>
 
33
#include <qhbuttongroup.h>
 
34
#include <qpushbutton.h>
 
35
#include <qlabel.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>
 
42
#include <qtooltip.h>
 
43
 
 
44
// KDE includes.
 
45
 
 
46
#include <kdialogbase.h>
 
47
#include <klocale.h>
 
48
#include <kfiledialog.h>
 
49
#include <kglobalsettings.h>
 
50
#include <kprinter.h>
 
51
#include <kglobal.h>
 
52
#include <kiconloader.h>
 
53
#include <kapplication.h>
 
54
 
 
55
// Local includes.
 
56
 
 
57
#include "ddebug.h"
 
58
#include "metadatalistview.h"
 
59
#include "mdkeylistviewitem.h"
 
60
#include "searchtextbar.h"
 
61
#include "metadatawidget.h"
 
62
#include "metadatawidget.moc"
 
63
 
 
64
namespace Digikam
 
65
{
 
66
 
 
67
class MetadataWidgetPriv
 
68
{
 
69
 
 
70
public:
 
71
 
 
72
    MetadataWidgetPriv()
 
73
    {
 
74
        toolButtons  = 0;
 
75
        levelButtons = 0;
 
76
        view         = 0;
 
77
        mainLayout   = 0;
 
78
        searchBar    = 0;
 
79
    }
 
80
 
 
81
    QGridLayout            *mainLayout;
 
82
 
 
83
    QHButtonGroup          *toolButtons;
 
84
    QHButtonGroup          *levelButtons;
 
85
 
 
86
    QByteArray              metadata;
 
87
 
 
88
    QString                 fileName;
 
89
 
 
90
    MetadataListView       *view;
 
91
 
 
92
    SearchTextBar          *searchBar;
 
93
 
 
94
    DMetadata::MetaDataMap  metaDataMap;
 
95
};
 
96
 
 
97
MetadataWidget::MetadataWidget(QWidget* parent, const char* name)
 
98
              : QWidget(parent, name)
 
99
{
 
100
    d = new MetadataWidgetPriv;
 
101
 
 
102
    d->mainLayout = new QGridLayout(this, 3, 4, KDialog::spacingHint(), KDialog::spacingHint());
 
103
    KIconLoader *iconLoader = KApplication::kApplication()->iconLoader();
 
104
 
 
105
    d->levelButtons = new QHButtonGroup(this);
 
106
    d->levelButtons->setInsideMargin( 0 );
 
107
    d->levelButtons->setExclusive(true);
 
108
    d->levelButtons->setFrameShape(QFrame::NoFrame);
 
109
 
 
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);
 
116
 
 
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);
 
123
 
 
124
    d->toolButtons = new QHButtonGroup(this);
 
125
    d->toolButtons->setInsideMargin( 0 );
 
126
    d->toolButtons->setFrameShape(QFrame::NoFrame);
 
127
 
 
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);
 
133
    
 
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);
 
139
 
 
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);
 
145
 
 
146
    d->view         = new MetadataListView(this);
 
147
    QString barName = QString(name) + "SearchBar";
 
148
    d->searchBar    = new SearchTextBar(this, barName.ascii());
 
149
 
 
150
    // -----------------------------------------------------------------
 
151
 
 
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);
 
158
 
 
159
    // -----------------------------------------------------------------
 
160
    
 
161
    connect(d->levelButtons, SIGNAL(released(int)),
 
162
            this, SLOT(slotModeChanged(int)));
 
163
 
 
164
    connect(copy2ClipBoard, SIGNAL(clicked()),
 
165
            this, SLOT(slotCopy2Clipboard()));
 
166
 
 
167
    connect(printMetadata, SIGNAL(clicked()),
 
168
            this, SLOT(slotPrintMetadata()));
 
169
 
 
170
    connect(saveMetadata, SIGNAL(clicked()),
 
171
            this, SLOT(slotSaveMetadataToFile()));     
 
172
 
 
173
    connect(d->searchBar, SIGNAL(signalTextChanged(const QString&)),
 
174
            d->view, SLOT(slotSearchTextChanged(const QString&)));
 
175
 
 
176
    connect(d->view, SIGNAL(signalTextFilterMatch(bool)),
 
177
            d->searchBar, SLOT(slotSearchResult(bool)));                   
 
178
}
 
179
 
 
180
MetadataWidget::~MetadataWidget()
 
181
{
 
182
    delete d;
 
183
}
 
184
 
 
185
MetadataListView* MetadataWidget::view()
 
186
{
 
187
    return d->view;
 
188
}
 
189
 
 
190
void MetadataWidget::enabledToolButtons(bool b)
 
191
{
 
192
    d->toolButtons->setEnabled(b);
 
193
}
 
194
 
 
195
bool MetadataWidget::setMetadata(const QByteArray& data)
 
196
{
 
197
    d->metadata = data;
 
198
    
 
199
    // Cleanup all metadata contents.
 
200
    setMetadataMap();
 
201
 
 
202
    if (d->metadata.isEmpty())
 
203
    {
 
204
        setMetadataEmpty();
 
205
        return false;
 
206
    }
 
207
 
 
208
    // Try to decode current metadata.
 
209
    if (decodeMetadata())
 
210
        enabledToolButtons(true);
 
211
    else
 
212
        enabledToolButtons(false);
 
213
    
 
214
    // Refresh view using decoded metadata.
 
215
    buildView();
 
216
 
 
217
    return true;
 
218
}
 
219
 
 
220
void MetadataWidget::setMetadataEmpty()
 
221
{
 
222
    d->view->clear();
 
223
    enabledToolButtons(false);
 
224
}
 
225
 
 
226
const QByteArray& MetadataWidget::getMetadata()
 
227
{
 
228
    return d->metadata;
 
229
}
 
230
 
 
231
bool MetadataWidget::storeMetadataToFile(const KURL& url)
 
232
{
 
233
    if( url.isEmpty() )
 
234
        return false;
 
235
 
 
236
    QFile file(url.path());
 
237
    if ( !file.open(IO_WriteOnly) ) 
 
238
        return false;
 
239
    
 
240
    QDataStream stream( &file );
 
241
    stream.writeRawBytes(d->metadata.data(), d->metadata.size());
 
242
    file.close();
 
243
    return true;
 
244
}
 
245
 
 
246
void MetadataWidget::setMetadataMap(const DMetadata::MetaDataMap& data)
 
247
{
 
248
    d->metaDataMap = data;
 
249
}
 
250
 
 
251
const DMetadata::MetaDataMap& MetadataWidget::getMetadataMap()
 
252
{
 
253
    return d->metaDataMap;
 
254
}
 
255
 
 
256
void MetadataWidget::setIfdList(const DMetadata::MetaDataMap &ifds, const QStringList& tagsFilter)
 
257
{
 
258
    d->view->setIfdList(ifds, tagsFilter);
 
259
}
 
260
 
 
261
void MetadataWidget::setIfdList(const DMetadata::MetaDataMap &ifds, const QStringList& keysFilter,
 
262
                                const QStringList& tagsFilter)
 
263
{
 
264
    d->view->setIfdList(ifds, keysFilter, tagsFilter);
 
265
}
 
266
 
 
267
void MetadataWidget::slotModeChanged(int)
 
268
{
 
269
    buildView();
 
270
}
 
271
 
 
272
void MetadataWidget::slotCopy2Clipboard()
 
273
{
 
274
    QString textmetadata = i18n("File name: %1 (%2)").arg(d->fileName).arg(getMetadataTitle());
 
275
    QListViewItemIterator it( d->view );
 
276
 
 
277
    while ( it.current() )
 
278
    {
 
279
        if ( !it.current()->isSelectable() )
 
280
        {
 
281
            MdKeyListViewItem *item = dynamic_cast<MdKeyListViewItem *>(it.current());
 
282
            textmetadata.append("\n\n>>> ");
 
283
            textmetadata.append(item->getMdKey());
 
284
            textmetadata.append(" <<<\n\n");
 
285
        }
 
286
        else
 
287
        {
 
288
            QListViewItem *item = it.current();
 
289
            textmetadata.append(item->text(0));
 
290
            textmetadata.append(" : ");
 
291
            textmetadata.append(item->text(1));
 
292
            textmetadata.append("\n");
 
293
        }
 
294
 
 
295
        ++it;
 
296
    }
 
297
 
 
298
    QApplication::clipboard()->setData(new QTextDrag(textmetadata), QClipboard::Clipboard);
 
299
}
 
300
 
 
301
void MetadataWidget::slotPrintMetadata()
 
302
{
 
303
    QString textmetadata = i18n("<p><big><big><b>File name: %1 (%2)</b></big></big>")
 
304
                           .arg(d->fileName)
 
305
                           .arg(getMetadataTitle());
 
306
    QListViewItemIterator it( d->view );
 
307
 
 
308
    while ( it.current() )
 
309
    {
 
310
        if ( !it.current()->isSelectable() )
 
311
        {
 
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>");
 
316
        }
 
317
        else
 
318
        {
 
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>");
 
324
        }
 
325
 
 
326
        ++it;
 
327
    }
 
328
 
 
329
    textmetadata.append("</p>");
 
330
 
 
331
    KPrinter printer;
 
332
    printer.setFullPage( true );
 
333
 
 
334
    if ( printer.setup( this ) )
 
335
    {
 
336
        QPainter p( &printer );
 
337
 
 
338
        if ( !p.device() ) 
 
339
            return;
 
340
 
 
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,
 
348
                                  QString(),
 
349
                                  QStyleSheet::defaultSheet(),
 
350
                                  QMimeSourceFactory::defaultFactory(),
 
351
                                  view.height() );
 
352
        richText.setWidth( &p, view.width() );
 
353
        int page = 1;
 
354
 
 
355
        do
 
356
        {
 
357
            richText.draw( &p, margin, margin, view, colorGroup() );
 
358
            view.moveBy( 0, view.height() );
 
359
            p.translate( 0 , -view.height() );
 
360
            p.setFont( font );
 
361
            p.drawText( view.right() - p.fontMetrics().width( QString::number( page ) ),
 
362
                        view.bottom() + p.fontMetrics().ascent() + 5, QString::number( page ) );
 
363
 
 
364
            if ( view.top() - margin >= richText.height() )
 
365
                break;
 
366
 
 
367
            printer.newPage();
 
368
            page++;
 
369
        }
 
370
        while (true);
 
371
    }
 
372
}
 
373
 
 
374
KURL MetadataWidget::saveMetadataToFile(const QString& caption, const QString& fileFilter)
 
375
{
 
376
    KFileDialog fileSaveDialog(KGlobalSettings::documentPath(),
 
377
                               QString(),
 
378
                               this,
 
379
                               "MetadataFileSaveDialog",
 
380
                               false);
 
381
 
 
382
    fileSaveDialog.setOperationMode(KFileDialog::Saving);
 
383
    fileSaveDialog.setMode(KFile::File);
 
384
    fileSaveDialog.setSelection(d->fileName);
 
385
    fileSaveDialog.setCaption(caption);
 
386
    fileSaveDialog.setFilter(fileFilter);
 
387
 
 
388
    // Check for cancel.
 
389
    if ( fileSaveDialog.exec() == KFileDialog::Accepted )
 
390
        return fileSaveDialog.selectedURL().path();
 
391
    
 
392
    return KURL();
 
393
}
 
394
 
 
395
void MetadataWidget::setMode(int mode)
 
396
{
 
397
    if (d->levelButtons->selectedId() == mode)
 
398
        return;
 
399
 
 
400
    d->levelButtons->setButton(mode);
 
401
    buildView();
 
402
}
 
403
 
 
404
int MetadataWidget::getMode()
 
405
{
 
406
    int level = d->levelButtons->selectedId();
 
407
    return level;
 
408
}
 
409
 
 
410
QString MetadataWidget::getCurrentItemKey() const
 
411
{
 
412
    return d->view->getCurrentItemKey();
 
413
}
 
414
 
 
415
void MetadataWidget::setCurrentItemByKey(const QString& itemKey)
 
416
{
 
417
    d->view->setCurrentItemByKey(itemKey);
 
418
}
 
419
 
 
420
bool MetadataWidget::loadFromData(const QString& fileName, const QByteArray& data)
 
421
{
 
422
    setFileName(fileName);
 
423
    return(setMetadata(data));
 
424
}
 
425
 
 
426
QString MetadataWidget::getTagTitle(const QString&)
 
427
{
 
428
    return QString();
 
429
}
 
430
 
 
431
QString MetadataWidget::getTagDescription(const QString&)
 
432
{
 
433
    return QString();
 
434
}
 
435
 
 
436
void MetadataWidget::setFileName(const QString& fileName)
 
437
{
 
438
    d->fileName = fileName;
 
439
}
 
440
 
 
441
void MetadataWidget::setUserAreaWidget(QWidget *w)
 
442
{
 
443
    QVBoxLayout *vLayout = new QVBoxLayout( KDialog::spacingHint() ); 
 
444
    vLayout->addWidget(w);
 
445
    vLayout->addStretch();
 
446
    d->mainLayout->addMultiCellLayout(vLayout, 3, 3, 0, 4);
 
447
}
 
448
 
 
449
void MetadataWidget::buildView()
 
450
{
 
451
    d->view->slotSearchTextChanged(d->searchBar->text());
 
452
}
 
453
 
 
454
}  // namespace Digikam