// This may look like C code, but it is really -*- C++ -*-

//<copyright>
// 
// Copyright (c) 1994,95,96
// Institute for Information Processing and Computer Supported New Media (IICM),
// Graz University of Technology, Austria.
// original version:
// Copyright (c) 1991 Stanford University
// Copyright (c) 1991 Silicon Graphics, Inc.
// 
//</copyright>


//<file>
//
// File:        fchooser.h - interface to file chooser
//
// Created:      1 Jul 94   Michael Pichler
//
// $Id: fchooser.h,v 1.9 1996/02/19 15:58:31 bmarsch Exp $
//
//</file>
//
// $Log: fchooser.h,v $
// Revision 1.9  1996/02/19 15:58:31  bmarsch
// Also accept callback for directories if flag is set
//
// Revision 1.8  1996/02/19 08:50:44  bmarsch
// Added flag to constructor to get a selection callback for
// directories
//
// Revision 1.7  1996/02/15 17:39:25  bmarsch
// Includes from OS/ were moved to hyperg/OS/
//
// Revision 1.6  1996/02/12 14:30:44  bmarsch
// Added members to get/change current directory
//
// Revision 1.5  1996/02/08 16:03:55  bmarsch
// Implemented members select_all() and deselect_all()
//
// Revision 1.4  1996/02/01 08:10:05  bmarsch
// Implemented multiselection
//


#ifndef harmony_widgets_fchooser_h
#define harmony_widgets_fchooser_h

#include "libwidgets.h"

#include <InterViews/dialog.h>
class WidgetKit;
#include <hyperg/OS/enter-scope.h>
class Directory;
class String;

class FieldEditor31;
class WFileBrowser;
class WFileChooserImpl;
class WFileChooserAction;


// File Chooser Dialog

class WFileChooser: public Dialog
{
  public:
    WFileChooser(                       // file chooser dialog
      const char* dir,                  //   start directory
      WidgetKit*,                       //   kit
      Style*,                           //   style
      WFileChooserAction* = nil,        //   action
      const char* filefilter = 0,       //   file name filter (e.g. "*.xxx")
      boolean multiselect = false,      //   allow multiple selections
      boolean dir_callbacks = false     //   call callbacks also for directories
    );
    virtual ~WFileChooser();

    virtual const char* selected(int i=-1) const;    // selection string
    virtual void reread();              // rescan directory

    void rebuild();                     // rebuild dialog

    FieldEditor31* editorField() const; // file name field
    WFileBrowser* fileBrowser() const;  // file browser (for focus management)
    Glyph* browserGlyph() const;        // file browser with scroll bar

    Directory* dir() const;             // get current directory
    void dir(const char* path);         // set current directory

    // Dialog
    virtual void dismiss(boolean);      // close dialog

    // multiple selections
    int num_selected() const;
    void select_all();
    void deselect_all();

  private:
    WFileChooserImpl* impl_;
};


class WFileChooserAction: public Resource
{
  protected:
    WFileChooserAction();
    virtual ~WFileChooserAction();

  public:
    virtual void execute(WFileChooser*, boolean accept);
    virtual void selection(WFileChooser*);
};


// WFileChooserCallback
// callback action for WFileChooser - preprocessor template
// lass declaration and implementation for class T are generated
// with declareWFileChooserCallback(T) and implementWFileChooserCallback(T)

#if defined(__STDC__) || defined(__ANSI_CPP__)
#define WFileChooserCallback(T) T##_WFileChooserCallback
#define WFileChooserMemberFunction(T) T##_WFileChooserMemberFunction
#define WFileChooserSelectFunction(T) T##_WFileChooserSelectFunction
#else
#define WFileChooserCallback(T) T/**/_WFileChooserCallback
#define WFileChooserMemberFunction(T) T/**/_WFileChooserMemberFunction
#define WFileChooserSelectFunction(T) T/**/_WFileChooserSelectFunction
#endif


#define declareWFileChooserCallback(T) \
typedef void (T::*WFileChooserMemberFunction(T))(WFileChooser*, boolean); \
typedef void (T::*WFileChooserSelectFunction(T))(WFileChooser*); \
class WFileChooserCallback(T) : public WFileChooserAction { \
public: \
    WFileChooserCallback(T)(T*, WFileChooserMemberFunction(T), \
                            WFileChooserSelectFunction(T) = nil); \
    virtual ~WFileChooserCallback(T)(); \
\
    virtual void execute(WFileChooser*, boolean accept); \
    virtual void selection(WFileChooser*); \
private: \
    T* obj_; \
    WFileChooserMemberFunction(T) func_; \
    WFileChooserSelectFunction(T) select_; \
};


#define implementWFileChooserCallback(T) \
WFileChooserCallback(T)::WFileChooserCallback(T)( \
    T* obj, WFileChooserMemberFunction(T) func, \
    WFileChooserSelectFunction(T) sel \
) { \
    obj_ = obj; \
    func_ = func; \
    select_ = sel; \
} \
\
WFileChooserCallback(T)::~WFileChooserCallback(T)() { } \
\
void WFileChooserCallback(T)::execute(WFileChooser* f, boolean accept) { \
    WFileChooserMemberFunction(T) pf = func_; \
    (obj_->*pf)(f, accept); \
} \
\
void WFileChooserCallback(T)::selection(WFileChooser* f) { \
    WFileChooserSelectFunction(T) sel = select_; \
    if (sel) (obj_->*sel)(f); \
}


#endif
