X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/2ed4d8dcc483ac6067149647eb457d46be7111c5..50acc2d6ecbae2fb3c228bf779b23eabf3346cb1:/src/infosidebarpage.cpp diff --git a/src/infosidebarpage.cpp b/src/infosidebarpage.cpp index 07887e2bd..a4c3d4157 100644 --- a/src/infosidebarpage.cpp +++ b/src/infosidebarpage.cpp @@ -17,22 +17,9 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * ***************************************************************************/ -#include - #include "infosidebarpage.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include #include @@ -42,63 +29,108 @@ #include #include #include -#include #include #include -#include "pixmapviewer.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include "dolphinsettings.h" #include "metadatawidget.h" +#include "metatextlabel.h" +#include "pixmapviewer.h" + +class InfoSeparator : public QWidget +{ +public: + InfoSeparator(QWidget* parent); + virtual ~InfoSeparator(); + +protected: + virtual void paintEvent(QPaintEvent* event); +}; + +InfoSeparator::InfoSeparator(QWidget* parent) : + QWidget(parent) +{ + setMinimumSize(0, 8); +} + +InfoSeparator::~InfoSeparator() +{ +} + +void InfoSeparator::paintEvent(QPaintEvent* event) +{ + Q_UNUSED(event); + QPainter painter(this); + + QStyleOptionMenuItem option; + option.initFrom(this); + option.menuItemType = QStyleOptionMenuItem::Separator; + style()->drawControl(QStyle::CE_MenuItem, &option, &painter, this); +} InfoSidebarPage::InfoSidebarPage(QWidget* parent) : SidebarPage(parent), - m_multipleSelection(false), //TODO: check if I'm needed m_pendingPreview(false), - m_timer(0), + m_shownUrl(), + m_urlCandidate(), + m_fileItem(), + m_nameLabel(0), m_preview(0), - m_name(0), - m_infos(0), - m_metadataWidget(0) + m_metaDataWidget(0), + m_metaTextLabel(0) { const int spacing = KDialog::spacingHint(); m_timer = new QTimer(this); + m_timer->setSingleShot(true); connect(m_timer, SIGNAL(timeout()), this, SLOT(slotTimeout())); QVBoxLayout* layout = new QVBoxLayout; layout->setSpacing(spacing); - // preview - m_preview = new PixmapViewer(this); - m_preview->setMinimumWidth(K3Icon::SizeEnormous); - m_preview->setFixedHeight(K3Icon::SizeEnormous); - // name - m_name = new QLabel(this); - m_name->setTextFormat(Qt::RichText); - m_name->setAlignment(m_name->alignment() | Qt::AlignHCenter); - m_name->setWordWrap(true); + m_nameLabel = new QLabel(this); + QFont font = m_nameLabel->font(); + font.setBold(true); + m_nameLabel->setFont(font); + m_nameLabel->setAlignment(Qt::AlignHCenter); + m_nameLabel->setWordWrap(true); - // general information - m_infos = new QLabel(this); - m_infos->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); - m_infos->setTextFormat(Qt::RichText); + // preview + m_preview = new PixmapViewer(this); + m_preview->setMinimumWidth(KIconLoader::SizeEnormous + KIconLoader::SizeMedium); + m_preview->setMinimumHeight(KIconLoader::SizeEnormous); if (MetaDataWidget::metaDataAvailable()) { - m_metadataWidget = new MetaDataWidget(this); + // rating, comment and tags + m_metaDataWidget = new MetaDataWidget(this); } - layout->addItem(new QSpacerItem(spacing, spacing, QSizePolicy::Preferred, QSizePolicy::Fixed)); + // general meta text information + m_metaTextLabel = new MetaTextLabel(this); + m_metaTextLabel->setMinimumWidth(spacing); + + layout->addWidget(m_nameLabel); + layout->addWidget(new InfoSeparator(this)); layout->addWidget(m_preview); - layout->addWidget(m_name); - layout->addWidget(new KSeparator(this)); - layout->addWidget(m_infos); - layout->addWidget(new KSeparator(this)); - if (m_metadataWidget) { - layout->addWidget(m_metadataWidget); - layout->addWidget(new KSeparator(this)); + layout->addWidget(new InfoSeparator(this)); + if (m_metaDataWidget != 0) { + layout->addWidget(m_metaDataWidget); + layout->addWidget(new InfoSeparator(this)); } + layout->addWidget(m_metaTextLabel); + // ensure that widgets in the information side bar are aligned towards the top layout->addStretch(1); setLayout(layout); @@ -108,9 +140,17 @@ InfoSidebarPage::~InfoSidebarPage() { } +QSize InfoSidebarPage::sizeHint() const +{ + QSize size = SidebarPage::sizeHint(); + size.setWidth(minimumSizeHint().width()); + return size; +} + void InfoSidebarPage::setUrl(const KUrl& url) { - if (!m_shownUrl.equals(url, KUrl::CompareWithoutTrailingSlash)) { + SidebarPage::setUrl(url); + if (url.isValid() && !m_shownUrl.equals(url, KUrl::CompareWithoutTrailingSlash)) { cancelRequest(); m_shownUrl = url; showItemInfo(); @@ -119,36 +159,61 @@ void InfoSidebarPage::setUrl(const KUrl& url) void InfoSidebarPage::setSelection(const KFileItemList& selection) { - cancelRequest(); SidebarPage::setSelection(selection); - m_multipleSelection = (selection.size() > 1); - showItemInfo(); + + const int count = selection.count(); + if (count == 0) { + m_shownUrl = url(); + showItemInfo(); + } else { + if ((count == 1) && !selection.first().url().isEmpty()) { + m_urlCandidate = selection.first().url(); + } + m_timer->start(TimerDelay); + } } -void InfoSidebarPage::requestDelayedItemInfo(const KUrl& url) +void InfoSidebarPage::requestDelayedItemInfo(const KFileItem& item) { cancelRequest(); - if (!url.isEmpty() && !m_multipleSelection) { - m_urlCandidate = url; - m_timer->setSingleShot(true); - m_timer->start(300); + m_fileItem = KFileItem(); + if (item.isNull()) { + // The cursor is above the viewport. If files are selected, + // show information regarding the selection. + if (selection().size() > 0) { + m_timer->start(TimerDelay); + } + } else if (!item.url().isEmpty()) { + m_urlCandidate = item.url(); + m_fileItem = item; + m_timer->start(TimerDelay); } } void InfoSidebarPage::showEvent(QShowEvent* event) { SidebarPage::showEvent(event); - showItemInfo(); + if (!event->spontaneous()) { + showItemInfo(); + } } void InfoSidebarPage::resizeEvent(QResizeEvent* event) { - // If the item name cannot get wrapped, the maximum width of - // the label is increased, so that the width of the information sidebar - // gets increased. To prevent this, the maximum width is adjusted to + // If the text inside the name label or the info label cannot + // get wrapped, then the maximum width of the label is increased + // so that the width of the information sidebar gets increased. + // To prevent this, the maximum width is adjusted to // the current width of the sidebar. - m_name->setMaximumWidth(event->size().width() - KDialog::spacingHint() * 4); + const int maxWidth = event->size().width() - KDialog::spacingHint() * 4; + m_nameLabel->setMaximumWidth(maxWidth); + + // try to increase the preview as large as possible + m_preview->setSizeHint(QSize(maxWidth, maxWidth)); + m_urlCandidate = m_shownUrl; // reset the URL candidate if a resizing is done + m_timer->start(TimerDelay); + SidebarPage::resizeEvent(event); } @@ -161,21 +226,20 @@ void InfoSidebarPage::showItemInfo() cancelRequest(); const KFileItemList& selectedItems = selection(); - - KUrl file; - if (selectedItems.count() == 0) { - file = m_shownUrl; - } else { - file = selectedItems[0]->url(); + const KUrl file = (!m_fileItem.isNull() || selectedItems.isEmpty()) ? m_shownUrl : selectedItems[0].url(); + if (!file.isValid()) { + return; } - if (m_multipleSelection) { + + const int selectionCount = selectedItems.count(); + if (m_fileItem.isNull() && (selectionCount > 1)) { KIconLoader iconLoader; - QPixmap icon = iconLoader.loadIcon("exec", - K3Icon::NoGroup, - K3Icon::SizeEnormous); + QPixmap icon = iconLoader.loadIcon("dialog-information", + KIconLoader::NoGroup, + KIconLoader::SizeEnormous); m_preview->setPixmap(icon); - m_name->setText(i18n("%1 items selected", selectedItems.count())); - } else if (!applyBookmark(file)) { + m_nameLabel->setText(i18ncp("@info", "%1 item selected", "%1 items selected", selectionCount)); + } else if (!applyPlace(file)) { // try to get a preview pixmap from the item... KUrl::List list; list.append(file); @@ -185,7 +249,7 @@ void InfoSidebarPage::showItemInfo() KIO::PreviewJob* job = KIO::filePreview(list, m_preview->width(), - K3Icon::SizeEnormous, + m_preview->height(), 0, 0, true, @@ -197,13 +261,10 @@ void InfoSidebarPage::showItemInfo() connect(job, SIGNAL(failed(const KFileItem&)), this, SLOT(showIcon(const KFileItem&))); - QString text(""); - text.append(file.fileName()); - text.append(""); - m_name->setText(text); + m_nameLabel->setText(file.fileName()); } - createMetaInfo(); + showMetaInfo(); } void InfoSidebarPage::slotTimeout() @@ -215,8 +276,8 @@ void InfoSidebarPage::slotTimeout() void InfoSidebarPage::showIcon(const KFileItem& item) { m_pendingPreview = false; - if (!applyBookmark(item.url())) { - m_preview->setPixmap(item.pixmap(K3Icon::SizeEnormous)); + if (!applyPlace(item.url())) { + m_preview->setPixmap(item.pixmap(KIconLoader::SizeEnormous)); } } @@ -230,7 +291,7 @@ void InfoSidebarPage::showPreview(const KFileItem& item, } } -bool InfoSidebarPage::applyBookmark(const KUrl& url) +bool InfoSidebarPage::applyPlace(const KUrl& url) { KFilePlacesModel* placesModel = DolphinSettings::instance().placesModel(); int count = placesModel->rowCount(); @@ -239,11 +300,7 @@ bool InfoSidebarPage::applyBookmark(const KUrl& url) QModelIndex index = placesModel->index(i, 0); if (url.equals(placesModel->url(index), KUrl::CompareWithoutTrailingSlash)) { - QString text(""); - text.append(placesModel->text(index)); - text.append(""); - m_name->setText(text); - + m_nameLabel->setText(placesModel->text(index)); m_preview->setPixmap(placesModel->icon(index).pixmap(128, 128)); return true; } @@ -255,97 +312,112 @@ bool InfoSidebarPage::applyBookmark(const KUrl& url) void InfoSidebarPage::cancelRequest() { m_timer->stop(); - m_pendingPreview = false; } -void InfoSidebarPage::createMetaInfo() +void InfoSidebarPage::showMetaInfo() { - beginInfoLines(); + m_metaTextLabel->clear(); + const KFileItemList& selectedItems = selection(); - if (selectedItems.size() == 0) { - KFileItem fileItem(S_IFDIR, KFileItem::Unknown, m_shownUrl); - fileItem.refresh(); + if ((selectedItems.size() <= 1) || !m_fileItem.isNull()) { + KFileItem fileItem; + if (m_fileItem.isNull()) { + // no pending request is ongoing + const KUrl url = (selectedItems.size() == 1) ? selectedItems.first().url() : m_shownUrl; + fileItem = KFileItem(KFileItem::Unknown, KFileItem::Unknown, url); + fileItem.refresh(); + } else { + fileItem = m_fileItem; + } if (fileItem.isDir()) { - addInfoLine(i18n("Type:"), i18n("Directory")); - } - if (MetaDataWidget::metaDataAvailable()) { - m_metadataWidget->setFile(fileItem.url()); - } - } else if (selectedItems.count() == 1) { - KFileItem* fileItem = selectedItems.at(0); - addInfoLine(i18n("Type:"), fileItem->mimeComment()); - - QString sizeText(KIO::convertSize(fileItem->size())); - addInfoLine(i18n("Size:"), sizeText); - addInfoLine(i18n("Modified:"), fileItem->timeString()); - - const KFileMetaInfo& metaInfo = fileItem->metaInfo(); - if (metaInfo.isValid()) { - QStringList keys = metaInfo.supportedKeys(); - for (QStringList::Iterator it = keys.begin(); it != keys.end(); ++it) { - if (showMetaInfo(*it)) { - KFileMetaInfoItem metaInfoItem = metaInfo.item(*it); - addInfoLine(*it, metaInfoItem.value().toString()); + m_metaTextLabel->add(i18nc("@label", "Type:"), i18nc("@label", "Folder")); + m_metaTextLabel->add(i18nc("@label", "Modified:"), fileItem.timeString()); + } else { + m_metaTextLabel->add(i18nc("@label", "Type:"), fileItem.mimeComment()); + + m_metaTextLabel->add(i18nc("@label", "Size:"), KIO::convertSize(fileItem.size())); + m_metaTextLabel->add(i18nc("@label", "Modified:"), fileItem.timeString()); + + // TODO: See convertMetaInfo below, find a way to display only interesting information + // in a readable way + const KFileMetaInfo::WhatFlags flags = KFileMetaInfo::Fastest | + KFileMetaInfo::TechnicalInfo | + KFileMetaInfo::ContentInfo | + KFileMetaInfo::Thumbnail; + const QString path = fileItem.url().url(); + const KFileMetaInfo fileMetaInfo(path, QString(), flags); + if (fileMetaInfo.isValid()) { + const QHash& items = fileMetaInfo.items(); + QHash::const_iterator it = items.constBegin(); + const QHash::const_iterator end = items.constEnd(); + QString labelText; + while (it != end) { + const KFileMetaInfoItem& metaInfoItem = it.value(); + const QVariant& value = metaInfoItem.value(); + if (value.isValid() && convertMetaInfo(metaInfoItem.name(), labelText)) { + m_metaTextLabel->add(labelText, value.toString()); + } + ++it; } } } - if (MetaDataWidget::metaDataAvailable()) { - m_metadataWidget->setFile(fileItem->url()); + + if (m_metaDataWidget != 0) { + m_metaDataWidget->setFile(fileItem.targetUrl()); } } else { - if (MetaDataWidget::metaDataAvailable()) { - m_metadataWidget->setFiles(selectedItems.urlList()); + if (m_metaDataWidget != 0) { + KUrl::List urls; + foreach (const KFileItem& item, selectedItems) { + urls.append(item.targetUrl()); + } + m_metaDataWidget->setFiles(urls); } - unsigned long int totSize = 0; - foreach(KFileItem* item, selectedItems) { - totSize += item->size(); //FIXME what to do with directories ? (same with the one-item-selected-code), item->size() does not return the size of the content : not very instinctive for users + unsigned long int totalSize = 0; + foreach (const KFileItem& item, selectedItems) { + // Only count the size of files, not dirs to match what + // DolphinViewContainer::selectionStatusBarText() does. + if (!item.isDir() && !item.isLink()) { + totalSize += item.size(); + } } - addInfoLine(i18n("Total size:"), KIO::convertSize(totSize)); + m_metaTextLabel->add(i18nc("@label", "Total size:"), KIO::convertSize(totalSize)); } - endInfoLines(); } -void InfoSidebarPage::beginInfoLines() +bool InfoSidebarPage::convertMetaInfo(const QString& key, QString& text) const { - m_infoLines = QString(); -} - -void InfoSidebarPage::endInfoLines() -{ - m_infos->setText(m_infoLines); -} - -bool InfoSidebarPage::showMetaInfo(const QString& key) const -{ - // sorted list of keys, where it's data should be shown - static const char* keys[] = { - "Album", - "Artist", - "Author", - "Bitrate", - "Date", - "Dimensions", - "Genre", - "Length", - "Lines", - "Pages", - "Title", - "Words" - }; + // TODO: This code prevents that interesting meta information might be hidden + // and only bypasses the current problem that not all the meta information should + // be shown to the user. Check whether it's possible with Nepomuk to show + // all "user relevant" information in a readable way... + + struct MetaKey { + const char* key; + const char* text; + }; + + // sorted list of keys, where its data should be shown + static const MetaKey keys[] = { + { "audio.album", "Album:" }, + { "audio.artist", "Artist:" }, + { "audio.title", "Title:" }, + }; // do a binary search for the key... int top = 0; - int bottom = sizeof(keys) / sizeof(char*) - 1; - while (top < bottom) { + int bottom = sizeof(keys) / sizeof(MetaKey) - 1; + while (top <= bottom) { const int middle = (top + bottom) / 2; - const int result = key.compare(keys[middle]); + const int result = key.compare(keys[middle].key); if (result < 0) { bottom = middle - 1; } else if (result > 0) { top = middle + 1; } else { + text = keys[middle].text; return true; } } @@ -353,12 +425,4 @@ bool InfoSidebarPage::showMetaInfo(const QString& key) const return false; } -void InfoSidebarPage::addInfoLine(const QString& labelText, const QString& infoText) -{ - if (!m_infoLines.isEmpty()) { - m_infoLines += "
"; - } - m_infoLines += QString("%1 %2").arg(labelText).arg(infoText); -} - #include "infosidebarpage.moc"