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.
655 lines
18 KiB
655 lines
18 KiB
/* ============================================================
|
|
* File : gallerywindow.cpp
|
|
* Author: Renchi Raju <renchi@pooh.tam.uiuc.edu>
|
|
* Date : 2004-11-30
|
|
* Description :
|
|
*
|
|
* Copyright 2004-2005 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
|
|
|
|
* 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.
|
|
*
|
|
* ============================================================ */
|
|
|
|
// Include files for TQt
|
|
|
|
#include <tqlistview.h>
|
|
#include <tqpushbutton.h>
|
|
#include <tqtimer.h>
|
|
#include <tqpixmap.h>
|
|
#include <tqcursor.h>
|
|
#include <tqlineedit.h>
|
|
#include <tqprogressdialog.h>
|
|
#include <tqspinbox.h>
|
|
#include <tqcheckbox.h>
|
|
|
|
// Include files for KDE
|
|
|
|
#include <tdeaboutdata.h>
|
|
#include <khelpmenu.h>
|
|
#include <tdepopupmenu.h>
|
|
#include <tdelocale.h>
|
|
#include <tdemessagebox.h>
|
|
#include <tdeapplication.h>
|
|
#include <kiconloader.h>
|
|
#include <tdehtml_part.h>
|
|
#include <tdehtmlview.h>
|
|
#include <krun.h>
|
|
#include <kdebug.h>
|
|
#include <tdeconfig.h>
|
|
|
|
// KIPI include files
|
|
|
|
#include <libkipi/interface.h>
|
|
#include <libkipi/imagedialog.h>
|
|
|
|
// Local includes.
|
|
|
|
#include "kpaboutdata.h"
|
|
#include "pluginsversion.h"
|
|
#include "galleries.h"
|
|
#include "gallerylist.h"
|
|
#include "gallerytalker.h"
|
|
#include "galleryitem.h"
|
|
#include "galleryviewitem.h"
|
|
#include "gallerywidget.h"
|
|
#include "galleryalbumdialog.h"
|
|
#include "gallerywindow.h"
|
|
#include "gallerywindow.moc"
|
|
|
|
namespace KIPIGalleryExportPlugin
|
|
{
|
|
|
|
GalleryWindow::GalleryWindow(KIPI::Interface* interface, TQWidget *parent, Galleries* pGalleries)
|
|
: KDialogBase(parent, 0, true, i18n("Gallery Export"), Help|Close, Close, false),
|
|
m_interface(interface),
|
|
mpGalleries(pGalleries)
|
|
{
|
|
m_uploadCount = 0;
|
|
m_uploadTotal = 0;
|
|
|
|
// About data and help button.
|
|
|
|
m_about = new KIPIPlugins::KPAboutData(I18N_NOOP("Gallery Export"),
|
|
0,
|
|
TDEAboutData::License_GPL,
|
|
I18N_NOOP("A Kipi plugin to export image collection to remote Gallery server."),
|
|
"(c) 2003-2005, Renchi Raju");
|
|
|
|
m_about->addAuthor("Renchi Raju", I18N_NOOP("Author"),
|
|
"renchi at pooh dot tam dot uiuc dot edu");
|
|
|
|
m_about->addAuthor("Colin Guthrie", I18N_NOOP("Maintainer"),
|
|
"kde at colin dot guthr dot ie");
|
|
|
|
m_helpButton = actionButton( Help );
|
|
KHelpMenu* helpMenu = new KHelpMenu(this, m_about, false);
|
|
helpMenu->menu()->removeItemAt(0);
|
|
helpMenu->menu()->insertItem(i18n("Plugin Handbook"), this, TQ_SLOT(slotHelp()), 0, -1, 0);
|
|
m_helpButton->setPopup( helpMenu->menu() );
|
|
|
|
GalleryWidget* widget = new GalleryWidget(this);
|
|
setMainWidget(widget);
|
|
widget->setMinimumSize(600, 400);
|
|
|
|
m_albumView = widget->m_albumView;
|
|
m_photoView = widget->m_photoView;
|
|
m_newAlbumBtn = widget->m_newAlbumBtn;
|
|
m_addPhotoBtn = widget->m_addPhotoBtn;
|
|
m_captTitleCheckBox = widget->m_captTitleCheckBox;
|
|
m_captDescrCheckBox = widget->m_captDescrCheckBox;
|
|
m_resizeCheckBox = widget->m_resizeCheckBox;
|
|
m_dimensionSpinBox = widget->m_dimensionSpinBox;
|
|
|
|
m_albumView->setRootIsDecorated( true );
|
|
|
|
m_newAlbumBtn->setEnabled( false );
|
|
m_addPhotoBtn->setEnabled( false );
|
|
|
|
m_progressDlg = new TQProgressDialog( this, 0, true );
|
|
m_progressDlg->setAutoReset( true );
|
|
m_progressDlg->setAutoClose( true );
|
|
|
|
connect(m_progressDlg, TQ_SIGNAL(canceled()), TQ_SLOT(slotAddPhotoCancel()));
|
|
|
|
connect(m_albumView, TQ_SIGNAL(selectionChanged()), TQ_SLOT(slotAlbumSelected()));
|
|
connect(m_photoView->browserExtension(),
|
|
TQ_SIGNAL(openURLRequest(const KURL&,
|
|
const KParts::URLArgs&)),
|
|
TQ_SLOT(slotOpenPhoto(const KURL&)));
|
|
|
|
connect(m_newAlbumBtn, TQ_SIGNAL(clicked()), TQ_SLOT(slotNewAlbum()));
|
|
connect(m_addPhotoBtn, TQ_SIGNAL(clicked()), TQ_SLOT( slotAddPhotos()));
|
|
|
|
// read config
|
|
TDEConfig config("kipirc");
|
|
config.setGroup("GallerySync Settings");
|
|
|
|
m_talker = new GalleryTalker( this );
|
|
connect( m_talker, TQ_SIGNAL( signalError( const TQString& ) ),
|
|
TQ_SLOT( slotError( const TQString& ) ) );
|
|
connect( m_talker, TQ_SIGNAL( signalBusy( bool ) ),
|
|
TQ_SLOT( slotBusy( bool ) ) );
|
|
connect( m_talker, TQ_SIGNAL( signalLoginFailed( const TQString& ) ),
|
|
TQ_SLOT( slotLoginFailed( const TQString& ) ) );
|
|
connect( m_talker, TQ_SIGNAL( signalAlbums( const TQValueList<GAlbum>& ) ),
|
|
TQ_SLOT( slotAlbums( const TQValueList<GAlbum>& ) ) );
|
|
connect( m_talker, TQ_SIGNAL( signalPhotos( const TQValueList<GPhoto>& ) ),
|
|
TQ_SLOT( slotPhotos( const TQValueList<GPhoto>& ) ) );
|
|
connect( m_talker, TQ_SIGNAL( signalAddPhotoSucceeded() ),
|
|
TQ_SLOT( slotAddPhotoSucceeded() ) );
|
|
connect( m_talker, TQ_SIGNAL( signalAddPhotoFailed( const TQString& ) ),
|
|
TQ_SLOT( slotAddPhotoFailed( const TQString& ) ) );
|
|
|
|
if (config.readBoolEntry("Resize", false))
|
|
{
|
|
m_resizeCheckBox->setChecked(true);
|
|
m_dimensionSpinBox->setEnabled(true);
|
|
}
|
|
else
|
|
{
|
|
m_resizeCheckBox->setChecked(false);
|
|
m_dimensionSpinBox->setEnabled(false);
|
|
}
|
|
|
|
if (config.readBoolEntry("Set title", true))
|
|
m_captTitleCheckBox->setChecked(true);
|
|
else
|
|
m_captTitleCheckBox->setChecked(false);
|
|
|
|
if (config.readBoolEntry("Set description", false))
|
|
m_captDescrCheckBox->setChecked(true);
|
|
else
|
|
m_captDescrCheckBox->setChecked(false);
|
|
|
|
m_dimensionSpinBox->setValue(config.readNumEntry("Maximum Width", 1600));
|
|
|
|
TQTimer::singleShot( 0, this, TQ_SLOT( slotDoLogin() ) );
|
|
}
|
|
|
|
GalleryWindow::~GalleryWindow()
|
|
{
|
|
// write config
|
|
TDEConfig config("kipirc");
|
|
config.setGroup("GallerySync Settings");
|
|
config.writeEntry("Resize", m_resizeCheckBox->isChecked());
|
|
config.writeEntry("Set title", m_captTitleCheckBox->isChecked());
|
|
config.writeEntry("Set description", m_captDescrCheckBox->isChecked());
|
|
config.writeEntry("Maximum Width", m_dimensionSpinBox->value());
|
|
|
|
delete m_progressDlg;
|
|
delete m_talker;
|
|
delete m_about;
|
|
}
|
|
|
|
void GalleryWindow::slotHelp()
|
|
{
|
|
TDEApplication::kApplication()->invokeHelp("galleryexport", "kipi-plugins");
|
|
}
|
|
|
|
void GalleryWindow::slotDoLogin()
|
|
{
|
|
GalleryList dlg(this, mpGalleries);
|
|
|
|
if (TQDialog::Accepted != dlg.exec())
|
|
{
|
|
close();
|
|
return;
|
|
}
|
|
|
|
Gallery* p_gallery = dlg.GetGallery();
|
|
if (!p_gallery)
|
|
{
|
|
close();
|
|
return;
|
|
}
|
|
|
|
GalleryTalker::setGallery2((2 == p_gallery->version()));
|
|
|
|
KURL url(p_gallery->url());
|
|
if (url.protocol().isEmpty())
|
|
{
|
|
url.setProtocol("http");
|
|
url.setHost(p_gallery->url());
|
|
}
|
|
if (!url.url().endsWith(".php"))
|
|
{
|
|
if (GalleryTalker::isGallery2())
|
|
url.addPath("main.php");
|
|
else
|
|
url.addPath("gallery_remote2.php");
|
|
}
|
|
// If we've done something clever, save it back to the gallery.
|
|
if (p_gallery->url() != url.url())
|
|
{
|
|
p_gallery->setUrl(url.url());
|
|
mpGalleries->Save();
|
|
}
|
|
|
|
m_talker->login(url.url(), p_gallery->username(), p_gallery->password());
|
|
}
|
|
|
|
void GalleryWindow::slotLoginFailed( const TQString& msg )
|
|
{
|
|
if ( KMessageBox::warningYesNo( this,
|
|
i18n( "Failed to login into remote gallery. " )
|
|
+ msg
|
|
+ i18n("\nDo you want to try again?" ) )
|
|
!= KMessageBox::Yes )
|
|
{
|
|
close();
|
|
return;
|
|
}
|
|
|
|
slotDoLogin();
|
|
}
|
|
|
|
void GalleryWindow::slotBusy( bool val )
|
|
{
|
|
if ( val )
|
|
{
|
|
setCursor(TQCursor::WaitCursor);
|
|
m_newAlbumBtn->setEnabled( false );
|
|
m_addPhotoBtn->setEnabled( false );
|
|
}
|
|
else
|
|
{
|
|
setCursor(TQCursor::ArrowCursor);
|
|
bool loggedIn = m_talker->loggedIn();
|
|
m_newAlbumBtn->setEnabled( loggedIn );
|
|
m_addPhotoBtn->setEnabled( loggedIn && m_albumView->selectedItem() );
|
|
}
|
|
}
|
|
|
|
void GalleryWindow::slotError( const TQString& msg )
|
|
{
|
|
KMessageBox::error( this, msg );
|
|
}
|
|
|
|
void GalleryWindow::slotAlbums( const TQValueList<GAlbum>& albumList )
|
|
{
|
|
m_albumDict.clear();
|
|
m_albumView->clear();
|
|
m_photoView->begin();
|
|
m_photoView->write( "<html></html>" );
|
|
m_photoView->end();
|
|
|
|
TDEIconLoader* iconLoader = TDEApplication::kApplication()->iconLoader();
|
|
TQPixmap pix = iconLoader->loadIcon( "folder", TDEIcon::NoGroup, 32 );
|
|
|
|
typedef TQValueList<GAlbum> GAlbumList;
|
|
GAlbumList::const_iterator iter;
|
|
for ( iter = albumList.begin(); iter != albumList.end(); ++iter )
|
|
{
|
|
const GAlbum& album = *iter;
|
|
|
|
if ( album.parent_ref_num == 0 )
|
|
{
|
|
GAlbumViewItem* item = new GAlbumViewItem( m_albumView, album.title,
|
|
album );
|
|
item->setPixmap( 0, pix );
|
|
m_albumDict.insert( album.ref_num, item );
|
|
}
|
|
else
|
|
{
|
|
TQListViewItem* parent = m_albumDict.find( album.parent_ref_num );
|
|
if ( parent )
|
|
{
|
|
GAlbumViewItem* item = new GAlbumViewItem( parent, album.title,
|
|
album);
|
|
item->setPixmap( 0, pix );
|
|
m_albumDict.insert( album.ref_num, item );
|
|
}
|
|
else
|
|
{
|
|
kdWarning() << "Failed to find parent for album "
|
|
<< album.name
|
|
<< " with id " << album.ref_num << "\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// find and select the last selected album
|
|
int lastSelectedID = 0;
|
|
for ( iter = albumList.begin(); iter != albumList.end(); ++iter )
|
|
{
|
|
if ((*iter).name == m_lastSelectedAlbum)
|
|
{
|
|
lastSelectedID = (*iter).ref_num;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (lastSelectedID > 0)
|
|
{
|
|
GAlbumViewItem* lastSelectedItem = m_albumDict.find( lastSelectedID );
|
|
if (lastSelectedItem)
|
|
{
|
|
m_albumView->setSelected( lastSelectedItem, true );
|
|
m_albumView->ensureItemVisible( lastSelectedItem );
|
|
}
|
|
}
|
|
}
|
|
|
|
void GalleryWindow::slotPhotos( const TQValueList<GPhoto>& photoList)
|
|
{
|
|
int pxSize = fontMetrics().height() - 2;
|
|
TQString styleSheet =
|
|
TQString( "body { margin: 8px; font-size: %1px; "
|
|
" color: %2; background-color: %3;}" )
|
|
.arg( pxSize )
|
|
.arg( colorGroup().text().name() )
|
|
.arg( colorGroup().base().name() );
|
|
|
|
styleSheet += TQString( "a { font-size: %1px; color: %2; "
|
|
"text-decoration: none;}" )
|
|
.arg( pxSize )
|
|
.arg( colorGroup().text().name() );
|
|
styleSheet += TQString( "i { font-size: %1px; color: %2; "
|
|
"text-decoration: none;}" )
|
|
.arg( pxSize-2 )
|
|
.arg( TQColor("steelblue").name() );
|
|
|
|
m_photoView->begin();
|
|
m_photoView->setUserStyleSheet( styleSheet );
|
|
m_photoView->write( "<html>" );
|
|
|
|
|
|
m_photoView->write("<table class='box-body' width='100%' "
|
|
"border='0' cellspacing='1' cellpadding='1'>" );
|
|
|
|
|
|
typedef TQValueList<GPhoto> GPhotoList;
|
|
GPhotoList::const_iterator iter;
|
|
for ( iter = photoList.begin(); iter != photoList.end(); ++iter )
|
|
{
|
|
const GPhoto& photo = *iter;
|
|
KURL imageurl(photo.albumURL + photo.name);
|
|
KURL thumburl(photo.albumURL + photo.thumbName);
|
|
|
|
m_photoView->write( "<tr><td class='photo'>"
|
|
+ TQString("<a href='%1'>")
|
|
.arg(imageurl.url())
|
|
+ TQString("<img border=1 src=\"%1\"><br>")
|
|
.arg(thumburl.url())
|
|
+ photo.name
|
|
+ ( photo.caption.isEmpty() ? TQString() :
|
|
TQString("<br><i>%1</i>")
|
|
.arg(photo.caption) )
|
|
+ "</a></td></tr>" );
|
|
}
|
|
|
|
m_photoView->write("</table>");
|
|
|
|
m_photoView->write( "</html>" );
|
|
m_photoView->end( );
|
|
}
|
|
|
|
void GalleryWindow::slotAlbumSelected()
|
|
{
|
|
TQListViewItem* item = m_albumView->selectedItem();
|
|
if ( !item )
|
|
{
|
|
m_addPhotoBtn->setEnabled( false );
|
|
}
|
|
else
|
|
{
|
|
if ( m_talker->loggedIn() )
|
|
{
|
|
m_addPhotoBtn->setEnabled( true );
|
|
|
|
m_photoView->begin();
|
|
m_photoView->write( "<html></html>" );
|
|
m_photoView->end();
|
|
|
|
GAlbumViewItem* viewItem = static_cast<GAlbumViewItem*>(item);
|
|
m_talker->listPhotos(viewItem->album.name);
|
|
m_lastSelectedAlbum = viewItem->album.name;
|
|
}
|
|
}
|
|
}
|
|
|
|
void GalleryWindow::slotOpenPhoto( const KURL& url )
|
|
{
|
|
new KRun(url);
|
|
}
|
|
|
|
void GalleryWindow::slotNewAlbum()
|
|
{
|
|
GalleryAlbumDialog dlg;
|
|
dlg.titleEdit->setFocus( );
|
|
if ( dlg.exec() != TQDialog::Accepted )
|
|
{
|
|
return;
|
|
}
|
|
|
|
TQString name = dlg.nameEdit->text();
|
|
TQString title = dlg.titleEdit->text();
|
|
TQString caption = dlg.captionEdit->text();
|
|
|
|
// check for prohibited chars in the album name
|
|
// \ / * ? " ' & < > | . + # ( ) or spaces
|
|
// Todo: Change this to a TQRegExp check.
|
|
TQChar ch;
|
|
bool clean = true;
|
|
for (uint i=0; i<name.length(); i++)
|
|
{
|
|
ch = name[i];
|
|
if (ch == '\\')
|
|
{
|
|
clean = false;
|
|
break;
|
|
}
|
|
else if (ch == '/')
|
|
{
|
|
clean = false;
|
|
break;
|
|
}
|
|
else if (ch == '*')
|
|
{
|
|
clean = false;
|
|
break;
|
|
}
|
|
else if (ch == '?')
|
|
{
|
|
clean = false;
|
|
break;
|
|
}
|
|
else if (ch == '"')
|
|
{
|
|
clean = false;
|
|
break;
|
|
}
|
|
else if (ch == '\'')
|
|
{
|
|
clean = false;
|
|
break;
|
|
}
|
|
else if (ch == '&')
|
|
{
|
|
clean = false;
|
|
break;
|
|
}
|
|
else if (ch == '<')
|
|
{
|
|
clean = false;
|
|
break;
|
|
}
|
|
else if (ch == '>')
|
|
{
|
|
clean = false;
|
|
break;
|
|
}
|
|
else if (ch == '|')
|
|
{
|
|
clean = false;
|
|
break;
|
|
}
|
|
else if (ch == '.')
|
|
{
|
|
clean = false;
|
|
break;
|
|
}
|
|
else if (ch == '+')
|
|
{
|
|
clean = false;
|
|
break;
|
|
}
|
|
else if (ch == '#')
|
|
{
|
|
clean = false;
|
|
break;
|
|
}
|
|
else if (ch == '(')
|
|
{
|
|
clean = false;
|
|
break;
|
|
}
|
|
else if (ch == ')')
|
|
{
|
|
clean = false;
|
|
break;
|
|
}
|
|
else if (ch == ' ')
|
|
{
|
|
clean = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!clean)
|
|
{
|
|
KMessageBox::error( this, i18n("Sorry, these characters are not allowed in album name: %1")
|
|
.arg("\\ / * ? \" \' & < > | . + # ( ) or spaces") );
|
|
return;
|
|
}
|
|
|
|
TQString parentAlbumName;
|
|
|
|
TQListViewItem* item = m_albumView->selectedItem();
|
|
if (item)
|
|
{
|
|
GAlbumViewItem* viewItem = static_cast<GAlbumViewItem*>(item);
|
|
parentAlbumName = viewItem->album.name;
|
|
}
|
|
else
|
|
{
|
|
parentAlbumName = "0";
|
|
}
|
|
|
|
m_talker->createAlbum(parentAlbumName, name, title, caption);
|
|
}
|
|
|
|
void GalleryWindow::slotAddPhotos()
|
|
{
|
|
TQListViewItem* item = m_albumView->selectedItem();
|
|
if (!item)
|
|
return;
|
|
|
|
KURL::List urls = KIPI::ImageDialog::getImageURLs( this, m_interface );
|
|
if (urls.isEmpty())
|
|
return;
|
|
|
|
typedef TQPair<TQString,TQString> Pair;
|
|
|
|
m_uploadQueue.clear();
|
|
for (KURL::List::iterator it = urls.begin(); it != urls.end(); ++it)
|
|
{
|
|
KIPI::ImageInfo info = m_interface->info( *it );
|
|
m_uploadQueue.append( Pair( (*it).path(), info.description() ) );
|
|
}
|
|
|
|
m_uploadTotal = m_uploadQueue.count();
|
|
m_uploadCount = 0;
|
|
m_progressDlg->reset();
|
|
slotAddPhotoNext();
|
|
}
|
|
|
|
void GalleryWindow::slotAddPhotoNext()
|
|
{
|
|
if ( m_uploadQueue.isEmpty() )
|
|
{
|
|
m_progressDlg->reset();
|
|
m_progressDlg->hide();
|
|
slotAlbumSelected();
|
|
return;
|
|
}
|
|
|
|
typedef TQPair<TQString,TQString> Pair;
|
|
Pair pathComments = m_uploadQueue.first();
|
|
m_uploadQueue.pop_front();
|
|
|
|
bool res = m_talker->addPhoto( m_lastSelectedAlbum, pathComments.first,
|
|
pathComments.second,
|
|
m_captTitleCheckBox->isChecked(),
|
|
m_captDescrCheckBox->isChecked(),
|
|
m_resizeCheckBox->isChecked(),
|
|
m_dimensionSpinBox->value() );
|
|
if (!res)
|
|
{
|
|
slotAddPhotoFailed( "" );
|
|
return;
|
|
}
|
|
|
|
m_progressDlg->setLabelText( i18n("Uploading file %1 ")
|
|
.arg( KURL(pathComments.first).filename() ) );
|
|
|
|
if (m_progressDlg->isHidden())
|
|
m_progressDlg->show();
|
|
}
|
|
|
|
void GalleryWindow::slotAddPhotoSucceeded()
|
|
{
|
|
m_uploadCount++;
|
|
m_progressDlg->setProgress( m_uploadCount, m_uploadTotal );
|
|
slotAddPhotoNext();
|
|
}
|
|
|
|
void GalleryWindow::slotAddPhotoFailed( const TQString& msg )
|
|
{
|
|
if ( KMessageBox::warningContinueCancel( this,
|
|
i18n( "Failed to upload photo into "
|
|
"remote gallery. " )
|
|
+ msg
|
|
+ i18n("\nDo you want to continue?" ) )
|
|
!= KMessageBox::Continue )
|
|
{
|
|
m_uploadQueue.clear();
|
|
m_progressDlg->reset();
|
|
m_progressDlg->hide();
|
|
|
|
// refresh the thumbnails
|
|
slotAlbumSelected();
|
|
}
|
|
else
|
|
{
|
|
m_uploadTotal--;
|
|
m_progressDlg->setProgress( m_uploadCount, m_uploadTotal );
|
|
slotAddPhotoNext();
|
|
}
|
|
}
|
|
|
|
void GalleryWindow::slotAddPhotoCancel()
|
|
{
|
|
m_uploadQueue.clear();
|
|
m_progressDlg->reset();
|
|
m_progressDlg->hide();
|
|
|
|
m_talker->cancel();
|
|
|
|
// refresh the thumbnails
|
|
slotAlbumSelected();
|
|
}
|
|
|
|
}
|
|
|