/* ====================================================================
 * Copyright (c) 2007-2009  Martin Hauner
 *                          http://subcommander.tigris.org
 *
 * Subcommander is licensed as described in the file doc/COPYING, which
 * you should have received as part of this distribution.
 * ====================================================================
 */

#ifndef _SC_WCVIEWTREE_H
#define _SC_WCVIEWTREE_H

// sc
#include "TreeView.h"
#include "WcViewViewState.h"
#include "svn/WcStatusTypes.h"
#include "svn/ClientTypes.h"
#include "util/String.h"
class WcViewTreeProxyModel;
class WcViewItemProxyModel;
class DeepStatus;
class WcSelection;
class ActionStorage;
class DragInfo;

// qt
class Q3PopupMenu;


/**
 * Working copy display widget. It can be configured as a tree view or
 * a flat view. The flat view is a tree view with minimum indentation
 * and no tree decoration. Internally it is always based on a tree
 * model.
 *\todo rename to WcViewView
 */
class WcViewTree : public TreeView
{
  typedef TreeView super;
  Q_OBJECT

public:
#ifdef SC_NEWPROXY
  WcViewTree( WcViewItemProxyModel* model, WcViewViewState* state,
    ActionStorage* as, QWidget* parent );
#else // SC_NEWPROXY
  WcViewTree( WcViewTreeProxyModel* model, WcViewViewState* state,
    ActionStorage* as, QWidget* parent );
#endif // SC_NEWPROXY
  ~WcViewTree();

public slots:
  /** remove old info.. */
  void updateOld( const sc::String&, const svn::WcStatuss& );
  /** ..add new info */
  void updateNew( const sc::String&, const svn::WcStatuss&, bool deep );

  void setCurrentDir( const sc::String& newCurrent );
  /** refresh the view, honoring any option changes */
  void refresh();
  /** adjust to state type */
  void refreshType();

  /** header geometry changed. */
  void headerChanged(int,int,int);

  // Q.. overwrites
  void contextMenuEvent( QContextMenuEvent* e );
  /** update actions after selection change */
  void selectionChanged( const QItemSelection& selected, const
    QItemSelection& deselected );
  
  void mouseDoubleClickEvent( QMouseEvent* e );
  /** Rename the current item to @a text. */
  void renameItem( const QString& text );
  void storeExpandedState( const QModelIndex& index );
  void storeCollapsedState( const QModelIndex& index );

  void showEvent( QShowEvent* );
  void mousePressEvent( QMouseEvent* e );
  void mouseMoveEvent( QMouseEvent* e );
  void dragEnterEvent( QDragEnterEvent* e );
  void dragMoveEvent( QDragMoveEvent* e );
  void dragLeaveEvent( QDragLeaveEvent* e );
  void dropEvent( QDropEvent* e );
  void timerEvent( QTimerEvent* e );

  void deepStatusChanged( const sc::String& );

signals:
  /** Signal move item, set base if @a to is a basename, else a dirname
      is assumed. */
  void move( const sc::String& to, bool base );
  void copy( const sc::String& to );
  /** notify current dir change */
  void currentChanged( const sc::String& );
  void selectionChanged( const WcSelection& );

private:
  void updateMenu( const WcSelection& sel );
  void getSelection( svn::WcStatuss& statuss );
  QMimeData* mimeData( const QModelIndexList& list );
  void restoreState( const QModelIndex& index );
  void restoreStates( const QModelIndex& index );

  bool shouldStoreExpandedState() const;
  void setRestoringExpandedState();
  void clrRestoringExpandedState();

  void storeExpandedState( const QModelIndex& index, bool state );

private:
#ifdef SC_NEWPROXY
  WcViewItemProxyModel* _proxyModel;
#else // SC_NEWPROXY
  WcViewTreeProxyModel* _proxyModel;
#endif // SC_NEWPROXY
  WcViewViewState*      _state;

  ActionStorage*        _actions;
  Q3PopupMenu*          _menu;

  bool                  _restoringExpandedState; ///< ignore expanded &
                                                 ///< collapsed signals.
  svn::Paths            _deepStatusPaths;        ///< expand
};

#endif // _SC_WCVIEWTREE_H
