dolphin/src/infosidebarpage.cpp
Peter Penz bafaf9496c some cleanups for the sidebar pages (move protected members to private section etc.)
svn path=/trunk/KDE/kdebase/apps/; revision=661815
2007-05-06 17:25:50 +00:00

350 lines
11 KiB
C++

/***************************************************************************
* Copyright (C) 2006 by Peter Penz <peter.penz@gmx.at> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
#include <config-kmetadata.h>
#include "infosidebarpage.h"
#include <QLayout>
#include <QPixmap>
#include <QLabel>
#include <QTimer>
#include <QPushButton>
#include <QMenu>
#include <QPainter>
#include <QFontMetrics>
#include <QEvent>
#include <QInputDialog>
#include <QDir>
#include <kfileplacesmodel.h>
#include <klocale.h>
#include <kstandarddirs.h>
#include <kio/previewjob.h>
#include <kfileitem.h>
#include <kdialog.h>
#include <kglobalsettings.h>
#include <kfilemetainfo.h>
#include <kvbox.h>
#include <kseparator.h>
#include <kiconloader.h>
#include "pixmapviewer.h"
#include "dolphinsettings.h"
#include "metadatawidget.h"
InfoSidebarPage::InfoSidebarPage(QWidget* parent) :
SidebarPage(parent),
m_multipleSelection(false), //TODO: check if I'm needed
m_pendingPreview(false),
m_timer(0),
m_preview(0),
m_name(0),
m_infos(0),
m_metadataWidget(0)
{
const int spacing = KDialog::spacingHint();
m_timer = new QTimer(this);
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);
QFontMetrics fontMetrics(m_name->font());
m_name->setMinimumHeight(fontMetrics.height() * 3);
m_name->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Maximum);
KSeparator* sep1 = new KSeparator(this);
// general information
m_infos = new QLabel(this);
m_infos->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
m_infos->setTextFormat(Qt::RichText);
KSeparator* sep2 = new KSeparator(this);
if (MetaDataWidget::metaDataAvailable()) {
m_metadataWidget = new MetaDataWidget(this);
}
layout->addItem(new QSpacerItem(spacing, spacing, QSizePolicy::Preferred, QSizePolicy::Fixed));
layout->addWidget(m_preview);
layout->addWidget(m_name);
layout->addWidget(sep1);
layout->addWidget(m_infos);
layout->addWidget(sep2);
if (m_metadataWidget) {
layout->addWidget(m_metadataWidget);
layout->addWidget(new KSeparator(this));
}
// ensure that widgets in the information side bar are aligned towards the top
layout->addStretch(1);
setLayout(layout);
}
InfoSidebarPage::~InfoSidebarPage()
{
}
void InfoSidebarPage::setUrl(const KUrl& url)
{
if (!m_shownUrl.equals(url, KUrl::CompareWithoutTrailingSlash)) {
cancelRequest();
m_shownUrl = url;
showItemInfo();
}
}
void InfoSidebarPage::setSelection(const KFileItemList& selection)
{
cancelRequest();
SidebarPage::setSelection(selection);
m_multipleSelection = (selection.size() > 1);
showItemInfo();
}
void InfoSidebarPage::requestDelayedItemInfo(const KUrl& url)
{
cancelRequest();
if (!url.isEmpty() && !m_multipleSelection) {
m_urlCandidate = url;
m_timer->setSingleShot(true);
m_timer->start(300);
}
}
void InfoSidebarPage::showItemInfo()
{
cancelRequest();
const KFileItemList& selectedItems = selection();
KUrl file;
if (selectedItems.count() == 0) {
file = m_shownUrl;
} else {
file = selectedItems[0]->url();
}
if (m_multipleSelection) {
KIconLoader iconLoader;
QPixmap icon = iconLoader.loadIcon("exec",
K3Icon::NoGroup,
K3Icon::SizeEnormous);
m_preview->setPixmap(icon);
m_name->setText(i18n("%1 items selected", selectedItems.count()));
} else if (!applyBookmark(file)) {
// try to get a preview pixmap from the item...
KUrl::List list;
list.append(file);
m_pendingPreview = true;
m_preview->setPixmap(QPixmap());
KIO::PreviewJob* job = KIO::filePreview(list,
m_preview->width(),
K3Icon::SizeEnormous,
0,
0,
true,
false);
job->setIgnoreMaximumSize(true);
connect(job, SIGNAL(gotPreview(const KFileItem&, const QPixmap&)),
this, SLOT(showPreview(const KFileItem&, const QPixmap&)));
connect(job, SIGNAL(failed(const KFileItem&)),
this, SLOT(showIcon(const KFileItem&)));
QString text("<b>");
text.append(file.fileName());
text.append("</b>");
m_name->setText(text);
}
createMetaInfo();
}
void InfoSidebarPage::slotTimeout()
{
m_shownUrl = m_urlCandidate;
showItemInfo();
}
void InfoSidebarPage::showIcon(const KFileItem& item)
{
m_pendingPreview = false;
if (!applyBookmark(item.url())) {
m_preview->setPixmap(item.pixmap(K3Icon::SizeEnormous));
}
}
void InfoSidebarPage::showPreview(const KFileItem& item,
const QPixmap& pixmap)
{
Q_UNUSED(item);
if (m_pendingPreview) {
m_preview->setPixmap(pixmap);
m_pendingPreview = false;
}
}
bool InfoSidebarPage::applyBookmark(const KUrl& url)
{
KFilePlacesModel* placesModel = DolphinSettings::instance().placesModel();
int count = placesModel->rowCount();
for (int i = 0; i < count; ++i) {
QModelIndex index = placesModel->index(i, 0);
if (url.equals(placesModel->url(index), KUrl::CompareWithoutTrailingSlash)) {
QString text("<b>");
text.append(placesModel->text(index));
text.append("</b>");
m_name->setText(text);
m_preview->setPixmap(placesModel->icon(index).pixmap(128, 128));
return true;
}
}
return false;
}
void InfoSidebarPage::cancelRequest()
{
m_timer->stop();
m_pendingPreview = false;
}
void InfoSidebarPage::createMetaInfo()
{
beginInfoLines();
const KFileItemList& selectedItems = selection();
if (selectedItems.size() == 0) {
KFileItem fileItem(S_IFDIR, KFileItem::Unknown, m_shownUrl);
fileItem.refresh();
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());
}
}
}
if (MetaDataWidget::metaDataAvailable()) {
m_metadataWidget->setFile(fileItem->url());
}
} else {
if (MetaDataWidget::metaDataAvailable()) {
m_metadataWidget->setFiles(selectedItems.urlList());
}
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
}
addInfoLine(i18n("Total size:"), KIO::convertSize(totSize));
}
endInfoLines();
}
void InfoSidebarPage::beginInfoLines()
{
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"
};
// do a binary search for the key...
int top = 0;
int bottom = sizeof(keys) / sizeof(char*) - 1;
while (top < bottom) {
const int middle = (top + bottom) / 2;
const int result = key.compare(keys[middle]);
if (result < 0) {
bottom = middle - 1;
} else if (result > 0) {
top = middle + 1;
} else {
return true;
}
}
return false;
}
void InfoSidebarPage::addInfoLine(const QString& labelText, const QString& infoText)
{
if (!m_infoLines.isEmpty()) {
m_infoLines += "<br/>";
}
m_infoLines += QString("<b>%1</b> %2").arg(labelText).arg(infoText);
}
#include "infosidebarpage.moc"