/*
* viewer.cpp -- Implementation of class KImageViewer.
* Author:       Sirtaj Singh Kang
* Version:      $Id: viewer.cpp,v 1.66 2001/02/18 13:02:58 mkretz Exp $
* Generated:    Wed Oct 15 11:37:16 EST 1997
*/

#include <assert.h>
#include <unistd.h>

#include <qpopupmenu.h>
#include <qprintdialog.h>
#include <qprinter.h>
#include <qstrlist.h>
#include <qaccel.h>
#include <qtimer.h>
#include <qevent.h>
#include <qdragobject.h>

#include <kmainwindow.h>
#include <kmenubar.h>
#include <kapp.h>
#include <kfiledialog.h>
#include <kaccel.h>
#include <kkeydialog.h>
#include <kmessagebox.h>
#include <klocale.h>
#include <kconfig.h>
#include <kimageio.h>
#include <kio/netaccess.h>
#include <kwin.h>
#include <kdebug.h>
#include <kstdaction.h>
#include <kaction.h>
#include <kedittoolbar.h>
#include <ktempfile.h>

#include "viewer.h"
#include "canvas.h"
#include "version.h"
#include "knumdialog.h"
#include "filter.h"
#include "kfilteraction.h"
#include "filtlist.h"
#include "imagelistdialog.h"
#include "kviewconfdialog.h"

enum {
        ID_FILENAME,
        ID_PROGRESS,
        ID_STATUS
};

const int MessageDelay = 3000;

KImageViewer::KImageViewer( KFilterList* filters )
        : KMainWindow( 0 ),
        _imageLoaded( false ),
        m_bFullScreen( false ),
        m_recent( 0 ),
        m_filterMenu( 0 ),

        _pctBuffer( new QString ),
        _lastPct( - 1 ),
        _msgTimer( 0 ),
        _imageList( new ImageListDialog ),
        _zoomFactor( 100 ),

        _loadMode   ( ResizeWindow )
{
  // Image canvas
  _canvas = new KImageCanvas( this );

  connect(_canvas, SIGNAL( contextPress(const QPoint&) ),
          this, SLOT ( contextPress(const QPoint&) ));

  assert( _canvas );
  setCentralWidget( _canvas );
  _canvas->setFrameStyle( QFrame::NoFrame );

  m_accel = new KAccel(this);

  // Caption
  setCaption( i18n( "no image loaded" ) );

  statusBar()->insertItem( i18n( "no image loaded" ), ID_FILENAME, 1 );
  statusBar()->setItemAlignment( ID_FILENAME, AlignLeft | AlignVCenter );
  statusBar()->insertFixedItem( "                 ", ID_STATUS, true );
  statusBar()->changeItem( i18n( "Ready" ), ID_STATUS );
  statusBar()->insertFixedItem( "                 ", ID_PROGRESS, true );

  // list dialog
  connect( _imageList, SIGNAL( pleaseLoad( const QString&, const KURL& ) ),
           this, SLOT( loadFile( const QString&, const KURL& ) ) );

  setupActions( filters );

  setAcceptDrops( true );
  restoreOptions();
}

KImageViewer::~KImageViewer()
{
  m_recent->saveEntries( kapp->config() );

  kapp->config()->sync();

  delete _canvas; _canvas = 0;

  delete _pctBuffer;
  delete _imageList;
}

void KImageViewer::load()
{
  KURL::List urls = KFileDialog::getOpenURLs( ":load_image", KImageIO::pattern( KImageIO::Reading ), this );

  if( urls.isEmpty() )
    return;

  for( KURL::List::Iterator it = urls.begin(); it != urls.end(); it++ )
  {
    _imageList->addURL( *it, false );
    m_recent->addURL( *it );
  }
  _imageList->slotLast();
  //firstImage();
}

void KImageViewer::firstImage()
{
  _imageList->slotFirst(); 
}

void KImageViewer::openRecent( const KURL& url )
{
  if( url.isEmpty() ) return;

  _imageList->addURL( url );
}

void KImageViewer::file_close()
{
  if( _imageList->removeCurrent() )
  {
    /* this was the last image in the list */

    _canvas->clear();
    menuEntriesEnabled( false );
    _imageLoaded = false;
    setCaption( i18n( "no image loaded" ) );
    statusBar()->changeItem( i18n( "no image loaded" ), ID_FILENAME );
    m_filename = "";
    m_url = KURL( "" );
    m_format = "PNG";
  }

  m_editCrop->setEnabled( false );
}

void KImageViewer::menuEntriesEnabled( bool b )
{
  m_fileSave->setEnabled( b );
  m_fileSaveAs->setEnabled( b );
  m_fileClose->setEnabled( b );
  m_filePrint->setEnabled( b );
  m_editReset->setEnabled( b );
  m_viewMenu->setEnabled( b );
  m_viewZoom->setEnabled( b );
  m_viewZoomIn->setEnabled( b );
  m_viewZoomOut->setEnabled( b );
  m_viewDouble->setEnabled( b );
  m_viewHalf->setEnabled( b );
  m_viewMax->setEnabled( b );
  m_viewMaxpect->setEnabled( b );
  m_transMenu->setEnabled( b );
  m_transRotateClock->setEnabled( b );
  m_transRotateAnti->setEnabled( b );
  m_transFlipV->setEnabled( b );
  m_transFlipH->setEnabled( b );
  m_deskMenu->setEnabled( b );
  m_deskTile->setEnabled( b );
  m_deskMax->setEnabled( b );
  m_deskMaxpect->setEnabled( b );
  m_imagePrev->setEnabled( b );
  m_imageNext->setEnabled( b );
  m_imageSlide->setEnabled( b );
  m_filterMenu->setEnabled( b );
}

void KImageViewer::dragEnterEvent(QDragEnterEvent* e)
{
  e->accept(
    QUriDrag::canDecode( e ) |
    QImageDrag::canDecode( e )
  );
}

void KImageViewer::dropEvent(QDropEvent *e)
{
  QStrList uri;
  QImage image;
  if( QUriDrag::decode(e, uri) )
  {
    _imageList->addURLList( uri );
  }
  else if( QImageDrag::decode( e, image ) )
  {
    addImage( image );
  }
}

void KImageViewer::addImage( const QImage &image )
{
  KTempFile tempfile;
  QString filename = tempfile.name();
  tempfile.close();

  if( ! image.save( filename, "PNG" ) ) return;
  
  _imageList->addURL( KURL( filename ) );
}

void KImageViewer::saveAs()
{
  KURL url = KFileDialog::getSaveURL( ":save_image", KImageIO::pattern( KImageIO::Writing ), this );

  if ( url.isEmpty())
    return;

  bool stat = false;

  if( url.isMalformed() )
  {
    message( i18n("Malformed URL.") );
  }

  QString tmpfile;
  if( url.isLocalFile() )
    tmpfile = url.path();
  else
  {
    KTempFile ktempf;
    tmpfile = ktempf.name();
  }
    
  stat = saveFile( tmpfile, KImageIO::type( url.path() ), url );

  if( stat == false )
  {
    message( i18n( "the file wasn't saved" ) );
    return;
  }

  message( i18n("%1: written").arg(url.prettyURL()) );
  m_recent->addURL( url );
}

void KImageViewer::slotSave()
{
  saveFile( m_filename, m_format, m_url );
}

bool KImageViewer::saveFile( const QString &filename, QString format, const KURL &url )
{
  if( !_canvas->save( filename, format ) )
    return false;

  m_filename = filename;
  m_format = format;
  

  if( !url.isEmpty() )
  {
    if( !KIO::NetAccess::upload( filename, url ) )
      return false;

    m_url = url;
  }
  else
  {
    m_url = m_filename;
  }

  _imageList->setFilename( m_filename );
  _imageList->setURL( m_url );

  setCaption( m_url.prettyURL() );
  statusBar()->changeItem( m_filename, ID_FILENAME );
}

void KImageViewer::zoomIn10()
{
  _mat.scale( 1.1, 1.1 );
  _canvas->transformImage( _mat );
}

void KImageViewer::zoomOut10()
{
  _mat.scale( 0.9, 0.9 );
  _canvas->transformImage( _mat );
}

void KImageViewer::zoomIn200()
{
  _mat.scale( 2.0, 2.0 );
  _canvas->transformImage( _mat );
}

void KImageViewer::zoomOut50()
{
  _mat.scale( 0.5, 0.5 );
  _canvas->transformImage( _mat );
}

void KImageViewer::zoomCustom()
{
  KNumDialog num( this );
  _zoomFactor = (int)(_mat.m11() * 100);

  if( !num.getNum( _zoomFactor, i18n("Enter Zoom factor (100 = 1x):") ) )
    return;

  if( _zoomFactor <= 0 )
  {
    message( i18n( "Illegal zoom factor" ) );
    return;
  }

  double val = (double)_zoomFactor/100;
  _mat.reset();
  _mat.scale( val, val );
  _canvas->transformImage( _mat );
}

void KImageViewer::rotateClock()
{
  _mat.rotate( 90 );
  _canvas->transformImage( _mat );
}

void KImageViewer::rotateAntiClock()
{
  _mat.rotate( -90 );
  _canvas->transformImage( _mat );
}

void KImageViewer::flipVertical()
{
  QWMatrix m( 1.0F, 0.0F, 0.0F, -1.0F, 0.0F, 0.0F );

  _mat *= m;

  _canvas->transformImage( _mat );
}

void KImageViewer::flipHorizontal()
{
  QWMatrix m( -1.0F, 0.0F, 0.0F, 1.0F, 0.0F, 0.0F );

  _mat *= m;

  _canvas->transformImage( _mat );
}

void KImageViewer::quitApp()
{
  kapp->quit();
}

void KImageViewer::tile()
{
  _canvas->tileToDesktop();
}

void KImageViewer::max()
{
  _canvas->maxToDesktop();
}

void KImageViewer::maxpect()
{
  _canvas->maxpectToDesktop();
}

void KImageViewer::appendURL( const KURL &url, bool show )
{
   _imageList->addURL( url, show );
}

void KImageViewer::invokeFilter( KImageFilter *f )
{
  assert( f != 0 );

  QObject::disconnect( f, SIGNAL( changed( const QImage& ) ), 0, 0 );
  connect( f, SIGNAL( changed( const QImage& ) ), _canvas, SLOT( setImage( const QImage& ) ) );

  f->invoke( _canvas->getImage() );
}

void KImageViewer::connectFilters( KFilterList *filters )
{
  // connect all filters
  for( int i = 0; i < filters->count(); i++ )
  {
    KImageFilter *filter = filters->filter( i );

    connect( filter, SIGNAL( changed( const QImage& ) ),
        _canvas, SLOT( setImage( const QImage& ) ) );
    connect( filter, SIGNAL( progress( int) ),
        SLOT( setProgress( int ) ) );
    connect( filter, SIGNAL( status( const QString& ) ),
        SLOT(setStatus( const QString& ) ) );
    connect( filter, SIGNAL( message( const QString& ) ),
        SLOT(message( const QString& ) ) );
    connect( filter, SIGNAL( selected( KImageFilter* ) ),
        SLOT( invokeFilter( KImageFilter* ) ) );
  }
}

void KImageViewer::setStatus( const QString & status )
{
  if ( status.isEmpty() )
    statusBar()->changeItem( i18n( "Ready" ), ID_STATUS );
  else
    statusBar()->changeItem( status, ID_STATUS );
}

void KImageViewer::loadFile( const QString & file, const KURL &_url )
{
  KURL url(_url);
  if( url.isEmpty() )
  {
    url = file;
  }

  setStatus( i18n( "Loading..." ) );

  // load the image
  _canvas->load( file, 0, _loadMode == ResizeImage );

  // update state
  setStatus( 0 );

  if( _canvas->status() != KImageCanvas::OK )
  {
    message( i18n( "Could not load %1" ).arg( url.prettyURL() ) );
    _imageList->removeCurrent();
  }
  else
  {
    // resize window to screen
    if( _loadMode == ResizeWindow )
    {
      rzWinToImg();
    }

    // set caption
    setCaption( url.prettyURL() );
    statusBar()->changeItem( file, ID_FILENAME );

    m_filename = file;
    m_format = KImageIO::type( url.path() );
    m_url = url;

    // enable Menu entries TODO: enable filters
    if( !_imageLoaded )
    {
      menuEntriesEnabled( true );
      _imageLoaded = true;
    }
    // reset matrix
    _mat.reset();
  }
}

void KImageViewer::setProgress( int pct )
{
  if( pct == _lastPct )
    return;

  QString buf;
  if( pct > 0 ) {
    _pctBuffer->setNum( pct );
    *_pctBuffer += '%';
    buf = *_pctBuffer;
  }

  _lastPct = pct;

  statusBar()->changeItem( buf, ID_PROGRESS );
}

void KImageViewer::message( const QString &message )
{
  statusBar()->message( message, MessageDelay );
}

void KImageViewer::toggleImageList()
{
  if ( _imageList->isVisible() ) {
    _imageList->hide();
  }
  else {
    _imageList->show();
  }
}


void KImageViewer::contextPress(const QPoint& p)
{
  QPopupMenu *pop = new QPopupMenu( this, "popupmenu" );

  m_settingsShowMenuBar->plug( pop );
  pop->insertSeparator();
  m_imageList->plug( pop );
  m_imagePrev->plug( pop );
  m_imageNext->plug( pop );
  m_imageSlide->plug( pop );
  pop->insertSeparator();
  m_editFullScreen->plug( pop );

  pop->popup( p );
}

void KImageViewer::fullScreen()
{
  m_bFullScreen = !m_bFullScreen;
  if( m_bFullScreen )
  {
    _posSave = pos();
    _sizeSave = size();

    // Preserve caption, reparent calls setCaption (!)
    showFullScreen();
    setCaption( m_filename );

    // Qt bug (see below)
    setAcceptDrops( FALSE );
    topData()->dnd = 0;
    setAcceptDrops( TRUE );

    // change to full
    toolBar()->hide();
    m_settingsShowToolBar->setChecked( false );
    statusBar()->hide();
    m_settingsShowStatusBar->setChecked( false );
    menuBar()->hide();
    m_settingsShowMenuBar->setChecked( false );
    
    m_editFullScreen->setText( i18n( "Stop Fullscreen Mode" ) );
    m_editFullScreen->setIcon( "window_nofullscreen" );
  }
  else
  {
    move( _posSave );
    resize( _sizeSave );

    showNormal();  // (calls setCaption, i.e. the one in this class!)
    setCaption( m_filename );

    // Qt bug, the flags aren't restored.
    setWFlags( WType_TopLevel | WDestructiveClose );
    // Other Qt bug
    setAcceptDrops( FALSE );
    topData()->dnd = 0;
    setAcceptDrops( TRUE );

    // change to normal
    toolBar()->show();
    m_settingsShowToolBar->setChecked( true );
    statusBar()->show();
    m_settingsShowStatusBar->setChecked( true );
    menuBar()->show();
    m_settingsShowMenuBar->setChecked( true );

    m_editFullScreen->setText( i18n( "Fullscreen Mode" ) );
    m_editFullScreen->setIcon( "window_fullscreen" );

    kapp->setTopWidget( this ); //restores the icon
  }
}

void KImageViewer::reset()
{
  _canvas->reset();
  _mat.reset();
}

void KImageViewer::saveProperties( KConfig *cfg )
{
  cfg->writeEntry( "ViewerFullScreen", m_bFullScreen );
  if( m_bFullScreen )
  {
    cfg->writeEntry( "ViewerPos", _posSave );
    cfg->writeEntry( "ViewerSize", _sizeSave );
  }
  else
  {
    cfg->writeEntry( "ViewerPos", pos() );
    cfg->writeEntry( "ViewerSize", size() );
  }

  _imageList->saveProperties( cfg );
}

void KImageViewer::readProperties( KConfig *cfg )
{
  m_bFullScreen = cfg->readBoolEntry( "ViewerFullScreen" );

  if( m_bFullScreen ) {
    fullScreen();
    _posSave = cfg->readPointEntry( "ViewerPos" );
    _sizeSave = cfg->readSizeEntry( "ViewerSize" );
  }
  else {
    move( cfg->readPointEntry( "ViewerPos" ) );
    resize( cfg->readSizeEntry( "ViewerSize" ) );
  }

  _imageList->restoreProperties( cfg );
}

void KImageViewer::slotSaveOptions()
{
  saveOptions();
}

void KImageViewer::saveOptions()
{
  KConfig *cfg = kapp->config();
  {
    KConfigGroupSaver save( cfg, "kview" );
    QString lmode;

    switch ( _loadMode ) {
      case ResizeNone:        lmode = "ResizeNone";   break;
      case ResizeImage:       lmode = "ResizeImage";  break;
      case ResizeWindow:
      default:                lmode = "ResizeWindow"; break;
    }
    cfg->writeEntry( "LoadMode", lmode );

    saveMainWindowSettings( cfg );
  }
  
  _imageList->saveOptions( cfg );
  m_recent->saveEntries( cfg );

  cfg->sync();
}

void KImageViewer::restoreOptions()
{
  KConfig *cfg = kapp->config();
  {
    KConfigGroupSaver save( cfg, "kview" );

    QString lmode = cfg->readEntry( "LoadMode", "ResizeWindow" ).lower();

    if ( lmode == "resizewindow" ) {
      _loadMode = ResizeWindow;
    }
    else if (lmode == "resizeimage" ) {
      _loadMode = ResizeImage;
    }
    else if (lmode == "resizenone" ) {
      _loadMode = ResizeNone;
    }
    else {
      kdWarning() << "kview: warning: Unknown resize mode " << lmode << endl;
      _loadMode = ResizeWindow;
    }

    applyMainWindowSettings( cfg );
    m_settingsShowToolBar->setChecked( !toolBar()->isHidden() );
    m_settingsShowStatusBar->setChecked( !statusBar()->isHidden() );
    m_settingsShowMenuBar->setChecked( !menuBar()->isHidden() );
  }

  _imageList->restoreOptions( cfg );
  m_recent->loadEntries( cfg );
}

void KImageViewer::printImage()
{
        QPrinter printer;

        // get settings
        if( QPrintDialog::getPrinterSetup( &printer ) == false )
                return;

        // print

        setStatus( i18n( "Printing..." ) );
        QApplication::setOverrideCursor( WaitCursor );
        _canvas->copyImage( &printer );
        printer.newPage();
        QApplication::restoreOverrideCursor();
        setStatus( 0 );
}

void KImageViewer::newViewer()
{
        emit wantNewViewer();
}

void KImageViewer::closeViewer()
{
        emit wantToDie( this );
}

void KImageViewer::closeEvent( QCloseEvent * )
{
        closeViewer();
}

void KImageViewer::cut()
{
        // TODO: stub
}

void KImageViewer::copy()
{
        // TODO: stub
}

void KImageViewer::paste()
{
        // TODO: stub
}

void KImageViewer::slotConfAccels()
{
  KKeyDialog::configureKeys( actionCollection(), xmlFile() );
}

void KImageViewer::prefs()
{
  KViewConfDialog dlg( this );
  dlg.setLoop( _imageList->loop() );
  dlg.setInterval( _imageList->interval() );
  dlg.setResize( int( _loadMode ) );

  if( dlg.exec() )
  {
    _imageList->setLoop( dlg.loop() );
    _imageList->setInterval( dlg.interval() );
    switch( dlg.resize() )
    {
      case 0: _loadMode = ResizeWindow; break;
      case 1: _loadMode = ResizeImage;  break;
      case 2: _loadMode = ResizeNone;   break;
    }
  }
}

void KImageViewer::rzWinToImg()
{
/*
plan: to make the client area of the KTW == area of canvas contents.
        pending:        image will fit on screen
                                size + extra
                        move allowed (TODO)
*/

  // we don't want to resize in FullScreen mode
  if( m_bFullScreen ) return;

  int iw = _canvas->contentsWidth();
  int ih = _canvas->contentsHeight();

  QRect geom = geometry();
  QRect desk = kapp->desktop()->geometry();

  int xextra = geom.width() - _canvas->visibleWidth();
  int yextra = geom.height()- _canvas->visibleHeight();

  resize( iw + xextra, ih + yextra );

  geom = geometry();

  xextra = geom.width() - _canvas->visibleWidth();
  yextra = geom.height()- _canvas->visibleHeight();
  int xmax = desk.width()  - ( xextra + geom.x() );
  int ymax = desk.height() - ( yextra + geom.y() );

  resize( QMIN( iw + xextra, xmax ), QMIN( ih + yextra, ymax ) );
}

void KImageViewer::setupActions( KFilterList *filters )
{
  //setup the file menu
  KStdAction::open( this, SLOT( load() ), actionCollection() );
  m_recent = KStdAction::openRecent(this, SLOT( openRecent( const KURL& ) ), actionCollection());
  m_fileSave = KStdAction::save( this, SLOT( slotSave() ), actionCollection() );
  m_fileSaveAs = KStdAction::saveAs( this, SLOT( saveAs() ), actionCollection() );
  m_fileClose = KStdAction::close( this, SLOT( file_close() ), actionCollection() );
  m_filePrint = KStdAction::print( this, SLOT( printImage() ), actionCollection() );
  (void)new KAction( i18n( "&New Window" ), CTRL+Key_N, this, SLOT( newViewer() ),
                     actionCollection(), "new_window" );
  (void)new KAction( i18n( "Close &Window" ), CTRL+Key_X, this, SLOT( closeViewer() ),
                     actionCollection(), "close_window" );
  KStdAction::quit( this, SLOT( quitApp() ), actionCollection() );

  //setup the edit menu
  m_editFullScreen = new KAction( i18n( "&Fullscreen Mode" ), "window_fullscreen", CTRL+SHIFT+Key_F, this, SLOT( fullScreen() ),
                     actionCollection(), "fullscreen" );
  m_editCrop = new KAction( i18n( "&Crop" ), Key_C, _canvas, SLOT( cropImage() ),
                     actionCollection(), "crop" );
  m_editCrop->setEnabled( false );
  m_editReset = KStdAction::undo( this, SLOT( reset() ), actionCollection(), "reset" );
  m_editReset->setText( i18n( "&Reset" ) );
  m_editReset->setAccel( CTRL+Key_R );

  //setup the view menu
  m_viewMenu = new KActionMenu( i18n( "&View" ), actionCollection(), "view" );

  m_viewZoom = KStdAction::zoom( this, SLOT( zoomCustom() ), actionCollection(), "zoom" );
  m_viewZoomIn = KStdAction::zoomIn( this, SLOT( zoomIn10() ), actionCollection(), "zoom_in" );
  m_viewZoomOut = KStdAction::zoomOut( this, SLOT( zoomOut10() ), actionCollection(), "zoom_out" );
  m_viewDouble = new KAction( i18n( "&Double size" ), Key_BracketRight, this, SLOT( zoomIn200() ),
                     actionCollection(), "double_size" );
  m_viewHalf = new KAction( i18n( "&Half size" ), Key_BracketLeft, this, SLOT( zoomOut50() ),
                     actionCollection(), "half_size" );
  m_viewMax = new KAction( i18n( "&Max size" ), Key_M, _canvas, SLOT( maxToWin() ),
                     actionCollection(), "max_size" );
  m_viewMaxpect = new KAction( i18n( "Max/&aspect" ), Key_A, _canvas, SLOT( maxpectToWin() ),
                     actionCollection(), "max_aspect" );
  m_viewMenu->insert( m_viewZoom );
  m_viewMenu->insert( m_viewZoomIn );
  m_viewMenu->insert( m_viewZoomOut );
  m_viewMenu->insert( m_viewDouble );
  m_viewMenu->insert( m_viewHalf );
  m_viewMenu->insert( m_viewMax );
  m_viewMenu->insert( m_viewMaxpect );

  //setup the transform menu
  m_transMenu = new KActionMenu( i18n( "&Transform" ), actionCollection(), "transform" );

  m_transRotateClock = new KAction( i18n( "Rotate &clockwise" ), Key_Semicolon, this, SLOT( rotateClock() ),
                     actionCollection(), "rotate_clockwise" );
  m_transRotateAnti = new KAction( i18n( "Rotate &anti-clockwise" ), Key_Comma, this, SLOT( rotateAntiClock() ),
                     actionCollection(), "rotate_anti-clockwise" );
  m_transFlipV = new KAction( i18n( "Flip &vertical" ), Key_V, this, SLOT( flipVertical() ),
                     actionCollection(), "flip_vertical" );
  m_transFlipH = new KAction( i18n( "Flip &horizontal" ), Key_H, this, SLOT( flipHorizontal() ),
                     actionCollection(), "flip_horizontal" );
  m_transMenu->insert( m_transRotateClock );
  m_transMenu->insert( m_transRotateAnti );
  m_transMenu->insert( m_transFlipV );
  m_transMenu->insert( m_transFlipH );

  //setup the desktop menu
  m_deskMenu = new KActionMenu( i18n( "&Desktop" ), actionCollection(), "desktop" );

  m_deskTile = new KAction( i18n( "Desktop &Tile" ), 0, this, SLOT( tile() ),
                     actionCollection(), "desktop_tile" );
  m_deskMax = new KAction( i18n( "Desktop &Max" ), 0, this, SLOT( max() ),
                     actionCollection(), "desktop_max" );
  m_deskMaxpect = new KAction( i18n( "Desktop Max&pect" ), 0, this, SLOT( maxpect() ),
                     actionCollection(), "desktop_maxpect" );
  m_deskMenu->insert( m_deskTile );
  m_deskMenu->insert( m_deskMax );
  m_deskMenu->insert( m_deskMaxpect );

  //setup the images menu
  m_imageList = new KAction( i18n( "&List..." ), 0, this, SLOT( toggleImageList() ),
                     actionCollection(), "list" );
  m_imagePrev = KStdAction::back( _imageList, SLOT( slotPrevious() ), actionCollection(), "previous" );
  m_imageNext = KStdAction::forward( _imageList, SLOT( slotNext() ), actionCollection(), "next" );
  m_imageSlide = new KAction( i18n( "&Slideshow On/Off" ), Key_S, _imageList, SLOT( toggleSlideshow() ),
                     actionCollection(), "slideshow" );

  //setup the filter menu
  m_filterMenu = new KFilterAction( filters, i18n( "&Filter" ), actionCollection(), "filter" );

  // setup Settings menu
  m_settingsShowMenuBar = KStdAction::showMenubar( this, SLOT( toggleMenuBar() ), actionCollection() );
  m_settingsShowToolBar = KStdAction::showToolbar( this, SLOT( toggleToolBar() ), actionCollection() );
  m_settingsShowStatusBar = KStdAction::showStatusbar( this, SLOT( toggleStatusBar() ), actionCollection() );

  KStdAction::saveOptions( this, SLOT( slotSaveOptions() ), actionCollection() );
  KStdAction::preferences( this, SLOT( prefs() ), actionCollection() );

  KStdAction::keyBindings( this, SLOT( slotConfAccels() ), actionCollection() );
  KStdAction::configureToolbars( this, SLOT( slotEditToolbars() ), actionCollection() );

  m_editCrop->setEnabled( false );
  connect( _canvas, SIGNAL( selected( bool ) ), m_editCrop, SLOT( setEnabled( bool ) ) );

  connectFilters( filters );
  menuEntriesEnabled( false );

  QValueList<KAction*> actions = actionCollection()->actions();
  for (QValueList<KAction*>::ConstIterator it = actions.begin(); it != actions.end(); it++)
     (*it)->plugAccel(m_accel);
  createGUI();
}

void KImageViewer::toggleMenuBar()
{
  if( menuBar()->isVisible() )
    menuBar()->hide();
  else
    menuBar()->show();
}

void KImageViewer::slotEditToolbars()
{
  KEditToolbar dlg( actionCollection() );
 
  if ( dlg.exec() )
    createGUI();
}

void KImageViewer::toggleToolBar()
{
  if( toolBar()->isVisible() )
    toolBar()->hide();
  else
    toolBar()->show();
}

void KImageViewer::toggleStatusBar()
{
  if( statusBar()->isVisible() )
    statusBar()->hide();
  else
    statusBar()->show();
}

#include "viewer.moc"

