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.
455 lines
13 KiB
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 <tdelocale.h>
|
|
#include <tdefiledialog.h>
|
|
#include <tdeglobalsettings.h>
|
|
#include <kprinter.h>
|
|
#include <tdeglobal.h>
|
|
#include <kiconloader.h>
|
|
#include <tdeapplication.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());
|
|
TDEIconLoader *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( "text-vnd.tde.ascii", (TDEIcon::Group)TDEIcon::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( "text-x-generic", (TDEIcon::Group)TDEIcon::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( "document-save", (TDEIcon::Group)TDEIcon::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( "document-print", (TDEIcon::Group)TDEIcon::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( "edit-copy", (TDEIcon::Group)TDEIcon::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
|