/* ****************************************************************************
  This file is part of KBabel

  Copyright (C) 1999-2000 by Matthias Kiefer
                            <matthias.kiefer@gmx.de>
                2001      by Stanislav Visnovsky <visnovsky@kde.org>

  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., 675 Mass Ave, Cambridge, MA 02139, USA.

**************************************************************************** */
#ifndef CATALOGMANAGERVIEW_H
#define CATALOGMANAGERVIEW_H

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <qdict.h>
#include <qlistview.h>
#include <qdatetime.h>
#include <qtimer.h>
#include <qfileinfo.h>
#include <qguardedptr.h>

#include <kdialogbase.h>
#include <kdirwatch.h>
#include <kprocess.h>
#include <qptrlist.h>

#include "settings.h"
#include "finddialog.h"

class CatManListItem;
class QPixmap;
class QPopupMenu;
class KBabelDictBox;
class CatManPreferences;
class QTextEdit;
class KProgress;
class KConfig;
class KBabelMailer;
struct PoInfo;


class CatalogManagerView : public QListView
{
   Q_OBJECT
public:
   CatalogManagerView(QWidget* parent=0, const char* name=0);
   virtual ~CatalogManagerView();

   CatManSettings settings() const;
   /** clears the tree */
   virtual void clear();

   /** pauses the update timer */
   void pause(bool);

   /** if file fileWithPath exists in the treeview, this is updated */
   void updateFile(QString fileWithPath, bool force = false);

   void updateAfterSave(QString fileWithPath, PoInfo &info);

   bool isActive() const {return _active;}
   bool isStopped() const {return _stop;}

   void restoreView(KConfig *config);
   void saveView(KConfig *config) const;
   
   void setRMBMenuFile( QPopupMenu *m);
   void setRMBMenuDir( QPopupMenu *m);
   void setDirCommandsMenu( QPopupMenu *m);
   void setFileCommandsMenu( QPopupMenu *m);
   
public slots:
   void setSettings(CatManSettings newSettings);
   void toggleMark();
   /**
   * removes all marks in directory of current item (must be a directory)
   */
   void slotClearMarksInDir();
   void clearAllMarks();
   void toggleAllMarks();
   void loadMarks();
   void saveMarks();
   /**
   * traverses all childs in the directory of the current item
   * (including all subdirectories) and displays some statistics
   * about the translations. If the item is a file, its
   * parent directory is used instead.
   */
   void statistics();
   /**
   * traverses all marked childs in the directory of the current item
   * (including all subdirectories) and displays some statistics
   * about the translations. If the item is a file, its
   * parent directory is used instead.
   */
   void markedStatistics();
   /** 
	* calls @ref Msgfmt::checkSyntax, to check the po-file of 
	* the selected item 
	*/
   void checkSyntax();
   
   void roughTranslation();
   void markedRoughTranslation();

   /** Send the selected item as a compressed mail attachment. If the 
    *  selected item is a directory send the items contained in the
    *  directory.
    */
   void mailFiles();
   /** Send the marked items as a compressed mail attachment.
    */
   void mailMarkedFiles();
   
   QString find(FindOptions &options, QStringList &rest);

   void showLog();

   void stop(bool s = true);
   
   /**
   * Stop searching, do not try to proceed to the next file
   * @ref @find will return clear list of rest to be searched
   * and @ref QString::null, if search string was not is the last searched file
   */
   void stopSearch();
   
   /**
   * Information for this file has been read. If the file is in 
   * @ref @_readInfoFileList, it will update progress bar by emitting @ref @progress
   */
   void fileInfoRead( QString file );
   
   void gotoNextUntranslated();
   void gotoPreviousUntranslated();
   void gotoNextFuzzy();
   void gotoPreviousFuzzy();
   void gotoNextFuzzyOrUntranslated();
   void gotoPreviousFuzzyOrUntranslated();
   void gotoNextError();
   void gotoPreviousError();
   void gotoNextTemplate();
   void gotoPreviousTemplate();
   void gotoNextPo();
   void gotoPreviousPo();
   void gotoNextMarked();
   void gotoPreviousMarked();
   
   void updateCurrent();
   
   /**
   * Returns the list of all currently selected files. If current selection is dir,
   * it returns list of all its children.
   */
   QStringList current();
   /**
   * Returns the list of all currently marked files.
   */
   QStringList marked();
   
signals:
   void openFile(QString filename,QString package);
   void openFileInNewWindow(QString filename,QString package);
   void openTemplate(QString openFilename,QString saveFileName,QString package);
   void openTemplateInNewWindow(QString openFilename,QString saveFileName,QString package);
   void settingsChanged(CatManSettings);
   void prepareProgressBar(QString msg,int max);
   void progress(int);
   void clearProgressBar();
   void prepareFindProgressBar(int max);
   void signalBuildTree(bool done);
   void signalSearchedFile(int count);
   
   void selectedChanged(bool hasPo, bool hasPot, bool hasMarks);

signals:
   void updateFinished();

protected:
   /**
   * builds the tree under dir relDir, but does not update any files
   * this functions always traverses all subdirs
   *
   * @param relDir the relative dir under the po- and pot- base directories
   * @param fast if true, no files will be updated
   *
   * @return true, if the directory contains any po or pot-files
   * @see CatalogManagerView::buildDir
   * @see CatalogManagerView::updateDir
   */
   bool buildDir(QString relDir,bool fast=true);

   /**
   * This function is traversing the real directory on the 
   * disc using baseDir as the
   * base directory and starts at baseDir+relDir
   * @param extension the extension of the files in this directory
   * @param fast if true, no file will be updated
   *
   * @return true, if the directory contains any po or pot-files
   * @see CatalogManagerView::buildDir
   * @see CatalogManagerView::updateDir
   */
   bool buildDir(const QString& baseDir,const QString& relDir, const QString extension,bool fast=true);

   /**
   * updates dir relDir and if any new subdir is added 
   * builds this with @ref buildDir
   *
   * This function doesn't enters subdirs except when a new subdir is added.
   * @see CatalogManagerView::buildDir
   */
   void updateDir(QString relDir);

   /**
   * stops the update timer and the dirwatch
   * @see KDirWatch::stop
   * @see QTimer::stop
   */
   virtual void hideEvent(QHideEvent*);
   /**
   * restarts the update timer and the dirwatch
   * @see KDirWatch::start
   * @see QTimer::start
   */
   virtual void showEvent(QShowEvent*);

   /** used for dragging */
   virtual void contentsMousePressEvent(QMouseEvent* e);
   /** used for dragging */
   virtual void contentsMouseMoveEvent(QMouseEvent* e);
   
   void showStatistics( CatManListItem *i, QStringList &packages);

protected slots:
   /** rebuilds the tree*/
   void buildTree();
   /**
   * recurse all visible files and updates them if necessary
   * @see CatManListItem::checkUpdate
   */
   void checkUpdate();

   /** this is called from KDirWatch when a directory has changed */
   void directoryChanged(const QString& dir);
   /** this is called from KDirWatch when a directory has been deleted */
   void directoryDeleted(const QString& dir);

   void showContentsMenu(QListViewItem *, const QPoint &, int col);
   /** does the default action on the currently selected item*/
   void activateItem(QListViewItem *);
   /** emits the state of the selected item using selectedChanged*/
   void checkSelected();
   /** calls @ref activateItem with the selected item as argument*/
   void slotOpenFile();
   void slotOpenFileInNewWindow();
   /** emits signal @ref openTemplate */
   void slotOpenTemplate();
   /** deletes the po-file on the disc, that belongs to the selected item */
   void slotDeleteFile();
   /** toggles the mark of the selected item */
   void slotToggleMark();
   /**
   * toggles all marks in directory of current item (must be a directory)
   */
   void slotToggleMarksInDir();
   void slotDirCommand(int);
   void slotFileCommand(int);

private slots:
   void showOutput(KProcess *proc, char *buffer, int buflen);
   void processEnded(KProcess *proc);

private:
   void readMarker(KConfig *config);
   void saveMarker(KConfig *config) const;
   /** 
	* deletes item with package name (relative directory) relDir
	* and makes sure, that all subitems are removed from the lists
	*/
   void deleteDirItem(QString relDir);
   
   bool hasMatchingWords( QStringList &itemWords, QStringList &searchWords);
   
   CatManListItem *itemBelow( CatManListItem *item );
   CatManListItem *itemAbove( CatManListItem *item );

private:
   QDict<CatManListItem> _dirList;
   QDict<CatManListItem> _fileList;

   KDirWatch *_dirWatch;
   QTimer *_updateTimer;
   
   // list of files for which was calculated the progress bar for reading file info
   QStringList _readInfoFileList;
   // current count of already read files in @ref @_readInfoFileList.
   int _readInfoCount;
   
   CatManSettings _settings;

   QStringList _markerList;

   bool _active;
   // stopping, application quit
   bool _stop;
   // stop searching, do not proceed to the next file
   bool _stopSearch;
   int _updateNesting;

   QPtrList<KProcess> _pendingProcesses;

   QTextEdit* _logView;
   KDialogBase* _logWindow;
   QPopupMenu* _fileContentsMenu;
   QPopupMenu* _dirContentsMenu;
   QPopupMenu* _dirCommandsMenu;
   QPopupMenu* _fileCommandsMenu;

   /** used for starting a drag */
   QPoint _pressPos;
   
   KBabelDictBox* _dictBox;

   KBabelMailer* mailer;
};

#endif // CATALOGMANAGERVIEW_H
