You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
digikam/digikam/libs/widgets/metadata/metadatawidget.cpp

455 lines
13 KiB

/* ============================================================
*
* This file is a part of digiKam project
* http://www.digikam.org
*
* Date : 2006-02-22
* Description : a generic widget to display metadata
*
* Copyright (C) 2006-2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
*
* 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, 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.
*
* ============================================================ */
// TQt includes.
#include <tqlayout.h>
#include <tqmap.h>
#include <tqfile.h>
#include <tqmime.h>
#include <tqheader.h>
#include <tqwhatsthis.h>
#include <tqpainter.h>
#include <tqhbuttongroup.h>
#include <tqpushbutton.h>
#include <tqlabel.h>
#include <tqdragobject.h>
#include <tqclipboard.h>
#include <tqsimplerichtext.h>
#include <tqpaintdevicemetrics.h>
#include <tqstylesheet.h>
#include <tqlistview.h>
#include <tqtooltip.h>
// KDE includes.
#include <kdialogbase.h>
#include <klocale.h>
#include <tdefiledialog.h>
#include <kglobalsettings.h>
#include <kprinter.h>
#include <kglobal.h>
#include <kiconloader.h>
#include <kapplication.h>
// Local includes.
#include "ddebug.h"
#include "metadatalistview.h"
#include "mdkeylistviewitem.h"
#include "searchtextbar.h"
#include "metadatawidget.h"
#include "metadatawidget.moc"
namespace Digikam
{
class MetadataWidgetPriv
{
public:
MetadataWidgetPriv()
{
toolButtons = 0;
levelButtons = 0;
view = 0;
mainLayout = 0;
searchBar = 0;
}
TQGridLayout *mainLayout;
TQHButtonGroup *toolButtons;
TQHButtonGroup *levelButtons;
TQByteArray metadata;
TQString fileName;
MetadataListView *view;
SearchTextBar *searchBar;
DMetadata::MetaDataMap metaDataMap;
};
MetadataWidget::MetadataWidget(TQWidget* parent, const char* name)
: TQWidget(parent, name)
{
d = new MetadataWidgetPriv;
d->mainLayout = new TQGridLayout(this, 3, 4, KDialog::spacingHint(), KDialog::spacingHint());
KIconLoader *iconLoader = TDEApplication::kApplication()->iconLoader();
d->levelButtons = new TQHButtonGroup(this);
d->levelButtons->setInsideMargin( 0 );
d->levelButtons->setExclusive(true);
d->levelButtons->setFrameShape(TQFrame::NoFrame);
TQPushButton *simpleLevel = new TQPushButton( d->levelButtons );
simpleLevel->setPixmap( iconLoader->loadIcon( "ascii", (KIcon::Group)KIcon::Toolbar ) );
simpleLevel->setToggleButton(true);
TQWhatsThis::add( simpleLevel, i18n( "Switch the tags view to a simple human-readable list" ) );
TQToolTip::add( simpleLevel, i18n( "Simple list" ));
d->levelButtons->insert(simpleLevel, SIMPLE);
TQPushButton *fullLevel = new TQPushButton( d->levelButtons );
fullLevel->setPixmap( iconLoader->loadIcon( "document", (KIcon::Group)KIcon::Toolbar ) );
fullLevel->setToggleButton(true);
TQWhatsThis::add( fullLevel, i18n( "Switch the tags view to a full list" ) );
TQToolTip::add( fullLevel, i18n( "Full list" ));
d->levelButtons->insert(fullLevel, FULL);
d->toolButtons = new TQHButtonGroup(this);
d->toolButtons->setInsideMargin( 0 );
d->toolButtons->setFrameShape(TQFrame::NoFrame);
TQPushButton *saveMetadata = new TQPushButton( d->toolButtons );
saveMetadata->setPixmap( iconLoader->loadIcon( "filesave", (KIcon::Group)KIcon::Toolbar ) );
TQWhatsThis::add( saveMetadata, i18n( "Save metadata to a binary file" ) );
TQToolTip::add( saveMetadata, i18n( "Save metadata" ));
d->toolButtons->insert(saveMetadata);
TQPushButton *printMetadata = new TQPushButton( d->toolButtons );
printMetadata->setPixmap( iconLoader->loadIcon( "fileprint", (KIcon::Group)KIcon::Toolbar ) );
TQWhatsThis::add( printMetadata, i18n( "Print metadata to printer" ) );
TQToolTip::add( printMetadata, i18n( "Print metadata" ));
d->toolButtons->insert(printMetadata);
TQPushButton *copy2ClipBoard = new TQPushButton( d->toolButtons );
copy2ClipBoard->setPixmap( iconLoader->loadIcon( "editcopy", (KIcon::Group)KIcon::Toolbar ) );
TQWhatsThis::add( copy2ClipBoard, i18n( "Copy metadata to clipboard" ) );
TQToolTip::add( copy2ClipBoard, i18n( "Copy metadata to clipboard" ));
d->toolButtons->insert(copy2ClipBoard);
d->view = new MetadataListView(this);
TQString barName = TQString(name) + "SearchBar";
d->searchBar = new SearchTextBar(this, barName.ascii());
// -----------------------------------------------------------------
d->mainLayout->addMultiCellWidget(d->levelButtons, 0, 0, 0, 1);
d->mainLayout->addMultiCellWidget(d->toolButtons, 0, 0, 4, 4);
d->mainLayout->addMultiCellWidget(d->view, 1, 1, 0, 4);
d->mainLayout->addMultiCellWidget(d->searchBar, 2, 2, 0, 4);
d->mainLayout->setRowStretch(1, 10);
d->mainLayout->setColStretch(3, 10);
// -----------------------------------------------------------------
connect(d->levelButtons, TQT_SIGNAL(released(int)),
this, TQT_SLOT(slotModeChanged(int)));
connect(copy2ClipBoard, TQT_SIGNAL(clicked()),
this, TQT_SLOT(slotCopy2Clipboard()));
connect(printMetadata, TQT_SIGNAL(clicked()),
this, TQT_SLOT(slotPrintMetadata()));
connect(saveMetadata, TQT_SIGNAL(clicked()),
this, TQT_SLOT(slotSaveMetadataToFile()));
connect(d->searchBar, TQT_SIGNAL(signalTextChanged(const TQString&)),
d->view, TQT_SLOT(slotSearchTextChanged(const TQString&)));
connect(d->view, TQT_SIGNAL(signalTextFilterMatch(bool)),
d->searchBar, TQT_SLOT(slotSearchResult(bool)));
}
MetadataWidget::~MetadataWidget()
{
delete d;
}
MetadataListView* MetadataWidget::view()
{
return d->view;
}
void MetadataWidget::enabledToolButtons(bool b)
{
d->toolButtons->setEnabled(b);
}
bool MetadataWidget::setMetadata(const TQByteArray& data)
{
d->metadata = data;
// Cleanup all metadata contents.
setMetadataMap();
if (d->metadata.isEmpty())
{
setMetadataEmpty();
return false;
}
// Try to decode current metadata.
if (decodeMetadata())
enabledToolButtons(true);
else
enabledToolButtons(false);
// Refresh view using decoded metadata.
buildView();
return true;
}
void MetadataWidget::setMetadataEmpty()
{
d->view->clear();
enabledToolButtons(false);
}
const TQByteArray& MetadataWidget::getMetadata()
{
return d->metadata;
}
bool MetadataWidget::storeMetadataToFile(const KURL& url)
{
if( url.isEmpty() )
return false;
TQFile file(url.path());
if ( !file.open(IO_WriteOnly) )
return false;
TQDataStream stream( &file );
stream.writeRawBytes(d->metadata.data(), d->metadata.size());
file.close();
return true;
}
void MetadataWidget::setMetadataMap(const DMetadata::MetaDataMap& data)
{
d->metaDataMap = data;
}
const DMetadata::MetaDataMap& MetadataWidget::getMetadataMap()
{
return d->metaDataMap;
}
void MetadataWidget::setIfdList(const DMetadata::MetaDataMap &ifds, const TQStringList& tagsFilter)
{
d->view->setIfdList(ifds, tagsFilter);
}
void MetadataWidget::setIfdList(const DMetadata::MetaDataMap &ifds, const TQStringList& keysFilter,
const TQStringList& tagsFilter)
{
d->view->setIfdList(ifds, keysFilter, tagsFilter);
}
void MetadataWidget::slotModeChanged(int)
{
buildView();
}
void MetadataWidget::slotCopy2Clipboard()
{
TQString textmetadata = i18n("File name: %1 (%2)").arg(d->fileName).arg(getMetadataTitle());
TQListViewItemIterator it( d->view );
while ( it.current() )
{
if ( !it.current()->isSelectable() )
{
MdKeyListViewItem *item = dynamic_cast<MdKeyListViewItem *>(it.current());
textmetadata.append("\n\n>>> ");
textmetadata.append(item->getMdKey());
textmetadata.append(" <<<\n\n");
}
else
{
TQListViewItem *item = it.current();
textmetadata.append(item->text(0));
textmetadata.append(" : ");
textmetadata.append(item->text(1));
textmetadata.append("\n");
}
++it;
}
TQApplication::clipboard()->setData(new TQTextDrag(textmetadata), TQClipboard::Clipboard);
}
void MetadataWidget::slotPrintMetadata()
{
TQString textmetadata = i18n("<p><big><big><b>File name: %1 (%2)</b></big></big>")
.arg(d->fileName)
.arg(getMetadataTitle());
TQListViewItemIterator it( d->view );
while ( it.current() )
{
if ( !it.current()->isSelectable() )
{
MdKeyListViewItem *item = dynamic_cast<MdKeyListViewItem *>(it.current());
textmetadata.append("<br><br><b>");
textmetadata.append(item->getMdKey());
textmetadata.append("</b><br><br>");
}
else
{
TQListViewItem *item = it.current();
textmetadata.append(item->text(0));
textmetadata.append(" : <i>");
textmetadata.append(item->text(1));
textmetadata.append("</i><br>");
}
++it;
}
textmetadata.append("</p>");
KPrinter printer;
printer.setFullPage( true );
if ( printer.setup( this ) )
{
TQPainter p( &printer );
if ( !p.device() )
return;
TQPaintDeviceMetrics metrics(p.device());
int dpiy = metrics.logicalDpiY();
int margin = (int) ( (2/2.54)*dpiy ); // 2 cm margins
TQRect view( margin, margin, metrics.width() - 2*margin, metrics.height() - 2*margin );
TQFont font(TDEApplication::font());
font.setPointSize( 10 ); // we define 10pt to be a nice base size for printing
TQSimpleRichText richText( textmetadata, font,
TQString(),
TQStyleSheet::defaultSheet(),
TQMimeSourceFactory::defaultFactory(),
view.height() );
richText.setWidth( &p, view.width() );
int page = 1;
do
{
richText.draw( &p, margin, margin, view, colorGroup() );
view.moveBy( 0, view.height() );
p.translate( 0 , -view.height() );
p.setFont( font );
p.drawText( view.right() - p.fontMetrics().width( TQString::number( page ) ),
view.bottom() + p.fontMetrics().ascent() + 5, TQString::number( page ) );
if ( view.top() - margin >= richText.height() )
break;
printer.newPage();
page++;
}
while (true);
}
}
KURL MetadataWidget::saveMetadataToFile(const TQString& caption, const TQString& fileFilter)
{
KFileDialog fileSaveDialog(TDEGlobalSettings::documentPath(),
TQString(),
this,
"MetadataFileSaveDialog",
false);
fileSaveDialog.setOperationMode(KFileDialog::Saving);
fileSaveDialog.setMode(KFile::File);
fileSaveDialog.setSelection(d->fileName);
fileSaveDialog.setCaption(caption);
fileSaveDialog.setFilter(fileFilter);
// Check for cancel.
if ( fileSaveDialog.exec() == KFileDialog::Accepted )
return fileSaveDialog.selectedURL().path();
return KURL();
}
void MetadataWidget::setMode(int mode)
{
if (d->levelButtons->selectedId() == mode)
return;
d->levelButtons->setButton(mode);
buildView();
}
int MetadataWidget::getMode()
{
int level = d->levelButtons->selectedId();
return level;
}
TQString MetadataWidget::getCurrentItemKey() const
{
return d->view->getCurrentItemKey();
}
void MetadataWidget::setCurrentItemByKey(const TQString& itemKey)
{
d->view->setCurrentItemByKey(itemKey);
}
bool MetadataWidget::loadFromData(const TQString& fileName, const TQByteArray& data)
{
setFileName(fileName);
return(setMetadata(data));
}
TQString MetadataWidget::getTagTitle(const TQString&)
{
return TQString();
}
TQString MetadataWidget::getTagDescription(const TQString&)
{
return TQString();
}
void MetadataWidget::setFileName(const TQString& fileName)
{
d->fileName = fileName;
}
void MetadataWidget::setUserAreaWidget(TQWidget *w)
{
TQVBoxLayout *vLayout = new TQVBoxLayout( KDialog::spacingHint() );
vLayout->addWidget(w);
vLayout->addStretch();
d->mainLayout->addMultiCellLayout(vLayout, 3, 3, 0, 4);
}
void MetadataWidget::buildView()
{
d->view->slotSearchTextChanged(d->searchBar->text());
}
} // namespace Digikam