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.
kipi-plugins/kipi-plugins/sync/gallerywindow.cpp

638 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_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);
}
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("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_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();
}
}