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.
464 lines
17 KiB
464 lines
17 KiB
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// DISPLAYCOMPARE.CPP
|
|
//
|
|
// Copyright (C) 2001 Richard Groult <rgroult at jalix.org> (from ShowImg project)
|
|
// Copyright (C) 2004 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 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, Cambridge, MA 02110-1301, USA.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Include files for TQt
|
|
|
|
#include <tqptrvector.h>
|
|
#include <tqdict.h>
|
|
#include <tqfile.h>
|
|
#include <tqlistbox.h>
|
|
#include <tqlabel.h>
|
|
#include <tqgroupbox.h>
|
|
#include <tqlistview.h>
|
|
#include <tqcheckbox.h>
|
|
#include <tqheader.h>
|
|
#include <tqlayout.h>
|
|
#include <tqfileinfo.h>
|
|
#include <tqimage.h>
|
|
#include <tqpixmap.h>
|
|
#include <tqwhatsthis.h>
|
|
#include <tqpushbutton.h>
|
|
#include <tqframe.h>
|
|
|
|
// Include files for KDE
|
|
|
|
#include <tdelocale.h>
|
|
#include <tdemessagebox.h>
|
|
#include <kiconloader.h>
|
|
#include <tdelistview.h>
|
|
#include <ksqueezedtextlabel.h>
|
|
#include <tdeapplication.h>
|
|
#include <kurl.h>
|
|
#include <tdeio/job.h>
|
|
#include <tdeio/jobclasses.h>
|
|
#include <tdeio/netaccess.h>
|
|
#include <tdeio/global.h>
|
|
#include <kimageio.h>
|
|
#include <tdeio/previewjob.h>
|
|
#include <khelpmenu.h>
|
|
#include <tdepopupmenu.h>
|
|
#include <kstandarddirs.h>
|
|
|
|
// Include files for KIPI
|
|
|
|
#include <libkipi/version.h>
|
|
|
|
// Local include files
|
|
|
|
#include "pluginsversion.h"
|
|
#include "kpaboutdata.h"
|
|
#include "displaycompare.h"
|
|
|
|
namespace KIPIFindDupplicateImagesPlugin
|
|
{
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
class FindOriginalItem : public TQCheckListItem
|
|
{
|
|
public:
|
|
FindOriginalItem(TQListView * parent, TQString const & name, TQString const & fullpath,
|
|
TQString const & album, TQString const & comments)
|
|
: TQCheckListItem( parent, name, TQCheckListItem::CheckBox), _name(name),
|
|
_fullpath(fullpath), _album (album), _comments (comments)
|
|
{}
|
|
|
|
TQString name() { return _name; }
|
|
TQString fullpath() { return _fullpath; }
|
|
TQString album() { return _album; }
|
|
TQString comments() { return _comments; }
|
|
|
|
private:
|
|
TQString _name;
|
|
TQString _fullpath;
|
|
TQString _album;
|
|
TQString _comments;
|
|
};
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
class FindDuplicateItem : public TQCheckListItem
|
|
{
|
|
public:
|
|
FindDuplicateItem(TQListView * parent, TQString const & name, TQString const & fullpath,
|
|
TQString const & album, TQString const & comments)
|
|
: TQCheckListItem( parent, name, TQCheckListItem::CheckBox), _name(name),
|
|
_fullpath(fullpath), _album (album), _comments (comments)
|
|
{}
|
|
|
|
TQString name() { return _name; }
|
|
TQString fullpath() { return _fullpath; }
|
|
TQString album() { return _album; }
|
|
TQString comments() { return _comments; }
|
|
|
|
private:
|
|
TQString _name;
|
|
TQString _fullpath;
|
|
TQString _album;
|
|
TQString _comments;
|
|
};
|
|
|
|
|
|
//////////////////////////////////// CONSTRUCTOR ////////////////////////////////////////////
|
|
|
|
DisplayCompare::DisplayCompare(TQWidget* parent, KIPI::Interface* interface,
|
|
const TQDict < TQPtrVector < TQFile > >& cmp )
|
|
: KDialogBase( parent, "DisplayCompare", true, 0,
|
|
Help|User1|Close, Close, false, i18n("Delete")),
|
|
m_cmp(cmp), m_interface( interface )
|
|
{
|
|
KImageIO::registerFormats();
|
|
|
|
// About data and help button.
|
|
|
|
m_about = new KIPIPlugins::KPAboutData(I18N_NOOP("Find Duplicate Images"),
|
|
0,
|
|
TDEAboutData::License_GPL,
|
|
I18N_NOOP("A Kipi plugin to find duplicate images\n"
|
|
"This plugin is based on ShowImg implementation algorithm"),
|
|
"(c) 2003-2004, Gilles Caulier");
|
|
|
|
m_about->addAuthor("Jesper K. Pedersen", I18N_NOOP("Maintainer"),
|
|
"blackie atkde dot org");
|
|
|
|
m_about->addAuthor("Gilles Caulier", I18N_NOOP("Original author"),
|
|
"caulier dot gilles at gmail dot com");
|
|
|
|
m_about->addAuthor("Richard Groult", I18N_NOOP("Find duplicate images algorithm"),
|
|
"rgroult at jalix.org");
|
|
|
|
m_helpButton = actionButton( Help );
|
|
KHelpMenu* helpMenu = new KHelpMenu(this, m_about, false);
|
|
helpMenu->menu()->removeItemAt(0);
|
|
helpMenu->menu()->insertItem(i18n("Plugin Handbook"), this, TQT_SLOT(slotHelp()), 0, -1, 0);
|
|
m_helpButton->setPopup( helpMenu->menu() );
|
|
|
|
// ----------------------------------------------------
|
|
|
|
TQWidget* box = new TQWidget( this );
|
|
setMainWidget(box);
|
|
TQVBoxLayout* ml = new TQVBoxLayout( box, 10 );
|
|
TQHBoxLayout* h1 = new TQHBoxLayout( ml );
|
|
TQVBoxLayout* v1 = new TQVBoxLayout( h1 );
|
|
h1->addSpacing( 5 );
|
|
TQGridLayout* g1 = new TQGridLayout( v1, 1, 2 );
|
|
|
|
//---------------------------------------------
|
|
|
|
GroupBox1 = new TQGroupBox( 1, TQt::Horizontal, i18n("Original Files"), box );
|
|
GroupBox1->layout()->setSpacing( 6 );
|
|
GroupBox1->layout()->setMargin( 11 );
|
|
|
|
OriginalNameLabel = new KSqueezedTextLabel( GroupBox1, "OriginalNameLabel" );
|
|
OriginalNameLabel->setFrameShape( TQLabel::Box );
|
|
OriginalNameLabel->setAlignment( int( TQLabel::AlignCenter ) );
|
|
|
|
preview1 = new TQLabel( GroupBox1, "preview1" );
|
|
preview1->setFixedHeight( 120 );
|
|
preview1->setAlignment( TQt::AlignHCenter | TQt::AlignVCenter );
|
|
preview1->setSizePolicy( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Preferred ) );
|
|
TQWhatsThis::add( preview1, i18n( "<p>The preview of files with duplicates." ) );
|
|
|
|
originalInfoLabel1 = new KSqueezedTextLabel( GroupBox1, "originalInfoLabel1" );
|
|
originalInfoLabel1->setAlignment( int( TQLabel::AlignCenter ) );
|
|
originalInfoLabel2 = new KSqueezedTextLabel( GroupBox1, "originalInfoLabel2" );
|
|
originalInfoLabel2->setAlignment( int( TQLabel::AlignCenter ) );
|
|
originalInfoLabel3 = new KSqueezedTextLabel( GroupBox1, "originalInfoLabel3" );
|
|
originalInfoLabel3->setAlignment( int( TQLabel::AlignCenter ) );
|
|
originalInfoLabel4 = new KSqueezedTextLabel( GroupBox1, "originalInfoLabel4" );
|
|
originalInfoLabel4->setAlignment( int( TQLabel::AlignCenter ) );
|
|
originalInfoLabel5 = new KSqueezedTextLabel( GroupBox1, "originalInfoLabel5" );
|
|
originalInfoLabel5->setAlignment( int( TQLabel::AlignCenter ) );
|
|
|
|
listName = new TDEListView( GroupBox1, "listName" );
|
|
listName->header()->setLabel( 0, i18n( "Files" ) );
|
|
TQWhatsThis::add( listName, i18n( "<p>This list contains all files with many duplicates." ) );
|
|
listName->addColumn( i18n( "Files" ) );
|
|
listName->setResizeMode(TQListView::AllColumns);
|
|
|
|
g1->addWidget( GroupBox1 , 0, 0);
|
|
|
|
//---------------------------------------------
|
|
|
|
GroupBox2 = new TQGroupBox( 1, TQt::Horizontal, i18n("Similar Files"), box );
|
|
GroupBox2->layout()->setSpacing( 6 );
|
|
GroupBox2->layout()->setMargin( 11 );
|
|
|
|
similarNameLabel = new KSqueezedTextLabel( GroupBox2, "similarNameLabel" );
|
|
similarNameLabel->setFrameShape( TQLabel::Box );
|
|
similarNameLabel->setAlignment( int( TQLabel::AlignCenter ) );
|
|
|
|
preview2 = new TQLabel( GroupBox2, "preview2" );
|
|
preview2->setFixedHeight( 120 );
|
|
preview2->setAlignment( TQt::AlignHCenter | TQt::AlignVCenter );
|
|
preview2->setSizePolicy( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Preferred ) );
|
|
TQWhatsThis::add( preview2, i18n( "<p>The preview of duplicate files." ) );
|
|
|
|
similarInfoLabel1 = new KSqueezedTextLabel( GroupBox2, "similarInfoLabel1" );
|
|
similarInfoLabel1->setAlignment( int( TQLabel::AlignCenter ) );
|
|
similarInfoLabel2 = new KSqueezedTextLabel( GroupBox2, "similarInfoLabel2" );
|
|
similarInfoLabel2->setAlignment( int( TQLabel::AlignCenter ) );
|
|
similarInfoLabel3 = new KSqueezedTextLabel( GroupBox2, "similarInfoLabel3" );
|
|
similarInfoLabel3->setAlignment( int( TQLabel::AlignCenter ) );
|
|
similarInfoLabel4 = new KSqueezedTextLabel( GroupBox2, "similarInfoLabel4" );
|
|
similarInfoLabel4->setAlignment( int( TQLabel::AlignCenter ) );
|
|
similarInfoLabel5 = new KSqueezedTextLabel( GroupBox2, "similarInfoLabel5" );
|
|
similarInfoLabel5->setAlignment( int( TQLabel::AlignCenter ) );
|
|
|
|
listEq = new TDEListView( GroupBox2, "listEq" );
|
|
listEq->header()->setLabel( 0, i18n( "Files" ) );
|
|
TQWhatsThis::add( listEq, i18n( "<p>This list contains all duplicates files." ) );
|
|
listEq->addColumn( i18n( "Identical To" ) );
|
|
listEq->setResizeMode(TQListView::AllColumns);
|
|
|
|
g1->addWidget( GroupBox2 , 0, 1);
|
|
|
|
setTabOrder( listName, listEq );
|
|
|
|
//---------------------------------------------
|
|
|
|
TQDictIterator < TQPtrVector < TQFile > >itres(m_cmp); // iterator for res
|
|
int n_id = 0;
|
|
|
|
while (itres.current ())
|
|
{
|
|
TQFileInfo fi(itres.currentKey());
|
|
TQString Temp = fi.dirPath();
|
|
TQString albumName = Temp.section('/', -1);
|
|
|
|
KURL url;
|
|
url.setPath(fi.fileName());
|
|
KIPI::ImageInfo info = m_interface->info(url);
|
|
TQString comments = info.description();
|
|
|
|
new FindOriginalItem( listName, fi.fileName(), itres.currentKey(), albumName, comments );
|
|
++itres;
|
|
++n_id;
|
|
}
|
|
|
|
setCaption(i18n("1 Original Image with Duplicate Images Has Been Found",
|
|
"%n Original Images with Duplicate Images Have Been Found", n_id));
|
|
|
|
// signals and slots connections
|
|
|
|
connect(this, TQT_SIGNAL(user1Clicked()),
|
|
this, TQT_SLOT(slotDelete()));
|
|
|
|
connect(listName, TQT_SIGNAL(selectionChanged ( TQListViewItem * )),
|
|
this, TQT_SLOT(slotDisplayLeft(TQListViewItem *)));
|
|
|
|
connect(listEq, TQT_SIGNAL(selectionChanged ( TQListViewItem * )),
|
|
this, TQT_SLOT(slotDisplayRight(TQListViewItem *)));
|
|
|
|
resize( 700, 600 );
|
|
listName->setSelected(listName->firstChild(), true);
|
|
}
|
|
|
|
|
|
//////////////////////////////////// DESTRUCTOR /////////////////////////////////////////////
|
|
|
|
DisplayCompare::~DisplayCompare()
|
|
{
|
|
delete m_about;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void DisplayCompare::slotHelp()
|
|
{
|
|
TDEApplication::kApplication()->invokeHelp("findduplicateimages",
|
|
"kipi-plugins");
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void DisplayCompare::slotDelete( void )
|
|
{
|
|
FindDuplicateItem *item = (FindDuplicateItem*)listEq->firstChild ();
|
|
FindDuplicateItem *itemTmp;
|
|
|
|
while(item) // Remove duplicate file selected.
|
|
{
|
|
if( item->isOn() )
|
|
{
|
|
itemTmp = (FindDuplicateItem*)item->nextSibling();
|
|
KURL deleteImage(item->fullpath());
|
|
|
|
if ( TDEIO::NetAccess::del(deleteImage) == false )
|
|
KMessageBox::error(this, i18n("Cannot remove duplicate file:\n%1").arg(item->fullpath()));
|
|
else
|
|
m_interface->delImage( deleteImage );
|
|
|
|
listEq->takeItem (item);
|
|
item = itemTmp;
|
|
}
|
|
else
|
|
item = (FindDuplicateItem*)item->nextSibling();
|
|
}
|
|
|
|
// Remove originals files selected.
|
|
|
|
for (FindOriginalItem* item = (FindOriginalItem*)listName->firstChild(); item;
|
|
item = (FindOriginalItem*)item->nextSibling())
|
|
{
|
|
if ( item->isOn() )
|
|
{
|
|
KURL deleteImage(item->fullpath());
|
|
|
|
if ( TDEIO::NetAccess::del(deleteImage) == false )
|
|
KMessageBox::error(this, i18n("Cannot remove original file:\n%1").arg(item->fullpath()));
|
|
|
|
item->setOn( false );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void DisplayCompare::slotDisplayLeft(TQListViewItem * item)
|
|
{
|
|
TDEApplication::setOverrideCursor( waitCursor );
|
|
listEq->clear();
|
|
FindOriginalItem *pitem = static_cast<FindOriginalItem*>( item );
|
|
TQPtrVector < TQFile > *list = (TQPtrVector < TQFile > *)m_cmp.find(pitem->fullpath());
|
|
TQImage im(pitem->fullpath());
|
|
|
|
if ( !im.isNull() )
|
|
{
|
|
OriginalNameLabel->setText(pitem->name());
|
|
originalInfoLabel1->setText(i18n("Image size: %1x%2 pixels").arg(im.width()).arg(im.height()));
|
|
originalInfoLabel2->setText(i18n("File size: 1 byte",
|
|
"File size: %n bytes",TQFileInfo(pitem->fullpath()).size()));
|
|
originalInfoLabel3->setText(i18n("Modified: %1").arg(TDELocale(NULL)
|
|
.formatDateTime(TQFileInfo(pitem->fullpath())
|
|
.lastModified())));
|
|
originalInfoLabel4->setText(i18n("Album: %1").arg(pitem->album()));
|
|
originalInfoLabel5->setText(i18n("Comments: %1").arg(pitem->comments()));
|
|
}
|
|
|
|
preview1->clear();
|
|
|
|
TQString IdemIndexed = "file:" + pitem->fullpath();
|
|
KURL url(IdemIndexed);
|
|
|
|
TDEIO::PreviewJob* thumbJob1 = TDEIO::filePreview( url, preview1->height() );
|
|
|
|
connect(thumbJob1, TQT_SIGNAL(gotPreview(const KFileItem*, const TQPixmap&)),
|
|
TQT_SLOT(slotGotPreview1(const KFileItem*, const TQPixmap&)));
|
|
|
|
FindDuplicateItem *last = NULL;
|
|
TQFile *f = NULL;
|
|
TQFileInfo *fi = new TQFileInfo();
|
|
TQString fn;
|
|
|
|
for (unsigned int i = 0 ; i < list->size () ; ++i)
|
|
{
|
|
f = (TQFile*)list->at(i);
|
|
fi->setFile(*f);
|
|
fn = fi->absFilePath();
|
|
|
|
if (fi->exists ())
|
|
{
|
|
TQString Temp = fi->dirPath();
|
|
TQString albumName = Temp.section('/', -1);
|
|
|
|
KURL url;
|
|
url.setPath(fi->fileName());
|
|
KIPI::ImageInfo info = m_interface->info(url);
|
|
TQString comments = info.description();
|
|
|
|
FindDuplicateItem *item = new FindDuplicateItem( listEq,
|
|
fi->fileName(),
|
|
fn,
|
|
albumName,
|
|
comments
|
|
);
|
|
if (!last)
|
|
last = item;
|
|
}
|
|
}
|
|
|
|
preview2->setPixmap(TQPixmap());
|
|
listEq->setSelected(last, true);
|
|
TDEApplication::restoreOverrideCursor();
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void DisplayCompare::slotGotPreview1(const KFileItem* /*url*/, const TQPixmap &pixmap)
|
|
{
|
|
preview1->setPixmap(pixmap);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void DisplayCompare::slotDisplayRight(TQListViewItem * item)
|
|
{
|
|
TDEApplication::setOverrideCursor( waitCursor );
|
|
FindDuplicateItem *pitem = static_cast<FindDuplicateItem*>( item );
|
|
TQImage im(pitem->fullpath());
|
|
|
|
if ( !im.isNull() )
|
|
{
|
|
similarNameLabel->setText(pitem->name());
|
|
similarInfoLabel1->setText(i18n("Image size: %1x%2 pixels").arg(im.width()).arg(im.height()));
|
|
similarInfoLabel2->setText(i18n("File size: 1 byte",
|
|
"File size: %n bytes", TQFileInfo(pitem->fullpath()).size()));
|
|
similarInfoLabel3->setText(i18n("Modified: %1").arg(TDELocale(NULL)
|
|
.formatDateTime(TQFileInfo(pitem->fullpath())
|
|
.lastModified())));
|
|
similarInfoLabel4->setText(i18n("Album: %1").arg(pitem->album()));
|
|
similarInfoLabel5->setText(i18n("Caption: %1").arg(pitem->comments()));
|
|
}
|
|
|
|
preview2->clear();
|
|
|
|
TQString IdemIndexed = "file:" + pitem->fullpath();
|
|
KURL url(IdemIndexed);
|
|
|
|
TDEIO::PreviewJob* thumbJob2 = TDEIO::filePreview( url, preview2->height() );
|
|
|
|
connect(thumbJob2, TQT_SIGNAL(gotPreview(const KFileItem*, const TQPixmap&)),
|
|
TQT_SLOT(slotGotPreview2(const KFileItem*, const TQPixmap&)));
|
|
|
|
TDEApplication::restoreOverrideCursor();
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void DisplayCompare::slotGotPreview2(const KFileItem* /*url*/, const TQPixmap &pixmap)
|
|
{
|
|
preview2->setPixmap(pixmap);
|
|
}
|
|
|
|
} // NameSpace KIPIFindDupplicateImagesPlugin
|
|
|
|
#include "displaycompare.moc"
|