/*
rkworkplaceview - This file is part of the RKWard project. Created: Tue Sep 26 2006
SPDX-FileCopyrightText: 2006-2020 by Thomas Friedrichsmeier <thomas.friedrichsmeier@kdemail.net>
SPDX-FileContributor: The RKWard Team <rkward@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/

#ifndef RKWORKPLACEVIEW_H
#define RKWORKPLACEVIEW_H

#include <QSplitter>
#include <QTabWidget>

class RKMDIWindow;
class QAction;
class KActionCollection;
class RKWorkplaceView;

class RKWorkplaceViewPane : public QTabWidget {
	Q_OBJECT
	friend class RKWorkplaceView;

  private:
	explicit RKWorkplaceViewPane(RKWorkplaceView *parent);
	~RKWorkplaceViewPane();
	RKWorkplaceView *workplace_view;
	/** Close a page given the corresponding widget */
	void closePage(QWidget *page);
	/** Close a page given its index */
	void closePage(int page);
	/** (Attempts to) close all tabs in this pane (and thus the pane itself) */
	void closeAll();
	bool isActive();
	void initActions();

  protected:
	void tabRemoved(int index) override;
	void tabInserted(int index) override;
	bool eventFilter(QObject *obj, QEvent *event) override;
  Q_SIGNALS:
	void becameEmpty(RKWorkplaceViewPane *pane);
  private Q_SLOTS:
	/** handle context menu requests */
	void showContextMenu(const QPoint &pos);
	/** handle close request from context menu */
	void contextMenuClosePage();
	/** handle detach request from context menu */
	void contextMenuDetachWindow();
	/** Internal function to ensure proper focus and update caption, when the current page has changed. */
	void currentPageChanged(int page);
};

/** This is mostly a QTabWidget with some extras such as updating the caption, a context menu, etc.
 */

class RKWorkplaceView : public QSplitter {
	Q_OBJECT
	friend class RKWorkplaceViewPane;

  public:
	/** constructor
	@param parent parent QWidget */
	explicit RKWorkplaceView(QWidget *parent);
	~RKWorkplaceView();

	/** add the given window to the view */
	void addWindow(RKMDIWindow *widget);
	/** remove the given window from the view
	@param destroyed if the window is already destroyed, set this to true */
	void removeWindow(RKMDIWindow *widget, bool destroyed = false);
	/** does this window exist in the view? */
	bool hasWindow(RKMDIWindow *widget) const;
	/** show the given page (does not set focus) */
	void showWindow(RKMDIWindow *widget);
	/** Returns true if the given window is in the active pane of this view. */
	bool windowInActivePane(RKMDIWindow *widget) const;

	/** @returns the currently active window */
	RKMDIWindow *activePage() const;
	/** reimplemented form QWidget::setCaption () to Q_EMIT captionChanged () when the caption changes */
	void setCaption(const QString &caption);
	/** initialize the window left/right actions */
	void initActions(KActionCollection *ac);

	/** List the contents of the view, recursively. @see RKWorkplace::makeItemDescription() */
	QStringList listContents() const;
	/** List the layout of the view, recursively. @see RKWorkplace::makeItemDescription() */
	QString listLayout() const;
	/** For use during workplace restoration, only: Make the next pane the active one, so it can be filled with content. @see restoreLayout */
	void nextPane();
	/** For use during workplace restoration, only: Set up splitters and panes according to the given description (generated by listContents()) */
	void restoreLayout(const QString &desc);
	/** For use right after workplace restoration: Purge any panes set up by restoreLayout(), but left empty */
	void purgeEmptyPanes();
	void splitView(Qt::Orientation orientation) { splitView(orientation, QString()); };
  Q_SIGNALS:
	/** a new page / window was activated
	@param widget the newly activated window */
	void pageChanged(RKMDIWindow *widget);
	/** caption has changed
	@param new_caption the new caption */
	void captionChanged(const QString &new_caption);
  private Q_SLOTS:
	/** called when the caption of a window changes. Updates the tab-label, and - if appropriate - the caption of this widget */
	void childCaptionChanged(RKMDIWindow *widget);
	/** Active the page left of the current tab */
	void pageLeft();
	/** Active the page right of the current tab */
	void pageRight();
	/** Purge the given pane (if it is empty) */
	void purgePane(RKWorkplaceViewPane *pane);
	/** Split current view vertically */
	void splitViewVert();
	/** Split current view horizontally */
	void splitViewHoriz();

  private:
	void updateActions();
	RKWorkplaceViewPane *createPane(bool init_actions = true);
	RKWorkplaceViewPane *findWindow(RKMDIWindow *window) const;
	void splitView(Qt::Orientation orientation, const QString &description, const QString &base = QString());

	QAction *action_page_left;
	QAction *action_page_right;
	QAction *action_split_horiz;
	QAction *action_split_vert;

	QList<RKWorkplaceViewPane *> panes;
	RKWorkplaceViewPane *activePane() const;
	/** Newly added pane. Pointer needed so the first "new" window will go here. */
	RKWorkplaceViewPane *newpane;
};

#endif
