~ubuntu-branches/ubuntu/maverick/kdebase/maverick-updates

« back to all changes in this revision

Viewing changes to apps/dolphin/src/panels/information/informationpanel.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Debian Qt/KDE Maintainers, Martin Alfke, Modestas Vainius
  • Date: 2010-05-01 23:37:50 UTC
  • mfrom: (0.7.4 upstream) (0.4.4 experimental)
  • mto: This revision was merged to the branch mainline in revision 285.
  • Revision ID: james.westby@ubuntu.com-20100501233750-maq4i4sh8ymjbneb
Tags: 4:4.4.3-1
* New upstream release:
  - Konsole does not crash when closing a broken restored session.
    (Closes: #555831)
  - Konqueror does not crash when closing fast a tab. (Closes: #441298)

[Martin Alfke]
* Update of debian/copyright for kde 4.4

[ Modestas Vainius ]
* Bump kde-sc-dev-latest build dependency to 4.4.3.
* Confirm symbol files for 4.4.2 on hurd-i386 i386 ia64 kfreebsd-amd64
  kfreebsd-i386 mips powerpc s390 sparc.
* Release KDE SC 4.4.3 to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/***************************************************************************
2
 
 *   Copyright (C) 2006 by Peter Penz <peter.penz@gmx.at>                  *
 
2
 *   Copyright (C) 2006-2009 by Peter Penz <peter.penz@gmx.at>             *
3
3
 *                                                                         *
4
4
 *   This program is free software; you can redistribute it and/or modify  *
5
5
 *   it under the terms of the GNU General Public License as published by  *
18
18
 ***************************************************************************/
19
19
 
20
20
#include "informationpanel.h"
21
 
 
22
 
#include <config-nepomuk.h>
23
 
 
24
 
#include <kdialog.h>
25
21
#include <kdirnotify.h>
26
 
#include <kfileitem.h>
27
 
#include <kfilemetainfo.h>
28
 
#include <kfileplacesmodel.h>
29
 
#include <kglobalsettings.h>
30
 
#include <kio/previewjob.h>
31
 
#include <kiconeffect.h>
32
 
#include <kiconloader.h>
33
 
#include <klocale.h>
34
 
#include <kmenu.h>
35
 
#include <kseparator.h>
36
 
 
37
 
#ifdef HAVE_NEPOMUK
38
 
 
39
 
#define DISABLE_NEPOMUK_LEGACY
40
 
 
41
 
#include <Nepomuk/Resource>
42
 
#include <Nepomuk/Types/Property>
43
 
#include <Nepomuk/Variant>
44
 
#endif
45
 
 
46
 
#include <Phonon/BackendCapabilities>
47
 
#include <Phonon/MediaObject>
48
 
#include <Phonon/SeekSlider>
49
 
 
50
 
#include <QEvent>
51
 
#include <QInputDialog>
52
 
#include <QLabel>
53
 
#include <QPainter>
54
 
#include <QPixmap>
55
 
#include <QResizeEvent>
56
 
#include <QScrollArea>
57
 
#include <QTextLayout>
58
 
#include <QTextLine>
59
 
#include <QTimer>
60
 
#include <QScrollBar>
61
 
#include <QVBoxLayout>
62
 
 
63
 
#include "dolphin_informationpanelsettings.h"
64
 
#include "settings/dolphinsettings.h"
65
 
#include "metadatawidget.h"
66
 
#include "metatextlabel.h"
67
 
#include "phononwidget.h"
68
 
#include "pixmapviewer.h"
69
 
 
70
 
/**
71
 
 * Helper function for sorting items with qSort() in
72
 
 * InformationPanel::contextMenu().
73
 
 */
74
 
bool lessThan(const QAction* action1, const QAction* action2)
75
 
{
76
 
    return action1->text() < action2->text();
77
 
}
78
 
 
 
22
#include <QShowEvent>
 
23
#include "informationpanelcontent.h"
79
24
 
80
25
InformationPanel::InformationPanel(QWidget* parent) :
81
26
    Panel(parent),
82
27
    m_initialized(false),
83
 
    m_pendingPreview(false),
84
28
    m_infoTimer(0),
85
 
    m_outdatedPreviewTimer(0),
86
29
    m_urlChangedTimer(0),
87
30
    m_resetUrlTimer(0),
88
31
    m_shownUrl(),
90
33
    m_invalidUrlCandidate(),
91
34
    m_fileItem(),
92
35
    m_selection(),
93
 
    m_nameLabel(0),
94
 
    m_preview(0),
95
 
    m_previewSeparator(0),
96
 
    m_phononWidget(0),
97
 
    m_metaDataWidget(0),
98
 
    m_metaDataSeparator(0),
99
 
    m_metaTextArea(0),
100
 
    m_metaTextLabel(0)
 
36
    m_content(0)
101
37
{
102
38
}
103
39
 
104
40
InformationPanel::~InformationPanel()
105
41
{
106
 
    InformationPanelSettings::self()->writeConfig();
107
42
}
108
43
 
109
44
QSize InformationPanel::sizeHint() const
146
81
    }
147
82
 
148
83
    m_selection = selection;
 
84
    m_fileItem = KFileItem();
149
85
 
150
86
    const int count = selection.count();
151
87
    if (count == 0) {
174
110
        // The cursor is above the viewport. If files are selected,
175
111
        // show information regarding the selection.
176
112
        if (m_selection.size() > 0) {
177
 
            m_pendingPreview = false;
178
113
            m_infoTimer->start();
179
114
        }
180
115
    } else {
204
139
void InformationPanel::resizeEvent(QResizeEvent* event)
205
140
{
206
141
    if (isVisible()) {
207
 
        // If the text inside the name label or the info label cannot
208
 
        // get wrapped, then the maximum width of the label is increased
209
 
        // so that the width of the information panel gets increased.
210
 
        // To prevent this, the maximum width is adjusted to
211
 
        // the current width of the panel.
212
 
        const int maxWidth = event->size().width() - KDialog::spacingHint() * 4;
213
 
        m_nameLabel->setMaximumWidth(maxWidth);
214
 
 
215
 
        // The metadata widget also contains a text widget which may return
216
 
        // a large preferred width.
217
 
        if (m_metaDataWidget != 0) {
218
 
            m_metaDataWidget->setMaximumWidth(maxWidth);
219
 
        }
220
 
 
221
 
        // try to increase the preview as large as possible
222
 
        m_preview->setSizeHint(QSize(maxWidth, maxWidth));
223
 
        m_urlCandidate = m_shownUrl; // reset the URL candidate if a resizing is done
 
142
        m_urlCandidate = m_shownUrl;
224
143
        m_infoTimer->start();
225
 
 
226
 
        if (m_phononWidget->isVisible() && (m_phononWidget->mode() == PhononWidget::Video)) {
227
 
            // assure that the size of the video player is the same as the preview size
228
 
            m_phononWidget->setVideoSize(QSize(maxWidth, maxWidth));
229
 
        }
230
144
    }
231
145
    Panel::resizeEvent(event);
232
146
}
233
147
 
234
 
bool InformationPanel::eventFilter(QObject* obj, QEvent* event)
235
 
{
236
 
    // Check whether the size of the meta text area has changed and adjust
237
 
    // the fixed width in a way that no horizontal scrollbar needs to be shown.
238
 
    if ((obj == m_metaTextArea->viewport()) && (event->type() == QEvent::Resize)) {
239
 
        QResizeEvent* resizeEvent = static_cast<QResizeEvent*>(event);
240
 
        m_metaTextLabel->setFixedWidth(resizeEvent->size().width());
241
 
    }
242
 
    return Panel::eventFilter(obj, event);
243
 
}
244
 
 
245
148
void InformationPanel::contextMenuEvent(QContextMenuEvent* event)
246
149
{
 
150
    m_content->configureSettings();
247
151
    Panel::contextMenuEvent(event);
248
 
 
249
 
#ifdef HAVE_NEPOMUK
250
 
    if (showMultipleSelectionInfo()) {
251
 
        return;
252
 
    }
253
 
 
254
 
    KMenu popup(this);
255
 
 
256
 
    QAction* previewAction = popup.addAction(i18nc("@action:inmenu", "Preview"));
257
 
    previewAction->setIcon(KIcon("view-preview"));
258
 
    previewAction->setCheckable(true);
259
 
    previewAction->setChecked(InformationPanelSettings::showPreview());
260
 
 
261
 
    const bool metaDataAvailable = MetaDataWidget::metaDataAvailable();
262
 
 
263
 
    QAction* ratingAction = popup.addAction(i18nc("@action:inmenu", "Rating"));
264
 
    ratingAction->setIcon(KIcon("rating"));
265
 
    ratingAction->setCheckable(true);
266
 
    ratingAction->setChecked(InformationPanelSettings::showRating());
267
 
    ratingAction->setEnabled(metaDataAvailable);
268
 
 
269
 
    QAction* commentAction = popup.addAction(i18nc("@action:inmenu", "Comment"));
270
 
    commentAction->setIcon(KIcon("text-plain"));
271
 
    commentAction->setCheckable(true);
272
 
    commentAction->setChecked(InformationPanelSettings::showComment());
273
 
    commentAction->setEnabled(metaDataAvailable);
274
 
 
275
 
    QAction* tagsAction = popup.addAction(i18nc("@action:inmenu", "Tags"));
276
 
    tagsAction->setCheckable(true);
277
 
    tagsAction->setChecked(InformationPanelSettings::showTags());
278
 
    tagsAction->setEnabled(metaDataAvailable);
279
 
 
280
 
    KConfig config("kmetainformationrc", KConfig::NoGlobals);
281
 
    KConfigGroup settings = config.group("Show");
282
 
    initMetaInfoSettings(settings);
283
 
 
284
 
    QList<QAction*> actions;
285
 
 
286
 
    // Get all meta information labels that are available for
287
 
    // the currently shown file item and add them to the popup.
288
 
    Nepomuk::Resource res(updateFileItem().url());
289
 
    QHash<QUrl, Nepomuk::Variant> properties = res.properties();
290
 
    QHash<QUrl, Nepomuk::Variant>::const_iterator it = properties.constBegin();
291
 
    while (it != properties.constEnd()) {
292
 
        Nepomuk::Types::Property prop(it.key());
293
 
        const QString key = prop.name();
294
 
 
295
 
        // Meta information provided by Nepomuk that is already
296
 
        // available from KFileItem should not be configurable.
297
 
        bool skip = (key == "fileExtension") ||
298
 
                    (key == "name") ||
299
 
                    (key == "sourceModified") ||
300
 
                    (key == "size") ||
301
 
                    (key == "mime type");
302
 
        if (!skip) {
303
 
            // Check whether there is already a meta information
304
 
            // having the same label. In this case don't show it
305
 
            // twice in the menu.
306
 
            foreach (const QAction* action, actions) {
307
 
                if (action->data().toString() == key) {
308
 
                    skip = true;
309
 
                    break;
310
 
                }
311
 
            }
312
 
        }
313
 
 
314
 
        if (!skip) {
315
 
            const QString label = tunedLabel(prop.label());
316
 
            QAction* action = new QAction(label, &popup);
317
 
            action->setCheckable(true);
318
 
            action->setChecked(settings.readEntry(key, true));
319
 
            action->setData(key);
320
 
            actions.append(action);
321
 
        }
322
 
 
323
 
        ++it;
324
 
    }
325
 
 
326
 
    if (actions.count() > 0) {
327
 
        popup.addSeparator();
328
 
 
329
 
        // add all items alphabetically sorted to the popup
330
 
        qSort(actions.begin(), actions.end(), lessThan);
331
 
        foreach (QAction* action, actions) {
332
 
            popup.addAction(action);
333
 
        }
334
 
    }
335
 
 
336
 
    // Open the popup and adjust the settings for the
337
 
    // selected action.
338
 
    QAction* action = popup.exec(QCursor::pos());
339
 
    if (action == 0) {
340
 
        return;
341
 
    }
342
 
 
343
 
    const bool isChecked = action->isChecked();
344
 
    if (action == previewAction) {
345
 
        m_preview->setVisible(isChecked);
346
 
        m_previewSeparator->setVisible(isChecked);
347
 
        InformationPanelSettings::setShowPreview(isChecked);
348
 
        updatePhononWidget();
349
 
    } else if (action == ratingAction) {
350
 
        m_metaDataWidget->setRatingVisible(isChecked);
351
 
        InformationPanelSettings::setShowRating(isChecked);
352
 
    } else if (action == commentAction) {
353
 
        m_metaDataWidget->setCommentVisible(isChecked);
354
 
        InformationPanelSettings::setShowComment(isChecked);
355
 
    } else if (action == tagsAction) {
356
 
        m_metaDataWidget->setTagsVisible(isChecked);
357
 
        InformationPanelSettings::setShowTags(isChecked);
358
 
    } else {
359
 
        settings.writeEntry(action->data().toString(), action->isChecked());
360
 
        settings.sync();
361
 
        showMetaInfo();
362
 
    }
363
 
 
364
 
    if (m_metaDataWidget != 0) {
365
 
        const bool visible = m_metaDataWidget->isRatingVisible() ||
366
 
                             m_metaDataWidget->isCommentVisible() ||
367
 
                             m_metaDataWidget->areTagsVisible();
368
 
        m_metaDataSeparator->setVisible(visible);
369
 
    }
370
 
#endif
371
152
}
372
153
 
373
154
void InformationPanel::showItemInfo()
379
160
    cancelRequest();
380
161
 
381
162
    if (showMultipleSelectionInfo()) {
382
 
        KIconLoader iconLoader;
383
 
        QPixmap icon = iconLoader.loadIcon("dialog-information",
384
 
                                           KIconLoader::NoGroup,
385
 
                                           KIconLoader::SizeEnormous);
386
 
        m_preview->setPixmap(icon);
387
 
        setNameLabelText(i18ncp("@info", "%1 item selected", "%1 items selected",  m_selection.count()));
 
163
        m_content->showItems(m_selection);
388
164
        m_shownUrl = KUrl();
389
165
    } else {
390
 
        const KFileItem item = updateFileItem();
391
 
        const KUrl itemUrl = item.url();
392
 
        if (!applyPlace(itemUrl)) {
393
 
            // try to get a preview pixmap from the item...
394
 
            m_pendingPreview = true;
395
 
 
396
 
            // Mark the currently shown preview as outdated. This is done
397
 
            // with a small delay to prevent a flickering when the next preview
398
 
            // can be shown within a short timeframe. This timer is not started
399
 
            // for directories, as directory previews might fail and return the
400
 
            // same icon.
401
 
            if (!item.isDir()) {
402
 
                m_outdatedPreviewTimer->start();
403
 
            }
404
 
 
405
 
            KIO::PreviewJob* job = KIO::filePreview(KFileItemList() << item,
406
 
                                                    m_preview->width(),
407
 
                                                    m_preview->height(),
408
 
                                                    0,
409
 
                                                    0,
410
 
                                                    false,
411
 
                                                    true);
412
 
 
413
 
            connect(job, SIGNAL(gotPreview(const KFileItem&, const QPixmap&)),
414
 
                    this, SLOT(showPreview(const KFileItem&, const QPixmap&)));
415
 
            connect(job, SIGNAL(failed(const KFileItem&)),
416
 
                    this, SLOT(showIcon(const KFileItem&)));
417
 
 
418
 
            setNameLabelText(itemUrl.fileName());
 
166
        KFileItem item;
 
167
        if (!m_fileItem.isNull()) {
 
168
            item = m_fileItem;
 
169
        } else if (!m_selection.isEmpty()) {
 
170
            Q_ASSERT(m_selection.count() == 1);
 
171
            item = m_selection.first();
 
172
        } else {
 
173
            // no item is hovered and no selection has been done: provide
 
174
            // an item for the directory represented by m_shownUrl
 
175
            item = KFileItem(KFileItem::Unknown, KFileItem::Unknown, m_shownUrl);
 
176
            item.refresh();
419
177
        }
 
178
 
 
179
        m_content->showItem(item);
420
180
    }
421
 
 
422
 
    showMetaInfo();
423
181
}
424
182
 
425
183
void InformationPanel::slotInfoTimeout()
428
186
    showItemInfo();
429
187
}
430
188
 
431
 
void InformationPanel::markOutdatedPreview()
432
 
{
433
 
    KIconEffect iconEffect;
434
 
    QPixmap disabledPixmap = iconEffect.apply(m_preview->pixmap(),
435
 
                                              KIconLoader::Desktop,
436
 
                                              KIconLoader::DisabledState);
437
 
    m_preview->setPixmap(disabledPixmap);
438
 
}
439
 
 
440
 
void InformationPanel::showIcon(const KFileItem& item)
441
 
{
442
 
    m_outdatedPreviewTimer->stop();
443
 
    m_pendingPreview = false;
444
 
    if (!applyPlace(item.url())) {
445
 
        m_preview->setPixmap(item.pixmap(KIconLoader::SizeEnormous));
446
 
    }
447
 
}
448
 
 
449
 
void InformationPanel::showPreview(const KFileItem& item,
450
 
                                  const QPixmap& pixmap)
451
 
{
452
 
    m_outdatedPreviewTimer->stop();
453
 
 
454
 
    Q_UNUSED(item);
455
 
    if (m_pendingPreview) {
456
 
        m_preview->setPixmap(pixmap);
457
 
        m_pendingPreview = false;
458
 
    }
459
 
}
460
 
 
461
189
void InformationPanel::reset()
462
190
{
463
191
    if (m_invalidUrlCandidate == m_shownUrl) {
477
205
    if (m_shownUrl == KUrl(source)) {
478
206
        m_shownUrl = KUrl(dest);
479
207
        m_fileItem = KFileItem(KFileItem::Unknown, KFileItem::Unknown, m_shownUrl);
 
208
 
 
209
        if ((m_selection.count() == 1) && (m_selection[0].url() == KUrl(source))) {
 
210
            m_selection[0] = m_fileItem;
 
211
            // Implementation note: Updating the selection is only required if exactly one
 
212
            // item is selected, as the name of the item is shown. If this should change
 
213
            // in future: Before parsing the whole selection take care to test possible
 
214
            // performance bottlenecks when renaming several hundreds of files.
 
215
        }
 
216
 
480
217
        showItemInfo();
481
218
    }
482
219
}
527
264
        // The signal 'leftDirectory' is also emitted when a media
528
265
        // has been unmounted. In this case no directory change will be
529
266
        // done in Dolphin, but the Information Panel must be updated to
530
 
        // indicate an invalid directory.       
 
267
        // indicate an invalid directory.
531
268
        markUrlAsInvalid();
532
269
    }
533
270
}
534
271
 
535
 
void InformationPanel::slotPlayingStarted()
536
 
{
537
 
    m_preview->setVisible(m_phononWidget->mode() != PhononWidget::Video);
538
 
}
539
 
 
540
 
void InformationPanel::slotPlayingStopped()
541
 
{
542
 
    m_preview->setVisible(true);
543
 
}
544
 
 
545
 
bool InformationPanel::applyPlace(const KUrl& url)
546
 
{
547
 
    KFilePlacesModel* placesModel = DolphinSettings::instance().placesModel();
548
 
    int count = placesModel->rowCount();
549
 
 
550
 
    for (int i = 0; i < count; ++i) {
551
 
        QModelIndex index = placesModel->index(i, 0);
552
 
 
553
 
        if (url.equals(placesModel->url(index), KUrl::CompareWithoutTrailingSlash)) {
554
 
            setNameLabelText(placesModel->text(index));
555
 
            m_preview->setPixmap(placesModel->icon(index).pixmap(128, 128));
556
 
            return true;
557
 
        }
558
 
    }
559
 
 
560
 
    return false;
561
 
}
562
 
 
563
272
void InformationPanel::cancelRequest()
564
273
{
565
274
    m_infoTimer->stop();
566
275
}
567
276
 
568
 
void InformationPanel::showMetaInfo()
569
 
{
570
 
    m_metaTextLabel->clear();
571
 
 
572
 
    if (showMultipleSelectionInfo()) {
573
 
        if (m_metaDataWidget != 0) {
574
 
            KUrl::List urls;
575
 
            foreach (const KFileItem& item, m_selection) {
576
 
                urls.append(item.targetUrl());
577
 
            }
578
 
            m_metaDataWidget->setFiles(urls);
579
 
        }
580
 
 
581
 
        quint64 totalSize = 0;
582
 
        foreach (const KFileItem& item, m_selection) {
583
 
            // Only count the size of files, not dirs to match what
584
 
            // DolphinViewContainer::selectionStatusBarText() does.
585
 
            if (!item.isDir() && !item.isLink()) {
586
 
                totalSize += item.size();
587
 
            }
588
 
        }
589
 
        m_metaTextLabel->add(i18nc("@label", "Total size:"), KIO::convertSize(totalSize));
590
 
    } else {
591
 
        const KFileItem item = updateFileItem();
592
 
        if (item.isDir()) {
593
 
            m_metaTextLabel->add(i18nc("@label", "Type:"), i18nc("@label", "Folder"));
594
 
            m_metaTextLabel->add(i18nc("@label", "Modified:"), item.timeString());
595
 
        } else {
596
 
            m_metaTextLabel->add(i18nc("@label", "Type:"), item.mimeComment());
597
 
 
598
 
            m_metaTextLabel->add(i18nc("@label", "Size:"), KIO::convertSize(item.size()));
599
 
            m_metaTextLabel->add(i18nc("@label", "Modified:"), item.timeString());
600
 
 
601
 
#ifdef HAVE_NEPOMUK
602
 
            KConfig config("kmetainformationrc", KConfig::NoGlobals);
603
 
            KConfigGroup settings = config.group("Show");
604
 
            initMetaInfoSettings(settings);
605
 
 
606
 
            Nepomuk::Resource res(item.url());
607
 
 
608
 
            QHash<QUrl, Nepomuk::Variant> properties = res.properties();
609
 
            QHash<QUrl, Nepomuk::Variant>::const_iterator it = properties.constBegin();
610
 
            while (it != properties.constEnd()) {
611
 
                Nepomuk::Types::Property prop(it.key());
612
 
                if (settings.readEntry(prop.name(), true)) {
613
 
                    // TODO #1: use Nepomuk::formatValue(res, prop) if available
614
 
                    // instead of it.value().toString()
615
 
                    // TODO #2: using tunedLabel() is a workaround for KDE 4.3 until
616
 
                    // we get translated labels
617
 
                    m_metaTextLabel->add(tunedLabel(prop.label()) + ':', it.value().toString());
618
 
                }
619
 
                ++it;
620
 
            }
621
 
#endif
622
 
        }
623
 
 
624
 
        if (m_metaDataWidget != 0) {
625
 
            m_metaDataWidget->setFile(item.targetUrl());
626
 
        }
627
 
    }
628
 
 
629
 
    updatePhononWidget();
630
 
}
631
 
 
632
 
KFileItem InformationPanel::updateFileItem()
633
 
{
634
 
    if (!m_fileItem.isNull()) {
635
 
        return m_fileItem;
636
 
    }
637
 
 
638
 
    if (!m_selection.isEmpty()) {
639
 
        Q_ASSERT(m_selection.count() == 1);
640
 
        return m_selection.first();
641
 
    }
642
 
 
643
 
    // no item is hovered and no selection has been done: provide
644
 
    // an item for the directory represented by m_shownUrl
645
 
    m_fileItem = KFileItem(KFileItem::Unknown, KFileItem::Unknown, m_shownUrl);
646
 
    m_fileItem.refresh();
647
 
    return m_fileItem;
648
 
}
649
 
 
650
277
bool InformationPanel::showMultipleSelectionInfo() const
651
278
{
652
279
    return m_fileItem.isNull() && (m_selection.count() > 1);
657
284
    return m_shownUrl.equals(url, KUrl::CompareWithoutTrailingSlash);
658
285
}
659
286
 
660
 
void InformationPanel::setNameLabelText(const QString& text)
661
 
{
662
 
    QTextOption textOption;
663
 
    textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
664
 
 
665
 
    QTextLayout textLayout(text);
666
 
    textLayout.setFont(m_nameLabel->font());
667
 
    textLayout.setTextOption(textOption);
668
 
 
669
 
    QString wrappedText;
670
 
    wrappedText.reserve(text.length());
671
 
 
672
 
    // wrap the text to fit into the width of m_nameLabel
673
 
    textLayout.beginLayout();
674
 
    QTextLine line = textLayout.createLine();
675
 
    while (line.isValid()) {
676
 
        line.setLineWidth(m_nameLabel->width());
677
 
        wrappedText += text.mid(line.textStart(), line.textLength());
678
 
 
679
 
        line = textLayout.createLine();
680
 
        if (line.isValid()) {
681
 
            wrappedText += QChar::LineSeparator;
682
 
        }
683
 
    }
684
 
    textLayout.endLayout();
685
 
 
686
 
    m_nameLabel->setText(wrappedText);
687
 
}
688
 
 
689
287
void InformationPanel::markUrlAsInvalid()
690
288
{
691
289
    m_invalidUrlCandidate = m_shownUrl;
692
290
    m_resetUrlTimer->start();
693
291
}
694
292
 
695
 
void InformationPanel::initMetaInfoSettings(KConfigGroup& group)
696
 
{
697
 
    if (!group.readEntry("initialized", false)) {
698
 
        // The resource file is read the first time. Assure
699
 
        // that some meta information is disabled per default.
700
 
 
701
 
        static const char* disabledProperties[] = {
702
 
            "asText", "contentSize", "depth", "fileExtension",
703
 
            "fileName", "fileSize", "isPartOf", "mimetype", "name",
704
 
            "parentUrl", "plainTextContent", "sourceModified",
705
 
            "size", "url",
706
 
            0 // mandatory last entry
707
 
        };
708
 
 
709
 
        int i = 0;
710
 
        while (disabledProperties[i] != 0) {
711
 
            group.writeEntry(disabledProperties[i], false);
712
 
            ++i;
713
 
        }
714
 
 
715
 
        // mark the group as initialized
716
 
        group.writeEntry("initialized", true);
717
 
    }
718
 
}
719
 
 
720
 
void InformationPanel::updatePhononWidget()
721
 
{
722
 
    const bool multipleSelections = showMultipleSelectionInfo();
723
 
    const bool showPreview = InformationPanelSettings::showPreview();
724
 
 
725
 
    if (multipleSelections || !showPreview) {
726
 
        m_phononWidget->hide();
727
 
    } else if (!multipleSelections && showPreview) {
728
 
        const KFileItem item = updateFileItem();
729
 
        const QString mimeType = item.mimetype();
730
 
        const bool usePhonon = Phonon::BackendCapabilities::isMimeTypeAvailable(mimeType) &&
731
 
                               (mimeType != "image/png");  // TODO: workaround, as Phonon
732
 
                                                           // thinks it supports PNG images
733
 
        if (usePhonon) {
734
 
            m_phononWidget->show();
735
 
            PhononWidget::Mode mode = mimeType.startsWith(QLatin1String("video"))
736
 
                                      ? PhononWidget::Video
737
 
                                      : PhononWidget::Audio;
738
 
            m_phononWidget->setMode(mode);
739
 
            m_phononWidget->setUrl(item.url());
740
 
            if ((mode == PhononWidget::Video) && m_preview->isVisible()) {
741
 
                m_phononWidget->setVideoSize(m_preview->size());
742
 
            }
743
 
        } else {
744
 
            m_phononWidget->hide();
745
 
            m_preview->setVisible(true);
746
 
        }
747
 
    }
748
 
}
749
 
 
750
 
QString InformationPanel::tunedLabel(const QString& label) const
751
 
{
752
 
    QString tunedLabel;
753
 
    const int labelLength = label.length();
754
 
    if (labelLength > 0) {
755
 
        tunedLabel.reserve(labelLength);
756
 
        tunedLabel = label[0].toUpper();
757
 
        for (int i = 1; i < labelLength; ++i) {
758
 
            if (label[i].isUpper() && !label[i - 1].isSpace() && !label[i - 1].isUpper()) {
759
 
                tunedLabel += ' ';
760
 
                tunedLabel += label[i].toLower();
761
 
            } else {
762
 
                tunedLabel += label[i];
763
 
            }
764
 
        }
765
 
    }
766
 
    return tunedLabel;
767
 
}
768
 
 
769
293
void InformationPanel::init()
770
294
{
771
295
    const int defaultDelay = 300;
776
300
    connect(m_infoTimer, SIGNAL(timeout()),
777
301
            this, SLOT(slotInfoTimeout()));
778
302
 
779
 
    // Initialize timer for disabling an outdated preview with a small
780
 
    // delay. This prevents flickering if the new preview can be generated
781
 
    // within a very small timeframe.
782
 
    m_outdatedPreviewTimer = new QTimer(this);
783
 
    m_outdatedPreviewTimer->setInterval(defaultDelay);
784
 
    m_outdatedPreviewTimer->setSingleShot(true);
785
 
    connect(m_outdatedPreviewTimer, SIGNAL(timeout()),
786
 
            this, SLOT(markOutdatedPreview()));
787
 
 
788
303
    m_urlChangedTimer = new QTimer(this);
789
304
    m_urlChangedTimer->setInterval(defaultDelay);
790
305
    m_urlChangedTimer->setSingleShot(true);
797
312
    connect(m_resetUrlTimer, SIGNAL(timeout()),
798
313
            this, SLOT(reset()));
799
314
 
800
 
    QVBoxLayout* layout = new QVBoxLayout;
801
 
    layout->setSpacing(KDialog::spacingHint());
802
 
 
803
 
    // name
804
 
    m_nameLabel = new QLabel(this);
805
 
    QFont font = m_nameLabel->font();
806
 
    font.setBold(true);
807
 
    m_nameLabel->setFont(font);
808
 
    m_nameLabel->setAlignment(Qt::AlignHCenter);
809
 
    m_nameLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
810
 
    m_nameLabel->setMaximumWidth(KIconLoader::SizeEnormous);
811
 
 
812
 
    // preview
813
 
    const int minPreviewWidth = KIconLoader::SizeEnormous + KIconLoader::SizeMedium;
814
 
 
815
 
    m_preview = new PixmapViewer(this);
816
 
    m_preview->setMinimumWidth(minPreviewWidth);
817
 
    m_preview->setMinimumHeight(KIconLoader::SizeEnormous);
818
 
 
819
 
    m_phononWidget = new PhononWidget(this);
820
 
    m_phononWidget->setMinimumWidth(minPreviewWidth);
821
 
    connect(m_phononWidget, SIGNAL(playingStarted()),
822
 
            this, SLOT(slotPlayingStarted()));
823
 
    connect(m_phononWidget, SIGNAL(playingStopped()),
824
 
            this, SLOT(slotPlayingStopped()));
825
 
 
826
 
    m_previewSeparator = new KSeparator(this);
827
 
 
828
 
    const bool showPreview = InformationPanelSettings::showPreview();
829
 
    m_preview->setVisible(showPreview);
830
 
    m_previewSeparator->setVisible(showPreview);
831
 
 
832
 
    if (MetaDataWidget::metaDataAvailable()) {
833
 
        // rating, comment and tags
834
 
        m_metaDataWidget = new MetaDataWidget(this);
835
 
        m_metaDataWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
836
 
        m_metaDataWidget->setMaximumWidth(KIconLoader::SizeEnormous);
837
 
 
838
 
        const bool showRating  = InformationPanelSettings::showRating();
839
 
        const bool showComment = InformationPanelSettings::showComment();
840
 
        const bool showTags    = InformationPanelSettings::showTags();
841
 
 
842
 
        m_metaDataWidget->setRatingVisible(showRating);
843
 
        m_metaDataWidget->setCommentVisible(showComment);
844
 
        m_metaDataWidget->setTagsVisible(showTags);
845
 
 
846
 
        m_metaDataSeparator = new KSeparator(this);
847
 
        m_metaDataSeparator->setVisible(showRating || showComment || showTags);
848
 
    }
849
 
 
850
 
    // general meta text information
851
 
    m_metaTextLabel = new MetaTextLabel(this);
852
 
    m_metaTextLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
853
 
 
854
 
    m_metaTextArea = new QScrollArea(this);
855
 
    m_metaTextArea->setWidget(m_metaTextLabel);
856
 
    m_metaTextArea->setWidgetResizable(true);
857
 
    m_metaTextArea->setFrameShape(QFrame::NoFrame);
858
 
 
859
 
    QWidget* viewport = m_metaTextArea->viewport();
860
 
    viewport->installEventFilter(this);
861
 
 
862
 
    QPalette palette = viewport->palette();
863
 
    palette.setColor(viewport->backgroundRole(), QColor(Qt::transparent));
864
 
    viewport->setPalette(palette);
865
 
 
866
 
    layout->addWidget(m_nameLabel);
867
 
    layout->addWidget(new KSeparator(this));
868
 
    layout->addWidget(m_preview);
869
 
    layout->addWidget(m_phononWidget);
870
 
    layout->addWidget(m_previewSeparator);
871
 
    if (m_metaDataWidget != 0) {
872
 
        layout->addWidget(m_metaDataWidget);
873
 
        layout->addWidget(m_metaDataSeparator);
874
 
    }
875
 
    layout->addWidget(m_metaTextArea);
876
 
    setLayout(layout);
877
 
 
878
315
    org::kde::KDirNotify* dirNotify = new org::kde::KDirNotify(QString(), QString(),
879
316
                                                               QDBusConnection::sessionBus(), this);
880
317
    connect(dirNotify, SIGNAL(FileRenamed(QString, QString)), SLOT(slotFileRenamed(QString, QString)));
884
321
    connect(dirNotify, SIGNAL(enteredDirectory(QString)), SLOT(slotEnteredDirectory(QString)));
885
322
    connect(dirNotify, SIGNAL(leftDirectory(QString)), SLOT(slotLeftDirectory(QString)));
886
323
 
 
324
    m_content = new InformationPanelContent(this);
 
325
    connect(m_content, SIGNAL(urlActivated(KUrl)), this, SIGNAL(urlActivated(KUrl)));
 
326
 
887
327
    m_initialized = true;
888
328
}
889
329