/** * @file PaiTabWidget.h * @brief PAI风格TabWidget * @date 2011-7-19 */ #ifndef PAI_FRAME_WIDGET_PAITABWIDGET_H #define PAI_FRAME_WIDGET_PAITABWIDGET_H #include #include #include "Turtle.h" class QByteArray; namespace pai { namespace gui { /** * @struct DragState * @brief 该结构代表了页签被拖拽时的上下文参数 */ struct DragState { bool isValid; ///< 拖拽参数是否合法 bool isDragging; ///< 是否正在拖拽中 QWidget *pDraggingWidget;///< 拖拽的页面 QIcon tabIcon; ///< 拖拽的页签的图标 QString tabText; ///< 拖拽的页签的文本 QPoint pressPosition; ///< 鼠标初始点击位置 QRect srcRect; ///< 被拖拽页面的矩形 qint64 appPid; ///< 进程id }; /** * @brief 序列化拖拽页签时的上下文参数 * @param[in] dragState 拖拽页签时的上下文参数 * @param[out] blob 序列化的二进制数组 */ extern void Serialize(const DragState& dragState, QByteArray& blob); /** * @brief 从二进制流中反序列化出拖拽参数 * @param[out] dragState 拖拽参数 * @param blob 反序列化的二进制数组 */ extern void Unserialize(DragState& dragState, QByteArray& blob); /** * @class PaiInfoTabBar * @brief P.A.I 系统里消息提示区风格的标签栏 */ class PaiInfoTabBar : public QTabBar { Q_OBJECT public: /** * @brief 构造函数 * @param[in] pParent 父窗口句柄 * @param[in] isSubTabBar 是否为子页签组件 * @param[in] behavior 选择模式 */ PaiInfoTabBar(QWidget *pParent = NULL, bool isSubTabBar = true, SelectionBehavior behavior = SelectPreviousTab); /** * @brief 设置是否可拖拽 * @param[in] draggable 是否可拖拽 */ void SetDraggable(bool draggable); protected: /** * @brief 自绘制页签栏来支持错误状态 * @param[in] pEvent 绘制事件 * @note 该重绘函数主要解决在未拖动的情况的绘制,其中style sheet中 * margin: 0px 0px 1px 5px; padding-right:0px; padding-left:5px;必需设置, * 否则因系统会因为大约5像素的偏差而导致文字的...(elide)被设置错误,在拖动的情况下则完全由QSS来决定。 */ virtual void paintEvent(QPaintEvent *pEvent); /** * @brief 重写鼠标按下事件来初始化拖拽参数 * @param[in] pEvent 鼠标事件 */ virtual void mousePressEvent(QMouseEvent *pEvent); /** * @brief 重写鼠标移动事件来实现页签拖拽到其他位置 * @param[in] pEvent 鼠标事件 */ virtual void mouseMoveEvent(QMouseEvent *pEvent); /** * @brief 重写鼠标释放事件来来重置拖拽参数 * @param[in] pEvent 鼠标事件 */ virtual void mouseReleaseEvent(QMouseEvent *pEvent); /** * @brief 重写事件响应函数来处理Tooltip事件 * @param[in] pEvent 事件 */ virtual bool event(QEvent *pEvent); /** * @brief 重写时钟事件来重置光标 * @param[in] pEvent 定时器事件 */ virtual void timerEvent(QTimerEvent *pEvent); private: /** * @brief 初始化拖拽参数 */ void InitDragState(); /** * @brief 是否可拖拽,取决于父页签容器是否属于一个PaiWorkspace * @return 是否可拖拽 */ bool IsDraggable() const; private: DragState m_DragState; ///< 拖拽参数 bool m_IsSubTabwidget; ///< 是否为子Tabwidget bool m_draggable; ///< 是否可拖拽 int m_OutOfConsoleTimer; ///< 定时器 }; /** * @class PaiTabWidget * @brief P.A.I 系统里消息提示区风格的标签控件 */ class PAI_WIDGET_EXPORT PaiTabWidget : public QTabWidget { Q_OBJECT public: /** * @brief 构造函数 * @param[in] pParent 父控件句柄 * @param[in] isSubTabBar 是否为子Tabbar * @param[in] behavior 选择模式 */ PaiTabWidget(QWidget *pParent, bool isSubTabBar = true, QTabBar::SelectionBehavior behavior = QTabBar::SelectPreviousTab); /** * @brief 是否显示标签 * @param[in] visible 是否显示 */ void SetTabVisible(bool visible); /** * @brief 通过发送信号关闭指定位置的页签,这种方式保证了如果有插件的页签关联了该信号则相关槽函数得以执行。 * @param[in] index 序列号 */ void CloseTab(int index); /** * @brief 通过发送信号关闭所有的页签,这种方式保证了如果有插件的页签关联了该信号则相关槽函数得以执行。 */ void CloseAll(); /** * @brief 设置此标签控件是否接收拖拽来的页签 * @param[in] dropable 是否接收拖拽 */ void SetDropable(bool dropable = true); /** * @brief 获得此标签控件是否接收拖拽来的页签 * @return 是否可以拖拽 */ bool IsDropable(); /** * @brief 设置此标签控件中的页签是否可以被拖拽出去 * @param[in] draggable 是否可以拖拽 */ void SetTabBarDraggable(bool draggable); public slots: /** * @brief 响应Tab页切换的消息 * @param[in] index 切换后的当前Tab页面的index */ void OnCurrentChanged(int index); protected: /** * @brief 重写该函数来发出一个Tab被添加的消息 * @param[in] index 索引号 */ virtual void tabInserted(int index); /** * @brief 重写该函数来发出最后一个Tab被移除的消息 * @param[in] index 索引号 */ virtual void tabRemoved(int index); /** * @brief 绘制事件 * @param[in] pEvent 绘制事件 */ virtual void paintEvent(QPaintEvent *pEvent); /** * @brief 重写该函数来移除QWebView类型的tab页面对拖拽页签的处理 * @param[in] pObject 监视对象 * @param[in] pEvent 监视对象的事件 * @return 是否被过滤 */ virtual bool eventFilter(QObject *pObject, QEvent *pEvent); private slots: /** * @brief 响应标签关闭的消息 * @param[in] index 当前要关闭的标签索引 */ void OnTabClose(int index); private: bool m_IsDropableTab; ///< 标签控件标志,否接收拖拽来的页签 QString m_ClosedTabID; ///< 关闭页签ID signals: /** * @brief 此信号在Tab页的Close按钮被点击时触发 * @param[in] extensionID 将要被关闭的Tab页面的ID */ void TabWillBeClosed(const QString & extensionID); /** * @brief 此信号在所有的tab页都被关闭后触发 * @param[in] areaName 该TabWidget所占的区域名 */ void AllTabClosed(QString areaName); /** * @brief 此信号在Tab页切换时触发 * @param[in] extensionID 切换后的当前Tab页面的ID */ void CurrentTabChanged(const QString & extensionID); /** * @brief 此信号在添加Tab页时触发 * @param[in] index 新添加的Tab页的索引 */ void TabInserted(int index); /** * @brief 此信号tab页被关闭后触发 * @param[in] extensionID 将要被关闭的Tab页面的ID */ void TabRemoved(const QString & extensionID); }; } } #endif ///< PAI_FRAME_WIDGET_PAITABWIDGET_H