/***************************************************************************
                          kbearpropertiesdialog.h  -  description
                             -------------------
    begin                : sön sep 15 2002
    copyright            : (C) 2003 by Björn Sahlström
    email                : kbjorn@users.sourceforge.net
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef KBEARPROPERTIESDIALOG_H
#define KBEARPROPERTIESDIALOG_H

//////////////////////////////////////////////////////////////////////
// Qt specific include files
#include <qwidget.h>
#include <qstring.h>
#include <qlist.h>
//////////////////////////////////////////////////////////////////////
// KDE specific include files
#include <kurl.h>
#include <kfileitem.h>
#include <kdialogbase.h>
//////////////////////////////////////////////////////////////////////
// Application specific include files



class QLineEdit;
class QCheckBox;
class QPushButton;
class KLineEdit;
class KURLRequester;
class QButton;
class KIconButton;
class KBearPropsDlgPlugin;
class QComboBox;
class Transfer;

/**
  *@author Björn Sahlström, hacked from KPropertiesDialog
  */


namespace KIO { class Job; }

/**
 * The main properties dialog class.
 * A Properties Dialog is a dialog which displays various information
 * about a particular file or URL, or several ones.
 * This main class holds various related classes, which are instantiated in
 * the form of tab entries in the tabbed dialog that this class provides.
 * The various tabs themselves will let the user view or change information
 * about the file or URL.
 *
 * This class must be created with (void)new KBearPropertiesDialog(...)
 * It will take care of deleting itself.
 */
class KBearPropertiesDialog : public KDialogBase {
	Q_OBJECT
	public:

	/**
	* @return whether there are any property pages available for the
	* given file items
	*/
	static bool canDisplay( KFileItemList _items );

  /**
   * Brings up a Properties dialog. Normal constructor for
   * file-manager-like applications.
   *
   * @param _items list of file items whose properties should be
   * displayed.
   *
   * @param parent is the parent of the dialog widget.
   * @param name is the internal name.
   * @param modal tells the dialog whether it should be modal.
   * @param autoShow tells the dialog whethr it should show itself automatically.
   */
  KBearPropertiesDialog( int id, KFileItemList _items, QWidget *parent, const char* name);



  /**
   * Cleans up the properties dialog and frees any associated resources,
   * including the dialog itself. Note that when a properties dialog is
   * closed it cleans up and deletes itself.
   */
  virtual ~KBearPropertiesDialog();


  /**
   * Adds a "3rd party" properties plugin to the dialog.  Useful
   * for extending the properties mechanism.
   *
   * To create a new plugin type, inherit from the base class KPropsPlugin
   * and implement all the methods. If you define a service .desktop file
   * for your plugin, you do not need to call insertPlugin().
   *
   * @param plugin is a pointer to the PropsPlugin. The Properties
   *        dialog will do destruction for you. The KPropsPlugin MUST
   *        have been created with the KBearPropertiesDialog as its parent.
   * @see KBearPropsDlgPlugin
   */
  void insertPlugin (KBearPropsDlgPlugin *plugin);

	/**
   * @return a parsed URL.
   * Valid only if dialog shown for one file/url.
   */
  const KURL& kurl() const { return m_singleUrl; }

  /**
   * @return the file item for which the dialog is shown
   * Warning, it returns the first item of the list.
   * This means, use this only if you are sure the dialog is used
   * for a single item.
   */
  KFileItem *item() { return m_items.first(); }

  /**
   * @return the items for which the dialog is shown
   */
  KFileItemList items() const { return m_items; }

  /**
   * @return a pointer to the dialog
   * @deprecated
   */
  KDialogBase* dialog() { return this; }
  const KDialogBase* dialog() const { return this; }

  /**
   * If we are building this dialog from a template,
   * @return the current directory
   * QString::null means no template used
   */
  const KURL& currentDir() const { return m_currentDir; }

  /**
   * If we are building this dialog from a template,
   * @return the default name (see 3rd constructor)
   * QString::null means no template used
   */
  const QString& defaultName() const { return m_defaultName; }

  /**
   * Updates the item url (either called by rename or because
   * a global apps/mimelnk desktop file is being saved)
   * Can only be called if the dialog applies to a single file/URL.
   * @param _name new URL
   */
  void updateUrl( const KURL& _newUrl );

  /**
   * #see FilePropsPlugin::applyChanges
   * Can only be called if the dialog applies to a single file/URL.
   * @param _name new filename, encoded.
   */
  void rename( const QString& _name );

  /**
   * To abort applying changes.
   */
  void abortApplying();

//  void showFileSharingPage();

public slots:
  /**
   * Called when the user presses 'Ok'.
   */
  virtual void slotOk();      // Deletes the PropertiesDialog instance
  virtual void slotCancel();     // Deletes the PropertiesDialog instance

signals:
  /**
   * Emitted when we have finished with the properties (be it Apply or Cancel)
   */
  void propertiesClosed();
  void applied();
  void canceled();
	void infoMessage( const QString& );

private:

  /**
   * Common initialization for all constructors
   */
  void init ();

  /**
   * Inserts all pages in the dialog.
   */
  void insertPages();

  /**
   * The URL of the props dialog (when shown for only one file)
   */
  KURL m_singleUrl;

  /**
   * List of items this props dialog is shown for
   */
  KFileItemList m_items;

  /**
   * For templates
   */
  QString m_defaultName;
  KURL m_currentDir;

  /**
   * List of all plugins inserted ( first one first )
   */
  QPtrList<KBearPropsDlgPlugin> m_pageList;

private:
	int m_ID;
  class KBearPropertiesDialogPrivate;
  KBearPropertiesDialogPrivate *d;
};


/**
 * A Plugin in the Properties dialog
 * This is an abstract class. You must inherit from this class
 * to build a new kind of page.
 * A plugin in itself is just a library containing code, not a dialog's page.
 * It's up to the plugin to insert pages into the parent dialog.
 *
 * To make a plugin available, define a service that implements the KPropsDlg/Plugin
 * servicetype, as well as the mimetypes for which the plugin should be created.
 * For instance, ServiceTypes=KPropsDlg/Plugin,text/html,application/x-mymimetype.
 *
 * You can also include X-KDE-Protocol=file if you want that plugin
 * to be loaded only for local files, for instance.
 */
class KBearPropsDlgPlugin : public QObject
{
  Q_OBJECT
public:
  /**
   * Constructor
   * To insert tabs into the properties dialog, use the add methods provided by
   * KDialogBase (the properties dialog is a KDialogBase).
   */
  KBearPropsDlgPlugin( int id, KBearPropertiesDialog *_props );
  virtual ~KBearPropsDlgPlugin();

  /**
   * Applies all changes to the file.
   * This function is called when the user presses 'Ok'. The last plugin inserted
   * is called first.
   */
  virtual void applyChanges();

  /**
   * Convenience method for most ::supports methods
   * @return true if the file is a local, regular, readable, desktop file
   */
  static bool isDesktopFile( KFileItem * _item );

  void setDirty( bool b );
  bool isDirty() const;

public slots:
  void setDirty(); // same as setDirty( true )

signals:
  /**
   * Emit this signal when the user changed anything in the plugin's tabs.
   * The hosting PropertiesDialog will call @ref applyChanges only if the
   * PropsPlugin has emitted this signal before.
   */
  void changed();

	void infoMessage( const QString& );
protected slots:
	void slotInfoMessage( const QString&, const QString& m );
	void slotInfoMessage( KIO::Job*, const QString& );
protected:
  /**
   * Pointer to the dialog
   */
  KBearPropertiesDialog *properties;
	int m_ID;

  int fontHeight;
private:
  class KBearPropsDlgPluginPrivate;
  KBearPropsDlgPluginPrivate *d;
};

/**
 * 'General' plugin
 *  This plugin displays the name of the file, its size and access times.
 * @internal
 */
class KBearFilePropsPlugin : public KBearPropsDlgPlugin
{
  Q_OBJECT
public:
  /**
   * Constructor
   */
  KBearFilePropsPlugin( int id, KBearPropertiesDialog *_props );
  virtual ~KBearFilePropsPlugin();

  /**
   * Applies all changes made.  This plugin must be always the first
   * plugin in the dialog, since this function may rename the file which
   * may confuse other applyChanges functions.
   */
  virtual void applyChanges();

  /**
   * Tests whether the files specified by _items need a 'General' plugin.
   */
  static bool supports( KFileItemList _items );

  /**
   * Called after all plugins applied their changes
   */
  void postApplyChanges();

protected slots:
  void slotCopyFinished( KIO::Job * );
  void slotFileRenamed( KIO::Job *, const KURL &, const KURL & );
  void slotDirSizeFinished( KIO::Job * );
//  void slotFoundMountPoint( const QString& mp, unsigned long kBSize, unsigned long kBUsed, unsigned long kBAvail );
  void slotSizeStop();
  void slotSizeDetermine();

private slots:
  // workaround for compiler bug
//void slotFoundMountPoint( const unsigned long& kBSize, const unsigned long& kBUsed, const unsigned long& kBAvail, const QString& mp );
 void nameFileChanged(const QString &text );
private:

//  void determineRelativePath( const QString & path );

  QWidget *iconArea;
  QWidget *nameArea;

  QLabel *m_sizeLabel;
  QPushButton *m_sizeDetermineButton;
  QPushButton *m_sizeStopButton;

  QString m_sRelativePath;
  bool m_bFromTemplate;

  /**
   * The initial filename
   */
  QString oldName;
  class KBearFilePropsPluginPrivate;
  KBearFilePropsPluginPrivate *d;
};

/**
 * 'Permissions' plugin
 * In this plugin you can modify permissions and change
 * the owner of a file.
 * @internal
 */
class KBearFilePermissionsPropsPlugin : public KBearPropsDlgPlugin
{
  Q_OBJECT
public:
  /**
   * Constructor
   */
  KBearFilePermissionsPropsPlugin( int id, KBearPropertiesDialog *_props );
  virtual ~KBearFilePermissionsPropsPlugin();

  virtual void applyChanges();

  /**
   * Tests whether the file specified by _items needs a 'Permissions' plugin.
   */
  static bool supports( KFileItemList _items );

private slots:

  void slotChmodResult( KIO::Job * );
  void slotRecursiveClicked();

private:
  QCheckBox *permBox[3][4];

  QComboBox *grpCombo;
  KLineEdit *usrEdit, *grpEdit;

  /**
   * Old permissions
   */
  mode_t permissions;
  /**
   * Old group
   */
  QString strGroup;
  /**
   * Old owner
   */
  QString strOwner;

  /**
   * Changeable Permissions
   */
  static mode_t fperm[3][4];
  class KBearFilePermissionsPropsPluginPrivate;
  KBearFilePermissionsPropsPluginPrivate *d;
};

#endif
