/*! @file

    @id $Id$
*/
//       1         2         3         4         5         6         7         8
// 45678901234567890123456789012345678901234567890123456789012345678901234567890

#ifndef SWISSWEBVIEW_HXX
#define SWISSWEBVIEW_HXX

#include <qbrowserlib/swisswebpage.hxx>

#include <QtWebKit>
#include <QWebView>
#include <QDesignerExportWidget>

#include <memory>

//! @addtogroup qbrowserlib
//! @{

namespace qbrowserlib {

  //! QWebViev class with additional features.
  /*! This QWebView class contains a @ref SwissWebPage and adds a new
      signal @refs newView that sends the view whenever the a new view
      (new window, new tab) must be opened.

      \copydetails  SwissWebView::newView(SwissWebView*)
      */ 
  class SwissWebView: public QWebView {
      Q_OBJECT;
    Q_SIGNALS:
      //! Signals that a new window (or tab) must be opened
      /*! @note You @b must connect to @ref newView and assign the new
          @ref SwissWebView instance to a partent widget or at least
          delete it, otherwise you'll have a memory leak! */
      void newView(qbrowserlib::SwissWebView*);
    public:
      //! Default construction, creates new @ref SwissWebView
      SwissWebView(QWidget *parent=0,
                   QNetworkAccessManager* net=0): QWebView(parent) {
        if (!net) net = (_fallbackNetworkAccessManager =
                         std::auto_ptr<QNetworkAccessManager>
                         (new QNetworkAccessManager)).get();
        //! @bugfix, gcc does not yet support constructor calling
        x(new SwissWebPage(net, this));
      }
      //! Construction with externally allocated @ref SwissWebPage
      /*! SwissWebView takes ownership of SwissWebPage. */
      SwissWebView(SwissWebPage* webpage) {
        //! @bugfix, gcc does not yet support constructor calling
        x(webpage); 
      }
    private:
      //! @bugfix, gcc does not yet support constructor calling
      /*! @see http://en.wikipedia.org/wiki/C++11#Object_construction_improvement
          */
      void x(SwissWebPage* webpage) {
        webpage->setParent(this);
        setPage(webpage);
        // create a new SwissWebView when a new SwissWebPage has been created
        assert(connect(page(), SIGNAL(newPage(SwissWebPage*)),
                       SLOT(newPage(SwissWebPage*))));
      }
    private Q_SLOTS:
      void newPage(SwissWebPage* p) {
        // memory will be lost if signal is not handled and SwissWebView
        // is not assigned
        newView(new SwissWebView(p));
      }

    private:

      std::auto_ptr<QNetworkAccessManager> _fallbackNetworkAccessManager;
  };

}

//! @}
#endif
