diff --git a/GCR/trunk/Glodon/bin/Debug/ReadMe.txt b/GCR/trunk/Glodon/bin/Debug/ReadMe.txt new file mode 100644 index 00000000..21c90aa1 --- /dev/null +++ b/GCR/trunk/Glodon/bin/Debug/ReadMe.txt @@ -0,0 +1 @@ +本目录下存放的是Unicode编码方式的Debug版本DLL文件 \ No newline at end of file diff --git a/GCR/trunk/Glodon/bin/Release/ReadMe.txt b/GCR/trunk/Glodon/bin/Release/ReadMe.txt new file mode 100644 index 00000000..8845f29d --- /dev/null +++ b/GCR/trunk/Glodon/bin/Release/ReadMe.txt @@ -0,0 +1 @@ +本目录下存放的是Unicode编码方式的Release版本DLL文件 \ No newline at end of file diff --git a/GCR/trunk/Glodon/bin/Release/X64/GSCAppImpl.lib b/GCR/trunk/Glodon/bin/Release/X64/GSCAppImpl.lib new file mode 100644 index 00000000..8a60d7b2 Binary files /dev/null and b/GCR/trunk/Glodon/bin/Release/X64/GSCAppImpl.lib differ diff --git a/GCR/trunk/Glodon/bin/Release/X64/LZMA.dll b/GCR/trunk/Glodon/bin/Release/X64/LZMA.dll new file mode 100644 index 00000000..a4fa348a Binary files /dev/null and b/GCR/trunk/Glodon/bin/Release/X64/LZMA.dll differ diff --git a/GCR/trunk/Glodon/bin/Release/X64/MT/ReadMe.txt b/GCR/trunk/Glodon/bin/Release/X64/MT/ReadMe.txt new file mode 100644 index 00000000..41cb5a97 --- /dev/null +++ b/GCR/trunk/Glodon/bin/Release/X64/MT/ReadMe.txt @@ -0,0 +1,3 @@ +本目录下存放的是Unicode编码方式的Release版本DLL文件 +本目录默认存放运行库为:MT(多线程) +64位 \ No newline at end of file diff --git a/GCR/trunk/Glodon/bin/Release/X64/ReadMe.txt b/GCR/trunk/Glodon/bin/Release/X64/ReadMe.txt new file mode 100644 index 00000000..d36c4810 --- /dev/null +++ b/GCR/trunk/Glodon/bin/Release/X64/ReadMe.txt @@ -0,0 +1,3 @@ +本目录下存放的是Unicode编码方式的Release版本DLL文件 +本目录默认存放运行库为:MD(多线程DLL) +64位 \ No newline at end of file diff --git a/GCR/trunk/Glodon/bin/Release/X86/GSCAppImpl.lib b/GCR/trunk/Glodon/bin/Release/X86/GSCAppImpl.lib new file mode 100644 index 00000000..3304bde3 Binary files /dev/null and b/GCR/trunk/Glodon/bin/Release/X86/GSCAppImpl.lib differ diff --git a/GCR/trunk/Glodon/bin/Release/X86/GSCCore.lib b/GCR/trunk/Glodon/bin/Release/X86/GSCCore.lib new file mode 100644 index 00000000..1205ff09 Binary files /dev/null and b/GCR/trunk/Glodon/bin/Release/X86/GSCCore.lib differ diff --git a/GCR/trunk/Glodon/bin/Release/X86/LZMA.dll b/GCR/trunk/Glodon/bin/Release/X86/LZMA.dll new file mode 100644 index 00000000..3b725cd7 Binary files /dev/null and b/GCR/trunk/Glodon/bin/Release/X86/LZMA.dll differ diff --git a/GCR/trunk/Glodon/bin/Release/X86/MT/ReadMe.txt b/GCR/trunk/Glodon/bin/Release/X86/MT/ReadMe.txt new file mode 100644 index 00000000..67e83c2e --- /dev/null +++ b/GCR/trunk/Glodon/bin/Release/X86/MT/ReadMe.txt @@ -0,0 +1,3 @@ +本目录下存放的是Unicode编码方式的Release版本DLL文件 +本目录下存放运行库为:MT(多线程) +32位 \ No newline at end of file diff --git a/GCR/trunk/Glodon/bin/Release/X86/ReadMe.txt b/GCR/trunk/Glodon/bin/Release/X86/ReadMe.txt new file mode 100644 index 00000000..4522c947 --- /dev/null +++ b/GCR/trunk/Glodon/bin/Release/X86/ReadMe.txt @@ -0,0 +1,3 @@ +本目录下存放的是Unicode编码方式的Release版本DLL文件 +本目录默认存放运行库为:MD(多线程DLL) +32位 \ No newline at end of file diff --git a/GCR/trunk/Glodon/include/GLD/GLD360MainWindow.h b/GCR/trunk/Glodon/include/GLD/GLD360MainWindow.h new file mode 100644 index 00000000..8b2fca49 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLD360MainWindow.h @@ -0,0 +1,172 @@ +/**** + * @file : GLD360MainWindow.h + * @brief : 360风格主窗体 + * + * @date : 2014-04-02 + * @author : duanb + * @remarks: + ****/ +#ifndef GLD360MAINWINDOW_H +#define GLD360MAINWINDOW_H + +#include +#include +#include + +#include "GLDStrUtils.h" +#include "GLDObjectList.h" + +class QLabel; +class QHBoxLayout; +class QSignalMapper; + +class GLDWIDGETSHARED_EXPORT GLD360PushButton : public QPushButton +{ + Q_OBJECT +public: + explicit GLD360PushButton(QWidget *parent = 0); + ~GLD360PushButton(); + void loadPixmap(const QString &picName); +protected: + void enterEvent(QEvent *); + void leaveEvent(QEvent *); + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void paintEvent(QPaintEvent *); +private: + //枚举按钮的几种状态 + enum ButtonStatus {NORMAL, ENTER, PRESS, NOSTATUS}; + ButtonStatus m_status; + QPixmap m_pixmap; + int m_btnWidth; //按钮宽度 + int m_btnHeight; //按钮高度 + bool m_mousePress; //按钮左键是否按下 +}; + +class GLDWIDGETSHARED_EXPORT GLD360ToolButton : public QToolButton +{ + Q_OBJECT +public: + explicit GLD360ToolButton(const GString &text, const GString &picName, QWidget *parent = 0); + ~GLD360ToolButton(); + void setMousePress(bool mousePress); +protected: + void enterEvent(QEvent *); + void leaveEvent(QEvent *); + void mousePressEvent(QMouseEvent *event); + void paintEvent(QPaintEvent *event); + void painterInfo(int topColor, int middleColor, int bottomColor); +public: + bool m_mouseOver; // 鼠标是否移过 + bool m_mousePress; // 鼠标是否按下 +}; + +// 标题栏 +class GLDWIDGETSHARED_EXPORT GLD360WindowTile : public QWidget +{ + Q_OBJECT +public: + explicit GLD360WindowTile(QWidget *parent = 0); + virtual ~GLD360WindowTile(); +signals: + void showSkin(); + void showMin(); + void showMax(); + void showMainMenu(); + void closeWidget(); +protected: + void mousePressEvent(QMouseEvent *); + void mouseMoveEvent(QMouseEvent *); + void mouseReleaseEvent(QMouseEvent *); + void mouseDoubleClickEvent(QMouseEvent *); +private: + bool m_isMove; + QPoint m_pressPoint;//鼠标按下去的点 + + QLabel *m_versionTitle; //标题 + GLD360PushButton *m_skinButton; //换肤 + GLD360PushButton *m_mainMenuButton; //主菜单 + GLD360PushButton *m_minButton; //最小化 + GLD360PushButton *m_maxButton; //最大化 + GLD360PushButton *m_closeButton; //关闭 +}; + +// 工具栏 +class GLDWIDGETSHARED_EXPORT GLD360MainToolBar : public QWidget +{ + Q_OBJECT +public: + explicit GLD360MainToolBar(QWidget *parent = 0); + virtual ~GLD360MainToolBar(); +public: + void add360Action(const GString &text, const GString &picName); + void setLogo(const GString &picName); + void setCurrentPage(const QString ¤tPage); +public slots: +signals: + void showMax(); +protected: + void mousePressEvent(QMouseEvent *); + void mouseMoveEvent(QMouseEvent *); + void mouseReleaseEvent(QMouseEvent *); + void mouseDoubleClickEvent(QMouseEvent *); +private slots: + void turnPage(const QString ¤tPage); +private: + bool m_isMove; + QPoint m_pressPoint; // 鼠标按下去的点 + GLDVector m_buttonList; + QSignalMapper *m_signalMapper; + QHBoxLayout *m_buttonLayout; + QLabel *m_logoLabel; +}; + +// 主窗体 +class GLDWIDGETSHARED_EXPORT GLD360MainWindow : public QWidget +{ + Q_OBJECT +public: + explicit GLD360MainWindow(QWidget *parent = 0); + virtual ~GLD360MainWindow(); +public: + void init(); + bool isCloseWhenMinimized() const; + void setIsCloseWhenMinimized(bool isCloseWhenMinimized); + void setSkinName(const QString &skinName); + bool allowMax() const; + void setAllowMax(bool allowMax); + + GLD360MainToolBar *mainToolBar() const; + void setMainToolBar(GLD360MainToolBar *mainToolBar); + + GLD360WindowTile *titleWidget() const; + void setTitleWidget(GLD360WindowTile *titleWidget); + +public slots: + void showWidget(); +protected: + virtual void initialize(); +signals: + void showSkin(); +protected: + void paintEvent(QPaintEvent *); +private slots: + void showMax(); + void showMainMenu(); + void changeSkin(const QString &skinName); +private: + QRect m_location; + GLD360WindowTile *m_titleWidget; //标题栏 + GLD360MainToolBar *m_mainToolBar; // 工具栏 + // todo 主界面还没有内容 + GObjectList m_contentWidgetList; //主界面内容 + QHBoxLayout *m_mainLayOut; + QString m_skinName;//主窗口背景图片的名称 + // todo + QMenu *m_mainMenu; //主菜单 + bool m_isCloseWhenMinimized; + bool m_allowMax; +}; + +#endif // GLD360MAINWINDOW_H + diff --git a/GCR/trunk/Glodon/include/GLD/GLDAbstractBtnEdit.h b/GCR/trunk/Glodon/include/GLD/GLDAbstractBtnEdit.h new file mode 100644 index 00000000..c1b24467 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDAbstractBtnEdit.h @@ -0,0 +1,73 @@ +#ifndef GLDABSTRACTBTNEDIT_H +#define GLDABSTRACTBTNEDIT_H + +#include +#include +#include "GLDWidget_Global.h" + +class QLineEdit; +class QTextEdit; +class QPlainTextEdit; +class QButtonGroup; +class QAbstractButton; + +class GLDWIDGETSHARED_EXPORT GLDAbstractBtnEdit : public QWidget +{ + Q_OBJECT +public: + explicit GLDAbstractBtnEdit(QWidget *parent = 0); + virtual ~GLDAbstractBtnEdit() = 0; + bool setButtonsCount(int nBtnCount); + inline int buttonsCount() const; + inline int maximumButtonsCount() const; + virtual QString text() const = 0; + virtual void setText(QString text) = 0; + bool eventFilter(QObject *obj, QEvent *event); +// bool connectBtnClicked(BtnClickedSlot btnSlot, int btnIndex); + bool setBtnText(QString &text, int btnIndex); + bool setButtonIcon(QIcon &icon, int btnIndex); + +signals: + void ellipsisButtonClicked(int clickedBtnIndex); + void ellipsisButtonClicked(QAbstractButton *clickedBtn); + +public slots: + virtual void onEllipsisButtonClicked(int clickedBtnIndex); + virtual void onEllipsisButtonClicked(QAbstractButton *clickedBtn); + virtual void selectAll() = 0; + virtual void cursorPosInsertANewLine() = 0; + virtual void cursorToEnd() = 0; +protected: + void init(); +protected: + QVector m_btnIconSize; + QVector m_btnUsingIcon; + QButtonGroup *m_btns; + QVariant *m_associateData; + static const int m_maxBtnCount = 5; +private: + Q_DISABLE_COPY(GLDAbstractBtnEdit) +}; + +class GLDWIDGETSHARED_EXPORT GLDBtnsLineEdit : public GLDAbstractBtnEdit +{ + Q_OBJECT +public: + explicit GLDBtnsLineEdit(int btnCount = 2, QWidget *parent = 0); + ~GLDBtnsLineEdit(); + QString text() const; + void setText(QString text); + void paintEvent(QPaintEvent *); +public slots: + void selectAll(); + void cursorPosInsertANewLine(); + void cursorToEnd(); +protected: + void init(int btnCount); +protected: + QLineEdit *m_edit; +private: + Q_DISABLE_COPY(GLDBtnsLineEdit) +}; + +#endif // GLDABSTRACTBTNEDIT_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDAbstractItemModel.h b/GCR/trunk/Glodon/include/GLD/GLDAbstractItemModel.h new file mode 100644 index 00000000..043dc711 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDAbstractItemModel.h @@ -0,0 +1,79 @@ +#ifndef GLDABSTRACTITEMMODEL_H +#define GLDABSTRACTITEMMODEL_H + +#include +#include "GLDVariant.h" +#include "GLDGlobal.h" + +enum GLDItemDataRole +{ + gidrBaseRole = 256, + gidrRowExpandedRole = 257, + gidrColExpandedRole = 258, + gidrRowHeightRole = 259, + gidrColWidthRole = 260, + gidrCommentRole = 261, + gidrCellMargin = 262, + gidrRowHeaderData = 263, + gidrFooterRowCount = 264, + gidrDiagonal = 265, + gidrAntiDiagonal = 266, + gidrMergeIDRole = 268, + gidrConerDataRole = 269, + gidrHeaderDecorationRole = 270, + gidrConerTextAlignmentRole = 271, + gidrHeaderTextAlignmentRole = 272, + gidrHeaderFontRole = 273, + gidrBoundLineRole = 274, + gidrDecorationAlignmentRole = 275, + gidrRightBoundLineColor = 276, // m_bDrawBoundLine为true时右边框线的颜色 + gidrBottomBoundLineColor = 277, // m_bDrawBoundLine为true时下边框线的颜色 + + gidrGSPBaseDataColRole = 384, + gidrUserBaseRole = 512, + + gidrAddUnEnableRole = 513, + gidrRemoveUnEnableRole = 514, + gidrCheckUnEnableRole = 515 +}; + +class GlodonAbstractItemModelPrivate; +class GLDCOMMONSHARED_EXPORT GlodonAbstractItemModel : public QAbstractItemModel +{ + Q_OBJECT + +public: + explicit GlodonAbstractItemModel(QObject *parent = 0); + virtual ~GlodonAbstractItemModel(); + +public: + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + Qt::ItemFlags flags(const QModelIndex &index) const; + bool showCheckBox(); + void setShowCheckBox(const bool &value); + bool isItemIsTristate(); + void setIsTristate(const bool &value); + bool isRecursiveCheck(); + void setRecursiveCheck(const bool &value); + + virtual void afterCurrentChanged(const QModelIndex &index); + +signals: + +public slots: + +protected: + GlodonAbstractItemModel(GlodonAbstractItemModelPrivate &dd, QObject *parent = 0); + +private: + bool recursiveCheck(const QModelIndex &index, const GVariant &value); + bool recursiveCheckParent(const QModelIndex &index, const GVariant &value); + void recursiveCheckParentPartCheck(const QModelIndex &index); + +private: + Q_DECLARE_PRIVATE(GlodonAbstractItemModel) + Q_DISABLE_COPY(GlodonAbstractItemModel) +}; + +#endif // GLDABSTRACTITEMMODEL_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDAbstractItemModel_p.h b/GCR/trunk/Glodon/include/GLD/GLDAbstractItemModel_p.h new file mode 100644 index 00000000..02c163e4 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDAbstractItemModel_p.h @@ -0,0 +1,25 @@ +#ifndef GLDABSTRACTITEMMODEL_P_H +#define GLDABSTRACTITEMMODEL_P_H + +#include +#include +#include +#include "GLDAbstractItemModel.h" + +class GLDCOMMONSHARED_EXPORT GlodonAbstractItemModelPrivate : public QAbstractItemModelPrivate +{ + Q_DECLARE_PUBLIC(GlodonAbstractItemModel) + +public: + GlodonAbstractItemModelPrivate(); + virtual ~GlodonAbstractItemModelPrivate(); +public: + bool m_showCheckbox; + bool m_recursiveCheck; + bool m_isTristate; + QSet m_checkedIndexes; + QSet m_partiallyCheckedIndexes; + QSet m_forbiddenCheckedIndexes; +}; + +#endif // GLDABSTRACTITEMMODEL_P_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDAbstractItemView.h b/GCR/trunk/Glodon/include/GLD/GLDAbstractItemView.h new file mode 100644 index 00000000..f985b0c2 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDAbstractItemView.h @@ -0,0 +1,940 @@ +/*! + *@file glodonabstractitemview.h + *@brief {所有View的抽象} + *定义了一些主要流程,如编辑、鼠标事件、setModel等 + *@author Gaosy + *@date 2012.9.7 + *@remarks {remarks} + *Copyright (c) 1998-2012 Glodon Corporation + */ + +#ifndef GLDABSTRACTITEMVIEW_H +#define GLDABSTRACTITEMVIEW_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "GLDString.h" +#include "GLDEvent.h" +#include "GLDDefaultItemDelegate.h" +#include "GLDTextEdit.h" +#include "GLDCommentFrame.h" + +class QLabel; +class QMenu; +class QDrag; +class QEvent; +class GlodonAbstractItemView; +class GlodonAbstractItemViewPrivate; + +/*! + *@struct: GEditorInfo + *@brief {缓存编辑方式,用于快速存取编辑所需控件} + *@author Gaosy + *@date 2012.9.7 + */ +struct GEditorInfo { + GEditorInfo(QWidget *e, bool s): widget(QPointer(e)), isStatic(s) {} + + GEditorInfo(): isStatic(false) {} + + QPointer widget; + bool isStatic; +}; + +typedef QHash GEditorIndexHash; +typedef QHash GIndexEditorHash; + +typedef QPair GItemViewPaintPair; +typedef QList GItemViewPaintPairs; + +/*! + *@class: GEmptyModel + *@brief {空Model,没有数据,仅用于初始化时使用} + *@author Gaosy + *@date 2012.9.7 + */ +class GLDTABLEVIEWSHARED_EXPORT GEmptyModel : public QAbstractItemModel +{ +public: + explicit GEmptyModel(QObject *parent = 0) : QAbstractItemModel(parent) {} + + QModelIndex index(int, int, const QModelIndex &) const { return QModelIndex(); } + + QModelIndex parent(const QModelIndex &) const { return QModelIndex(); } + + int rowCount(const QModelIndex &) const { return 0; } + + int columnCount(const QModelIndex &) const { return 0; } + + bool hasChildren(const QModelIndex &) const { return false; } + + QVariant data(const QModelIndex &, int) const { return QVariant(); } +}; + +/*! + *@class: GlodonAbstractItemView + *@brief {所有View的抽象父类,定义了数据编辑、鼠标事件、数据装载(setModel)、选择、移动焦点、设置编辑方式等功能(流程)} + *@author Gaosy + *@date 2012.9.7 + */ +class GLDTABLEVIEWSHARED_EXPORT GlodonAbstractItemView : public QAbstractScrollArea +{ + Q_OBJECT + + Q_ENUMS(SelectionMode SelectionBehavior ScrollHint ScrollMode DragDropMode) + Q_FLAGS(EditTriggers) + Q_PROPERTY(bool autoScroll READ hasAutoScroll WRITE setAutoScroll) + Q_PROPERTY(int autoScrollMargin READ autoScrollMargin WRITE setAutoScrollMargin) + Q_PROPERTY(EditTriggers editTriggers READ editTriggers WRITE setEditTriggers) + Q_PROPERTY(bool tabKeyNavigation READ tabKeyNavigation WRITE setTabKeyNavigation) +#ifndef QT_NO_DRAGANDDROP + Q_PROPERTY(bool showDropIndicator READ showDropIndicator WRITE setDropIndicatorShown) + Q_PROPERTY(bool dragEnabled READ dragEnabled WRITE setDragEnabled) + Q_PROPERTY(bool dragDropOverwriteMode READ dragDropOverwriteMode WRITE setDragDropOverwriteMode) + Q_PROPERTY(DragDropMode dragDropMode READ dragDropMode WRITE setDragDropMode) + Q_PROPERTY(Qt::DropAction defaultDropAction READ defaultDropAction WRITE setDefaultDropAction) +#endif + Q_PROPERTY(bool alternatingRowColors READ alternatingRowColors WRITE setAlternatingRowColors) + Q_PROPERTY(SelectionMode selectionMode READ selectionMode WRITE setSelectionMode) + Q_PROPERTY(SelectionBehavior selectionBehavior READ selectionBehavior WRITE setSelectionBehavior) + Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize) + Q_PROPERTY(Qt::TextElideMode textElideMode READ textElideMode WRITE setTextElideMode) + Q_PROPERTY(ScrollMode verticalScrollMode READ verticalScrollMode WRITE setVerticalScrollMode) + Q_PROPERTY(ScrollMode horizontalScrollMode READ horizontalScrollMode WRITE setHorizontalScrollMode) + +public: + /*! + *@enum: SelectionMode + *@brief {选择模式} + *@author Gaosy + *@date 2012.9.10 + */ + enum SelectionMode { + NoSelection, + SingleSelection, + MultiSelection, + ExtendedSelection, + ContiguousSelection + }; + + /*! + *@enum: SelectionBehavior + *@brief {选择行为:选格子、选行、选列} + *@author Gaosy + *@date 2012.9.10 + */ + enum SelectionBehavior { + SelectItems, + SelectRows, + SelectColumns + }; + + /*! + *@enum: ScrollHint + *@brief {滚动条滚动位置控制} + *@author Gaosy + *@date 2012.9.10 + */ + enum ScrollHint { + EnsureVisible, + PositionAtTop, + PositionAtBottom, + PositionAtCenter + }; + + /*! + *@enum: EditTrigger + *@brief {进入编辑状态的方式} + *@author Gaosy + *@date 2012.9.10 + */ + enum EditTrigger { + NoEditTriggers = 0, + CurrentChanged = 1, + DoubleClicked = 2, + SelectedClicked = 4, + EditKeyPressed = 8, + AnyKeyPressed = 16, + AllEditTriggers = 31 + }; + + Q_DECLARE_FLAGS(EditTriggers, EditTrigger) + + /*! + *@enum: ScrollMode + *@brief {滚动方式:逐个格子滚动、逐个像素滚动} + *@author Gaosy + *@date 2012.9.10 + */ + enum ScrollMode { + ScrollPerItem, // 滚没一格,即一格格子由可见变为不可见 + ScrollPerPixel + }; + + // 非编辑状态下,只要显示编辑方式,则显示即可操作,不需要获取焦点 + enum EditStyleDrawType { + SdtNone = 0, // 不显示编辑方式 + SdtCurrentCell = 1, // 显示焦点所在格子的编辑方式 + SdtCurrentRow = 2, // 显示焦点所在行的编辑方式 + SdtCurrentCol = 3, // 显示焦点所在列的编辑方式 + SdtAll = 4 // 所有的编辑方式都显示 + }; + /*! + *@enum: DragDropMode + *@brief {拖拽方式} + *@author Gaosy + *@date 2012.9.10 + */ + enum DragDropMode { + NoDragDrop, + DragOnly, + DropOnly, + DragDrop, + InternalMove + }; + + /*! + *@enum: State + *@brief {当前View的状态} + *@author Gaosy + *@date 2012.9.10 + */ + enum State { + NoState, // 处于默认状态 + DraggingState, // 正在拖拽Item + DragSelectingState, // 正在选择Item + EditingState, // 正在编辑Item + ExpandingState, // 正在展开节点 + CollapsingState, // 正在折叠节点 + AnimatingState, // View处于动画状态 + RangeFillingState, // 正在进行拖拉复制 + RangeMovingState, // 正在进行框选拖拽 + DragResizingState // 正在拖拽改变大小 + }; + + /*! + *@enum: State + *@brief {跳格开关开启时当前格子的状态} + *@author Chenq-a + *@date 2013.9.5 + */ + enum EnterMovingState { + FirstFocus, // 第一次获得格子焦点 + Editting, // 进入了编辑框 + LastFocus // 从编辑框退出时获得焦点的临时状态 + }; + + /*! + *@enum: CursorAction + *@brief {移动焦点的方向} + *@author Gaosy + *@date 2012.9.13 + */ + enum CursorAction { + MoveUp, + MoveDown, + MoveLeft, + MoveRight, + MoveHome, + MoveEnd, + MovePageUp, + MovePageDown, + MoveNext, + MovePrevious + }; + +public: + explicit GlodonAbstractItemView(QWidget *parent = 0); + ~GlodonAbstractItemView(); + +public: + // 一、Qt方法 + // 1. 功能选项 + /** + * @brief QAbstractItemView方法,查找到最符合搜索值的Item,移动过去并选中。 + * 如果搜索的值为空,会重置搜索 + * @param search 要查找的值 + */ + virtual void keyboardSearch(const QString &search); + + /** + * @brief QAbstractItemView方法,设置输入法操作 + * @param query 各种控制,例如字体等 + */ + virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const; + + /** + * @brief QAbstractItemView方法,设置Item的Tab、backTab是有可用 + * @param enable + */ + void setTabKeyNavigation(bool enable); + bool tabKeyNavigation() const; + +#ifndef QT_NO_DRAGANDDROP + /** + * @brief QAbstractItemView方法,设置ViewPort是否允许拖拽它的Item + * @param enable + */ + void setDragEnabled(bool enable); + bool dragEnabled() const; + + /** + * @brief QAbstractItemView方法,设置Drag\Drop时,ViewPort的操作 + * @param behavior + */ + void setDragDropMode(DragDropMode behavior); + DragDropMode dragDropMode() const; + + /** + * @brief QAbstractItemView方法,控制ViewPort上的Item在拖动释放时的操作 + * 如果是true,则将原来的Item替换为拖动的Item + * 如果是false,则插入一个新的Item + * @param overwrite + */ + void setDragDropOverwriteMode(bool overwrite); + bool dragDropOverwriteMode() const; + + /** + * @brief QAbstractItemView方法,设置默认的Drop操作 + * @param dropAction + */ + void setDefaultDropAction(Qt::DropAction dropAction); + Qt::DropAction defaultDropAction() const; + + /** + * @brief QAbstractItemView方法,设置在拖拽Item和结束拖拽Item时,是否显示提示 + * @param enable + */ + void setDropIndicatorShown(bool enable); + bool showDropIndicator() const; +#endif + + // 2. 外观选项 + /** + * @brief QAbstractItemView方法,返回QStyleOptionViewItem结构体,里面包含字体等 + */ + virtual QStyleOptionViewItem viewOptions() const; + + /** + * @brief QAbstractItemView方法纯虚,将滚动条滚至给定的Index + * @param index 目标Index + * @param hint + */ + virtual void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible) = 0; + + /** + * @brief 设置选择模式,可以为单选,多选等 + * @param mode + */ + void setSelectionMode(GlodonAbstractItemView::SelectionMode mode); + GlodonAbstractItemView::SelectionMode selectionMode() const; + + /** + * @brief 设置选择模式,行选,或者列选 + * @param behavior 默认值 SelectItems + */ + void setSelectionBehavior(GlodonAbstractItemView::SelectionBehavior behavior); + GlodonAbstractItemView::SelectionBehavior selectionBehavior() const; + + /** + * @brief 设置垂直滚动条的滚动模式(逐个格子滚动、逐个像素滚动) + * @param mode + */ + void setVerticalScrollMode(ScrollMode mode); + ScrollMode verticalScrollMode() const; + + /** + * @brief 设置水平滚动条的滚动模式(逐个格子滚动、逐个像素滚动) + * @param mode + */ + void setHorizontalScrollMode(ScrollMode mode); + ScrollMode horizontalScrollMode() const; + + /*! + *@brief 设置隔行背景色不同 + *@param[in] enable + *@return 无 + */ + void setAlternatingRowColors(bool enable); + bool alternatingRowColors() const; + + /*! + *@brief 设置Item图标大小 + *@param[in] enable + *@return 无 + */ + void setIconSize(const QSize &size); + QSize iconSize() const; + + /** + * @brief 获取/设置,自动滚动区域 + * @return + */ + void setAutoScrollMargin(int margin); + int autoScrollMargin() const; + + /** + * @brief 点击右键的时候设置tooltip隐藏 + * @return 无 + */ + void setToolTipFrameHide(); + +public: + // Glodon方法 + // 1. 功能选项 + /** + * @brief 设置是否选择移动 + * @param value + */ + virtual void setAllowRangeMoving(bool value); + virtual bool allowRangeMoving() const; + + /** + * @brief 是否能开始drag + * @param indexes + * @return + */ + virtual bool canStartDrag(QModelIndexList indexes); + + // 2. 外观选项 + /** + * @brief 设置是否允许全选 + * @return + */ + void setAllowSelectAll(bool value); + bool allowSelectAll() const; + + /** + * @brief 格子区域中的文字绘制时是否用包含行间距 + * @return + */ + void setGridTextIncludeLeading(bool value); + bool gridTextIncludeLeading() const; + + /** + * @brief 鼠标拖拽滚动条时,是否在松开滚动条时刻才进行表格区域的滚动 + * @param value + */ + void setScrollBarTracking(bool value); + bool scrollBarTracking() const; + + /** + * @brief 设置表格ViewPort背景颜色 + * @return + */ + virtual void setGridColor(QColor value); + QColor gridColor() const; + + /** + * @brief 设置当格子内容显示不全时,是否显示提示框 + * @param value + * @param showIndexContext 如果toolTipRole没有值,是否显示格子中的值 + */ + void setIsShowHint(bool value, bool showIndexContent = false); + void setShowHintDelay(int time); + + /** + * @brief 获取/设置,竖直方向滚动条的值 + * @return + */ + void setVerticalScrollBarValue(int value); + int verticalScrollbarValue(); + + /** + * @brief 设置是否完全显示当前点击的格子,主要用于控制在当前格子部分显示时的点击行为,即:是否调整滚动条,使该格完全显示 + * @param value + * @note 复杂layout情形下,没有滚动条时的显示不完全点击后不会有效果 + */ + void setShowPressIndex(bool value); + + /** + * @brief 获取/设置,横向滚动条的值 + * @return + */ + void setHorizontalScrollbarValue(int value); + int horizontalScrollbarValue(); + + /** + * @brief 得到StyleOptionViewItem + */ + QStyleOptionViewItem StyleOptionViewItem(); + +public: + virtual QWidget *initCustomComment(const QModelIndex &index, GString &text); + virtual QRect visualRect(const QModelIndex &index) const = 0; + virtual QModelIndex indexAt(const QPoint &point) const = 0; + GCommentFrame *commentFrame(); + +public: + virtual void setModel(QAbstractItemModel *model); + QAbstractItemModel *model() const; + + QSize sizeHintForIndex(const QModelIndex &index) const; + virtual int sizeHintForRow(int row) const; + virtual int sizeHintForColumn(int column) const; + + void setDataModel(QAbstractItemModel *dataModel); + QAbstractItemModel *dataModel() const; + + /*! + *设置QItemselectionModel,用于记录当前已选择区域 + *@param[in] selectionModel + *@return 无 + */ + virtual void setSelectionModel(QItemSelectionModel *selectionModel); + QItemSelectionModel *selectionModel() const; + + /*! + *设置QAbstractItemDelegate,即编辑方式,目前默认初始化为GlodonDefaultItemDelegate + *如果需要自行设置编辑方式,请从GlodonDefaultItemDelegate派生 + *其优先级低于rowDelegate和columnDelegate,默认情况下rowDelegate和columnDelegate为空 + *@param[in] delegate + *@return 无 + */ + void setItemDelegate(GlodonDefaultItemDelegate *delegate); + GlodonDefaultItemDelegate *itemDelegate() const; + + QModelIndex currentIndex() const; + QModelIndex rootIndex() const; + + + void openPersistentEditor(const QModelIndex &index); + void closePersistentEditor(const QModelIndex &index); + + /*! + *获取给定index的QAbstractItemDelegate,优先级顺序为 + *rowDelegate > columnDelegate > itemDelegate + *@param[in] index + *@return QAbstractItemDelegate* + */ + GlodonDefaultItemDelegate *itemDelegate(const QModelIndex &index) const; + + /** + * @brief 正处于编辑状态的ModelIndex + * @return + */ + QModelIndex editorModelIndex(); + + /** + * @brief 设置进入编辑状态的方式 + * @param triggers + */ + void setEditTriggers(EditTriggers triggers); + EditTriggers editTriggers() const; + + void setAutoScroll(bool enable); + bool hasAutoScroll() const; + + /*! + *为给定的index设置持久性的编辑方式,与delegate的编辑方式的区别在于: + *这种方式的编辑控件widget持续显示,而不会随着退出编辑状态而隐藏 + *@param[in] index + *@param[in] widget + *@return 无 + */ + void setIndexWidget(const QModelIndex &index, QWidget *widget); + QWidget *indexWidget(const QModelIndex &index) const; + + /*! + *为给定逻辑行设置编辑方式QAbstractItemDelegate,其优先级高于columnDelegate和itemDelegate + *@param[in] row 逻辑行号 + *@param[in] delegate + *@return 无 + */ + void setItemDelegateForRow(int row, GlodonDefaultItemDelegate *delegate); + GlodonDefaultItemDelegate *itemDelegateForRow(int row) const; + + /*! + *为给定逻辑列设置编辑方式QAbstractItemDelegate,其优先级低于rowDelegate但高于itemDelegate + *@param[in] column 逻辑列号 + *@param[in] delegate + *@return 无 + */ + void setItemDelegateForColumn(int column, GlodonDefaultItemDelegate *delegate); + GlodonDefaultItemDelegate *itemDelegateForColumn(int column) const; + + /*! + * \brief 设置总是处于编辑状态(调用完后,tableView会把所有的编辑方式都创建出来,请在setModel之后或dataSource激活后调用) + * \return + */ + bool alwaysShowEditorPro(); + void setAlwaysShowEditorPro(bool value); + + /** + * @brief 是否允许搜索定位 + * @param value + */ + void setIsSearchModel(bool value); + bool isSearchModel(); + + void setTextElideMode(Qt::TextElideMode mode); + Qt::TextElideMode textElideMode() const; + +#ifdef Q_NO_USING_KEYWORD + inline void update() { QAbstractScrollArea::update(); } +#else + using QAbstractScrollArea::update; +#endif + + /** + * @brief 判断是否是拖拽选择状态 + * @return + */ + bool dragSelectingState(){return state() == DragSelectingState;} + +Q_SIGNALS: + void pressed(const QModelIndex &index); + void clicked(const QModelIndex &index); + void doubleClicked(const QModelIndex &index); + + void activated(const QModelIndex &index); + void entered(const QModelIndex &index); + void viewportEntered(); + void onQueryImageRatioMode(const QModelIndex &index, GlodonDefaultItemDelegate::GAspectRatioMode &ratioMode); + void onQueryFloatOrDoubleViewFormat(const QModelIndex &index, QString &text); + void onQueryIndexDataType(const QModelIndex &index, GlodonDefaultItemDelegate::GDataType &dataType); + void onCommitEditor(const QModelIndex &index, QVariant data, bool &commit); + void onCloseEditor(const QModelIndex &index, QVariant data, bool &close); + void onPressEnter(GlodonAbstractItemView::CursorAction &direction); + void onbeforeMoveCurrent(const QModelIndex &oldIndex, const QModelIndex &newIndex, + QItemSelectionModel::SelectionFlags &command, + MoveReason moveReason, bool &canMove); + void onAfterMoveCurrent(const QModelIndex &oldIndex, const QModelIndex &newIndex, + QItemSelectionModel::SelectionFlags &command, MoveReason moveReason); + void canShowComment(const QModelIndex &index, bool &canShow); + + void onEditorCanCopy(bool yes); + void onEditorCanCut(bool yes); + void onEditorCanPaste(bool yes); + void onEditorCanDelete(bool yes); + void isInEditing(bool yes); + + void onEditorCopy(); + void onEditorCut(); + void onEditorPaste(); + void onEditorDelete(); + +public Q_SLOTS: + /*! + *重置整个View + *@return 无 + */ + virtual void reset(); + + virtual void setRootIndex(const QModelIndex &index); + virtual void doItemsLayout(); + + /*! + *选中整个View + *@return 无 + */ + virtual void selectAll(); + + /*! + *给定的index格子进入编辑状态 + *@param[in] index + *@return 无 + */ + virtual void edit(const QModelIndex &index); + + /*! + *清除所有选择 + *@return 无 + */ + void clearSelection(); + + /*! + *设置给定的index为焦点 + *@param[in] index + *@return 无 + */ + virtual void setCurrentIndex(const QModelIndex &index); + + void scrollToTop(); + void scrollToBottom(); + + /*! + *更新index所在格子 + *@param[in] index + *@return 无 + */ + virtual void update(const QModelIndex &index); + + /** + * @brief 提交数据并关闭编辑器 + */ + bool commitDataAndCloseEditor(); + + void showToolTip(const QModelIndex &index); + + void editorCopy(); + void editorCut(); + void editorPaste(); + void editorDelete(); + +protected Q_SLOTS: + virtual void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles = QVector()); + virtual void rowsInserted(const QModelIndex &parent, int start, int end); + virtual void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end); + virtual void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected); + virtual void currentChanged(const QModelIndex ¤t, const QModelIndex &previous); + virtual void updateEditorData(); + virtual void updateEditorGeometries(); + virtual void updateGeometries(); + virtual void verticalScrollbarAction(int action); + virtual void horizontalScrollbarAction(int action); + virtual void verticalScrollbarValueChanged(int value); + virtual void horizontalScrollbarValueChanged(int value); + virtual void closeEditor(QWidget *editor, bool &canCloseEditor, GlodonDefaultItemDelegate::EndEditHint hint); + virtual void commitData(QWidget *editor, bool &canCloseEditor); + virtual void editorDestroyed(QObject *editor); + + virtual void doSelectionChanged(); + virtual void doEditorCopyAvailable(bool); + virtual void doCursorPositionChanged(); + virtual void doCursorPositionChanged(int, int); + +protected: + GlodonAbstractItemView(GlodonAbstractItemViewPrivate &dd, QWidget *parent = 0); + + void setHorizontalStepsPerItem(int steps); + int horizontalStepsPerItem() const; + void setVerticalStepsPerItem(int steps); + int verticalStepsPerItem() const; + + virtual bool moveCurrent(const QModelIndex &oldIndex, const QModelIndex &newIndex, + QItemSelectionModel::SelectionFlags command, MoveReason moveReason); + + virtual void beforeMoveCurrent(const QModelIndex &oldIndex, const QModelIndex &newIndex, + QItemSelectionModel::SelectionFlags command, MoveReason moveReason, bool &canMove); + virtual void doMoveCurrent(const QModelIndex &oldIndex, const QModelIndex &newIndex, + QItemSelectionModel::SelectionFlags command, MoveReason moveReason); + virtual void afterMoveCurrent(const QModelIndex &oldIndex, const QModelIndex &newIndex, + QItemSelectionModel::SelectionFlags command, MoveReason moveReason); + + virtual QModelIndex moveCursor(CursorAction cursorAction, + Qt::KeyboardModifiers modifiers) = 0; + + virtual int horizontalOffset() const = 0; + virtual int verticalOffset() const = 0; + + virtual bool isIndexHidden(const QModelIndex &index) const = 0; + + virtual void setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command) = 0; + virtual QRegion visualRegionForSelection(const QItemSelection &selection) const = 0; + virtual QModelIndexList selectedIndexes() const; + + virtual bool edit(const QModelIndex &index, EditTrigger trigger, QEvent *event); + + virtual QItemSelectionModel::SelectionFlags selectionCommand(const QModelIndex &index, + const QEvent *event = 0) const; + virtual bool isLegalData(); + virtual void setLegalData(bool value); + +#ifndef QT_NO_DRAGANDDROP + virtual void startDrag(Qt::DropActions supportedActions); +#endif + + State state() const; + void setState(State state); + + void scheduleDelayedItemsLayout(); + void executeDelayedItemsLayout(); + + void setDirtyRegion(const QRegion ®ion); + void scrollDirtyRegion(int dx, int dy); + + void startAutoScroll(); + void stopAutoScroll(); + void doAutoScroll(); + + bool focusNextPrevChild(bool next); + bool event(QEvent *event); + bool viewportEvent(QEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void leaveEvent(QEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseDoubleClickEvent(QMouseEvent *event); + +#ifndef QT_NO_DRAGANDDROP + void dragEnterEvent(QDragEnterEvent *event); + void dragMoveEvent(QDragMoveEvent *event); + void dragLeaveEvent(QDragLeaveEvent *event); + void dropEvent(QDropEvent *event); +#endif + + void focusInEvent(QFocusEvent *event); + void focusOutEvent(QFocusEvent *event); + void keyPressEvent(QKeyEvent *event); + void resizeEvent(QResizeEvent *event); + void timerEvent(QTimerEvent *event); + void inputMethodEvent(QInputMethodEvent *event); + + bool inLinkCell(const QPoint &pos); + +#ifndef QT_NO_DRAGANDDROP + enum DropIndicatorPosition { OnItem, AboveItem, BelowItem, OnViewport }; + DropIndicatorPosition dropIndicatorPosition() const; +#endif + + bool setNewCurrentSelection(QKeyEvent *event, QPersistentModelIndex oNewCurrent); + + /** + * @brief 同步一些标记到Delegate里面 + */ + virtual void syncStateToDelegate(GlodonDefaultItemDelegate *delegate); + + /*! + *在重置View前的操作 + *@return 无 + */ + virtual void beforeReset(); + + /*! + *重置View + *@return 无 + */ + virtual void doReset(); + + /*! + *执行View重置后的操作 + *@return 无 + */ + virtual void afterReset(); + +protected: + void doGMFirst(GLDEvent *event); + void doGMQueryFirst(GLDEvent *event); + void doGMPrev(GLDEvent *event); + void doGMQueryPrev(GLDEvent *event); + void doGMNext(GLDEvent *event); + void doGMQueryNext(GLDEvent *event); + void doGMLast(GLDEvent *event); + void doGMQueryLast(GLDEvent *event); + void doGMSetSel(GLDEvent *event); + void doGMQuerySetSel(GLDEvent *event); + void doGMSetColRow(GLDEvent *event); + +private: + void controlEditorNormalActions(const QModelIndex &index); + void setEditorActSignals(QWidget *editor); + bool connectEditorSignal(QWidget *sender, const char *name, + QWidget *receiver, const char *slotName); + bool editorHasSelText(QWidget *editor); + bool editorReadOnly(QWidget *editor); + void resetActAvailable(QWidget *editor); + void disableEditorActions(); + + bool isComment(const QPersistentModelIndex &index); + + /** + * @brief 给特殊的edit(Edit内部还有其他的控件会印象eventFilter,比如viewport)安装EventFilter + * @param widget + * @param delegate + */ + void installEventFilterWidthEdit(QWidget *widget, GlodonDefaultItemDelegate *delegate); + + // mousePressEvent重构 + void dealWithSelectionAndAutoScroll(QModelIndex index, QMouseEvent *event); + + // KeyPressEvent重构 +#ifdef QT_KEYPAD_NAVIGATION + void dealWithKeyPadNavigation(QKeyEvent *event); +#endif + + QPersistentModelIndex getNewCurrentAccordingToKeyPressOperation(QKeyEvent *event); + void scrollToNewCurrent(QKeyEvent *event, QPersistentModelIndex &oNewCurrent); + void dealWithEventAcception(QKeyEvent *event); + + // mouseMoveEvent重构 + void setSelectionAndScrollToOnMouseMove( + const QModelIndex &oCurIndex, QMouseEvent *event, const QPoint &oPrePoint, const QPoint &oCurPoint); + + // TimerEvent重构 + void showCurIndexToolTip(); + void doLayoutAndScroll(); + // doAutoScroll重构 + void scrollVerticalScrollBar(int nVerticalValue, QScrollBar *verticalScroll); + void scrollHorizontalScrollBar(int nHorizontalValue, QScrollBar *horizontalScroll); + + // CommitEditor重构 + void removeNonPersistentEditor(QWidget *editor); + void setEditorFocus(QWidget *editor); + void dealWithEndEditHint(GlodonDefaultItemDelegate::EndEditHint hint); + + void resetEditorFocus(); + + /*! + * \brief 处理提交数据和关闭编辑器,未能关闭编辑器时,则将编辑中文本全部选中 + * \param canCloseEditor + */ + void doCommitDataAndCloseEditor(bool &canCloseEditor); + + /** + * @brief 通过delegate向Model中写入数据 + * @param[in] pDelegate + * @param[in] editor + * @param[in] index + * @param[in] canCloseEditor + */ + void setModelData(GlodonDefaultItemDelegate *pDelegate, QWidget *editor, + const QModelIndex & index, bool &canCloseEditor); + + /** + * @brief 设置数据的合法性 + * @param[in] pDelegate + * @param[in] canCloseEditor + */ + void setLegitimacyOfData(GlodonDefaultItemDelegate *pDelegate, bool & canCloseEditor); + +private Q_SLOTS: + void _q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end); + void _q_columnsRemoved(const QModelIndex &index, int start, int end); + void _q_columnsInserted(const QModelIndex &index, int start, int end); + void _q_rowsInserted(const QModelIndex &index, int start, int end); + void _q_rowsRemoved(const QModelIndex &index, int start, int end); + void _q_modelDestroyed(); + void _q_layoutChanged(); + void _q_headerDataChanged(); + +private: + Q_DECLARE_PRIVATE(GlodonAbstractItemView) + Q_DISABLE_COPY(GlodonAbstractItemView) + + friend class QAccessibleItemRow; + friend class QListModeViewBase; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(GlodonAbstractItemView::EditTriggers) + +class GLDTABLEVIEWSHARED_EXPORT GAbstractItemModel : public QAbstractItemModel +{ + Q_OBJECT +public: + friend class GlodonAbstractItemViewPrivate; +}; + +enum GLDScrollBarType +{ + gsbtAll = 0, + gsbtVertical = 1, + gsbtHorizon = 2 +}; + +#endif // GLDABSTRACTITEMVIEW_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDAbstractItemView_p.h b/GCR/trunk/Glodon/include/GLD/GLDAbstractItemView_p.h new file mode 100644 index 00000000..aefa9ed3 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDAbstractItemView_p.h @@ -0,0 +1,357 @@ +#ifndef GLDABSTRACTITEMVIEW_P_H +#define GLDABSTRACTITEMVIEW_P_H + +#include +#include "GLDAbstractItemView.h" + +class GLDTABLEVIEWSHARED_EXPORT GlodonAbstractItemViewPrivate : public QAbstractScrollAreaPrivate +{ + Q_DECLARE_PUBLIC(GlodonAbstractItemView) + +public: + GlodonAbstractItemViewPrivate(); + virtual ~GlodonAbstractItemViewPrivate(); + +public: + void init(); + + virtual void _q_rowsRemoved(const QModelIndex &parent, int start, int end); + virtual void _q_rowsInserted(const QModelIndex &parent, int start, int end); + virtual void _q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end); + virtual void _q_columnsRemoved(const QModelIndex &parent, int start, int end); + virtual void _q_columnsInserted(const QModelIndex &parent, int start, int end); + virtual void _q_modelDestroyed(); + virtual void _q_layoutChanged(); + void _q_headerDataChanged() + { + doDelayedItemsLayout(); + } + + void fetchMore(); + + bool shouldEdit(GlodonAbstractItemView::EditTrigger trigger, const QModelIndex &index) const; + bool shouldForwardEvent(GlodonAbstractItemView::EditTrigger trigger, const QEvent *event) const; + bool shouldAutoScroll(const QPoint &pos) const; + void doDelayedItemsLayout(int delay = 0); + void doWheel(); + void interruptDelayedItemsLayout() const; + + void startAutoScroll() + { + int nScrollInterval = (m_verticalScrollMode == GlodonAbstractItemView::ScrollPerItem) ? 150 : 50; + m_autoScrollTimer.start(nScrollInterval, q_func()); + m_autoScrollCount = 0; + } + + void stopAutoScroll() + { + m_autoScrollTimer.stop(); + m_autoScrollCount = 0; + } + +#ifndef QT_NO_DRAGANDDROP + virtual bool dropOn(QDropEvent *event, int *row, int *col, QModelIndex *index); +#endif + bool droppingOnItself(QDropEvent *event, const QModelIndex &index); + + QWidget *editor(const QModelIndex &index, const QStyleOptionViewItem &options); + bool sendDelegateEvent(const QModelIndex &index, QEvent *event) const; + bool openEditor(const QModelIndex &index, QEvent *event); + void updateEditorData(const QModelIndex &topLeft, const QModelIndex &bottomRight); + + QItemSelectionModel::SelectionFlags multiSelectionCommand(const QModelIndex &index, + const QEvent *event) const; + QItemSelectionModel::SelectionFlags extendedSelectionCommand(const QModelIndex &index, + const QEvent *event) const; + QItemSelectionModel::SelectionFlags contiguousSelectionCommand(const QModelIndex &index, + const QEvent *event) const; + virtual void selectAll(QItemSelectionModel::SelectionFlags command); + + void setHoverIndex(const QPersistentModelIndex &index); + + void checkMouseMove(const QPersistentModelIndex &index); + inline void checkMouseMove(const QPoint &pos) + { + checkMouseMove(q_func()->indexAt(pos)); + } + + QItemSelectionModel::SelectionFlags selectionBehaviorFlags() const; + +#ifndef QT_NO_DRAGANDDROP + virtual GlodonAbstractItemView::DropIndicatorPosition position(const QPoint &pos, + const QRect &rect, + const QModelIndex &idx) const; + + bool canDecode(QDropEvent *e) const; + + void paintDropIndicator(QPainter *painter); + +#endif + virtual GItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const; + + virtual void adjustViewOptionsForIndex(QStyleOptionViewItem *, const QModelIndex &) const {} + + void releaseEditor(QWidget *editor) const; + + void executePostedLayout() const + { + if (m_delayedPendingLayout && m_state != GlodonAbstractItemView::CollapsingState) + { + interruptDelayedItemsLayout(); + const_cast(q_func())->doItemsLayout(); + } + } + + inline void setDirtyRegion(const QRegion &visualRegion) + { + m_updateRegion += visualRegion; + + if (!m_updateTimer.isActive()) + { + m_updateTimer.start(0, q_func()); + } + } + + inline void scrollDirtyRegion(int dx, int dy) + { + m_scrollDelayOffset = QPoint(-dx, -dy); + updateDirtyRegion(); + m_scrollDelayOffset = QPoint(0, 0); + } + + inline void scrollContentsBy(int dx, int dy) + { + scrollDirtyRegion(dx, dy); + viewport->scroll(dx, dy); + } + + inline void scrollContentsBy(int dx, int dy, QRect rect) + { + scrollDirtyRegion(dx, dy); + viewport->scroll(dx, dy, rect); + } + + void updateDirtyRegion() + { + m_updateTimer.stop(); + viewport->update(m_updateRegion); + m_updateRegion = QRegion(); + } + + void clearOrRemove(); + void checkPersistentEditorFocus(); + + QPixmap renderToPixmap(const QModelIndexList &indexes, QRect *r) const; + + inline QPoint offset() const + { + Q_Q(const GlodonAbstractItemView); + return QPoint(q->isRightToLeft() ? -q->horizontalOffset() + : q->horizontalOffset(), q->verticalOffset()); + } + + const GEditorInfo &editorForIndex(const QModelIndex &index) const; + inline bool hasEditor(const QModelIndex &index) const + { + return m_indexEditorHash.find(index) != m_indexEditorHash.constEnd(); + } + + QModelIndex indexForEditor(QWidget *editor) const; + void addEditor(const QModelIndex &index, QWidget *editor, bool isStatic); + void removeEditor(QWidget *editor); + + inline bool isAnimating() const + { + return m_state == GlodonAbstractItemView::AnimatingState; + } + + inline GlodonDefaultItemDelegate *delegateForIndex(const QModelIndex &index) const + { + GlodonDefaultItemDelegate *del; + + if ((del = m_rowDelegates.value(index.row(), 0))) + { + return del; + } + + if ((del = m_columnDelegates.value(index.column(), 0))) + { + return del; + } + + return m_itemDelegate; + } + + inline bool isIndexValid(const QModelIndex &index) const + { + return (index.row() >= 0) && (index.column() >= 0) && (index.model() == m_model); + } + inline bool isIndexSelectable(const QModelIndex &index) const + { + return (Qt::NoItemFlags != (m_model->flags(index) & Qt::ItemIsSelectable)); + } + inline bool isIndexEnabled(const QModelIndex &index) const + { + return (Qt::NoItemFlags != (m_model->flags(index) & Qt::ItemIsEnabled)); + } + inline bool isIndexDropEnabled(const QModelIndex &index) const + { + return (Qt::NoItemFlags != (m_model->flags(index) & Qt::ItemIsDropEnabled)); + } + inline bool isIndexDragEnabled(const QModelIndex &index) const + { + return (Qt::NoItemFlags != (m_model->flags(index) & Qt::ItemIsDragEnabled)); + } + + virtual bool selectionAllowed(const QModelIndex &index) const + { + return isIndexValid(index) && isIndexSelectable(index); + } + + virtual QPoint contentsOffset() const + { + Q_Q(const GlodonAbstractItemView); + return QPoint(q->horizontalOffset(), q->verticalOffset()); + } + + /** + * For now, assume that we have few editors, if we need a more efficient implementation + * we should add a QMap member. + */ + int delegateRefCount(const GlodonDefaultItemDelegate *delegate) const; + + /** + * return true if the index is registered as a QPersistentModelIndex + */ + inline bool isPersistent(const QModelIndex &index) const; + + QModelIndexList selectedDraggableIndexes() const; + + QStyleOptionViewItem viewOptionsV4() const; + + void doDelayedReset(); + + void updateNoStaticEditorData(const QModelIndex &editorIndex); + +private: + // extendedSelectionCommand重构 + bool mouseMoveEventFlag(Qt::KeyboardModifiers &modifiers, const QEvent *event, QItemSelectionModel::SelectionFlags &selectionFlags) const; + bool mouseButtonPressEventFlag(Qt::KeyboardModifiers &modifiers, const QModelIndex &index, const QEvent *event, QItemSelectionModel::SelectionFlags &selectionFlags) const; + QItemSelectionModel::SelectionFlags mouseButtonReleaseEventFlag( + Qt::KeyboardModifiers &modifiers, const QModelIndex &index, const QEvent *event) const; + bool keyPressEventFlag(Qt::KeyboardModifiers &modifiers, const QEvent *event, QItemSelectionModel::SelectionFlags &selectionFlags) const; + bool isNewSelect(Qt::KeyboardModifiers &modifiers, const QModelIndex &index, const QEvent *event) const; + +public: + QAbstractItemModel *m_model; + QAbstractItemModel *m_dataModel; + + QPointer m_itemDelegate; + QMap > m_rowDelegates; + QMap > m_columnDelegates; + QPointer m_selectionModel; + QItemSelectionModel::SelectionFlag m_ctrlDragSelectionFlag; + bool m_noSelectionOnMousePress; + + GlodonAbstractItemView::SelectionMode m_selectionMode; + GlodonAbstractItemView::SelectionBehavior m_selectionBehavior; + + GEditorIndexHash m_editorIndexHash; + GIndexEditorHash m_indexEditorHash; + QSet m_persistent; + QWidget *m_pCurCommittingEditor; + + QPersistentModelIndex m_enteredIndex; + QPersistentModelIndex m_pressedIndex; + Qt::KeyboardModifiers m_pressedModifiers; + QPoint m_pressedPosition; + bool m_pressedAlreadySelected; + + //forces the next mouseMoveEvent to send the viewportEntered signal + //if the mouse is over the viewport and not over an item + bool m_viewportEnteredNeeded; + GlodonAbstractItemView::State m_state; + GlodonAbstractItemView::State m_stateBeforeAnimation; + GlodonAbstractItemView::EditTriggers m_editTriggers; + GlodonAbstractItemView::EditTrigger m_lastTrigger; + + QPersistentModelIndex m_root; + QPersistentModelIndex m_hover; + + bool m_bTabKeyNavigation; + +#ifndef QT_NO_DRAGANDDROP + bool m_bShowDropIndicator; + QRect m_dropIndicatorRect; + bool m_bDragEnabled; + GlodonAbstractItemView::DragDropMode m_dragDropMode; + bool m_bDragDropOverwrite; + GlodonAbstractItemView::DropIndicatorPosition m_dropIndicatorPosition; + Qt::DropAction m_defaultDropAction; +#endif + +#ifdef QT_SOFTKEYS_ENABLED + QAction *doneSoftKey; +#endif + + QString m_keyboardInput; + QElapsedTimer m_keyboardInputTime; + + bool m_bAutoScroll; + QBasicTimer m_autoScrollTimer; + int m_nAutoScrollMargin; + int m_autoScrollCount; + bool m_shouldScrollToCurrentOnShow; //used to know if we should scroll to current on show event + bool m_shouldClearStatusTip; //if there is a statustip currently shown that need to be cleared when leaving. + + bool m_bAlternatingColors; + + QSize m_oIconSize; + Qt::TextElideMode m_textElideMode; + + QRegion m_updateRegion; // used for the internal update system + QPoint m_scrollDelayOffset; + + QBasicTimer m_updateTimer; + QBasicTimer m_delayedAutoScroll; //used when an item is clicked +// QBasicTimer delayedDragSelect; //used when mouse is moving fo multi selecting + QBasicTimer m_delayedReset; + + QBasicTimer m_delayedShowToolTip; + int m_nDelayedHintTime; + + GlodonAbstractItemView::ScrollMode m_verticalScrollMode; + GlodonAbstractItemView::ScrollMode m_horizontalScrollMode; + + bool m_bCurrentIndexSet; + + bool m_bWrapItemText; + mutable bool m_delayedPendingLayout; + bool m_moveCursorUpdatedView; + bool m_bGridTextIncludeLeading; //格子区域中的文字绘制时是否用包含行间距 + bool m_bScrollBarTracking; //鼠标拖拽滚动条时,是否在松开滚动条时刻才进行表格区域的滚动 + bool m_bAllowSelectAll;//允许全选 + bool m_isSearchModel;//是否允许当满足定位时,进行内容定位 + bool m_bMouseMoveRefresh;//鼠标移动时,是否刷新鼠标当前覆盖的格子和之前的格子 + + QModelIndex m_oEditorIndex; + QColor m_oGridColor; + + mutable QBasicTimer m_delayedLayout; + mutable QBasicTimer m_fetchMoreTimer; + + GToolTipFrame *m_pToolTipFrame; + GlodonAbstractItemView::EnterMovingState m_prevState; + + bool m_bShowIndexContent;//是否显示格子内容 + bool m_ignoreActiveWindowFocusReason; + bool m_alwaysShowEditorPro;//总是处于编辑状态,一开始就创建出全部的控件 + + QWidget *m_currentEditor;//配合alwaysShowEditorPro使用,每次创建之后,用该变量存储创建出来的editor,并且加到m_persisten里面 + + // 标识当前tableView是否有多块选择区域,在有合并格或者行列移动时, + bool m_bIsInMultiSelect; // selectionModel中的selectionRange个数不能作为选择区域个数的标识 + +}; + +#endif // GLDABSTRACTITEMVIEW_P_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDApplication.h b/GCR/trunk/Glodon/include/GLD/GLDApplication.h new file mode 100644 index 00000000..d405f6e8 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDApplication.h @@ -0,0 +1,36 @@ +#ifndef GLDAPPLICATION_H +#define GLDAPPLICATION_H + +#include +#include +#include "GLDWidget_Global.h" + +class GLDWIDGETSHARED_EXPORT GLDApplication : public QApplication +{ + Q_OBJECT +public: + GLDApplication(int &argc, char **argv, int _internal = ApplicationFlags); + ~GLDApplication(); + bool notify(QObject *, QEvent *); + +signals: + //[NOTE] time-cost things should NOT be done in this function, + //otherwise, it will block main event loop + void idle(); + + //static void initEventDispatcher(); +protected: + + void onIdle(); + void timerEvent( QTimerEvent *event ); + //child can re-assign other types to this variable to filter out + QSet m_nonBusyEventTypes; + QSet m_busyEventTypes; + bool useFilterInBusy; + +private: + int m_idleTimerID; + +}; + +#endif // GLDAPPLICATION_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDBuffer.h b/GCR/trunk/Glodon/include/GLD/GLDBuffer.h new file mode 100644 index 00000000..3c9aa9c4 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDBuffer.h @@ -0,0 +1,9 @@ +#ifndef GLDBUFFER +#define GLDBUFFER + +#include + +typedef QBuffer GBuffer; + +#endif // GLDBUFFER + diff --git a/GCR/trunk/Glodon/include/GLD/GLDByteArray.h b/GCR/trunk/Glodon/include/GLD/GLDByteArray.h new file mode 100644 index 00000000..28656ab9 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDByteArray.h @@ -0,0 +1,9 @@ +#ifndef GLDBYTEARRAY +#define GLDBYTEARRAY + +#include + +typedef QByteArray GByteArray; + +#endif // GLDBYTEARRAY + diff --git a/GCR/trunk/Glodon/include/GLD/GLDCalendarWidget.h b/GCR/trunk/Glodon/include/GLD/GLDCalendarWidget.h new file mode 100644 index 00000000..eeaee22f --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDCalendarWidget.h @@ -0,0 +1,587 @@ +#ifndef GLDCALENDARWIDGET_H +#define GLDCALENDARWIDGET_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "GLDWidget_Global.h" + +const QString c_weekdayTextForeColor = "#585858"; +const QString c_weekdayTextBackColor = "#fbfbfb"; +const QString c_weekendTextForeColor = "#585858"; +const QString c_weekendTextBackColor = "#efefef"; + +#ifndef QT_NO_CALENDARWIDGET + +QT_BEGIN_NAMESPACE + +enum { + RowCount = 6, + ColumnCount = 7, + HeaderColumn = 0, + HeaderRow = 0, + MinimumDayOffset = 1 +}; + +class QDate; +class QTextCharFormat; + +class GLDWIDGETSHARED_EXPORT GLDCalendarDateSectionValidator +{ +public: + + enum Section { + NextSection, + ThisSection, + PrevSection + }; + + GLDCalendarDateSectionValidator() {} + virtual ~GLDCalendarDateSectionValidator() {} + virtual Section handleKey(int key) = 0; + virtual QDate applyToDate(const QDate &date) const = 0; + virtual void setDate(const QDate &date) = 0; + virtual QString text() const = 0; + virtual QString text(const QDate &date, int repeat) const = 0; + + QLocale m_locale; + +protected: + QString highlightString(const QString &str, int pos) const; +}; + +class GLDWIDGETSHARED_EXPORT GLDCalendarDayValidator : public GLDCalendarDateSectionValidator +{ +public: + GLDCalendarDayValidator(); + virtual Section handleKey(int key); + virtual QDate applyToDate(const QDate &date) const; + virtual void setDate(const QDate &date); + virtual QString text() const; + virtual QString text(const QDate &date, int repeat) const; +private: + int m_pos; + int m_day; + int m_oldDay; +}; + +class GLDWIDGETSHARED_EXPORT GLDCalendarMonthValidator : public GLDCalendarDateSectionValidator +{ +public: + GLDCalendarMonthValidator(); + virtual Section handleKey(int key); + virtual QDate applyToDate(const QDate &date) const; + virtual void setDate(const QDate &date); + virtual QString text() const; + virtual QString text(const QDate &date, int repeat) const; +private: + int m_pos; + int m_month; + int m_oldMonth; +}; + +class GLDWIDGETSHARED_EXPORT GLDCalendarYearValidator : public GLDCalendarDateSectionValidator +{ +public: + GLDCalendarYearValidator(); + virtual Section handleKey(int key); + virtual QDate applyToDate(const QDate &date) const; + virtual void setDate(const QDate &date); + virtual QString text() const; + virtual QString text(const QDate &date, int repeat) const; +private: + int pow10(int n); + int m_pos; + int m_year; + int m_oldYear; +}; + +class GLDWIDGETSHARED_EXPORT GLDCalendarDateValidator +{ +public: + GLDCalendarDateValidator(); + ~GLDCalendarDateValidator(); + + void handleKeyEvent(QKeyEvent *keyEvent); + QString currentText() const; + QDate currentDate() const { return m_currentDate; } + void setFormat(const QString &format); + void setInitialDate(const QDate &date); + + void setLocale(const QLocale &locale); + +private: + struct SectionToken + { + SectionToken(GLDCalendarDateSectionValidator *val, int rep) : validator(val), repeat(rep) {} + GLDCalendarDateSectionValidator *validator; + int repeat; + }; + + void toNextToken(); + void toPreviousToken(); + void applyToDate(); + + int countRepeat(const QString &str, int index) const; + void clear(); + + QStringList m_separators; + QList m_tokens; + GLDCalendarDateSectionValidator *m_yearValidator; + GLDCalendarDateSectionValidator *m_monthValidator; + GLDCalendarDateSectionValidator *m_dayValidator; + + SectionToken *m_currentToken; + + QDate m_initialDate; + QDate m_currentDate; + + GLDCalendarDateSectionValidator::Section m_lastSectionMove; +}; + +class GLDWIDGETSHARED_EXPORT GLDCalendarView : public QTableView +{ + Q_OBJECT +public: + GLDCalendarView(QWidget *parent = 0); + + void internalUpdate() { updateGeometries(); } + void setReadOnly(bool enable); + virtual void keyboardSearch(const QString & search) { Q_UNUSED(search) } + +signals: + void showDate(const QDate &date); + void changeDate(const QDate &date, bool changeMonth); + void clicked(const QDate &date); + void editingFinished(); +protected: + QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers); + void mouseDoubleClickEvent(QMouseEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); +#ifndef QT_NO_WHEELEVENT + void wheelEvent(QWheelEvent *event); +#endif + void keyPressEvent(QKeyEvent *event); + bool event(QEvent *event); + + QDate handleMouseEvent(QMouseEvent *event); +public: + bool m_readOnly; +private: + bool m_validDateClicked; +#ifdef QT_KEYPAD_NAVIGATION + QDate origDate; +#endif +}; + +class GLDCalendarWidgetPrivate; +class GLDWIDGETSHARED_EXPORT GLDCalendarDelegate : public QItemDelegate +{ + Q_OBJECT +public: + GLDCalendarDelegate(GLDCalendarWidgetPrivate *w, QObject *parent = 0) + : QItemDelegate(parent), calendarWidgetPrivate(w) + { } + virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const; + void paintCell(QPainter *painter, const QRect &rect, const QDate &date) const; + +private: + GLDCalendarWidgetPrivate *calendarWidgetPrivate; + mutable QStyleOptionViewItem storedOption; +}; + +//Private tool button class +class GLDWIDGETSHARED_EXPORT GLDCalToolButton: public QToolButton +{ +public: + GLDCalToolButton(QWidget * parent) + : QToolButton(parent) + { } +protected: + void paintEvent(QPaintEvent *e) + { + Q_UNUSED(e) + +#ifndef Q_WS_MAC + QStyleOptionToolButton opt; + initStyleOption(&opt); + + if (opt.state & QStyle::State_MouseOver || isDown()) { + //act as normal button + setPalette(QPalette()); + } else { + //set the highlight color for button text + QPalette toolPalette = palette(); + toolPalette.setColor(QPalette::ButtonText, toolPalette.color(QPalette::HighlightedText)); + setPalette(toolPalette); + } +#endif + QToolButton::paintEvent(e); + } +}; + +class GLDWIDGETSHARED_EXPORT GLDPrevNextCalButton : public QToolButton +{ + Q_OBJECT +public: + GLDPrevNextCalButton(QWidget *parent) : QToolButton(parent) {} +protected: + void paintEvent(QPaintEvent *) { + QStylePainter painter(this); + QStyleOptionToolButton opt; + initStyleOption(&opt); + opt.state &= ~QStyle::State_HasFocus; + painter.drawComplexControl(QStyle::CC_ToolButton, opt); + } +}; + +class QLabel; +class GLDCalendarDateValidator; +class QFrame; +class GLDWIDGETSHARED_EXPORT GLDCalendarTextNavigator: public QObject +{ + Q_OBJECT +public: + GLDCalendarTextNavigator(QObject *parent = 0) + : QObject(parent), m_dateText(0), m_dateFrame(0), m_dateValidator(0), m_widget(0), m_editDelay(1500), m_date(QDate::currentDate()) { } + + QWidget *widget() const; + void setWidget(QWidget *widget); + + int dateEditAcceptDelay() const; + void setDateEditAcceptDelay(int delay); + + QDate date() const; + void setDate(const QDate &date); + + bool eventFilter(QObject *o, QEvent *e); + void timerEvent(QTimerEvent *e); + +signals: + void dateChanged(const QDate &date); + void editingFinished(); + +private: + void applyDate(); + void updateDateLabel(); + void createDateLabel(); + void removeDateLabel(); + + QLabel *m_dateText; + QFrame *m_dateFrame; + QBasicTimer m_acceptTimer; + GLDCalendarDateValidator *m_dateValidator; + QWidget *m_widget; + int m_editDelay; + + QDate m_date; +}; + +class GLDWIDGETSHARED_EXPORT GLDCalendarWidget : public QWidget +{ + Q_OBJECT + Q_ENUMS(Qt::DayOfWeek) + Q_ENUMS(HorizontalHeaderFormat) + Q_ENUMS(VerticalHeaderFormat) + Q_ENUMS(SelectionMode) + Q_PROPERTY(QDate selectedDate READ selectedDate WRITE setSelectedDate) + Q_PROPERTY(QDate minimumDate READ minimumDate WRITE setMinimumDate) + Q_PROPERTY(QDate maximumDate READ maximumDate WRITE setMaximumDate) + Q_PROPERTY(Qt::DayOfWeek firstDayOfWeek READ firstDayOfWeek WRITE setFirstDayOfWeek) + Q_PROPERTY(bool gridVisible READ isGridVisible WRITE setGridVisible) + Q_PROPERTY(SelectionMode selectionMode READ selectionMode WRITE setSelectionMode) + Q_PROPERTY(HorizontalHeaderFormat horizontalHeaderFormat READ horizontalHeaderFormat WRITE setHorizontalHeaderFormat) + Q_PROPERTY(VerticalHeaderFormat verticalHeaderFormat READ verticalHeaderFormat WRITE setVerticalHeaderFormat) + Q_PROPERTY(bool navigationBarVisible READ isNavigationBarVisible WRITE setNavigationBarVisible) + Q_PROPERTY(bool dateEditEnabled READ isDateEditEnabled WRITE setDateEditEnabled) + Q_PROPERTY(int dateEditAcceptDelay READ dateEditAcceptDelay WRITE setDateEditAcceptDelay) +public: + enum HorizontalHeaderFormat { + NoHorizontalHeader, + SingleLetterDayNames, + ShortDayNames, + LongDayNames + }; + + enum VerticalHeaderFormat { + NoVerticalHeader, + ISOWeekNumbers + }; + + enum SelectionMode { + NoSelection, + SingleSelection + }; + + explicit GLDCalendarWidget(QDateTime &dt, QWidget *parent = 0); + ~GLDCalendarWidget(); + + virtual QSize sizeHint() const; + virtual QSize minimumSizeHint() const; + + QDate selectedDate() const; + + int yearShown() const; + int monthShown() const; + + QDate minimumDate() const; + void setMinimumDate(const QDate &date); + + QDate maximumDate() const; + void setMaximumDate(const QDate &date); + + Qt::DayOfWeek firstDayOfWeek() const; + void setFirstDayOfWeek(Qt::DayOfWeek dayOfWeek); + + bool isNavigationBarVisible() const; + bool isGridVisible() const; + + SelectionMode selectionMode() const; + void setSelectionMode(SelectionMode mode); + + HorizontalHeaderFormat horizontalHeaderFormat() const; + void setHorizontalHeaderFormat(HorizontalHeaderFormat format); + + VerticalHeaderFormat verticalHeaderFormat() const; + void setVerticalHeaderFormat(VerticalHeaderFormat format); + + QTextCharFormat headerTextFormat() const; + void setHeaderTextFormat(const QTextCharFormat &format); + + QTextCharFormat weekdayTextFormat(Qt::DayOfWeek dayOfWeek) const; + void setWeekdayTextFormat(Qt::DayOfWeek dayOfWeek, const QTextCharFormat &format); + + QMap dateTextFormat() const; + QTextCharFormat dateTextFormat(const QDate &date) const; + void setDateTextFormat(const QDate &date, const QTextCharFormat &format); + + bool isDateEditEnabled() const; + void setDateEditEnabled(bool enable); + + int dateEditAcceptDelay() const; + void setDateEditAcceptDelay(int delay); + + void addCalendarHead(); + + void addButtonToHeader(QString weekday, QHBoxLayout *headLayout); + + void setWeekdayTextColor(const QColor &foreColor = QColor(c_weekdayTextForeColor), + const QColor &backColor = QColor(c_weekdayTextBackColor)); + void setWeekendTextColor(const QColor &foreColor = QColor(c_weekendTextForeColor), + const QColor &backColor = QColor(c_weekendTextBackColor)); + +protected: + bool event(QEvent *event); + bool eventFilter(QObject *watched, QEvent *event); + void mousePressEvent(QMouseEvent *event); + void resizeEvent(QResizeEvent * event); + void keyPressEvent(QKeyEvent * event); + + virtual void paintCell(QPainter *painter, const QRect &rect, const QDate &date) const; + void updateCell(const QDate &date); + void updateCells(); + +public Q_SLOTS: + void setSelectedDate(const QDate &date); + void setDateRange(const QDate &min, const QDate &max); + void setCurrentPage(int year, int month); + void setGridVisible(bool show); + void setNavigationBarVisible(bool visible); + void showNextMonth(); + void showPreviousMonth(); + void showNextYear(); + void showPreviousYear(); + void showSelectedDate(); + void showToday(); + void dateTimeChanged(const QDateTime &dateTime); + +Q_SIGNALS: + void selectionChanged(); + void clicked(const QDate &date); + void activated(const QDate &date); + void currentPageChanged(int year, int month); + void passDateToEdit(const QDate &date); + +private: + QWidget *m_calendarHead; + QDateTime m_dateTime; + +private: + Q_DECLARE_PRIVATE(GLDCalendarWidget) + Q_DISABLE_COPY(GLDCalendarWidget) + + Q_PRIVATE_SLOT(d_func(), void _q_slotShowDate(const QDate &date)) + Q_PRIVATE_SLOT(d_func(), void _q_slotChangeDate(const QDate &date)) + Q_PRIVATE_SLOT(d_func(), void _q_slotChangeDate(const QDate &date, bool changeMonth)) + Q_PRIVATE_SLOT(d_func(), void _q_slotPassDateToEdit(const QDate &date, bool changeMonth)) + Q_PRIVATE_SLOT(d_func(), void _q_editingFinished()) + Q_PRIVATE_SLOT(d_func(), void _q_prevMonthClicked()) + Q_PRIVATE_SLOT(d_func(), void _q_nextMonthClicked()) + Q_PRIVATE_SLOT(d_func(), void _q_yearEditingFinished()) + Q_PRIVATE_SLOT(d_func(), void _q_yearClicked()) + Q_PRIVATE_SLOT(d_func(), void _q_monthChanged(int monthNum)) +}; + +class GLDWIDGETSHARED_EXPORT GLDCalendarModel : public QAbstractTableModel +{ + Q_OBJECT +public: + GLDCalendarModel(const QDate &date = QDate::currentDate(), QObject *parent = 0); + + int rowCount(const QModelIndex &) const + { return RowCount + m_firstRow; } + int columnCount(const QModelIndex &) const + { return ColumnCount + m_firstColumn; } + QVariant data(const QModelIndex &index, int role) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + + bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) + { + beginInsertRows(parent, row, row + count - 1); + endInsertRows(); + return true; + } + + bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex()) + { + beginInsertColumns(parent, column, column + count - 1); + endInsertColumns(); + return true; + } + + bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) + { + beginRemoveRows(parent, row, row + count - 1); + endRemoveRows(); + return true; + } + + bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex()) + { + beginRemoveColumns(parent, column, column + count - 1); + endRemoveColumns(); + return true; + } + + void showMonth(int year, int month); + void setDate(const QDate &d); + + void setMinimumDate(const QDate &date); + void setMaximumDate(const QDate &date); + + void setRange(const QDate &min, const QDate &max); + + void setHorizontalHeaderFormat(GLDCalendarWidget::HorizontalHeaderFormat format); + + void setFirstColumnDay(Qt::DayOfWeek dayOfWeek); + Qt::DayOfWeek firstColumnDay() const; + + bool weekNumbersShown() const; + void setWeekNumbersShown(bool show); + + QTextCharFormat formatForCell(int row, int col) const; + Qt::DayOfWeek dayOfWeekForColumn(int section) const; + int columnForDayOfWeek(Qt::DayOfWeek day) const; + QDate dateForCell(int row, int column) const; + void cellForDate(const QDate &date, int *row, int *column) const; + QString dayName(Qt::DayOfWeek day) const; + + void setView(GLDCalendarView *view) + { m_view = view; } + + void internalUpdate(); + QDate referenceDate() const; + int columnForFirstOfMonth(const QDate &date) const; + + int m_firstColumn; + int m_firstRow; + QDate m_date; + QDate m_minimumDate; + QDate m_maximumDate; + int m_shownYear; + int m_shownMonth; + Qt::DayOfWeek m_firstDay; + GLDCalendarWidget::HorizontalHeaderFormat m_horizontalHeaderFormat; + bool m_weekNumbersShown; + QMap m_dayFormats; + QMap m_dateFormats; + QTextCharFormat m_headerFormat; + GLDCalendarView *m_view; +}; + +class GLDWIDGETSHARED_EXPORT GLDCalendarWidgetPrivate : public QWidgetPrivate +{ + Q_DECLARE_PUBLIC(GLDCalendarWidget) +public: + GLDCalendarWidgetPrivate(); + + void showMonth(int year, int month); + void update(); + void paintCell(QPainter *painter, const QRect &rect, const QDate &date) const; + + void _q_slotShowDate(const QDate &date); + void _q_slotChangeDate(const QDate &date); + void _q_slotChangeDate(const QDate &date, bool changeMonth); + void _q_slotPassDateToEdit(const QDate &date, bool changeMonth); + void _q_editingFinished(); + void _q_monthChanged(int monthNum); + void _q_prevMonthClicked(); + void _q_nextMonthClicked(); + void _q_yearEditingFinished(); + void _q_yearClicked(); + + void createNavigationBar(QWidget *widget); + void updateButtonIcons(); + void updateMonthMenu(); + void updateNavigationBar(); + void updateMonthMenuNames(); + void updateCurrentPage(const QDate &newDate); + inline QDate getCurrentDate(); + void setNavigatorEnabled(bool enable); + + GLDCalendarModel *m_model; + GLDCalendarView *m_view; + GLDCalendarDelegate *m_delegate; + QItemSelectionModel *m_selection; + GLDCalendarTextNavigator *m_navigator; + bool m_dateEditEnabled; + + QPushButton *m_nextMonth; + QPushButton *m_prevMonth; + QComboBox *m_monthComboBox; + GLDCalToolButton *m_yearButton; + QSpinBox *m_yearEdit; + QWidget *m_navBarBackground; + QSpacerItem *m_spaceHolder; + QLabel *m_yearText; + bool m_navBarVisible; + mutable QSize m_cachedSizeHint; + Qt::FocusPolicy m_oldFocusPolicy; +}; + +QT_END_NAMESPACE + +#endif // QT_NO_CALENDARWIDGET + +#endif // GLDCALENDARWIDGET_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDChar.h b/GCR/trunk/Glodon/include/GLD/GLDChar.h new file mode 100644 index 00000000..a447c06a --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDChar.h @@ -0,0 +1,9 @@ +#ifndef GLDCHAR +#define GLDCHAR + +#include + +typedef QChar GChar; + +#endif // GLDCHAR + diff --git a/GCR/trunk/Glodon/include/GLD/GLDClassFactory.h b/GCR/trunk/Glodon/include/GLD/GLDClassFactory.h new file mode 100644 index 00000000..33e67732 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDClassFactory.h @@ -0,0 +1,39 @@ +#ifndef GLDCLASSFACTORY_H +#define GLDCLASSFACTORY_H + +#include "GLDObject.h" + +/// 定义类厂的基类 +template < class T > +class GLDCOMMONSHARED_EXPORT GClassFactory: public GObject, public IClassFactory +{ +public: + DECLARE_IUNKNOWN + + STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv) + { + if (riid == IID_IClassFactory) + { + GetGInterface((IClassFactory*) this, ppv); + return NOERROR; + } + else + { + return GObject::NonDelegatingQueryInterface( riid , ppv ); + } + + } + + STDMETHODIMP CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObject) + { + T* p = new T; + return GetGInterface((LPUNKNOWN) (PGNDUNKNOWN) p, ppvObject); + } + + STDMETHODIMP LockServer( BOOL /*fLock*/) + { + return S_OK; + } +}; + +#endif // GLDCLASSFACTORY_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDClassicsOutLookBar.h b/GCR/trunk/Glodon/include/GLD/GLDClassicsOutLookBar.h new file mode 100644 index 00000000..03597bfa --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDClassicsOutLookBar.h @@ -0,0 +1,212 @@ +#ifndef GLDCLASSICSOUTLOOKBAR_H +#define GLDCLASSICSOUTLOOKBAR_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "GLDString.h" +#include "GLDWidget_Global.h" + +class GLDOutLookBarAction; +// 视图区 +// 用于显示设置的widget +class GLDWIDGETSHARED_EXPORT GLDOutLookView: public QFrame +{ +public: + explicit GLDOutLookView(QWidget* parent = 0, Qt::WindowFlags f = 0); + ~GLDOutLookView(); + + void addView(QWidget *widget); + void setTitle(const GString &title); + void setTitleHeight(int nHeight); + void removeView(QWidget *widget); +private: + QVBoxLayout *m_layout; + QLabel *m_title; + QWidget *m_titleWgt; +}; + +class GLDWIDGETSHARED_EXPORT GLDNavigationItem: public QPushButton +{ +public: + explicit GLDNavigationItem(QWidget *parent = 0); + explicit GLDNavigationItem(const GString &text, QWidget *parent = 0); + GLDNavigationItem(const GString &text, const QIcon& icon, QWidget *parent = 0); + ~GLDNavigationItem(); +public: + void addOutLookBarAction(GLDOutLookBarAction *action); + void setChecked(bool checked); + inline GString uuid() { return m_uuid.toString(); } + +private: + void init(); +private: + QUuid m_uuid; +}; + +// 缩略按钮bar +class GLDWIDGETSHARED_EXPORT GLDThumbnailBar: public QToolBar +{ + Q_OBJECT +public: + explicit GLDThumbnailBar(QWidget *parent = 0); + ~GLDThumbnailBar(); +public: + GLDOutLookBarAction *addAction(const QIcon &icon, const GString &text); + GLDOutLookBarAction *addAction(GLDOutLookBarAction *action); + void removeAction(GLDOutLookBarAction *action); + + void addLeftAction(GLDOutLookBarAction *action); + void removeLeftAction(); + + bool hasAction(const GString &uId); + void clearButtons(); +private slots: + void showMoreAction(); +private: + QAction *m_foldAction; + QStack m_btnActions; +}; + +// 导航 +class GLDWIDGETSHARED_EXPORT GLDOutLookNavigationBar: public QWidget +{ +public: + explicit GLDOutLookNavigationBar(QWidget *parent); + ~GLDOutLookNavigationBar(); + +public: + GLDNavigationItem *addItem(GLDNavigationItem *item); + GLDNavigationItem *addItem(const GString &text); + GLDNavigationItem *addItem(const GString &text, const QIcon &icon); + bool removeItem(GLDNavigationItem *item); + bool removeItem(int index); + + GLDNavigationItem *addLastAction(GLDOutLookBarAction *action); + GLDNavigationItem *findByUuid(const GString &value); + QAction *removeLastAction(); + + void clearItems(); + int needItemCount(int offset); + int itemCount(); + +private: + void initLayout(); + +private: + QObjectList *m_itemList; + QVBoxLayout *m_itemLayout; +}; + +//分割条的按钮 +class GLDWIDGETSHARED_EXPORT GLDNavigationSplitterHandle : public QSplitterHandle +{ + Q_OBJECT +public: + explicit GLDNavigationSplitterHandle(Qt::Orientation o, QSplitter *parent); +signals: + void splitterHandleChanged(bool downward); +protected: + void mouseMoveEvent(QMouseEvent *); + void mousePressEvent(QMouseEvent *); +private: + double m_windowPosY; +}; + +// GLDNavigationSplitter +class GLDWIDGETSHARED_EXPORT GLDNavigationSplitter : public QSplitter +{ + Q_OBJECT +public: + explicit GLDNavigationSplitter(Qt::Orientation, QWidget* parent = 0); + +signals: + void splitterChanged(bool downward); + +protected: + QSplitterHandle *createHandle(); + +private slots: + void splitterHandleChanged(bool downward); +}; + +//GLDOutLookBarAction +class GLDWIDGETSHARED_EXPORT GLDOutLookBarAction : public QObject +{ + Q_OBJECT +public: + explicit GLDOutLookBarAction(const GString &text, const QIcon &icon = QIcon(), QObject *parent = 0); + ~GLDOutLookBarAction(); +public: + inline QAction *action(){ return m_action; } + inline GString uuid(){ return m_uuid.toString(); } + void setChecked(bool checked = false); + inline GString text() { return m_action->text(); } + inline QIcon icon() { return m_action->icon(); } + +signals: + void clicked(const GString &Uuid); + +private slots: + void triggered(); + +private: + QAction *m_action; + QUuid m_uuid; +}; + +// outLook +class GLDWIDGETSHARED_EXPORT GLDClassicsOutLookBar : public QScrollArea +{ + Q_OBJECT +public: + explicit GLDClassicsOutLookBar(QWidget *parent = 0); + ~GLDClassicsOutLookBar(); + +public: + GLDNavigationItem *addBarItem(QWidget *view, const GString &text, const QIcon &icon = QIcon()); + QAction *addThumbnailButton(QWidget *view, const GString &text, const QIcon &icon = QIcon()); + void setTitleHeight(int nHeight); + int currentIndex() const; + void setCurrentIndex(int nIndex); + QWidget *currentWidget() const; + QWidget *widget(int nIndex) const; + void setCurrentWidget(QWidget * widget); + GString currentText() const; + void setToolButtonStyle(Qt::ToolButtonStyle style); + void clearItems(); + void setIsHideThumbnailButton(bool isHide); + +signals: + void currentChanged(int nIndex); +private slots: + void itemClick(const GString &itemID); + void splitterChanged(bool downward); +private: + void initLayout(); + GLDOutLookBarAction *findAction(const GString &uID); + int findActionIndex(const GString &itemID) const; + void setItemCheck(const GString &uID, bool checked); +private: + GLDOutLookView *m_outLookView; + GLDNavigationSplitter *m_splitter; + GLDOutLookNavigationBar *m_outLookNavigBar; + GLDThumbnailBar *m_thumbnailButtons; + + QHash m_itemViews; + QList m_actions; + + GLDOutLookBarAction *m_curAction; + QWidget *m_curView; +}; + +#endif // GLDOUTLOOKBAR_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDColorList.h b/GCR/trunk/Glodon/include/GLD/GLDColorList.h new file mode 100644 index 00000000..eadba4c4 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDColorList.h @@ -0,0 +1,99 @@ +/*! + *@file gcolorlist.h + *@brief {颜色下拉选择框} + * + *@author Gaosy + *@date 2012.9.19 + *@remarks + *Copyright (c) 1998-2012 Glodon Corporation + */ + +#ifndef GLDCOLORLIST_H +#define GLDCOLORLIST_H + +#include +#include +#include "GLDWidget_Global.h" + +#define ITEM_RIGHT_OFFSET 16 + +/*! + *@class: GColorList + *@brief {颜色下拉选择框} + *@author Gaosy + *@date 2012.9.19 + */ +class GLDWIDGETSHARED_EXPORT GColorList : public QComboBox +{ + Q_OBJECT +public: + explicit GColorList(QWidget *parent = 0); + + void setUserDefaultColor(bool value); + bool userDefaultColor(); + + /*! + *根据给定颜色,查找其是否在颜色列表中 + *存在则返回其在列表中的位置,否则返回-1 + *@param[in] color 需要查找的颜色 + *@return int + */ + int findColor(QColor color); + + /*! + *将给定颜色添加到颜色列表中,如果该颜色已存在 + *则仅返回其在列表中的下标,并不重复添加 + *不存在则添加该颜色至列表最末尾,并返回下标 + *@param[in] color 需要添加到列表中的颜色 + *@return int + */ + int addColor(QColor color); + + /** + * @brief 下拉框的倒数第二项为用户自定义的颜色 + * @param color + * @return + */ + int setUserColor(QColor color); + QColor userColor(); + + /*! + *返回颜色列表当前选中的颜色 + *@return QColor + */ + QColor currentColor(); + + /** + * @brief 设置当前颜色选择框的颜色 + * @param color + */ + void selectColor(QColor color); + + void setCurrentIndex(int index); + +signals: + /** + * @brief 当前颜色改变时才会发出此信号,如果点击更多,选择了自定义颜色,则会发出选择颜色对应的index + * @param index + */ + void colorIndexChange(int index); + +protected: + void resizeEvent(QResizeEvent *e); + +private slots: + void moreColorClicked(int index); + +private: + QIcon colorToIcon(QColor color); + void initColorList(); + +private: + QSize m_newSize; + QColor m_userColor; + bool m_isInInit; + int m_currentIndex; + QVector m_addColors; +}; + +#endif // GLDCOLORLIST_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDColorListEx.h b/GCR/trunk/Glodon/include/GLD/GLDColorListEx.h new file mode 100644 index 00000000..c65f81fb --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDColorListEx.h @@ -0,0 +1,262 @@ +#ifndef GColorListEx_H +#define GColorListEx_H + +#include +#include +#include +#include +#include +#include +#include +#include "GLDWidget_Global.h" + +typedef QList GLDColorList; + +/** + * GLDColorBlock + */ +class GLDWIDGETSHARED_EXPORT GLDColorBlock : public QPushButton +{ + Q_OBJECT +public: + explicit GLDColorBlock(const QColor &color, const QColor &edgeColor, QWidget *parent = 0); + ~GLDColorBlock(){} + + void updateColor(const QColor &color, const QColor &edgeColor); + inline QColor color() const + { + return m_color; + } + + inline QColor edgeColor() const + { + return m_edgeColor; + } + +private: + void drawColorBlock(); + +signals: + void colorValue(const QColor &color, const QColor &edgeColor); + void colorBlock(GLDColorBlock *currentBlock); + void commitSelectedColor(const QColor &color, const QColor &edgeColor); + +public slots: + void onClick(); + +private: + QColor m_color; + QColor m_edgeColor; +}; + +/** + * GLDColorTableTitle + */ +class GLDWIDGETSHARED_EXPORT GLDColorTableTitle : public QPushButton +{ + Q_OBJECT +public: + explicit GLDColorTableTitle(QWidget *parent = 0); + ~GLDColorTableTitle(){} +}; + +/** + * GLDColorRow + */ +class GLDWIDGETSHARED_EXPORT GLDColorRow : public QWidget +{ + Q_OBJECT +public: + explicit GLDColorRow(const QList &colors, const QList &edgeColors, QWidget *parent = 0); + ~GLDColorRow(){} + +public: + void setBackgroundColor(QColor &color); + void updateColorBlocks(QList &colors, QList &edgeColors, int updateColorCount); + GLDColorBlock* initBlock(); + GLDColorBlock* findColorBlock(const QColor color); + int findColorBlockIndex(const QColor color); + +private: + void initColorBlocks(const QList &colors, const QList &edgeColors); + void initColorBlocksLayout(); + +signals: + void currentSelectedColor(const QColor &color, const QColor &edgeColor); + void currentSelectedBlock(GLDColorBlock *block); + void commitSelectedColor(const QColor &color, const QColor &edgeColor); + +private: + QList m_colorBlocks; +}; + +/** + * GLDColorTable +*/ +class GLDWIDGETSHARED_EXPORT GLDColorTable : public QWidget +{ + Q_OBJECT +public: + explicit GLDColorTable(const QList &firstRowColors, const QList &firstRowEdgeColors, QWidget *parent); + ~GLDColorTable(); + + void addTitle(const QString &title); + void appendColorRow(const QList &colors, const QList &edgeColor); + void updateColorRow(int row, QList &blockColors, + QList &blockEdgeColors, int updateColorCount); + void initTableLayout(); + void setBackgroundColor(QColor &color); + GLDColorBlock* initBlock(); + GLDColorBlock* findColorBlock(const QColor &color); + int findColorBlockIndex(const QColor &color, const QColor &edgeColor); + +signals: + void currentSelectedColor(const QColor &color, const QColor &edgeColor); + void currentSelectedBlock(GLDColorBlock *block); + void findColor(const QColor &color); + void commitSelectedColor(const QColor &color, const QColor &edgeColor); + +protected: + void mouseReleaseEvent(QMouseEvent *e); + +private: + void initTitleLayout(QVBoxLayout *layout); + void initColorRows(QVBoxLayout *layout); + +private: + GLDColorTableTitle *m_title; + QList m_colorRows; + QColor m_BackColor; +}; + +/** + * GColorListEx +*/ +class GLDWIDGETSHARED_EXPORT GColorListEx : public QComboBox +{ + Q_OBJECT +public: + // isLoadRecentColor用来控制是否配置临时文件以保存与加载从更多颜色中选择的颜色 + explicit GColorListEx(QWidget *parent = 0, QColor color = QColor("#000000"), + bool isLoadRecentColor = false); + ~GColorListEx(); + +public: + void setHasBorder(bool bHasBorder); + void loadColorFile(const QString &fileName = ":/inis/GColorListEx.ini"); + + /** + * @brief 根据给定颜色,查找其是否在颜色列表中 + * 存在则返回其在列表中的位置,否则返回-1 + * @param color 需要查找的颜色 + * @return + */ + GLDColorBlock *findColorBlock(const QColor &color); + + /** + * @brief 返回颜色列表当前选中的颜色 + * @return + */ + QColor currentColor() const; + + void setCurrentColor(const QColor color); + + /** + * @brief isLoadRecentColor 是否配置临时文件以加载和保存最近从更多颜色中选择的颜色 + * @return + */ + bool isLoadRecentColor() const; + /** + * @brief setIsLoadRecentColor 设置是否配置临时文件以加载和保存最近从更多颜色中选择的颜色 + * @param isLoadRecentColor + */ + void setIsLoadRecentColor(const bool isLoadRecentColor); + + /** + * @brief 颜色块是否显示ToolTip + * @return + */ + bool isShowRGBColor() const; + + /** + * @brief 设置颜色块是否显示ToolTip + * @param isShowColorRGB + */ + void setIsShowRGBColor(const bool isShowColorRGB = false); + + /** + * @brief 控件进入编辑状态后是否显示表示该颜色块的RGB值 + * @return + */ + bool isShowRGBStr() const; + + /** + * @brief 设置控件进入编辑状态后是否显示表示该颜色块的RGB值 + * @param isShowRGBStr + */ + void setIsShowRGBStr(bool isShowRGBStr); + + /** + * @brief iconUrlInEdit 设置编辑框上面的icon, iconUrl为icon的所在路径 + * 但是icon是有限制的,必须为整体16*16 pixel,icon + * 中的图像为14*10 pixel,并且水平居中垂直居上,以保证界面美观 + * @return + */ + QString iconUrlInEdit() const; + void setIconUrlInEdit(const QString iconUrl); + +signals: + void currentSelectedColor(const QColor &color, const QColor &edgeColor); + /** + * @brief 当前颜色改变时才会发出此信号,如果点击更多,选择了自定义颜色,则会发出选择颜色对应的index + * @param index + */ + void colorIndexChange(const QColor &color); + void findColor(const QColor &color, const GLDColorBlock *block); + void colorBlockClicked(int); + +private slots: + void drawColor(const QColor &color, const QColor &edgeColor); + void moreColor(); + void currentSelectedBlock(GLDColorBlock *block); + void commitSelectedColor(const QColor &color, const QColor &edgeColor); + +private: + QColor getColor(const QString sVal); + void addGrayColorTable(); + void addMoreButton(); + void addStandardColorTable(); + void addRecentColorTable(); + QColor getEdgeColor(const QColor &color); + void updateRecentColorTable(); + void addTable(GLDColorTable *table, int tableWid, int tableHeight); + void addThemeColorTable(); + void initColorComboBox(); + void initPopUpWidget(); + void addRecentColorList(); + void loadDefaultConfigColorVal(); + void loadSelectedMoreColor(); + void saveSelectedMoreColor(); + void removeRecentColorConfFile(); + void updateCurrentColor(); + +private: + GLDColorList m_blockColors; // 颜色块内部颜色 + GLDColorList m_edgeColors; // 颜色块边框颜色 + QListWidget *m_comboBoxWidget; + QColor m_curColor; + QColor m_userColor; + GLDColorBlock *m_currentBlock; + GLDColorBlock *m_originalBlock; + int m_recentUseColorCount; + GLDColorList m_recentUseColor; + GLDColorList m_recentUseEdgeColor; + GLDColorTable *m_recentColorTable; + QList m_colorTableList; + bool m_isLoadRecentColor; // 控制是否配置临时文件以保存与加载从更多颜色中选择的颜色 + bool m_isShowRGBColor; // 控制是否显示RGB在每个颜色button上 + bool m_isShowRGBStr; // 控制格子内是否显示表示颜色块的RGB字符串 + QString m_iconUrlInEdit; // 存放编辑框中icon的Url +}; + +#endif // GColorListEx_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDComDLLMain.h b/GCR/trunk/Glodon/include/GLD/GLDComDLLMain.h new file mode 100644 index 00000000..520b0f22 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDComDLLMain.h @@ -0,0 +1,44 @@ + +// The following ifdef block is the standard way of creating macros which make exporting +// from a DLL simpler. All files within this DLL are compiled with the GDLLEX_EXPORTS +// symbol defined on the command line. this symbol should not be defined on any project +// that uses this DLL. This way any other project whose source files include this file see +// GDLLEX_API functions as being imported from a DLL, wheras this DLL sees symbols +// defined with this macro as being exported. + +#ifndef WIN32 +//TODO: Linux, Mac OS +#else //WIN32 + + +#ifdef GWP_BCB //Glodon Work Platform 软件开发平台 +#include +#include //GWP_BCB c++builder +#pragma hdrstop +#pragma argsused + + +//Project中要定义这个宏 _DEFINE_INTERFACE_ +//Project中要Dependencis COMExt这个Project +//接口定义都在xapp.h中进行,COMExt项目中 +#ifdef GDLLEX_EXPORTS +#define GDLLEX_API __declspec(dllexport) +#else +#define GDLLEX_API __declspec(dllimport) +#endif + +extern "C" GDLLEX_API int __cdecl LoadGCOMExtension( void* ); + + +#else //GWP_BCB + +#ifdef GDLLEX_EXPORTS +# define GDLLEX_API __declspec(dllexport) +#else +# define GDLLEX_API __declspec(dllimport) +#endif + +extern "C" GDLLEX_API int __cdecl _LoadGCOMExtension( void* ); + +#endif //GWP_BCB +#endif //WIN32 diff --git a/GCR/trunk/Glodon/include/GLD/GLDComHelper.h b/GCR/trunk/Glodon/include/GLD/GLDComHelper.h new file mode 100644 index 00000000..0d8fc61f --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDComHelper.h @@ -0,0 +1,86 @@ +/************************************************************************* +* * +* 广联达COM辅助函数单元 H * +* * +* 设计:Zhangsk 2012.05.23 * +* 备注: * +* 审核: * +* * +* Copyright (c) 2012-2013 GLD Corporation * +* * +*************************************************************************/ + +#ifndef GLDCOMHELPER_H +#define GLDCOMHELPER_H + +#include "GLDUnknwn.h" +#include "GLDComptr.h" +#include "GLDObject.h" +#include "GLDNameSpace.h" + +G_GLODON_BEGIN_NAMESPACE +G_COMHELPER_BEGIN_NAMESPACE + +template +inline bool Supports(IUnknown *pInstance, const IID &iid, T **pIntf) +{ + return (pInstance != NULL) && (GLD_OK == pInstance->QueryInterface(iid, (void **)pIntf)); +} + +inline bool Supports(IUnknown *pInstance, const IID &iid) +{ + GComPtr pUnk; + return Supports(pInstance, iid, &pUnk); +} + +template +inline bool Supports(IUnknown *pInstance, T **pIntf) +{ + return Supports(pInstance, __uuidof(T), pIntf); +} + +template +inline bool Supports(GObject *pObj, const IID &iid, T **pIntf) +{ + GComPtr pUnk = NULL; + if (pObj->QueryInterface(iid, (void **)&pUnk) >= 0) + { + return Supports(pUnk, iid, pIntf); + } + else + { + return false; + } +} + +inline bool Supports(GObject *pObj, const IID &iid) +{ + GComPtr pOut = NULL; + return Supports(pObj, iid, &pOut); +} + +template +inline bool Supports(GObject *pObj, T **pIntf) +{ + return Supports(pObj, __uuidof(T), pIntf); +} + + + + +template +struct _SupportsHelper +{ + static bool supports(IUnknown *pInstance) + { + GComPtr p; + return (pInstance != NULL) && (GLD_OK == pInstance->QueryInterface( __uuidof(T), (void **)&p)); + } +}; + +#define SUPPORTS(pInstance, T) _SupportsHelper::supports(pInstance) + + +G_COMHELPER_END_NAMESPACE +G_GLODON_END_NAMESPACE +#endif // GLDCOMHELPER_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDComLoaderIntf.h b/GCR/trunk/Glodon/include/GLD/GLDComLoaderIntf.h new file mode 100644 index 00000000..21bb30e6 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDComLoaderIntf.h @@ -0,0 +1,32 @@ +/********************************************************************** + * + * 广联达 COM加载器接口定义 + * + * 设计:Zhangsk 2012.05.25 + * 备注: + * 审核: + * 注意: + * + * Copyright (c) 2012-2013 GlodonSoft Corporation + * + **********************************************************************/ + +#ifndef GLDCOMLOADERINTF_H +#define GLDCOMLOADERINTF_H + +#include "GLDUnknwn.h" +//#include "GLDObject.h" + +DEFINE_IID(IComLoader, "{A4CD87EA-E1DE-4588-A2E0-277C3AE2B536}"); +DECLARE_INTERFACE_(IComLoader, IUnknown) +{ + /*! 安装一个应用的类厂 + \param pszName 对象的名称,建议方式:com.grand.gsp + \param pszVersion 对象的版本 + \param pFactory 类厂对象 + \return S_OK S_FALSE + */ + STDMETHOD(InstallApplication)( wchar_t *pszName , wchar_t *pszVersion, IUnknown* pFactory ) PURE; +}; + +#endif // GLDCOMLOADERINTF_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDComObject.h b/GCR/trunk/Glodon/include/GLD/GLDComObject.h new file mode 100644 index 00000000..1d9eb852 Binary files /dev/null and b/GCR/trunk/Glodon/include/GLD/GLDComObject.h differ diff --git a/GCR/trunk/Glodon/include/GLD/GLDComboBox.h b/GCR/trunk/Glodon/include/GLD/GLDComboBox.h new file mode 100644 index 00000000..f0e39f9d --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDComboBox.h @@ -0,0 +1,152 @@ +#ifndef GLDCOMBOBOX_H +#define GLDCOMBOBOX_H + +#include +#include +#include +#include "GLDWidget_Global.h" + +class GLDWIDGETSHARED_EXPORT GLDCustomComboBox : public QComboBox +{ + Q_OBJECT + Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly) + Q_PROPERTY(bool hasSelectedText READ hasSelectedText) +public: + explicit GLDCustomComboBox(QWidget *parent = 0); + virtual void showPopup(); + virtual void hidePopup(); + + /** + * @brief ComboBox中的Edit是否能编辑 + * @return + */ + bool isReadOnly(); + void setReadOnly(bool value); + + bool hasSelectedText(); + + /** + * @brief 在处于readOnly时,edit中的内容按Backspace键或则Delete键是否能删除内容 + * 只有ComboBox的readOnly为true时,才能开启该功能,否则按照正常编辑操作处理 + * @return + */ + bool canDelete(); + void setCanDelete(bool value); + + void setCurrentIndexAndEmitSignal(int index); + virtual void resizeContent(); + /** + * @brief setAlignment 设置下拉框选择后编辑框中文字的对齐方式 + */ + void setAlignment(Qt::Alignment align); + +Q_SIGNALS: + void onSetCurrentIndex(int index); + void cursorPositionChanged(); + void selectionChanged(); + +public Q_SLOTS: + void cut(); + void paste(); + void copy(); + void deleteSelectedText(); + +private slots: + void onExpandOrCollapsed(const QModelIndex &index); + void doCursorPositionChanged(int, int); + void doSelectionChanged(); + +protected: + void resizeEvent(QResizeEvent *e); + +private: + void updateEditFieldGeometry(); + +private: + bool m_isReadOnly; +}; + +class GLDWIDGETSHARED_EXPORT GLDCustomComboBoxEx : public GLDCustomComboBox +{ + Q_OBJECT +public: + explicit GLDCustomComboBoxEx(QWidget *parent = 0); + +public: + void setHasBorder(bool hasBorder = false); + //对输入文本后的弹出框进行样式修改 + void setFilterPopupStyleSheet(); + +protected: + void resizeEvent(QResizeEvent *e); + bool eventFilter(QObject *target, QEvent *e); + void keyPressEvent(QKeyEvent *e); +private: + bool m_hasBorder; + bool m_isShow; +}; + +class GLDWIDGETSHARED_EXPORT GLDLineWidthComboBox : public QComboBox +{ + Q_OBJECT +public: + explicit GLDLineWidthComboBox(QWidget *parent); + + inline int minLineWidth() { return m_minLineWidth; } + void setMinLineWidth(int minLineWidth); + + inline int maxLineWidth() { return m_maxLineWidth; } + void setMaxLineWidth(int maxLineWidth); + + inline int currentLineWidth() { return m_currentLineWidth; } + void setCurrentLineWidth(int lineWidth); + +protected: + void resizeEvent(QResizeEvent *); + +private slots: + void onCurrentIndexChanged(int index); + +private: + void initLineWidthIcon(); + QWidget *m_parent; + QSize m_parentSize; + int m_minLineWidth; + int m_maxLineWidth; + int m_currentLineWidth; + bool m_inAddItem; +}; + +class GLDWIDGETSHARED_EXPORT GLDComboBoxLineEdit : public QLineEdit +{ + Q_OBJECT +public: + explicit GLDComboBoxLineEdit(QWidget *parent = 0); + + bool canDelete(); + void setCanDelete(bool value); + +public slots: + void deleteSelectedText(); + +protected: + void keyPressEvent(QKeyEvent *keyEvent); + +private: + bool m_canDelete; +}; + +class GLDWIDGETSHARED_EXPORT FilterPopupItemDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + FilterPopupItemDelegate(QObject *parent = 0); + virtual ~FilterPopupItemDelegate(); + + void paint(QPainter *painter, + const QStyleOptionViewItem &option, const QModelIndex &index) const; + QSize sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const; +}; + +#endif // GLDCOMBOBOX_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDCommentFrame.h b/GCR/trunk/Glodon/include/GLD/GLDCommentFrame.h new file mode 100644 index 00000000..16683af7 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDCommentFrame.h @@ -0,0 +1,112 @@ +/*! + *@file GLDCommentFrame.h + *@brief 定义了一个可以移动comment, + *@author liul + *@date 2014.4.24 + *@remarks {remarks} + *Copyright (c) 1998-2014 Glodon Corporation + */ + +#ifndef GLDCOMMENTFRAME_H +#define GLDCOMMENTFRAME_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "GLDTextEdit.h" +#include "GLDWidget_Global.h" + +#define GLD_PI 3.14159265358979 + +class GLDWIDGETSHARED_EXPORT GArrowFrame : public QFrame +{ +public: + explicit GArrowFrame(QFrame* parent = NULL); + void setPosition(QPoint topLeft, QPoint bottomRight); + void setBottomRight(QPoint bottomRight); + QPoint bottomRight(); + void setTopLeft(QPoint topLeft); + QPoint topLeft(); + +protected: + void paintEvent(QPaintEvent *); + +private: + QPoint m_topLeft; + QPoint m_bottomRight; +}; + +class GLDWIDGETSHARED_EXPORT GCommentFrame : public QFrame +{ + Q_OBJECT +public: + explicit GCommentFrame(QWidget* parent = NULL, QPoint pt = QPoint(0, 0)); + ~GCommentFrame(); + +public Q_SLOTS: + void hide(); + void show(); + void move(int x, int y); + void move(const QPoint &); + void setCommentText(const QString &str); +public: + GArrowFrame *m_arrow; + +private: + QLabel *m_label; + QWidget *m_parent; + const int m_nMarginWidth; + const int m_nWidth; + const int m_nHeight; +}; + +class GLDWIDGETSHARED_EXPORT GToolTipFrame : public QFrame +{ +public: + explicit GToolTipFrame(QFrame* parent = NULL, QPoint pt = QPoint(0, 0), + const QString &text = QString()); + ~GToolTipFrame(); + void hide(); + void show(); + void move(int x, int y); + void move(const QPoint &); + void setHintText(const QString &text); +private: + QFrame *m_parent; + QLabel *m_label; + QString m_lastShowText; + const int m_nMarginWidth; +// const int m_nWidth; +// const int m_nHeight; +}; + +/** + * @brief 调整行列大小信息提示框,其中主要包含了label + */ +class GLDWIDGETSHARED_EXPORT GInfoFrame : public QFrame +{ +public: + explicit GInfoFrame(QFrame* parent = NULL, QPoint pt = QPoint(0, 0)); + ~GInfoFrame(); + +public: + void move(const QPoint &); + void setText(const QString &str); + + inline void setOrientation(Qt::Orientation orientation){ m_direction = orientation; } + inline Qt::Orientation orientation(){ return m_direction; } + +private: + QLabel *m_label; + Qt::Orientation m_direction; +}; + +#endif // GLDCOMMENTFRAME_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDCommentFrameEx.h b/GCR/trunk/Glodon/include/GLD/GLDCommentFrameEx.h new file mode 100644 index 00000000..aae78f08 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDCommentFrameEx.h @@ -0,0 +1,157 @@ +/*! + *@file GLDCommentFrameEx.h + *@brief {注释框控件} + * + *@author mazq-a + *@date 2014.07.07 + *@remarks + *Copyright (c) 1998-2012 Glodon Corporation + */ + +#ifndef GLDCOMMENTFRAMEEX_H +#define GLDCOMMENTFRAMEEX_H + +#include +#include +#include "GLDString.h" +#include "GLDUITypes.h" +#include "GLDTableView_Global.h" + +class GLDPlainTextEdit; +class GlodonAbstractItemView; +class GLDTABLEVIEWSHARED_EXPORT GCustomCommentFrameEx : public QWidget +{ + Q_OBJECT + + enum EAnchorPos + { + ELeftUp, + ELeftDown, + EBottomLeft, + EBottomRight, + ERightUp, + ERightDown, + ETopLeft, + ETopRight, + ECenter + }; + + enum EMousePos + { + EMoveWindPos, + EStretchLeft, + EStretchRight, + EStretchUp, + EStretchDown, + EStretchLeftUp, + EStretchLeftDown, + EStretchRightUp, + EStretchRightDown, + EMousePosEdit, + EMousePosNULL + }; + +public: + explicit GCustomCommentFrameEx(QWidget *parent = NULL, QPoint pt = QPoint(0, 0)); + ~GCustomCommentFrameEx(); + +Q_SIGNALS: + void textChanged(const GString &str); + void editFocusOut(); + +public Q_SLOTS: + void setCommentText(const GString &str); + GString commentText(); +public: + void move(int x, int y); + void move (const QPoint& pt); + void move(const QModelIndex& index, const GlodonAbstractItemView& instView ); + void hide(); + void show(bool bautohiden = false); + void setFramePosition(QPoint point); + bool isReadOnly() const; + void setReadOnly(bool bReadOnly); + +protected: + void paintEvent(QPaintEvent *e); + void drawImageOnWin(QPainter *painter); + void drawFreamRect(QPainter *painter, bool bPainterEvent = true); + void resizeEvent(QResizeEvent *e); + void mousePressEvent(QMouseEvent *e); + void mouseReleaseEvent(QMouseEvent *e); + void mouseMoveEvent(QMouseEvent *e); + void enterEvent(QEvent *e); + void leaveEvent(QEvent *e); + bool eventFilter(QObject *watched, QEvent *event); + +private: + EAnchorPos getAnchorPos(const QPoint& pt, const QRect& rc) const; + EAnchorPos getTriangleByAnchorAndRect(const QPoint& ptAnchor + , const QRect& rcPos + , QPoint& ptFirst + , QPoint& ptSecond ) const; + + void updatePaintPolygonDate(const QPoint& ptAnchor, const QRect& rcPos); + EMousePos getMousePos(const QPoint& pos) const; + void processMousePos(QMouseEvent *e, GCustomCommentFrameEx::EMousePos pos); + void processMoveWindPos(QMouseEvent *e); + void processStretchLeft(QMouseEvent *e); + void processStretchRight(QMouseEvent *e); + void processStretchUp(QMouseEvent *e); + void processStretchDown(QMouseEvent *e); + void processStretchLeftUp(QMouseEvent *e); + void processStretchLeftDown(QMouseEvent *e); + void processStretchRightUp(QMouseEvent *e); + void processStretchRightDown(QMouseEvent *e); + void setWindowMask(bool birregularWnd); + void updateEditPos(); + +private: + bool rotationLeft(const QRect& rcPos); + bool rotationRight(const QRect& rcPos); + bool rotationUp(const QRect& rcPos); + bool rotationDown(const QRect& rcPos); + bool setPosByParent(const QRect& rcPos); + void initPlaintEdit(); + void setUpUI(); + QRect getMaxRect(const QPoint& pt, const QRect& rc) const; + void updateWindow(); + +private: + QPoint m_dragPoint; + QSize m_initWinSize; + // 调整大小的矩形框 + QRect m_rectLT; + QRect m_rectRT; + QRect m_rectMT; + QRect m_rectMB; + QRect m_rectRB; + QRect m_rectLB; + QRect m_rectML; + QRect m_rectMR; + + // 注释框指示的坐标点 + QPoint m_anchor; + QPoint m_ptAnchorFirst; + QPoint m_ptAnchorSecond; + + QRect m_rcPos; + // 其它所有边框的点 + QVector m_verFreamPoint; + EMousePos m_mouseCurrentPos; + bool m_bShowStretch; + GLDPlainTextEdit *m_plainTextEdit; // 编辑框 + GColor m_clBg; + GColor m_clText; + GColor m_clBorder; + QModelIndex m_curIndex; + const QPixmap m_mapbl; + const QPixmap m_mapbr; + const QPixmap m_mapbc; + const QPixmap m_maprt; + const QPixmap m_maprc; + bool m_bWndState; + bool m_bIsMenuShow; +}; + +#endif // MAINWINDOW_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDCommon_Global.h b/GCR/trunk/Glodon/include/GLD/GLDCommon_Global.h new file mode 100644 index 00000000..4e25db83 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDCommon_Global.h @@ -0,0 +1,16 @@ +#ifndef GLDCOMMON_GLOBAL_H +#define GLDCOMMON_GLOBAL_H + +#include + +#ifndef GLD_FULLSOURCE + #if defined(GLDCOMMON_LIBRARY) + # define GLDCOMMONSHARED_EXPORT Q_DECL_EXPORT + #else + # define GLDCOMMONSHARED_EXPORT Q_DECL_IMPORT + #endif +#else + #define GLDCOMMONSHARED_EXPORT +#endif + +#endif // GLDCOMMON_GLOBAL_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDComptr.h b/GCR/trunk/Glodon/include/GLD/GLDComptr.h new file mode 100644 index 00000000..91e37b72 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDComptr.h @@ -0,0 +1,261 @@ +#ifndef GLDCOMPTR_H +#define GLDCOMPTR_H + +#include +//#include "sal.h" +#include "GLDUnknwn.h" + +#ifndef NULL +# define NULL 0 +#endif + +template + +class GComPtr +{ +public: + inline GComPtr() + { + p = NULL; + } + + inline GComPtr(T *lp) + { + p = lp; + if (p != NULL) + p->AddRef(); + } + + inline GComPtr(const GComPtr &lp) + { + p = lp.p; + if (p != NULL) + p->AddRef(); + } + + //inline GComPtr(GComPtr&& lp) + //{ + // p = lp.p; + // lp.p = NULL; + //} + + inline GComPtr(T* lp, bool /*dummy*/) + { + p = lp; + } + + template + inline GComPtr(const GComPtr &lp) + { + if (NULL == lp.p) + { + p = NULL; + } + else + { + lp.p->QueryInterface(__uuidof(T), (void**)&p); + //if (p != NULL) p->AddRef(); // QueryInterface已经增加引用计数了 + } + } + + template + inline GComPtr(const GComPtr &lp, bool /*dummy*/) + { + if (NULL == lp.p) + { + p = NULL; + } + else + { + lp.p->QueryInterface(__uuidof(T), (void**)&p); + if (p != NULL) p->Release(); // QueryInterface已经增加引用计数了 + } + } + + inline ~GComPtr() + { + if (p) + p->Release(); + } + + inline operator T*() const + { + return p; + } + + inline T& operator*() const + { + //ATLENSURE(p != NULL); + return *p; + } + + //The assert on operator& usually indicates a bug. If this is really + //what is needed, however, take the address of the p member explicitly. + inline T** operator&() + { + //assert(p == NULL); + return &p; + } + + bool operator!() const + { + return (p == NULL); + } + + bool operator<(T* pT) const + { + return p < pT; + } + + bool operator!=(T* pT) const + { + return !operator==(pT); + } + + bool operator==(T* pT) const + { + return p == pT; + } + + T* operator=(T* lp) + { + if (*this!=lp) + { + if (lp != NULL) + lp->AddRef(); + if (p) + p->Release(); + p = lp; + return lp; + } + return *this; + } + + T* operator=(const GComPtr& lp) + { + if (*this != lp) + { + if (p) + p->Release(); + if (lp != NULL && !lp.isNull()) + { + lp.p->AddRef(); + p = lp.p; + } + else + { + p = NULL; + } + return p; + } + return *this; + } + + /*T* operator=(GComPtr&& lp) + { + if (*this != lp) + { + if (p != NULL) + p->Release(); + + p = lp.p; + lp.p = NULL; + } + return *this; + }*/ + + template + T* operator=(const GComPtr& lp) + { + /*if ( !IsEqualObject(lp) ) + { + return static_cast(AtlComQIPtrAssign((IUnknown**)&p, lp, __uuidof(T))); + }*/ + if (NULL == lp.p) + { + p = NULL; + } + else + { + if (p != NULL) + p->Release(); + lp.p->QueryInterface(__uuidof(T), (void**)&p); + if (p != NULL) + p->AddRef(); + } + return *this; + } + + inline bool isNull() const { return !p; } + + void AddRef() + { + if (!p) + p->AddRef(); + } + + // Release the interface and set to NULL + void Release() + { + T* pTemp = p; + if (pTemp) + { + p = NULL; + pTemp->Release(); + } + } + + // Compare two objects for equivalence + /*bool IsEqualObject(IUnknown* pOther) + { + if (p == NULL && pOther == NULL) + return true; // They are both NULL objects + + if (p == NULL || pOther == NULL) + return false; // One is NULL the other is not + + GComPtr punk1; + GComPtr punk2; + p->QueryInterface(__uuidof(IUnknown), (void**)&punk1); + pOther->QueryInterface(__uuidof(IUnknown), (void**)&punk2); + return punk1 == punk2; + }*/ + + // Attach to an existing interface (does not AddRef) + void Attach(T* p2) + { + if (p) + p->Release(); + p = p2; + } + + // Detach the interface (does not Release) + T* Detach() + { + T* pt = p; + p = NULL; + return pt; + } + + /*HRESULT CopyTo(T** ppT) + { + //assert(ppT != NULL); + if (ppT == NULL) + return E_POINTER; + *ppT = p; + if (p) + p->AddRef(); + return S_OK; + }*/ + + template + HRESULT QueryInterface(Q** pp) const + { + //assert(pp != NULL); + return p->QueryInterface(__uuidof(Q), (void**)pp); + } + + T* p; +}; + +#endif // GLDCOMPTR_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDCrypt.h b/GCR/trunk/Glodon/include/GLD/GLDCrypt.h new file mode 100644 index 00000000..f7acea72 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDCrypt.h @@ -0,0 +1,204 @@ +/*! +* @加解密库头文件 +* +* @author lijb +* @date 2015.06.05 +* @remarks 备注 +* Copyright (c) 1998-2015 Glodon Corporation +*/ +#ifndef GLDCRYPT_H +#define GLDCRYPT_H + +#include "GLDCrypt_Global.h" +#include "GLDString.h" +#include "GLDCrypt_Global.h" +#include "cryptlib.h" + +//class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE SymmetricCipher; + +//加解密算法枚举,目前支持AES, DES,可扩充 +enum EnAlgorithmType +{ + EN_ALGORITHM_AES = 0, + EN_ALGORITHM_DES = 1, + EN_ALGORITHM_UNKOWN +}; + +//加解密算法加密模式枚举 +enum EnEncodeMode +{ + ENCODE_MODE_CBC = 0, + ENCODE_MODE_CFB = 1, + ENCODE_MODE_ECB = 2, + ENCODE_MODE_OFB = 3, + ENCODE_MODE_PCBC = 4, + ENCODE_MODE_UNKOWN +}; + +//加解密算法填充模式枚举 +enum EnPaddingType +{ + //enum BlockPaddingScheme {NO_PADDING, ZEROS_PADDING, PKCS_PADDING, ONE_AND_ZEROS_PADDING, DEFAULT_PADDING}; + //下边枚举需要和cryptlib库一致 + EN_NOPADDING = 0, + EN_ZEROS_PADDING = 1, + EN_PKCS_PADDING = 2, + EN_ONE_AND_ZEROS_PADDING = 3, + EN_DEFAULT_PADDING = 4, + EN_PADDING_UNKOWN +}; + +class GCryptAlgorithmPrivate; +//////////////////////////////////////////////////////////////////////////////// +//设计:创建一个加解密算法策略基类,提供相应虚接口,相关接口需要子类实现; +// 公共接口如encryptStr等封装到基类实现 +//功能:算法基类,提供加解密串/文件,以及设置加解密相关配置接口 +//////////////////////////////////////////////////////////////////////////////// +class GLDCRYPTSHARED_EXPORT GCryptAlgorithm +{ +public: + //使用密钥加密明文字符串plainText 并且返回密文 + const GString encryptStr(const GString &plainText); + + //使用密钥解密密文cipher 并且返回恢复后的明文 + const GString decryptStr(const GString &cipher); + + //使用密钥加密明文文件inFilename 并且返回密文文件outFilename + bool encryptFile(const GString & outFilename, const GString & inFilename); + + //使用密钥解密密文文件DecFilename 并且返回恢复后的名文文件recoverFilename + bool decryptFile(const GString & recoverFilename, const GString & DecFilename); + + //根据用户参数加密模式EnEncodeType,返回对应的字符串 + static GString encodeModeStr(EnEncodeMode EnEncodeType); + + //根据用户参数填充类型EnPadding,返回对应的字符串 + static GString paddingTypeStr(EnPaddingType EnPadding); + + //设置加密参数,包括加密算法EnAlgorithmKind,加密模式EnEncodeType,填充类型EnPadding + void setEncodeMode(EnAlgorithmType EnAlgorithmKind, EnEncodeMode EnEncodeType, EnPaddingType EnPadding); + + //设置加密密钥及长度,此处需要重载,因为CBC模式不需要初始向量iv + void setKey(byte *key, int length, byte *iv); + void setKey(byte *key, int length); + + //获取加密密钥 + byte * key(); + //获取加密初始向量 + byte * ivKey(); + + //根据内部生成随机的加密密钥并设置 + virtual void setRandomKey() = 0; + + //根据用户参数加密模式EnEncodeType 生成相应的加解密器 + virtual SymmetricCipher* encryptor(EnEncodeMode EnEncodeType) = 0; + virtual SymmetricCipher* decryptor(EnEncodeMode EnEncodeType) = 0; + +protected: + GCryptAlgorithm(EnAlgorithmType EnAlgorithmKind, EnEncodeMode EnEncodeType, EnPaddingType EnPadding); + GCryptAlgorithm(GCryptAlgorithmPrivate &dd, EnAlgorithmType EnAlgorithmKind, EnEncodeMode EnEncodeType, EnPaddingType EnPadding); + ~GCryptAlgorithm(); + +protected: + GCryptAlgorithmPrivate* const d_ptr; + Q_DECLARE_PRIVATE(GCryptAlgorithm); + + friend class GCrypt; +}; + +class GAesAlgorithmPrivate; +//////////////////////////////////////////////////////////////////////////////// +//设计:AES 加解密算法策略类,实现父类GCryptAlgorithm加解密器的方法 +//功能:AES算法子类,提供加解密串/文件,以及设置加解密相关配置接口 +//////////////////////////////////////////////////////////////////////////////// +class GLDCRYPTSHARED_EXPORT GAesAlgorithm : public GCryptAlgorithm +{ +public: + GAesAlgorithm(EnEncodeMode EnEncodeMode, EnPaddingType EnPaddingType); + ~GAesAlgorithm(); + + //根据内部生成随机的加密密钥并设置 + void setRandomKey(); + + //根据用户参数加解密模式EnEncodeType等 生成相应的加解密密器 + SymmetricCipher* encryptor(EnEncodeMode EnEncodeMode); + SymmetricCipher* decryptor(EnEncodeMode EnEncodeMode); + +private: + Q_DECLARE_PRIVATE(GAesAlgorithm); +}; + +class GDesAlgorithmPrivate; +//////////////////////////////////////////////////////////////////////////////// +//设计:DES 加解密算法策略类,实现父类GCryptAlgorithm加解密器的方法 +// +//功能:DES算法子类,提供加解密串/文件,以及设置加解密相关配置接口 +//////////////////////////////////////////////////////////////////////////////// +class GLDCRYPTSHARED_EXPORT GDesAlgorithm : public GCryptAlgorithm +{ +public: + GDesAlgorithm(EnEncodeMode EnEncodeMode, EnPaddingType EnPaddingType); + ~GDesAlgorithm(); + + //根据内部生成随机的加密密钥并设置 + void setRandomKey(); + + //根据用户参数加解密模式EnEncodeType 生成相应的加解密密器 + SymmetricCipher* encryptor(EnEncodeMode EnEncodeMode); + SymmetricCipher* decryptor(EnEncodeMode EnEncodeMode); + +private: + Q_DECLARE_PRIVATE(GDesAlgorithm); +}; + +class GCryptPrivate; +//////////////////////////////////////////////////////////////////////////////// +//设计:创建一个加解密策略类,根据用户传入参数,用工厂方法动态创建加解密对象 +// ,屏蔽差异,用户不感知,方便扩展;封装适配器接口,供具体对象实现 +//功能:根据用户传入的加密参数,生成对应的加密对象 +//////////////////////////////////////////////////////////////////////////////// +class GLDCRYPTSHARED_EXPORT GCrypt +{ +public: + GCrypt(EnAlgorithmType enAlgorithmType = EN_ALGORITHM_DES + , EnEncodeMode EnEncodeType = ENCODE_MODE_CBC, EnPaddingType EnPadding = EN_PKCS_PADDING); + ~GCrypt(); + + //使用密钥加密明文字符串plainText 并且返回密文 + GString encryptStr(const GString &strPlainText); + + //使用密钥解密密文cipher 并且返回恢复后的明文 + GString decryptStr(const GString &strCipher); + + //使用密钥加密明文文件inFilename 并且返回密文文件outFilename + bool encryptFile(const GString &strOutFilename, const GString &strInFilename); + + //使用密钥解密密文文件DecFilename 并且返回恢复后的名文文件recoverFilename + bool decryptFile(const GString &strRecoverFilename, const GString &strDecFilename); + + //设置加密参数,包括加密算法EnAlgorithmKind,加密模式EnEncodeType,填充类型EnPadding + void setEncodeMode(EnAlgorithmType EnAlgorithmKind, EnEncodeMode EnEncodeType, EnPaddingType EnPadding); + + //根据内部生成随机的加密密钥并设置 + void setRandomKey(); + + //设置加密密钥及长度,此处需要重载,因为CBC模式不需要初始向量iv + void setKey(byte *key, int length, byte *iv); + void setKey(byte *key, int length) ; + + //获取加密密钥 + byte * key(); + + //获取加密初始向量 + byte * ivKey(); + +private: + //根据用户传入的加密参数,生成对应的加密类对象 + GCryptAlgorithm* createAlgorithm(EnAlgorithmType enAlgorithmType, EnEncodeMode EnEncodeMode, EnPaddingType EnPaddingType); + +private: + GCryptPrivate * const d_ptr; + Q_DECLARE_PRIVATE(GCrypt); +}; + +#endif diff --git a/GCR/trunk/Glodon/include/GLD/GLDCrypt_Global.h b/GCR/trunk/Glodon/include/GLD/GLDCrypt_Global.h new file mode 100644 index 00000000..62677ba4 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDCrypt_Global.h @@ -0,0 +1,16 @@ +#ifndef GLDCRYPT_GLOBAL_H +#define GLDCRYPT_GLOBAL_H + +#include + +#ifndef GLD_FULLSOURCE + #if defined(GLDCRYPT_LIBRARY) + # define GLDCRYPTSHARED_EXPORT Q_DECL_EXPORT + #else + # define GLDCRYPTSHARED_EXPORT Q_DECL_IMPORT + #endif +#else + #define GLDCRYPTSHARED_EXPORT +#endif + +#endif // GLDCRYPT_GLOBAL_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDCustomButton.h b/GCR/trunk/Glodon/include/GLD/GLDCustomButton.h new file mode 100644 index 00000000..bdeab0d5 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDCustomButton.h @@ -0,0 +1,26 @@ +#ifndef GLDCUSTOMBUTTON_H +#define GLDCUSTOMBUTTON_H + +#include "GLDMask_Global.h" + +#include + +class GLDMASKSHARED_EXPORT GLDCustomButton : public QPushButton +{ + Q_OBJECT + +public: + explicit GLDCustomButton(QWidget* parent = nullptr); + explicit GLDCustomButton(const QString &iconPath, QWidget* parent = nullptr); + + void setPixmap(const QPixmap& pm); + QSize sizeHint() const; + +protected: + void paintEvent(QPaintEvent* e); + +private: + QPixmap m_pixmap; +}; + +#endif // GLDCUSTOMBUTTON_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDCustomCommentFrame.h b/GCR/trunk/Glodon/include/GLD/GLDCustomCommentFrame.h new file mode 100644 index 00000000..591b10c1 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDCustomCommentFrame.h @@ -0,0 +1,167 @@ +/*! + *@file GLDCommentFrame.h + *@brief 定义了一个可以移动comment, + *@author liul + *@date 2014.4.24 + *@remarks {remarks} + *Copyright (c) 1998-2014 Glodon Corporation + */ + +#ifndef GLDCUSTOMCOMMENTFRAME_H +#define GLDCUSTOMCOMMENTFRAME_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "GLDTextEdit.h" +#include "GLDTableView_Global.h" + +#define GLD_PI 3.14159265358979 + +class GLDTABLEVIEWSHARED_EXPORT GCustomCommentFrame : public QFrame +{ + Q_OBJECT +public: + explicit GCustomCommentFrame(QWidget* parent = NULL, QPoint pt = QPoint(0, 0)); + ~GCustomCommentFrame(); + enum GCustomCommentFrameState + { + m_EnMoving = 0, + m_EnUP, + m_EnDown, + m_EnLeft, + m_EnRiht, + m_EnLeftUp, + m_EnbottomLeft, + m_EnRightUp, + m_EnRightDown, + m_EnNormal + }; + const static int c_AdjustWith = 6; + +public: + inline QModelIndex curIndex() { return m_curIndex; } + inline void setCurIndex(const QModelIndex &index) { m_curIndex = index; } + + void setFramePosition(QPoint point); + + void resetBordrect(); + + // 当鼠标不父亲上点击事件的时候,获取不到编辑状态,需要将这个编辑状态设置为false + inline void setEllopseHide() { m_isShowEllopse = false; } + + inline bool isShowCommentPersistent() { return m_isShowCommentPersistent; } + inline QPoint topLeft(){ return m_topLeft; } + +Q_SIGNALS: + void textChanged(const QString &str); + + // 批注框失去焦点时会触发信号,外部写值的时机 + void editFocusOut(); + +public Q_SLOTS: + void hide(); + void show(bool isPersistent = false); + void move(int x, int y); + void move(const QPoint &); + void move(QModelIndex index); + void moveTo(QPoint point); + void setCommentText(const QString &str); + QString commentText(); + +protected: + void paintEvent(QPaintEvent *event); + void mousePressEvent(QMouseEvent *e); + void mouseMoveEvent(QMouseEvent *e); + void mouseReleaseEvent(QMouseEvent *e); + bool eventFilter(QObject *obj, QEvent *event); + void showEvent(QShowEvent *); + void resizeEvent(QResizeEvent *); + +private: + void onMouseMoveEvent(QMouseEvent *e); + void initPlaintEdit(); + void setInitStyle(); + void setCommentFrameSize(); + void setCommentFrameMask(); + void setEditTextPos(); + void resetBorderRect(); + // TODO: 如果别的项目也需要一些角度转弧度,弧度转角度,根据两个点计算先的时候,需要存放函数到公共类中去。 + double cacultAngle(); + inline double radianToAngle(const double Degree){ return (Degree*180/GLD_PI);} + double getDistance(const QPoint border, const QPoint pos); + + void inMoveRange(QPoint pos); + // TODO:如果以后需要频繁做一些两个点之间的判断关系的画,是要把这些放到一个公共的类中去 + bool containPosPoint(const QPoint pos, const QPoint border); + bool containPos(const QPoint pos, const QRect subBorderRect); + + void repainLineAndArrow(QPainter *painter); + void repainArrow(QPainter *painter); + void repainArrowMoving(QPainter *painter); + void repainAdjustRect(QPainter *painter); + + inline QPoint adjustRectLeftPoint(); + inline QPoint adjustRectRightPoint(); + inline QPoint adjustRectUpPoint(); + inline QPoint adjustRectBottomPoint(); + + bool isPosInFrame(QPoint pos); + void resetFramePosition(); + +private: + QWidget *m_parent; // 存放当commet的容器 + const int m_nMarginWidth; // 边框和编辑框之间的大小 + int m_nWidth; // 编辑框的宽度 + int m_nHeight; // 编辑框的高度 + int m_nDefaultWidth; // 编辑框的宽度 + int m_nDefaultHeight; // 编辑框的高度 + QModelIndex m_curIndex; + bool m_isShowEllopse; // 编辑框是否被选择 + bool m_starDraw; // 描绘开始 + + //窗体移动需要 +// QPoint m_windowPos; + QPoint m_mousePos; + // QPoint m_dPos; + GCustomCommentFrameState m_state; + + // 该控件的子控件,共有四个,箭头,箭头到编辑框的距离,编辑框,移动的图形。 + GLDPlainTextEdit *m_plainTextEdit; // 编辑框 + QPoint m_topLeft; // 箭头的顶点位置 + QPoint m_bottomRight; // 箭头的箭尾位置,和矩形编辑框的连接位置 + QRect m_borderRect; + double m_angle; + QVector m_arrowPoints; + bool m_isShowCommentPersistent; +}; + +QPoint GCustomCommentFrame::adjustRectLeftPoint() +{ + return QPoint(m_borderRect.left() - 10, (m_borderRect.top() + m_borderRect.bottom()) / 2); +} + +QPoint GCustomCommentFrame::adjustRectRightPoint() +{ + return QPoint(m_borderRect.right(), (m_borderRect.top() + m_borderRect.bottom()) / 2); +} + +QPoint GCustomCommentFrame::adjustRectUpPoint() +{ + return QPoint((m_borderRect.left() + m_borderRect.right()) / 2, m_borderRect.top() - 10); +} + +QPoint GCustomCommentFrame::adjustRectBottomPoint() +{ + return QPoint((m_borderRect.left() + m_borderRect.right()) / 2, m_borderRect.bottom()); +} + +#endif // GLDCOMMENTFRAME_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDCustomWaitingBox.h b/GCR/trunk/Glodon/include/GLD/GLDCustomWaitingBox.h new file mode 100644 index 00000000..2d7d069c --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDCustomWaitingBox.h @@ -0,0 +1,47 @@ +#ifndef GCUSTOMWAITINGBOX_H +#define GCUSTOMWAITINGBOX_H + +#include +#include "GLDWidget_Global.h" + +class GLDWIDGETSHARED_EXPORT GLDCustomWaitingBox : public QWidget +{ + Q_OBJECT + +public: + explicit GLDCustomWaitingBox(QWidget *parent = 0); + ~GLDCustomWaitingBox(); + + /** + * @brief loadWaitMap + * @param fileName + * @return 是否加载成功 + * 加载一组图标,图标个数为 2行6列。可以参见 CLDCustomWaitingBox.png + * 注意是 2 行 6列 + */ + bool loadWaitMap(const QString &fileName); +signals: + void start(); + void end(); + +public Q_SLOTS: + void hide(); + void show(); + +public: + void setBackGroundColor(const QColor &color); + QColor backGroundColor(); + +protected: + bool eventFilter(QObject *target, QEvent *event); + void paintEvent(QPaintEvent *); + void timerEvent(QTimerEvent *event); + +private: + QPixmap m_mapWait; + int m_nimageIndex; + int m_nTimerId; + QColor m_bkColor; +}; + +#endif // GCUSTOMWAITINGBOX_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDDateTime.h b/GCR/trunk/Glodon/include/GLD/GLDDateTime.h new file mode 100644 index 00000000..252f2463 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDDateTime.h @@ -0,0 +1,11 @@ +#ifndef GLDDATETIME +#define GLDDATETIME + +#include + +typedef QDate GDate; +typedef QTime GTime; +typedef QDateTime GDateTime; + +#endif // GLDDATETIME + diff --git a/GCR/trunk/Glodon/include/GLD/GLDDateTimeEdit.h b/GCR/trunk/Glodon/include/GLD/GLDDateTimeEdit.h new file mode 100644 index 00000000..a407156b --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDDateTimeEdit.h @@ -0,0 +1,33 @@ +#ifndef GLDDATETIMEEDIT_H +#define GLDDATETIMEEDIT_H + +#include +#include "qabstractspinbox.h" +#include "GLDWidget_Global.h" + +class GLDWIDGETSHARED_EXPORT GLDDateTimeEdit : public QDateTimeEdit +{ + Q_OBJECT + Q_PROPERTY(bool hasSelectedText READ hasSelectedText) +public: + explicit GLDDateTimeEdit(QWidget *parent = 0); + explicit GLDDateTimeEdit(const QDateTime &dt, QWidget *parent = 0); + + bool hasSelectedText(); + +Q_SIGNALS: + void selectionChanged(); + void cursorPositionChanged(); + +public slots: + void cut(); + void paste(); + void copy(); + void deleteSelectedText(); + +private slots: + void doSelectionChanged(); + void doCursorPositionChanged(int, int); +}; + +#endif // GLDDATETIMEEDIT_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDDateTimeEditEx.h b/GCR/trunk/Glodon/include/GLD/GLDDateTimeEditEx.h new file mode 100644 index 00000000..a4af66e4 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDDateTimeEditEx.h @@ -0,0 +1,189 @@ +#ifndef GLDDateTimeEditEx_H +#define GLDDateTimeEditEx_H + +#include "GLDDateTimeEdit.h" +#include "GLDCalendarWidget.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "GLDWidget_Global.h" + + +/** + * @brief The GLDDateTimeEditEx class 日历类 + */ +class GLDWIDGETSHARED_EXPORT GLDDateTimeEditEx : public GLDDateTimeEdit +{ + Q_OBJECT +public: + enum ButtonTypes { None, ComboBoxArrow, Ellipsis }; + + explicit GLDDateTimeEditEx(const QDateTime &dt = QDateTime::currentDateTime(), QWidget *parent = 0); + ~ GLDDateTimeEditEx(); + +public: + + /** + * @brief plainText 返回编辑框的内容 + * @return + */ + QString plainText(); + + bool calendarPopup() const; + + /** + * @brief setCalendarPopup 设置是否有弹出框 + * @param enable + */ + void setCalendarPopup(bool enable); + + /** + * @brief setHasBorder 设置是否有边线 + * @param bValue + */ + void setHasBorder(const bool bValue); + + /** + * @brief 获取QSS文件路径 + * @param path + */ + virtual const QString qssFilePath(const QString &path); + + /** + * @brief 日期不能包含字母消息提示 + * @param 无 + */ + virtual void excludeLetterMessageBox(); + + /** + * @brief 日期输入方式有误消息提示 + * @param 无 + */ + virtual void errorDateMessageBox(); + + /** + * @brief 选择的日期小于最小日期消息提示 + * @param 无 + */ + virtual void dateLessThanSysDateMessageBox(); + + /** + * @brief 选择的日期大于最大日期消息提示 + * @param 无 + */ + virtual void dateLargerThanSysDateMessageBox(); + + void updateValue(); + + /** 返回日期的显示格式 + * yyyy:代表年 MM:代表月份 dd:代表天 + * hh:代表时 mm:代表分 ss:代表秒 + * 格式一般为: yyyy-MM-dd hh:mm:ss + * @brief displayFormat + * @return + */ + QString displayFormat() const; + + /** 由于需求的变化,需要设置显示格式的时候按正规的格式来设置(请严格遵守, 区分大小写) + * yyyy:代表年 MM:代表月份 dd:代表天 + * hh:代表时 mm:代表分 ss:代表秒 + * 格式一般为: yyyy-MM-dd hh:mm:ss + * @brief setDisplayFormat + * @param format + */ + void setDisplayFormat(const QString &format); + + /** + * @brief setCalendarPopupOffset 设置日历弹出窗体的偏移量 + * @param xOffset + * @param yOffset + */ + void setCalendarPopupOffset(int xOffset = 0, int yOffset = 0); + +signals: + void inputInvalid(bool bIsInputInvalid); + +protected: + void keyPressEvent(QKeyEvent *event); + void mousePressEvent(QMouseEvent *event); + void paintEvent(QPaintEvent *event); + void enterEvent(QEvent *event); + void leaveEvent(QEvent *event); + + QDateTime dateTimeFromText(const QString &text) const; + QString textFromDateTime(const QDateTime &dt) const; + QValidator::State validate(QString &input, int &pos) const; + void focusOutEvent(QFocusEvent *event); + +private: + /** + * @brief initCalendarPopup + */ + void initCalendarPopup(); + + /** + * @brief positionCalendarPopup 定位弹出框的位置,特别是在屏幕以外时的特殊位置定位 + */ + void positionCalendarPopup(); + + /** + * @brief showPopUp 显示日历下拉框 + */ + void showPopUp(); + + /** + * @brief hidePopUp 隐藏日历下拉框 + */ + void hidePopUp(); + + QStyle::SubControl newHoverControl(const QPoint &pos); + /** + * @brief parseText 采用补全的方式,对用户输入的不完整的日期格式进行补全修正, 只做补0操作 + * 如2014-1-2 3:4:5修正为2014-01-02 03:04:05 + * @param input 用户输入 + * @return 经补全的日期格式 + */ + QString parseText(const QString &input); + + QString formatDate(const QString &input); + +Q_SIGNALS: + void onshowPopup(bool &value); + +private slots: + /** + * @brief GLDDateTimeEditEx::selectDate 显示给定的日期 + * @param date + */ + void selectDate(const QDate &date); + void selectDateTime(const QDateTime &dateTime); + +private: + bool m_isCalendarPopup; // 是否有弹出框 + bool m_hasBorder; + bool m_curKeyIsEnter; // 判断是否是Key_Enter或Key_Return键 + // m_justKeyPressed 和 m_keyPressing用来控制编辑框删除后的第一次和之后的输入 + bool m_justKeyPressed; + bool m_keyPressing; + QString m_curStr; // 保存当前输入 + mutable QString m_lastStrForDatetime; + int m_curPos; //保存当前输入的position + GLDCalendarWidget *m_calendarWidget; + ButtonTypes m_buttonType; + QDateTime m_dateTime; + int m_xOffset; + int m_yOffset; +}; + +#endif // GLDDateTimeEditEx_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDDefaultItemDelegate.h b/GCR/trunk/Glodon/include/GLD/GLDDefaultItemDelegate.h new file mode 100644 index 00000000..c478e3fa --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDDefaultItemDelegate.h @@ -0,0 +1,569 @@ +/*! + *@file glodondefaultitemdelegate.h + *@brief {默认编辑方式} + *提供了TableView需要的默认编辑方式,如需要扩展,则一律从此派生 + *@author Gaosy + *@date 2012.9.7 + *@remarks {remarks} + *Copyright (c) 1998-2012 Glodon Corporation + */ + +#ifndef GLDDEFAULTITEMDELEGATE_H +#define GLDDEFAULTITEMDELEGATE_H + +#include +#include "GLDComboBox.h" +#include "GLDEnum.h" + +#include "GLDDateTimeEdit.h" +#include "GLDMathUtils.h" +#include "GLDTableView_Global.h" + +class QComboBox; +class GlodonAbstractItemView; +class GlodonAbstractItemViewPrivate; +class GLDTableView; +class GLDTableViewPrivate; +class GLDAbstractButtonEdit; +class GlodonDefaultItemDelegatePrivate; +class GLDWindowComboBoxEx; +class GLDLineWidthComboBoxEx; + +/*! + *@class: GlodonDefaultItemDelegate + *@brief {Grid默认编辑方式,所有需要扩展编辑方式的,都需要从这里派生} + *@author Gaosy + *@date 2012.9.10 + */ +class GLDTABLEVIEWSHARED_EXPORT GlodonDefaultItemDelegate : public QItemDelegate +{ + Q_OBJECT +public: + explicit GlodonDefaultItemDelegate(QObject *parent = 0); + +public: + // 派生类需要覆盖的方法 + virtual bool editable(const QModelIndex &index) const; + virtual GEditStyle editStyle(const QModelIndex &index, bool &readOnly) const; + virtual void initEllipsisButtonEdit(GLDAbstractButtonEdit *ellipsis, const QModelIndex &index) const; + virtual void initComboBox(QComboBox *comboBox, const QModelIndex &index) const; + virtual void initWindowComboBox(GLDWindowComboBoxEx *comboBox, const QModelIndex &index) const; + virtual void initLineWidthComboBox(GLDLineWidthComboBoxEx *comboBox, const QModelIndex &index) const; + virtual void initSpinBox(QAbstractSpinBox *spinBox, const QModelIndex &index); + virtual void initDateTimeEdit(GLDDateTimeEdit *dateTimeEdit, const QModelIndex &index); + + virtual void itemViewSelected(QComboBox *comboBox, const QModelIndex &index, const QModelIndex &itemIndex) const; +public: + /*! + *@enum: GDataType + *@brief {数据类型,当前仅为HTML超链接提供支持} + *@author Gaosy + *@date 2012.9.10 + */ + enum GDataType + { + GTypeNormal, + GTypeHTML, + GRichText, + GDiaSymbol, + GMeterSymbol + }; + + /** + * @brief 图片显示的模式 + * @see QImage::scaled + */ + enum GAspectRatioMode + { + IgnoreAspectRatio, //忽略长宽比(只为充满) + KeepAspectRatio, //保持比例缩放(图片完全展示前提下尽可能地缩放) + KeepAspectRatioByExpanding,//保持比例缩放(图片只能有一个维度超过容纳的尺寸) + KeepAspectPixel //保持原大小 + }; + + /*! + *格子的绘制 + *@param[in] painter + *@param[in] option + *@param[in] index + *@return 无 + *@see 参见QItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, + * const QModelIndex &index) const; + */ + void paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const; + + QSize sizeHint( + const QStyleOptionViewItem &option, const QModelIndex &index) const; + + /*! + *返回编辑方式需要的控件 + *@param[in] parent + *@param[in] option + *@param[in] index + *@return QWidget* + */ + QWidget *createEditor(QWidget *parent, + const QStyleOptionViewItem &option, + const QModelIndex &index) const; + + /*! + *进入编辑状态时,初始化控件的值 + *@param[in] editor 格子编辑需要的控件 + *@param[in] index + *@return 无 + */ + void setEditorData(QWidget *editor, const QModelIndex &index) const; + + /*! + *退出编辑状态时,将编辑控件中的值提交 + *@param[in] editor 格子编辑需要的控件 + *@param[in] model TableView的model + *@param[in] index + *@return 无 + */ + void setModelData(QWidget *editor, + QAbstractItemModel *model, + const QModelIndex &index) const; + + /*! + *设置编辑控件的位置及Geometry信息 + *@param[in] editor 格子编辑需要的控件 + *@param[in] model TableView的model + *@param[in] index + *@return 无 + */ + void updateEditorGeometry(QWidget *editor, + const QStyleOptionViewItem &option, + const QModelIndex &index) const; + + virtual QVariant currentEditorData(const QModelIndex &index, QWidget *editor); + + QModelIndex dataIndex(const QModelIndex &index) const; + QModelIndex treeIndex(const QModelIndex &index) const; + + static GEditStyle editStyleByVariantType(QVariant::Type vType); + + inline QWidget *curEditor() + { + return m_curEditor; + } + + /** + * 设置编辑方式esDropDown是否选择值立即退出编辑状态: 默认值true + * @brief setComboBoxConvenient + * @param convenient + */ + inline bool isComboBoxConvenient() const + { + return m_comboBoxConvenient; + } + inline void setComboBoxConvenient(bool convenient) + { + m_comboBoxConvenient = convenient; + } + + void setIsTextEllipse(bool value); + inline bool isTextElided() const + { + return m_isTextEllipse; + } + /** + * @brief 判断当前tableView是否处于编辑状态 + * @return + */ + bool isEditing(); + inline void setCurrTreeEditting(const QModelIndex &value) + { + m_currTreeEditing = value; + } + inline QModelIndex currTreeEditting() + { + return m_currTreeEditing; + } /*! + *绘制格子背景 + *@param[in] painter + *@param[in] option + *@param[in] index + *@return 无 + *@see 参见QItemDelegate::drawBackground(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const + */ + virtual void drawBackground(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + + /*! + * \brief 设置文本绘制时的折行方式 + * \param wrap + */ + inline void setTextWrapMode(QTextOption::WrapMode wrap) + { + m_wrapMode = wrap; + } + inline QTextOption::WrapMode textWrapMode() + { + return m_wrapMode; + } + +protected: + QRect textLayoutBounds(const QStyleOptionViewItem &option) const; + bool isBoolCell(const QModelIndex &index) const; + + bool eventFilter(QObject *object, QEvent *event); + + template + bool commitIfCanElseSelectAll(QEvent *event, QWidget *editor, bool &state); + + bool commitDataAndCloseEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint = NoHint); + + /*! + * \brief cursorMoveTextEndByEndKey,使用Ctrl + End键来将光标位置移动到最后 + * \param editor + */ + void cursorMoveTextEndByEndKey(QWidget *editor); + /*! + * \brief cursorMoveTextEnd,用于将鼠标光标在editor中移向最后一个位置 + * \param editor + * \return + */ + bool cursorMoveTextEnd(QWidget *editor); + /*! + * \brief cursorPosInsertANewLine + * \param editor + * \return true:move to a new line successful, false:cursor can`t movable control,or moving failed + */ + bool cursorPosInsertANewLine(QWidget *editor); + QStyleOptionViewItem setOptions(const QModelIndex &index, + const QStyleOptionViewItem &option) const; +Q_SIGNALS: + void onQueryImageAspectRatioMode(const QModelIndex &index, GlodonDefaultItemDelegate::GAspectRatioMode &ratioMode) const; + void onQueryFloatOrDoubleViewFormat(const QModelIndex &index, QString &text) const; + void onQueryIndexDataType(const QModelIndex &index, GlodonDefaultItemDelegate::GDataType &dataType) const; + void onCommitDataAndCloseEditor(); + void commitData(QWidget *editor, bool &canCloseEditor); + void closeEditor(QWidget *editor, bool &canCloseEditor, QAbstractItemDelegate::EndEditHint hint = NoHint); + +protected: + /** + * 设置传入的editor中的文本被全选 + * @brief setTextAllSelected + * @param editor + */ + bool setTextAllSelected(QWidget *editor); + /** + * 失去焦点退出编辑状态: 默认值false + * @brief hideEditOnExit + * @return + */ + inline bool closeEditorOnFocusOut() const + { + return m_bCloseEditorOnFocusOut; + } + inline void setCloseEditorOnFocusOut(bool value, bool ignoreActiveWindowFocusReason = false) + { + m_bCloseEditorOnFocusOut = value; + m_bIgnoreActiveWindowFocusReason = ignoreActiveWindowFocusReason; + } + + /*! + * \brief 设置是否使用comboBox的自动提示功能,默认为使用 + * \return + */ + inline bool useComboBoxCompleter() const + { + return m_bUseComboBoxCompleter; + } + inline void setUseComboBoxCompleter(bool value) + { + m_bUseComboBoxCompleter = value; + } + /** + * 选中单元格使用混色 + * @brief useBlendColor + * @return + */ + inline bool useBlendColor() const + { + return m_bUseBlendColor; + } + inline void setUseBlendColor(bool value) + { + m_bUseBlendColor = value; + } + /** + * 选中单元格的背景颜色 + * @brief useBlendColor + * @return + */ + inline QColor selectedCellBackgroundColor() const + { + return m_oSelectedCellBackgroundColor; + } + inline void setSelectedCellBackgroundColor(QColor value) + { + m_oSelectedCellBackgroundColor = value; + } + /** + * @brief 判断tableview是否处于回车跳格状态 + * @param value + */ + inline bool isEnterJump() const + { + return m_enterJump; + } + inline void setIsEnterJump(bool value) + { + m_enterJump = value; + } + + inline bool isEnterJumpPro() const + { + return m_enterJumpPro; + } + inline void setIsEnterJumpPro(bool value) + { + m_enterJumpPro = value; + } + /*! + * \brief setIncludeLeading设置显示文字时是否包含行间距 + * \param value + */ + inline bool isIncludeLeading() const + { + return m_includingLeading; + } + inline void setIncludeLeading(bool value) + { + m_includingLeading = value; + } + /*! + *绘制格子焦点状态 + *@param[in] painter + *@param[in] option + *@param[in] rect + *@return 无 + *@see 参见QItemDelegate::drawFocus(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect) const + */ + virtual void drawFocus(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect) const; + + inline void setCurEditor(QWidget *value) + { + m_curEditor = value; + } + + void drawDisplay(QPainter *painter, const QStyleOptionViewItem &option, + const QRect &rect, const QString &text, const QModelIndex &index) const; + +private: + void paintOther(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const; + void paintDouble(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const; + void paintImg(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const; + void paintBool(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const; + void paintColor(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const; + void paintGType(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index, GDataType type) const; + + bool setTreeViewModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; + bool setDropDownWindowModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; + bool setMonthCalendarModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index, QVariant::Type vType) const; + + QWidget *doCreateEditor(QWidget *parent, + const QStyleOptionViewItem &option, + const QModelIndex &index); + + void createLineEditEditor(QWidget *parent, bool bReadOnly); + void createTreeViewEditor(QWidget *parent, QModelIndex &dIndex, bool bReadOnly); + void createDropDownWindowEditor(QWidget *parent, QModelIndex &dIndex, bool bReadOnly, GEditStyle eEditStyle); + void createMonthCalendarEditor(QWidget *parent, QModelIndex &dIndex, QVariant::Type vType); + void createColorListEditor(QWidget *parent, QModelIndex &dIndex, bool bReadOnly); + void createFontListEditor(QWidget *parent); + void createLineWidthEditor(QModelIndex &dIndex, QWidget *parent); + + template + void createEllipsisEditor(QWidget *parent, QModelIndex &dIndex, bool bReadOnly) + { + T *ellipsis = new T(parent); + + m_curEditor = ellipsis; + + initEllipsisButtonEdit(ellipsis, dIndex); + ellipsis->setEditable(!bReadOnly); + ellipsis->setHasBorder(false); + } + + /** + * @brief esSimple,esUpDown这两种编辑方式创建的都是QSpinBox类似控件 + * @param parent + * @param option + * @param index + * @param vType 数据类型 + * @param isUpDown 是否是增量设置框 + * @param numberRightAlign + * @return + */ + void createSpinBox(QWidget *parent, const QModelIndex &index, const QStyleOptionViewItem &option, + QVariant::Type vType, bool bReadOnly, bool &numberRightAlign); + + + void drawEditStyleDraw(QPainter *painter, QStyleOptionViewItem &option, QRect &rect) const; + /** + * @brief 与QItemDelegate中的drawDisplay一样,去掉了从style中获取margin部分 + * @param painter + * @param option + * @param rect + * @param text + */ + void doDrawDisplay( + QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect, + const QString &text, const QModelIndex &index) const; + /** + * @brief 根据role,画对角线和反对角线 + * @param painter + * @param rect + * @param index + */ + void drawDiagonal(QPainter *painter, const QRect &rect, const QModelIndex &index) const; + + /** + * @brief 根据显示区域行高,计算显示文本的行数 + * @param textRect 显示区域 + */ + int calculateLineCount(const QRect &textRect) const; + + /** + * @brief text不包含换行,根据行高及option处理text,适应显示区域 + * @param[out] textLineCount text显示的行数 + * @param[in] rectLineCount 显示区域能够显示的行数 + * @param[in] textRect 显示区域 + * @param[in] text 显示区域的字串 + * @param[in] option 其它的格式(是否显示...等) + */ + QString elidedText(int &textLineCount, int rectLineCount, const QRect &textRect, const QString &text, const QStyleOptionViewItem &option) const; + /** + * @brief text不包含换行,根据行高及option处理text,适应显示区域 + * @param[in] textRect 显示区域 + * @param[in] text 显示区域的字串 + * @param[in] option 其它的格式(是否显示...等) + */ + QString elidedTextWithoutLineFeed(const QRect &textRect, const QString &text, const QStyleOptionViewItem &option) const; + /** + * @brief text包含换行,根据行高及option处理text,适应显示区域 + * @param[in] textRect 显示区域 + * @param[in] text 显示区域的字串 + * @param[in] option 其它的格式(是否显示...等) + */ + QString elidedTextWithLineFeed(const QRect &textRect, const QString &text, const QStyleOptionViewItem &option) const; + + inline bool checkSetModelData() const + { + return m_checkSetModelData; + } + inline void setCheckSetModelData(bool value) + { + m_checkSetModelData = value; + } + /** + * @brief 根据给定的缩放因子缩放Delegate画TableView的内容时的字体 + * @param index + * @param font + * @param factor + * @return + */ + QFont zoomFont(QModelIndex index, QFont font, double factor) const; + /** + * @brief 给ComboBox增加QCompleter + * @param comboBox + * @param index + */ + void initComboBoxCompleter(QComboBox *comboBox, QModelIndex index); + + /*! + * \brief 根据编辑方式,获取对应编辑方式所占区域 + * \param index + * \param rect + * \return + */ + QRect editStyleRect(QModelIndex index, QRect rect); + bool isInSubControlRect(QModelIndex index, QPoint pos); + void clickSubControl(QModelIndex index); + + void adjustDecorationAlignment(const QModelIndex &index, QStyleOptionViewItem &opt) const; + +private: + bool filterKeyPress(QWidget *editor, QEvent *event); + bool filterReturnKeyPress(QWidget *editor, QKeyEvent *keyEvent); + bool filterRightKeyPress(QWidget *editor, QKeyEvent *keyEvent); + bool filterUpKeyPress(QWidget *editor, QKeyEvent *keyEvent); + // 重构filterKeyPress + void dealWithEscapeKeyPress(QWidget *editor); + bool dealWithTabKeyPress(QWidget *editor); + bool dealWithBackTabPress(QWidget *editor); + template + QVariant compareDataByType(QVariant oldData, T newData) const; + QVariant compareDataByType(QVariant oldData, double newData) const; + // 重构EventFilter + bool dealWithLoseFocus(QEvent *event, QWidget *pEditor); + bool dealWithShortCutOverride(QEvent *event); + + // 重构自动行高 + QRect calcRectByData( + const QStyleOptionViewItem &option, const QModelIndex &index, int role) const; + QRect textRectangle( + const QRect &rect, const QFont &font, const QString &text) const; + + void innerDoLayout( + const QStyleOptionViewItem &option, QRect *checkRect, QRect *pixmapRect, QRect *textRect, + bool hint) const; + void adjustRectByTextMargin(const QModelIndex &index, const QStyleOptionViewItem &opt, bool isIncludeMargin, QRect &rect) const; + +private Q_SLOTS: + void doComboBoxActivated(int index); + +private: + Q_DECLARE_PRIVATE(GlodonDefaultItemDelegate) + + mutable QModelIndex m_currTreeEditing; + QWidget *m_curEditor; + GlodonAbstractItemView *m_pTable; + mutable int m_oComboBoxCurIndex; + static Qt::Alignment s_originalDisplayAlignmentForCurrentItem; //用于保持displayAlignment + double m_factor;//缩放因子 + QEvent *m_closeEditEvent;//导致退出编辑状态的event + + bool m_comboBoxConvenient;//combo立即展开下拉 + bool m_bCloseEditorOnFocusOut; + bool m_inCommitData; + bool m_inSetModelData; //setModelData时不再调用setEditorData,否则会初始化多次 + bool m_checkSetModelData;//setModelData是否成功 + static bool s_digitCurrentItem; + bool m_bUseBlendColor; + bool m_includingLeading; //draw文字时是否包含leading(行距) + bool m_enterJump; + bool m_enterJumpPro; + bool m_isTextEllipse; + bool m_bRepeatCommit; //当开启失去焦点退出编辑状态,通过抛异常的方式校验数据不合法时,会出现重复提交现象 + bool m_bCanHideEidtOnExit; + bool m_bIgnoreActiveWindowFocusReason; + bool m_bUseComboBoxCompleter;//设置是否使用comboBox的自动提示功能 + QTextOption::WrapMode m_wrapMode; + + QColor m_oSelectedCellBackgroundColor; //选择区域的背景颜色 + mutable QVariant m_oDisplayData; + + friend class GlodonAbstractItemView; + friend class GlodonAbstractItemViewPrivate; + friend class GLDTableView; + friend class GLDTableViewPrivate; +}; + +#endif // GLDDEFAULTITEMDELEGATE_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDDefaultItemDelegateFactory.h b/GCR/trunk/Glodon/include/GLD/GLDDefaultItemDelegateFactory.h new file mode 100644 index 00000000..e3dc3212 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDDefaultItemDelegateFactory.h @@ -0,0 +1,22 @@ +#ifndef GLDDEFAULTITEMDELEGATEFACTORY_H +#define GLDDEFAULTITEMDELEGATEFACTORY_H + +#include +#include "GLDTableView_Global.h" + +class GlodonDefaultItemDelegate; + +class GLDTABLEVIEWSHARED_EXPORT GlodonDefaultItemDelegateFactory : public QObject +{ + Q_OBJECT +public: + explicit GlodonDefaultItemDelegateFactory(/*QObject *parent = 0*/); + virtual ~GlodonDefaultItemDelegateFactory(); + virtual GlodonDefaultItemDelegate *createDelegate() = 0; +signals: + +public slots: + +}; + +#endif // GLDDEFAULTITEMDELEGATEFACTORY_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDDes.h b/GCR/trunk/Glodon/include/GLD/GLDDes.h new file mode 100644 index 00000000..c38e09ec --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDDes.h @@ -0,0 +1,48 @@ +#ifndef GLDDES_H +#define GLDDES_H + +#include "GLDCrypt_Global.h" +#include "GLDStream.h" +#include "GLDCrypt_Global.h" + +#pragma pack(push, 1) +struct GDESContext +{ + unsigned long transformedKey[32];/*range 0..31*/ + bool encrypt; +}; + +#pragma pack(pop) + +typedef unsigned char GKey64[8];/*range 0..7*/ +typedef unsigned char GKey128[16];/*range 0..15*/ + +/*3 DES */ +typedef GDESContext GTripleDESContext[2];/*range 0..1*/ + +/*GSP 加密文件头 */ + +struct CGSPEncryptRec +{ + unsigned int version; + byte key[16]; +}; + +/*GSP 处理密钥 */ + +GLDCRYPTSHARED_EXPORT extern const unsigned char c_DefDESKey[16]; + + +GLDCRYPTSHARED_EXPORT unsigned char* DES(const unsigned char* inString, int inSize, GKey64 key64, bool encrypt); + +GLDCRYPTSHARED_EXPORT unsigned char* DESEncrypt(const unsigned char* inString, int inSize, GKey64 key64, bool encrypt); +GLDCRYPTSHARED_EXPORT void DESEncryptStream(GStream *inStream, GStream *outStream, GKey64 key64, bool encrypt); + +GLDCRYPTSHARED_EXPORT unsigned char* tripleDES(unsigned char* inString, int inSize, const GKey128 key128, bool encrypt); + +GLDCRYPTSHARED_EXPORT unsigned char* tripleDESEncrypt(const unsigned char* inString, int inSize, GKey128 key128, bool encrypt); +GLDCRYPTSHARED_EXPORT void tripleDESEncryptStream(GStream *inStream, GStream *outStream, const GKey128 key128, bool encrypt); + +GLDCRYPTSHARED_EXPORT void overlapDES(unsigned char *inString, int inSize, GKey64 key64, bool encrypt); + +#endif // GLDDES_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDDir.h b/GCR/trunk/Glodon/include/GLD/GLDDir.h new file mode 100644 index 00000000..ea47451c --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDDir.h @@ -0,0 +1,8 @@ +#ifndef GLDDIR +#define GLDDIR + +#include +typedef QDir GDir; + +#endif // GLDDIR + diff --git a/GCR/trunk/Glodon/include/GLD/GLDDocView.h b/GCR/trunk/Glodon/include/GLD/GLDDocView.h new file mode 100644 index 00000000..26151fbf --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDDocView.h @@ -0,0 +1,576 @@ +/*! + *@file GLDDocView.h + *@brief {} + *@author duanb + *@date 2013.12.19 + *@remarks {} + *Copyright (c) 1998-2013 Glodon Corporation + */ +#ifndef GLDDOCVIEW_H +#define GLDDOCVIEW_H + +#include +#include +#include +#include +#include +#include + +#include "GLDString.h" +#include "GLDIntList.h" +#include "GLDTreeModel.h" +#include "GLDTableView_p.h" +#include "GLDTableView.h" +#include "GLDPaperWidgetModel.h" +#include "GLDPaperWidget.h" +#include "GLDObjectList.h" +#include "GLDHash.h" +#include "GLDDefaultItemDelegateFactory.h" +#include "GLDAbstractItemModel.h" + +class QVBoxLayout; +class QPrinter; +class QHBoxLayout; + +class GLDDocViewToExcel; +class GLDDocViewTableViewFactory; +class GLDDocView; + +/*! + *@enum: ScrollHint + *@brief {滚动条滚动位置控制} + *@author liurx + *@date 2014.2.27 + */ +enum ScrollHint +{ + shEnsureVisible, + shPositionAtTop, + shPositionAtBottom, + shPositionAtCenter +}; + +typedef GLDList GRectList; + +struct GLDDocInfo +{ +public: + int pageOf(int nValue); + GIntList pageOf(int nValue, const QRect &rc); + +public: + GIntList rowCountPerPageList; + GIntList startRowList; + GRectList pageGeometryInfoList; + + int nPageSplitterHeight; + int nPageCount; +}; + +struct GLDDocFocusInfo +{ + GLDDocFocusInfo(): nFocusRow(-1), nFocusPageNo(-1), nFocusColumn(-1), isInEditing(false) {} + int nFocusRow; + int nFocusPageNo; + int nFocusColumn; + bool isInEditing; +}; + +class GLDTABLEVIEWSHARED_EXPORT GLDScrollArea : public QScrollArea +{ +public: + explicit GLDScrollArea(GLDDocView *parent = 0); + +protected: + bool event(QEvent *); + bool eventFilter(QObject *, QEvent *); + void resizeEvent(QResizeEvent *); +#ifndef QT_NO_WHEELEVENT + void wheelEvent(QWheelEvent *event); +#endif + +private: + GLDDocView *m_parent; +}; + +class GLDTABLEVIEWSHARED_EXPORT GLDBaseWidgetFactory : public QObject +{ + Q_OBJECT +public: + virtual ~GLDBaseWidgetFactory(); + // nPage从1开始,nWidth、nHeight的单位是像素 + virtual QWidget *createHeaderWidget(int nWidth, int nHeight, int nLeftMargin, int nRightMargin, ZoomFactor factor, int nPage, int nPageCount) = 0; + virtual QWidget *createFooterWidget(int nWidth, int nHeight, int nLeftMargin, int nRightMargin, ZoomFactor factor, int nPage, int nPageCount) = 0; +}; + +class GLDTABLEVIEWSHARED_EXPORT GLDDocViewTableViewFactory : public QObject +{ + Q_OBJECT +public: + virtual ~GLDDocViewTableViewFactory(); + virtual GlodonPaperTableView *createTableView(QWidget *parent) = 0; +}; + +class GLDTABLEVIEWSHARED_EXPORT GLDDocView : public QWidget +{ + Q_OBJECT +public: + explicit GLDDocView(QWidget *parent = 0, Qt::WindowFlags f = 0); + virtual ~GLDDocView(); + +public: + void setModel(QAbstractItemModel *model); + QAbstractItemModel *dataModel(); + + ZoomFactor factor() const; + void setFactor(const ZoomFactor &value); + + virtual QSize sizeHint() const; + + int pageCount() const; + + void print(); + void printPreview(); + void exportToPdf(); + /** + * @brief 直接导出pdf而不带有预览效果 + * @param 外部传进来文件路径+文件名 + */ + void exportToPdf(QString fileName); + + void fistPage(); + void lastPage(); + void prevPage(); + void nextPage(); + + void gotoPage(int value); // 从0开始 + + int footerHeight() const; // 单位是像素 + void setFooterHeight(int footerHeight); // 单位是mm + + int headerHeight() const; // 单位是像素 + void setHeaderHeight(int headerHeight); // 单位是mm + + int tableViewHorizontalHeaderHeight() const; // 单位是像素 + void setTableViewHorizontalHeaderHeight(int tableViewHorizontalHeaderHeight); // 单位是mm + + int leftMargin() const; // 单位是像素 + void setLeftMargin(int leftMargin); + + int rightMargin() const; // 单位是像素 + void setRightMargin(int rightMargin); // 单位是mm + + /** + * @brief 返回当前的QModelIndex,行和列对应的是在dataModel中的 + * @return + */ + QModelIndex currentIndex() + { + return m_currentIndex; + } + + /** + * @brief 把PaperWidgetModel中对应的QModelIndex转成dataModel中的QModelIndex + * @param pageNo index所在的页 + * @param index paperWidgetModel对应的QModelIndex + * @return + */ + QModelIndex dataIndex(int pageNo, const QModelIndex &index); + inline QModelIndex dataIndex(const QModelIndex &tableViewIndex) + { + return dataIndex(curPageNo(tableViewIndex), tableViewIndex); + } + + void registerWidgetFactory(GLDBaseWidgetFactory *factory); + GLDBaseWidgetFactory *registeredWidgetFactory() const; + + void registerDelegateFactory(GlodonDefaultItemDelegateFactory *factory); + GlodonDefaultItemDelegateFactory *registeredDelegateFactory() const; + + int curPageNo(); + int curFocusPageNo(); + + bool removePageAt(int nPage); + bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); + bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()); + bool appendRows(int count, const QModelIndex &parent = QModelIndex()); + + void setColumnWidth(int column, int size); // size单位是mm + void setColumnWidthPixel(int column, int size); //单位是像素 + int columnWidth(int column); // 单位是像素 + int columnCount() const; + + GIntList fitColWidths() const; + void setFitColWidths(const GIntList &fitColWidths); + + bool hasFitColumn() const; + + /** + * @brief 设置当前的焦点 + * @param dataIndex + */ + void setCurrentIndex(QModelIndex dataIndex); + /** + * @brief 设置格子进入编辑状态 + * @param dataIndex + */ + void setIndexEdit(QModelIndex dataIndex); + void reLayoutPaperWidget(); + + int paperWidth() const; + void setPaperWidth(int value); + + int paperHeight() const; + void setPaperHeight(int value); + + void setBackgroundPalette(QPalette palette); + + GlodonHeaderView::ResizeMode resizeMode() const; + void setResizeMode(const GlodonHeaderView::ResizeMode &resizeMode); + + bool allowZoom() const; + void setAllowZoom(bool bAllowZoom); + + int rowPosition(QModelIndex dataIndex); + int columnPosition(QModelIndex dataIndex); + /** + * @brief 根据dataIndex,返回该格子的全局绘制位置 + * @param dataIndex + * @return + */ + QRect visualRect(const QModelIndex dataIndex); + void scrollTo(QModelIndex dataIndex, ScrollHint hint = shEnsureVisible); + QQueue &paperWidgetList(); + + + /** + * @brief 刷新一列 + * @param col + */ + void updateCol(QModelIndex dataIndex); + + /** + * @brief 刷新一行 + * @param row + */ + void updateRow(QModelIndex dataIndex); + + /** + * @brief 刷新整个tableView + */ + void updateAll(); + + /** + * @brief 刷新焦点处的控件 + */ + void updateFocusWidget(); + + /** + * @brief 设置表头是否为多行表头,需要在分页之前调用 + * @param value + */ + void setMutilHeaderView(bool value, Qt::Orientation orientation = Qt::Horizontal); + bool isMutilHeaderViewEnable() const ; + + QScrollArea *scrollArea(); + + int cellHeight() const; + void setCellHeight(int cellHeight); + + bool suitRowHeight() const; + void setSuitRowHeight(bool suitRowHeight); + + void registerTableViewFactory(GLDDocViewTableViewFactory *tableViewFactory); + + /** + * @brief 设置允许通过格线调整行高列宽, 需要在分页之前调用 + * @param value + */ + void setAllowToResize(bool value); + bool allowToResize() const; + + /** + * @brief 获取当前正在处于编辑状态的index + * @return 返回的是dataIndex + */ + QModelIndex editingIndex(); + + /** + * @brief 强制关闭当前的编辑状态 + */ + void forceCloseEditor(); + + void setShowHorizontalHeaderView(bool value); + bool isShowHorizontalHeaderView(); + + void setDrawFrameLine(bool value); + bool drawFrameLine(); + + void setShowVerticalLine(bool value); + bool isShowVerticalLine(); + + void setShowHorizontalLine(bool value); + bool isShowHorizontalLine(); + + void setGridLineWidth(int value); + int gridLineWidth(); + + /*! + * \brief 设置打印方向 + * \param oritation + */ + void setPrintOrientation(QPrinter::Orientation oritation); + QPrinter::Orientation printOrientation(); + + + /*! + *设置给定逻辑列的隐藏状态 + *@param[in] column 逻辑列号 + *@param[in] hide true表示隐藏,false表示显示 + *@return 无 + */ + void setColumnHidden(int column, bool hide); + bool columnHidden(int column) const; + bool hasColumnHidden() const; + + QMap &columnsVisableState(); + + void handleKeyDownEvent(QEvent *event, QKeyEvent *keyEvent, GlodonTableView *currentTableView); + + void initTableView(GlodonTableView *pTableView, GLDPaperWidget *pPaperWidget, int nPageNo); + + QModelIndex indexAt(QPoint pos); + + + QModelIndexList selectedIndexes(); + + int curPageNo(const QModelIndex ¤tIndex) const; + + int dataIndexPageNo(QModelIndex dataIndex); + + QModelIndex index(QModelIndex dataIndex); + + void updateModelIndex(QModelIndex dataIndex); + +public slots: + void calculatePages(); + +Q_SIGNALS: + void currPageChanged(int nPage); + void currentFocusChanged(const QModelIndex &previous, + const QModelIndex ¤t); + void focusToNextRow(const QModelIndex &oldIndex, + const QModelIndex &newIndex, + bool &canMove); + void onbeforeMoveCursor(const QModelIndex &oldDataIndex, + const QModelIndex &newDataIndex, + QItemSelectionModel::SelectionFlags &command, + MoveReason moveReason, bool &canMove); + + void onKeyPress(const QModelIndex &index, QKeyEvent &keyEvent, bool &handled); + void onCommitEditor(const QModelIndex &index, QVariant& data, bool &commit); + void onQueryIndexDataType(const QModelIndex &index, GlodonDefaultItemDelegate::GDataType &dataType) const; + void onMousePress(const QModelIndex &index, QPoint globalPos, QMouseEvent *mousePressEvent, bool &handled); + void onMouseButtonDblClick(const QModelIndex &index, QPoint globalPos, QMouseEvent *mousePressEvent, bool &handled); + void onRangeFill(const QModelIndexList &srcModelIndexList, + const QModelIndexList &destModelIndexList, + int srcRowCount, + int srcColumnCount, + bool &handled); + +protected: + +#ifndef QT_NO_WHEELEVENT + virtual void wheelEvent(QWheelEvent *); +#endif + + virtual void resizeEvent(QResizeEvent *); + + void customEvent(QEvent *event); + bool eventFilter(QObject *object, QEvent *event); + + bool keyPressEventFilter(QObject *object, QKeyEvent *keyEvent); + bool mousePressEventFilter(QObject *object, QMouseEvent *pMouseEvent); + + bool onKeyUp(GlodonTableView *tableView, QKeyEvent *keyEvent); + bool onKeyDown(GlodonTableView *tableView, QKeyEvent *keyEvent); + bool onKeyPress(GlodonTableView *tableView, QKeyEvent *keyEvent); + bool onKeyPageUp(GlodonTableView *tableView, QKeyEvent *keyEvent); + bool onKeyPageDown(GlodonTableView *tableView, QKeyEvent *keyEvent); + +private: + double colWidthRate(int col) const; + double zoomFactorAsDouble() const; + + GLDPaperWidget *editingPaper(); + GLDPaperWidget *findPaper(QModelIndex& tableViewIndex); + GLDPaperWidget *findPaper(int nPageNo, bool createIfNotFound = false); + GLDPaperWidget *newPaper(int nPageNo); + + bool paperVisible(int nPageNo); + bool hasPager(int nPageNo); + int indexPaper(int nPageNo); + void removePaper(int nPageNo); + + void printPage(int index, QPainter &painter); + void printPage(int index, QPainter &painter, QPrinter *printer); + + int verticalPosition(const QModelIndex& tableViewIndex); + int horizontalPosition(const QModelIndex& tableViewIndex); + + int paperVerticalPosition(const QModelIndex &tableViewIndex); + int paperHorizontalPosition(const QModelIndex& tableViewIndex); + + int rowHeight(const QModelIndex &tableViewIndex); + + void initScrollArea(); + void updateScrollArea(); + + void updateVisablePapersList(); + + void updatePaperLayout(int nVpos, int nHpos, const QRect &rc); + int updateLeftLayout(int nHpos, const QRect &rc, GLDPaperWidget *pPaperWidget); + int updateRightLayout(int nHpos, const QRect &rc, GLDPaperWidget *pPaperWidget); + int updatePageLayout(int nHpos, const QRect &rc, GLDPaperWidget *pPaperWidget); + + void recoverFocusState(); + + void hidePapersOutOfView(); + + void updatePapers(); + void cacheNewPapers(); + bool isPaperCacheFull(); + void clearPaperCache(); + void clearPagers(); + void clearOtherIndex(); + void prepareLoadPages(); + + void calculatePageCount(); + void calculatePageGeometryInfo(); + void calculatePageWidth(); + void calculatePageHeight(); + + void setInitPageWidth(int value); + void setInitPageHeight(int value); + + void initPageGeometry(); + + void setPaperColumnWidth(int column, int size); + + GLDDocInfo &docInfo(); + QAbstractItemModel *model() const; + +private slots: + void verticalScrollBarValueChanged(int value); + void horizontalScrollBarValueChanged(int value); + + void postUpdatePaperEvent(); + + void printDocument(QPrinter *printer, QPrintDialog *printDialog); + void printDocument(QPrinter *printer); + void printALLDocument(QPrinter *printer); + + void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); + void onCurrentFocusChanged(const QModelIndex ¤t, const QModelIndex &previous); + void onAfterCurrentFocusChanged(const QModelIndex ¤t, const QModelIndex &previous); + + void onbeforeMoveCurrent(const QModelIndex &oldIndex, + const QModelIndex &newIndex, + QItemSelectionModel::SelectionFlags &command, + MoveReason moveReason, + bool &canMove); + + void onTableViewRangeFill(QModelIndexList src, + QModelIndexList dest, + int rowCount, + int columnCount, + bool &handled); + + void doNewWidthsToPapers(GIntList *widths); + void enableFitColWidths(bool enable); + + void commitEditor(const QModelIndex &index, QVariant data, bool &commit); + void queryIndexDataType(const QModelIndex &index, GlodonDefaultItemDelegate::GDataType &dataType); + +private: + bool m_allowToResize; + bool m_allowZoom; + bool m_isHorizontalMutilHeaderView; + bool m_isInClearOtherIndex; + bool m_isInManualControlScrollBar; + bool m_suitRowHeight; + + GIntList m_fitColWidths; + GLDBaseWidgetFactory *m_headerAndFooterWidgetFactory; + GLDDocFocusInfo m_docFocusInfo; + GLDDocInfo m_docInfo; + GLDDocViewTableViewFactory *m_tableViewFactory; + GIntList m_visiblePageNoList; + GlodonDefaultItemDelegateFactory *m_delegateFactory; + GlodonHeaderView::ResizeMode m_resizeMode; + GlodonTreeModel *m_treeModel; + + int m_nCellHeight; + + int m_nFooterHeight; + int m_nHeaderHeight; + + int m_nLeftMargin; + int m_nRightMargin; + + int m_nCurFocusPageNo; // 从0开始 + int m_nCurPageNo; // 从0开始 + + int m_nPageWidth; + int m_nPageHeight; + + int m_nCurrentDPI; // 需要同步设备DPI + int m_nSettedWidthsSum; + int m_nPageSplitterHeight; + int m_nTableViewHHeaderHeight; + + QAbstractItemModel *m_dataModel; + QAbstractItemModel *m_model; + + QModelIndex m_currentIndex; + QModelIndex m_preIndex; + + QQueue m_papers; + QScrollArea *m_scrollArea; + QVector m_colWidth; + ZoomFactor m_zoomFactor; + QMap columnsVisableMap; + +private: + bool m_bDrawFrameLine; + bool m_bShowHHeaderView; + + bool m_bHorzLine; //显示水平格线 + bool m_bVertLine; //显示垂直格线 + + double m_dInitPageWidth; // 单位为毫米 + double m_dInitPageHeight; + + double m_dInitFooterHeight; + double m_dInitHeaderHeight; + + double m_dInitLeftMargin; + double m_dInitRightMargin; + + int m_nGridLineWidth; + int m_nInitMaxPageNo; + int m_nInitPageLabelFontSize; + int m_nInitPageSplitterHeight; + int m_nInitTableViewHHeaderHeight; + + QPrinter::Orientation m_printerOrientation; + + friend class GLDPaperWidgetModel; + friend class GLDScrollArea; + friend class GLDPaperWidget; + friend class GLDDocViewToExcel; +}; + +extern const GString c_GLDDocView_HHeader; + +#endif // GLDDOCVIEW_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDDockContainer.h b/GCR/trunk/Glodon/include/GLD/GLDDockContainer.h new file mode 100644 index 00000000..152635da --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDDockContainer.h @@ -0,0 +1,244 @@ +#ifndef GLDDOCKCONTAINER_H +#define GLDDOCKCONTAINER_H + +#include +#include +#include +#include + +#include "GLDString.h" +#include "GLDWidget_Global.h" + +class GLDDockContainerTitleButton; +class GLDDockContainerTitleBar; +class GLDDockContainer; +class GLDDockContainerTabBar; + +//GLDDockContainerTitleBar +class GLDWIDGETSHARED_EXPORT GLDDockContainerTitleBar : public QWidget +{ + Q_OBJECT +public: + GLDDockContainerTitleBar(const GString &title, QWidget *parent); + virtual ~GLDDockContainerTitleBar(); + void init(); + + void setCloseBtnVisible(bool bShow); + +protected: + void paintEvent(QPaintEvent *evente); + void resizeEvent(QResizeEvent *event); + QSize sizeHint() const; + QSize minimumSizeHint() const; + GLDDockContainerTitleButton *fixButton() ; + GLDDockContainerTitleButton *closeButton() ; + GString title(); + +private: + void alignBtns(bool isCloseBtnShow = true); + +private: + bool m_showCloseBtn; + GString m_title; + GLDDockContainerTitleButton *m_fixedBtn; + GLDDockContainerTitleButton *m_closeBtn; + friend class GLDDockContainer; +}; + +//GLDDockContainerImageTitleBar +class GLDWIDGETSHARED_EXPORT GLDDockContainerImageTitleBar : public GLDDockContainerTitleBar +{ + Q_OBJECT +public: + GLDDockContainerImageTitleBar(const GString &title, QWidget *parent); + virtual ~GLDDockContainerImageTitleBar(); + + void setCustomTitlePixmap(const QPixmap &leftPm,const QPixmap ¢erPm, + const QPixmap &rightPm); + void setUseCustomPixmap(bool used); + + void setTextColor(const QColor &textColor); + void setTextAlignment(Qt::Alignment alignment); + void setTextMargins(const QMargins &margins); + + QColor textColor() const; + Qt::Alignment textAlignment() const; + QMargins textMargins() const; + +protected: + void paintEvent(QPaintEvent *event); + void mousePressEvent(QMouseEvent *event); + +protected: + QColor m_textColor;//(0,0,0) + QPixmap m_leftPm, m_centerPm, m_rightPm; + bool m_useCustomPixmap;//false; + Qt::Alignment m_textAlignment;//vcenter,hleft + QMargins m_textMargins;//top:1,bottom : 1, left : 30,right : 30 + friend class GLDDockContainer; +}; + +//GLDDockContainerTitleButton +class GLDWIDGETSHARED_EXPORT GLDDockContainerTitleButton : public QAbstractButton +{ + Q_OBJECT + +public: + GLDDockContainerTitleButton(QWidget *dockWidget); + + inline QIcon dockIcon() { return m_dockIcon; } + inline void setNormIcon(QIcon value) { m_icon = value; } //泊靠时图标 + inline void setDockIcon(QIcon value) { m_dockIcon = value; } //泊靠时图标 + void setInDock(bool value); + QSize sizeHint() const; + inline QSize minimumSizeHint() const + { return sizeHint(); } + + void enterEvent(QEvent *event); + void leaveEvent(QEvent *event); + void paintEvent(QPaintEvent *event); + +private: + QIcon m_dockIcon; + QIcon m_icon; +}; + +//GLDDockContainerTabBar +class GLDWIDGETSHARED_EXPORT GLDDockContainerTabBar : public QTabBar +{ + Q_OBJECT +public: + explicit GLDDockContainerTabBar(QWidget *parent = 0); + GLDDockContainerTabBar(QString title,QWidget *parent = 0); + + void setTabsClosable(bool closable); + GString title() const; + Qt::Orientation textOrientation(); + void setTextOrientation(Qt::Orientation orient); + +Q_SIGNALS: + void clicked(); + +protected: + void paintEvent(QPaintEvent *event); + void mousePressEvent(QMouseEvent *event); + void initStyleOption(QStyleOptionTab *option, int tabIndex) const; + //转换为垂直的字符串 + GString verticalString(const GString &str); + +protected: + GString m_title; + +private: + bool m_inResize; + Qt::Orientation m_textOrientation; +}; + +//GLDDockContainerImageTabBar +class GLDWIDGETSHARED_EXPORT GLDDockContainerImageTabBar : public GLDDockContainerTabBar +{ + Q_OBJECT +public: + explicit GLDDockContainerImageTabBar(QString title, QWidget *parent = 0); + void setCustomTitlePixmap(const QPixmap &leftPm,const QPixmap ¢erPm, + const QPixmap &rightPm); + void setUseCustomPixmap(bool used); + + void setSize(const QSize &size); + void setTextColor(const QColor &textColor); + void setTextMargins(const QMargins &margins); + void setTextAlignment(Qt::Alignment alignment); + + QSize size() const; + QColor textColor() const; + QMargins textMargins() const; + Qt::Alignment textAlignment() const; + +public: + virtual QSize sizeHint() const; + +protected: + virtual void paintEvent(QPaintEvent *event); + QString verticalTitle(); + +protected: + QPixmap m_leftPm; + QPixmap m_centerPm; + QPixmap m_rightPm; + bool m_usePixmap;//false + QString m_title; + QSize m_size; + QColor m_textColor;//Black + Qt::Alignment m_textAlignment; //hCenter,vTop; + QMargins m_textMargins;//top:10,bottom:10,left:1,right 1; +}; + +class GLDWIDGETSHARED_EXPORT GLDDockContainer : public QWidget +{ + Q_OBJECT +public: + explicit GLDDockContainer(const GString &title, QWidget *parent = 0, bool bWest = true); + ~GLDDockContainer(); + +public: + void addDockWidget(QWidget *w); + void setCloseBtnVisible(bool value); + void setTabsCloseAble(bool value); + void setTitleBar(GLDDockContainerTitleBar *titleBar); + void setTabBar(GLDDockContainerTabBar *tabBar); + /*设置固定按钮图标*/ + QIcon fixedIcon(); + void setFixedIcon(QIcon &icon); + /*设置固定按钮在泊靠状态下的图标*/ + void setFixedDockIcon(QIcon &icon); + /** + ** tab control 字体方向 + **/ + Qt::Orientation tabTextOrientation(); + void setTabTextOrientation(Qt::Orientation orient); + /*设置关闭按钮图标*/ + QIcon closeIcon(); + void setCloseIcon(QIcon &icon); + inline void setMinDockWidth(int value) { m_minWidth = value; } + +protected: + void initStyleOption(QStyleOptionDockWidget *option) const; + void doShow(); + void alignWidgets(bool bNeedRemove = true); + void alignSplitter(); + void reInitTitleBar(); + void reInitTabBar(); + +protected: + void paintEvent(QPaintEvent *event); + bool eventFilter(QObject *obj, QEvent *event); + bool event(QEvent *event); + QSize sizeHint() const; + QSize minimumSizeHint() const; + + void doHideContainer(); + void doShowContainer(); + void doAddToSplitter(); + +protected slots: + void doFixedClick(); + void doClickBar(); + void doShowFrame(bool bHideBar = true); + +private: + GLDDockContainerTitleBar *m_titleBar; + QGridLayout *m_gridLayout; + QWidget *m_dockWidget; + GLDDockContainerTabBar *m_tabBar; + QSize m_preSize; + QSize m_fullSize; //包含tabBar和DockContainer,即鼠标悬浮在tabBar上面时应有的大小 + bool m_fixedFrame; + bool m_barAtLeft; + QMargins *m_oldMargin; + int m_indexAtSplitter; + QWidget *m_preParent; + GString m_title; + int m_minWidth; +}; + +#endif // GLDDOCKCONTAINER_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDDockPanel/GLDDockCommon.h b/GCR/trunk/Glodon/include/GLD/GLDDockPanel/GLDDockCommon.h new file mode 100644 index 00000000..d5452905 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDDockPanel/GLDDockCommon.h @@ -0,0 +1,18 @@ +#ifndef GLDDockCOMMON_H +#define GLDDockCOMMON_H + +enum DockArea +{ + NoneArea = 0, + LeftArea = 1, + TopArea = 1 << 2, + RightArea = 1 << 3, + BottomArea = 1 << 4, + CenterArea = 1 << 5, + CenterLeftArea = 1 << 6, + CenterTopArea = 1 << 7, + CenterRightArea = 1 << 8, + CenterBottomArea = 1 << 9 +}; + +#endif // GLDDockCOMMON_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDDockPanel/GLDDockFrame.h b/GCR/trunk/Glodon/include/GLD/GLDDockPanel/GLDDockFrame.h new file mode 100644 index 00000000..6ad38604 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDDockPanel/GLDDockFrame.h @@ -0,0 +1,46 @@ +#ifndef GLDDockFRAME_H +#define GLDDockFRAME_H + +#include +#include "GLDDockCommon.h" +#include + +class GLDDockPanel; +class GLDDockNode; +class GLDDockMaskWidget; +class GLDDockManager; +class GLDDockArrows; + +class GLDDockFrame : public QWidget +{ + Q_OBJECT + +public: + explicit GLDDockFrame(GLDDockManager *manager, QWidget *parent); + virtual ~GLDDockFrame(); + void showArrow(); + + void relayout(); +protected: + virtual void dragEnterEvent(QDragEnterEvent *); + virtual void dragMoveEvent(QDragMoveEvent *); + virtual void dragLeaveEvent(QDragLeaveEvent *); + virtual void dropEvent(QDropEvent *); + virtual void resizeEvent(QResizeEvent *); + +private: + GLDDockArrows *m_pArrows; + GLDDockNode *rootNode_; + GLDDockMaskWidget *maskWidget_; + std::map dockPanels_; + GLDDockManager *manager_; + + DockArea lastMaskArea_; +private: + void onDragEnterPanel(); + void onDragLeavePanel(); + void onEndDragAtPanel(); + friend class GLDDockManager; +}; + +#endif // GLDDockFRAME_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDDockPanel/GLDDockManager.h b/GCR/trunk/Glodon/include/GLD/GLDDockPanel/GLDDockManager.h new file mode 100644 index 00000000..08ba45ff --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDDockPanel/GLDDockManager.h @@ -0,0 +1,50 @@ +#ifndef GLDDockMANAGER_H +#define GLDDockMANAGER_H + +#include +#include +#include "GLDDockCommon.h" +#include "GLDDockFrame.h" +#include "GLDWidget_Global.h" + +class GLDDockNode; + +class GLDWIDGETSHARED_EXPORT GLDDockManager : public QObject +{ + friend class GLDDockPanel; + friend class GLDDockFrame; + + Q_OBJECT + +public: + GLDDockManager(QWidget *parent); + ~GLDDockManager(); + + GLDDockFrame *getDockFrame() + { + return dockFrmae_; + } + GLDDockPanel *addPanel(int id, const QString &title, QPoint pos, QSize size, QWidget *contensWidget = NULL); + GLDDockPanel *getDockPanelByID(int id); + +public slots: + bool dockPanelToFrame(GLDDockPanel *panel, DockArea area); + bool dockPanelToPanel(GLDDockPanel *from, GLDDockPanel *target, DockArea area); + +public: + bool isRootNode(GLDDockNode *node); + + void undockPanel(GLDDockPanel *panel); + +private: + void onDragEnterPanel(); + void onDragLeavePanel(); + void onEndDragAtPanel(); + bool dockPanelToFloatPanel(GLDDockPanel *from, GLDDockPanel *target, DockArea area); + bool dockPanelToDockedPanel(GLDDockPanel *from, GLDDockPanel *target, DockArea area); +private: + GLDDockFrame *dockFrmae_; + std::map dockPanels_; +}; + +#endif // GLDDockMANAGER_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDDockWidget.h b/GCR/trunk/Glodon/include/GLD/GLDDockWidget.h new file mode 100644 index 00000000..468fa4bf --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDDockWidget.h @@ -0,0 +1,55 @@ +#ifndef GLDDOCKWIDGET_H +#define GLDDOCKWIDGET_H + +#include +#include +#include +#include +#include +#include +#include "GLDWidget_Global.h" + +class GLDWIDGETSHARED_EXPORT GLDDockWidget : public QDockWidget +{ + Q_OBJECT +public: + explicit GLDDockWidget(const QString &title, QWidget *parent = 0, Qt::WindowFlags flags = 0); + +signals: + +public: + QAction *addAction(const QIcon & icon, const QString & text); + QAction *addWidget(QWidget *widget); + void setIcon(const QIcon &icon); + + void setPressPosOnTab(const QPoint &pos); + void setReleasePosOnTab(const QPoint &pos); + +protected: + void resizeEvent(QResizeEvent *); + void mouseReleaseEvent(QMouseEvent *event); + void leaveEvent(QEvent *event); +private slots: + void allowedAreasChanged(Qt::DockWidgetAreas); + void featuresChanged(QDockWidget::DockWidgetFeatures); + void dockLocationChanged(Qt::DockWidgetArea); + void topLevelChanged(bool); + void visibilityChanged(bool); + + void onFloat(); + void onLock(); + void onClose(); + +private: + void initTitleBar(); + +private: + QToolBar *m_titleBar; + QLabel *m_title; + QAction *m_actTitle; + QAction *m_actClose; + QAction *m_actLock; + QAction *m_actFloat; +}; + +#endif // GLDDOCKWIDGET_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDDrawSymbol.h b/GCR/trunk/Glodon/include/GLD/GLDDrawSymbol.h new file mode 100644 index 00000000..7e87af36 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDDrawSymbol.h @@ -0,0 +1,300 @@ +#ifndef GLDDRAWSYMBOL_H +#define GLDDRAWSYMBOL_H +#include +#include +#include +#include "GLDString.h" +#include "GLDObjectList.h" +#include "GLDStrUtils.h" +#include "GLDTableView_Global.h" + +struct GlodonDiameterSymbolRec +{ + GString symbol; + GString resourceName; +}; + +struct GlodonSymbolPos +{ + int pos; + int symbolPosIndex; +}; + +const GString c_MeterSymbol = "m"; + +const GString c_SquareSymbol = "2"; +const GString c_CubeSymbol = "3"; + +const GString c_SquareReplace = TRANS_STRING("弍");//这两个字符是为了替换m2,m3做标识用,不用翻译 +const GString c_CubeReplace = TRANS_STRING("弎"); +const GString c_SharpReplace = "#"; + +const GString c_SuperSymbol = "3"; +const double c_SuperScale = 0.5; +const double c_SharpScale = 0.7; + +#ifndef _FONTSYMBOL_ + #ifdef __APPLE__ + const GlodonDiameterSymbolRec c_DiameterSymbols [] = + { + {TRANS_STRING("Φ16"), "SDIABFE"}, + {TRANS_STRING("Φ15"), "SDIAEEE"}, + {TRANS_STRING("Φ13"), "SDIABE"}, + {TRANS_STRING("Φ14"), "SDIACE"}, + {TRANS_STRING("Φ17"), "SDIACFE"}, + {TRANS_STRING("Φ18"), "SDIAEFE"}, + {TRANS_STRING("ΦA"), "SDIAA"}, + {TRANS_STRING("ΦB"), "SDIAB"}, + {TRANS_STRING("Φ2"), "SDIABF"}, + {TRANS_STRING("ΦC"), "SDIAC"}, + {TRANS_STRING("Φ3"), "SDIACF"}, + {TRANS_STRING("ΦD"), "SDIAD"}, + {TRANS_STRING("ΦE"), "SDIAE"}, + {TRANS_STRING("Φ5"), "SDIAEF"}, + {TRANS_STRING("ΦG"), "SDIAG"}, + {TRANS_STRING("ΦL"), "SDIAL"}, + {TRANS_STRING("ΦN"), "SDIAN"}, + {TRANS_STRING("ΦY"), "SDIAY"} + }; + #else + const GlodonDiameterSymbolRec c_DiameterSymbols [] = + { + {GString::fromLocal8Bit("Φ16"), "SDIABFE"}, + {GString::fromLocal8Bit("Φ15"), "SDIAEEE"}, + {GString::fromLocal8Bit("Φ13"), "SDIABE"}, + {GString::fromLocal8Bit("Φ14"), "SDIACE"}, + {GString::fromLocal8Bit("Φ17"), "SDIACFE"}, + {GString::fromLocal8Bit("Φ18"), "SDIAEFE"}, + {GString::fromLocal8Bit("ΦA"), "SDIAA"}, + {GString::fromLocal8Bit("ΦB"), "SDIAB"}, + {GString::fromLocal8Bit("Φ2"), "SDIABF"}, + {GString::fromLocal8Bit("ΦC"), "SDIAC"}, + {GString::fromLocal8Bit("Φ3"), "SDIACF"}, + {GString::fromLocal8Bit("ΦD"), "SDIAD"}, + {GString::fromLocal8Bit("ΦE"), "SDIAE"}, + {GString::fromLocal8Bit("Φ5"), "SDIAEF"}, + {GString::fromLocal8Bit("ΦG"), "SDIAG"}, + {GString::fromLocal8Bit("ΦL"), "SDIAL"}, + {GString::fromLocal8Bit("ΦN"), "SDIAN"}, + {GString::fromLocal8Bit("ΦY"), "SDIAY"} + }; + #endif +#else + #ifdef __APPLE__ + const GlodonDiameterSymbolRec c_DiameterSymbols [] = + { + {TRANS_STRING("Φ16"), TRANS_STRING("")}, + {TRANS_STRING("Φ15"), TRANS_STRING("")}, + {TRANS_STRING("Φ13"), TRANS_STRING("")}, + {TRANS_STRING("Φ14"), TRANS_STRING("")}, + {TRANS_STRING("Φ17"), TRANS_STRING("")}, + {TRANS_STRING("Φ18"), TRANS_STRING("")}, + {TRANS_STRING("ΦA"), TRANS_STRING("")}, + {TRANS_STRING("ΦB"), TRANS_STRING("")}, + {TRANS_STRING("Φ2"), TRANS_STRING("")}, + {TRANS_STRING("ΦC"), TRANS_STRING("")}, + {TRANS_STRING("Φ3"), TRANS_STRING("")}, + {TRANS_STRING("ΦD"), TRANS_STRING("")}, + {TRANS_STRING("ΦE"), TRANS_STRING("")}, + {TRANS_STRING("Φ5"), TRANS_STRING("")}, + {TRANS_STRING("ΦG"), TRANS_STRING("")}, + {TRANS_STRING("ΦL"), TRANS_STRING("")}, + {TRANS_STRING("ΦN"), TRANS_STRING("")}, + {TRANS_STRING("ΦY"), TRANS_STRING("")} + }; + #else + const GlodonDiameterSymbolRec c_DiameterSymbols [] = + { + {GString::fromLocal8Bit("Φ16"), GString::fromLocal8Bit("")}, + {GString::fromLocal8Bit("Φ15"), GString::fromLocal8Bit("")}, + {GString::fromLocal8Bit("Φ13"), GString::fromLocal8Bit("")}, + {GString::fromLocal8Bit("Φ14"), GString::fromLocal8Bit("")}, + {GString::fromLocal8Bit("Φ17"), GString::fromLocal8Bit("")}, + {GString::fromLocal8Bit("Φ18"), GString::fromLocal8Bit("")}, + {GString::fromLocal8Bit("ΦA"), GString::fromLocal8Bit("")}, + {GString::fromLocal8Bit("ΦB"), GString::fromLocal8Bit("")}, + {GString::fromLocal8Bit("Φ2"), GString::fromLocal8Bit("")}, + {GString::fromLocal8Bit("ΦC"), GString::fromLocal8Bit("")}, + {GString::fromLocal8Bit("Φ3"), GString::fromLocal8Bit("")}, + {GString::fromLocal8Bit("ΦD"), GString::fromLocal8Bit("")}, + {GString::fromLocal8Bit("ΦE"), GString::fromLocal8Bit("")}, + {GString::fromLocal8Bit("Φ5"), GString::fromLocal8Bit("")}, + {GString::fromLocal8Bit("ΦG"), GString::fromLocal8Bit("")}, + {GString::fromLocal8Bit("ΦL"), GString::fromLocal8Bit("")}, + {GString::fromLocal8Bit("ΦN"), GString::fromLocal8Bit("")}, + {GString::fromLocal8Bit("ΦY"), GString::fromLocal8Bit("")} + }; + #endif +#endif + +class GlodonCustomDrawSymbol; +class GlodonMeterDrawSymbol; +class GlodonDiaDrawSymbol; +class GlodonCustomDrawSymbolFactory; +class GlodonMeterDrawSymbolFactory; +class GlodonDiaDrawSymbolFactory; + +class GlodonCustomDrawSymbolFactory +{ +public: + virtual ~GlodonCustomDrawSymbolFactory() = 0; + + virtual GlodonCustomDrawSymbol* create() = 0; +}; + +class GlodonMeterDrawSymbolFactory : public GlodonCustomDrawSymbolFactory +{ +public: + virtual ~GlodonMeterDrawSymbolFactory() = 0; + GlodonCustomDrawSymbol* create(); +}; + +class GlodonDiaDrawSymbolFactory : public GlodonCustomDrawSymbolFactory +{ +public: + virtual ~GlodonDiaDrawSymbolFactory() = 0; + GlodonCustomDrawSymbol* create(); +}; + +class GLDTABLEVIEWSHARED_EXPORT GlodonCustomDrawSymbol +{ +public: + GlodonCustomDrawSymbol(QObject *parent = 0); + bool virtual canHandle(const QString &text) = 0; + +protected: + virtual void drawText(QPainter *painter, int scale, const QString &text, Qt::Alignment align, QRect &rect) = 0; +}; + +class GlodonDrawSymbolManager +{ +public: + GlodonDrawSymbolManager(); + ~GlodonDrawSymbolManager(); + +public: + int indexOfDrawSymbolClass(const QString &text); + void addDrawSymbol(); + + void drawText(QPainter *painter, int scale, const QString &text, Qt::Alignment align, QRect &rect, bool &handle); +}; + +class GLDTABLEVIEWSHARED_EXPORT GlodonMeterDrawSymbol : public GlodonCustomDrawSymbol +{ +public: + bool canHandle(const QString &text); +protected: + /** + * @brief 计算在指定宽度下能输出字串的长度,同时返回实际占用的宽度 + * @param painter + * @param text + * @param width + * @param height + * @return + */ + int calcDrawLineLength(QPainter *painter, const QString &text, int &width); + /** + * @brief 计算在制定范围内能输出的字串的长度 + * @param painter + * @param text + * @param width + * @param height + * @return + */ + int calcDrawTextLength(QPainter *painter, const QString &text, int width, int height); + int calcM2M3Length(QPainter *painter); + +public: + void drawText(QPainter *painter, int scale, const QString &text, Qt::Alignment align, QRect &rect); + +private: + bool isTextM2M3(const QString &text); + bool isTextSharp(const QString &text); + QString replaceSymbolText(const QString &text); + void drawLine(QPainter *painter, const QString &text, int x, int y, int &width, int &height); + void drawM2M3(QPainter *painter, int x, int y, const QString & symbol); + void drawSharp(QPainter *painter, int x, int y, const QString &symbol); + void interDrawText(QPainter *painter, const QString &text, Qt::Alignment align, int x, int y, int width, int &height); +}; + +class GLDTABLEVIEWSHARED_EXPORT GlodonDiaDrawSymbol : public GlodonCustomDrawSymbol +{ +public: + bool canHandle(const QString &text); + +public: + void draw(QPainter *painter, int scale, const QString &text, Qt::Alignment align, QRect &rect); + void drawText(QPainter *painter, int scale, const QString &text, Qt::Alignment align, QRect &rect); + +private: + void draw1Symbol(QPainter *painter, int scale, const QString &text, Qt::Alignment align, QRect &rect, int index); + void drawBitMap(QPainter *painter, int scale, Qt::Alignment align, QRect &rect, int index); + void innerDrawText(QPainter *painter, Qt::Alignment align, QRect &rect, const QString &text); + int getContentWidth(QPainter *painter, int scale, const QString &text); + int getContentHeight(QPainter *painter, int scale, const QString &text); +}; + +// function DrawSymbolManager TDrawSymbolManager; + +GLDTABLEVIEWSHARED_EXPORT bool includeM2M3(const QString &text); +GLDTABLEVIEWSHARED_EXPORT void drawTextMx(QPainter *painter, const QString &text, Qt::Alignment align, QRect &rect); +GLDTABLEVIEWSHARED_EXPORT bool includeSharp(const QString &text); +GLDTABLEVIEWSHARED_EXPORT bool includeDiaSymbol(const QString &text); + +GLDTABLEVIEWSHARED_EXPORT void drawDiaSymbol(QPainter *painter, int scale, const QString &text, Qt::Alignment align, QRect &rect); +GObjectList *createIndexOfDiameterSymbolList(const QString &text); +GLDTABLEVIEWSHARED_EXPORT bool compare(GlodonSymbolPos *item1, GlodonSymbolPos *item2); + +/** + * @brief The GlodonSymbols class 钢筋符号类 + */ + +#ifdef _FONTSYMBOL_ +class GLDTABLEVIEWSHARED_EXPORT GlodonSymbols +{ +public: + GlodonSymbols(); + ~GlodonSymbols(){} + +public: + /** + * @brief aliasFromDisplaySymbol 如果displaySymbol属于钢筋符号库,则返回其别名,否则返回displaySymbol + * @param displaySymbol + * @return + */ + QString aliasFromDisplaySymbol(const QString &displaySymbol); + /** + * @brief displaySymbolFromGiveSymbol 如果alias属于钢筋符号库,择返回用于显示的钢筋符号字符串,否则返回alias + * @param giveSymbol + * @return + */ + QString displaySymbolFromAlias(const QString &alias); + + /** + * @brief allSymbols 返回所有的钢筋符号 + * @return QMap QMap中第一个参数为钢筋符号别名,同GlodonDiameterSymbolRec结构体中的symbol + * QMap中第二个参数为钢筋符号的显示字符串, 主要用于显示 + */ + QMap allSymbols() const; + + /** + * @brief aliasesFromDisplaySymbols 从显示的钢筋符号串(多个钢筋符号)转为别名符号串(多个) + * @param displaySymbols + * @return + */ + QString aliasesFromDisplaySymbols(const QString &displaySymbols); + + /** + * @brief displaySymbolsFromAliases 从别名符号串(多个)转为显示的钢筋符号串(多个) + * @param aliases + * @return + */ + QString displaySymbolsFromAliases(const QString &aliases); + +private: + void initSymbols(const GlodonDiameterSymbolRec array[], size_t size); + QMap m_symbols; // 钢筋符号列表, 第一个参数为钢筋符号别名,后一个参数为需要显示的钢筋符号 +}; +#endif + +#endif // GLDDRAWSYMBOL_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDEllipsis.h b/GCR/trunk/Glodon/include/GLD/GLDEllipsis.h new file mode 100644 index 00000000..e1c9715e --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDEllipsis.h @@ -0,0 +1,188 @@ +#ifndef GLDELLIPSIS_H +#define GLDELLIPSIS_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "GLDWidget_Global.h" + +const int c_MinButtonEditBtnWidth = 18; + +class GLDWIDGETSHARED_EXPORT GLDAbstractButtonEdit: public QWidget +{ + Q_OBJECT + +public: + GLDAbstractButtonEdit(QWidget *parent); + virtual ~GLDAbstractButtonEdit(); + + virtual QString text() const = 0; + virtual void setText(QString text) = 0; + + QString buttonCaption() const; + void setButtonCaption(QString caption); + + QModelIndex modelIndex() const; + void setModelIndex(QModelIndex newIndex); + + virtual void setEditable(bool canEdit) = 0; + virtual bool selectAll() = 0; + virtual bool cursorPosInsertANewLine(bool addANewLine = true) = 0; + virtual bool cursorMoveTextEnd() = 0; + virtual QMargins contentsMargins() const = 0; + virtual void setContentsMargins(const QMargins &rhs) const = 0; + virtual void setHasBorder(bool) {} + +public Q_SLOTS: + void onEllipsisButtonClicked(); + +//protected Q_SLOTS: +// bool event(QEvent *e); + +Q_SIGNALS: + void ellipsisButtonClicked(); + void ellipsisButtonClicked(const QModelIndex &index); + +protected: + QPushButton *m_button; + QModelIndex index; +}; + +class GLDWIDGETSHARED_EXPORT GLDPlainButtonEdit : public GLDAbstractButtonEdit +{ + Q_OBJECT + Q_PROPERTY(bool readOnly READ isReadOnly) + Q_PROPERTY(bool hasSelectedText READ hasSelectedText) +public: + GLDPlainButtonEdit(QWidget *parent); + virtual ~GLDPlainButtonEdit(); + + void paintEvent(QPaintEvent *); + + QString text() const; + void setText(QString text); + void setEditable(bool canEdit); + bool eventFilter(QObject *, QEvent *); + bool selectAll(); + bool cursorPosInsertANewLine(bool addANewLine = true); + bool cursorMoveTextEnd(); + QMargins contentsMargins() const; + void setContentsMargins(const QMargins &rhs) const; + void setFont(const QFont &font); + + inline bool hasSelectedText(){ return m_hasSelectedText; } + inline bool isReadOnly(){ return m_plainTextEdit->isReadOnly(); } + +public slots: + void cut(); + void paste(); + void copy(); + void deleteSelectedText(); + +signals: + void copyAvailable(bool yes); + +private slots: + void onCopyAvailable(bool yes); + +protected: + QPlainTextEdit *m_plainTextEdit; + +private: + bool m_hasSelectedText; +}; + +class GLDWIDGETSHARED_EXPORT GLDEllipsisLineEdit : public QLineEdit +{ + Q_OBJECT +public: + explicit GLDEllipsisLineEdit(QWidget *parent = 0); + + void closeCopy(); + void openCopy(); + void closePaste(); + void openPaste(); + void keyPressEvent(QKeyEvent *e); + +private: + bool m_closePaste; + bool m_closeCopy; +}; + +class GLDWIDGETSHARED_EXPORT GLDLineButtonEdit : public GLDAbstractButtonEdit +{ + Q_OBJECT + Q_PROPERTY(bool readOnly READ isReadOnly) + Q_PROPERTY(bool hasSelectedText READ hasSelectedText) +public: + GLDLineButtonEdit(QWidget *parent, QLineEdit *editor = NULL); + virtual ~GLDLineButtonEdit(); + + void paintEvent(QPaintEvent *); + + QString text() const; + void setText(QString text); + void setEditable(bool canEdit); + bool eventFilter(QObject *, QEvent *); + bool selectAll(); + bool cursorPosInsertANewLine(bool addANewLine = true); + bool cursorMoveTextEnd(); + virtual QMargins contentsMargins() const; + void setContentsMargins(const QMargins &rhs) const; + void setFont(const QFont &font); + + inline bool hasSelectedText(){ return m_lineEdit->hasSelectedText(); } + + inline bool isReadOnly(){ return m_lineEdit->isReadOnly(); } + inline QLineEdit* lineEdit() { return m_lineEdit; } + + void closeCopy(); + void openCopy(); + void closePaste(); + void openPaste(); +public slots: + void cut(); + void paste(); + void copy(); + void deleteSelectedText(); + +signals: + void selectionChanged(); + void cursorPositionChanged(); + +private slots: + void doSelectionChanged(); + void doCursorPositionChanged(int, int); + +protected: + QLineEdit *m_lineEdit; +}; + +class GLDWIDGETSHARED_EXPORT GLDLineButtonEditEx: public GLDLineButtonEdit +{ +public: + GLDLineButtonEditEx(QWidget *parent = 0, QLineEdit *editor = NULL); + ~GLDLineButtonEditEx(); + +public: + void paintEvent(QPaintEvent *e); + virtual void setHasBorder(bool enable = true); +}; + +class GLDWIDGETSHARED_EXPORT GLDPlainButtonEditEx : public GLDPlainButtonEdit +{ +public: + GLDPlainButtonEditEx(QWidget *parent = 0); + ~GLDPlainButtonEditEx(); + +public: + void paintEvent(QPaintEvent *e); + virtual void setHasBorder(bool bHasBorder = true); +}; + +#endif // GLDELLIPSIS_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDEnum.h b/GCR/trunk/Glodon/include/GLD/GLDEnum.h new file mode 100644 index 00000000..2098bfe2 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDEnum.h @@ -0,0 +1,68 @@ +#ifndef GLDENUM +#define GLDENUM + +enum GLDValueRelationship +{ + gvrLessThanValue = -1, + gvrEqualsValue = 0, + gvrGreaterThanValue = 1 +}; + +// TableView.ItemDelegate选项 +enum GEditStyle +{ + esNone, // 不能编辑 + esSimple, // 默认编辑框,根据数据类型创建编辑方式 + esPlainEdit, // 多行编辑框 + esLineEdit, // 单行编辑框 + esPlainEllipsis, // 省略号按钮 + esLineEllipsis, // 省略号按钮,单行编辑 + esMultiButton, // 多个按钮 + esBool, // 布尔类型的格子 + esMonthCalendar, // 日期选择框 + esImage, // 图片 + esVectorGraph, // 矢量图 + esFontList, // 字体选择框 + esColorList, // 颜色选择列表 + esLineWidthList, // 线框选择列表 + esUpDown, // 增量设置框 + esDropDown, // 下拉选择框 + esTreeView, // 树形框 + esDropDownWindow, // 下拉的浮动窗体 + esDropDownWindowEllipsis, // 下拉的浮动窗体, button的样式为三个点 + esDropDownWindowNone // 下拉的浮动窗体, 不显示button +}; + +// GridSetting选项 +enum GLDGridSettingEditStyle +{ + gesAuto, + gesEdit, + gesDropDownList, + gesDropDown, + gesEllipsisReadOnly, + gesEllipsis, + gesDateTimePicker, + gesTreeView, + gesCheckBox, + gesDropDownWindowReadOnly, + gesSpin, + gesDropDownWindow, + gesLineEdit +}; + +enum FontStyle +{ + fsBold = 0x01, + fsItalic = 0x02, + fsUnderline = 0x04, + fsStrikeOut = 0x08 +}; + +//MoveCurrent的原因 +enum MoveReason { mrKey, mrMouse, mrMouseWheel, mrProgram }; + +typedef GLDGridSettingEditStyle GLDEditStyle; + +#endif // GLDENUM + diff --git a/GCR/trunk/Glodon/include/GLD/GLDEvent.h b/GCR/trunk/Glodon/include/GLD/GLDEvent.h new file mode 100644 index 00000000..31ba8edd --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDEvent.h @@ -0,0 +1,100 @@ +#ifndef GLDEVENT_H +#define GLDEVENT_H + +#include +#include +#include "GLDSystem.h" +#include "GLDGlobal.h" + +const unsigned short c_GM_BASE = 2000; + +enum GLDEventType +{ + GM_BASE = c_GM_BASE, + GM_PREV = c_GM_BASE + 0, // 上一行 + GM_NEXT = c_GM_BASE + 1, // 下一行 + GM_FIRST = c_GM_BASE + 2, // 首行 + GM_Last = c_GM_BASE + 3, // 末行 + GM_MOVEUP = c_GM_BASE + 4, // 上移一行 + GM_MOVEDOWN = c_GM_BASE + 5, // 下移一行 + GM_MOVELEFT = c_GM_BASE + 6, // 左移一列 + GM_MOVERIGHT = c_GM_BASE + 7, // 右移一列 + GM_INSERTCOL = c_GM_BASE + 8, // 插入一列 + GM_DELETECOL = c_GM_BASE + 9, // 删除一列 + GM_INSERTROW = c_GM_BASE + 10, // 插入一行 + GM_DELETEROW = c_GM_BASE + 11, // 删除一行 + GM_DUPLICATEROW = c_GM_BASE + 12, // 复制一行 + GM_ZAP = c_GM_BASE + 13, // 删除所有行 + GM_EXPAND = c_GM_BASE + 14, // 展开 + GM_COLLAPSE = c_GM_BASE + 15, // 折叠 + GM_EXPANDALL = c_GM_BASE + 16, // 展开全部 + GM_COLLAPSEALL = c_GM_BASE + 17, // 折叠全部 + GM_LEVELUP = c_GM_BASE + 18, // 级别上移 + GM_LEVELDOWN = c_GM_BASE + 19, // 级别下移 + GM_SETCOLROW = c_GM_BASE + 20, // 设置行列 + GM_SETSEL = c_GM_BASE + 21, // 全选 + GM_CUT = c_GM_BASE + 22, // 剪切 + GM_COPY = c_GM_BASE + 23, // 复制 + GM_PASTE = c_GM_BASE + 24, // 粘贴 + GM_CLEAR = c_GM_BASE + 25, // 删除 + GM_PASTEASCHILD = c_GM_BASE + 26, // 作为子粘贴 + + GM_QUERYPREV = c_GM_BASE + 50, // 允许上一行 + GM_QUERYNEXT = c_GM_BASE + 51, // 允许下一行 + GM_QUERYFIRST = c_GM_BASE + 52, // 允许首行 + GM_QUERYLAST = c_GM_BASE + 53, // 允许末行 + GM_QUERYMOVEUP = c_GM_BASE + 54, // 允许上移一行 + GM_QUERYMOVEDOWN = c_GM_BASE + 55, // 允许下移一行 + GM_QUERYMOVELEFT = c_GM_BASE + 56, // 允许左移一列 + GM_QUERYMOVERIGHT = c_GM_BASE + 57, // 允许右移一列 + GM_QUERYINSERTCOL = c_GM_BASE + 58, // 允许插入一列 + GM_QUERYDELETECOL = c_GM_BASE + 59, // 允许删除一列 + GM_QUERYINSERTROW = c_GM_BASE + 60, // 允许插入一行 + GM_QUERYDELETEROW = c_GM_BASE + 61, // 允许删除一行 + GM_QUERYDUPLICATEROW = c_GM_BASE + 62, // 允许复制一行 + GM_QUERYZAP = c_GM_BASE + 63, // 允许删除所有行 + GM_QUERYEXPAND = c_GM_BASE + 64, // 允许展开 + GM_QUERYCOLLAPSE = c_GM_BASE + 65, // 允许折叠 + GM_QUERYEXPANDALL = c_GM_BASE + 66, // 允许展开全部 + GM_QUERYCOLLAPSEALL = c_GM_BASE + 67, // 允许折叠全部 + GM_QUERYLEVELUP = c_GM_BASE + 68, // 允许级别上移 + GM_QUERYLEVELDOWN = c_GM_BASE + 69, // 允许级别下移 + GM_QUERYLESETCOLROW = c_GM_BASE + 70, // 允许设置行列 + GM_QUERYSETSEL = c_GM_BASE + 71, // 允许全选 + GM_QUERYCUT = c_GM_BASE + 72, // 允许剪切 + GM_QUERYCOPY = c_GM_BASE + 73, // 允许复制 + GM_QUERYPASTE = c_GM_BASE + 74, // 允许粘贴 + GM_QUERYCLEAR = c_GM_BASE + 75, // 允许删除 + GM_QUERYPASTEASCHILD = c_GM_BASE + 76, // 允许作为子粘贴 + GM_DELAYSETRECORD = c_GM_BASE + 77, // 延迟设置当前record + + GM_SetScrollBarStep = c_GM_BASE + 101, + GM_DocViewCalculatePage = c_GM_BASE + 102, + + GM_GSPBASE = c_GM_BASE + 1000, + GM_GTPBASE = c_GM_BASE + 1500, + GM_APPBASE = c_GM_BASE + 2000 +}; + +typedef PtrInt GLDWParam; +typedef PtrInt GLDLParam; +typedef PtrInt GLDEventResult; + +class GLDCOMMONSHARED_EXPORT GLDEvent : public QEvent +{ +public: + GLDEvent(GLDEventType type, GLDWParam wParam = 0, GLDLParam lParam = 0); + + GLDWParam wParam() const; + GLDWParam lParam() const; + + GLDEventType type() const; + GLDEventResult result() const; + void setResult(GLDEventResult value); +private: + GLDWParam m_wParam; + GLDLParam m_lParam; + GLDEventResult m_result; +}; + +#endif // GLDEVENT_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDExcelGridIntf.h b/GCR/trunk/Glodon/include/GLD/GLDExcelGridIntf.h new file mode 100644 index 00000000..6f4574ec --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDExcelGridIntf.h @@ -0,0 +1,91 @@ +#ifndef GLDEXCELGRIDINTF_H +#define GLDEXCELGRIDINTF_H + +#include "GLDString.h" +#include "GLDVariant.h" +#include "GLDComptr.h" +#include "GLDUnknwn.h" + +interface IGEGExcelGrid; +interface IGEGRecordIterator; +interface IGEGFieldIterator; +interface IGEGRecord; +interface IGEGField; + +enum GEGDataType +{ + GEGdtEmply, + GEGdtNumber, + GEGdtString, + GEGdtBool, + GEGdtBlank, + GEGdtError +}; + +struct GEGValue +{ + GVariant value; + GEGDataType type; +}; + +// GEGExcelGrid 接口 +DEFINE_IID(IGEGExcelGrid, "{A0AC57BF-112A-4859-A900-1CA7A497AED7}"); +DECLARE_INTERFACE_(IGEGExcelGrid, IUnknown) +{ + GLDMETHOD(IGEGRecordIterator *, recordIterator)() PURE; + GLDMETHOD(IGEGFieldIterator *, fieldIterator)() PURE; + GLDMETHOD(IGEGRecordIterator *, createRecordIterator)() PURE; + GLDMETHOD(IGEGFieldIterator *, createFieldIterator)() PURE; +}; + +// GEGRecordIterator 接口 +DEFINE_IID(IGEGRecordIterator, "{9983BCDD-0F29-421E-AD3C-34F7B600A417}"); +DECLARE_INTERFACE_(IGEGRecordIterator, IUnknown) +{ + GLDMETHOD(void, first)() PURE; + GLDMETHOD(void, next)() PURE; + GLDMETHOD(void, prev)() PURE; + GLDMETHOD(void, last)() PURE; + GLDMETHOD(IGEGRecord *, current)() PURE; + GLDMETHOD(bool, isDone)() PURE; +}; + +// GEGFieldIterator 接口 +DEFINE_IID(IGEGFieldIterator, "{590DEA04-4469-46E6-92FD-58A0E5E62297}"); +DECLARE_INTERFACE_(IGEGFieldIterator, IUnknown) +{ + GLDMETHOD(void, first)() PURE; + GLDMETHOD(void, next)() PURE; + GLDMETHOD(void, prev)() PURE; + GLDMETHOD(void, last)() PURE; + GLDMETHOD(IGEGField *, current)() PURE; + GLDMETHOD(bool, isDone)() PURE; +}; + +// GEGRecord 接口 +DEFINE_IID(IGEGRecord, "{ECCB0561-7E07-4DE1-B5E1-5B45F8777135}"); +DECLARE_INTERFACE_(IGEGRecord, IUnknown) +{ + GLDMETHOD(GString, code)() PURE; + GLDMETHOD(void, setCode)(const GString &value) PURE; + GLDMETHOD(bool, isChecked)() PURE; + GLDMETHOD(void, setIsChecked)(bool isChecked) PURE; + GLDMETHOD(GEGValue, fullValues)(const GString &fieldName) PURE; + GLDMETHOD(bool, addValues)(const GString &fieldName, const GEGValue &value) PURE; + GLDMETHOD(int, excelRowNo)() PURE; + GLDMETHOD(void, setExcelRowNo)(int rowNo) PURE; +}; + +// GEGField 接口 +DEFINE_IID(IGEGField, "{550359AA-838C-4572-A8CC-12EB1E41F6A1}"); +DECLARE_INTERFACE_(IGEGField, IUnknown) +{ + GLDMETHOD(GString, code)() PURE; + GLDMETHOD(GEGDataType, dataType)() PURE; + GLDMETHOD(void, setCode)(const GString &code) PURE; + GLDMETHOD(void, setDataType)(GEGDataType type) PURE; + GLDMETHOD(GString, name)() PURE; + GLDMETHOD(void, setName)(const GString &name) PURE; +}; + +#endif // GLDEXCELGRIDINTF_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDExcelGridIterator.h b/GCR/trunk/Glodon/include/GLD/GLDExcelGridIterator.h new file mode 100644 index 00000000..0e3b31cb --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDExcelGridIterator.h @@ -0,0 +1,458 @@ +#ifndef GLDEXCELGRIDITERATOR_H +#define GLDEXCELGRIDITERATOR_H + +#include +#include +#include "GLDExcelGridIntf.h" +#include "GLDString.h" +#include "GLDStringList.h" +#include "GLDXLSModel.h" +#include "GLDObjectList.h" + +#include "GLDComptr.h" +#include "GLDUnknwn.h" +#include "GLDObject.h" +#include "GLDTableView_Global.h" + +static const int c_IS_EXPORT_COLNO = 0; // 是否导出标志所在列 +static const int c_ROW_METCHED_RESULT_COLNO = 1; // 行匹配结果所在的列 +static const int c_COL_METCHED_RESULT_ROWNO = 0; // 列匹配结果所在的行 + +static const int c_DATA_BEGIN_ROWNO = c_COL_METCHED_RESULT_ROWNO + 2; +static const int c_DATA_BEGIN_COLNO = c_ROW_METCHED_RESULT_COLNO + 1; + +static const int c_titleRow = 1; + +static const int c_IndexCol = c_ROW_METCHED_RESULT_COLNO + 1; //序号列 + +class CGEGFieldIterator; +class CGEGRecordIterator; +class CGEGField; +class CGEGRecord; +class GEGExcelModel; +class GEGRecord; +class GEGField; +class GEGRecordIterator; +class GEGFieldIterator; + +class GLDTABLEVIEWSHARED_EXPORT GEGExcelRowIdentityChangeEvent +{ +public: + virtual void onRowIdentityChanged(int row, const GString &oldValue, GString &newValue) = 0; +}; + +class GLDTABLEVIEWSHARED_EXPORT GEGExcelColIdentityChangeEvent +{ +public: + virtual void onColIdentityChanged(int col, const GString &oldValue, GString &newValue) = 0; +}; + +class GLDTABLEVIEWSHARED_EXPORT GEGExcelRowIdentityChangeEventList : public GLDVector +{ +public: + void doEvent(int row, const GString &oldValue, GString &newValue); +}; + +class GLDTABLEVIEWSHARED_EXPORT GEGExcelColIdentityChangeEventList : public GLDVector +{ +public: + void doEvent(int col, const GString &oldValue, GString &newValue); +}; + +class GLDTABLEVIEWSHARED_EXPORT GLDXLSQueryCellAttributeEvent +{ +public: + virtual ~GLDXLSQueryCellAttributeEvent() {} + + virtual void onQueryCellXLSAttribute(GString &sheetName, int row, int col, + int role, GVariant &attribute, bool &handled) = 0; +}; + +class GLDTABLEVIEWSHARED_EXPORT GLDXLSQueryCellAttributeEventList : public GLDVector +{ +public: + bool doEvent(GString &sheetName, int row, int col, + int role, GVariant &attribute) const; +}; + +class GLDTABLEVIEWSHARED_EXPORT GEGExcelGrid : public GComPtr +{ +public: + inline GEGExcelGrid(): GComPtr(){} + inline GEGExcelGrid(IGEGExcelGrid *lp) : GComPtr(lp){} +public: + IGEGRecordIterator *recordIterator(); + IGEGFieldIterator *fieldIterator(); + IGEGRecordIterator *createRecordIterator(); + IGEGFieldIterator *createFieldIterator(); +}; + +class GLDTABLEVIEWSHARED_EXPORT CGEGExcelGrid : public GInterfaceObject, public IGEGExcelGrid +{ +public: + CGEGExcelGrid(GEGExcelModel *model); + ~CGEGExcelGrid(); +public: + DECLARE_IUNKNOWN + IGEGRecordIterator * GLDMETHODCALLTYPE recordIterator(); + IGEGFieldIterator * GLDMETHODCALLTYPE fieldIterator(); + IGEGRecordIterator * GLDMETHODCALLTYPE createRecordIterator(); + IGEGFieldIterator * GLDMETHODCALLTYPE createFieldIterator(); +protected: + HRESULT STDMETHODCALLTYPE _QueryInterface(REFIID riid, void **ppvObject); +private: + CGEGRecordIterator *m_recordIterator; + CGEGFieldIterator *m_fieldIterator; + GEGExcelModel *m_xlsModel; +}; + +// GEGRecordIterator +class GLDTABLEVIEWSHARED_EXPORT GEGRecordIterator : public GComPtr +{ +public: + inline GEGRecordIterator() : GComPtr(){} + inline GEGRecordIterator(IGEGRecordIterator *lp) : GComPtr(lp){} +public: + void first(); + void next(); + void prev(); + void last(); + IGEGRecord *current(); + bool isDone(); +}; + +class GLDTABLEVIEWSHARED_EXPORT CGEGRecordIterator : public GInterfaceObject, public IGEGRecordIterator +{ +public: + CGEGRecordIterator(GEGExcelModel *model); + ~CGEGRecordIterator() {} + +public: + DECLARE_IUNKNOWN + void GLDMETHODCALLTYPE first(); + void GLDMETHODCALLTYPE next(); + void GLDMETHODCALLTYPE prev(); + void GLDMETHODCALLTYPE last(); + IGEGRecord * GLDMETHODCALLTYPE current(); + bool GLDMETHODCALLTYPE isDone(); +protected: + HRESULT STDMETHODCALLTYPE _QueryInterface(REFIID riid, void **ppvObject); +private: + void loadItems(); +private: + GObjectList m_recordList; // todo linw ref + int m_currentIndex; + GEGExcelModel *m_model; +}; + +// GEGFieldIterator 接口 +class GLDTABLEVIEWSHARED_EXPORT GEGFieldIterator : public GComPtr +{ +public: + inline GEGFieldIterator(): GComPtr(){} + inline GEGFieldIterator(IGEGFieldIterator *lp): GComPtr(lp){} +public: + void first(); + void next(); + void prev(); + void last(); + IGEGField *current(); + bool isDone(); +}; + +class GLDTABLEVIEWSHARED_EXPORT CGEGFieldIterator : public GInterfaceObject, public IGEGFieldIterator +{ +public: + CGEGFieldIterator(GEGExcelModel *model); + ~CGEGFieldIterator(); +public: + DECLARE_IUNKNOWN + void GLDMETHODCALLTYPE first(); + void GLDMETHODCALLTYPE next(); + void GLDMETHODCALLTYPE prev(); + void GLDMETHODCALLTYPE last(); + IGEGField * GLDMETHODCALLTYPE current(); + bool GLDMETHODCALLTYPE isDone(); +protected: + HRESULT STDMETHODCALLTYPE _QueryInterface(REFIID riid, void **ppvObject); +private: + void loadItems(); +private: + GObjectList m_fieldList; // todo linw ref + int m_currentIndex; + GEGExcelModel *m_model; +}; + +class GLDTABLEVIEWSHARED_EXPORT GEGRecord : public GComPtr +{ +public: + inline GEGRecord(): GComPtr(){} + inline GEGRecord(IGEGRecord *lp): GComPtr(lp){} +public: + inline GString code() { return p->code(); } + inline void setCode(const GString &value) { p->setCode(value); } + inline bool isChecked() { return p->isChecked(); } + inline void setIsChecked(bool isChecked) { p->setIsChecked(isChecked); } + GEGValue fullValues(const GString &fieldName); + bool addValues(const GString &fieldName, const GEGValue &value); + inline int excelRowNo() { return p->excelRowNo(); } + inline void setExcelRowNo(int rowNo) { p->setExcelRowNo(rowNo); } +}; + +class GLDTABLEVIEWSHARED_EXPORT CGEGRecord : public GInterfaceObject, public IGEGRecord +{ +public: + CGEGRecord(); + ~CGEGRecord() {} + +public: + DECLARE_IUNKNOWN + inline GString GLDMETHODCALLTYPE code() { return m_code; } + inline void GLDMETHODCALLTYPE setCode(const GString &value) { m_code = value; } + inline bool GLDMETHODCALLTYPE isChecked() { return m_isChecked; } + inline void GLDMETHODCALLTYPE setIsChecked(bool isChecked) { m_isChecked = isChecked; } + GEGValue GLDMETHODCALLTYPE fullValues(const GString &fieldName); + bool GLDMETHODCALLTYPE addValues(const GString &fieldName, const GEGValue &value); + int GLDMETHODCALLTYPE excelRowNo() { return m_excelRowNo; } + + void GLDMETHODCALLTYPE setExcelRowNo(int rowNo) { m_excelRowNo = rowNo; } + +protected: + HRESULT STDMETHODCALLTYPE _QueryInterface(REFIID riid, void **ppvObject); +private: + QHash m_values; + GString m_code; + bool m_isChecked; + int m_excelRowNo; +}; + +class GLDTABLEVIEWSHARED_EXPORT GEGField : public GComPtr +{ +public: + inline GEGField() : GComPtr(){} + inline GEGField(IGEGField *lp) : GComPtr(lp){} +public: + inline GString code() { return p->code(); } + inline GEGDataType dataType() { return p->dataType(); } + inline void setCode(const GString &code) { p->setCode(code); } + inline void setDataType(GEGDataType type) { p->setDataType(type); } + inline GString name() { return p->name(); } + inline void setName(const GString &name) { p->setName(name); } +}; + +class GLDTABLEVIEWSHARED_EXPORT CGEGField : public GInterfaceObject, public IGEGField +{ +public: + CGEGField(); + ~CGEGField() {} + +public: + DECLARE_IUNKNOWN + inline GString GLDMETHODCALLTYPE code() { return m_code; } + inline GEGDataType GLDMETHODCALLTYPE dataType() { return m_dataType; } + inline void GLDMETHODCALLTYPE setCode(const GString &code) { m_code = code; } + inline void GLDMETHODCALLTYPE setDataType(GEGDataType type) { m_dataType = type; } + inline GString GLDMETHODCALLTYPE name() { return m_name; } + inline void GLDMETHODCALLTYPE setName(const GString &name) { m_name = name; } +protected: + HRESULT STDMETHODCALLTYPE _QueryInterface(REFIID riid, void **ppvObject); +private: + GString m_code; + GVariant m_value; + GEGDataType m_dataType; + GString m_name; +}; + +class GLDTABLEVIEWSHARED_EXPORT GEGRule +{ +public: + GEGRule(GEGExcelModel *model); + virtual ~GEGRule(); +public: + inline GString identity() { return m_identity; } + inline void setIdentity(const GString &value) { m_identity = value; } + inline bool visible() { return m_visible; } + inline void setVisible(bool value) { m_visible = value; } + inline int tag() { return m_tag; } + inline void setTag(int value) { m_tag = value; } + inline GEGExcelModel *model() { return m_owner; } + virtual void compile() {} + +private: + GEGExcelModel *m_owner; + GString m_identity; + bool m_visible; + int m_tag; +}; + +class GLDTABLEVIEWSHARED_EXPORT GEGColRule : public GEGRule +{ +public: + GEGColRule(GEGExcelModel *model); + virtual ~GEGColRule(); +public: + virtual bool macthKeyWord(const GString &value); + bool match(int col, bool force); + void clear(); + void reset(); + bool isMatched(); + inline GStringList keyWords() { return m_keyWords; } + inline int matchCol() { return m_matchCol; } + inline void setMatchCol(int col) { m_matchCol = col; } + inline GEGDataType dataType() { return m_dataType; } + inline void setDataType(GEGDataType type) { m_dataType = type; } + inline GString name() { return m_name; } + inline void setName(const GString &name) { m_name = name; } + virtual void compile(); +protected: + virtual bool doMatch(int col, bool force); +private: +// void writeColIdentity(); + void buildTokens(); +private: + GStringList m_keyWords; + GObjectList m_tokens; + int m_matchCol; + GEGDataType m_dataType; + GString m_name; +}; + +class GLDTABLEVIEWSHARED_EXPORT GEGRowRule : public GEGRule +{ +public: + GEGRowRule(GEGExcelModel *model); + virtual ~GEGRowRule(); +public: + bool match(int row, bool force); + void clear(int row); +protected: + virtual bool doMatch(int row, bool force); + bool excuteRegExpr(const GString ®Expr, const GString &inputStr); + GString asString(int row, int col); + GString asString(GEGColRule *colRule, int row); + GString asString(const GString &identity, int row); + bool asBool(int row, int col); + int asInt(int row, int col); + double asDouble(int row, int col); +private: + void writeRowIdentity(int row); +private: + QRegExp *m_regExpr; +}; + +class GLDTABLEVIEWSHARED_EXPORT GEGExcelModel : public GlodonXLSModel +{ + Q_OBJECT +public: + GEGExcelModel(QObject *parent = 0); + ~GEGExcelModel(); +public: + GEGColRule *addColRule(); + void addColRule(GEGColRule *rule); + GEGColRule *addColRule(const GString &identity, const GLDVector keywords); + GEGColRule *addColRule(const GString &identity); + GEGRowRule *addRowRule(); + void addRowRule(GEGRowRule *rule); + GEGColRule *findColRule(const GString &identity); + GEGRowRule *findRowRule(const GString &identity); + inline int colRuleCount() { return m_colRules.count(); } + GEGColRule *colRule(int index); + inline int rowRuleCount() { return m_rowRules.count(); } + GEGRowRule *rowRule(int index); + void clearColRules(); + void clearRowRules(); + + inline void clearMatchedRow() { m_rowIdentityHash.clear(); } + inline void clearMatchedCol() { m_colIdentityHash.clear(); } + + inline GLDXLSQueryCellAttributeEventList &queryCellXLSAttributeEventList() { return m_queryCellXLSAttributeEventList; } +public: + void setActive(bool value); + QModelIndex getPrevUnmatchedRow(QModelIndex &index); + QModelIndex getNextUnmatchedRow(QModelIndex &index); + bool inIsExportCol(const QModelIndex &index) const; + bool inRowMatchedResultCol(const QModelIndex &index) const; + bool inColMatchedResultRow(const QModelIndex &index) const; + bool inIndexCol(const QModelIndex &index) const; + bool inTitleRow(const QModelIndex &index) const; + + void addRowIdentity(int row, GString &identity); + void addColIdentity(int col, GString &identity); + void setRowCheckData(int row); + void setAllRowsCheckData(bool value); + void setRowCheck(int row, bool check); + + void removeRowIdentity(int row); + void removeColIdentity(int col); + + bool colIsIdentity(int col, GString &identity); + bool rowIsIdentity(int row, GString &identity); + bool rowIsChecked(int row); + + int getColWidth(int col);//tableView的列 + int getRowHeight(int row);//tableView的行 +public: + void autoMatchCol(); + void autoMatchRow(); + void autoMatch(); + + inline bool allowAutoMatch() { return m_allowAutoMatch; } + inline void setAllowAutoMatch(bool value) { m_allowAutoMatch = value; } + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); +public: + GString asString(int dataRow, int dataCol); + GString asString(GEGColRule *rule, int dataRow); + GString asString(const GString &name, int dataRow); + bool asBool(int dataRow, int dataCol); + int asInteger(int dataRow, int dataCol); + double asDouble(int dataRow, int dataCol); + GEGDataType dataType(int dataRow, int dataCol); + QRect getMergeRect(int row, int col); + GString findRowIdentityByRow(int row); +public: + GEGExcelRowIdentityChangeEventList m_rowIdentityChangeEventList; + GEGExcelColIdentityChangeEventList m_colIdentityChangeEventList; +protected: + virtual void doRegisterRules(); + virtual void doAutoMatchRow(); + virtual void doAutoMatchCol(); + bool isDataCol(int col) const;//以下为TableView的行列 + bool isDataRow(int row) const; + int dataCol(int col) const; + int dataRow(int row) const; + bool inDRange(int row, int col) const; +private: + GVariant configDisplayColData(int col) const; + GVariant configDisplayRowData(int row) const; + GVariant configDisplayIsExportData(int row) const; + int indexOfColRule(const GString &identity); + int indexOfRowRule(const GString &identity); + int lastMatchDataCol(); + void initializeRules(); + void registerRules(); + void loadRules(); + QVariant indexColData(const QModelIndex &index, int role = Qt::DisplayRole) const; + QVariant indexTitleData(const QModelIndex &index, int role = Qt::DisplayRole) const; + +private: + GLDXLSQueryCellAttributeEventList m_queryCellXLSAttributeEventList; + GObjectList m_colRules; + GObjectList m_rowRules; + QHash m_rowIdentityHash; + QHash m_rowCheckHash; + QHash m_colIdentityHash; + int m_firstDataCol; + int m_firstDataRow; + bool m_allowAutoMatch; + + friend class GEGColRule; + friend class GEGRowRule; + friend class CGEGRecordIterator; + friend class CGEGFieldIterator; +}; + +#endif // GLDEXCELGRIDITERATOR_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDExcelIteratorTableView.h b/GCR/trunk/Glodon/include/GLD/GLDExcelIteratorTableView.h new file mode 100644 index 00000000..5b86a9f5 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDExcelIteratorTableView.h @@ -0,0 +1,66 @@ +#ifndef GLDEXCELITERATORTABLEVIEW_H +#define GLDEXCELITERATORTABLEVIEW_H + +#include +#include "GLDTableView.h" +#include "GLDExcelGridIterator.h" + +class GLDExcelIteratorTableViewPrivate; +class GLDTABLEVIEWSHARED_EXPORT GLDExcelIteratorTableView : public GlodonTableView +{ + Q_OBJECT + Q_PROPERTY(QMenu * colPopMenu READ colPopMenu) + Q_PROPERTY(QMenu * rowPopMenu READ rowPopMenu) + Q_PROPERTY(QMenu * selectPopMenu READ selectPopMenu) +public: + GLDExcelIteratorTableView(QWidget *parent); + + void setModel(GEGExcelModel *model); + GEGExcelModel *model() const; + IGEGExcelGrid *getExcelGridIterator(); +public slots: + void hideMatchedRows(); + void showAllRows(); + void selectAllClick(); + void cancelAllClick(); + void clearMatchRowIndentity(); + +public: + QMenu *colPopMenu(); + QMenu *rowPopMenu(); + QMenu *selectPopMenu(); + QMenu *contextMenu(); +protected: + void mouseReleaseEvent(QMouseEvent *event); + + void createPopupMenus(); + void bindColumSetting(); + void bindRowSetting(); + +private Q_SLOTS: + void refresh(); + + void prevUnmatchedRow(); + void nextUnmatchedRow(); + + void autoMatch(); + + void setCurrentIndexValue(const GString &value); + + void doGridContextMenuRequest(QPoint value); +private: + //GLDExcelIteratorTableViewPrivate * const d_ptr; + Q_DECLARE_PRIVATE(GLDExcelIteratorTableView); +}; + +class GLDTABLEVIEWSHARED_EXPORT GLDExcellIteratorDelegate : public GlodonDefaultItemDelegate +{ +public: + explicit GLDExcellIteratorDelegate(QObject *parent = 0); + +public: + GEditStyle editStyle(const QModelIndex &index, bool &readOnly) const; + bool editable(const QModelIndex &index) const; +}; + +#endif // GLDEXCELITERATORTABLEVIEW_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDException.h b/GCR/trunk/Glodon/include/GLD/GLDException.h new file mode 100644 index 00000000..d7efdab1 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDException.h @@ -0,0 +1,95 @@ +#ifndef GLDEXCEPTION_H +#define GLDEXCEPTION_H + +#include +#include "GLDStrUtils.h" + +#ifdef __APPLE__ +# define _GLIBCXX_USE_NOEXCEPT throw() +#endif +#ifdef _MSC_VER +# define _GLIBCXX_USE_NOEXCEPT +#else +# define __CLR_OR_THIS_CALL +# define _THROW0() +#endif + +class GLDException : public std::exception +{ +public: + __CLR_OR_THIS_CALL GLDException() _THROW0() + : exception(), m_errorCode(-1) + { + } + + __CLR_OR_THIS_CALL GLDException(const GString &message) _THROW0() + : exception(), m_message(message), m_errorCode(-1) + { + } + + __CLR_OR_THIS_CALL GLDException(const GString &message, int errorCode) _THROW0() + : exception(), m_message(message), m_errorCode(errorCode) + { + } + + virtual ~GLDException() _GLIBCXX_USE_NOEXCEPT {} + +public: + inline GString message() const { return m_message; } + inline void setMessage(const GString &value) { m_message = value; } + inline int errorCode() const { return m_errorCode; } + inline void setErrorCode(int value) { m_errorCode = value; } + +private: + GString m_message; + int m_errorCode; +}; + +class GLDCOMMONSHARED_EXPORT GLDFieldSettingException : public GLDException +{ +public: + __CLR_OR_THIS_CALL GLDFieldSettingException(const GString &message, int tableIndex, int col, int errorCode) _THROW0() + : GLDException(message, errorCode), m_tableIndex(tableIndex), m_col(col) + { + } + +private: + int m_tableIndex; + int m_col; +}; + +typedef GLDFieldSettingException GLDFieldNameException; +typedef GLDFieldSettingException GLDSaveFieldNameException; +typedef GLDException GLDColSettingException; + +inline void gldError(const GString &message, int errorCode = -1) +{ + throw GLDException(message, errorCode); +} + +inline void gldErrorFmt(const GString &message, const GString &a, int errorCode = -1) +{ + throw GLDException(format(message, a), errorCode); +} + +inline void gldErrorFmt(const GString &message, int a, int errorCode = -1) +{ + throw GLDException(format(message, a), errorCode); +} + +inline void gldControlError(const GString &message, int errorCode = -1) +{ + throw GLDException(message, errorCode); +} + +inline void gldFieldNameError(const GString &message, int tableIndex, int col, int errorCode = -1) +{ + throw GLDFieldNameException(message, tableIndex, col, errorCode); +} + +inline void gldSaveFieldNameError(const GString &message, int tableIndex, int col, int errorCode = -1) +{ + throw GLDSaveFieldNameException(message, tableIndex, col, errorCode); +} + +#endif // GLDEXCEPTION_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDExtPropDefs.h b/GCR/trunk/Glodon/include/GLD/GLDExtPropDefs.h new file mode 100644 index 00000000..d189e915 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDExtPropDefs.h @@ -0,0 +1,90 @@ +#ifndef GLDEXTPROPDEFS_H +#define GLDEXTPROPDEFS_H + +#include "GLDObject.h" +#include "GLDHash.h" +#include "GLDStrUtils.h" +#include "GLDTableView_Global.h" + +class CGLDExtPropDef; +class CGLDExtPropDefs; + +class CGLDExtPropDefsPrivate; +// 扩展属性容器 +class GLDTABLEVIEWSHARED_EXPORT CGLDExtPropDefs : public GInterfaceObject +{ +public: + CGLDExtPropDefs(); + virtual ~CGLDExtPropDefs(); +public: + CGLDExtPropDef *GSPMETHODCALLTYPE add(); + CGLDExtPropDef *GSPMETHODCALLTYPE insert(long index); + virtual void GSPMETHODCALLTYPE Delete(long index); + virtual void GSPMETHODCALLTYPE remove(GString code); + virtual void GSPMETHODCALLTYPE move(long fromIndex, long toIndex); + virtual void GSPMETHODCALLTYPE clear(); + CGLDExtPropDef *GSPMETHODCALLTYPE find(GString code); + virtual long GSPMETHODCALLTYPE indexOf(GString code); + virtual long GSPMETHODCALLTYPE count(); + CGLDExtPropDef *GSPMETHODCALLTYPE items(long index); + virtual GString GSPMETHODCALLTYPE asString(); + virtual void GSPMETHODCALLTYPE setAsString(GString value); + CGLDExtPropDef *GSPMETHODCALLTYPE extPropByName(GString code); + virtual PtrInt GSPMETHODCALLTYPE tag(); + virtual void GSPMETHODCALLTYPE setTag(PtrInt value); + +public: +// void loadFromXML(const IXMLNode node); +// void saveToXML(const IXMLNode node); + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + + void assign(CGLDExtPropDefs *source); + void compile(); + void clearCompileInfo(); + + void buildCodeHash(); + void freeCodeHash(); + virtual void onChanging(); + virtual void onChanged(); + + CGLDExtPropDef *addObj(); + CGLDExtPropDef *insertObj(long index); + CGLDExtPropDef *findObj(const GString &code); + CGLDExtPropDef *itemObjs(long index); + CGLDExtPropDef *operator[](int index) { return itemObjs(index); } + +protected: + virtual CGLDExtPropDef *doCreateExtPropDef(); +protected: + CGLDExtPropDefsPrivate * const d_ptr; + Q_DECLARE_PRIVATE(CGLDExtPropDefs); +}; + +class CGLDExtPropDefPrivate; +// 扩展属性 +class GLDTABLEVIEWSHARED_EXPORT CGLDExtPropDef : public GInterfaceObject +{ +public: + CGLDExtPropDef(CGLDExtPropDefs *owner); + virtual ~CGLDExtPropDef(); +public: + virtual GString GSPMETHODCALLTYPE code(); + virtual void GSPMETHODCALLTYPE setCode(GString value); + virtual GString GSPMETHODCALLTYPE value(); + virtual void GSPMETHODCALLTYPE setValue(GString value); + virtual GString GSPMETHODCALLTYPE asString(); + virtual void GSPMETHODCALLTYPE setAsString(GString value); + virtual PtrInt GSPMETHODCALLTYPE tag(); + virtual void GSPMETHODCALLTYPE setTag(PtrInt value); +public: +// void loadFromXML(const IXMLNode node); +// void saveToXML(const IXMLNode node); + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); +protected: + CGLDExtPropDefPrivate * const d_ptr; + Q_DECLARE_PRIVATE(CGLDExtPropDef); +}; + +#endif // GLDEXTPROPDEFS_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDFile.h b/GCR/trunk/Glodon/include/GLD/GLDFile.h new file mode 100644 index 00000000..fe997b18 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDFile.h @@ -0,0 +1,10 @@ +#ifndef GLDFILE +#define GLDFILE + +#include + +typedef QFile GFileStream; +typedef QFile GFile; + +#endif // GLDFILE + diff --git a/GCR/trunk/Glodon/include/GLD/GLDFileInfo.h b/GCR/trunk/Glodon/include/GLD/GLDFileInfo.h new file mode 100644 index 00000000..3fd86b91 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDFileInfo.h @@ -0,0 +1,11 @@ +#ifndef GLDFILEINFO +#define GLDFILEINFO + +#include +#include + +typedef QFileInfo GFileInfo; +typedef QList GFileInfoList; + +#endif // GLDFILEINFO + diff --git a/GCR/trunk/Glodon/include/GLD/GLDFileSystemModel.h b/GCR/trunk/Glodon/include/GLD/GLDFileSystemModel.h new file mode 100644 index 00000000..c49273c6 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDFileSystemModel.h @@ -0,0 +1,225 @@ +#ifndef GLDFILESYSTEMMODEL_H +#define GLDFILESYSTEMMODEL_H + +#include +#include +#include +#include +#include "GLDListView.h" + +#ifndef QT_NO_DIRMODEL + +class GLDShellComboBoxItemDelegate; +class GLDFileSystemModelPrivate; +class GLDFileSystemModel; + +class GLDWIDGETSHARED_EXPORT GLDCustomFileSystemModel : public QAbstractItemModel +{ +public: + explicit GLDCustomFileSystemModel(QObject *parent = 0); + GLDCustomFileSystemModel(QAbstractItemModelPrivate &dd, QObject *parent = 0); + virtual ~GLDCustomFileSystemModel() {} + +public: + enum Roles { + FileIconRole = Qt::DecorationRole, + FilePathRole = Qt::UserRole + 1, + FileNameRole = Qt::UserRole + 2, + HideChildRole = Qt::UserRole + 3 // 用户GLDFileDialog中,在左边的目录树中,一个子都不需要显示,需要返回true + }; + virtual QModelIndex index(const QString &path, int column = 0) const = 0; + + virtual bool isDir(const QModelIndex &index) const = 0; + virtual QString filePath(const QModelIndex &index) const = 0; + virtual QString makeCaseCorrespondingToSystem(const QString &path) const = 0; + virtual GLDFileSystemModel *fileSystemModel() const; + virtual QModelIndex mkdir(const QModelIndex &parent, const QString &name) = 0; + virtual void refresh(const QModelIndex &parent = QModelIndex()) = 0; + virtual bool rmdir(const QModelIndex &index); + virtual bool remove(const QModelIndex &index); + +public: + /*! + * \brief 设置view的显示模式模式,model需要根据view的显示模式,来调节对齐方式 + * \param viewMode + */ + virtual void setViewMode(GLDListView::GLDViewMode viewMode); + virtual GLDListView::GLDViewMode viewMode(); + +protected: + GLDListView::GLDViewMode m_enViewMode; +}; + +class GLDWIDGETSHARED_EXPORT GLDFileSystemModel : public GLDCustomFileSystemModel +{ + Q_OBJECT + Q_PROPERTY(bool resolveSymlinks READ resolveSymlinks WRITE setResolveSymlinks) + Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly) + Q_PROPERTY(bool lazyChildCount READ lazyChildCount WRITE setLazyChildCount) + +public: + explicit GLDFileSystemModel(bool includingFile = false, QObject *parent = 0); + ~GLDFileSystemModel(); + + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex &child) const; + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + + bool hasChildren(const QModelIndex &index = QModelIndex()) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + + void sort(int column, Qt::SortOrder order = Qt::AscendingOrder); + + QStringList mimeTypes() const; + QMimeData *mimeData(const QModelIndexList &indexes) const; + bool dropMimeData(const QMimeData *data, Qt::DropAction action, + int row, int column, const QModelIndex &parent); + Qt::DropActions supportedDropActions() const; + + // GLDFileSystemModel specific API + + void setIconProvider(QFileIconProvider *provider); + QFileIconProvider *iconProvider() const; + + void setNameFilters(const QStringList &filters); + QStringList nameFilters() const; + + void setFilter(QDir::Filters filters); + QDir::Filters filter() const; + + void setSorting(QDir::SortFlags sort); + QDir::SortFlags sorting() const; + + void setResolveSymlinks(bool enable); + bool resolveSymlinks() const; + + void setReadOnly(bool enable); + bool isReadOnly() const; + + void setLazyChildCount(bool enable); + bool lazyChildCount() const; + + QModelIndex index(const QString &path, int column = 0) const; + + bool isDir(const QModelIndex &index) const; + QModelIndex mkdir(const QModelIndex &parent, const QString &name); + bool rmdir(const QModelIndex &index); + bool remove(const QModelIndex &index); + + QString filePath(const QModelIndex &index) const; + QString fileName(const QModelIndex &index) const; + QIcon fileIcon(const QModelIndex &index) const; + QFileInfo fileInfo(const QModelIndex &index) const; + +#ifdef Q_NO_USING_KEYWORD + inline QObject *parent() const { return QObject::parent(); } +#else + using QObject::parent; +#endif + + QString makeCaseCorrespondingToSystem(const QString &path) const; + + void refresh(const QModelIndex &parent = QModelIndex()); + +protected: + GLDFileSystemModel(const QStringList &nameFilters, QDir::Filters filters, + QDir::SortFlags sort, QObject *parent = 0); + GLDFileSystemModel(GLDFileSystemModelPrivate &, QObject *parent = 0); + friend class QFileDialogPrivate; +private: + Q_DECLARE_PRIVATE(GLDFileSystemModel) + Q_DISABLE_COPY(GLDFileSystemModel) + Q_PRIVATE_SLOT(d_func(), void _q_refresh()) +}; + +class GLDWIDGETSHARED_EXPORT GLDFileSystemModelPrivate : public QAbstractItemModelPrivate +{ + Q_DECLARE_PUBLIC(GLDFileSystemModel) + +public: + struct QDirNode + { + QDirNode() : parent(0), populated(false), stat(false) {} + ~QDirNode() { children.clear(); } + + QDirNode *parent; + QFileInfo info; + QIcon icon; // cache the icon + mutable QVector children; + mutable bool populated; // have we read the children + mutable bool stat; + }; + + GLDFileSystemModelPrivate() + : resolveSymlinks(true), + readOnly(true), + lazyChildCount(false), + allowAppendChild(true), + iconProvider(&defaultProvider), + shouldStat(true) // ### This is set to false by QFileDialog + { } + + void init(); + QDirNode *node(int row, QDirNode *parent) const; + QVector children(QDirNode *parent, bool stat) const; + + void _q_refresh(); + + void savePersistentIndexes(); + void restorePersistentIndexes(); + + QFileInfoList entryInfoList(const QString &path) const; + QStringList entryList(const QString &path) const; + + QString name(const QModelIndex &index) const; + QString size(const QModelIndex &index) const; + QString type(const QModelIndex &index) const; + QString updateDateTime(const QModelIndex &index) const; + QString createDateTime(const QModelIndex &index) const; + + void appendChild(GLDFileSystemModelPrivate::QDirNode *parent, const QString &path) const; + void removeChild(GLDFileSystemModelPrivate::QDirNode *parent, const QModelIndex &index) const; + void removeAll(GLDFileSystemModelPrivate::QDirNode *pNode); + static QFileInfo resolvedInfo(QFileInfo info); + + QDirNode *node(const QModelIndex &index) const; + void populate(QDirNode *parent) const; + void clear(QDirNode *parent) const; + + void invalidate(); + + mutable QDirNode root; + bool resolveSymlinks; + bool readOnly; + bool lazyChildCount; + bool allowAppendChild; + + QDir::Filters filters; + QDir::SortFlags sort; + QStringList nameFilters; + + QFileIconProvider *iconProvider; + QFileIconProvider defaultProvider; + + struct SavedPersistent { + QString path; + int column; + QPersistentModelIndexData *data; + QPersistentModelIndex index; + }; + + QList savedPersistent; + QPersistentModelIndex toBeRefreshed; + + bool shouldStat; // use the "carefull not to stat directories" mode +}; + +#endif //ifndef QT_NO_DIRMODEL +#endif // GLDFILESYSTEMMODEL_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDFileUtils.h b/GCR/trunk/Glodon/include/GLD/GLDFileUtils.h new file mode 100644 index 00000000..ddb973fb --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDFileUtils.h @@ -0,0 +1,86 @@ +/************************************************************************* +* * +* 广联达文件类相关公共函数单元 H * +* * +* 设计:Zhangsk 2012.05.21 * +* 备注: * +* 审核: * +* * +* Copyright (c) 2012-2013 Glodon Corporation * +* * +* ********************************************************************** * +* * +* 修改: * +* * +* 20XX.05.01 - XXX * +* * +* 1、XXXXXX * +* * +* * +*************************************************************************/ + +#ifndef GLDFILEUTILS_H +#define GLDFILEUTILS_H + +#include "GLDString.h" +#include "GLDStrUtils.h" +#include "GLDNameSpace.h" + +#include "GLDWidget_Global.h" + +G_GLODON_BEGIN_NAMESPACE +G_GLODON_END_NAMESPACE + +GLDCOMMONSHARED_EXPORT GString exeFullName(); +GLDCOMMONSHARED_EXPORT GString exePath(); +GLDCOMMONSHARED_EXPORT GString exeDir(); + +GLDCOMMONSHARED_EXPORT GString moduleName(void *module); + +GLDCOMMONSHARED_EXPORT GString getCurrentDir(); +GLDCOMMONSHARED_EXPORT GString getProductPath(const GString &path, const GString &productName, const GString &version); + +GLDCOMMONSHARED_EXPORT GString getCommonDocumentsPath(); + +GLDCOMMONSHARED_EXPORT GString getTempFile(const GString &prefix, const GString &path); + +GLDCOMMONSHARED_EXPORT bool isLibrary(); + +//实现Win32平台函数BOOL CopyFile(LPCTSTR lpExistingFileName,LPCTSTR lpNewFileName,BOOL bFailIfExists ); +GLDCOMMONSHARED_EXPORT bool copyFile(const GString &oldFile, const GString &newFile, bool failIfExists); + +GLDCOMMONSHARED_EXPORT bool deleteFile(const GString &fileName); +GLDCOMMONSHARED_EXPORT bool deleteTree(const GString &path); + +GLDCOMMONSHARED_EXPORT bool fileExists(const GString &fileName); +GLDCOMMONSHARED_EXPORT GStream *createFileStream(const GString &fileName); +GLDCOMMONSHARED_EXPORT GString extractFileExt(const GString &fileName); +GLDCOMMONSHARED_EXPORT GString changeFileExt(const GString &fileName, const GString &extension); + +GLDCOMMONSHARED_EXPORT void findSubFolders(const GString &path, GStrings &folders); +GLDCOMMONSHARED_EXPORT void findFiles(const GString &path, const GStrings &nameFilters, GStrings &files); +GLDCOMMONSHARED_EXPORT void findFiles(const GString &path, const GString &nameFilter, GStrings &files); +GLDCOMMONSHARED_EXPORT void getFiles(const GString &path, GStrings &files, const GString &nameFilter = ""); +GLDCOMMONSHARED_EXPORT void getFiles(const GString &path, const GStrings &nameFilters, GStrings &files, bool includeDir = false); +GLDCOMMONSHARED_EXPORT GString getValidFileName(const GString &fileName); + +GLDCOMMONSHARED_EXPORT bool createDir(const GString &path); +GLDCOMMONSHARED_EXPORT bool forceDirectories(const GString &path); +GLDCOMMONSHARED_EXPORT bool directoryExists(const GString &path); + +GLDCOMMONSHARED_EXPORT GString extractFilePath(const GString &fileName); +GLDCOMMONSHARED_EXPORT GString extractFileDir(const GString &fileName); +GLDCOMMONSHARED_EXPORT GString extractFileName(const GString &fileName); +GLDCOMMONSHARED_EXPORT GString extractFileNameOnly(const GString &fileName); +GLDCOMMONSHARED_EXPORT GString expandFileName(const GString &fileName); +GLDCOMMONSHARED_EXPORT int pathDelimPos(const GString &fileName); +GLDCOMMONSHARED_EXPORT void fileSetReadOnly(const GString &fileName, bool readOnly = true); + +GLDCOMMONSHARED_EXPORT gint64 getFileSize(const GString &fileName); + +// 取得运行命令行的输出:默认的codepage为Local8Bit(中文操作系统为936) +GLDCOMMONSHARED_EXPORT GString getCommandLineOutput( + const GString &commandLine, const GString &workDir, int &exitCode); + +GLDCOMMONSHARED_EXPORT GString loadQssFile(const GString &fileName); +#endif // GLDFILEUTILS_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDFilterTableView.h b/GCR/trunk/Glodon/include/GLD/GLDFilterTableView.h new file mode 100644 index 00000000..985e2a4e --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDFilterTableView.h @@ -0,0 +1,125 @@ +/*! + *@file glodonfiltertableview.h + *@brief {提供筛选功能的Grid} + * + *@author Gaosy + *@date 2012.9.7 + *@remarks {remarks} + *Copyright (c) 1998-2012 Glodon Corporation + */ + +#ifndef GLDFILTERTABLEVIEW_H +#define GLDFILTERTABLEVIEW_H + +#include "GLDTableView.h" +#include "GLDFilterView.h" +#include "GLDGlobal.h" + +class GlodonFilterTableViewPrivate; + +/*! + *@class: GlodonFilterTableView + *@brief {提供筛选行的Grid,通过对筛选行设置筛选方式,可自定义筛选方式,默认为ComboBox} + *@author Gaosy + *@date 2012.9.10 + */ +class GLDTABLEVIEWSHARED_EXPORT GlodonFilterTableView : public GlodonTableView +{ + Q_OBJECT + +public: + /*! + *GlodonFilterTableView构造方法 + *@param[in] parent 父widget + *@return 无 + */ + GlodonFilterTableView(QWidget *parent); + + /*! + *为GlodonFilterTableView设置model,用于数据显示和编辑,同时为filter(筛选行)设置model + *@param[in] model + *@return 无 + */ + void setModel(QAbstractItemModel *model); + + /*! + *GlodonFilterTableView的绘制方法,调用父类GlodonTableView的绘制方法 + *@param[in] e + *@return 无 + *@see 参见GlodonTableView::paintEvent(QPaintEvent *e) + */ + void paintEvent(QPaintEvent *e); + + /*! + *设置水平表头,将filter(筛选行)与表头的resize、moveSection信号连接 + *@param[in] header 水平表头 + *@return 无 + */ + void setHorizontalHeader(GlodonHeaderView *header); + + /*! + *设置是否显示filter(筛选行) + *@param[in] hide true为隐藏filter(筛选行),false为显示filter(筛选行) + *@return 无 + *@warning 如果使用的是GSPDataSource,必须在GSPDataSource被setActive后,再设置过滤行可见 + */ + void setIsDisplayFilter(bool show); + /** + * @brief 是否显示过滤行 + * @return + */ + bool isDisplayFilter(); + + /*! + *设置GlodonFilterTableView中水平表头、竖直表头、表体、筛选行的位置, + *将筛选行置于水平表头和表体之间 + *@return 无 + */ + void updateGeometries(); + + /*! + *设置固定可编辑列数 + *@param[in] fixedColCount 固定可编辑列数 + *@return 无 + */ + void setFixedColCount(int fixedColCount); + + //筛选行 + GFilterView *filter(); + void setGridColor(QColor value); + void setGridLineColor(QColor value); + +public Q_SLOTS: + /*! + *处理默认情况下的筛选 + *@param[in] column The memory area to copy from. + *@return 无 + */ + void changeViewItemsForFilter(int column); + +protected Q_SLOTS: + void columnResized(int column, int oldWidth, int newWidth, bool isManual = false); + +Q_SIGNALS: + bool onFilterData(int row); + +protected: + GlodonFilterTableView(GlodonFilterTableViewPrivate &dd, QWidget *parent); + void timerEvent(QTimerEvent *event); + void resetModel(QAbstractItemModel *dataModel); + + virtual void resetEllipsisButtonLocation(); + + bool isFilterHide(); + +protected: + // 重构updateGeometries + void updateFilterViewGeometry(int nFilterViewHeight); + void updateHorizontalHeaderGeometry(int nHorizontalHeaderHeight, int nFilterViewHeight); + +private: + bool m_bDisplayFilter; + Q_DECLARE_PRIVATE(GlodonFilterTableView) +}; + +#endif // GLDFILTERTABLEVIEW_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDFilterTableView_p.h b/GCR/trunk/Glodon/include/GLD/GLDFilterTableView_p.h new file mode 100644 index 00000000..7cefe209 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDFilterTableView_p.h @@ -0,0 +1,19 @@ +#ifndef GLDFILTERTABLEVIEW_P_H +#define GLDFILTERTABLEVIEW_P_H + +#include "GLDTableView_p.h" + +class GLDTABLEVIEWSHARED_EXPORT GlodonFilterTableViewPrivate : public GlodonTableViewPrivate +{ + Q_DECLARE_PUBLIC(GlodonFilterTableView) +public: + GlodonFilterTableViewPrivate(); + void init(); + void initFilter(); + void connectFilterSignal(); +public: + //筛选行 + GFilterView *filter; +}; + +#endif // GLDFILTERTABLEVIEW_P_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDFilterView.h b/GCR/trunk/Glodon/include/GLD/GLDFilterView.h new file mode 100644 index 00000000..9dcdf37b --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDFilterView.h @@ -0,0 +1,128 @@ +/*! + *@file gfilterview.h + *@brief {筛选行} + *用于筛选表格中的数据 + *@author Gaosy + *@date 2012.9.7 + *@remarks {位置在水平表头之下,目前仅支持单行} + *Copyright (c) 1998-2012 Glodon Corporation + */ + +#ifndef GLDFILTERVIEW_H +#define GLDFILTERVIEW_H + +#include "GLDHeaderView.h" +#include + +class GFilterViewPrivate; + +/*! + *@class: GFilterView + *@brief {为Grid提供筛选行的功能,可自定义筛选方式,默认为ComboBox方式} + *@author Gaosy + *@date 2012.9.7 + */ +class GLDTABLEVIEWSHARED_EXPORT GFilterView : public GlodonHeaderView +{ + Q_OBJECT +public: + /*! + *GFilterView构造方法 + *@param[in] parent 父widget + *@return 无 + */ + GFilterView(QWidget *parent); + + /*! + *获取logicalIndex这一列的筛选控件的内容 + *@param[in] logicalIndex 需要获取筛选控件内容的逻辑列号(Model中的列号) + *@return QString + */ + QString filterData(int logicalIndex); + + /*! + *为GFilterView设置model,仅仅是为了控制显示的列数,没有其他意义 + *@param[in] model + *@return 无 + */ + void setModel(QAbstractItemModel *model); + + /*! + *使GFilterView获取TableView中使用的Model,用于默认筛选方式的建立 + *@param[in] filterModel TableView中使用的Model + *@return 无 + */ + void setFilterDataModel(QAbstractItemModel *filterModel); + + /*! + *获取index所在格子的大小 + *@param[in] index + *@return QRect + */ + QRect visualRect(const QModelIndex &index) const; + + /*! + *GFilterView的绘制方法 + *@param[in] e + *@return 无 + */ + void paintEvent(QPaintEvent *e); + + /*! + *获取控件的高度 + *@return int + */ + int height() const; + +public: + //TableView中的数据Model,用于Filter的筛选行初始化 + QAbstractItemModel *m_pFilterDataModel; + void resetFilter(int col); +public Q_SLOTS: + /*! + *用于同步resize动作 + *@param[in] logicalIndex resize动作发生的逻辑列(Model中的列) + *@param[in] oldSize resize前该列的宽度 + *@param[in] size resize后该列的宽度 + *@return 无 + */ + void resizeSection(int logicalIndex, int oldSize, int size); + + /*! + *用于同步列移动动作 + *@param[in] logicalIndex 列移动动作发生的逻辑列(Model中的列) + *@param[in] oldSize 列移动前该列所处的位置 + *@param[in] size 列移动后该列所处的位置 + *@return 无 + */ + void moveSection(int logicalIndex, int from, int to); + + /*! + *处理筛选控件的值的改变 + *@return 无 + */ + void filterChanged(); + + /*! + *设置应为隐藏状态的子widget为隐藏状态 + *@return 无 + */ + void hideHiddenSection(int hbarPos); + + void filterDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); + void initFilterWidget(); + +Q_SIGNALS: + void onFilterChanged(int column); + QWidget* onQueryFilterWidget(int logicalIndex); + +protected: + void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const; + void paintSection(int beginToHideIndex) const; + void keyPressEvent(QKeyEvent *event); + mutable bool m_bHideFlag; +private: + Q_DECLARE_PRIVATE(GFilterView) +}; + +#endif // GLDFILTERVIEW_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDFilterView_p.h b/GCR/trunk/Glodon/include/GLD/GLDFilterView_p.h new file mode 100644 index 00000000..7f5ad52e --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDFilterView_p.h @@ -0,0 +1,13 @@ +#ifndef GLDFILTERVIEW_P_H +#define GLDFILTERVIEW_P_H + +#include "GLDHeaderView_p.h" + +class GLDCOMMONSHARED_EXPORT GFilterViewPrivate : public GlodonHeaderViewPrivate +{ + Q_DECLARE_PUBLIC(GFilterView) +public: + GFilterViewPrivate(){} +}; + +#endif // GLDFILTERVIEW_P_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDFilterWidget.h b/GCR/trunk/Glodon/include/GLD/GLDFilterWidget.h new file mode 100644 index 00000000..790ffeaa --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDFilterWidget.h @@ -0,0 +1,103 @@ +/**************************************************************************************************** + + 补充数据过滤控件 + + 作者: jiangjb 2014-03-13 + 备注: + 审核: + + Copyright (c) 1994-2013 Glodon Corporation + +****************************************************************************************************/ +#ifndef GLDFILTERWIDGET_H +#define GLDFILTERWIDGET_H + +#include +#include +#include +#include "GLDString.h" +#include "GLDWidget_Global.h" + +#define ICONBUTTON_SIZE 16 + +class GLDWIDGETSHARED_EXPORT GLDHintLineEdit : public QLineEdit +{ + Q_OBJECT +public: + explicit GLDHintLineEdit(QWidget *parent = 0); + + bool refuseFocus() const; + void setRefuseFocus(bool v); + +protected: + virtual void mousePressEvent(QMouseEvent *event); + virtual void focusInEvent(QFocusEvent *e); + +private: + const Qt::FocusPolicy m_eDefaultFocusPolicy; + bool m_bRefuseFocus; +}; + + +// IconButton: This is a simple helper class that represents clickable icons +class GLDWIDGETSHARED_EXPORT GLDIconButton: public QToolButton +{ + Q_OBJECT + Q_PROPERTY(float fader READ fader WRITE setFader) +public: + GLDIconButton(QWidget *parent); + + float fader(); + void setFader(float value); + void animateShow(bool visible); + +protected: + void paintEvent(QPaintEvent *event); + +private: + float m_fFader; +}; + + +class GLDWIDGETSHARED_EXPORT GLDFilterWidget : public QWidget +{ + Q_OBJECT +public: + enum GLDLayoutMode { + // For use in toolbars: Expand to the right + lmAlignRight, + // No special alignment + lmAlignNone + }; + + explicit GLDFilterWidget(QWidget *parent = 0, GLDLayoutMode mode = lmAlignRight); + GLDFilterWidget(QIcon icon, QWidget *parent = 0, GLDLayoutMode mode = lmAlignRight); + + GString text() const; + void setText(const GString str); + void resizeEvent(QResizeEvent *); + bool refuseFocus() const; // see HintLineEdit + void setRefuseFocus(bool v); + void setAutoResize(bool autoResize); + void setInputPlaceholderText(const GString &text); +signals: + void filterChanged(const GString &); + +public slots: + void reset(); + +private slots: + void checkButton(const GString &text); +private: + void init(GLDLayoutMode mode, QIcon value); + +private: + GLDHintLineEdit *m_pLedtEditor; + GLDIconButton *m_pBtnIcon; + int m_nButtonWidth; + GString m_sOldText; + bool m_autoResize;//false + GString m_inputPlaceholderText; +}; + +#endif // GLDFILTERWIDGET_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDFloatFormating.h b/GCR/trunk/Glodon/include/GLD/GLDFloatFormating.h new file mode 100644 index 00000000..75650f9d --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDFloatFormating.h @@ -0,0 +1,38 @@ +#ifndef GLDFLOATFORMATING_H +#define GLDFLOATFORMATING_H + +#include "GLDString.h" +#include "GLDCommon_Global.h" + +struct FloatRec +{ + int exponent; + bool negative; + char digits[20]; +}; + +class GLDFloatFormatingPrivate; +class GLDCOMMONSHARED_EXPORT GLDFloatFormating +{ +public: + GLDFloatFormating(); + ~GLDFloatFormating(); +public: + static GString formatFloat(double value, const GString &format); +private: + GString internalFloatToTextFmt(double value, const GString &format); + int findSection(int index); + GString scanSection(int pos); + void applyFormat(int sectionIndex); + int digitsLength(); + void putFmtDigit(); + void writeDigit(char digit); + void addDigit(); + void putExponent(QChar eChar, QChar sign, int zeros, int exponent); + +private: + GLDFloatFormatingPrivate * const d_ptr; + Q_DECLARE_PRIVATE(GLDFloatFormating); +}; + +#endif // GLDFLOATFORMATING_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDFontList.h b/GCR/trunk/Glodon/include/GLD/GLDFontList.h new file mode 100644 index 00000000..1504460f --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDFontList.h @@ -0,0 +1,41 @@ +#ifndef GLDFONTLIST_H +#define GLDFONTLIST_H + +#include +#include "GLDWidget_Global.h" + +#define ITEM_WIDTH 70 +#define ITEM_HEIGHT 24 +class GlodonFontFamilyDelegate; +class GLDWIDGETSHARED_EXPORT GFontList : public QFontComboBox +{ +public: + explicit GFontList(QWidget *parent); + ~GFontList(); +public: + virtual void showPopup(); +protected: + int m_bFirstPopup; +}; + +class GLDWIDGETSHARED_EXPORT GlodonFontFamilyDelegate : public QAbstractItemDelegate +{ + Q_OBJECT +public: + explicit GlodonFontFamilyDelegate(QObject *parent); + + // painting + void paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const; + + QSize sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const; + +private: + QIcon truetype; + QIcon bitmap; + QFontDatabase::WritingSystem writingSystem; +}; + +#endif // GLDFONTLIST_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDFontListEx.h b/GCR/trunk/Glodon/include/GLD/GLDFontListEx.h new file mode 100644 index 00000000..17b0126c --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDFontListEx.h @@ -0,0 +1,95 @@ +#ifndef GFontListEx_H +#define GFontListEx_H + +#include +#include +#include "GLDWidget_Global.h" + +class GLDFontListDelegate; + +class GLDWIDGETSHARED_EXPORT GFontListEx : public QFontComboBox +{ + Q_OBJECT +public: + explicit GFontListEx(QWidget *parent = 0); + ~GFontListEx(); + +public: + virtual void showPopup(); + void setHasBorder(bool bHasBorder = true); + +protected: + QColor m_highLightBackgroundColor; + QColor m_highLightTextColor; + +protected slots: + void showFontFamily(QString family); + +private: + void setHightBackground(QColor color); + void setHightText(QColor color); + void setFontListItemDelegate(GLDFontListDelegate *delegate); + void setHighLighColor(QColor background, QColor text); + +private: + GLDFontListDelegate *m_pFontDelegate; +}; + +class GLDWIDGETSHARED_EXPORT GLDFontListDelegate : public QAbstractItemDelegate +{ + Q_OBJECT +public: + explicit GLDFontListDelegate(QObject *parent = 0); + +public: + void setTTypeIconPath(const QString &path); // 设置TrueType的图标路径 + void setBMapIconPath(const QString &path); // 设置Bitmap图标的路径 + void setCMarkIconPath(const QString &path); // 设置选中状态图标的路径 + + // 控制是否显示选中状态图标的getter与setter + bool isShowCheckMark(); + void setIsShowCheckMark(bool isShow = true); + + // 控制是否显示字体类型图标的getter与setter + bool isShowFontTypeImage(); + void setIsShowFontTypeImage(bool isShow = true); + + // 控制显示时每个字体对应的效果图 + void setEnglishCaption(const QString &caption); + void setZhCaption(const QString &caption); + + QString defaultFont(); // 取得默认字体 + void setDefaultFont(QString family); // 设置默认字体 + + QString selectedFamily() const; // 取得组合框中选中的字体 + void setSelectedFamily(const QString &family); // 根据combobox的设置选中的字体 + +protected: + void paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const; // paint each list item + QSize sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const; + +private: + void paintFontTypeImage(QRect &rect, QString fontFamilyName, + QPainter *painter, const QStyleOptionViewItem &option) const; + void paintCheckStatusIcon(QRect &rect, QPainter *painter) const; + +private: + QString m_sTTypeIconPath; // True Type图标的路径 + QString m_sBMapIconPath; // Bitmpa类型图标的路径 + QString m_sCMarkIconPath; // 选择状态图标的路径 + QIcon m_trueTypeIcon; + QIcon m_bitmapIcon; + QIcon m_checkMark; + bool m_bShowTypeImageFlag; + + QString m_sEnglishCaption; + QString m_sZhCaption; + QString m_sDefaultFont; + + QString m_sSelectedFamily; + bool m_bShowCheckMark; +}; +#endif // GFontListEx_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDFooterModel.h b/GCR/trunk/Glodon/include/GLD/GLDFooterModel.h new file mode 100644 index 00000000..89fc90b3 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDFooterModel.h @@ -0,0 +1,90 @@ +#ifndef GLDFOOTERMODEL_H +#define GLDFOOTERMODEL_H + +#include "GLDAbstractItemModel.h" + +class GLDCOMMONSHARED_EXPORT GlodonFooterBodyModel : public GlodonAbstractItemModel +{ + Q_OBJECT + +public: + GlodonFooterBodyModel(QAbstractItemModel *model, QObject *parent = 0); +public: + QModelIndex index(const QModelIndex &dataIndex) const; + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex &child) const; + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + bool hasChildren(const QModelIndex &parent = QModelIndex()) const; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, + int role = Qt::EditRole); + void sort(int column, Qt::SortOrder order); + Qt::ItemFlags flags(const QModelIndex &index) const; + + QStringList mimeTypes() const; + QMimeData *mimeData(const QModelIndexList &indexes) const; + bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, + int column, const QModelIndex &parent) const; + bool dropMimeData(const QMimeData *data, Qt::DropAction action, + int row, int column, const QModelIndex &parent); + +public: + QModelIndex dataIndex(const QModelIndex &footerIndex) const; + QModelIndex footerBodyIndex(const QModelIndex &dataIndex) const; + inline int footerRowCount() const { return m_footerRowCount; } + inline void setFooterRowCount(int value) { m_footerRowCount = value; } +private: + QAbstractItemModel *m_model; + int m_footerRowCount; + +private Q_SLOTS: + void onRowRemoved(const QModelIndex &parent, int first, int last); + void onRowInserted(const QModelIndex &parent, int first, int last); + void onRowMoved(const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row); + void onUpdate(QModelIndex &topLeft); + void onResetModel(); + void onDataChange(const QModelIndex &topLeft, const QModelIndex &bottomRight, + const QVector&roles = QVector()); +}; + +class GLDCOMMONSHARED_EXPORT GlodonFooterModel : public GlodonAbstractItemModel +{ + Q_OBJECT + +public: + GlodonFooterModel(QAbstractItemModel *model, QObject *parent = 0); +public: + QModelIndex index(const QModelIndex &dataIndex) const; + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex &child) const; + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + bool hasChildren(const QModelIndex &parent = QModelIndex()) const; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); +public: + QModelIndex dataIndex(const QModelIndex &footerIndex) const; + QModelIndex footerIndex(const QModelIndex &dataIndex) const; + inline int footerRowCount() const { return m_footerRowCount; } + inline void setFooterRowCount(int value) { m_footerRowCount = value; } +private Q_SLOTS: + void onDataChange(const QModelIndex &topLeft, const QModelIndex &bottomRight, + const QVector&roles = QVector()); +private: + QAbstractItemModel *m_model; + int m_footerRowCount; + +private Q_SLOTS: + void onResetModel(); +}; + +#endif // GLDFOOTERMODEL_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDFooterTableView.h b/GCR/trunk/Glodon/include/GLD/GLDFooterTableView.h new file mode 100644 index 00000000..de7e595f --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDFooterTableView.h @@ -0,0 +1,97 @@ +/*! + *@file glodonfootertableview.h + *@brief {带有筛选行及合计行功能的Grid} + * + *@author Gaosy + *@date 2012.9.7 + *@remarks {remarks} + *Copyright (c) 1998-2012 Glodon Corporation + */ + +#ifndef GLDFOOTERTABLEVIEW_H +#define GLDFOOTERTABLEVIEW_H + +#include "GLDFilterTableView.h" +#include "GLDFooterView.h" +#include "GLDFooterModel.h" + +class GlodonFooterTableViewPrivate; + +/*! + *@class: GlodonFooterGrid + *@brief {带有筛选行及合计行功能的Grid,筛选行可以隐藏,合计行需要单独setModel} + *@author Gaosy + *@date 2012.9.10 + */ +class GLDTABLEVIEWSHARED_EXPORT GlodonFooterTableView : public GlodonFilterTableView +{ + Q_OBJECT + +public: + /*! + *GlodonFooterGrid构造方法 + *@param[in] parent 父widget + *@return 无 + */ + GlodonFooterTableView(QWidget *parent); + + /*! + *设置GlodonFooterGrid中水平表头、竖直表头、表体、筛选行、合计行的位置, + *将合计行置于表体的下方 + *@return 无 + */ + void updateGeometries(); + + /*! + *为合计行设置model + *@param[in] model 合计行显示和编辑需要的model + *@return 无 + */ + void setFooterModel(QAbstractItemModel *model); + + /*! + *设置水平表头,将footer(合计行)与表头的resize、moveSection信号连接 + *@param[int] header 水平表头 + *@return 无 + */ + void setHorizontalHeader(GlodonHeaderView *header); + void setModel(QAbstractItemModel *model); + + bool totalRowAtFooter() const; + void setTotalRowAtFooter(bool value); + + void setTotalRowCount(int value); + void paintEvent(QPaintEvent *e); + void setGridColor(QColor value); + void setGridLineColor(QColor value); + void setFixedColCount(int fixedColCount); +public: + //合计行 + GFooterView *footer(); + +protected Q_SLOTS: + void beforeReset(); + void doReset(); + void afterReset(); + +protected: + GlodonFooterTableView(GlodonFooterTableViewPrivate &dd, QWidget *parent); + void resetModel(); + void createModel(); + +protected: + void updateFooterGeometry(int nVerticalHeaderWidth); + +private: + Q_DECLARE_PRIVATE(GlodonFooterTableView) + + void changeVerticalHeaderDrawWidth(); + +protected Q_SLOTS: + virtual void currentChanged(const QModelIndex ¤t, const QModelIndex &previous); + void columnResized(int column, int oldWidth, int newWidth, bool isManual = false); + void setCurrentIndex(const QModelIndex &dataIndex); + void setCurrentIndexForFooter(const QModelIndex ¤t); +}; + +#endif // GLDFOOTERTABLEVIEW_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDFooterTableView_p.h b/GCR/trunk/Glodon/include/GLD/GLDFooterTableView_p.h new file mode 100644 index 00000000..4357e2f9 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDFooterTableView_p.h @@ -0,0 +1,24 @@ +#ifndef GLDFOOTERTABLEVIEW_P_H +#define GLDFOOTERTABLEVIEW_P_H + +#include "GLDFilterTableView_p.h" + +class GlodonFooterTableViewPrivate : public GlodonFilterTableViewPrivate +{ + Q_DECLARE_PUBLIC(GlodonFooterTableView) +public: + GlodonFooterTableViewPrivate() : m_dataModel(NULL), footerModel(NULL), footBodyModel(NULL), + footer(NULL), totalRowAtFooter(true), footerRowCount(0) {} + + void init(); + void connectFooterSignal(); + //合计行 + QAbstractItemModel *m_dataModel; + GlodonFooterModel *footerModel; + GlodonFooterBodyModel *footBodyModel; + GFooterView *footer; + bool totalRowAtFooter; + int footerRowCount; +}; + +#endif // GLDFOOTERTABLEVIEW_P_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDFooterView.h b/GCR/trunk/Glodon/include/GLD/GLDFooterView.h new file mode 100644 index 00000000..e8484944 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDFooterView.h @@ -0,0 +1,90 @@ +/*! + *@file gfooterview.h + *@brief {合计行} + *固定的显示在TableView的下方 + *@author Gaosy + *@date 2012.9.7 + *@remarks {支持多行,可进行合并,需要单独setModel} + *Copyright (c) 1998-2012 Glodon Corporation + */ + +#ifndef GLDFOOTERVIEW_H +#define GLDFOOTERVIEW_H + +#include "GLDTableView.h" + +class GFooterViewPrivate; + +/*! + *@class: GFooterView + *@brief {合计行,为Grid提供合计行功能,支持多行和合并,需要额外setModel} + *@author Gaosy + *@date 2012.9.7 + */ +class GLDTABLEVIEWSHARED_EXPORT GFooterView : public GlodonTableView +{ + Q_OBJECT + +public: + /*! + *GFooterView构造方法 + *@param[in] parent 父widget + *@return 无 + */ + GFooterView(QWidget *parent); + + /*! + *为GFooterView设置model,用于合计行的数据显示和编辑,与所处的TableView表体数据独立 + *@param[in] model + *@return 无 + */ + void setModel(QAbstractItemModel *model); + + /*! + *获取控件的高度 + *@return int + */ + int height() const; + void paintEvent(QPaintEvent *e); + void resetCurrentIndex(const QModelIndex ¤t); + + void setVerticalHeaderDrawWidth(int width); + +Q_SIGNALS: + void currentIndexChanged(const QModelIndex ¤t); + +public Q_SLOTS: + /*! + *用于同步resize动作 + *@param[in] logicalIndex resize动作发生的逻辑列(Model中的列) + *@param[in] oldSize resize前该列的宽度 + *@param[in] size resize后该列的宽度 + *@return 无 + */ + void resizeSection(int logicalIndex, int oldSize,int size); + /*! + *用于同步列移动动作 + *@param[in] logicalIndex 列移动动作发生的逻辑列(Model中的列) + *@param[in] oldSize 列移动前该列所处的位置 + *@param[in] size 列移动后该列所处的位置 + *@return 无 + */ + void moveSection(int logicalIndex, int from, int to); + void setOffset(int offset); + void currentChanged(const QModelIndex ¤t, const QModelIndex &previous); +private: + Q_DECLARE_PRIVATE(GFooterView) +}; + +/** + * @brief FooterView的Delegate, 不能编辑 + */ +class GLDTABLEVIEWSHARED_EXPORT GFooterViewDelegate : public GlodonDefaultItemDelegate +{ +public: + explicit GFooterViewDelegate(QObject *parent = 0); + GEditStyle editStyle(const QModelIndex &index, bool &readOnly) const; +}; + +#endif // GLDFOOTERVIEW_H + diff --git a/GCR/trunk/Glodon/include/GLD/GLDFooterView_p.h b/GCR/trunk/Glodon/include/GLD/GLDFooterView_p.h new file mode 100644 index 00000000..a9892457 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDFooterView_p.h @@ -0,0 +1,13 @@ +#ifndef GLDFOOTERVIEW_P_H +#define GLDFOOTERVIEW_P_H + +#include "GLDTableView_p.h" + +class GFooterViewPrivate : public GlodonTableViewPrivate +{ + Q_DECLARE_PUBLIC(GFooterView) +public: + GFooterViewPrivate() {} +}; + +#endif // GLDFOOTERVIEW_P_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDGlobal.h b/GCR/trunk/Glodon/include/GLD/GLDGlobal.h new file mode 100644 index 00000000..15d45331 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDGlobal.h @@ -0,0 +1,77 @@ +#ifndef GLDGLOBAL_H +#define GLDGLOBAL_H + +#include "GLDCommon_Global.h" + +#ifdef GDP_QT +# include +# define G_ASSERT(cond) Q_ASSERT(cond) +# ifndef assert +# define assert(cond) Q_ASSERT(cond) +# endif +# define G_ASSERT_X(cond, where, what) Q_ASSERT_X(cond, where, what) +# define G_UNUSED(x) (void)x; +#else +# define G_ASSERT(cond) Q_ASSERT(cond) +# define assert(cond) Q_ASSERT(cond) +# define G_ASSERT_X(cond, where, what) Q_ASSERT_X(cond, where, what) +# define G_UNUSED(x) (void)x; +#endif + +#define freePtr(p) {if (p) {delete p;}} +#define freeAndNil(p) {if (p) {delete p; p = NULL;}} +#define freeAndNilIntf(p) {if (p) {p->Release(); p = NULL;}} +#define freeAndNilArray(p) {if (p) {delete[] p; p = NULL;}} +#define freeAndNilByGFree(p) {if (p) {gFree(p); p = NULL;}} +#define doNothingMacro() + +#define MaxInt 0x7FFFFFFF +#define MinInt 0x80000000 +#define MaxListSize 0x07FFFFFF +#define MINCHAR 0x80 +#define MAXCHAR 0x7f +#define MINSHORT 0x8000 +#define MAXSHORT 0x7fff +#define MINLONG 0x80000000 +#define MAXLONG 0x7fffffff +#define MINDOUBLE 2.2250738585072014e-308 +#define MAXDOUBLE 1.7976931348623158e+308 +#define MAXBYTE 0xff +#define MAXWORD 0xffff +#define MAXDWORD 0xffffffff + +const long long c_MaxInt64 = 0x7FFFFFFFFFFFFFFF; +const long long c_MinInt64 = 0x8000000000000000; + +GLDCOMMONSHARED_EXPORT void *gMalloc(size_t size); +GLDCOMMONSHARED_EXPORT void gFree(void *ptr); +GLDCOMMONSHARED_EXPORT void *gRealloc(void *ptr, size_t size); +GLDCOMMONSHARED_EXPORT void *gMemCopy(void *dest, const void *src, size_t n); +GLDCOMMONSHARED_EXPORT void *gMemSet(void *dest, int c, size_t n); +GLDCOMMONSHARED_EXPORT void gMemMove(void *dest, const void *src, size_t n); + +//void *gMallocAligned(size_t size, size_t alignment); +//void *gReallocAligned(void *ptr, size_t size, size_t oldsize, size_t alignment); +//void gFreeAligned(void *ptr); +//void freeAndNil(void **p); + +#ifdef TEST_GSP +#include +#include + +extern int g_sumTime; +extern int g_sumCount; +#define TEST_START \ + DWORD startTime = GetTickCount(); + +#define TEST_END \ + g_sumTime += GetTickCount() - startTime; \ + ++g_sumCount; + +#else +#define TEST_START +#define TEST_END +#endif + + +#endif // GLDGLOBAL_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDGridSetting.h b/GCR/trunk/Glodon/include/GLD/GLDGridSetting.h new file mode 100644 index 00000000..b7a2c5ad --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDGridSetting.h @@ -0,0 +1,2008 @@ +#ifndef GLDGRIDSETTING_H +#define GLDGRIDSETTING_H + +#include "GLDSystem.h" +#include "GLDString.h" +#include "GLDIntList.h" +#include "GLDXMLTypes.h" +#include "GLDUITypes.h" +#include "GLDObject.h" +#include "GLDExtPropDefs.h" + +typedef unsigned char FontStyles; + +extern GLDTABLEVIEWSHARED_EXPORT const char *g_GLDGridSettingVersion; // "2.2.5"; +extern GLDTABLEVIEWSHARED_EXPORT const char *g_EditText; // "@EditText"; +extern GLDTABLEVIEWSHARED_EXPORT const char *g_TitleCaptionDelimiter; // "||"; +DEF_RESOURCESTRING3(CDefInvalidValueLabel, "!非法值"); // 缺省非法值显示标签 +extern GLDTABLEVIEWSHARED_EXPORT const GString CDefFontName; +DEF_RESOURCESTRING3(CDefFormatStr, ""); +DEF_RESOURCESTRING3(CDefComment, ""); +DEF_RESOURCESTRING3(CDelimiter, "*##*"); +extern GLDTABLEVIEWSHARED_EXPORT const GString c_GLDCellSuitTypeStrings[4]; +extern GLDTABLEVIEWSHARED_EXPORT const GString c_GLDGridRuleTypeStrings[20]; + +const int CDefDisplayWidth = 80; // 缺省列宽 +const int CDefTitleRowHeight = 20; // 缺省标题行高 +const int CDefFilterRowHeight = 20; // 缺省过滤行高 +const int CDefRowHeight = 18; // 缺省行高 +const int CDefFixedCols = 1; // 缺省固定列 +const int CDefFixedEditRows = 0; // 缺省可编辑固定行数 +const int CDefFixedEditCols = 0; // 缺省可编辑固定列数 +const int CDefCellHorzMargin = 2; // 缺省水平间隙 +const int CDefCellVertMargin = 2; // 缺省垂直间隙 +const int CDefGridLineWidth = 1; // 缺省格线宽 +const GRgb CDefGridLineColor = qRgb(125,125,125); // 缺省格线颜色 +const GRgb CDefGridColor = qRgb(255,255,255); // 缺省表格颜色 +const GRgb CDefBoundLineColor = qRgb(0,0,0); // 缺省框线颜色 + +const int DefFontSize = 9; +const GRgb DefForeColor = qRgb(0,0,0); +const GRgb DefBackColor = qRgb(255,255,255); +//todo yaok +//DefFontStyle = []; + +const int DefLeftLineWidth = 0; +const int DefTopLineWidth = 0; +const int DefRightLineWidth = 0; +const int DefBottomLineWidth = 0; +const int DefDiagonalWidth = 0; +const int DefAntiDiagonalWidth = 0; + +const bool DefNullIsZero = false; +const int CDefHorzMargin = 2; +const int CDefVertMargin = 2; +const bool CDefHandleSymbol = false; +const int CDefImageIndex = -1; + +const int DefHorzMargin = 2; +const int DefVertMargin = 2; +const int DefImageIndex = -1; + +const bool CDefShowComment = false; + +const wchar_t CExpressionMark = '&'; // 标记字段值为表达式前缀 +const wchar_t CLookupMark = '#'; // 标记查询字段前缀 + +enum GLDPersistentStyle +{ + gpsFromDFM = 0, + gpsFromFile = 1 +}; + +enum GLDTotalStyle +{ + gtsByTree = 0, + gtsByList = 1 +}; + +// 单元格自动折行类型 +enum GLDCellSuitType +{ + gcstFixed, + gcstSuitRowHeight, + gcstSuitColWidth, + gcstFitColWidth +}; + +// 水平对齐方式 +enum GLDHorzAlignment +{ + ghaAuto, + ghaLeftJustify, + ghaRightJustify, + ghaCenter +}; + +// 垂直对齐方式 +enum GLDVertAlignment +{ + gvaAuto, + gvaTopJustify, + gvaBottomJustify, + gvaCenter +}; + +// 显示规则类型 +enum GLDGridRuleType +{ + grtFont = 0, + grtBackColor = 1, + grtEditStyle = 2, + grtBoundLine = 3, + grtAlignment = 4, + grtMargin = 5, + grtReadonly = 6, + grtCanFocus = 7, + grtHandleSymbol = 8, + grtImage = 9, + grtComment = 10, + grtVisible = 11, + grtMerge = 12, + grtRejectDelete = 13, + grtRejectInsert = 14, + grtRejectInsertChild = 15, + grtRejectMove = 16, + grtRejectLevel = 17, + grtEditForm = 18, + grtClearCell = 19 +}; + +const int CGridRuleTypeCount = 20; + +const GLDEditStyle CDefEditStyle = gesAuto; + +// 视图编辑器属性缺省值 +const int CDefFontSize = 9; +const GRgb CDefFontColor = qRgb(0, 0, 0); +const FontStyles CDefFontStyles= 0; +const GRgb CDefBackColor = qRgb(125,125,125); +const int CDefRightLine = 0; +const int CDefBottomLine = 0; +const int CDefDiagonal = 0; +const int CDefAntiDiagonal = 0; + +enum GLDCellImageLayout +{ + gclImageLeft = 0, + gclImageRight = 1, + gclImageTop = 2, + gclImageBottom = 3 +}; + +const GLDHorzAlignment DefTitleHorzAlignment = ghaCenter; + +typedef unsigned char GLDBaseDataType; +typedef unsigned char GLDDataType; + +struct GLDSortState +{ + inline GLDSortState() : sortIndex(-1), asc(true), dataType(0), col(-1) {} + int sortIndex; + bool asc; + GLDBaseDataType dataType; + int col; +}; + +const GLDHorzAlignment CDefHorzAlignment = ghaAuto; +const GLDVertAlignment CDefVertAlignment = gvaCenter; +const GLDVertAlignment DefVertAlignment = gvaAuto; +const GLDHorzAlignment DefHorzAlignment = ghaAuto; +const GLDCellImageLayout CDefImageLayout = gclImageLeft; + +const bool CDefReadonly = true; +const bool CDefCanFocus = true; +const bool CDefVisible = true; + +class GLDGridRule; +class GLDGridRules; +class CGLDExtPropDefs; +class GLDFontRule; +class GLDEditStyleRule; +class GLDBackColorRule; +class GLDBoundLineRule; +class GLDAlignRule; +class GLDMarginRule; +class GLDReadonlyRule; +class GLDCanFocusRule; +class GLDHandleSymbolRule; +class GLDImageRule; +class GLDVisibleRule; +class GLDCommentRule; +class GLDMergeRule; +class GLDRejectDeleteRule; +class GLDRejectRule; +class GLDRejectDeleteRule; +class GLDRejectInsertRule; +class GLDRejectInsertChildRule; +class GLDRejectMoveRule; +class GLDRejectLevelRule; +class GLDEditFormRule; +class GLDClearCellRule; + +class GLDCustomGridSetting; +class GLDGridSetting; +class GLDTableSettings; +class GLDTableSetting; +class GLDColSettings; +class GLDColSetting; +class GLDFilterRows; +class GLDFilterRow; +class GLDTitleRows; +class GLDTitleRow; +class GLDHeaderRowFieldSettings; +class GLDHeaderRowFieldSetting; +class GLDExpandRowFieldSettings; +class GLDExpandRowFieldSetting; +class GLDTotalRowFieldSettings; +class GLDTotalRowFieldSetting; +class GLDCellFormats; +class GLDCellFormat; +class GLDFieldSettings; +class GLDFieldSetting; +class GLDCustomFieldSetting; +class GLDFilterCell; +class GLDTitleCell; + +class GLDRecordGridSetting; +class GLDRecordSettings; +class GLDRecordSetting; +class GLDRecordFieldSettings; +class GLDRecordFieldSetting; +class GLDRecordGridRules; + +typedef GLDVector GLDColSettingVector; + +class GLDTABLEVIEWSHARED_EXPORT GLDDBGridSettingNotifyEvent +{ +public: + virtual void doEvent(GLDCustomGridSetting *sender) = 0; +}; + +typedef GLDVector GLDGridSettingNotifyEventList; +class GLDTABLEVIEWSHARED_EXPORT GLDCustomGridSetting +{ +public: + GLDCustomGridSetting(); + virtual ~GLDCustomGridSetting(); + + bool active() const; + void setActive(const bool value); + GLDPersistentStyle persistentStyle() const; + void setPersistentStyle(const GLDPersistentStyle value); + GString persistentValue() const; + void setPersistentValue(const GString &value); + +public: + void reLoad(); + void reBuild(); + virtual void reBuildPersistentValue(); + void assignData(GLDCustomGridSetting &source); + virtual void clearData() = 0; + + virtual void saveToFile(const GString &fileName) = 0; + virtual void loadFromStream(GStream *stream); + virtual void saveToStream(GStream *stream); + virtual GString shortIdentity(); + virtual GString fullIdentity(); + + void refreshRule(GLDGridRule *rule); + + bool designState() const; + void setDesignState(bool value); + GString version() const; + GString description() const; + void setDescription(GString value); + GString remark() const; + void setRemark(GString value); + GString identity() const; + void setIdentity(GString value); + unsigned char leftMargin() const; + void setLeftMargin(unsigned char value); + unsigned char rightMargin() const; + void setRightMargin(unsigned char value); + unsigned char topMargin() const; + void setTopMargin(unsigned char value); + unsigned char bottomMargin() const; + void setBottomMargin(unsigned char value); + unsigned char gridLineWidth() const; + void setGridLineWidth(unsigned char value); + GRgb gridLineColor() const; + void setGridLineColor(GRgb value); + GRgb gridColor() const; + void setGridColor(GRgb value); + GRgb boundLineColor() const; + void setBoundLineColor(GRgb value); + unsigned short fixedCols() const; + void setFixedCols(unsigned short value); + unsigned short fixedEditCols() const; + void setFixedEditCols(unsigned short value); + unsigned short fixedEditRows() const; + void setFixedEditRows(unsigned short value); + bool showAsTree() const; + void setShowAsTree(bool value); + bool editing() const; + void setEditing(bool value); + bool vertLine() const; + void setVertLine(bool value); + bool horzLine() const; + void setHorzLine(bool value); + bool rowSizing() const; + void setRowSizing(bool value); + bool colSizing() const; + void setColSizing(bool value); + bool colMoving() const; + void setColMoving(bool value); + bool allowSelectRow() const; + void setAllowSelectRow(bool value); + bool allowSelectCol() const; + void setAllowSelectCol(bool value); + bool allowSelectAll() const; + void setAllowSelectAll(bool value); + bool multiSelection() const; + void setMultiSelection(bool value); + GString invalidValueLabel() const; + void setInvalidValueLabel(GString value); + bool alwaysShowEditor() const; + void setAlwaysShowEditor(bool value); + bool rangeSelect() const; + void setRangeSelect(bool value); + bool autoThemeAdapt() const; + void setAutoThemeAdapt(bool value); + bool returnKeyAsTab() const; + void setReturnKeyAsTab(bool value); + bool showFixedRow() const; + void setShowFixedRow(bool value); + bool cellFilling() const; + void setCellFilling(bool value); + bool fixedCellEvent() const ; + void setFixedCellEvent(bool value); + bool allow3DStyle() const; + void setAllow3DStyle(bool value); + bool allowCopyPaste() const; + void setAllowCopyPaste(bool value); + bool borderStyle() const; + void setBorderStyle(bool value); + bool hideEditOnExit() const; + void setHideEditOnExit(bool value); + bool useBlendColor() const; + void setUseBlendColor(bool value); + bool cellFillEditField() const; + void setCellFillEditField(bool value); + CGLDExtPropDefs *extPropDefs() const; + PtrInt tag() const; + void setTag(PtrInt tag); + GLDGridSettingNotifyEventList *afterActiveEventList(); + //GSPGridSettingNotifyEventList * beforeDeactiveEventList();//todo event + +protected: + virtual void compile() = 0; + virtual void clearCompileInfo() = 0; + virtual GString saveDialogDefaultExt() = 0; + virtual GString saveDialogFilter() = 0; + virtual void loadGridSetting() = 0; + virtual GString fileName(); + virtual void doAfterActive(); + virtual void doBeforeDeactive(); + virtual void doLoadFromXML(GXMLDocument &doc) = 0; + virtual void doLoadFromFile(const GString &fileName) = 0; + virtual void doSaveToXML(GXMLDocument &doc) = 0; + virtual void loaded(); + virtual void doLoad(); + virtual void doUnload(); + +protected: + bool m_active; + bool m_loaded; + + CGLDExtPropDefs *m_extProps; + //派生有操作 + unsigned short m_fixedCols; //全局选项 固定列数 1 + unsigned short m_fixedEditCols; //全局选项 可编辑固定列数 3 + unsigned short m_fixedEditRows; //全局选项 可编辑固定行数 2 + unsigned char m_leftMargin; //全局选项 内容与格线水平空间? 4 + unsigned char m_rightMargin; //全局选项 内容与格线垂直空间? 5 + unsigned char m_topMargin; //全局选项 + unsigned char m_bottomMargin; + unsigned char m_gridLineWidth; + GRgb m_gridLineColor; + GRgb m_gridColor; + GRgb m_boundLineColor; + GString m_invalidValueLabel; + bool m_showAsTree; + bool m_editing; + bool m_vertLine; + bool m_horzLine; + bool m_rowSizing; + bool m_colSizing; + bool m_colMoving; + bool m_allowSelectRow; + bool m_allowSelectCol; + bool m_allowSelectAll; + bool m_multiSelection; + + bool m_alwaysShowEditor; + bool m_rangeSelect; + bool m_autoThemeAdapt; + bool m_returnKeyAsTab; + bool m_showFixedRow; + bool m_cellFilling; + bool m_fixedCellEvent; + bool m_allow3DStyle; + bool m_allowCopyPaste; + bool m_borderStyle; + bool m_hideEditOnExit; + bool m_useBlendColor; + bool m_cellFillEditField; + bool m_designState; + GLDPersistentStyle m_persistentStyle; + +private: + void designing_DfmToFile(); + void designing_FileToDfm(); +protected: + + GString m_persistentValue; //持久化对象名称(也就是gsf文件名) + GString m_description; //xml头部信息中标签Description里的内容 + GString m_remark; //同上remark中的内容 + GString m_identity; //怀疑对应于基本信息中的名称(Delphi版的未保存该值) + + GLDGridSettingNotifyEventList *m_afterActiveEventList; + //GSPGridSettingNotifyEventList *beforeDeactiveEventList_;//todo event + PtrInt m_tag; +}; + +class GLDTABLEVIEWSHARED_EXPORT GLDGridSetting: public GLDCustomGridSetting +{ +public: + GLDGridSetting(); + virtual ~GLDGridSetting(); + + virtual void initialize(); + static GLDGridSetting *createGLDGridSetting(); + + /*此函数供组件编辑器使用 */ + void saveToFile(const GString &fileName); + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + void clearData(); + virtual void compileExpandRow(); + + bool allowSort() const; + void setAllowSort(bool value); + GString sortFieldNames() const; + void setSortFieldNames(GString value); + int ascImageIndex() const; + void setAscImageIndex(int value); + int descImageIndex() const; + void setDescImageIndex(int value); + bool totalRowAtFooter() const; + void setTotalRowAtFooter(bool value); + + GLDColSettings *colSettings() const; + GLDTitleRows *titleRows() const; + GLDFilterRows *filterRows() const; + GLDTableSettings *tableSettings() const; + + void setTableSettings(GLDTableSettings *pTableSettings); +public: + ULONG AddControlRef(); + ULONG ReleaseControlRef(); +protected: + void compile(); + void clearCompileInfo(); + void loadGridSetting(); + void doLoadFromXML(GXMLDocument &doc); + void doLoadFromFile(const GString &fileName); + void doSaveToXML(GXMLDocument &doc); + GString saveDialogDefaultExt(); + GString saveDialogFilter(); +protected: + bool m_allowSort; + GString m_sortFieldName; + int m_ascImageIndex; + int m_descImageIndex; + bool m_totalRowAtFooter; + GLDColSettings *m_colSettings; + GLDTitleRows *m_titleRows; + GLDFilterRows *m_filterRows; + GLDTableSettings *m_tableSettings; + ULONG m_controlRef; +}; + +// 表设置容器类 +class GLDTABLEVIEWSHARED_EXPORT GLDTableSettings +{ +public: + GLDTableSettings(GLDGridSetting *owner); + virtual ~GLDTableSettings(); + + GLDGridSetting *owner() const; + bool hasHeaderOrTotalRow() const; + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + + void clone(GLDTableSetting *protoType, int insertIndex, int count); + void clearClonedTableSetting(); + virtual GLDTableSetting *insert(int index = -1); + void Delete(int index); + void move(int fromIndex, int toIndex); + void clear(); + int count() const; + virtual void setCount(const int value); + int indexOf(GLDTableSetting *tableSetting) const; + GLDTableSetting *items(int index); + GLDTableSetting *operator[](int index); + GLDTableSetting *createTableSetting(GLDTableSettings *owner); + virtual GLDTableSetting *doCreateTableSetting(GLDTableSettings *owner); + + void compile(); + void clearCompileInfo(); +protected: + GLDGridSetting *m_owner; + bool m_hasHeaderOrTotalRow; + GObjectList* m_list; +}; + +// 列设置容器类 +class GLDTABLEVIEWSHARED_EXPORT GLDColSettings +{ +public: + GLDColSettings(GLDGridSetting *owner); + virtual ~GLDColSettings(); + + GLDGridSetting *owner() const; + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + + virtual void clearCompileInfo(); + void clone(GLDColSetting *protoType, int insertIndex, int count); + void clearClonedColSetting(); + GLDColSetting *insert(int index = -1); + void Delete(int index); + void move(int fromIndex, int toIndex); + void clear(); + int indexOf(GLDColSetting *colSetting) const; + GLDColSetting *findColSetting(const GString &identity); + int visibleColCount(); + int fixedColCount(); + GIntList suitRowHeightCols(); // todo + GIntList suitColWidthCols(); + GIntList fitColWidthCols(); + int count() const; + void setCount(int value); + GLDColSetting *items(int index) const; + GLDColSetting *operator[](int index); + GObjectList &visibleCondItems(); + virtual void compile(); + virtual GLDColSetting *createColSetting(GLDColSettings *owner); + virtual GLDFieldSetting *createFieldSetting(GLDFieldSettings *owner); + virtual GLDHeaderRowFieldSetting *createHeaderRowFieldSetting(GLDHeaderRowFieldSettings *owner); + virtual GLDTotalRowFieldSetting *createTotalRowFieldSetting(GLDExpandRowFieldSettings *owner); + virtual GLDTitleCell *createTitleCell(GLDTitleRow *owner); + virtual GLDFilterCell *createFilterCell(GLDFilterRow *owner); +protected: + virtual int findParserIndex(const GString &expr); +protected: + GLDGridSetting *m_owner; + GLDColSettingVector m_list; + GObjectList m_visibleCondItems; +}; + +// 列设置类 +class GLDTABLEVIEWSHARED_EXPORT GLDColSetting +{ +public: + GLDColSetting(GLDColSettings *owner); + virtual ~GLDColSetting(); + + void clearCompileInfo(); + void compile(); + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + + virtual void refreshVisibleState(int col); + GString fullIdentity(); + + int displayWidth() const; + void setDisplayWidth(int value); + bool enabled() const; + void setEnabled(bool value); + int calcedWidth() const; + void setCalcedWidth(int value); + int zoomWidth() const; + void setZoomWidth(int value); + int originWidth() const; + void setOriginWidth(int value); + int originIndex() const; + void setOriginIndex(int value); + GString visibleCondition() const; + void setVisibleCondition(const GString &value); + bool visible() const; + void setVisible(bool value); + GLDCellSuitType cellSuitType() const; + void setCellSuitType(GLDCellSuitType value); + int index(); + bool isFixedCol(); + GString identity() const; + void setIdentity(GString value); + GString extData() const; + void setExtData(GString value); + CGLDExtPropDefs *extPropDefs() const; + bool cloneFlag() const; + void setCloneFlag(bool value); + bool crossExtFlag() const; + void setCrossExtFlag(bool value); + PtrInt tag() const; + void setTag(PtrInt value); + GLDGridSetting *gridSetting() const; + GLDColSettings *owner(); +protected: + GLDColSettings *m_owner; + int m_displayWidth; + int m_calcedWidth; + int m_zoomWidth; + int m_originWidth; // 为了外部保存配置用 + int m_originIndex; // 为了外部保存配置用 + bool m_visible; + bool m_enabled; // Enable=False等价于Visible=False + bool m_cloneFlag; + bool m_crossExtFlag; // 交叉表动态扩展标志 + GLDCellSuitType m_cellSuitType; + GString m_visibleCondition; + GString m_identity; + GString m_extData; + CGLDExtPropDefs *m_extProps; + PtrInt m_tag; +}; + +// 表设置类 +class GLDTABLEVIEWSHARED_EXPORT GLDTableSetting +{ +public: + GLDTableSetting(GLDTableSettings *owner); + virtual ~GLDTableSetting(); + + GLDTableSettings *owner() const; + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + + virtual GLDTableSetting *clone(); + void deleteHeaderRow(int index); + void deleteTotalRow(int index); + void clearTotalRows(); + void clearHeaderRows(); + GLDHeaderRowFieldSettings *insertHeaderRow(int index = -1); + GLDTotalRowFieldSettings *insertTotalRow(int index = -1); + int index() const; + int defRowHeight() const; + void setDefRowHeight(int value); + + GLDFieldSettings *fieldSettings() const; + CGLDExtPropDefs *extPropDefs() const; + bool hasHeaderRow(); + bool hasTotalRow(); + GString refDatabaseName() const; + void setRefDatabaseName(const GString &value); + GString refTableName() const; + void setRefTableName(const GString &value); + GString refFullName(); + GLDGridRules *rules() const; + PtrInt tag() const; + void setTag(const PtrInt value); + int headerRowCount() const; + int totalRowCount() const; + GLDHeaderRowFieldSettings *headerRows(int index); + GLDTotalRowFieldSettings *totalRows(int index); + + bool customDataSource() const; + void setCustomDataSource(const bool &value); + GString masterViewName() const; + void setMasterViewName(const GString &value); + GString selfFieldName() const; + void setSelfFieldName(const GString &value); + GString masterFieldName() const; + void setMasterFieldName(const GString &value); + GString primaryKeyFieldName() const; + void setPrimaryKeyFieldName(const GString &value); + GString parentKeyFieldName() const; + void setParentKeyFieldName(const GString &value); + bool isTree() const; + void setIsTree(bool value); + bool isTreeWithMasterView() const; + void setIsTreeWithMasterView(bool value); + GLDTotalStyle totalStyle() const; + void setTotalStyle(GLDTotalStyle value); + bool needExpandTotalExpr() const; + void setNeedExpandTotalExpr(const bool value); + bool cloneFlag() const; + void setCloneFlag(bool value); + + virtual void compile(); + void clearCompileInfo(); + virtual void initialize(); + virtual GLDTableSetting *createTableSetting(GLDTableSettings *owner); + virtual GLDHeaderRowFieldSettings *createHeaderRowFieldSettings(GLDTableSetting *owner); + virtual GLDTotalRowFieldSettings *createTotalRowFieldSettings(GLDTableSetting *owner); +protected: + GLDTableSettings *m_owner; + int m_defRowHeight; + GObjectList m_headerRows; + GObjectList m_totalRows; + GLDFieldSettings *m_fieldSettings; + GLDGridRules *m_rules; + GString m_refDatabaseName; + GString m_refTableName; + PtrInt m_tag; + bool m_cloneFlag; + + // 带区设置 + CGLDExtPropDefs *m_extProps; + bool m_customDataSource; + GString m_masterViewName; + GString m_selfFieldName; + GString m_masterFieldName; + GString m_primaryKeyFieldName; + GString m_parentKeyFieldName; + bool m_isTree; + bool m_isTreeWithMasterView; + GLDTotalStyle m_totalStyle; + bool m_needExpandTotalExpr; +}; + +// 过滤行容器 +class GLDTABLEVIEWSHARED_EXPORT GLDFilterRows +{ +public: + GLDFilterRows(GLDGridSetting *owner); + virtual ~GLDFilterRows(); + + GLDGridSetting *owner() const; + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + GLDFilterRow *insert(int index = -1); + void Delete(int index); + void clear(); + int count() const; + void setCount(const int value); + int indexOf(GLDFilterRow *value) const; + GLDFilterRow *items(int index); + GLDFilterRow *operator[](int index); + void compile(); + void clearCompileInfo(); + virtual GLDFilterRow *createFilterRow(GLDFilterRows *owner); +protected: + GLDGridSetting *m_owner; + GObjectList m_list; +}; + +// 过滤行 +class GLDTABLEVIEWSHARED_EXPORT GLDFilterRow +{ +public: + GLDFilterRow(GLDFilterRows *owner); + virtual ~GLDFilterRow(); + + GLDFilterRows *owner() const; + int indexOf(GLDFilterCell *value); + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + int index() const; + int rowHeight() const; + void setRowHeight(const int &value); + int cellCount() const; + GLDFilterCell *cells(int index); + void setCellCount(int value); + void Delete(int index); + void compile(); + void clear(); + void clearCompileInfo(); + GLDFilterCell *cellByCaption(const GString &caption); + GLDFilterCell *operator[](int index); + GObjectList &list(); + virtual GLDFilterCell *creatrFilterCell(GLDFilterRow *owner); +protected: + GLDFilterRows *m_owner; + GObjectList m_list; + int m_rowHeight; +}; + +// 过滤单元格 +class GLDTABLEVIEWSHARED_EXPORT GLDFilterCell +{ +public: + GLDFilterCell(GLDFilterRow *owner); + virtual ~GLDFilterCell(); + virtual void compile(); + virtual void clearCompileInfo(); + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + int index(); + int rowIndex(); + int colIndex(); + bool isLabel() const; + GString caption() const; + void setCaption(const GString &value); + GString editorName() const; + void setEditorName(const GString &value); + int mergeID() const; + void setMergeID(const int &value); + bool isFixedCol(); + GLDCellFormat *cellFormat() const; + void setCellFormat(GLDCellFormat *value); + GLDGridSetting *gridSetting(); +protected: + GLDFilterRow *m_owner; + GString m_caption; + GString m_editorName; + int m_mergeID; + bool m_isLabel; + GLDCellFormat *m_cellFormat; +}; + +// 标题行容器 +class GLDTABLEVIEWSHARED_EXPORT GLDTitleRows +{ +public: + GLDTitleRows(GLDGridSetting *owner); + virtual ~GLDTitleRows(); + + GLDGridSetting *owner() const; + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + GString fullTitle(int index) const; + GLDTitleRow *insert(int index = -1); + void Delete(int index); + void clear(); + int count() const; + void setCount(const int value); + GLDTitleRow *items(int index) const; + int indexOf(GLDTitleRow * value) const; + GLDTitleRow *operator[](int index); + + void compile(); + void clearCompileInfo(); + GLDTitleRow *createTitleRow(GLDTitleRows *owner); + virtual GLDTitleRow *doCreateTitleRow(GLDTitleRows *owner); +protected: + GLDGridSetting *m_owner; + GObjectList m_list; +}; + +// 标题单元格 +class GLDTABLEVIEWSHARED_EXPORT GLDTitleCell +{ +public: + GLDTitleCell(GLDTitleRow *owner); + virtual ~GLDTitleCell(); + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + virtual void compile(); + virtual void clearCompileInfo(); + + int index() const; + int colIndex() const; + int rowIndex() const; + GLDGridSetting *gridSetting(); + + bool isLabel() const; + GString caption() const; + void setCaption(const GString &value); + int mergeID() const; + void setMergeID(const int &value); + GLDCellFormat *cellFormat() const; + void setCellFormat(GLDCellFormat *value); + GLDTitleRow *owner(); +protected: + GLDTitleRow *m_owner; + GString m_caption; + int m_mergeID; + bool m_isLabel; + GLDCellFormat *m_cellFormat; +}; + +// 标题行 +class GLDTABLEVIEWSHARED_EXPORT GLDTitleRow +{ +public: + GLDTitleRow(GLDTitleRows *owner); + virtual ~GLDTitleRow(); + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + int index(); + + void setCellCount(int value); + void compile(); + void clear(); + void clearCompileInfo(); + GLDTitleCell *cellByCaption(const GString &caption); + void Delete(int index); + GLDGridSetting *gridSetting(); + + virtual GLDTitleCell *createTitleCell(GLDTitleRow *owner); + + int rowHeight() const; + void setRowHeight(int value); + int cellCount() const; + GLDTitleCell *cells(const int index) const; + GObjectList &list(); +protected: + GLDTitleRows *m_owner; + GObjectList m_list; + int m_rowHeight; +}; + +// 扩展行字段设置容器类 +class GLDTABLEVIEWSHARED_EXPORT GLDExpandRowFieldSettings +{ +public: + GLDExpandRowFieldSettings(GLDTableSetting *owner); + virtual ~GLDExpandRowFieldSettings(); + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + GStringList toValueArray(); + void Delete(int index); + void clear(); + + int count() const; + void setCount(int value); + + bool visible() const; + void setVisible(bool value); + int rowHeight() const; + void setRowHeight(int value); + GLDTableSetting *owner() const; + GLDExpandRowFieldSetting *items(int index); + GObjectList &list(); + GLDExpandRowFieldSetting *operator[](int index); +protected: + virtual GLDExpandRowFieldSetting *createExpandRowFieldSetting(); +protected: + GObjectList m_list; + GLDTableSetting *m_owner; + bool m_visible; + int m_rowHeight; +}; + +// 带区标题行字段设置容器类 +class GLDTABLEVIEWSHARED_EXPORT GLDHeaderRowFieldSettings: public GLDExpandRowFieldSettings +{ +public: + inline GLDHeaderRowFieldSettings(GLDTableSetting *owner): GLDExpandRowFieldSettings(owner) {} + + GLDHeaderRowFieldSetting *items(int index); + inline GLDHeaderRowFieldSetting *operator[](int index) { return items(index); } +protected: + virtual GLDExpandRowFieldSetting *createExpandRowFieldSetting(); +}; + +// 扩展行字段设置类 +class GLDTABLEVIEWSHARED_EXPORT GLDExpandRowFieldSetting +{ +public: + GLDExpandRowFieldSetting(GLDExpandRowFieldSettings *owner); + virtual ~GLDExpandRowFieldSetting(); + + virtual void compile(); + virtual void clearCompileInfo(); + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + + bool isSimpleStr() const; + int mergeID() const; + void setMergeID(int value); + GLDDataType resultDataType() const; + GString value() const; + void setValue(GString value); + int index(); + GLDCellFormat *cellFormat() const; + void setCellFormat(GLDCellFormat *value); + bool isFixedCol(); + + virtual int varCount(); + virtual GString varCodes(int index); + virtual void setVarCodes(int index, const GString &value); +private: + int tableIndex(); + GString refFullName(); +protected: + bool m_isSimpleStr; + int m_mergeID; + GLDExpandRowFieldSettings *m_owner; + GLDDataType m_resultDataType; + GString m_value; + GLDCellFormat *m_cellFormat; +}; + +// 合计字段设置类 +class GLDTABLEVIEWSHARED_EXPORT GLDHeaderRowFieldSetting: public virtual GLDExpandRowFieldSetting +{ +public: + inline GLDHeaderRowFieldSetting(GLDExpandRowFieldSettings *owner): GLDExpandRowFieldSetting(owner) {} + virtual void compile(); +}; + +// 合计字段设置容器类 +class GLDTABLEVIEWSHARED_EXPORT GLDTotalRowFieldSettings: public GLDExpandRowFieldSettings +{ +public: + inline GLDTotalRowFieldSettings(GLDTableSetting *owner) : GLDExpandRowFieldSettings(owner){} + GLDTotalRowFieldSetting *items(int index); + inline GLDTotalRowFieldSetting *operator[](int index) { return items(index); } +protected: + virtual GLDExpandRowFieldSetting *createExpandRowFieldSetting(); +}; + +// 合计字段设置类 +class GLDTABLEVIEWSHARED_EXPORT GLDTotalRowFieldSetting: virtual public GLDExpandRowFieldSetting +{ +public: + inline GLDTotalRowFieldSetting(GLDExpandRowFieldSettings *owner) : GLDExpandRowFieldSetting(owner) {} + virtual void compile(); +}; + +class GLDTABLEVIEWSHARED_EXPORT GLDCellFormat +{ +public: + GLDCellFormat(); + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + + bool isEqual(GLDCellFormat *cellFormat); + + GRgb foreColor() const; + void setForeColor(const GRgb value); + GString fontName() const; + void setFontName(GString value); + int fontSize() const; + void setFontSize(int value); + FontStyles fontStyle() const; + void setFontStyle(FontStyles value); + GRgb backColor() const; + void setBackColor(const GRgb value); + GLDHorzAlignment horzAlignment() const; + void setHorzAlignment(const GLDHorzAlignment value); + GLDVertAlignment vertAlignment() const; + void setVertAlignment(const GLDVertAlignment value); + unsigned char leftLineWidth() const; + void setLeftLineWidth(const unsigned char value); + unsigned char topLineWidth() const; + void setTopLineWidth(unsigned char value); + unsigned char rightLineWidth() const; + void setRightLineWidth(unsigned char value); + unsigned char bottomLineWidth() const; + void setBottomLineWidth(unsigned char value); + unsigned char diagonalWidth() const; + void setDiagonalWidth(unsigned char value); + unsigned char antiDiagonalWidth() const; + void setAntiDiagonalWidth(unsigned char value); + GString formatStr() const; + void setFormatStr(const GString &value); + bool nullIsZero() const; + void setNullIsZero(const bool value); + unsigned char leftMargin() const; + void setLeftMargin(unsigned char value); + unsigned char rightMargin() const; + void setRightMargin(unsigned char value); + unsigned char topMargin() const; + void setTopMargin(unsigned char value); + unsigned char bottomMargin() const; + void setBottomMargin(unsigned char value); + int imageIndex() const; + void setImageIndex(int value); + GLDCellImageLayout imageLayout(); + void setImageLayout(GLDCellImageLayout value); + +protected: + GString m_fontName; + int m_fontSize; + int m_foreColor; + FontStyles m_fontStyle; + int m_backColor; + unsigned char m_leftLineWidth; + unsigned char m_topLineWidth; + unsigned char m_bottomLineWidth; + unsigned char m_rightLineWidth; + unsigned char m_diagonalWidth; + unsigned char m_antiDiagonalWidth; + int m_horzAlignment; + int m_vertAlignment; + GString m_formatStr; + bool m_nullIsZero; + unsigned char m_leftMargin; + unsigned char m_rightMargin; + unsigned char m_topMargin; + unsigned char m_bottomMargin; + GLDCellImageLayout m_imageLayout; + int m_imageIndex; +}; + +class GLDTABLEVIEWSHARED_EXPORT GLDCellFormats +{ +public: + GLDCellFormats(); + virtual ~GLDCellFormats(); + int count() const; + GLDCellFormat *formats(const int index) const; + GLDCellFormat *operator[](int index) { return formats(index); } +protected: + GObjectList *m_list; +}; + +// 字段设置容器类 +class GLDTABLEVIEWSHARED_EXPORT GLDFieldSettings +{ +public: + GLDFieldSettings(GLDTableSetting *owner); + virtual ~GLDFieldSettings(); + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + + void setCount(int value); + void Delete(int index); + void clear(); + + virtual GLDFieldSetting *createFieldSetting(GLDFieldSettings *owner); + + GLDFieldSetting *items(int index); + int count() const; + GLDTableSetting *owner() const; + GObjectList &list(); + GLDFieldSetting *operator[](int index); +protected: + GLDTableSetting *m_owner; + GObjectList m_list; +}; + +// 字段设置类 +class GLDTABLEVIEWSHARED_EXPORT GLDCustomFieldSetting +{ +public: + GLDCustomFieldSetting(); + virtual ~GLDCustomFieldSetting(); + + virtual void compile(); + virtual void clearCompileInfo(); + virtual int index() const = 0; + + virtual void loadFromStream(GStream *stream); + virtual void saveToStream(GStream *stream); + bool displayExprIsFieldName() const; + + GString displayFieldName() const; + + int mergeID() const; + void setMergeID(int value); + GString editFieldName() const; + void setEditFieldName(const GString &value); + GString displayExpr() const; + void setDisplayExpr(const GString &value); + GString saveFieldName() const; + void setSaveFieldName(const GString &value); + GString saveRule() const; + void setSaveRule(const GString &value); + GString nullValDisplayStr() const; + void setNullValDisplayStr(GString value); + virtual GString cellIdentity() const; + void setCellIdentity(const GString &value); + GString editorName() const; + void setEditorName(const GString &value); + GString extData() const; + void setExtData(GString value); + CGLDExtPropDefs *extPropDefs() const; + GLDCellFormat *cellFormat() const; + void setCellFormat(GLDCellFormat * value); + bool editTextIsDisplayText() const; + void setEditTextIsDisplayText(bool value); + + virtual unsigned char displayExprDataType() = 0; + virtual bool isLabel() const; + virtual int varCount() const; + virtual GString varCodes(int index) const; +protected: + virtual bool isValidFieldName(const GString &fieldName); + virtual bool isExprEnumDateTimeField(const GString &fieldName); + virtual void buildDisplayParser(); + virtual void buildSaveRuleParser(); + GString buildDisplayParserDisplayExpr(); + + virtual void setIsLabel(bool value); + + virtual bool designState() = 0; + + virtual int tableIndex() = 0; + virtual GString refFullName() = 0; + virtual GLDCustomGridSetting *gridSetting() = 0; +protected: + int m_mergeID; + GString m_editFieldName; + GString m_displayExpr; + GString m_saveFieldName; + GString m_saveRule; + GString m_nullValDisplayStr; + GString m_extData; + CGLDExtPropDefs *m_extProps; + GString m_editorName; // 二级窗体编辑器名 + GString m_cellIdentity; + GLDCellFormat *m_cellFormat; + bool m_displayExprIsFieldName; + bool m_editTextIsDisplayText; +}; + +// 字段设置类 +class GLDTABLEVIEWSHARED_EXPORT GLDFieldSetting: virtual public GLDCustomFieldSetting +{ +public: + GLDFieldSetting(GLDFieldSettings *owner); + virtual ~GLDFieldSetting(); + + bool designState(); + int index() const; + int tableIndex(); + GString refFullName(); + GLDCustomGridSetting *gridSetting(); + GLDDataType displayExprDataType(); + GString cellIdentity() const; + + bool isDefaultCellIdentity(); + GString title(); + bool isFixedCol(); + + GLDFieldSettings *owner() const; + GLDTableSetting *tableSetting() const; + GLDSortState sortState() const; + void setsortState(GLDSortState value); +protected: + GLDFieldSettings *m_owner; + GLDSortState m_sortState; +}; + +class GLDTABLEVIEWSHARED_EXPORT GLDCustomGridRules +{ +public: + GLDCustomGridRules(); + virtual ~GLDCustomGridRules(); + + void buildRuleArray(GLDGridRuleType ruleType); + void clearRuleArray(); + + virtual GLDCustomGridSetting *gridSetting() = 0; + virtual GString refFullName() = 0; + + virtual bool designState(); + virtual int tableIndex(); + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + void assign(GLDCustomGridRules *source); + GLDGridRule *insert(int index, GLDGridRuleType ruleType); + void Delete(int index); + void move(int fromIndex, int toIndex); + void clear(); + + bool hasRule(GLDGridRuleType ruleType); + GLDGridRule *findRule(GLDGridRuleType ruleType, const GString &ruleName); + + int count() const; + int indexOf(GLDGridRule* value) const; + GLDGridRule *items(int index) const; + GLDGridRule *operator[](int index) const { return items(index); } + + virtual GLDFontRule *createFontRule(GLDCustomGridRules *owner); + virtual GLDBackColorRule *createBackColorRule(GLDCustomGridRules *owner); + virtual GLDEditStyleRule *createEditStyleRule(GLDCustomGridRules *owner); + virtual GLDBoundLineRule *createBoundLineRule(GLDCustomGridRules *owner); + virtual GLDAlignRule *createAlignRule(GLDCustomGridRules *owner); + virtual GLDMarginRule *createMarginRule(GLDCustomGridRules *owner); + virtual GLDReadonlyRule *createReadonlyRule(GLDCustomGridRules *owner); + virtual GLDCanFocusRule *createCanFocusRule(GLDCustomGridRules *owner); + virtual GLDHandleSymbolRule *createHandleSymbolRule(GLDCustomGridRules *owner); + virtual GLDImageRule *createImageRule(GLDCustomGridRules *owner); + virtual GLDCommentRule *createCommentRule(GLDCustomGridRules *owner); + virtual GLDVisibleRule *createVisibleRule(GLDCustomGridRules *owner); + virtual GLDMergeRule *createMergeRule(GLDCustomGridRules *owner); + virtual GLDRejectDeleteRule *createRejectDeleteRule(GLDCustomGridRules *owner); + virtual GLDRejectInsertRule *createRejectInsertRule(GLDCustomGridRules *owner); + virtual GLDRejectInsertChildRule *createRejectInsertChileRule(GLDCustomGridRules *owner); + virtual GLDRejectMoveRule *createRejectMoveRule(GLDCustomGridRules *owner); + virtual GLDRejectLevelRule *createRejectLevelRule(GLDCustomGridRules *owner); + virtual GLDEditFormRule *creataeEditFormRule(GLDCustomGridRules *owner); + virtual GLDClearCellRule *createClearCellRule(GLDCustomGridRules *owner); +protected: + GObjectList m_list; + GLDVector m_ruleArray[CGridRuleTypeCount]; +}; + +// 显示规则基类 +class GLDTABLEVIEWSHARED_EXPORT GLDGridRule +{ +public: + GLDGridRule(GLDCustomGridRules *owner); + virtual ~GLDGridRule(); + + virtual void loadFromStream(GStream *stream); + virtual void saveToStream(GStream *stream); + + virtual bool autoRefresh() const; + virtual void compile(); + virtual void clearCompileInfo(); + + virtual int varCount(); + int index(); + virtual GLDGridRuleType ruleType() = 0; + + bool enable() const; + void setEnable(const bool value); + GString fieldCondition() const; + void setFieldCondition(const GString &value); + GString recordCondition() const; + void setRecordCondition(const GString &value); + GString ruleName() const; + void setRuleName(const GString &value); +private: + bool designState(); + int tableIndex(); + GString refFullName(); +protected: + GLDCustomGridRules *m_owner; + bool m_enable; + GString m_fieldCondition; + GString m_recordCondition; + GString m_ruleName; + int m_fixedCols; +}; + +// 显示规则容器类 +class GLDTABLEVIEWSHARED_EXPORT GLDGridRules: virtual public GLDCustomGridRules +{ +public: + GLDGridRules(GLDTableSetting *owner); + virtual ~GLDGridRules(); + GLDCustomGridSetting *gridSetting(); + GString refFullName(); +protected: + bool designState(); + int tableIndex(); +protected: + GLDTableSetting *m_owner; +}; + +// 字体规则类 +class GLDTABLEVIEWSHARED_EXPORT GLDFontRule: virtual public GLDGridRule +{ +public: + GLDFontRule(GLDCustomGridRules *owner); + virtual ~GLDFontRule(); + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + + bool autoRefresh() const; + GLDGridRuleType ruleType(); + + GRgb fontColor() const; + void setFontColor(GRgb value); + GString fontName() const; + void setFontName(const GString &value); + int fontSize() const; + void setFontSize(int value); + FontStyles fontStyles() const; + void setFontStyles(FontStyles value); +protected: + GRgb m_fontColor; + GString m_fontName; + int m_fontSize; + FontStyles m_fontStyles; +}; + +// 背景色规则类 +class GLDTABLEVIEWSHARED_EXPORT GLDBackColorRule: virtual public GLDGridRule +{ +public: + GLDBackColorRule(GLDCustomGridRules *owner); + virtual ~GLDBackColorRule(); + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + + bool autoRefresh() const; + GLDGridRuleType ruleType(); + + GRgb backColor() const; + void setBackColor(GRgb value); + +protected: + GRgb m_backColor; +}; + +// 编辑方式规则类 +class GLDTABLEVIEWSHARED_EXPORT GLDEditStyleRule: virtual public GLDGridRule +{ +public: + GLDEditStyleRule(GLDCustomGridRules *owner); + virtual ~GLDEditStyleRule(); + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + GLDGridRuleType ruleType(); + + GLDEditStyle editStyle() const; + void setEditStyle(GLDEditStyle value); + +protected: + GLDEditStyle m_editStyle; +}; + +// 边框线规则类 +class GLDTABLEVIEWSHARED_EXPORT GLDBoundLineRule: virtual public GLDGridRule +{ +public: + GLDBoundLineRule(GLDCustomGridRules *owner); + virtual ~GLDBoundLineRule(); + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + bool autoRefresh() const; + GLDGridRuleType ruleType(); + + byte antiDiagonal() const; + void setAntiDiagonal(const byte value); + byte bottomLine() const; + void setBottomLine(const byte value); + byte diagonal() const; + void setDiagonal(const byte value); + byte rightLine() const; + void setRightLine(const byte value); +protected: + byte m_antiDiagonal; + byte m_bottomLine; + byte m_diagonal; + byte m_rightLine; +}; + +// 对齐方式规则类 +class GLDTABLEVIEWSHARED_EXPORT GLDAlignRule: virtual public GLDGridRule +{ +public: + GLDAlignRule(GLDCustomGridRules *owner); + virtual ~GLDAlignRule(); + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + + bool autoRefresh() const; + GLDGridRuleType ruleType(); + + GLDHorzAlignment horzAlignment() const; + void setHorzAlignment(const GLDHorzAlignment value); + GLDVertAlignment vertAlignment() const; + void setVertAlignment(const GLDVertAlignment value); + +protected: + GLDHorzAlignment m_horzAlignment; + GLDVertAlignment m_vertAlignment; +}; + +// 边界规则类 +class GLDTABLEVIEWSHARED_EXPORT GLDMarginRule: virtual public GLDGridRule +{ +public: + GLDMarginRule(GLDCustomGridRules *owner); + virtual ~GLDMarginRule(); + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + bool autoRefresh() const; + GLDGridRuleType ruleType(); + + byte leftMargin() const; + void setLeftMargin(const byte value); + byte rightMargin() const; + void setRightMargin(const byte value); + byte topMargin() const; + void setTopMargin(const byte value); + byte bottomMargin() const; + void setBottomMargin(const byte value); +protected: + byte m_leftMargin; + byte m_rightMargin; + byte m_topMargin; + byte m_bottomMargin; +}; + +// 只读规则类 +class GLDTABLEVIEWSHARED_EXPORT GLDReadonlyRule: virtual public GLDGridRule +{ +public: + GLDReadonlyRule(GLDCustomGridRules *owner); + virtual ~GLDReadonlyRule(); + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + + GLDGridRuleType ruleType(); + + bool readonly() const; + void setReadonly(bool value); + +protected: + bool m_readonly; +}; + +// 只读规则类 +class GLDTABLEVIEWSHARED_EXPORT GLDCanFocusRule: virtual public GLDGridRule +{ +public: + GLDCanFocusRule(GLDCustomGridRules *owner); + virtual ~GLDCanFocusRule(); + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + GLDGridRuleType ruleType(); + + bool canFocus() const; + void setCanFocus(const bool value); +protected: + bool m_canFocus; +}; + +// 处理符号规则类 +class GLDTABLEVIEWSHARED_EXPORT GLDHandleSymbolRule: virtual public GLDGridRule +{ +public: + GLDHandleSymbolRule(GLDCustomGridRules *owner); + virtual ~GLDHandleSymbolRule(); + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + GLDGridRuleType ruleType(); + bool handleSymbol() const; + void setHandleSymbol(bool value); +protected: + bool m_handleSymbol; +}; + +// 图标规则类 +class GLDTABLEVIEWSHARED_EXPORT GLDImageRule: virtual public GLDGridRule +{ +public: + GLDImageRule(GLDCustomGridRules *owner); + virtual ~GLDImageRule(); + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + bool autoRefresh() const; + GLDGridRuleType ruleType(); + + int imageIndex() const; + void setImageIndex(int value); + GLDCellImageLayout imageLayout() const; + void setImageLayout(GLDCellImageLayout value); +protected: + int m_imageIndex; + GLDCellImageLayout m_imageLayout; +}; + +// 注释规则类 +class GLDTABLEVIEWSHARED_EXPORT GLDCommentRule: virtual public GLDGridRule +{ +public: + GLDCommentRule(GLDCustomGridRules *owner); + virtual ~GLDCommentRule(); + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + GLDGridRuleType ruleType(); + + GString comment() const; + void setComment(const GString &value); + bool showComment() const; + void setShowComment(bool value); +protected: + GString m_comment; + bool m_showComment; +}; + +// 显示规则类 +class GLDTABLEVIEWSHARED_EXPORT GLDVisibleRule: virtual public GLDGridRule +{ +public: + GLDVisibleRule(GLDCustomGridRules *owner); + virtual ~GLDVisibleRule(); + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + + bool autoRefresh() const; + GLDGridRuleType ruleType(); + + GString inVisibleText() const; + void setInVisibleText(GString value); + +protected: + GString m_inVisibleText; +}; + +// 合并单元格规则类 +class GLDTABLEVIEWSHARED_EXPORT GLDMergeRule: virtual public GLDGridRule +{ +public: + inline GLDMergeRule(GLDCustomGridRules *owner) : GLDGridRule(owner) {} + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + bool autoRefresh() const; + GLDGridRuleType ruleType(); + + GString mergeExpr() const; + void setMergeExpr(const GString &value); +protected: + GString m_mergeExpr; +}; + +// 禁止规则基类 +class GLDTABLEVIEWSHARED_EXPORT GLDRejectRule: virtual public GLDGridRule +{ +public: + inline GLDRejectRule(GLDCustomGridRules *owner) : GLDGridRule(owner) {} + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + + int isTree() const; + void setIsTree(int value); +protected: + int m_isTree; // 1: IsTree; -1: IsList; 0:全部 +}; + +// 禁止删除规则类 +class GLDTABLEVIEWSHARED_EXPORT GLDRejectDeleteRule: virtual public GLDRejectRule +{ +public: + inline GLDRejectDeleteRule(GLDCustomGridRules *owner) : GLDGridRule(owner), GLDRejectRule(owner) {} + GLDGridRuleType ruleType(); +}; + +// 禁止插入规则类 +class GLDTABLEVIEWSHARED_EXPORT GLDRejectInsertRule: virtual public GLDRejectRule +{ +public: + inline GLDRejectInsertRule(GLDCustomGridRules *owner) : GLDGridRule(owner), GLDRejectRule(owner) {} + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + GLDGridRuleType ruleType(); + + int isBefore() const; + void setIsBefore(const int &value); + GString tableNames() const; + void setTableNames(const GString &value); +protected: + GString m_tableNames; + int m_isBefore; // 1: Before; -1: After; 0:全部 +}; + +//禁止插入孩子规则 +class GLDTABLEVIEWSHARED_EXPORT GLDRejectInsertChildRule: virtual public GLDRejectInsertRule +{ +public: + inline GLDRejectInsertChildRule(GLDCustomGridRules *owner) : + GLDGridRule(owner), GLDRejectRule(owner), GLDRejectInsertRule(owner), m_level(-1) {} + virtual ~GLDRejectInsertChildRule(); + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + GLDGridRuleType ruleType(); + + int level() const; + void setLevel(int value); +protected: + int m_level; +}; + +// 禁止上下移规则类 +class GLDTABLEVIEWSHARED_EXPORT GLDRejectMoveRule: virtual public GLDRejectRule +{ +public: + inline GLDRejectMoveRule(GLDCustomGridRules *owner) : GLDGridRule(owner), GLDRejectRule(owner) {} + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + GLDGridRuleType ruleType(); + + int isMoveUp() const; + void setIsMoveUp(int value); + int includeChild() const; + void setIncludeChild(int value); +protected: + int m_isMoveUp; // 1: 上移; -1: 下移; 0:全部 + int m_includeChild; // 1: IncludeChild; -1: not IncludeChild; 0:全部 +}; + +// 禁止升降级规则类 +class GLDTABLEVIEWSHARED_EXPORT GLDRejectLevelRule: virtual public GLDRejectRule +{ +public: + inline GLDRejectLevelRule(GLDCustomGridRules *owner) : GLDGridRule(owner), GLDRejectRule(owner) {} + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + GLDGridRuleType ruleType(); + + int isLevelUp() const; + void setIsLevelUp(int value); + int isFixPos() const; + void setIsFixPos(int value); +protected: + int m_isLevelUp; // 1: 升级; -1: 降级; 0:全部 + int m_isFixPos; // 1: 保持位置; -1: 不保持位置; 0:全部 +}; + +// 通用编辑窗体规则类 +class GLDTABLEVIEWSHARED_EXPORT GLDEditFormRule: virtual public GLDGridRule +{ +public: + GLDEditFormRule(GLDCustomGridRules *owner); + virtual ~GLDEditFormRule(); + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + + GLDGridRuleType ruleType(); + + bool enable() const; + void setEnable(bool value); +protected: + bool m_enable; +}; + +// 清空格子内容规则 +class GLDTABLEVIEWSHARED_EXPORT GLDClearCellRule: virtual public GLDGridRule +{ +public: + GLDClearCellRule(GLDCustomGridRules *owner); + virtual ~GLDClearCellRule(); + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + GLDGridRuleType ruleType(); + + bool allowClear() const; + void setAllowClear(bool value); +protected: + bool m_allowClear; +}; + +class GLDTABLEVIEWSHARED_EXPORT GLDRecordGridSetting: public GLDCustomGridSetting +{ +public: + GLDRecordGridSetting(); + virtual ~GLDRecordGridSetting(); + + static GLDRecordGridSetting *createGLDRecordGridSetting(); + /*此函数供组件编辑器使用 */ + void saveToFile(const GString &fileName); + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + void clearData(); + + void loadRowHeightsFromStr(const GString &s); + void loadColWidthsFromStr(const GString &s); + void loadMinColWidthsFromStr(const GString &s); + void loadColStylesFromStr(const GString &s); + void loadColIdentitysFromStr(const GString &s); + GString rowHeightsToStr(); + GString colWidthsToStr(); + GString minColWidthsToStr(); + GString colStylesToStr(); + GString colIdentitysToStr(); + void setColWidths(int index, const int value); + void setOriginColWidths(int index, const int value); + void setRowHeights(int index, const int value); + GLDRecordFieldSetting *fieldsetting(int row, int col); + void setColStyles(int index, const GLDCellSuitType value); + void setColIdentitys(int index, const GString &value); + void setColZoomWidths(int index, const int value); + void setMinColWidths(int index, const int value); + void insertRow(int index); + void insertCol(int index); + void deleteRow(int index); + void deleteCol(int index); + void moveRow(int fromIndex, int toIndex); + void moveCol(int fromIndex, int toIndex); + GIntList suitColWidthCols(); + GIntList suitRowHeightCols(); + GIntList fitColWidthCols(); + GLDRecordSettings *recordSettings(); + GLDRecordFieldSettings *fieldSettings() const; + GLDRecordFieldSetting *cells(int col, int row); + + int rowCount() const; + void setRowCount(const int value); + int colCount() const; + void setColCount(const int value); + int rowHeights(const int index) const; + int colWidths(int index) const; + int colZoomWidths(int index) const; + GLDCellSuitType colStyles(int index); + int originColWidths(int index) const; + int minColWidths(int index) const; + GString colIdentitys(int index) const; + unsigned short fixedRows() const; + void setFixedRows(unsigned short value); + bool ignoreInvalidCell() const; + void setIgnoreInvalidCell(bool value); + bool allowLabelSelection() const; + void setAllowLabelSelection(bool value); + virtual void initialize(); +protected: + void compile(); + void clearCompileInfo(); + void loadGridSetting(); + void doLoadFromXML(GXMLDocument &doc); + void doLoadFromFile(const GString &fileName); + void doSaveToXML(GXMLDocument &doc); + GString saveDialogDefaultExt(); + GString saveDialogFilter(); +private: + GString intAryToStr(GIntList &ary); + void setLength(GIntList &ary, int count); + void setLength(GStringList &ary, int count); +protected: + unsigned short m_fixedRows; + bool m_ignoreInvalidCell; + bool m_allowLabelSelection; + int m_rowCount; + int m_colCount; + GIntList m_rowHeights; + GIntList m_colWidths; + GIntList m_colZoomWidths; + GIntList m_colStyles; // 0:固定尺寸; 1:自动行高; 2、自动列宽 + GStringList m_colIdentitys; + GLDRecordSettings *m_recordSettings; + GLDRecordFieldSettings *m_fieldSettings; + /*临时信息,不需要存储 */ + GIntList m_fieldCols; + GIntList m_originColWidths; + GIntList m_minColWidths; +}; + +// 记录设置容器类 +class GLDTABLEVIEWSHARED_EXPORT GLDRecordSettings +{ +public: + GLDRecordSettings(GLDRecordGridSetting *owner); + virtual ~GLDRecordSettings(); + + void compile(); + void clearCompileInfo(); + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + GLDRecordSetting *insert(int index = -1); + void Delete(int index); + void move(int fromIndex, int toIndex); + void clear(); + int count() const ; + void setCount(const int value); + GLDRecordSetting *items(int index) const; + GLDRecordSetting *operator[](int index); + GLDRecordGridSetting *owner(); + GLDRecordSetting *createRecordSetting(GLDRecordSettings *owner); + virtual GLDRecordSetting *doCreateRecordSetting(GLDRecordSettings *owner); +protected: + GObjectList m_list; + GLDRecordGridSetting *m_owner; +}; + +// 记录设置规则 +class GLDTABLEVIEWSHARED_EXPORT GLDRecordSetting +{ +public: + GLDRecordSetting(GLDRecordSettings *owner); + virtual ~GLDRecordSetting(); + + void compile(); + void clearCompileInfo(); + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + GString refFullName(); + + GString refDatabaseName() const; + void setRefDatabaseName(const GString &value); + GString refTableName() const; + void setRefTableName(const GString &value); + GLDRecordGridRules *rules(); + GLDRecordSettings *owner(); + virtual GLDRecordGridRules *createGridRules(GLDRecordSetting *owner); + void initialize(); +protected: + GLDRecordSettings *m_owner; + GLDRecordGridRules *m_rules; + GString m_refDatabaseName; + GString m_refTableName; +}; + +class GLDTABLEVIEWSHARED_EXPORT GLDRecordFieldSettings +{ +public: + GLDRecordFieldSettings(GLDRecordGridSetting *owner); + virtual ~GLDRecordFieldSettings(); + + void compile(); + void clearCompileInfo(); + void saveToStream(GStream *stream); + void loadFromStream(GStream *stream); + GLDRecordFieldSetting *insert(int index); + void Delete(int index); + void clear(); + GLDRecordFieldSetting *items(int index) const; + GLDRecordFieldSetting *operator[](int index); + int indexOf(GLDRecordFieldSetting *value) const; + GObjectList &list(); + int count(); + GLDRecordGridSetting *owner() const; + virtual GLDRecordFieldSetting *createFieldSetting(GLDRecordFieldSettings *owner); +protected: + GLDRecordGridSetting *m_owner; + GObjectList m_list; +}; + +class GLDTABLEVIEWSHARED_EXPORT GLDRecordFieldSetting: virtual public GLDCustomFieldSetting +{ +public: + GLDRecordFieldSetting(GLDRecordFieldSettings *owner); + virtual ~GLDRecordFieldSetting(); + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + + void compile(); + void clearCompileInfo(); + GLDDataType displayExprDataType(); + bool designState(); + int index() const; + int tableIndex(); + GString refFullName(); + GLDCustomGridSetting *gridSetting(); + + int colNo(); + int rowNo(); + GLDRecordSetting *recordSetting(); + GLDRecordGridSetting *recordGridSetting() const; + void assign(GLDRecordFieldSetting *fieldSetting); + + bool isLabel() const; + void setIsLabel(bool value); + bool visible() const; + void setVisible(const bool &value); + GString visibleCondition() const; + void setVisibleCondition(const GString &value); + int dataSourceID() const; + void setDataSourceID(const int value); + bool isPasswordChar() const; + void setIsPasswordChar(bool value); + GLDRecordFieldSettings *owner(); +protected: + GLDRecordFieldSettings *m_owner; + bool m_isLabel; + int m_dataSourceID; + bool m_isPasswordChar; + bool m_visible; + GString m_visibleCondition; +}; + +class GLDTABLEVIEWSHARED_EXPORT GLDRecordGridRules: virtual public GLDCustomGridRules +{ +public: + GLDRecordGridRules(GLDRecordSetting *owner); + virtual ~GLDRecordGridRules(); + GLDCustomGridSetting *gridSetting(); + GString refFullName(); +protected: + bool designState(); + int tableIndex(); +protected: + GLDRecordSetting *m_owner; +}; + +GString GLDTABLEVIEWSHARED_EXPORT trimExpression(const GString &s); +bool GLDTABLEVIEWSHARED_EXPORT textIsLabel(const GString &s); +bool GLDTABLEVIEWSHARED_EXPORT isNullTitleCell(GLDTitleCell *cell); +bool GLDTABLEVIEWSHARED_EXPORT isDefaultCellFormat(GLDCellFormat *cellFormat, GLDHorzAlignment defHorzAlignment = + DefHorzAlignment); +bool GLDTABLEVIEWSHARED_EXPORT isNullFilterCell(GLDFilterCell *filterCell); +bool GLDTABLEVIEWSHARED_EXPORT isNullFieldSetting(GLDFieldSetting *fieldSetting); +bool GLDTABLEVIEWSHARED_EXPORT isNullFieldSetting(GLDRecordFieldSetting *fieldSetting); +bool GLDTABLEVIEWSHARED_EXPORT isNullExpandFieldSetting(GLDExpandRowFieldSetting *fieldSetting); + +#endif // GLDGRIDSETTING_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDGridSettingXMLBuilder.h b/GCR/trunk/Glodon/include/GLD/GLDGridSettingXMLBuilder.h new file mode 100644 index 00000000..e018280a --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDGridSettingXMLBuilder.h @@ -0,0 +1,161 @@ +#ifndef GLDGRIDSETTINGXMLBUILDER_H +#define GLDGRIDSETTINGXMLBUILDER_H + +#include "GLDSystem.h" +#include "GLDString.h" +#include "GLDXMLTypes.h" +#include "GLDGridSetting.h" + +enum GLDGridOption +{ + ggoShowAsTree, + ggoEditing, + ggoVertLine, + ggoHorzLine, + ggoRowSizing, + ggoColSizing, + ggoColMoving, + ggoAlwaysShowEditor, + ggoRangeSelect, + ggoAllowSelectRow, + ggoAllowSelectCol, + ggoAllowSelectAll, + ggoMultiSelection, + ggoAutoThemeAdapt, + ggoReturnKeyAsTab, + ggoShowFixedRow, + ggoCellFilling, + ggoFixedCellEvent, + ggo3DStyle, + ggoHideEditOnExit, + ggoBorderStyle, + ggoUseBlendColor, + ggoCellFillEditField +}; + +extern GLDTABLEVIEWSHARED_EXPORT GString g_OldVersion; +class GLDTABLEVIEWSHARED_EXPORT GLDGridSettingXMLBaseReader +{ +public: + inline GLDGridSettingXMLBaseReader() {} + virtual ~GLDGridSettingXMLBaseReader(); +protected: + void readGridRule(const GXMLNode &node, GLDGridRule *rule); + void readCellFormat(const GXMLNode &node, GLDCellFormat *cellFormat, GLDHorzAlignment + defHorzAlignment = DefHorzAlignment ); + void readExtPropDefs(const GXMLNode &node, CGLDExtPropDefs *extPropDefs); +}; + +//GSF文件读取类 +class GLDTABLEVIEWSHARED_EXPORT GLDGridSettingXMLReader: public GLDGridSettingXMLBaseReader +{ +public: + inline GLDGridSettingXMLReader() {} + inline ~GLDGridSettingXMLReader() {} +public: + void read(const GString &fileName, GLDGridSetting *gridSetting); + void read(GXMLDocument &xmlDoc, GLDGridSetting *gridSetting); + void read(const GXMLNode &node, GLDGridSetting *gridSetting); +private: + void readColSettings(const GXMLNode &node, GLDColSettings *colSettings); + void readColSetting(const GXMLNode &node, GLDColSetting *colSetting); + void readTitleRows(const GXMLNode &node, GLDTitleRows *titleRows); + void readTitleRow(const GXMLNode &node, GLDTitleRow *titleRow); + void readTitleCells(const GXMLNode &node, GLDTitleRow *titleRow); + void readTitleCell(const GXMLNode &node, GLDTitleCell *titleCell); + void readFilterRows(const GXMLNode &node, GLDFilterRows *filterRows); + void readFilterRow(const GXMLNode &node, GLDFilterRow *filterRow); + void readFilterCells(const GXMLNode &node, GLDFilterRow *filterRow); + void readFilterCell(const GXMLNode &node, GLDFilterCell *filterCell); + void readTableSettings(const GXMLNode &node, GLDTableSettings *tableSettings); + void readTableSetting(const GXMLNode &node, GLDTableSetting *tableSetting); + void readFieldSettings(const GXMLNode &node, GLDFieldSettings *fieldSettings); + void readFieldSetting(const GXMLNode &node, GLDFieldSetting *fieldSetting); + void readGridRules(const GXMLNode &node, GLDGridRules *gridRules); + void readHeaderRowFieldSettings(const GXMLNode &node, GLDHeaderRowFieldSettings *headerRowFieldSettings); + void readHeaderRowFieldSetting(const GXMLNode &node, GLDHeaderRowFieldSetting *headerRowFieldSetting); + void readTotalRowFieldSettings(const GXMLNode &node, GLDTotalRowFieldSettings *totalRowFieldSettings); + void readTotalRowFieldSetting(const GXMLNode &node, GLDTotalRowFieldSetting *totalRowFieldSetting); +}; + +//RGF文件读取类 +class GLDTABLEVIEWSHARED_EXPORT GLDRecordGridSettingXMLReader: public GLDGridSettingXMLBaseReader +{ +public: + GLDRecordGridSettingXMLReader(); + ~GLDRecordGridSettingXMLReader(); +public: + void read(const GString &fileName, GLDRecordGridSetting *gridSetting); + void read(const GXMLDocument &xmlDoc, GLDRecordGridSetting *gridSetting); + void read(const GXMLNode &node, GLDRecordGridSetting *gridSetting); +private: + void readGridRules(const GXMLNode &node, GLDRecordGridRules *gridRules); + void readFieldSetting(const GXMLNode &node, GLDRecordFieldSetting *fieldSetting); + void readFieldSettings(const GXMLNode &node, GLDRecordFieldSettings *fieldSettings); + void readRecordSetting(const GXMLNode &node, GLDRecordSetting *recordSetting); + void readRecordSettings(const GXMLNode &node, GLDRecordSettings *recordSettings); +}; + +class GLDTABLEVIEWSHARED_EXPORT GLDGridSettingXMLBaseWriter +{ +public: + inline GLDGridSettingXMLBaseWriter() {} + inline ~GLDGridSettingXMLBaseWriter() {} +protected: + + void writeCellFormat(GXMLNode &node, GLDCellFormat *cellFormat, GLDHorzAlignment defHorzAlignment = DefHorzAlignment); + void writeGridRule(GXMLNode &node, GLDGridRule *rule); + void writeExtPropDefs(GXMLNode &node, CGLDExtPropDefs *extPropDefs); +}; + +//GSF写入类 +class GLDTABLEVIEWSHARED_EXPORT GLDGridSettingXMLWriter: public GLDGridSettingXMLBaseWriter +{ +private: + void writeColSettings(GXMLNode &node, GLDColSettings *colSettings); + void writeColSetting(GXMLNode &node, GLDColSetting *colSetting); + void writeTitleRows(GXMLNode &node, GLDTitleRows *titleRows); + void writeTitleRow(GXMLNode &node, GLDTitleRow *titleRow); + void writeTitleCells(GXMLNode &node, GLDTitleRow *titleRow); + void writeTitleCell(GXMLNode &node, GLDTitleCell *titleCell); + void writeFilterRows(GXMLNode &node, GLDFilterRows *filterRows); + void writeFilterRow(GXMLNode &node, GLDFilterRow *filterRow); + void writeFilterCells(GXMLNode &node, GLDFilterRow *filterRow); + void writeFilterCell(GXMLNode &node, GLDFilterCell *filterCell); + void writeTableSettings(GXMLNode &node, GLDTableSettings *tableSettings); + void writeTableSetting(GXMLNode &node, GLDTableSetting *tableSetting); + void writeFieldSettings(GXMLNode &node, GLDFieldSettings *fieldSettings); + void writeFieldSetting(GXMLNode &node, GLDFieldSetting *fieldSetting); + void writeGridRules(GXMLNode &node, GLDGridRules *gridRules); + void writeHeaderRowFieldSettings(GXMLNode &node, GLDHeaderRowFieldSettings *headerRowFieldSettings); + void writeHeaderRowFieldSetting(GXMLNode &node, GLDHeaderRowFieldSetting *headerRowFieldSetting); + void writeTotalRowFieldSettings(GXMLNode &node, GLDTotalRowFieldSettings *totalRowFieldSettings); + void writeTotalRowFieldSetting(GXMLNode &node, GLDTotalRowFieldSetting *totalRowFieldSetting); +public: + void write(const GString &fileName, GLDGridSetting *gridSetting); + void write(GXMLDocument &xmlDoc, GLDGridSetting *gridSetting); + void write(GXMLNode &node, GLDGridSetting *gridSetting); +public: + inline GLDGridSettingXMLWriter(){} + inline ~GLDGridSettingXMLWriter(){} +}; + +//RGF写入类 +class GLDTABLEVIEWSHARED_EXPORT GLDRecordGridSettingXMLWriter: public GLDGridSettingXMLBaseWriter +{ +private: + void writeGridRules(GXMLNode &node, GLDRecordGridRules *gridRules); + void writeFieldSetting(GXMLNode &node, GLDRecordFieldSetting *fieldSetting); + void writeFieldSettings(GXMLNode &node, GLDRecordFieldSettings *fieldSettings); + void writeRecordSetting(GXMLNode &node, GLDRecordSetting *recordSetting); + void writeRecordSettings(GXMLNode &node, GLDRecordSettings *recordSettings); +public: + void write(const GString &fileName, GLDRecordGridSetting *gridSetting, bool encryptData = false); + void write(GXMLDocument &xmlDoc, GLDRecordGridSetting *gridSetting); + void write(GXMLNode &node, GLDRecordGridSetting *gridSetting); +public: + inline GLDRecordGridSettingXMLWriter() {} + inline ~GLDRecordGridSettingXMLWriter() {} +}; + +#endif // GLDGRIDSETTINGXMLBUILDER_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDGroupHeaderView.h b/GCR/trunk/Glodon/include/GLD/GLDGroupHeaderView.h new file mode 100644 index 00000000..0521157a --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDGroupHeaderView.h @@ -0,0 +1,98 @@ +#ifndef GLDGROUPHEADERVIEW_H +#define GLDGROUPHEADERVIEW_H + +#include "GLDHeaderView.h" + +class GlodonColumnGroupFrame; +class GColumnGroupLabel; +class GlodonGroupHeaderViewPrivate; + +class GLDTABLEVIEWSHARED_EXPORT GlodonGroupHeaderView : public GlodonHeaderView +{ + Q_OBJECT +public: + GlodonGroupHeaderView(QWidget *parent); + + int drawWidth() const; + void setModel(QAbstractItemModel *model); + void updateGeometries(); + +public Q_SLOTS: + void cgFrameChanged(int col, bool dragIn); + void onGroupChanged(); + +Q_SIGNALS: + void cgFrameChanged(); + void groupChanged(QVector newGroups); + +protected: + void mousePressEvent(QMouseEvent *e); + void mouseMoveEvent(QMouseEvent *e); + void mouseReleaseEvent(QMouseEvent *e); + void dragEnterEvent(QDragEnterEvent *dee); + void dragMoveEvent(QDragMoveEvent *dme); + void dropEvent(QDropEvent *de); + +private: + GlodonColumnGroupFrame *cgFrame; + GColumnGroupLabel *sectionLabel; + +private: + Q_DECLARE_PRIVATE(GlodonGroupHeaderView) + void setupSectionLabel(int section); + QVector currentGroups(); +}; + +class GLDTABLEVIEWSHARED_EXPORT GColumnGroupLabel : public QLabel +{ + Q_OBJECT +public: + explicit GColumnGroupLabel(int col, QString text, QWidget *parent = 0); + + void mousePressEvent(QMouseEvent *e); + void draggedLeaveFrame(); + +public: + int column; + +Q_SIGNALS: + void leaveFrame(); +}; + +class GLDTABLEVIEWSHARED_EXPORT GlodonColumnGroupFrame : public QFrame +{ + Q_OBJECT +public: + explicit GlodonColumnGroupFrame(QWidget *parent = 0); + + void paintEvent(QPaintEvent *e); + + void dragEnterEvent(QDragEnterEvent *dee); + void dropEvent(QDropEvent *de); + void dragMoveEvent(QDragMoveEvent *dme); + void dragLeaveEvent(QDragLeaveEvent *); + + int frameHeight() const; + +public Q_SLOTS: + void onLabelDragOut(); + +public: + QList labels; + +Q_SIGNALS: + void cgFrameChanged(int col, bool dragOut); + void groupChanged(); + +private: + QRect labelRect(int level); + void drawBranch(int level, QRect labelRect); + int moveTarget(QPoint pos); + QRect branchRect(int level); + +private: + int moveStart; + int movePos; +}; + +#endif // GLDGROUPHEADERVIEW_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDGroupHeaderView_p.h b/GCR/trunk/Glodon/include/GLD/GLDGroupHeaderView_p.h new file mode 100644 index 00000000..418c523e --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDGroupHeaderView_p.h @@ -0,0 +1,14 @@ +#ifndef GLDGROUPHEADERVIEW_P_H +#define GLDGROUPHEADERVIEW_P_H + +#include "GLDHeaderView_p.h" + +class GlodonGroupHeaderViewPrivate : public GlodonHeaderViewPrivate +{ + Q_DECLARE_PUBLIC(GlodonGroupHeaderView) + +public: + GlodonGroupHeaderViewPrivate() : GlodonHeaderViewPrivate() {} +}; + +#endif // GLDGROUPHEADERVIEW_P_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDGroupModel.h b/GCR/trunk/Glodon/include/GLD/GLDGroupModel.h new file mode 100644 index 00000000..b1212e5f --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDGroupModel.h @@ -0,0 +1,112 @@ +#ifndef GLDCXMODEL_H +#define GLDCXMODEL_H + +#include +#include + +#include "GLDObjectList.h" + +class GlodonGroupModelAbstractItem; + +typedef QHash ValueRowInfo; +typedef QHash ColumnValueInfo; +typedef QList GlodonCXModelItemList; + +class GLDCOMMONSHARED_EXPORT GlodonGroupModel : public QAbstractItemModel +{ + Q_OBJECT +public: + explicit GlodonGroupModel(QAbstractItemModel *pModel, QObject *parent = 0); + ~GlodonGroupModel(); + + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex &child) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role) const; + bool setData(const QModelIndex &index, const QVariant &value, int role); + QVariant headerData(int section, Qt::Orientation orientation, int role) const; + bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role); + + Qt::ItemFlags flags(const QModelIndex &index) const; + + void buildModel(bool reset = false); + QAbstractItemModel *model() const; + void setModel(QAbstractItemModel *model); + + QModelIndex dataIndex(const QModelIndex &index) const; + QModelIndex groupIndex(const QModelIndex &index) const; + +public Q_SLOTS: + void groupChanged(QVector newGroup); + void onResetModel(); +Q_SIGNALS: + void modelRebuild(); + +private: + QVector m_groupCols; + QAbstractItemModel *m_model; + ColumnValueInfo m_valueInfo; + GlodonGroupModelAbstractItem *m_root; + int m_treeCol; + +private: + void resetModel(); + void loadChildItems(int index, const QList &rows, GlodonGroupModelAbstractItem *parent); + void LoadChildModelIndex(GlodonGroupModelAbstractItem *parentItem, QModelIndex parentIndex); + void initColumnValueInfo(int col); + QVariant groupData(const QModelIndex &index, int role, GlodonGroupModelAbstractItem *item) const; + QVariant itemData(const QModelIndex &index, int role, GlodonGroupModelAbstractItem *item) const; +}; + +class GLDCOMMONSHARED_EXPORT GlodonGroupModelAbstractItem +{ +public: + enum CXType + { + CXGroup = 0, + CXData = 1 + }; + +public: + GlodonGroupModelAbstractItem(GlodonGroupModelAbstractItem *parentItem = 0); + virtual ~GlodonGroupModelAbstractItem(); + virtual CXType type() const = 0; + +public: + GlodonGroupModelAbstractItem *parent; + GObjectList child; +}; + +class GLDCOMMONSHARED_EXPORT GlodonGroupModelGroupItem : public GlodonGroupModelAbstractItem +{ +public: + GlodonGroupModelGroupItem(GlodonGroupModelAbstractItem *parentItem = 0); + + CXType type() const { return GlodonGroupModelAbstractItem::CXGroup; } + + inline QString data() { return m_data; } + inline void setData(QString value) { m_data = value; } + +private: + QString m_data; +}; + +class GLDCOMMONSHARED_EXPORT GlodonGroupModelDataItem : public GlodonGroupModelAbstractItem +{ +public: + GlodonGroupModelDataItem(QModelIndex parentIndex = QModelIndex(), GlodonGroupModelAbstractItem *parentItem = 0); + + CXType type() const { return GlodonGroupModelAbstractItem::CXData; } + + inline void setIndex(int rowNo) { m_row = rowNo; } + inline int index() const { return m_row; } + inline void setPIndex(QModelIndex index) { m_index = index; } + inline QModelIndex parentIndex() const { return m_index; } + +private: + int m_row; + QModelIndex m_index; +}; + +#endif // GLDCXMODEL_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDGuidDef.h b/GCR/trunk/Glodon/include/GLD/GLDGuidDef.h new file mode 100644 index 00000000..05a17e43 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDGuidDef.h @@ -0,0 +1,220 @@ +// +// Copyright (c) Microsoft Corporation. All rights reserved. +// +// +// Use of this source code is subject to the terms of the Microsoft end-user +// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT. +// If you did not accept the terms of the EULA, you are not authorized to use +// this source code. For a copy of the EULA, please see the LICENSE.RTF on your +// install media. +// +//+--------------------------------------------------------------------------- +// +// +// +// File: GLDGuidDef.h +// +// Contents: GUID definition +// +//---------------------------------------------------------------------------- + +#ifndef GLDGUIDDEF_H +#define GLDGUIDDEF_H + +#ifndef GUID_DEFINED +#define GUID_DEFINED +#if defined(__midl) +typedef struct { + unsigned long Data1; + unsigned short Data2; + unsigned short Data3; + byte Data4[ 8 ]; +} GUID; +#else +typedef struct _GUID { + unsigned long Data1; + unsigned short Data2; + unsigned short Data3; + unsigned char Data4[ 8 ]; +} GUID; +#endif +#endif + +#ifndef FAR +#ifdef _WIN32 +#define FAR +#else +#define FAR _far +#endif +#endif + +#ifndef DECLSPEC_SELECTANY +#if (_MSC_VER >= 1100) +#define DECLSPEC_SELECTANY __declspec(selectany) +#else +#define DECLSPEC_SELECTANY +#endif +#endif + +#ifndef EXTERN_C +#ifdef __cplusplus +#define EXTERN_C extern "C" +#else +#define EXTERN_C extern +#endif +#endif + +#ifdef DEFINE_GUID +#undef DEFINE_GUID +#endif + +#ifdef INITGUID +#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + EXTERN_C const GUID DECLSPEC_SELECTANY name \ + = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } +#else +#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ + const GUID FAR name +#endif // INITGUID + +#ifdef DEFINE_OLEGUID +#undef DEFINE_OLEGUID +#endif + +#define DEFINE_OLEGUID(name, l, w1, w2) DEFINE_GUID(name, l, w1, w2, 0xC0,0,0,0,0,0,0,0x46) + +#ifndef __LPGUID_DEFINED__ +#define __LPGUID_DEFINED__ +typedef GUID *LPGUID; +#endif + +#ifndef __LPCGUID_DEFINED__ +#define __LPCGUID_DEFINED__ +typedef const GUID *LPCGUID; +#endif + +#ifndef __IID_DEFINED__ +#define __IID_DEFINED__ + +typedef GUID IID; +typedef IID *LPIID; +#define IID_NULL GUID_NULL +#define IsEqualIID(riid1, riid2) IsEqualGUID(riid1, riid2) +typedef GUID CLSID; +typedef CLSID *LPCLSID; +#define CLSID_NULL GUID_NULL +#define IsEqualCLSID(rclsid1, rclsid2) IsEqualGUID(rclsid1, rclsid2) +typedef GUID FMTID; +typedef FMTID *LPFMTID; +#define FMTID_NULL GUID_NULL +#define IsEqualFMTID(rfmtid1, rfmtid2) IsEqualGUID(rfmtid1, rfmtid2) + +#ifdef __midl_proxy +#define __MIDL_CONST +#else +#define __MIDL_CONST const +#endif + +#ifndef _REFGUID_DEFINED +#define _REFGUID_DEFINED +#ifdef __cplusplus +#define REFGUID const GUID & +#else +#define REFGUID const GUID * __MIDL_CONST +#endif +#endif + +#ifndef _REFIID_DEFINED +#define _REFIID_DEFINED +#ifdef __cplusplus +#define REFIID const IID & +#else +#define REFIID const IID * __MIDL_CONST +#endif +#endif + +#ifndef _REFCLSID_DEFINED +#define _REFCLSID_DEFINED +#ifdef __cplusplus +#define REFCLSID const IID & +#else +#define REFCLSID const IID * __MIDL_CONST +#endif +#endif + +#ifndef _REFFMTID_DEFINED +#define _REFFMTID_DEFINED +#ifdef __cplusplus +#define REFFMTID const IID & +#else +#define REFFMTID const IID * __MIDL_CONST +#endif +#endif + +#endif // !__IID_DEFINED__ + +#if !defined (__midl) +#if !defined (_SYS_GUID_OPERATORS_) +#define _SYS_GUID_OPERATORS_ +//#include + +// Faster (but makes code fatter) inline version...use sparingly +#ifdef __cplusplus +__inline int InlineIsEqualGUID(REFGUID rguid1, REFGUID rguid2) +{ + return ( + ((unsigned long *) &rguid1)[0] == ((unsigned long *) &rguid2)[0] && + ((unsigned long *) &rguid1)[1] == ((unsigned long *) &rguid2)[1] && + ((unsigned long *) &rguid1)[2] == ((unsigned long *) &rguid2)[2] && + ((unsigned long *) &rguid1)[3] == ((unsigned long *) &rguid2)[3]); +} + +__inline int IsEqualGUID(REFGUID rguid1, REFGUID rguid2) +{ + //return !memcmp(&rguid1, &rguid2, sizeof(GUID)); + return ((long long *) &rguid1)[0] == ((long long *) &rguid2)[0] && + ((long long *) &rguid1)[1] == ((long long *) &rguid2)[1]; +} + +#else // ! __cplusplus + +#define InlineIsEqualGUID(rguid1, rguid2) \ + (((unsigned long *) rguid1)[0] == ((unsigned long *) rguid2)[0] && \ + ((unsigned long *) rguid1)[1] == ((unsigned long *) rguid2)[1] && \ + ((unsigned long *) rguid1)[2] == ((unsigned long *) rguid2)[2] && \ + ((unsigned long *) rguid1)[3] == ((unsigned long *) rguid2)[3]) + +#define IsEqualGUID(rguid1, rguid2) (!memcmp(rguid1, rguid2, sizeof(GUID))) + +#endif // __cplusplus + +#ifdef __INLINE_ISEQUAL_GUID +#undef IsEqualGUID +#define IsEqualGUID(rguid1, rguid2) InlineIsEqualGUID(rguid1, rguid2) +#endif + +// Same type, different name + +#define IsEqualIID(riid1, riid2) IsEqualGUID(riid1, riid2) +#define IsEqualCLSID(rclsid1, rclsid2) IsEqualGUID(rclsid1, rclsid2) + + +#if !defined _SYS_GUID_OPERATOR_EQ_ && !defined _NO_SYS_GUID_OPERATOR_EQ_ +#define _SYS_GUID_OPERATOR_EQ_ +// A couple of C++ helpers + +#ifdef __cplusplus +__inline int operator==(REFGUID guidOne, REFGUID guidOther) +{ + return IsEqualGUID(guidOne,guidOther); +} + +__inline int operator!=(REFGUID guidOne, REFGUID guidOther) +{ + return !(guidOne == guidOther); +} +#endif +#endif // _SYS_GUID_OPERATOR_EQ_ +#endif // _SYS_GUID_OPERATORS_ +#endif // __midl +#endif // GLDGUIDDEF_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDHash.h b/GCR/trunk/Glodon/include/GLD/GLDHash.h new file mode 100644 index 00000000..bb1c1896 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDHash.h @@ -0,0 +1,16 @@ +#ifndef GLDHASH_H +#define GLDHASH_H + +#include + +template +class GLDHash : public QHash +{ +}; + +template +class GLDMultiHash : public QMultiHash +{ +}; + +#endif // GLDHASH_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDHeaderView.h b/GCR/trunk/Glodon/include/GLD/GLDHeaderView.h new file mode 100644 index 00000000..9722e0b8 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDHeaderView.h @@ -0,0 +1,707 @@ +/*! + *@file glodonheaderview.h + *@brief {表头} + * + *@author Gaosy + *@date 2012.9.7 + *@remarks {} + *Copyright (c) 1998-2012 Glodon Corporation + */ + +#ifndef GLDHEADERVIEW_H +#define GLDHEADERVIEW_H + +#include +#include +#include +#include "GLDAbstractItemView.h" + +class GLDHeaderSpan; +class GLDTableView; +class GlodonTableView; +class GlodonHeaderViewPrivate; + +/*! + *@class: GlodonHeaderView + *@brief {默认表头,仅支持单行,表头显示内容从model中的headerData中获取} + *@author Gaosy + *@date 2012.9.10 + */ +class GLDTABLEVIEWSHARED_EXPORT GlodonHeaderView : public GlodonAbstractItemView +{ + Q_OBJECT + + Q_PROPERTY(bool showSortIndicator READ isSortIndicatorShown WRITE setSortIndicatorShown) + Q_PROPERTY(bool highlightSections READ highlightSections WRITE setHighlightSections) + Q_PROPERTY(bool cascadingSectionResizes READ cascadingSectionResizes WRITE setCascadingSectionResizes) + Q_PROPERTY(int defaultSectionSize READ defaultSectionSize WRITE setDefaultSectionSize) + Q_PROPERTY(int minimumSectionSize READ minimumSectionSize WRITE setMinimumSectionSize) + Q_PROPERTY(Qt::Alignment defaultAlignment READ defaultAlignment WRITE setDefaultAlignment) + Q_ENUMS(ResizeMode) + +public: + /*! + *@enum: ResizeModel + *@brief {resize方式} + *@author Gaosy + *@date 2012.9.11 + */ + enum ResizeMode + { + Interactive, + Fixed + }; + + enum VisibleState + { + LUnvisibleRVisible = -1, + LVisibleRUnvisible = 1, + BothVisible = 2, + BothUnvisible = 0 + }; + + enum ResizeState + { + Press, + Move, + Finish + }; + +public: + /*! + *GlodonHeaderView构造方法 + *@param[in] orientation 表头方向,Qt::Horizontal表示水平;Qt::Vertical表示竖直 + *@param[in] parent 父widget + *@return 无 + */ + explicit GlodonHeaderView(Qt::Orientation orientation, QWidget *parent = 0); + virtual ~GlodonHeaderView(); + + /*! + *为表头提供数据来源 + *@param[in] model + *@return 无 + *@see 参见GlodonAbstractItemView::setModel(QAbstractItemModel *model) + */ + void setModel(QAbstractItemModel *model); + + /*! + *返回表头的方向 + *@return Qt::Orientation + */ + Qt::Orientation orientation() const; + + /*! + *返回表头的偏移 + *@return int + */ + virtual int offset() const; + + /*! + *返回表头的长度 + *@return int + */ + virtual int length() const; + + /*! + *返回水平(竖直)表头的高度(宽度) + *@return int + */ + virtual int drawWidth() const; + + /*! + *返回水平(竖直)表头的列(行)数 + *@return int + */ + int sectionCount() const; + + /*! + *返回根据sizeHint计算的表头大小 + *@return QSize + */ + QSize sizeHint() const; + + /** + * @brief Qt5重新实现 + * @param v + */ + void setVisible(bool v); + + /*! + *根据sizeHint计算给定行(列)表头的宽度(高度) + *@param[in] logicalIndex 逻辑列(行)号 + *@return int + */ + int sectionSizeHint(int logicalIndex) const; + + /*! + *根据给定的坐标位置,返回虚拟列(行)号,即绘制时的列(行)号 + *@param[in] position 水平(竖直)表头的x轴(y轴)坐标 + *@return int + */ + int visualIndexAt(int position) const; + + /*! + *根据给定的坐标位置,返回逻辑列(行)号,即model中的列(行)号 + *@param[in] position 水平(竖直)表头的x轴(y轴)坐标 + *@return int + */ + int logicalIndexAt(int position) const; + + int logicalIndexAt(int x, int y) const + { + return orientation() == Qt::Horizontal ? logicalIndexAt(x) : logicalIndexAt(y); + } + + int logicalIndexAt(const QPoint &pos) const + { + return logicalIndexAt(pos.x(), pos.y()); + } + + /*! + *返回给定列(行)的宽度(高度) + *@param[in] logicalIndex 逻辑列(行)号 + *@return int + */ + int sectionSize(int logicalIndex) const; + /** + * @brief 返回给定列(行)的宽度(高度) + * @param visualIndex 显示列(行)号 + * @return + */ + int visualSectionSize(int visualIndex)const; + + /*! + *返回给定列(行)的绝对起始位置 + *@param[in] logicalIndex 逻辑列(行)号 + *@return int + */ + int sectionPosition(int logicalIndex) const; + + /*! + *返回给定列(行)的相对起始位置,即绘制起始位置 + *@param[in] logicalIndex 逻辑列(行)号 + *@return int + */ + int sectionViewportPosition(int logicalIndex) const; + + /** + * @brief 返回给定列(行)的相对起始位置,即绘制起始位置 + * @param visualIndex 显示列(行)号 + * @return + */ + int sectionVisualPosition(int visualIndex) const; + + /*! + *将from列(行)移动到to列(行)位置 + *@param[in] from 起始列的虚拟列(行)号 + *@param[in] to 目标的虚拟列(行)号 + *@return 无 + */ + void moveSection(int from, int to); + + /*! + *交换两列(行)的位置 + *@param[in] first 要交换的虚拟列(行)号 + *@param[in] second 另一个要交换的虚拟列(行)号 + *@return 无 + */ + void swapSections(int first, int second); + + /*! + *调整给定列(行)的列宽(行高) + *@param[in] logicalIndex 逻辑列(行)号 + *@param[in] size 新的列宽(行高) + *@return 无 + */ + virtual void resizeSection(int logicalIndex, int size, bool update = true, bool isManual = false); + + /** + * @brief 设置headerView的SectionSpan的创建方式,默认为false + * @param value + */ + void setSectionSpanSeparate(bool value); + bool isSectionSpanSeparate(); + + /*! + *判断给定列(行)是否被隐藏(特指collapsed) + *@param[in] logicalIndex 逻辑列(行)号 + *@return bool + */ + bool isSectionHidden(int logicalIndex) const; + + /*! + *判断给定列(行)是否可见(即区分处于以滚动条为代表的视窗内还是视窗外) + *@param[in] logicalIndex 逻辑列(行)号 + *@return int -1:左(上)端不可见,右(下)端可见。0:不可见。1:左(上)端可见,右(下)端不可见。2:双端可见。3:预留定义。详见VisibleState型枚举值 + */ + inline bool isSectionVisible(const int &logicalIndex) const + { + return visibleState(logicalIndex) != BothUnvisible; + } + + VisibleState visibleState(int logicalIndex) const; + + /*! + *隐藏(显示)给定列(行) + *@param[in] logicalIndex 逻辑列(行)号 + *@param[in] hide true表示隐藏,false表示显示 + *@return bool + */ + void setSectionHidden(int logicalIndex, bool hide); + + /*! + * \brief 批量显示或隐藏section,只进行一次recalcSectionStartPos + * \param logicalIndexs + * \param hide + */ + void batchSetSectionHidden(QSet logicalIndexs, bool hide); + + /*! + *返回隐藏的列(行)数 + *@return int + */ + int hiddenSectionCount() const; + + /*! + *隐藏列(行) + *@param[in] logicalIndex 逻辑列(行)号 + *@return 无 + */ + void hideSection(int logicalIndex) + { + setSectionHidden(logicalIndex, true); + } + + /*! + *显示列(行) + *@param[in] logicalIndex 逻辑列(行)号 + *@return 无 + */ + void showSection(int logicalIndex) + { + setSectionHidden(logicalIndex, false); + } + + /*! + *返回水平(竖直)表头的列(行)数 + *@return int + */ + virtual int count() const; + + /*! + *返回给定逻辑列(行)的虚拟列(行)号,即返回其绘制时的列(行)号 + *@param[in] logicalIndex 逻辑列(行)号 + *@return int + */ + int visualIndex(int logicalIndex) const; + + /*! + *返回给定虚拟列(行)的逻辑列(行)号,即返回其在model中对应的列(行)号 + *@param[in] visualIndex 虚拟列(行)号 + *@return int + */ + int logicalIndex(int visualIndex) const; + + void setMovable(bool movable); + bool isMovable() const; + + void setClickable(bool clickable); + bool isClickable() const; + + void setHighlightSections(bool highlight); + bool highlightSections() const; + + /*! + *设置固定格背景色 + *@param[in] index 列(行)号 + *@param[in] value 填充的背景色 + */ + void setFixedCellColor(const QColor &value, int index = -1); + void inserFixedCellColor(const QColor &value, int index); + void setFixedCellEvent(bool value); + bool isFixedcellEvent() const; + + void setGridLineWidth(int value); + void setGridLineColor(QColor value); + void setResizeMode(ResizeMode mode); + void setResizeMode(int logicalIndex, ResizeMode mode); + ResizeMode resizeMode() const; + ResizeMode resizeMode(int logicalIndex) const; + + void setSortIndicatorShown(bool show); + bool isSortIndicatorShown() const; + + void setSortIndicator(int logicalIndex, Qt::SortOrder order); + int sortIndicatorSection() const; + void setSortIndicatorSection(int logicalIndex); + Qt::SortOrder sortIndicatorOrder() const; + void setSortIndicatorOrder(Qt::SortOrder order); + + bool cascadingSectionResizes() const; + void setCascadingSectionResizes(bool enable); + + int defaultSectionSize() const; + void setDefaultSectionSize(int size); + + int minimumSectionSize() const; + void setMinimumSectionSize(int size); + + bool isTree() const; + + /*! + *设置是否显示树形结构,仅对竖直表头有意义 + *由于会显示(隐藏)子节点,所以会更新行数 + *同时,会导致之前设置的行高,无效 + *@param[in] showTree + */ + void setIsTree(bool showTree); + + bool autoSectionData() const; + + /*! + *设置是否自动填充列(行)号 + *@param[in] autoData + */ + void setAutoSectionData(bool autoData); + + int fixedCount() const; + + /*! + *设置固定编辑列(行)数 + *@param[in] fixedCount + */ + virtual void setFixedCount(int fixedCount); + + Qt::Alignment defaultAlignment() const; + void setDefaultAlignment(Qt::Alignment alignment); + + /*! + *重置表头 + *@return 无 + */ + void doItemsLayout(); + + /*! + *返回是否有列(行)移动过 + *@return bool + */ + bool sectionsMoved() const; + + /*! + * @brief 清除列移动的信息 + */ + void clearSectionMove(); + + /*! + *返回是否有列(行)隐藏 + *@return bool + */ + bool sectionsHidden() const; + + /*! + *返回指定坐标的sectionHandle + *@return int + */ + int getSectionHandleAt(int position); + + QModelIndex indexAt(const QPoint &p) const; + bool isIndexHidden(const QModelIndex &index) const; + bool isAllSectionHidden() const; + + void paintEvent(QPaintEvent *e); + bool viewportEvent(QEvent *e); + virtual void updateGeometries(); + void currentChanged(const QModelIndex ¤t, const QModelIndex &old); + /** + * @brief 调整行(列),高(框)时,返回鼠标的位置 + * @return + */ + QPoint mousePosition(); + void setMousePosition(QPoint pos); + + void setResizeDelay(bool delay); + +#ifndef QT_NO_DATASTREAM + QByteArray saveState() const; + bool restoreState(const QByteArray &state); +#endif + + /*! + *重置表头 + *@return 无 + *@see 参见GlodonAbstractItemView::reset(); + */ + void reset(); + + /*! + *为分组模式重置表头 + *@return 无 + *@see 参见GlodonAbstractItemView::reset(); + */ + inline void resetForGroup() + { + initializeSections(); + } + + void resetAfterTreeBuild(const QVector &showRows); + + /** + * @brief 重置表头,即使sectionCount没有变化 + */ + void resetSectionItems(); + + /** + * @brief 根据缩放因子,缩放headerView的大小 + */ + void zoomInSection(double factor); + + void setInZoomingSection(bool zooming); + bool inZoomingSection() const; + + /** + * @brief 设置是表头移动的数据是否写入到model中 + * @brief 暂时需要外部截获canSectionMove信号进行处理 + */ + void setLogicalSectionMovable(bool isManual); + bool isLogicalSectionMovable() const; + + /** + * @brief 设置是否显示边框 + * @return + */ + bool drawBorder() const; + void setDrawBorder(bool value); + + /** + * @brief 设置是否允许双击事件 + * @return + */ + bool allowDoubleClicked() const; + void setAllowDoubleClicked(bool value); + + /** + * @brief 选中时,字体是否加粗显示 + * @return + */ + bool boldWithSelected(); + void setBoldWithSelected(bool value); + + /** + * @brief 字体是否带有白色阴影 + * @return + */ + bool isFontShadow() const; + void setFontShadow(bool fontShadow); + + QColor fontShadowColor() const; + void setFontShadowColor(const QColor &clr); + + /** + * @brief isHeaderLinearGradient 判断表头是否带有渐变色 + * @return + */ + bool isHeaderLinearGradient() const; + void setHeaderLinearGradient(bool value); + + /** + * @brief 设置排序列的箭头是否在文字的上方 + * @param bIsSortArrowOnTextUp + */ + void setSortArrowOnTextTop(bool bIsSortArrowOnTextTop); + + void setLogicalIndexImage(QMultiHash logicalIndexHash, int spanTop); + + /*! + * \brief 批量reSizeSection过程中只会重新设置SectionItem中的size,最后只调用一次recalcSectionStartPos + * \param logicalIndexSizes key为sectionIndex,value为size + */ + void batchResizeSection(const QMap &logicalIndexSizes); + +public Q_SLOTS: + virtual void setOffset(int offset); + void setOffsetToSectionPosition(int visualSectionNumber); + void setOffsetToLastSection(); + void headerDataChanged(Qt::Orientation orientation, int logicalFirst, int logicalLast); + void setDrawWidth(int drawWidth); + +Q_SIGNALS: + void sectionMoved(int logicalIndex, int oldVisualIndex, int newVisualIndex); + void sectionResized(int logicalIndex, int oldSize, int newSize, bool isManual = false); + void sectionPressed(int logicalIndex); + void sectionClicked(int logicalIndex); + void sectionEntered(int logicalIndex); + void sectionDoubleClicked(int logicalIndex); + void sectionCountChanged(int oldCount, int newCount); + void sectionHandleDoubleClicked(int logicalIndex); + void sectionAutoResize(int logicalIndex, GlodonHeaderView::ResizeMode mode); + + void geometriesChanged(); + void sortIndicatorChanged(int logicalIndex, Qt::SortOrder order); + void scrolled(int offset); + void drawWidthChanged(int newWidth); + void canSectionMove(int from, int to, bool &canMove); + /** + * @brief 调整行(列)大小时,发型号,通知tableview画黑线 + * @param mousePosition 鼠标的位置 + * @param direction headview的方向 + * @param state 当前处于什么状态(mousepress,mousemove, mouserelease) + */ + void sectionResizing(QPoint &mousePosition, Qt::Orientation direction, GlodonHeaderView::ResizeState state); + +protected Q_SLOTS: + void updateSection(int logicalIndex); + void sectionsInserted(const QModelIndex &parent, int logicalFirst, int logicalLast); + void sectionsAboutToBeRemoved(const QModelIndex &parent, int logicalFirst, int logicalLast); + +protected: + GlodonHeaderView(GlodonHeaderViewPrivate &dd, Qt::Orientation orientation, QWidget *parent = 0); + + void updateTargetSectionRecord(int pos); + void setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags flags); + + void scrollTo(const QModelIndex &index, ScrollHint hint); + void scrollContentsBy(int dx, int dy); + + void rowsInserted(const QModelIndex &parent, int start, int end); + + /** + * @brief 绘制排序列的表头小三角 + * @param painter + * @param opt + * @param widget + */ + void paintSectionSortArrow(QPainter *painter, QStyleOptionHeader &opt, const QWidget *widget) const; + + /*! + * @brief 基于Qt绘制函数绘制表头section部分 + * @param [i]painter + * @param [i]opt + * @param [i]widget + * @return void + */ + void paintSectionOnQt(QPainter *painter, QStyleOptionHeader &opt, const QWidget *widget, bool bHighLight) const; + void paintHighLightSection(QPainter *painter, QStyleOptionHeader &opt, const QRect &rect) const; + void paintEmptySection(QPainter *painter, const QRect &rect); + + void mouseReleaseEvent(QMouseEvent *e); + void mousePressEvent(QMouseEvent *e); + void mouseMoveEvent(QMouseEvent *e); + void mouseDoubleClickEvent(QMouseEvent *e); + + inline bool isInValidLogicalIndex(const int &logicalIndex) const + { + return logicalIndex < 0 || logicalIndex >= count(); + } + + void initStyleOption(QStyleOptionHeader *option) const; + void initializeSections(int start, int end); + void initializeSections(); + void initialize(); + + void fillFixedCell(QPainter *painter, QStyleOptionHeader &opt, QRect rect, int logicalIndex) const; + void drawCellBorder(QPainter *painter, QStyleOptionHeader &opt) const; + + virtual void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const; + virtual void paintSection(int beginToHideIndex) const; + + virtual QSize sectionSizeFromContents(int logicalIndex) const; + + QRegion visualRegionForSelection(const QItemSelection &selection) const; + + QRect visualRect(const QModelIndex &index) const; + QRect textRect(const QRect &rect) const; + + QModelIndex moveCursor(CursorAction, Qt::KeyboardModifiers); + + int verticalOffset() const; + int horizontalOffset() const; + + bool event(QEvent *e); + + void drawImageInDesignatedLogicalIndex(QPainter *painter, QStyleOptionHeader &supopt) const; + +private Q_SLOTS: + void _q_sectionsRemoved(const QModelIndex &parent, int logicalFirst, int logicalLast); + void _q_layoutAboutToBeChanged(); + +private: + bool m_isSortArrowOnTextTop; + +private: + friend class GLDTableView; + friend class GLDTableViewPrivate; + Q_DECLARE_PRIVATE(GlodonHeaderView) + Q_DISABLE_COPY(GlodonHeaderView) +}; + +struct GlodonCellAttr +{ +public: + Qt::Orientation orientation; + QColor background; +}; + +class GLDTABLEVIEWSHARED_EXPORT GlodonHHeaderView : public GlodonHeaderView +{ + Q_OBJECT +public: + explicit GlodonHHeaderView(QWidget *parent = 0); + ~GlodonHHeaderView(); + +}; + +class GLDTABLEVIEWSHARED_EXPORT GlodonVHeaderView : public GlodonHeaderView +{ + Q_OBJECT +public: + explicit GlodonVHeaderView(QWidget *parent = 0); + ~GlodonVHeaderView(); + +}; + +class GLDTABLEVIEWSHARED_EXPORT GlodonHHeaderViewGraphicsEffect : public QGraphicsEffect +{ +public: + GlodonHHeaderViewGraphicsEffect(GlodonHeaderView *header) + : QGraphicsEffect(header) + , m_header(header) + , m_clrStart("#A5AAB3") + , m_clrMid("#A5AAB3") + , m_clrEnd("#A5AAB3") + , m_shadowHeight(3) + { + m_clrMid.setAlpha(40); + m_clrEnd.setAlpha(20); + } + virtual void draw(QPainter *painter); + + virtual QRectF boundingRectFor(const QRectF &rect) const; + + void setStartColor(const QColor &color) + { + m_clrStart = color; + } + void setMidColor(const QColor &color) + { + m_clrMid = color; + } + void setEndColor(const QColor &color) + { + m_clrEnd = color; + } + + void setShadowHeight(int height) + { + m_shadowHeight = height; + } + +private: + GlodonHeaderView *m_header; + QColor m_clrStart; + QColor m_clrMid; + QColor m_clrEnd; + int m_shadowHeight; +}; + +#endif // GLDHEADERVIEW_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDHeaderView_p.h b/GCR/trunk/Glodon/include/GLD/GLDHeaderView_p.h new file mode 100644 index 00000000..a019f028 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDHeaderView_p.h @@ -0,0 +1,389 @@ +#ifndef GLDHEADERVIEW_P_H +#define GLDHEADERVIEW_P_H + +#include "GLDAbstractItemView_p.h" +#include "GLDHeaderView.h" + +class GlodonHeaderViewPrivate: public GlodonAbstractItemViewPrivate +{ + Q_DECLARE_PUBLIC(GlodonHeaderView) + +public: + enum StateVersion { VersionMarker = 0xff }; + + GlodonHeaderViewPrivate() + : m_state(NoState), + offset(0), + sortIndicatorOrder(Qt::DescendingOrder), + sortIndicatorSection(0), + sortIndicatorShown(false), + fixedCount(0), + isTree(false), + autoSectionData(false), + lastPos(-1), + firstPos(-1), + originalSize(-1), + section(-1), + target(-1), + pressed(-1), + m_hover(-1), + drawWidth(0), + gridLineWidth(1), + length(0), + m_srcLength(-1), + preventCursorChangeInSetOffset(false), + movableSections(true), + clickableSections(true), + highlightSelected(true), + cascadingResizing(false), + m_inZoomForceResize(false), + defaultSectionSize(0), + minimumSectionSize(-1), + lastSectionSize(0), + sectionIndicatorOffset(0), + sectionIndicator(0), + globalResizeMode(GlodonHeaderView::Interactive), + sectionStartposRecalc(true), + resizeDelay(true), + m_mousePosition(), + fixedCellEvent(false), + gridLineColor(255, 255, 255), + m_isMouseDoubleClick(false), + m_srcFontPointSize(-1), + m_createSectionSpanSeparate(false), + m_drawBorder(false), + m_allowDoubleClicked(true), + m_boldWithSelected(true), + m_bFontShadow(false), + m_clrFontShadow(244, 245, 249), + m_bLinearGradient(false), + m_logicalMovable(false) + + {} + + int modelSectionCount() const; + int childIndexRowCount(QModelIndex index) const; + int lastVisibleVisualIndex() const; + int sectionHandleAt(int position); + void setupSectionIndicator(int section, int position); + void updateSectionIndicator(int section, int position); + void updateHiddenSections(int logicalFirst, int logicalLast); + void _q_sectionsRemoved(const QModelIndex &parent, int logicalFirst, int logicalLast); + void _q_layoutAboutToBeChanged(); + void _q_layoutChanged(); + + bool isSectionSelected(int section) const; + bool isFirstVisibleSection(int section) const; + bool isLastVisibleSection(int section) const; + + inline bool rowIntersectsSelection(int row) const + { + return (m_selectionModel ? m_selectionModel->rowIntersectsSelection(row, m_root) : false); + } + + inline bool columnIntersectsSelection(int column) const + { + return (m_selectionModel ? m_selectionModel->columnIntersectsSelection(column, m_root) : false); + } + + inline bool sectionIntersectsSelection(int logical) const + { + return (orientation == Qt::Horizontal ? columnIntersectsSelection(logical) : rowIntersectsSelection(logical)); + } + + inline bool isRowSelected(int row) const + { + return (m_selectionModel ? m_selectionModel->isRowSelected(row, m_root) : false); + } + + inline bool isColumnSelected(int column) const + { + return (m_selectionModel ? m_selectionModel->isColumnSelected(column, m_root) : false); + } + + inline void prepareSectionSelected() + { + if (!m_selectionModel || !m_selectionModel->hasSelection()) + { + sectionSelected.clear(); + } + else if (sectionSelected.count() != sectionCount() * 2) + { + sectionSelected.fill(false, sectionCount() * 2); + } + else + { + sectionSelected.fill(false); + } + } + + inline int sectionCount() const + { + return sectionItems.count(); + } + + inline bool reverse() const + { + return orientation == Qt::Horizontal && q_func()->isRightToLeft(); + } + + inline int logicalIndex(int visualIndex) const + { + return logicalIndices.isEmpty() ? visualIndex : logicalIndices.at(visualIndex); + } + + inline int visualIndex(int logicalIndex) const + { + return visualIndices.isEmpty() ? logicalIndex : visualIndices.at(logicalIndex); + } + + inline void setDefaultValues(Qt::Orientation o) + { + orientation = o; + defaultSectionSize = (o == Qt::Horizontal ? 100 + : qMax(q_func()->minimumSectionSize(), 30)); + defaultAlignment = Qt::AlignCenter; + } + + inline bool isVisualIndexHidden(int visual) const + { + return !sectionHidden.isEmpty() && sectionHidden.at(visual); + } + + inline void setVisualIndexHidden(int visual, bool hidden) + { + if (!sectionHidden.isEmpty()) + { + sectionHidden.setBit(visual, hidden); + } + } + + QStyleOptionHeader getStyleOption() const; + + inline void invalidateCachedSizeHint() const + { + cachedSizeHint = QSize(); + } + + inline void initializeIndexMapping() const + { + if (visualIndices.count() != sectionCount() + || logicalIndices.count() != sectionCount()) + { + visualIndices.resize(sectionCount()); + logicalIndices.resize(sectionCount()); + + for (int s = 0; s < sectionCount(); ++s) + { + visualIndices[s] = s; + logicalIndices[s] = s; + } + } + } + + inline void clearCascadingSections() + { + firstCascadingSection = sectionCount(); + lastCascadingSection = 0; + cascadingSectionSize.clear(); + } + + inline void saveCascadingSectionSize(int visual, int size) + { + if (!cascadingSectionSize.contains(visual)) + { + cascadingSectionSize.insert(visual, size); + firstCascadingSection = qMin(firstCascadingSection, visual); + lastCascadingSection = qMax(lastCascadingSection, visual); + } + } + + inline bool sectionIsCascadable(int visual) const + { + return headerSectionResizeMode(visual) == GlodonHeaderView::Interactive; + } + + inline bool modelIsEmpty() const + { + return (m_model->rowCount(m_root) == 0 || m_model->columnCount(m_root) == 0); + } + + int fixedSectionsSize() const; + + void clear(); + void flipSortIndicator(int section); + void cascadingResize(int visual, int newSize, bool isManual); + + enum State { NoState, ResizeSection, MoveSection, SelectSections, NoClear, CXMoveSection } m_state; + + int offset; + Qt::Orientation orientation; + Qt::SortOrder sortIndicatorOrder; + int sortIndicatorSection; + bool sortIndicatorShown; + int fixedCount; + bool isTree; + bool autoSectionData; + + mutable QVector visualIndices; // visualIndex = visualIndices.at(logicalIndex) + mutable QVector logicalIndices; // logicalIndex = row or column in the model + mutable QBitArray sectionSelected; // from logical index to bit + mutable QBitArray sectionHidden; // from visual index to bit, 有行/列折叠时,所有行加入进来,全部展开时,为空。 + mutable QHash hiddenSectionSize; // from logical index to section size + mutable QHash cascadingSectionSize; // from visual index to section size + mutable QSize cachedSizeHint; + mutable QBasicTimer delayedResize; + + int firstCascadingSection; + int lastCascadingSection; + + int lastPos; + int firstPos; + int originalSize; + int section; // used for resizing and moving sections + int target; + int pressed; + int m_hover; + + int drawWidth; + int gridLineWidth; + int length; + int m_srcLength; + bool preventCursorChangeInSetOffset; + bool movableSections; + bool clickableSections; + bool highlightSelected; + bool cascadingResizing; + bool m_inZoomForceResize; + bool m_logicalMovable; + + int defaultSectionSize; + int minimumSectionSize; + int lastSectionSize; + int sectionIndicatorOffset; + Qt::Alignment defaultAlignment; + QLabel *sectionIndicator; + GlodonHeaderView::ResizeMode globalResizeMode; + QList persistentHiddenSections; + + mutable bool sectionStartposRecalc; + + bool resizeDelay; //调整行或者列大小时,是否实施刷新,默认为延迟刷新 + QPoint m_mousePosition;//存储调整行(列)大小时,鼠标的位置 + bool fixedCellEvent; //自定义固定格背景色 + QColor gridLineColor; + bool m_isMouseDoubleClick;//当鼠标双击时,置为True,防止在开启延迟调整行高(列宽)时,是否在MouseRelease中再次调整 + int m_srcFontPointSize; + bool m_createSectionSpanSeparate;//每列,行,单独作为一个sectionSpan,在使用放大缩小功能时,建议开启 + + mutable QHash fixedCellsColor; + + QMultiHash m_logicalIndexHash; //表头加图标 + + int m_spanTop; //所加图片的位置 + + // header section + struct SectionItem + { + uint size : 20; + uint reservedForIsHidden : 1; + uint resizeMode : 5; // (holding GlodonHeaderView::ResizeMode) + uint currentlyUnusedPadding : 6; + + int srcSize; + + union // This union is made in order to save space and ensure good vector performance (on remove) + { + mutable int calculated_startpos; // <- this is the primary used member. + mutable int tmpLogIdx; // When one of these 'tmp'-members has been used we call + int tmpDataStreamSectionCount; // recalcSectionStartPos() or set sectionStartposRecalc to true + }; + + inline SectionItem() + : size(0), srcSize(-1), resizeMode(GlodonHeaderView::Interactive) {} + inline SectionItem(int length, GlodonHeaderView::ResizeMode mode) + : size(length), srcSize(-1), resizeMode(mode), calculated_startpos(-1) {} + + inline int sectionSize() const + { + return size; + } + + inline int calculatedEndPos() const + { + return calculated_startpos + size; + } + +#ifndef QT_NO_DATASTREAM + inline void write(QDataStream &out) const + { + out << static_cast(size); + out << 1; + out << (int)resizeMode; + } + + inline void read(QDataStream &in) + { + int m; + in >> m; + size = m; + in >> tmpDataStreamSectionCount; + in >> m; + resizeMode = m; + } +#endif + + }; + + QVector sectionItems; + + void createSectionItems(int start, int end, int size, GlodonHeaderView::ResizeMode mode); + void removeSectionsFromSectionItems(int start, int end); + void resetGroupSectionSpans(int start, int end); + void resizeSectionItem(int visualIndex, int oldSize, int newSize, bool isManual); + void setDefaultSectionSize(int size); + void recalcSectionStartPos() const; // not really const + void resetAfterTreeBuild(const QVector &showRows); + void resetTreeSectionItems(const QVector &showRows); + int headerLength() const; // for debugging + int headerSectionSize(int visual) const; + int headerSectionPosition(int visual) const; + + /** + * @brief 根据绘制位置,返回行(列)号,不考虑滚动条的位置 + * @param position + * @return + */ + int headerVisualIndexAt(int position) const; + + // resize mode + void setHeaderSectionResizeMode(int visual, GlodonHeaderView::ResizeMode mode); + GlodonHeaderView::ResizeMode headerSectionResizeMode(int visual) const; + void setGlobalHeaderResizeMode(GlodonHeaderView::ResizeMode mode); + + // other + int viewSectionSizeHint(int logical) const; + int adjustedVisualIndex(int visualIndex) const; + void setScrollOffset(const QScrollBar *scrollBar, GlodonAbstractItemView::ScrollMode scrollMode); + + QRect viewportScrollArea(); + + void resizeSectionItem(int newSize, SectionItem &oCurrentSectionItem); + void excludeNotNeedHideSections(const QSet &logicalIndexs, bool hide, QSet> &oNeedHideLogicalAndVisualIndexs); + + void doBatchResizeSection(const QMap &logicalIndexSizes, bool isInHiddenSection); + +#ifndef QT_NO_DATASTREAM + void write(QDataStream &out) const; + bool read(QDataStream &in); +#endif + bool m_drawBorder; // 如果为treu则自绘左边线和上边线 + bool m_allowDoubleClicked; + bool m_boldWithSelected; // 当前列,行被选择时,字体是否加粗 + + bool m_bLinearGradient; // 表头背景是否渐变 + bool m_bFontShadow; // 表头字体是否带有泛白阴影 + QColor m_clrFontShadow; // 表头字体是否带有泛白阴影颜色 +}; + +#endif // GLDHEADERVIEW_P_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDIODevice.h b/GCR/trunk/Glodon/include/GLD/GLDIODevice.h new file mode 100644 index 00000000..8b343e76 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDIODevice.h @@ -0,0 +1,9 @@ +#ifndef GLDIODEVICE +#define GLDIODEVICE + +#include + +typedef QIODevice GStream; + +#endif // GLDIODEVICE + diff --git a/GCR/trunk/Glodon/include/GLD/GLDImageEditor.h b/GCR/trunk/Glodon/include/GLD/GLDImageEditor.h new file mode 100644 index 00000000..c620a27c --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDImageEditor.h @@ -0,0 +1,76 @@ +/*! + *@file gimageeditor.h + *@brief {图片选择控件} + *用于QImage类型数据的默认编辑方式 + *@author Gaosy + *@date 2012.9.7 + *@remarks {} + *Copyright (c) 1998-2012 Glodon Corporation + */ + +#ifndef GLDIMAGEEDITOR_H +#define GLDIMAGEEDITOR_H + +#include +#include +#include "GLDWidget_Global.h" +/*! + *@class: GImageEditor + *@brief {图片选择控件,作为显示图片的格子的默认编辑方式} + *@author Gaosy + *@date 2012.9.10 + */ +class GLDWIDGETSHARED_EXPORT GImageEditor : public QWidget +{ + Q_OBJECT +public: + /*! + *GImageEditor构造方法 + *@param[in] parent 父widget + *@return 无 + */ + explicit GImageEditor(QWidget *parent = 0); + + /*! + *GImageEditor析构方法 + *@return 无 + */ + virtual ~GImageEditor(); + + /*! + *GFilterView的绘制方法 + *@param[in] e + *@return 无 + */ + void paintEvent(QPaintEvent *); + + /*! + *为GImageEditor设置当前图片 + *@param[in] img 设置当前的图片 + *@return 无 + */ + void setImage(QImage img); + + /*! + *返回当前图片 + *@return QImage + */ + QImage image(); + +private: + //GImageEditor右侧的按钮,点击后弹出文件选择对话框, + //从中选择新的图片 + QPushButton *m_button; + + //用于在GImageEditor中绘制当前图片 + QLabel *m_label; + + //因为QLabel本身是透明的,因此在后面加一层QFrame绘制白色背景 + //去掉透明效果 + QFrame *m_frame; + +private slots: + void editorButtonClicked(); +}; + +#endif // GLDIMAGEEDITER_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDIniFiles.h b/GCR/trunk/Glodon/include/GLD/GLDIniFiles.h new file mode 100644 index 00000000..f02a1eae --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDIniFiles.h @@ -0,0 +1,119 @@ +#ifndef GLDINIFILES_H +#define GLDINIFILES_H + +#include "GLDString.h" +#include "GLDDateTime.h" +#include "GLDStringObjectList.h" + +class GLDCustomIniFilePrivate; +class GLDMemIniFilePrivate; +class GLDCOMMONSHARED_EXPORT GLDCustomIniFile +{ +public: + explicit GLDCustomIniFile(const GString &fileName); + virtual ~GLDCustomIniFile(); +public: + bool sectionExists(const GString §ion); + virtual GString readString(const GString §ion, const GString &ident, const GString &defVal) = 0; + virtual void writeString(const GString §ion, const GString &ident, const GString &value) = 0; + + virtual long readInteger(const GString §ion, const GString &ident, long defVal); + virtual void writeInteger(const GString §ion, const GString &ident, long value); + + virtual bool readBool(const GString §ion, const GString &ident, bool defVal); + virtual void writeBool(const GString §ion, const GString &ident, bool value); + + virtual int readBinaryStream(const GString §ion, const GString &name, GStream *value); + virtual void writeBinaryStream(const GString §ion, const GString &name, GStream *value); + + virtual GDate readDate(const GString §ion, const GString &name, GDate &defVal); + virtual void writeDate(const GString §ion, const GString &name, GDate &value); + + virtual GDateTime readDateTime(const GString §ion, const GString &name, GDateTime &defVal); + virtual void writeDateTime(const GString §ion, const GString &name, GDateTime &value); + + virtual double readFloat(const GString §ion, const GString &name, double defVal); + virtual void writeFloat(const GString §ion, const GString &name, double value); + + virtual GTime readTime(const GString §ion, const GString &name, GTime &defVal); + virtual void writeTime(const GString §ion, const GString &name, GTime &value); + + virtual void readSection(const GString §ion, GStringObjectList *strings) = 0; + virtual void readSections(GStringObjectList *strings) = 0; + virtual void readSections(const GString §ion, GStringObjectList *strings); + virtual void readSectionValues(const GString §ion, GStringObjectList *strings) = 0; + virtual void eraseSection(const GString §ion) = 0; + virtual void deleteKey(const GString §ion, const GString &ident) = 0; + virtual void updateFile() = 0; + virtual bool valueExists(const GString §ion, const GString &ident); + void setFileName(const GString &fileName); + GString fileName(); + +protected: + GLDCustomIniFile(const GString &fileName, GLDCustomIniFilePrivate &d); + GLDCustomIniFilePrivate * const d_ptr; + Q_DECLARE_PRIVATE(GLDCustomIniFile); +}; + +class GLDCOMMONSHARED_EXPORT GLDIniFile : public GLDCustomIniFile +{ +public: + explicit GLDIniFile(const GString &fileName); + ~GLDIniFile(); +public: + GString readString(const GString §ion, const GString &ident, const GString &defVal); + void writeString(const GString §ion, const GString &ident, const GString &value); + void readSection(const GString §ion, GStringObjectList *strings); + void readSections(GStringObjectList *strings); + void readSectionValues(const GString §ion, GStringObjectList *strings); + void eraseSection(const GString §ion); + void deleteKey(const GString §ion, const GString &ident); + void updateFile(); +private: + int strCopy(const GString &source, char *dest, int size = -1); + int getPrivateProfileString(const GString &strSectionName, const GString &strKeyName, GString strDefault, + char *pReturnedValue, int size, const GString &strFileName); + bool writePrivateProfileString(const GString &strSectionName, const GString &strKeyName, + const GString &strValue, const GString &strFileName); +}; + +/*! + *@ GLDMemIniFile + *@brief TMemIniFile - loads an entire INI file into memory and allows all + operations to be performed on the memory image. The image can then + be written out to the disk file + *@author duanb + *@date 2013.08.23 +*/ + +class GLDCOMMONSHARED_EXPORT GLDMemIniFile : public GLDCustomIniFile +{ +public: + explicit GLDMemIniFile(const GString &fileName); + ~GLDMemIniFile(); +public: + void clear(); + void deleteKey(const GString §ion, const GString &ident); + void eraseSection(const GString §ion); + void strings(GStringObjectList *list); + void readSection(const GString §ion, GStringObjectList *strings); + void readSections(GStringObjectList *strings); + void readSectionValues(const GString §ion, GStringObjectList *strings); + GString readString(const GString §ion, const GString &ident, const GString &Default); + void rename(const GString &fileName, bool reload); + void setStrings(GStringObjectList *list); + void updateFile(); + void writeString(const GString §ion, const GString &ident, const GString &value); + bool allowValueHasSpace(); + void setAllowValueHasSpace(bool allowValueHasSpace); + +private: + GStringObjectList* addSection(const GString §ion); + bool caseSensitive(); + void setCaseSensitive(bool value); + void loadValues(); +private: + Q_DECLARE_PRIVATE(GLDMemIniFile) +}; + +#endif // GLDINIFILES_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDIntList.h b/GCR/trunk/Glodon/include/GLD/GLDIntList.h new file mode 100644 index 00000000..b13c5ecb --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDIntList.h @@ -0,0 +1,10 @@ +#ifndef GLDINTLIST +#define GLDINTLIST + +#include + +typedef QList GIntList; +typedef QList GLongIntList; + +#endif // GLDINTLIST + diff --git a/GCR/trunk/Glodon/include/GLD/GLDInterfaceObject.h b/GCR/trunk/Glodon/include/GLD/GLDInterfaceObject.h new file mode 100644 index 00000000..6c3cf1ad --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDInterfaceObject.h @@ -0,0 +1,63 @@ +#ifndef GLDINTERFACEOBJECT_H +#define GLDINTERFACEOBJECT_H + +#include +#include "GLDUnknwn.h" +#include "GLDObject.h" +#include "GLDCommon_Global.h" + +#define DECLARE_IUNKNOWN_Q DECLARE_IUNKNOWN + +#ifndef QT_NO_QOBJECT +class GLDCOMMONSHARED_EXPORT QInterfaceObject : public QObject, public IUnknown +{ + Q_OBJECT +public: + explicit QInterfaceObject(QObject *parent = 0) : QObject(parent){m_cRef = 0;} + +public: + DECLARE_IUNKNOWN +signals: + +public slots: + +protected: + virtual HRESULT STDMETHODCALLTYPE _QueryInterface(REFIID riid, void **ppvObject) + { + if (riid == IID_IUnknown) + { + this->AddRef(); + *ppvObject = static_cast(this); + return NOERROR; + } + else + { + *ppvObject = NULL; + return E_NOINTERFACE; + } + } + + virtual ULONG STDMETHODCALLTYPE _AddRef(void) + { + return m_cRef++; + } + + virtual ULONG STDMETHODCALLTYPE _Release(void) + { + m_cRef--; + if (m_cRef == 0) + { + delete this; + return ULONG(0); + } + else + return m_cRef; + } + +private: + LONG m_cRef; +}; + +#endif + +#endif // GLDINTERFACEOBJECT_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDIrregularForm.h b/GCR/trunk/Glodon/include/GLD/GLDIrregularForm.h new file mode 100644 index 00000000..051f8c99 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDIrregularForm.h @@ -0,0 +1,39 @@ +#ifndef GLDIRREGULARFORM_H +#define GLDIRREGULARFORM_H + +#include "GLDMask_Global.h" + +#include +#include + +class GLDCustomButton; + +class GLDMASKSHARED_EXPORT GLDIrregularForm : public QWidget +{ + Q_OBJECT + +public: + explicit GLDIrregularForm(QWidget *parent = 0); + explicit GLDIrregularForm(const QString & irregularImgPath, const QString & btnImgPath, QWidget *parent = 0); + + void setFlagAndAttribute(); + + ~GLDIrregularForm(); + + QSize sizeHint() const; + + void loadPixmap(const QString & pixmapPath); + void setPixmap(const QPixmap & pm); + +Q_SIGNALS: + void irregularFormClicked(); + +protected: + virtual void paintEvent(QPaintEvent *event); + +private: + GLDCustomButton* m_pCustomBtn; + QPixmap m_irregularFormPm; +}; + +#endif // GLDIRREGULARFORM_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDJSONTypes.h b/GCR/trunk/Glodon/include/GLD/GLDJSONTypes.h new file mode 100644 index 00000000..6b3e526d --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDJSONTypes.h @@ -0,0 +1,18 @@ +#ifndef GLDJSONTYPES_H +#define GLDJSONTYPES_H + +#include +#include +#include +#include +#include +#include + +typedef QJsonDocument GJsonDocument; +typedef QJsonArray GJsonArray; +typedef QJsonObject GJsonObject; +typedef QJsonValue GJsonValue; +typedef QJsonValueRef GJsonValueRef; +typedef QJsonParseError GJsonParseError; + +#endif // GLDJSONTYPES_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDJSONUtils.h b/GCR/trunk/Glodon/include/GLD/GLDJSONUtils.h new file mode 100644 index 00000000..5e4e5788 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDJSONUtils.h @@ -0,0 +1,29 @@ +#ifndef GLDJSONUTILS_H +#define GLDJSONUTILS_H + +#include "GLDString.h" +#include "GLDJSONTypes.h" +#include "GLDSystem.h" +#include +#include "GLDCommon_Global.h" + +GLDCOMMONSHARED_EXPORT GString readStrFromJSON(const GJsonObject &jsonObject, const GString &jsonObjectKey, const GString &defVal = ""); +GLDCOMMONSHARED_EXPORT bool readBoolFromJSON(const GJsonObject &jsonObject, const GString &jsonObjectKey, bool defVal = false); +GLDCOMMONSHARED_EXPORT int readIntFromJSON(const GJsonObject &jsonObject, const GString &jsonObjectKey, int defVal = 0); +GLDCOMMONSHARED_EXPORT gint64 readInt64FromJSON(const GJsonObject &jsonObject, const GString &jsonObjectKey, long long defVal = 0); +GLDCOMMONSHARED_EXPORT guint64 readUInt64FromJSON(const GJsonObject &jsonObject, const GString &jsonObjectKey, guint64 defVal = 0); +GLDCOMMONSHARED_EXPORT double readFloatFromJSON(const GJsonObject &jsonObject, const GString &jsonObjectKey, double defVal = 0); + +GLDCOMMONSHARED_EXPORT void writeStrToJSON(GJsonObject &jsonObject, const GString &jsonObjectKey, const GString &value, const GString &defVal = ""); +GLDCOMMONSHARED_EXPORT void writeBoolToJSON(GJsonObject &jsonObject, const GString &jsonObjectKey, bool value, bool defVal = false); +GLDCOMMONSHARED_EXPORT void writeIntToJSON(GJsonObject &jsonObject, const GString &jsonObjectKey, int value, int defVal = 0); +GLDCOMMONSHARED_EXPORT void writeInt64ToJSON(GJsonObject &jsonObject, const GString &attrjsonObjectKey, long long value, long long defVal = 0); +GLDCOMMONSHARED_EXPORT void writeUInt64ToJSON(GJsonObject &jsonObject, const GString &attrjsonObjectKey, guint64 value, guint64 defVal = 0); +GLDCOMMONSHARED_EXPORT void writeFloatToJSON(GJsonObject &jsonObject, const GString &jsonObjectKey, double value, double defVal = 0); + +GLDCOMMONSHARED_EXPORT GJsonDocument loadJSONDocument(const GString &fileName); +GLDCOMMONSHARED_EXPORT GJsonDocument loadJSONDocument(QTextStream &stream); +GLDCOMMONSHARED_EXPORT void saveJSONDocument(GJsonDocument &doc, const GString &fileName); +GLDCOMMONSHARED_EXPORT void saveJSONDocument(GJsonDocument &doc, QTextStream &stream); + +#endif // GLDJSONUTILS_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDKeyboardButton.h b/GCR/trunk/Glodon/include/GLD/GLDKeyboardButton.h new file mode 100644 index 00000000..b129df62 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDKeyboardButton.h @@ -0,0 +1,24 @@ +#ifndef GLDKEYBOARDBUTTON_H +#define GLDKEYBOARDBUTTON_H + +#include +#include +#include "GLDString.h" +#include "GLDWidget_Global.h" + +class GLDWIDGETSHARED_EXPORT GLDKeyboardButton : public QPushButton +{ + Q_OBJECT +public: + explicit GLDKeyboardButton(const QString &text, QWidget *parent = 0); + + void setButtonText(const GString specialSymbolList[], + const GString specialSymbolListBlock[], + int length); +public slots: + void switchLetterCase(); + void switchNumberAndSymbol(); + void switchPunctuations(); +}; + +#endif // GLDKEYBOARDBUTTON_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDKeyboardInput.h b/GCR/trunk/Glodon/include/GLD/GLDKeyboardInput.h new file mode 100644 index 00000000..a01e9f28 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDKeyboardInput.h @@ -0,0 +1,48 @@ +#ifndef GLDKEYBOARDINPUT_H +#define GLDKEYBOARDINPUT_H + +#include +#include +#include +#include + +#include "GLDString.h" +#include "GLDWidget_Global.h" + +class QPushButton; + +class GLDWIDGETSHARED_EXPORT GLDKeyboardInput : public QWidget +{ + Q_OBJECT +public: + explicit GLDKeyboardInput(QWidget *parent = 0); + +public slots: + void onClickedCapsLock(bool checked); + void onClickedShift(bool checked); + +public: + void initUI(); + void show(); + void addButton(QGridLayout *pgridlayout, const GString numberTagList[], + const GString numberTagListBlock[], int lineNumber, + int startKeySpace, int length); + void onClickCapsAndShift(bool checked); + void addButton(QGridLayout *pgridlayout, QMap hashMap, int lineNumber, int startKeySpace); + +private: + void initConnection(); + void setFormsMask(); + void mouseMoveEvent(QMouseEvent *event); + void focusOutEvent(QFocusEvent *); + +private: + QPushButton *m_pclosebtn; + QPushButton *m_pdeletebtn; + QPushButton *m_pshiftbtn; + QPushButton *m_pcapslockbtn; + + QSignalMapper *m_signalMapperLowercase; + QSignalMapper *m_signalMapperBlockletter; +}; +#endif // GLDKEYBOARDINPUT_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDLineWidthComboBoxEx.h b/GCR/trunk/Glodon/include/GLD/GLDLineWidthComboBoxEx.h new file mode 100644 index 00000000..802fc5cb --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDLineWidthComboBoxEx.h @@ -0,0 +1,156 @@ +/**** + * @file : GLDLineWidthComboBoxEx.h + * @brief : 重写了线条宽度选择框。 + * 1.支持更多选择按钮,并且浮动在最后不随滚动条滑动 + * 2.根据用户体验的要求,将像素改为磅数,并显示在前面 + * 3.QSS美化了界面,每个控件定义了property属性,要修改可以再qss中定位再修改属性。 + * + * @date : 2014-08-18 + * @author : lijl-c + * @remarks: 实现思路:QComboBox中加载2个QListWidget.上面的再嵌套QListWidget + * 每行是1个QLabel和QPushButton + ****/ + +#ifndef GLDLINEWIDTHCOMBOBOXEX_H +#define GLDLINEWIDTHCOMBOBOXEX_H + +#include +#include +#include +#include +#include +#include +#include "GLDWidget_Global.h" + +class GLDWIDGETSHARED_EXPORT GLDLineWidthButton : public QPushButton +{ + Q_OBJECT +public: + explicit GLDLineWidthButton(qreal lineWeight, QWidget *parent = 0); + ~GLDLineWidthButton(){} + +protected: + void resizeEvent(QResizeEvent *e); + +private: + /** + * @brief drawLineWidth 画每一行的线宽 + * @param lineWeight + * @param lineLength + */ + void drawLineWidth(qreal lineWeight, int lineLength); + +private: + qreal m_lineWeigth; +}; + +/** + * @brief The GLDLineWidthRow class 线宽下拉框中的一行 + */ +class GLDWIDGETSHARED_EXPORT GLDLineWidthRow : public QWidget +{ + Q_OBJECT +public: + explicit GLDLineWidthRow(QWidget *parent = 0, int rowIndex = 0); + ~GLDLineWidthRow(){} + +public: + /** + * @brief initRowLabel 初始化每行的label + * @param rowIndex + */ + void initRowLabel(int rowIndex); + + /** + * @brief initRowButton 初始化每行的线宽Button + * @param rowIndex + */ + void initRowButton(int rowIndex); + +signals: + void mapped(int index); + +private: + QLabel *m_label; + GLDLineWidthButton *m_lineWidthBtn; + QHBoxLayout *m_rowLayout; + int m_rowIndex; +}; + +class GLDWIDGETSHARED_EXPORT GLDLineWidthComboBoxEx : public QComboBox +{ + Q_OBJECT +public: + explicit GLDLineWidthComboBoxEx(QWidget *parent = 0); + ~GLDLineWidthComboBoxEx(); + + inline int minLineCount() { return m_minLineCount; } + inline void setMinLineCount(int minLineCount) { m_minLineCount = minLineCount; } + + inline int maxLineCount() { return m_maxLineCount; } + inline void setMaxLineCount(int maxLineCount) { m_maxLineCount = maxLineCount; } + + inline int currentIndex() {return m_curIndex;} + inline void setCurrentIndex(const int index){ m_curIndex = index;} + + inline double curLineWidth() { return m_curLineWidth; } + inline void setCurLineWidth(const double curLineWidth) { m_curLineWidth = curLineWidth; } + + inline int lineWidthPopupHight() { return m_lineWidthPopupHight; } + inline void setLineWidthPopupHight(int height) { m_lineWidthPopupHight = height; } + + void setHasBorder(bool hasBorder = false); + +private: + /** + * @brief 初始化控件模型,绘制控件 + * + * @fn initModel + */ + void initPopUp(); + + /** + * @brief initLineWidthPart 初始化下拉框上半部分, 包括 磅值labels和线宽buttons部分 + */ + void initLineWidth(); + + /** + * @brief initMoreLinesPart 初始化下拉框下半部分, 更多颜色Button + */ + void initMoreLinesButton(); + + /** + * @brief createLineWidthRow 创建一行 + * @param index + * @return + */ + QWidget* createLineWidthRow(int index); + + /** + * @brief 为线框项添加内容,即添加每一行的内容 + * + * @fn createLineWidthRowItem + * @return QListWidget + */ + void createLineWidthRowItem(QListWidget *pLineWidthItem); + + void createMoreLinesItem(QListWidget *pMoreItem); + +signals: + void itemClicked(int index); + +private slots: + void onClicked(int index); + void onClicked(); + +private: + int m_minLineCount; /**< TODO 最小线条数量*/ + int m_maxLineCount; /**< TODO 最大线条数量*/ + int m_lineWidthPopupHight; /**< TODO 下拉框高度*/ + bool m_hasBorder; //是否需要边框 + QListWidget *m_popupListWidgets; + int m_curIndex; + double m_curLineWidth; +}; + +#endif // GLDLINEWIDTHCOMBOBOXEX_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDList.h b/GCR/trunk/Glodon/include/GLD/GLDList.h new file mode 100644 index 00000000..0eee4cbb --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDList.h @@ -0,0 +1,12 @@ +#ifndef GLDLIST +#define GLDLIST + +#include + +template +class GLDList : public QList +{ +}; + +#endif // GLDLIST + diff --git a/GCR/trunk/Glodon/include/GLD/GLDListView.h b/GCR/trunk/Glodon/include/GLD/GLDListView.h new file mode 100644 index 00000000..f094e85c --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDListView.h @@ -0,0 +1,247 @@ +#ifndef GLDLISTVIEW_H +#define GLDLISTVIEW_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "GLDWidget_Global.h" + +class GLDListView; +class GLDCommonStyle; +class GLDShellTreeView; +class GLDListViewPrivate; + +namespace innerGLD{ + +class GLDWIDGETSHARED_EXPORT innerShellTreeView : public QTreeView +{ + Q_OBJECT +public: + explicit innerShellTreeView(QWidget *parent = 0); + +public: + void setModel(QAbstractItemModel *model); + QAbstractItemModel *dataModel(); + + QModelIndex dataIndex(const QModelIndex &index); + QModelIndex proxyIndex(const QModelIndex &index); + + bool showBranches() const { return m_bShowBranches; } + void setShowBranches(bool b){ m_bShowBranches = b; } + +public slots: + void adjustColumnWidth(const QModelIndex &); + +signals: + void intoPath(const QModelIndex &); + void currentItemJustChanged(const QModelIndex ¤t, const QModelIndex &previous); + void itemPressed(const QModelIndex &index); + +protected slots: + void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected); + +protected: + bool event(QEvent *e); + void drawBranches(QPainter *painter, + const QRect &rect, + const QModelIndex &index) const; + void mousePressEvent(QMouseEvent *event); + void mouseDoubleClickEvent(QMouseEvent *event); + void currentChanged(const QModelIndex ¤t, const QModelIndex &previous); + virtual QSortFilterProxyModel *createSortModel(); + +private slots: + void onItemPressed(const QModelIndex &index); + +protected: + /*! + * \brief m_bShowBranches 是否绘制表示展开/收起的小图标 + */ + bool m_bShowBranches; + +private: + QAbstractItemModel *m_pDataModel; + QSortFilterProxyModel *m_pModel; + +private: + friend class GLDListView; + typedef QTreeView inherit; +}; +} + +class GLDWIDGETSHARED_EXPORT GLDListView : public QListView +{ + Q_OBJECT +public: + GLDListView(QWidget *parent = 0); + ~GLDListView(); + + void setModel(QAbstractItemModel *model); + void setRootIndex(const QModelIndex &index); + QRect visualRect(const QModelIndex &index) const; + + enum GLDViewMode { VSListMode, VSIconMode, VSSmallIconMode, VSReportMode}; + + + virtual void setVsViewMode(GLDViewMode mode); + virtual GLDViewMode vsViewMode() const; + + bool showToolTip()const{ return m_bShowToolTip; } + + void setShowToolTip(bool l){ m_bShowToolTip = l; } + + void enterEdit(const QModelIndex &index); + void setSectionResizeMode(int logicalIndex, QHeaderView::ResizeMode mode); + + /*! + * \brief setDragActionEnable 设置拖拽功能是否启用。注意,不要使用setDragDropMode和setDragEnabled等Qt方法,不保证有效。 + * \note 默认是开启状态 + * \param enable + */ + void setDragActionEnable(bool enable); + bool dragActionEnabled() const; + + /*! + * \brief currentVSViewStateName + * \return 当前的VsViewMode的状态的名称{list,icon,smallicon,report}四种 + */ + virtual QString currentVSViewStateName() const; + + /*! + * \brief 需要先切换到ReportModel,再调用该方法 + * \return + */ + innerGLD::innerShellTreeView *shellTreeView(); + +Q_SIGNALS: + void itemJustBeSelected(const QModelIndex &index); + void itemJustBeDoubleClicked(const QModelIndex &index); + void currentItemJustChanged(const QModelIndex ¤t, const QModelIndex &previous); + +protected slots: + void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected); + void initVsViewState(); + +protected: + bool event(QEvent *event); + void paintEvent(QPaintEvent *e); + void timerEvent(QTimerEvent *e); + void currentChanged(const QModelIndex ¤t, const QModelIndex &previous); + void mouseDoubleClickEvent(QMouseEvent *event); + void dropEvent(QDropEvent *e); + + void setViewMode(ViewMode mode); + void switchDragDropState(); + void switchChildTreeDragDropState(); + inline bool currentReportMode() const { return VSReportMode == m_viewMode; } + virtual innerGLD::innerShellTreeView* createTreeView(); + +protected: + mutable QTime stopDelayedLayoutTime; + mutable bool stopDelayedLayoutTimer; + bool m_bShowToolTip; + bool m_bDragEnabled; + bool m_bVsModeSetted; + GLDViewMode m_viewMode; + innerGLD::innerShellTreeView *m_shellTree; + +private slots: + void onInnerShellTreeViewClick(const QModelIndex &index); + +private: + Q_DECLARE_PRIVATE(GLDListView) + Q_DISABLE_COPY(GLDListView) + friend class innerGLD::innerShellTreeView; + void init(); + typedef QListView inherit; +}; + +class GLDListViewPrivate: public QListViewPrivate +{ + Q_DECLARE_PUBLIC(GLDListView) +public: + GLDListViewPrivate():QListViewPrivate(){} + + ~GLDListViewPrivate(){} + + void interruptDelayedItemsLayout() const; + QRect mapToViewport(const QRect &rect, bool extend) const; + QStyleOptionViewItem viewOptions() const; + + inline QVector intersectingSet(const QRect &area, bool doLayout = true) const { + if (doLayout) executePostedLayout(); + QRect a = (q_func()->isRightToLeft() ? flipX(area.normalized()) : area.normalized()); + return commonListView->intersectingSet(a); + } + + inline void executePostedLayout() const + { + if (delayedPendingLayout && state != (GLDListView::CollapsingState)) + { + interruptDelayedItemsLayout(); + const_cast(q_func())->doItemsLayout(); + } + } +protected: + void updateStyledFrameWidths(); + QStyleOptionViewItem abstractViewOptions() const; + +private: + Q_DISABLE_COPY(GLDListViewPrivate) +}; + +class GLDWIDGETSHARED_EXPORT GLDListStyledItemDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + GLDListStyledItemDelegate(QObject *parent = 0):QStyledItemDelegate(parent){} + + ~GLDListStyledItemDelegate(){} + + void paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const; +}; + +class GLDWIDGETSHARED_EXPORT GLDWindowsVistaStyle : public QProxyStyle +{ + Q_OBJECT +public: + GLDWindowsVistaStyle(GLDListView *list):QProxyStyle(), m_textLineHeight(0), m_custom(list){} + + QRect subElementRect(SubElement sr, const QStyleOption *opt, + const QWidget *widget) const; + void drawPrimitive(PrimitiveElement element, const QStyleOption *option, + QPainter *painter, const QWidget *widget = 0) const; + + mutable double m_textLineHeight; +protected: + GLDListView *m_custom; +private: + void* parentOffset; + void* grandparentOffset; +}; + +class GLDWIDGETSHARED_EXPORT GLDFileSortModel : public QSortFilterProxyModel +{ + Q_OBJECT +public: + GLDFileSortModel(QObject *parent = 0); + +protected: + bool lessThan(const QModelIndex &left, const QModelIndex &right) const; + +private: + bool sizeCompare(const QVariant &oLeftData, const QVariant &oRightData) const; + +private: + QHash m_oSizeUnits; +}; + +#endif // GLDLISTVIEW_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDMD5.h b/GCR/trunk/Glodon/include/GLD/GLDMD5.h new file mode 100644 index 00000000..d7f8876a --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDMD5.h @@ -0,0 +1,53 @@ +/* + * This is the header file for the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an + * MD5Context structure, pass it to MD5Init, call MD5Update as + * needed on buffers full of bytes, and then call MD5Final, which + * will fill a supplied 16-byte array with the digest. + * + * Changed so as no longer to depend on Colin Plumb's `usual.h' + * header definitions; now uses stuff from dpkg's config.h + * - Ian Jackson . + * Still in the public domain. + */ + +#ifndef GLDMD5_H +#define GLDMD5_H + +#include "GLDCrypt_Global.h" +#include "GLDString.h" +#include "GLDIODevice.h" +#include "GLDCrypt_Global.h" + +typedef unsigned char md5byte; +typedef unsigned int UWORD32; + +struct MD5Context { + UWORD32 buf[4]; + UWORD32 bytes[2]; + UWORD32 in[16]; +}; + +GLDCRYPTSHARED_EXPORT GString getMD5(const char *buffer, size_t bufSize); +GLDCRYPTSHARED_EXPORT GString getMD5(GStream *stream); +GLDCRYPTSHARED_EXPORT GString strMD5(const GString &buffer); +GLDCRYPTSHARED_EXPORT GString fileMD5(const GString &fileName); + +static void MD5Init(struct MD5Context *context); +static void MD5Update(struct MD5Context *context, md5byte const *buf, unsigned len); +static void MD5Final(struct MD5Context *context, unsigned char digest[16]); +static void MD5Transform(UWORD32 buf[4], UWORD32 const in[16]); + +static void MD5UpdateBuffer(struct MD5Context *context, const char *buffer, size_t bufSize); +static void MD5UpdateBuffer(struct MD5Context *context, GStream *stream); + +#endif // GLDMD5_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDMacroUtils.h b/GCR/trunk/Glodon/include/GLD/GLDMacroUtils.h new file mode 100644 index 00000000..af2a940f --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDMacroUtils.h @@ -0,0 +1,53 @@ + +/********************************************************************** + * + * 广联达 宏工具单元 + * + * 设计:Zhangsk 2012.04.17 + * 备注: + * 审核: + * 注意: + * + * Copyright (c) 2012-2013 GlodonSoft Corporation + * + **********************************************************************/ + +#ifndef GLDMACROUTILS_H +#define GLDMACROUTILS_H + + + +//字符化操作符。 +#define makechar(x) #@x + +//把宏参数变为一个字符串。 +#define makestring(x) #x + +//符号连接操作符。将宏定义的多个形参成一个实际参数名。 +#define token_pasting(n) num##n + +//#define IID_PPV_ARGS + + +extern "C++" +{ + template void** IID_PPV_ARGS_Helper(T** pp) + { + // make sure everyone derives from IUnknown + static_cast(*pp); + + return reinterpret_cast(pp); + } +} + +#define IID_PPV_ARGS(ppType) __uuidof(**(ppType)), IID_PPV_ARGS_Helper(ppType) + +#define IID_PPV_ARGS_Base(Type, Expr) IID_##Type, \ + reinterpret_cast(static_cast(Expr)) + +//todo: 辅助宏帮助支持#pragma once的编译器 +//#if defined (_MSC_VER) && (_MSC_VER >= 1020) && !defined(__midl) +//#pragma once +//#endif + +#endif //GLDMACROUTILS_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDMap.h b/GCR/trunk/Glodon/include/GLD/GLDMap.h new file mode 100644 index 00000000..87733a06 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDMap.h @@ -0,0 +1,12 @@ +#ifndef GLDMAP +#define GLDMAP + +#include + +template +class GMap : public QMap +{ +}; + +#endif // GLDMAP + diff --git a/GCR/trunk/Glodon/include/GLD/GLDMaskBox.h b/GCR/trunk/Glodon/include/GLD/GLDMaskBox.h new file mode 100644 index 00000000..4368bcbf --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDMaskBox.h @@ -0,0 +1,193 @@ +#ifndef GLDMASK_H +#define GLDMASK_H + +#include "GLDMask_Global.h" +#include "GLDIrregularForm.h" + +#include +#include + +namespace GLDCBB +{ + static QWidget* topParentWidget(QWidget* pWgt) + { + if (!pWgt) + { + return nullptr; + } + + QWidget* widget = nullptr; + + for (widget = pWgt; widget != nullptr; widget = widget->parentWidget()) + { + if (widget->isWindow()) + { + break; + } + } + + return widget; + } +} + +struct CoordinateParam +{ +public: + enum Quadrant + { + Zero, + First, + Second, + Third, + Fourth + }; + + CoordinateParam() + : m_point(-1, -1) + , m_quadrant(Zero) + { + + } + + QPoint m_point; + CoordinateParam::Quadrant m_quadrant; +}; + +class GLDMaskBoxParam +{ +public: + GLDMaskBoxParam() + : m_strTipPath("") + , m_strBtnPath("") + , m_maskWidget(nullptr) + { + + } + + GLDMaskBoxParam& operator=(GLDMaskBoxParam& param) + { + m_strTipPath = param.m_strTipPath; + m_strBtnPath = param.m_strBtnPath; + m_maskWidget = param.m_maskWidget; + return *this; + } + + QString m_strTipPath; // 提示信息 + QString m_strBtnPath; // 按钮 + QWidget* m_maskWidget; // 需要显示蒙版的widget +}; + +class GLDMASKSHARED_EXPORT GLDMaskBox : public QWidget +{ + Q_OBJECT + +public: + enum MASKCOLOR + { + GrayColor, // 128, 128, 128 + GlassColor, // 201, 120, 12 + CalaeattaColor, // 252, 239, 232 + CreamColor // 233, 241, 246 + }; + +public: + static GLDMaskBox* createMaskFor(QWidget* widget, const QString & tipInfoPath = "", const QString & btnInfoPath = ""); + + /** + * @brief 设置蒙版颜色 + * @param maskColor + */ + void setMaskColor(MASKCOLOR maskColor); + + /** + * @brief 设置箭头颜色 + * @param color + */ + void setArrowColor(const QColor& color); + + /** + * @brief 设置箭头曲线宽度 + * @param lineWidth + */ + void setArrowLineWidth(const int lineWidth); + + /** + * @brief 读取ini文件用于判断是否需要显示蒙版 + * @param filePath + */ + void openIniFile(const QString& filePath); + +private: + void setMaskShow(); + bool getMaskShow(const QString& prefix, const QString& key); + + QString getValue(const QString& prefix, const QString& key); + void setValue(const QString& prefix, const QString& key); + + QPoint calcPosOfOwner(); + + /** + * @brief 计算提示信息位置 + * @return + */ + CoordinateParam calcPosOfTipInfo(); + +private: + GLDMaskBox(QWidget *parent = nullptr); + GLDMaskBox(GLDMaskBoxParam& param, QWidget * parent = nullptr); + virtual ~GLDMaskBox(); + +Q_SIGNALS: + void customClicked(); + +public slots: + /** + * @brief 关闭蒙版 + */ + void slotClose(); + +protected: + virtual void paintEvent(QPaintEvent *event); + virtual void mousePressEvent(QMouseEvent *event); + +private: + /** + * @brief 绘制蒙版 + * @param painter + */ + void drawMask(QPainter & painter); + + /** + * @brief 绘制指向左上角的箭头,即贝塞尔曲线 + * @param ownerPoint 起点 + * @param endPoint 终点 + * @param painter + */ + void drawLeftTopArrow(QPoint &startPoint, QPoint &endPoint, QPainter &painter); + + /** + * @brief 绘制指向左下角的箭头,即贝塞尔曲线 + * @param ownerPoint 起点 + * @param endPoint 终点 + * @param painter + */ + void drawLeftBottomArrow(QPoint &startPoint, QPoint &endPoint, QPainter &painter); + +private: + static GLDMaskBox* m_pMaskBox; + + GLDMaskBox::MASKCOLOR m_maskColor; + + GLDMaskBoxParam m_oMaskBoxParam; + + QWidget* m_pClippedWgt; + QSettings* m_pSettings; + GLDIrregularForm* m_pTipBox; + + bool m_bShowMask; + + QColor m_arrowColor; + int m_arrowLineWidth; +}; + +#endif // GLDMASK_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDMask_Global.h b/GCR/trunk/Glodon/include/GLD/GLDMask_Global.h new file mode 100644 index 00000000..1fa3880c --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDMask_Global.h @@ -0,0 +1,12 @@ +#ifndef GLDMASK_GLOBAL_H +#define GLDMASK_GLOBAL_H + +#include + +#if defined(GLDMASK_LIBRARY) +# define GLDMASKSHARED_EXPORT Q_DECL_EXPORT +#else +# define GLDMASKSHARED_EXPORT Q_DECL_IMPORT +#endif + +#endif // GLDMASK_GLOBAL_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDMathUtils.h b/GCR/trunk/Glodon/include/GLD/GLDMathUtils.h new file mode 100644 index 00000000..90d81532 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDMathUtils.h @@ -0,0 +1,162 @@ +/************************************************************************* +* * +* 广联达数学运算公共函数单元 * +* * +* 设计:duanb 2013.4.10 * +* 备注: * +* 审核: * +* * +* Copyright (c) 2012-2013 Glodon Corporation * +* * +* ********************************************************************** * +* * +* 修改: * +* * +* 20XX.05.01 - XXX * +* * +* 1、XXXXXX * +* * +* * +*************************************************************************/ + +#ifndef GLDMATHUTILS_H +#define GLDMATHUTILS_H +#include +#define PI 3.14159265358979323846 + +#include "GLDString.h" +#include "GLDVariant.h" +#include "GLDVector.h" +#include "GLDSystem.h" +#include "GLDEnum.h" +#include "GLDGlobal.h" + +enum CompareResult +{ + crLessThan = -1, + crEqual = 0, + crGreaterThan = 1 +}; + +template T Max(T a, T b) +{ + return (a > b ? a : b); +} + +template T Min(T a, T b) +{ + return (a < b ? a : b); +} + +template T Abs(T a) +{ + return (a > 0 ? a : - a); +} + +GLDCOMMONSHARED_EXPORT double ln(double v); +GLDCOMMONSHARED_EXPORT double logN(double x, double y); +GLDCOMMONSHARED_EXPORT double arcSin(double v); +GLDCOMMONSHARED_EXPORT double arcCos(double v); +GLDCOMMONSHARED_EXPORT double arctan(double v); +GLDCOMMONSHARED_EXPORT double sqr(double v); + +GLDCOMMONSHARED_EXPORT bool sameFloat(float firstNum, float secondNum); + +GLDCOMMONSHARED_EXPORT bool sameValue(double a, double b, double epsilon = 1e-12); +GLDCOMMONSHARED_EXPORT GLDValueRelationship compareValue(double a, double b, double epsilon = 1e-12); +template +inline GLDValueRelationship compareDigit(T a, T b) +{ return (a == b) ? gvrEqualsValue : ((a < b) ? gvrLessThanValue : gvrGreaterThanValue); } + +GLDCOMMONSHARED_EXPORT long long itrunc(double v); +GLDCOMMONSHARED_EXPORT long long iround(double v); +GLDCOMMONSHARED_EXPORT double fRound(double v, int decimal, double epsilon = 1e-12); +GLDCOMMONSHARED_EXPORT double frac(double v); +GLDCOMMONSHARED_EXPORT double drandom(); +GLDCOMMONSHARED_EXPORT int random(int n); + +class GlodonMathUtils +{ +public: + static inline long long trunc(double v) { return itrunc(v); } + static inline long long round(double v) { return iround(v); } +}; + +#ifdef _MSC_VER +inline double random() { return drandom(); } +#endif + +GLDCOMMONSHARED_EXPORT int randomRange(int from, int to); +GLDCOMMONSHARED_EXPORT double radToDeg(double radians); +GLDCOMMONSHARED_EXPORT double degToRad(double degrees); +GLDCOMMONSHARED_EXPORT double power(double x, double y); +GLDCOMMONSHARED_EXPORT bool isZero(double value, double epsilon = 0); + +GLDCOMMONSHARED_EXPORT bool varIsNullEx(const GVariant &value); +GLDCOMMONSHARED_EXPORT GVariant varArrayOf(GLDVector &values); +GLDCOMMONSHARED_EXPORT GVariant inc(const GVariant &value); + +GLDCOMMONSHARED_EXPORT GString num2CChar(int n); +GLDCOMMONSHARED_EXPORT GString num2ChsNum(double arabic); +GLDCOMMONSHARED_EXPORT GString currToChnNum(double currnum); + +GLDCOMMONSHARED_EXPORT GString formatFloat(const GString &format, double value); +/*判断结果是否溢出*/ +inline bool isOverflowAddUnsignedInt(unsigned int a, unsigned int b) +{ + return UINT_MAX - a < b; +} + +inline bool isOverflowAddInt(int a, int b) +{ + return a >= 0 ? INT_MAX - a < b : INT_MIN - a > b; +} + +//inline bool isOverflowMultiplyUnsignedInt(unsigned int a, unsigned int b) +//{ +// return (a == 0 || b == 0) ? false : (UINT_MAX / a < b); +//} + +inline bool isOverflowMultiplyInt(int a, int b) +{ + if ((a == 0 || b == 0)) + return false; + else if (a > 0 && b > 0 ) + return INT_MAX / a < b; + else if (a < 0 && b < 0) + return INT_MAX / a > b; + else if (a > 0 && b < 0) + return INT_MIN / a > b; + else + return INT_MIN / a < b; +} + +inline bool isOverflowMultiplyInt64(long long a, long long b) +{ + if ((a == 0 || b == 0)) + return false; + else if (a > 0 && b > 0 ) + return LLONG_MAX / a < b; + else if (a < 0 && b < 0) + return LLONG_MAX / a > b; + else if (a > 0 && b < 0) + return LLONG_MIN / a > b; + else + { + if (-1 == a) + { + return false; + } + else + { + return LLONG_MIN / a < b; + } + } +} + +GLDCOMMONSHARED_EXPORT GRgb turnRgb(GRgb rgb); +inline int unsignedCharToInt(unsigned char top, unsigned char bottom, unsigned char left, unsigned char right) +{ + return top | (bottom << 8) | (left << 16) | (right << 24); +} +#endif // GLDMATHUTILS_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDMultiHeaderView.h b/GCR/trunk/Glodon/include/GLD/GLDMultiHeaderView.h new file mode 100644 index 00000000..b15a95f0 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDMultiHeaderView.h @@ -0,0 +1,383 @@ +/*! + *@file glodonmultiheaderview.h + *@brief {树型表头} + *通过解析Model中的HeaderData,用‘|’分割父子关系 + *@author Gaosy + *@date 2012.9.7 + *@remarks {remarks} + *Copyright (c) 1998-2012 Glodon Corporation + */ + +#ifndef GLDMULTIHEADERVIEW_H +#define GLDMULTIHEADERVIEW_H + +#include "GLDHeaderView.h" +#include "GLDObjectList.h" + +class GlodonMultiHeaderView; +class GlodonMultiHeaderViewPrivate; +class GHeaderSpanCollection; + +/*! + *@enum: HeaderSpanRelation + *@brief {两个HeaderSpan之间的位置关系,用于初始化表头} + *@author Gaosy + *@date 2012.9.10 + */ +enum HeaderSpanRelation +{ + Contain, + Overlapping, + AdjacentUp, + AdjacentDown, + AdjacentLeft, + AdjacentRight, + AdjacentIrrelevant,//相邻,但是高度或者宽度不一样 + Irrelevant +}; + +/*! + *@class : HeaderSpan + *@brief {表头合并块儿,记录当前表头块显示的内容、是否选中及表头块的大小} + *@author Gaosy + *@date 2012.9.10 + */ +class GLDTABLEVIEWSHARED_EXPORT GLDHeaderSpan +{ +public: + GLDHeaderSpan() + : m_top(-1), m_left(-1), m_bottom(-1), m_right(-1), m_section(-1), m_selected(false) {} + + GLDHeaderSpan(int row, int column, int rowCount, int columnCount, QString text, int section) + : m_top(row), m_left(column), m_bottom(row + rowCount - 1), + m_right(column + columnCount - 1), m_text(QString(text)), + m_section(section), m_selected(false) {} + + inline int top() const { return m_top; } + inline int left() const { return m_left; } + inline int bottom() const { return m_bottom; } + inline int right() const { return m_right; } + inline int height() const { return m_bottom - m_top + 1; } + inline int width() const { return m_right - m_left + 1; } + + inline void setTop(int top) { m_top = top; } + inline void setLeft(int left) { m_left = left; } + inline void setBottom(int bottom) { m_bottom = bottom; } + inline void setRight(int right) { m_right = right; } + + inline QString text() const { return m_text; } + inline void setText(QString text) { m_text = text; } + inline int section() const { return m_section; } + inline void setSection(int section) { m_section = section; } + inline bool selected() const { return m_selected; } + inline void setSelected(bool selected) { m_selected = selected; } + + /*! + *判断该表头合并块与另一个合并块之间的位置关系 + *@param[in] span 另一个表头合并块 + *@return HeaderSpanRelation + */ + HeaderSpanRelation spanRelation(GLDHeaderSpan span); + +private: + int m_top; + int m_left; + int m_bottom; + int m_right; + QString m_text; + int m_section; + bool m_selected; +}; + +/*! + *@class: GHeaderSpanCollection + *@brief {一个表头中所有表头合并块的集合} + *@author Gaosy + *@date 2012.9.10 + */ +class GLDTABLEVIEWSHARED_EXPORT GHeaderSpanCollection +{ +public: + GHeaderSpanCollection() {} + + ~GHeaderSpanCollection() + { + } + + /*! + *添加一个合并块,主要在初始化合并表头的时候调用 + *@param[in] span + *@return 无 + */ + void addSpan(GLDHeaderSpan *span); + + /*! + *通过行列号获取该位置的合并块在集合中的下标 + *@param[in] rowIndex 逻辑行号(model中的行号) + *@param[in] colIndex 逻辑列号(model中的列号) + *@return 无 + */ + int spanAt(int rowIndex, int colIndex) const; + +public: + //所有表头合并块的集合 + GObjectList spans; + +private: + void parseSpanInternal(int index, bool isInRecursion, int i); + bool parseSpanRelationRecursively(GLDHeaderSpan *span, bool isInRecursion, int index); +}; + +/*! + *@class: GlodonMultiHeaderView + *@brief {树型表头,通过解析Model中的HeaderData,用‘|’分割父子关系} + *@author Gaosy + *@date 2012.9.10 + */ +class GLDTABLEVIEWSHARED_EXPORT GlodonMultiHeaderView : public GlodonHeaderView +{ + Q_OBJECT + +public: + GlodonMultiHeaderView(Qt::Orientation orientation, QWidget *parent = 0); + virtual ~GlodonMultiHeaderView(); + + /*! + *重新设置一列(行)的宽度(高度) + *@param[in] logicalIndex 逻辑列号(行号) + *@param[in] size 新的列宽(行高) + *@return 无 + */ + void resizeSection(int logicalIndex, int size, bool update = true, bool isManual = false); + + /*! + *为表头提供数据来源,每一个合并块中显示的内容通过model中的headerData()获取,进行拆分 + *根据‘|’划分父子关系,形成树形结构表头 + * |_____a_____| + *例如:第一列为‘a|b’,第二列为‘a|c’,解析后效果为 | b | c | + * + *@param[in] model 提供数据的model + *@return 无 + */ + void setModel(QAbstractItemModel *model); + + /*! + *获取当前表头额外行(列)数,即总行(列)数减1 + *@return int + */ + int extraCount() const; + + /*! + *获取水平(竖直)表头的高度(宽度) + *@return int + */ + int drawWidth() const; + + /*! + *刷新表头 + *@return 无 + @see 参见GlodonHeaderView::updateGeometries() + */ + void updateGeometries(); + + /*! + *GlodonMultiHeaderView的绘制方法 + *@param[in] e + *@return 无 + */ + void paintEvent(QPaintEvent *e); + + /*! + *初始化表头,根据固定编辑行(列)与表头的对应关系,检查合法性 + *若出现某一个父合并块的部分子合并块为固定行(列),而部分不是 + *则返回false + *@return bool + */ + void initTitles(); + + /*! + *根据给定的坐标点,返回相应的合并块在其集合中的下标 + *@param[in] point 坐标位置 + *@return int + */ + int headerSpanAt(QPoint point); + + /*! + *根据给定的合并块下标,返回其虚拟位置(实际绘制的位置) + *@param[in] index 合并块在其集合中的下标 + *@return HeaderSpan + */ + GLDHeaderSpan visualSpan(int index); + + /*! + *设置固定编辑行(列)数,会进行合法性判断 + *若出现某一个父合并块的部分子合并块为固定行(列) + *而一部分不是,则发出Assert + *@param[in] fixedCount + *@return 无 + */ + void setFixedCount(int fixedCount); + + void mouseMoveEvent(QMouseEvent *e); + void mouseReleaseEvent(QMouseEvent *e); + void mousePressEvent(QMouseEvent *e); + + /*! + *根据给定的合并块下标,返回其坐标位置 + *@param[in] index 合并块在其集合中的下标 + *@return QRect + */ + QRect headerSpanRect(int index); + + /*! + *根据给定的合并块下标,刷新该合并块 + *@param[in] index 合并块在其集合中的下标 + *@return 无 + */ + void updateHeaderSpan(int index); + + /*! + *选择(反选)合并块,并递归处理父合并块和子合并块的选中状态 + *@param[in] index 合并块在其集合中的下标 + *@param[in] select true表示选中,false表示不选中 + *@param[in] checkParent 是否修改父合并块的选中状态 + *@param[in] checkChild 是否修改子合并块的选中状态 + *@return 无 + */ + void selectHeaderSpan(int index, bool select, bool checkParent = true, bool checkChild = true); + + /*! + *根据给定的选择区域,返回该选择区域的坐标 + *@param[in] selection 选择区域 + *@return QRegion + */ + QRegion visualRegionForSelection(const QItemSelection &selection) const; + + /*! + *根据选中的区域和反选的区域更新表头相关合并块的选中状态 + *@param[in] selected 选中的区域 + *@param[in] deselected 反选的区域 + *@return 无 + */ + void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected); + + /*! + *返回表头行数 + *@return int + */ + int rowCount() const; + + /*! + *返回表头列数 + *@return int + */ + int colCount() const; + /** + * @brief 重新计算当前显示行的多行表头 + * @return + */ + int resetSpan(); + /** + * @brief 刷新一行(列)(包括同步dataSource中的数据到headerData中) + * @param index + * @return + */ + void updateSpan(int index); + + /** + * @brief 根据行或列号,把相应的span选中 + * @param index tableView的行或列 + * @return + */ + void setSpansSelected(int index, bool selected); + + /*! + * \brief 用来让外部设置横向表头高度,顺序为从上往下 + * \param minHs高度的集合 + */ + void setMinimumHeights(QVector &minHs); + +public Q_SLOTS: + /*! + *设置滚动条偏移 + *@param[in] offset + *@return 无 + *@see 参见GlodonHeaderView::setOffset(int offset) + */ + void setOffset(int offset); + +public: + //为了达到水平表头多行(竖直表头多列)的效果,内部创建多行GlodonHeaderView + //并利用其setModel、resizeSection方法实现与表体的同步 + QVector headerList; + + //所有合并块的集合 + GHeaderSpanCollection *headerData; + + //当前选中的合并块在集合中的下标 + int pressedHeaderSpan; + + //用于绘制拖拽动画影像 + QLabel *headerSpanIndicator; + + //拖拽动画影像与鼠标当前位置的偏移 + int headerSpanIndicatorOffset; + + //水平(竖直)表头拖拽动画影像的y方向(x方向)位置 + int headerSpanIndicatorDrawPos; + + //被拖拽的合并块在集合中的下标 + int moveStartSpan; + +Q_SIGNALS: + void headerSpanPressed(int left, int top, int right, int bottom); + +protected: + void currentChanged(const QModelIndex ¤t, const QModelIndex &old); + +protected Q_SLOTS: + void updateSection(int logicalIndex); + +private: + /*! + *初始化拖拽动画影像 + *@param[in] position 拖拽动画影像的起始位置 + *@return 无 + */ + void setupHeaderSpanIndicator(int position); + + /*! + *更新拖拽动画影像 + *@param[in] position 拖拽动画影像要移动到的位置 + *@return 无 + */ + void updateHeaderSpanIndicator(int position); + + void setExtraCount(int count); + + /*! + *取得最后的列宽或行高 + *@param[in] 无 + *@return 最后的列宽或行高 + */ + int lastDrawWidth(); + void paintSpanHeader(QPainter *painter, const QRect &rect, GLDHeaderSpan *span) const; + bool checkLogicalTitles(int fixedCount); + bool inTopHeaderRange(int topHeaderIndex, int index); + bool checkCanMove(int targetLogicalIndex); + void deselectedHeaderSpans(); + int parseSpan(int nFirstVisual, int nLastVisual, int nMaxCount); + int maxCount(); + Q_DECLARE_PRIVATE(GlodonMultiHeaderView) + + /*! + * \brief 恢复重新创建前设置好的高度 + */ + void recoverMinimumHeights(); + +private: + // 用来存储设置好的高度 + QVector m_minimumHeights; +}; + +#endif // GLDMULTIHEADERVIEW_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDMultiHeaderView_p.h b/GCR/trunk/Glodon/include/GLD/GLDMultiHeaderView_p.h new file mode 100644 index 00000000..0df27155 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDMultiHeaderView_p.h @@ -0,0 +1,13 @@ +#ifndef GLDMULTIHEADERVIEW_P_H +#define GLDMULTIHEADERVIEW_P_H + +#include "GLDHeaderView_p.h" + +class GlodonMultiHeaderViewPrivate : public GlodonHeaderViewPrivate +{ + Q_DECLARE_PUBLIC(GlodonMultiHeaderView) +public: + GlodonMultiHeaderViewPrivate() {} +}; + +#endif // GLDMULTIHEADERVIEW_P_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDMutex.h b/GCR/trunk/Glodon/include/GLD/GLDMutex.h new file mode 100644 index 00000000..f008f568 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDMutex.h @@ -0,0 +1,10 @@ +#ifndef GLDMUTEX +#define GLDMUTEX + +#include + +typedef QMutex GMutex; +typedef QMutex GCriticalSection; + +#endif // GLDMUTEX + diff --git a/GCR/trunk/Glodon/include/GLD/GLDNameSpace.h b/GCR/trunk/Glodon/include/GLD/GLDNameSpace.h new file mode 100644 index 00000000..a21ed7f1 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDNameSpace.h @@ -0,0 +1,26 @@ +/************************************************************************* +* +* 广联达命名空间定义 +* +* 设计:Zhangsk 2012.05.22 +* 备注: +* 审核: +* +* Copyright (c) 2012-2013 Glodon Corporation +* +*************************************************************************/ + +#ifndef GNAMESPACE_H +#define GNAMESPACE_H + +#define G_GLODON_BEGIN_NAMESPACE namespace gld { +#define G_GLODON_END_NAMESPACE } //namespace gld + +#define G_GSP_BEGIN_NAMESPACE namespace gsp { +#define G_GSP_END_NAMESPACE } //namespace gsp + +#define G_COMHELPER_BEGIN_NAMESPACE namespace gcom { +#define G_COMHELPER_END_NAMESPACE } //namespace gcom + + +#endif // GNAMESPACE_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDNetScapeSplitter.h b/GCR/trunk/Glodon/include/GLD/GLDNetScapeSplitter.h new file mode 100644 index 00000000..7d369239 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDNetScapeSplitter.h @@ -0,0 +1,265 @@ +#ifndef GLDNETSCAPESPLITTER_H +#define GLDNETSCAPESPLITTER_H + +#include +#include +#include +#include +#include + +#include "GLDSplitter.h" +#include "GLDGlobal.h" +#include "GLDNetScapeSplitterHandle.h" + +enum ArrowDirection +{ + leftToRight, + rightToleft, + TopToBottom, + bottomToTop, + inValidDirection +}; + +class GLDWIDGETSHARED_EXPORT GLDNestScapSplitterTripleHelper +{ +public: + GLDNestScapSplitterTripleHelper(QPoint &mid, int radius, int direction) : + m_midPoint(mid), m_radius(radius), m_direction(direction) {} + +public: + QPoint vertexA() const;//左手顶点 + QPoint vertexB() const;//直角点 + QPoint vertexC() const;//右手顶点 + +private: + QPoint m_midPoint; + double m_radius; + int m_direction; +}; + +/*! + * \brief The GLDNetScapeSplitterButton class 用来绘制三角的button,并发送点击消息给splitter + */ +class GLDWIDGETSHARED_EXPORT GLDNetScapeSplitterButton : public QPushButton +{ + Q_OBJECT +public: + explicit GLDNetScapeSplitterButton(Qt::Orientation o, QWidget *parent) : + QPushButton(parent), + m_arrowDirection(o == Qt::Horizontal ? leftToRight : TopToBottom), + m_qssFileName(), + m_orientation(o) {} + +public: + void setArrowDirection(int direction) + { + m_arrowDirection = direction; + setButtonNameByArrowDirection(); + loadStyleSheet(m_qssFileName); + } + void setQssFileName(const QString &fileName) + { + m_qssFileName = fileName; + } + void setButtonNameByArrowDirection(); + void setButtonObjectName() + { + setButtonNameByArrowDirection(); + } + + virtual void loadStyleSheet(const QString &fileName) + { + G_UNUSED(fileName); + } + +protected: + bool hitButton(const QPoint &pos) const; + void mousePressEvent(QMouseEvent *e); + void paintEvent(QPaintEvent *e); +protected: + /*! + * \brief m_arrowDirection 0:left,1:right,2:top,3:bottom + */ + int m_arrowDirection; + +private: + QString m_qssFileName; + Qt::Orientation m_orientation; +private: + friend class GLDNetScapeSplitterHandle; +}; + +/*! + * \brief The GLDNetScapeSplitter 通过基类的setHandleWidth设置分隔条宽度 + * \note 现仅支持两个child,也就是说多个child时的不相关的index行为是由QSplitter定义或者是未定义的 + */ +class GLDWIDGETSHARED_EXPORT GLDNetScapeSplitter : public GLDSplitter +{ + Q_OBJECT +public: + enum SplitterAlign + { + alLeftBottom, //向左/下收起(根据splitter的orientation组合出一个特定的方向) + alRightTop //向右/上收起(根据splitter的orientation组合出一个特定的方向) + }; + +public: + explicit GLDNetScapeSplitter(QWidget *parent = 0); + explicit GLDNetScapeSplitter(Qt::Orientation original, QWidget *parent = 0); + explicit GLDNetScapeSplitter(bool initCollapse, QWidget *parent = 0); + explicit GLDNetScapeSplitter(Qt::Orientation original, bool initCollapse, QWidget *parent = 0); + +public: + inline SplitterAlign alignment() const + { + return m_align; + } + + inline void setAlignment(SplitterAlign align) + { + m_align = align; + //TODO + } + + int indexOffsetForCollapse() + { + return m_align == alLeftBottom ? 0 : 1; + } + + /*! + * \brief hiddenLength 收起时的宽度 + */ + inline int hiddenLength() const + { + return m_minHideLength; + } + + /*! + * \brief hiddenLength 收起时的宽度 + * \note 界面显示后调用的即设即用效果暂时是TODO状态 + */ + inline void setHiddenLength(int value) + { + m_minHideLength = value; + } + + /*! + * \brief setCompletlyCollpased 设置通过Qt::Orientation与SplitterAlign确定方向的那一边在初始化时是被完全隐藏 + * 并且,通过点击button也是在给定的展开宽度与完全收起间进行切换。(忽略收起宽度的设置) + * \param collpased + * \warning 不要与setHiddenLength同时调用,(特别是以非0的参数),结果是未定义的 + * \note 这是一个窗口未显示前调用才有效的方法 + * \deprecated + */ + void setCompletlyCollpased() + { + // if (!m_bInitShow) return; + // m_bInitCollapse = true; + } + + /*! + * \brief setCompletlyCollpasedEnabled 设置确定的那一边的完全隐藏。分为当前是展开状态,以及当前是带有收起宽度的收起状态。 + * 均会切换为收起宽度为0的收起状态,并会将收起宽度置为0。对于已处于宽度为0的收起状态,则不会有任何动作。 + * \note 设置是否可以完全收起。若为false,则收起时的宽度将设为之前设置的收起时宽度(无设置则是默认)。若为true,则收起时的宽度将变为0 + */ + void setCollpaseCompletable(bool enabled = true); + + /*! + * \brief setCollpaseSideStretchFactor 设置通过Qt::Orientation与SplitterAlign确定方向的那一边的初始的 展开尺寸,可以通过 + *拖动handle后,点击button进行隐藏的手法改变 展开尺寸,也就是说此方法只在初始时有效,并不保证move handle后的 展开尺寸 + * \param rate 可隐藏的那一边的 展开尺寸 相对于spliter的宽度的比率,必须是在(0, 1)之间,若与实际的尺寸计算后不足1像素,将会采用 + *默认值 + * \retval true:设置成功 false:设置失败 + * \warning 请不要试图调用基类的 setStretchFactor()方法 结果是未定义的 + * \note 这是一个窗口未显示前调用才有效的方法 + */ + bool setCollpaseSideStretchFactor(double rate); + + /*! + * \brief setExpandSize + * \param size + * \see setCollpaseSideStretchFactor() + * \warning size应是有意义的,若超出或为负值,结果是未定义的。 + * \note 这是一个窗口未显示前调用才有效的方法 + */ + void setExpandSize(int size) + { + // if (!m_bInitShow) return false; + m_nWantedExpandSize = size; + m_dWantedExpandFactor = -1; + } + + /*! + * \brief setLastExpandedSizeWantedEnable + * \param enabled true:最后一次展开的宽度为隐藏时点击按钮后的展开宽度 + * false:通过setExpandSize、setCollpaseSideStretchFactor等设置的展开宽度是点击按钮的展开宽度 + */ + void setLastExpandedSizeWantedEnable(bool enabled = true) + { + m_bUsingLastExpandSize = enabled; + } + + /*! + * \brief 用于控制是否展开 + * \param show 展开 + */ + void doTrigger(bool show); + +Q_SIGNALS: + /*! + * \brief resizeSignal 用以在resize事件中发出些信号,使得handle中的button得到通知,进而自适应调整button的位置 + * \param e + */ + void resizeSignal(QResizeEvent *e); + void resizeSignal(int length); + +protected: + void showEvent(QShowEvent *e) + { + GLDSplitter::showEvent(e); + + onShowEvent(); + } + void onShowEvent(); + void resizeEvent(QResizeEvent *e) + { + emit resizeSignal(e); + GLDSplitter::resizeEvent(e); + } + virtual GLDSplitterHandle *createHandle(); + void initSignalSlot(GLDNetScapeSplitterHandle *handle); + inline bool isUsingLastExpandSize() const + { + return m_bUsingLastExpandSize; + } + +private Q_SLOTS: + void changeHandleLength(GLDNetScapeSplitterHandle *handle, int handleLengthe); + void emitHandlerMoved(int length, int index); + +private: + void init(); + int getHandleIndexOffset(); + void showSplitterHandle(GLDNetScapeSplitterHandle *splitterHandle); + void updateSplitterExpendLength(GLDNetScapeSplitterHandle *splitterHandle); + void updateSplitterSizes(); + void onFirstTimeShowEvent(); + +protected: + int m_minHideLength; + GLDNetScapeSplitterHandle *m_handle; + +private: + SplitterAlign m_align; + bool m_bFirstTimeShow; + bool m_bInitCollapse; + bool m_bCollapseCompletable; + bool m_bUsingLastExpandSize; + int m_nWantedExpandSize; + double m_dWantedExpandFactor; +private: + friend class GLDNetScapeSplitterHandle; + Q_DISABLE_COPY(GLDNetScapeSplitter) +}; + +#endif // GLDNETSCAPESPLITTER_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDNetScapeSplitterEx.h b/GCR/trunk/Glodon/include/GLD/GLDNetScapeSplitterEx.h new file mode 100644 index 00000000..12f0f9c1 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDNetScapeSplitterEx.h @@ -0,0 +1,52 @@ +#ifndef GLDNETSCAPESPLITTEREX_H +#define GLDNETSCAPESPLITTEREX_H + +#include "GLDNetScapeSplitter.h" + +const int c_InitialHandleWidthEx = 6; + +/*! + *\brief Used to declare Class inheritance +*/ +class GLDWIDGETSHARED_EXPORT GLDNetScapeSplitterButtonEx : public GLDNetScapeSplitterButton +{ +public: + explicit GLDNetScapeSplitterButtonEx(Qt::Orientation o, QWidget *parent = 0); + +public: + void loadStyleSheet(const QString &fileName); + +protected: + void paintEvent(QPaintEvent *e); +}; + +class GLDWIDGETSHARED_EXPORT GLDNetScapeSplitterHandleEx : public GLDNetScapeSplitterHandle +{ + Q_OBJECT +public: + explicit GLDNetScapeSplitterHandleEx(Qt::Orientation o, + GLDNetScapeSplitter *parent = 0); + virtual void initButton(); +}; + +class GLDWIDGETSHARED_EXPORT GLDNetScapeSplitterEx : public GLDNetScapeSplitter +{ + Q_OBJECT +public: + explicit GLDNetScapeSplitterEx(QWidget *parent = 0); + explicit GLDNetScapeSplitterEx(Qt::Orientation original, QWidget *parent = 0); + explicit GLDNetScapeSplitterEx(bool initCollapsed, QWidget *parent = 0); + explicit GLDNetScapeSplitterEx(Qt::Orientation original, + bool initCollapsed, QWidget *parent = 0); + +public: + void loadStyleSheet(const QString &fileName); + +protected: + virtual GLDSplitterHandle *createHandle(); + +private: + void init(); +}; + +#endif // GLDNetScapeSplitterButtonEx_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDNetScapeSplitterHandle.h b/GCR/trunk/Glodon/include/GLD/GLDNetScapeSplitterHandle.h new file mode 100644 index 00000000..729cdc0d --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDNetScapeSplitterHandle.h @@ -0,0 +1,132 @@ +#ifndef GLDNETSCAPESPLITTERHANDLE_H +#define GLDNETSCAPESPLITTERHANDLE_H + +#include "GLDSplitterHandle.h" +#include "GLDWidget_Global.h" + +const int c_InitialHidenLength = 12; +const int c_InitialHandleWidth = 10; +const int c_InitialButtonLength = 120; + +const int c_TriangleToEndRate = 20; +const int c_TriangleBottomToBorderPixel = 2; + +class GLDNetScapeSplitter; +class GLDNetScapeSplitterButton; + +/*! + * \brief The GLDNetScapeSplitterHandle class 自写的handle类,主要功能是与GLDNetScapeSplitter搭配使用,成为 + *GLDNetScapeSplitterButton的容器 + */ +class GLDWIDGETSHARED_EXPORT GLDNetScapeSplitterHandle : public GLDSplitterHandle +{ + Q_OBJECT +public: + explicit GLDNetScapeSplitterHandle(Qt::Orientation o, GLDSplitter *parent); + +public: + /*! + * \brief setButtonLength 设置包含的GLDNetScapeSplitterButton的长度值(所谓长度,是指普通的btn较长的那一边的尺寸) + * \param val 像素为单位 + */ + void setButtonLength(int val) + { + m_buttonHeight = val; + //TODO btn显示后的设置需要仍然有效 + } + + int buttonLenght() const + { + return m_buttonHeight; + } + + /*! + * \brief setCollapseLength + * \param val 设置要可被收起的那一侧收起时的最小尺寸,一般地,会有一个不为零的默认值,若此处设置为0或负值,则表示可以完全收起(也就是隐藏) + * + */ + void setCollapseLength(int val) + { + int nPreVal = m_collapseLength; + m_collapseLength = qMax(val, 0); + Q_UNUSED(nPreVal); + //TODO 考虑界面已经显示后调用此接口的情形 + } + int collapseLength() const + { + return m_collapseLength; + } + + int dragMoveState() const + { + return m_dragMoveState; + } + + inline bool getSplitterState() + { + return m_bExpanded; + } + + inline GLDNetScapeSplitterButton *getButton() + { + return m_pButton; + } + + void adjustButtonPos(int buttonHeight); + + virtual void initButton(); + +signals: + void splitterStateSwitched(GLDNetScapeSplitterHandle *, int); + +public slots: + virtual void handlerButtonClick(); + virtual void onSplitterResized(QResizeEvent *e); + virtual void onSplitterResized(int nSplitterLength); + +protected: + enum EnDragMoveState + { + initial = -1, + pressed, + moved, + dragging + }; + +protected: + void setDragMoveState(int state) + { + m_dragMoveState = state; + } + + void changeSplitterExpendLength(QResizeEvent *e); + + void mousePressEvent(QMouseEvent *e); + void mouseMoveEvent(QMouseEvent *e); + void mouseReleaseEvent(QMouseEvent *e); + + int curArrowDirection() const; + int newArrowDirection() const; + void adjustArrowDirection(); + + + void saveExpandLength(int expandLength) const; + +protected: + mutable int m_buttonHeight; + mutable int m_collapseLength; + mutable int m_expandedLength; + + GLDNetScapeSplitterButton *m_pButton; + GLDNetScapeSplitter *m_pSplitter; + + int m_dragMoveState; + bool m_bExpanded; + +private: + friend class GLDNetScapeSplitter; + friend class GLDNetScapeSplitterButton; + Q_DISABLE_COPY(GLDNetScapeSplitterHandle) +}; + +#endif // GLDNETSCAPESPLITTERHANDLE_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDObjBase.h b/GCR/trunk/Glodon/include/GLD/GLDObjBase.h new file mode 100644 index 00000000..3ef09e04 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDObjBase.h @@ -0,0 +1,391 @@ +#ifndef GLDOBJBASE_H +#define GLDOBJBASE_H + +//定义宏 + +#define interface struct + +#ifdef WIN32 +# define STDMETHODCALLTYPE __stdcall +# define WINAPI __stdcall +# define STDAPICALLTYPE __stdcall +# define APIENTRY WINAPI +#else +# define STDMETHODCALLTYPE +# define WINAPI +# define STDAPICALLTYPE +# define APIENTRY WINAPI +#endif + +#define STDAPI EXTERN_C HRESULT STDAPICALLTYPE +#define STDAPI_(type) EXTERN_C type STDAPICALLTYPE +#define STDMETHOD(method) virtual HRESULT STDMETHODCALLTYPE method +#define STDMETHOD_(type,method) virtual type STDMETHODCALLTYPE method +#define STDMETHODIMP HRESULT STDMETHODCALLTYPE +#define STDMETHODIMP_(type) type STDMETHODCALLTYPE +#define PURE = 0 +#define DECLSPEC_NOVTABLE +#define DECLARE_INTERFACE(iface) interface DECLSPEC_NOVTABLE iface +#define DECLARE_INTERFACE_(iface, baseiface) interface DECLSPEC_NOVTABLE iface : public baseiface + +#define DECLSPEC_IMPORT __declspec(dllimport) +#define WINBASEAPI DECLSPEC_IMPORT + + +#define BEGIN_INTERFACE +#define END_INTERFACE + + + +#ifdef __cplusplus +#define EXTERN_C extern "C" +#else +#define EXTERN_C extern +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +typedef char CHAR; +typedef char CCHAR; +typedef unsigned char BYTE; + +typedef short SHORT; +typedef unsigned short WORD; +typedef unsigned short USHORT; +typedef short VARIANT_BOOL; + +typedef long LONG; +typedef long HRESULT; +typedef unsigned long DWORD; +typedef DWORD *PDWORD; +typedef DWORD ULONG; +typedef LONG SCODE; + +typedef int BOOL; +typedef int INT; +typedef unsigned int UINT; +typedef unsigned int *PUINT; + +typedef long long LONGLONG; +typedef unsigned long long ULONGLONG; + +typedef float FLOAT; +typedef FLOAT *PFLOAT; + +typedef double DOUBLE; +typedef double DATE; + +typedef void *HANDLE; +typedef HANDLE HINSTANCE; +typedef void *PVOID; +typedef void *LPVOID; + +typedef wchar_t *LPOLESTR; +typedef const wchar_t *LPCOLESTR; +typedef const wchar_t *LPCTSTR; +typedef wchar_t OLECHAR; +typedef OLECHAR *BSTR; + +typedef DWORD LCID; +typedef PDWORD PLCID; +typedef WORD LANGID; + +typedef LONG DISPID; + +typedef union tagCY +{ + struct + { + unsigned long Lo; + long Hi; + } DUMMYSTRUCTNAME; + LONGLONG int64; +} CY; + +typedef struct tagSAFEARRAYBOUND +{ + ULONG cElements; + LONG lLbound; +} SAFEARRAYBOUND; + +typedef struct tagSAFEARRAY +{ + USHORT cDims; + USHORT fFeatures; + ULONG cbElements; + ULONG cLocks; + PVOID pvData; + SAFEARRAYBOUND rgsabound[ 1 ]; +} SAFEARRAY; + +typedef struct tagDEC +{ + USHORT wReserved; + union + { + struct + { + BYTE scale; + BYTE sign; + } DUMMYSTRUCTNAME; + USHORT signscale; + } DUMMYUNIONNAME; + ULONG Hi32; + union + { + struct + { + ULONG Lo32; + ULONG Mid32; + } DUMMYSTRUCTNAME2; + ULONGLONG Lo64; + } DUMMYUNIONNAME2; +} DECIMAL; + +#define _VARIANT_BOOL /##/ +typedef unsigned short VARTYPE; +typedef /* [wire_marshal] */ struct tagVARIANT VARIANT; +struct tagVARIANT +{ + union + { + struct __tagVARIANT + { + VARTYPE vt; + WORD wReserved1; + WORD wReserved2; + WORD wReserved3; + union + { + LONGLONG llVal; + LONG lVal; + BYTE bVal; + SHORT iVal; + FLOAT fltVal; + DOUBLE dblVal; + VARIANT_BOOL boolVal; + //_VARIANT_BOOL bool; + SCODE scode; + CY cyVal; + DATE date; + BSTR bstrVal; + //IUnknown *punkVal; + //IDispatch *pdispVal; + SAFEARRAY *parray; + BYTE *pbVal; + SHORT *piVal; + LONG *plVal; + LONGLONG *pllVal; + FLOAT *pfltVal; + DOUBLE *pdblVal; + VARIANT_BOOL *pboolVal; + //_VARIANT_BOOL *pbool; + SCODE *pscode; + CY *pcyVal; + DATE *pdate; + BSTR *pbstrVal; + //IUnknown **ppunkVal; + //IDispatch **ppdispVal; + SAFEARRAY **pparray; + VARIANT *pvarVal; + PVOID byref; + CHAR cVal; + USHORT uiVal; + ULONG ulVal; + ULONGLONG ullVal; + INT intVal; + UINT uintVal; + DECIMAL *pdecVal; + CHAR *pcVal; + USHORT *puiVal; + ULONG *pulVal; + ULONGLONG *pullVal; + INT *pintVal; + UINT *puintVal; + //struct __tagBRECORD + //{ + // PVOID pvRecord; + // IRecordInfo *pRecInfo; + //} __VARIANT_NAME_4; + } __VARIANT_NAME_3; + } __VARIANT_NAME_2; + DECIMAL decVal; + } __VARIANT_NAME_1; +} ; +typedef VARIANT *LPVARIANT; + +typedef VARIANT VARIANTARG; + +typedef VARIANT *LPVARIANTARG; + +typedef VARIANT VARIANTARG; + +typedef union _LARGE_INTEGER +{ + struct + { + DWORD LowPart; + LONG HighPart; + } DUMMYSTRUCTNAME; + struct + { + DWORD LowPart; + LONG HighPart; + } u; + LONGLONG QuadPart; +} LARGE_INTEGER; + +typedef LARGE_INTEGER *PLARGE_INTEGER; + +typedef union _ULARGE_INTEGER { + struct + { + DWORD LowPart; + DWORD HighPart; + } DUMMYSTRUCTNAME; + struct + { + DWORD LowPart; + DWORD HighPart; + } u; + ULONGLONG QuadPart; +} ULARGE_INTEGER; + +typedef ULARGE_INTEGER *PULARGE_INTEGER; + +typedef struct _FILETIME +{ + DWORD dwLowDateTime; + DWORD dwHighDateTime; +} FILETIME, *PFILETIME, *LPFILETIME; + +typedef struct tagDISPPARAMS +{ + /* [size_is] */ VARIANTARG *rgvarg; + /* [size_is] */ DISPID *rgdispidNamedArgs; + UINT cArgs; + UINT cNamedArgs; +} DISPPARAMS; + +typedef struct tagEXCEPINFO { + WORD wCode; + WORD wReserved; + BSTR bstrSource; + BSTR bstrDescription; + BSTR bstrHelpFile; + DWORD dwHelpContext; + PVOID pvReserved; + void *pfnDeferredFillIn;//HRESULT (__stdcall *pfnDeferredFillIn)(struct tagEXCEPINFO *); // todo + SCODE scode; +} EXCEPINFO, * LPEXCEPINFO; + +typedef +enum tagSTREAM_SEEK +{ + STREAM_SEEK_SET = 0, + STREAM_SEEK_CUR = 1, + STREAM_SEEK_END = 2 +} STREAM_SEEK; + +typedef +enum tagSTGTY +{ + STGTY_STORAGE = 1, + STGTY_STREAM = 2, + STGTY_LOCKBYTES = 3, + STGTY_PROPERTY = 4 +} STGTY; + +typedef +enum tagLOCKTYPE +{ + LOCK_WRITE = 1, + LOCK_EXCLUSIVE = 2, + LOCK_ONLYONCE = 4 +} LOCKTYPE; + + +/* +WINBASEAPI +LONG +WINAPI +InterlockedIncrement ( + __inout LONG volatile *lpAddend + ); + +WINBASEAPI +LONG +WINAPI +InterlockedDecrement ( + __inout LONG volatile *lpAddend + ); +*/ + +#ifndef DECLSPEC_UUID +#if (_MSC_VER >= 1100) && defined (__cplusplus) +#define DECLSPEC_UUID(x) __declspec(uuid(x)) +#else +#define DECLSPEC_UUID(x) +#endif +#endif + +#ifndef DECLSPEC_NOVTABLE +#if (_MSC_VER >= 1100) && defined(__cplusplus) +#define DECLSPEC_NOVTABLE __declspec(novtable) +#else +#define DECLSPEC_NOVTABLE +#endif +#endif + +#ifndef DECLSPEC_SELECTANY +#if (_MSC_VER >= 1100) +#define DECLSPEC_SELECTANY __declspec(selectany) +#else +#define DECLSPEC_SELECTANY +#endif +#endif + +/**************************************************************************** + * VC COM support + ****************************************************************************/ + +#ifndef DECLSPEC_SELECTANY +#if (_MSC_VER >= 1100) +#define DECLSPEC_SELECTANY __declspec(selectany) +#else +#define DECLSPEC_SELECTANY +#endif +#endif + +#ifndef DECLSPEC_NOVTABLE +#if (_MSC_VER >= 1100) && defined(__cplusplus) +#define DECLSPEC_NOVTABLE __declspec(novtable) +#else +#define DECLSPEC_NOVTABLE +#endif +#endif + +#ifndef DECLSPEC_UUID +#if (_MSC_VER >= 1100) && defined(__cplusplus) +#define DECLSPEC_UUID(x) __declspec(uuid(x)) +#else +#define DECLSPEC_UUID(x) +#endif +#endif + +#define MIDL_INTERFACE(x) struct DECLSPEC_UUID(x) DECLSPEC_NOVTABLE + +#if _MSC_VER >= 1100 +#define EXTERN_GUID(itf,l1,s1,s2,c1,c2,c3,c4,c5,c6,c7,c8) \ + EXTERN_C const IID DECLSPEC_SELECTANY itf = {l1,s1,s2,{c1,c2,c3,c4,c5,c6,c7,c8}} +#else +#define EXTERN_GUID(itf,l1,s1,s2,c1,c2,c3,c4,c5,c6,c7,c8) EXTERN_C const IID itf +#endif + +#endif // GLDOBJBASE_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDObject.h b/GCR/trunk/Glodon/include/GLD/GLDObject.h new file mode 100644 index 00000000..9cf0b6cc --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDObject.h @@ -0,0 +1,438 @@ +/************************************************************************* +* * +* 广联达 对象定义单元 H * +* * +* 设计:Zhangsk 2012.05.23 * +* 备注: * +* 审核: * +* * +* Copyright (c) 2012-2013 Glodon Corporation * +* * +*************************************************************************/ + +#ifndef GLDOBJECT_H +#define GLDOBJECT_H + +#include "GLDUnknwn.h" +#include "GLDVector.h" +#include "GLDObjectList.h" +#include "GLDGlobal.h" + +#define DECLARE_IUNKNOWN \ + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) { \ + return _QueryInterface(riid, ppvObject); \ + }; \ + ULONG STDMETHODCALLTYPE AddRef() { \ + return _AddRef(); \ + }; \ + ULONG STDMETHODCALLTYPE Release() { \ + return _Release(); \ + }; + +#define DECLARE_IDISPATCH \ + DECLARE_IUNKNOWN \ + HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT *pctinfo) { \ + return _GetTypeInfoCount(pctinfo); \ + } \ + HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) { \ + return _GetTypeInfo(iTInfo, lcid, ppTInfo); \ + } \ + HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) { \ + return _GetIDsOfNames(riid, rgszNames, cNames, lcid, rgDispId); \ + } \ + HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, \ + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { \ + return _Invoke(dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); \ + } + +/*! 查询接口映射宏,使用在头文件和cpp文件中加略显麻烦,主要是针对编译器(怕有的编译器把_QueryInterface编译成内联函数) */ +// 头文件中添加的宏 +#define GLD_DECLARE_INTERFACE_MAP \ + protected: \ + HRESULT STDMETHODCALLTYPE _QueryInterface(const IID & riid, void ** ppvObject) +/*! 源文件中添加的宏 */ +#define GLD_INTERFACE_MAP_BEGIN(_ClassName) \ + HRESULT STDMETHODCALLTYPE _ClassName::_QueryInterface(const IID & riid, void ** ppvObject) \ + { \ + HRESULT hr = NOERROR; \ + do \ + { +#define GLD_INTERFACE_MAP_ITFC(_Inteface) \ + if (riid == __uuidof(_Inteface)) \ + { \ + *ppvObject = static_cast<_Inteface *>(this); \ + break; \ + } +#define GLD_INTERFACE_MAP_CLASS(_ClassName) \ + hr = _ClassName::_QueryInterface(riid, ppvObject); \ + if (nullptr != *ppvObject) \ + { \ + return hr; \ + } +#define GLD_INTERFACE_MAP_END \ + *ppvObject = nullptr; \ + hr = E_NOINTERFACE; \ + } while (false); \ + if (nullptr != *ppvObject) \ + { \ + this->AddRef(); \ + } \ + return hr; \ + } + +class GLDCOMMONSHARED_EXPORT GInterfaceObject : public IUnknown +{ +public: + GInterfaceObject(); + virtual ~GInterfaceObject(); + +public: + DECLARE_IUNKNOWN + +public: + inline void doAddRef() { m_cRef.ref(); } + inline void doRelease() { m_cRef.deref(); } + inline LONG refCount() const { return m_cRef.load(); } + +protected: + virtual HRESULT STDMETHODCALLTYPE _QueryInterface(REFIID riid, void **ppvObject); + virtual ULONG STDMETHODCALLTYPE _AddRef(void); + virtual ULONG STDMETHODCALLTYPE _Release(void); + + void beforeDestruction(); + void afterConstruction(); + +private: + QBasicAtomicInteger m_cRef; +}; + +class GLDCOMMONSHARED_EXPORT GAutoIntfObject : public GInterfaceObject, public IDispatch +{ +public: + DECLARE_IDISPATCH +#if defined(GLD_DLL) +public: + GAutoIntfObject() {} + ~GAutoIntfObject() {} +#endif + +protected: + HRESULT STDMETHODCALLTYPE _GetTypeInfoCount(UINT *pctinfo); + HRESULT STDMETHODCALLTYPE _GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo); + HRESULT STDMETHODCALLTYPE _GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId); + HRESULT STDMETHODCALLTYPE _Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr); +protected: + virtual HRESULT STDMETHODCALLTYPE _QueryInterface(REFIID riid, void **ppvObject); +}; + +typedef GInterfaceObject GObject; + +class GLDCOMMONSHARED_EXPORT GNoRefInterfaceObject : public IUnknown +{ +public: + GNoRefInterfaceObject(); + virtual ~GNoRefInterfaceObject(); +public: + DECLARE_IUNKNOWN + +protected: + virtual HRESULT STDMETHODCALLTYPE _QueryInterface(REFIID riid, void **ppvObject); + virtual ULONG STDMETHODCALLTYPE _AddRef(void); + virtual ULONG STDMETHODCALLTYPE _Release(void); +}; + +template +class GInterfaceObjectList +{ +public: + typedef typename GLDVector::const_iterator const_iterator; + typedef typename GLDVector::iterator iterator; +public: + inline GInterfaceObjectList(bool ownerObject = true) { m_ownerObject = ownerObject; } + inline GInterfaceObjectList(const GInterfaceObjectList &l) { clear(); m_ownerObject = l.m_ownerObject; append(l); } + virtual ~GInterfaceObjectList(); + GInterfaceObjectList &operator=(const GInterfaceObjectList &l) + { + clear(); + m_ownerObject = l.m_ownerObject; + append(l); + return *this; + } + + /* + GInterfaceListObject &operator=(const GInterfaceListObject &l); +#ifdef Q_COMPILER_RVALUE_REFS + inline GInterfaceListObject &operator=(GInterfaceListObject &&other) + { qSwap(d, other.d); return *this; } +#endif + inline void swap(GInterfaceListObject &other) { qSwap(d, other.d); } +#ifdef Q_COMPILER_INITIALIZER_LISTS + inline GInterfaceListObject(std::initializer_list args) : d(&GInterfaceListObjectData::shared_null) + { d->ref.ref(); qCopy(args.begin(), args.end(), std::back_inserter(*this)); } +#endif + bool operator==(const GInterfaceListObject &l) const; + inline bool operator!=(const GInterfaceListObject &l) const { return !(*this == l); } +*/ + inline size_t size() const { return m_list.size(); } +/* + inline void detach() { if (d->ref != 1) detach_helper(); } + + inline void detachShared() + { + // The "this->" qualification is needed for GCCE. + if (d->ref != 1 && this->d != &GInterfaceListObjectData::shared_null) + detach_helper(); + } + + inline bool isDetached() const { return d->ref == 1; } + inline void setSharable(bool sharable) { if (!sharable) detach(); d->sharable = sharable; } + inline bool isSharedWith(const GInterfaceListObject &other) const { return d == other.d; } +*/ + + inline bool isEmpty() const { return m_list.empty(); } + + void clear(); + + const T &at(int i) const; + const T &operator[](int i) const; + T &operator[](int i); +/* + void reserve(int size); +*/ + void push_back(const T &t); + void append(const T &t); + void append(const GInterfaceObjectList &t); + void prepend(const T &t); + void insert(int i, const T &t); + void replace(int i, const T &t); + void Delete(int index); + inline void removeAt(int i) + { + Delete(i); + } + int removeAll(const T &t); + int removeOne(const T &t); + inline int remove(const T &t) + { + return removeOne(t); + } + T takeAt(int i); + T takeFirst(); + T takeLast(); + void move(int from, int to); + void swap(int i, int j); + int indexOf(const T &t, int from = 0) const; + int lastIndexOf(const T &t, int from = -1) const; + bool contains(const T &t) const; + int count(const T &t) const; + + inline int count() const { return int(m_list.size()); } + inline int length() const { return int(m_list.size()); } +// GLDVector::const_iterator begin() const { return m_list.begin(); } +// GLDVector::const_iterator end() const { return m_list.end(); } + inline GLDVector &list() { return m_list; } +private: + GLDVector m_list; + bool m_ownerObject; +}; + +/* GInterfaceObjectList */ + +template +GLD_OUTOFLINE_TEMPLATE GInterfaceObjectList::~GInterfaceObjectList() +{ + clear(); +} + +template +GLD_OUTOFLINE_TEMPLATE void GInterfaceObjectList::push_back(const T &t) +{ + if (t != NULL) + { + if (m_ownerObject) + { + t->AddRef(); + } + } + m_list.push_back(t); +} + +template +GLD_OUTOFLINE_TEMPLATE void GInterfaceObjectList::append(const T &t) +{ + push_back(t); +} + +template +GLD_OUTOFLINE_TEMPLATE void GInterfaceObjectList::prepend(const T &t) +{ + if (m_ownerObject) + t->AddRef(); + m_list.insert(m_list.cbegin(), t); +} + +template +GLD_OUTOFLINE_TEMPLATE void GInterfaceObjectList::insert(int i, const T &t) +{ + if (m_ownerObject) + { + t->AddRef(); + } + m_list.insert(i, t); +} + +template +GLD_OUTOFLINE_TEMPLATE void GInterfaceObjectList::replace(int i, const T &t) +{ + if (m_ownerObject) + { + t->AddRef(); + m_list[i]->Release(); + } + m_list[i] = t; +} + +template +GLD_OUTOFLINE_TEMPLATE void GInterfaceObjectList::Delete(int i) +{ + if (m_ownerObject) + { + m_list[i]->Release(); + } + m_list.Delete(i); +} + +template +GLD_OUTOFLINE_TEMPLATE int GInterfaceObjectList::removeAll(const T &t) +{ + int n = m_list.removeAll(t); + if (m_ownerObject) + { + for (int i = 0; i < n; ++i) + t->Release(); + } + return n; +} + +template +GLD_OUTOFLINE_TEMPLATE int GInterfaceObjectList::removeOne(const T &t) +{ +#ifdef _MSC_VER + for (const_iterator it = m_list.begin(); it != m_list.end(); ++it) +#else + for (iterator it = m_list.begin(); it != m_list.end(); ++it) +#endif + { + if (*it == t) + { + int result = it - m_list.begin(); + m_list.erase(it); + if (m_ownerObject) + t->Release(); + return result; + } + } + return -1; +} + +template +GLD_OUTOFLINE_TEMPLATE T GInterfaceObjectList::takeAt(int i) +{ + return m_list.at(i); +} + +template +GLD_OUTOFLINE_TEMPLATE T GInterfaceObjectList::takeFirst() +{ + return m_list.at(0); +} + +template +GLD_OUTOFLINE_TEMPLATE T GInterfaceObjectList::takeLast() +{ + return m_list.at(size() - 1); +} + +template +GLD_OUTOFLINE_TEMPLATE void GInterfaceObjectList::move(int from, int to) +{ + m_list.move(from, to); +} + +template +GLD_OUTOFLINE_TEMPLATE void GInterfaceObjectList::swap(int i, int j) +{ + const T c_value = m_list[i]; + m_list[i] = m_list[j]; + m_list[j] = c_value; +} + +template +GLD_OUTOFLINE_TEMPLATE int GInterfaceObjectList::indexOf(const T &t, int from) const +{ + return m_list.indexOf(t, from); +} + +template +GLD_OUTOFLINE_TEMPLATE int GInterfaceObjectList::lastIndexOf(const T &t, int from) const +{ + return m_list.lastIndexOf(t, from); +} + +template +GLD_OUTOFLINE_TEMPLATE bool GInterfaceObjectList::contains(const T &t) const +{ + return m_list.contains(t); +} + +template +GLD_OUTOFLINE_TEMPLATE int GInterfaceObjectList::count(const T &t) const +{ + return m_list.count(t); +} + +template +GLD_OUTOFLINE_TEMPLATE void GInterfaceObjectList::append(const GInterfaceObjectList &t) +{ + for (int i = 0; i != (int)t.m_list.size(); ++i) + { + append(t.m_list[i]); + } +} + +template +GLD_OUTOFLINE_TEMPLATE void GInterfaceObjectList::clear() +{ + if (m_ownerObject) + { + for (int i = 0; i != (int)m_list.size(); ++i) + { + if (m_list[i] != NULL) + { + m_list[i]->Release(); + } + } + } + m_list.clear(); +} + +template +GLD_OUTOFLINE_TEMPLATE const T &GInterfaceObjectList::at(int i) const +{ + return m_list.at(i); +} + +template +GLD_OUTOFLINE_TEMPLATE const T &GInterfaceObjectList::operator [](int i) const +{ + return m_list[i]; +} + +template +GLD_OUTOFLINE_TEMPLATE T &GInterfaceObjectList::operator [](int i) +{ + return m_list[i]; +} + +#endif // GLDOBJECT_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDObjectList.h b/GCR/trunk/Glodon/include/GLD/GLDObjectList.h new file mode 100644 index 00000000..8dc5f2a3 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDObjectList.h @@ -0,0 +1,260 @@ +#ifndef GLDOBJECTLIST_H +#define GLDOBJECTLIST_H + +#include "GLDVector.h" +#include "GLDGlobal.h" + +#define GLD_OUTOFLINE_TEMPLATE + +template +class GObjectList +{ +public: + inline GObjectList(bool ownerObject = true) { m_ownerObject = ownerObject; } + inline GObjectList(const GObjectList &l) { clear(); m_ownerObject = l.m_ownerObject; append(l); } + ~GObjectList(); + /* + GInterfaceListObject &operator=(const GInterfaceListObject &l); +#ifdef Q_COMPILER_RVALUE_REFS + inline GInterfaceListObject &operator=(GInterfaceListObject &&other) + { qSwap(d, other.d); return *this; } +#endif + inline void swap(GInterfaceListObject &other) { qSwap(d, other.d); } +#ifdef Q_COMPILER_INITIALIZER_LISTS + inline GInterfaceListObject(std::initializer_list args) : d(&GInterfaceListObjectData::shared_null) + { d->ref.ref(); qCopy(args.begin(), args.end(), std::back_inserter(*this)); } +#endif + bool operator==(const GInterfaceListObject &l) const; + inline bool operator!=(const GInterfaceListObject &l) const { return !(*this == l); } +*/ + size_t size() const { return m_list.size(); } + +/* + inline void detach() { if (d->ref != 1) detach_helper(); } + + inline void detachShared() + { + // The "this->" qualification is needed for GCCE. + if (d->ref != 1 && this->d != &GInterfaceListObjectData::shared_null) + detach_helper(); + } + + inline bool isDetached() const { return d->ref == 1; } + inline void setSharable(bool sharable) { if (!sharable) detach(); d->sharable = sharable; } + inline bool isSharedWith(const GInterfaceListObject &other) const { return d == other.d; } +*/ + + inline bool isEmpty() const { return m_list.empty(); } + + void clear(); + + const T &at(int i) const; + const T &operator[](int i) const; + T &operator[](int i); +/* + void reserve(int size); +*/ + void push_back(const T &t); + void append(const T &t); + void append(const GObjectList &t); + void prepend(const T &t); + void insert(int i, const T &t); + void replace(int i, const T &t); + void Delete(int i); + inline void removeAt(int i) + { + Delete(i); + } + int removeAll(const T &t); + int removeOne(const T &t); + inline int remove(const T &t) + { + return removeOne(t); + } + T takeAt(int i); + T takeFirst(); + T takeLast(); + void move(int from, int to); + void swap(int i, int j); + int indexOf(const T &t, int from = 0) const; + int lastIndexOf(const T &t, int from = -1) const; + bool contains(const T &t) const; + int count(const T &t); + + inline int count() const { return int(m_list.size()); } + inline int length() const { return int(m_list.size()); } + inline GLDVector &list() { return m_list; } +private: + GLDVector m_list; + bool m_ownerObject; +}; + +/* GObjectList */ + +template +GLD_OUTOFLINE_TEMPLATE GObjectList::~GObjectList() +{ + clear(); +} + +template +GLD_OUTOFLINE_TEMPLATE void GObjectList::push_back(const T &t) +{ + m_list.push_back(t); +} + +template +GLD_OUTOFLINE_TEMPLATE void GObjectList::append(const T &t) +{ + m_list.push_back(t); +} + +template +GLD_OUTOFLINE_TEMPLATE void GObjectList::prepend(const T &t) +{ + m_list.insert(0, t); +} + +template +GLD_OUTOFLINE_TEMPLATE void GObjectList::insert(int i, const T &t) +{ + if (i >= 0) + m_list.insert(i, t); + else + m_list.push_back(t); +} + +template +GLD_OUTOFLINE_TEMPLATE void GObjectList::replace(int i, const T &t) +{ + if (m_ownerObject) + { + delete m_list[i]; + } + m_list[i] = t; +} + +template +GLD_OUTOFLINE_TEMPLATE void GObjectList::Delete(int i) +{ + if (m_ownerObject) + delete m_list[i]; + m_list.Delete(i); +} + +template +GLD_OUTOFLINE_TEMPLATE int GObjectList::removeAll(const T &t) +{ + int n = m_list.removeAll(t); + if (m_ownerObject && (n > 0)) + { + delete t; + } + return n; +} + +template +GLD_OUTOFLINE_TEMPLATE int GObjectList::removeOne(const T &t) +{ + return m_list.remove(t); +} + +template +GLD_OUTOFLINE_TEMPLATE T GObjectList::takeAt(int i) +{ + return m_list.at(i); +} + +template +GLD_OUTOFLINE_TEMPLATE T GObjectList::takeFirst() +{ + return m_list.at(0); +} + +template +GLD_OUTOFLINE_TEMPLATE T GObjectList::takeLast() +{ + return m_list.at(size() - 1); +} + +template +GLD_OUTOFLINE_TEMPLATE void GObjectList::move(int from, int to) +{ + m_list.move(from, to); +} + +template +GLD_OUTOFLINE_TEMPLATE void GObjectList::swap(int i, int j) +{ + T tObj = m_list[i]; + m_list[i] = m_list[j]; + m_list[j] = tObj; +} + +template +GLD_OUTOFLINE_TEMPLATE int GObjectList::indexOf(const T &t, int from) const +{ + return m_list.indexOf(t); // todo from + G_UNUSED(from) +} + +template +GLD_OUTOFLINE_TEMPLATE int GObjectList::lastIndexOf(const T &t, int from) const +{ + return m_list.lastIndexOf(t, from); +} + +template +GLD_OUTOFLINE_TEMPLATE bool GObjectList::contains(const T &t) const +{ + return m_list.find(t) != m_list.end(); +} + +template +GLD_OUTOFLINE_TEMPLATE int GObjectList::count(const T &t) +{ + return m_list.count(t); +} + +template +GLD_OUTOFLINE_TEMPLATE void GObjectList::append(const GObjectList &t) +{ + for (int i = 0; i != (int)t.m_list.size(); ++i) + { + append(t.m_list[i]); + } +} + +template +GLD_OUTOFLINE_TEMPLATE void GObjectList::clear() +{ + if (m_ownerObject) + { + for (int i = 0; i != (int)m_list.size(); ++i) + { + T tObj = m_list[i]; + delete tObj; + } + } + m_list.clear(); +} + +template +GLD_OUTOFLINE_TEMPLATE const T &GObjectList::at(int i) const +{ + return m_list.at(i); +} + +template +GLD_OUTOFLINE_TEMPLATE const T &GObjectList::operator [](int i) const +{ + return m_list[i]; +} + +template +GLD_OUTOFLINE_TEMPLATE T &GObjectList::operator [](int i) +{ + return m_list[i]; +} + +#endif // GLDOBJECTLIST_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDPaperTableView.h b/GCR/trunk/Glodon/include/GLD/GLDPaperTableView.h new file mode 100644 index 00000000..48b178ca --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDPaperTableView.h @@ -0,0 +1,26 @@ +#ifndef GLDPAPERTABLEVIEW_H +#define GLDPAPERTABLEVIEW_H + +#include "GLDTableView.h" + +class GlodonPaperTableViewPrivate; + +class GlodonPaperTableView : public GlodonTableView +{ +public: + explicit GlodonPaperTableView(QWidget *parent = 0); + +protected: + explicit GlodonPaperTableView(GlodonPaperTableViewPrivate &dd, QWidget *parent = 0); + +protected: + virtual void showSectionResizingInfoFrame(const QPoint &mousePosition, Qt::Orientation direction, GlodonHeaderView::ResizeState state); + + virtual void columnResized(int column, int oldWidth, int newWidth, bool isManual = false); + +private: + Q_DECLARE_PRIVATE(GlodonPaperTableView) + Q_DISABLE_COPY(GlodonPaperTableView) +}; + +#endif // GLDPAPERTABLEVIEW_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDPaperTableView_p.h b/GCR/trunk/Glodon/include/GLD/GLDPaperTableView_p.h new file mode 100644 index 00000000..3fc8ff98 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDPaperTableView_p.h @@ -0,0 +1,21 @@ +#ifndef GLDPAPERTABLEVIEW_P_H +#define GLDPAPERTABLEVIEW_P_H + +#include "GLDTableView_p.h" +#include "GLDPaperTableView.h" + +class GlodonPaperTableViewPrivate : public GlodonTableViewPrivate +{ + Q_DECLARE_PUBLIC(GlodonPaperTableView) + +public: + GlodonPaperTableViewPrivate() : + m_paperState(GlodonHeaderView::Press) + { + + } + +public: + GlodonHeaderView::ResizeState m_paperState; //在分布模式下记录用 +}; +#endif // GLDPAPERTABLEVIEW_P_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDPaperWidget.h b/GCR/trunk/Glodon/include/GLD/GLDPaperWidget.h new file mode 100644 index 00000000..e713038d --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDPaperWidget.h @@ -0,0 +1,116 @@ +#ifndef GLDPAPERWIDGET_H +#define GLDPAPERWIDGET_H + +#include "GLDHeaderView.h" + +#include + +#define ONE_INCHES 25.4 // 1 inches = 25.4mm + +#define POINT_NUMBER_FROM_MM(mm, nDPI) (double(double(mm) * nDPI) / ONE_INCHES) + +class GLDDocViewTableViewFactory; +class GLDDocView; +class GlodonPaperTableView; + +enum ZoomFactor { NoneFactor = -1, percent_50 = 0, percent_100 = 1, percent_200 = 2, percent_400 = 4 }; + +class GLDTABLEVIEWSHARED_EXPORT GLDPaperWidget : public QWidget +{ + Q_OBJECT +public: + explicit GLDPaperWidget(GLDDocView *docView, int curPageNo, int pageCount, + GlodonHeaderView::ResizeMode resizeMode, GLDDocViewTableViewFactory *tableViewFactory, + QWidget *parent = 0, Qt::WindowFlags f = 0); + virtual ~GLDPaperWidget(); + +public: + inline GlodonPaperTableView *tableView() + { + return m_tableView; + } + int curPageNo(); + +private slots: + void rowHeightResized(int row, int oldSize, int newSize, bool isManual = false); + void columnResized(int column, int oldSize, int newSize, bool isManual = false); + +private: + ZoomFactor factor() const; + void setFactor(const ZoomFactor &value); + + virtual QSize sizeHint() const; + + int headerHeight() const; + void setHeaderHeight(int headerHeight); + + int footerHeight() const; + void setFooterHeight(int footerHeight); + + int tableViewHeight() const; + void setTableViewHeight(int tableViewHeight); + + int tableViewWidth() const; + void setTableViewWidth(int tableViewWidth); + + int leftMargin() const; + void setLeftMargin(int leftMargin); + + int rightMargin() const; + void setRightMargin(int rightMargin); + + void reLayout(); + + QWidget *headerWidget() const; + void setHeaderWidget(QWidget *headerWidget); + + QWidget *footerWidget() const; + void setFooterWidget(QWidget *footerWidget); + + int paperWidth() const; + void setPaperWidth(int value); + + int paperHeight() const; + void setPaperHeight(int value); + + void createTableView(); + void initTableView(); + void initHeaderFooter(); + void initPageGeometry(); + void initHeaderView(); + void initDelegate(); + void initColWidths(); + void initRowHeights(); + void installEventFilter(); + void initDataModel(); + void initTableViewMisc(); + void initColumnHidden(); + void configGridLine(); + void connectTableViewSignalSlot(); + +private: + ZoomFactor m_factor; + + QWidget *m_headerWidget; + QWidget *m_footerWidget; + + int m_tableViewWidth; + int m_tableViewHeight; + int m_rightMargin; + int m_pageCount; + int m_dPageHeight; + int m_dPageWidth; + int m_leftMargin; + int m_headerHeight; + int m_footerHeight; + int m_curPageNo; + + GlodonPaperTableView *m_tableView; + GlodonHeaderView::ResizeMode m_resizeMode; + GLDDocViewTableViewFactory *m_tableViewFactory; + GLDDocView *m_docView; + + friend class GLDDocView; +}; + +#endif // GLDPAPERWIDGET_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDPaperWidgetModel.h b/GCR/trunk/Glodon/include/GLD/GLDPaperWidgetModel.h new file mode 100644 index 00000000..96fec6d4 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDPaperWidgetModel.h @@ -0,0 +1,63 @@ +/*! + *@file GLDPaperWidgetModel.h + *@brief {} + *@author duanb + *@date 2013.12.31 + *@remarks {} + *Copyright (c) 1998-2013 Glodon Corporation + */ +#ifndef GLDPAPERWIDGETMODEL_H +#define GLDPAPERWIDGETMODEL_H + +#include "GLDAbstractItemModel.h" +#include "GLDTableView_Global.h" + +class GLDTABLEVIEWSHARED_EXPORT GLDPaperWidgetModel : public GlodonAbstractItemModel +{ + Q_OBJECT +public: + explicit GLDPaperWidgetModel(QAbstractItemModel *pModel, int nCurPageNo, int startRow, int rowCount, QObject *parent = 0); + ~GLDPaperWidgetModel(); + +public: + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex &child) const; + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + + Qt::ItemFlags flags(const QModelIndex &index) const; + QModelIndex dataIndex(const QModelIndex &index) const; + + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, + int role = Qt::EditRole); + + bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()); + bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex()); + bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); + bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex()); + + void setStartRow(int startRow); + + void setRowCountPerPage(int rowCount); + + int curPageNo() const; + void setCurPageNo(int nCurPageNo); + +Q_SIGNALS: + void rowHeightChanged(const QModelIndex &index,const int &value); + void columnWidthChanged(const QModelIndex &index,const int &value); + +private: + QAbstractItemModel *m_dataModel; + int m_nStartRow; + int m_nRowCountPerPage; + int m_nCurPageNo; // 从0开始 +}; + +#endif // GLDPAPERWIDGETMODEL_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDPlainTextEdit.h b/GCR/trunk/Glodon/include/GLD/GLDPlainTextEdit.h new file mode 100644 index 00000000..873cb87b --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDPlainTextEdit.h @@ -0,0 +1,68 @@ +#ifndef GLDPlainTextEdit_H +#define GLDPlainTextEdit_H +#include +#include +#include +#include + +class GLDIndexPoint : public QPoint +{ +public: + explicit GLDIndexPoint() : QPoint(){} + explicit GLDIndexPoint(int x, int y) : QPoint(x, y){} + explicit GLDIndexPoint(const QPoint &rhs) : QPoint(rhs.x(), rhs.y()){} + explicit GLDIndexPoint(const GLDIndexPoint &rhs) : QPoint(rhs.x(), rhs.y()){} + bool isValide() const{ + return x() >= 0 && y() >= 0; + } + bool operator<(const GLDIndexPoint &rhs) const + { + if (this->x() < rhs.x()) + return true; + else if (x() > rhs.x()) + return false; + else if (y() < rhs.y()) + return true; + else + return false; + } +}; + +//class GLDPlainTextEdit : public QPlainTextEdit +//{ +//Q_OBJECT +//public: +// GLDPlainTextEdit(QWidget *parent); +// GLDPlainTextEdit(QWidget *parent, QPoint gridIndex); +// void setPaddingByOffset(); +// void setPaddingByOffset(const QPoint &gridUsingOffset); +// void resetPadding(int left = 0x7fff, int top = 0x7fff, int right = 0x7fff, int bottom = 0x7fff); + +//protected Q_SLOTS: +// void adjustVerticalPadding(); + +//protected: +// virtual void showEvent(QShowEvent *); + +// QPoint gridUsingOffset(); +// static QString leftTopStyleString() +// { +// static QString str = "padding-left:%1 px; padding-top: %2 px;"; +// return str; +// } +// static QString leftTopRightBottomStyleString() +// { +// static QString str = "padding-left:%1 px; padding-top: %2 px; padding-right: %3 px; padding-bottom: %4 px;"; +// return str; +// } + +//protected: +// int prevLineCount; +// int prevLeftPadding; +// int prevTopPadding; +// bool firstShow; +// GLDIndexPoint gridDrawIndex; +//private: +//}; + +#endif // GLDPlainTextEdit_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDPopupWindow.h b/GCR/trunk/Glodon/include/GLD/GLDPopupWindow.h new file mode 100644 index 00000000..0d0745f1 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDPopupWindow.h @@ -0,0 +1,313 @@ +#ifndef GPOPUPWINDOW_H +#define GPOPUPWINDOW_H + +#include +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class QLineEdit; +class GLDPopupWindowPrivate; + +class GLDPopupWindow : public QWidget +{ + Q_OBJECT + + Q_ENUMS(InsertPolicy) + Q_ENUMS(SizeAdjustPolicy) + Q_PROPERTY(bool editable READ isEditable WRITE setEditable) + Q_PROPERTY(QString currentText READ currentText) + Q_PROPERTY(SizeAdjustPolicy sizeAdjustPolicy READ sizeAdjustPolicy WRITE setSizeAdjustPolicy) + Q_PROPERTY(int minimumContentsLength READ minimumContentsLength WRITE setMinimumContentsLength) + Q_PROPERTY(bool duplicatesEnabled READ duplicatesEnabled WRITE setDuplicatesEnabled) + Q_PROPERTY(bool frame READ hasFrame WRITE setFrame) + +public: + explicit GLDPopupWindow(QWidget *parent = 0); + ~GLDPopupWindow(); + + int maxVisibleItems() const; + void setMaxVisibleItems(int maxItems); + + int count() const; + void setMaxCount(int max); + int maxCount() const; + + bool duplicatesEnabled() const; + void setDuplicatesEnabled(bool enable); + + void setFrame(bool); + bool hasFrame() const; + + void setPopupWidget(QWidget *newWidget); + QWidget *PopupWidget(); + + enum InsertPolicy + { + NoInsert, + InsertAtTop, + InsertAtCurrent, + InsertAtBottom, + InsertAfterCurrent, + InsertBeforeCurrent, + InsertAlphabetically + }; + + InsertPolicy insertPolicy() const; + void setInsertPolicy(InsertPolicy policy); + + enum SizeAdjustPolicy + { + AdjustToContents, + AdjustToContentsOnFirstShow, + AdjustToMinimumContentsLengthWithIcon + }; + + SizeAdjustPolicy sizeAdjustPolicy() const; + void setSizeAdjustPolicy(SizeAdjustPolicy policy); + int minimumContentsLength() const; + void setMinimumContentsLength(int characters); + QSize iconSize() const; + void setIconSize(const QSize &size); + + bool isEditable() const; + void setEditable(bool editable); + void setLineEdit(QLineEdit *edit); + QLineEdit *lineEdit() const; +#ifndef QT_NO_VALIDATOR + void setValidator(const QValidator *v); + const QValidator *validator() const; +#endif + QSize sizeHint() const; + QSize minimumSizeHint() const; + + bool event(QEvent *event); + + QString currentText() const; + +public Q_SLOTS: + void clear(); + void clearEditText(); + void setEditText(const QString &text); + virtual void showPopup(); + virtual void hidePopup(); + +Q_SIGNALS: + void editTextChanged(const QString &); + void activated(int index); + void activated(const QString &); + void highlighted(int index); + void highlighted(const QString &); + +protected: + void focusInEvent(QFocusEvent *e); + void focusOutEvent(QFocusEvent *e); + void changeEvent(QEvent *e); + void resizeEvent(QResizeEvent *e); + void paintEvent(QPaintEvent *e); + void showEvent(QShowEvent *e); + void hideEvent(QHideEvent *e); + void mousePressEvent(QMouseEvent *e); + void mouseReleaseEvent(QMouseEvent *e); + void keyPressEvent(QKeyEvent *e); + void keyReleaseEvent(QKeyEvent *e); +#ifndef QT_NO_WHEELEVENT + void wheelEvent(QWheelEvent *e); +#endif + void contextMenuEvent(QContextMenuEvent *e); + void inputMethodEvent(QInputMethodEvent *); + QVariant inputMethodQuery(Qt::InputMethodQuery) const; + void initStyleOption(QStyleOptionComboBox *option) const; + +protected: + GLDPopupWindow(GLDPopupWindowPrivate &, QWidget *); + +private: + Q_DECLARE_PRIVATE(GLDPopupWindow) + Q_DISABLE_COPY(GLDPopupWindow) + Q_PRIVATE_SLOT(d_func(), void _q_returnPressed()) + Q_PRIVATE_SLOT(d_func(), void _q_resetButton()) +}; + +class QAction; + +class GPopupWindowPrivateScroller : public QWidget +{ + Q_OBJECT + +public: + GPopupWindowPrivateScroller(QAbstractSlider::SliderAction action, QWidget *parent) + : QWidget(parent), sliderAction(action) + { + setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); + setAttribute(Qt::WA_NoMousePropagation); + } + QSize sizeHint() const + { + return QSize(20, style()->pixelMetric(QStyle::PM_MenuScrollerHeight)); + } + +protected: + inline void stopTimer() + { + timer.stop(); + } + + inline void startTimer() + { + timer.start(100, this); + fast = false; + } + + void enterEvent(QEvent *) + { + startTimer(); + } + + void leaveEvent(QEvent *) + { + stopTimer(); + } + void timerEvent(QTimerEvent *e) + { + if (e->timerId() == timer.timerId()) + { + emit doScroll(sliderAction); + if (fast) { + emit doScroll(sliderAction); + emit doScroll(sliderAction); + } + } + } + void hideEvent(QHideEvent *) + { + stopTimer(); + } + + void mouseMoveEvent(QMouseEvent *e) + { + // Enable fast scrolling if the cursor is directly above or below the popup. + const int mouseX = e->pos().x(); + const int mouseY = e->pos().y(); + const bool horizontallyInside = pos().x() < mouseX && mouseX < rect().right() + 1; + const bool verticallyOutside = (sliderAction == QAbstractSlider::SliderSingleStepAdd) ? + rect().bottom() + 1 < mouseY : mouseY < pos().y(); + + fast = horizontallyInside && verticallyOutside; + } + + void paintEvent(QPaintEvent *) { + QPainter p(this); + QStyleOptionMenuItem menuOpt; + menuOpt.init(this); + menuOpt.checkType = QStyleOptionMenuItem::NotCheckable; + menuOpt.menuRect = rect(); + menuOpt.maxIconWidth = 0; + menuOpt.tabWidth = 0; + menuOpt.menuItemType = QStyleOptionMenuItem::Scroller; + if (sliderAction == QAbstractSlider::SliderSingleStepAdd) + menuOpt.state |= QStyle::State_DownArrow; +#ifndef Q_WS_S60 + p.eraseRect(rect()); +#endif + style()->drawControl(QStyle::CE_MenuScroller, &menuOpt, &p); + } + +Q_SIGNALS: + void doScroll(int action); + +private: + QAbstractSlider::SliderAction sliderAction; + QBasicTimer timer; + bool fast; +}; + +class GPopupWindowPrivateContainer : public QFrame +{ + Q_OBJECT + +public: + GPopupWindowPrivateContainer(GLDPopupWindow *parent); + int spacing() const; + void updateTopBottomMargin(); + void setWidget(QWidget *newFrame); + QWidget *widget(); + + QTimer blockMouseReleaseTimer; + QBasicTimer adjustSizeTimer; + QPoint initialClickPosition; + +protected: + void changeEvent(QEvent *e); + bool eventFilter(QObject *o, QEvent *e); + void mousePressEvent(QMouseEvent *e); + void mouseReleaseEvent(QMouseEvent *e); + void showEvent(QShowEvent *e); + void hideEvent(QHideEvent *e); + void timerEvent(QTimerEvent *timerEvent); + void resizeEvent(QResizeEvent *e); + QStyleOptionComboBox comboStyleOption() const; + +Q_SIGNALS: + void resetButton(); + +private: + GLDPopupWindow *combo; + QWidget *popupWidget; +}; + +class GLDPopupWindowPrivate : public QWidgetPrivate +{ + Q_DECLARE_PUBLIC(GLDPopupWindow) +public: + GLDPopupWindowPrivate(); + ~GLDPopupWindowPrivate() {} + void init(); + GPopupWindowPrivateContainer* viewContainer(); + void updateLineEditGeometry(); + Qt::MatchFlags matchFlags() const; + void _q_returnPressed(); + void _q_resetButton(); + void _q_updateIndexBeforeChange(); + void updateArrow(QStyle::StateFlag state); + bool updateHoverControl(const QPoint &pos); + QRect popupGeometry(int screen = -1) const; + QStyle::SubControl newHoverControl(const QPoint &pos); + int computeWidthHint() const; + QSize recomputeSizeHint(QSize &sh) const; + void adjustComboBoxSize(); + void updateLayoutDirection(); + void updateViewContainerPaletteAndOpacity(); + + QLineEdit *lineEdit; + GPopupWindowPrivateContainer *container; + GLDPopupWindow::SizeAdjustPolicy sizeAdjustPolicy; + int minimumContentsLength; + QSize iconSize; + uint shownOnce : 1; + uint duplicatesEnabled : 1; + uint frame : 1; + uint padding : 26; + mutable QSize minimumSizeHint; + mutable QSize sizeHint; + QStyle::StateFlag arrowState; + QStyle::SubControl hoverControl; + QRect hoverRect; + int indexBeforeChange; + static QPalette viewContainerPalette(GLDPopupWindow *cmb) + { return cmb->d_func()->viewContainer()->palette(); } +}; + + +#endif // GPOPUPWINDOW_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDProgressBar.h b/GCR/trunk/Glodon/include/GLD/GLDProgressBar.h new file mode 100644 index 00000000..d77132c2 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDProgressBar.h @@ -0,0 +1,83 @@ +/*! +*@file +*@brief 进度条 +*@author wangdz +*@date 2014年12月13日 +*@remarks +* +*Copyright (c) 1998-25 Glodon Corporation +*/ + +#ifndef GLDPROGRESSBAR_H +#define GLDPROGRESSBAR_H + +#include +#include +#include +#include "GLDWidget_Global.h" + +class GLDWIDGETSHARED_EXPORT GLDProgressBar: public QObject +{ + Q_OBJECT + +public: + GLDProgressBar(QWidget *parent = NULL); + ~GLDProgressBar(); + +public: + /** + * @brief 设置当前进度条的值 + */ + void setValue(const int); + /** + * @brief 设置进度条的边界范围 + * @param[in] minimum 进度条最小的边界值 + * @param[in] maximum 进度条最大的边界值 + * @note 当出现minimum = maximum = 0时,会出现进度条busy的状态指示 + * @see QProgressDialog::setRange,setMinimum,setMaximum + * + */ + void setRange(int minimum, int maximum); + /** + * @brief 在非主线程调用刷新方法,需要通知主线程更新m_progressDlg的value + * @param[in] pos 进度条当前边界值 + */ + void updateProgress(int pos); + /** + * @brief 显示进度条 + */ + void show(); + + virtual bool event(QEvent *event); + /** + * @brief 隐藏进度条 + */ + void hide(); + /** + * @brief 得到当前进度条位置 + * @param[in] pos 进度条当前边界值 + */ + int getProgressPos(); + /** + * @brief 设置进度条的大小 + * @param[in] width 宽度 + * @param[in] height 高度 + */ + void setSize(int width, int height); + void setPos(int x, int y); + /** + * @brief 设置进度条上方文本信息 + * 注:此方法一定要在resize方法之前使用 否则resize方法会失效 + */ + void setText(const QString &str); + +private: + bool isCreateThread(); + +private: + int m_cachePos; + Qt::HANDLE m_barThreadId; + QProgressDialog *m_progressDlg; + QWaitCondition m_waitobj; +}; +#endif diff --git a/GCR/trunk/Glodon/include/GLD/GLDProgressBarEvent.h b/GCR/trunk/Glodon/include/GLD/GLDProgressBarEvent.h new file mode 100644 index 00000000..5c4e79fe --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDProgressBarEvent.h @@ -0,0 +1,93 @@ +/*! +*@file +*@brief 定义设置值的各种事件 +*@author wangdz +*@date 2014年12月13日 +*@remarks +* +*Copyright (c) 1998-25 Glodon Corporation +*/ +#ifndef GLDPROGRESSBAREVENT_H +#define GLDPROGRESSBAREVENT_H + + +#include +#include "GLDWidget_Global.h" + +static const QEvent::Type SetValue = (QEvent::Type) QEvent::registerEventType(QEvent::User + 100); +static const QEvent::Type SetVisible = (QEvent::Type) QEvent::registerEventType(QEvent::User + 101); +static const QEvent::Type Resize = (QEvent::Type) QEvent::registerEventType(QEvent::User + 102); +static const QEvent::Type SetPosition = (QEvent::Type) QEvent::registerEventType(QEvent::User + 103); +static const QEvent::Type Dispose = (QEvent::Type) QEvent::registerEventType(QEvent::User + 104); + +//刷新滚动条值事件 +class GLDWIDGETSHARED_EXPORT GUpdateEvent: public QEvent +{ +public: + GUpdateEvent(): QEvent(SetValue) {} + int value(); + void setValue(int value); + +private: + int m_value; +}; + +//设置显隐事件 +class GLDWIDGETSHARED_EXPORT GVisibleEvent: public QEvent +{ +public: + GVisibleEvent(): QEvent(SetVisible) + { + m_visible = false; + } + bool visible(); + void setIsVisible(bool visible); + +private: + bool m_visible; +}; + +//设置大小事件 +class GLDWIDGETSHARED_EXPORT GResizeEvent: public QEvent +{ +public: + GResizeEvent(): QEvent(Resize) + { + m_width = 0; + m_height = 0; + } + int width(); + int height(); + void setWidth(int width); + void setHeight(int height); + +private: + int m_width; + int m_height; +}; + +class GLDWIDGETSHARED_EXPORT GSetPosEvent: public QEvent +{ +public: + GSetPosEvent(): QEvent(SetPosition) + { + m_x = 0; + m_y = 0; + } + int x(); + int y(); + void setX(int x); + void setY(int y); + +private: + int m_x; + int m_y; +}; + +class GLDWIDGETSHARED_EXPORT GDisposeEvent: public QEvent +{ +public: + GDisposeEvent(): QEvent(Dispose) {} +}; + +#endif diff --git a/GCR/trunk/Glodon/include/GLD/GLDRBTree.h b/GCR/trunk/Glodon/include/GLD/GLDRBTree.h new file mode 100644 index 00000000..134ab929 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDRBTree.h @@ -0,0 +1,576 @@ +#ifndef GLDRBTREE_H +#define GLDRBTREE_H + +#include "GLDVector.h" + +template +class GLDRBTreeNode +{ +public: + inline GLDRBTreeNode() : data(0), parent(0), left(0), right(0), red(true) { } + inline ~GLDRBTreeNode() {if (left) delete left; if (right) delete right;} + T data; + GLDRBTreeNode *parent; + GLDRBTreeNode *left; + GLDRBTreeNode *right; + bool red; +}; + +template +class GLDRBTree +{ +public: + inline GLDRBTree() : m_root(0), freeList(0) { } + inline ~GLDRBTree(); + + inline void clear(); + + void attachBefore(GLDRBTreeNode *parent, GLDRBTreeNode *child); + void attachAfter(GLDRBTreeNode *parent, GLDRBTreeNode *child); + + inline GLDRBTreeNode *front(GLDRBTreeNode *node) const; + inline GLDRBTreeNode *back(GLDRBTreeNode *node) const; + GLDRBTreeNode *next(GLDRBTreeNode *node) const; + GLDRBTreeNode *previous(GLDRBTreeNode *node) const; + + inline void deleteNode(GLDRBTreeNode *&node); + inline GLDRBTreeNode *newNode(); + + // Return 1 if 'left' comes after 'right', 0 if equal, and -1 otherwise. + // 'left' and 'right' cannot be null. + int order(GLDRBTreeNode *left, GLDRBTreeNode *right); + inline bool validate() const; + +private: + void rotateLeft(GLDRBTreeNode *node); + void rotateRight(GLDRBTreeNode *node); + void update(GLDRBTreeNode *node); + + inline void attachLeft(GLDRBTreeNode *parent, GLDRBTreeNode *child); + inline void attachRight(GLDRBTreeNode *parent, GLDRBTreeNode *child); + + int blackDepth(GLDRBTreeNode *top) const; + bool checkRedBlackProperty(GLDRBTreeNode *top) const; + + void swapNodes(GLDRBTreeNode *n1, GLDRBTreeNode *n2); + void detach(GLDRBTreeNode *node); + + // 'node' must be black. rebalance will reduce the depth of black nodes by one in the sibling tree. + void rebalance(GLDRBTreeNode *node); +public: + GLDRBTreeNode *root() const { return m_root; } +private: + GLDRBTreeNode *m_root; + GLDRBTreeNode *freeList; +}; + +template +inline GLDRBTree::~GLDRBTree() +{ + clear(); + while (freeList) + { + // Avoid recursively calling the destructor, as this list may become large. + GLDRBTreeNode *next = freeList->right; + freeList->right = 0; + delete freeList; + freeList = next; + } +} + +template +inline void GLDRBTree::clear() +{ + if (m_root) + delete m_root; + m_root = 0; +} + +template +void GLDRBTree::rotateLeft(GLDRBTreeNode *node) +{ + // | | // + // N B // + // / \ / \ // + // A B ---> N D // + // / \ / \ // + // C D A C // + + GLDRBTreeNode *&ref = (node->parent ? (node == node->parent->left ? node->parent->left : node->parent->right) : m_root); + ref = node->right; + node->right->parent = node->parent; + + // : // + // N // + // / :| // + // A B // + // / \ // + // C D // + + node->right = ref->left; + if (ref->left) + ref->left->parent = node; + + // : | // + // N B // + // / \ : \ // + // A C D // + + ref->left = node; + node->parent = ref; + + // | // + // B // + // / \ // + // N D // + // / \ // + // A C // +} + +template +void GLDRBTree::rotateRight(GLDRBTreeNode *node) +{ + // | | // + // N A // + // / \ / \ // + // A B ---> C N // + // / \ / \ // + // C D D B // + + GLDRBTreeNode *&ref = (node->parent ? (node == node->parent->left ? node->parent->left : node->parent->right) : m_root); + ref = node->left; + node->left->parent = node->parent; + + node->left = ref->right; + if (ref->right) + ref->right->parent = node; + + ref->right = node; + node->parent = ref; +} + +template +void GLDRBTree::update(GLDRBTreeNode *node) // call this after inserting a node +{ + while (true) + { + GLDRBTreeNode *parent = node->parent; + + // if the node is the m_root, color it black + if (!parent) + { + node->red = false; + return; + } + + // if the parent is black, the node can be left red + if (!parent->red) + return; + + // at this point, the parent is red and cannot be the m_root + GLDRBTreeNode *grandpa = parent->parent; + Q_ASSERT(grandpa); + + GLDRBTreeNode *uncle = (parent == grandpa->left ? grandpa->right : grandpa->left); + if (uncle && uncle->red) + { + // grandpa's black, parent and uncle are red. + // let parent and uncle be black, grandpa red and recursively update grandpa. + Q_ASSERT(!grandpa->red); + parent->red = false; + uncle->red = false; + grandpa->red = true; + node = grandpa; + continue; + } + + // at this point, uncle is black + if (node == parent->right && parent == grandpa->left) + rotateLeft(node = parent); + else if (node == parent->left && parent == grandpa->right) + rotateRight(node = parent); + parent = node->parent; + + if (parent == grandpa->left) + { + rotateRight(grandpa); + parent->red = false; + grandpa->red = true; + } + else + { + rotateLeft(grandpa); + parent->red = false; + grandpa->red = true; + } + return; + } +} + +template +inline void GLDRBTree::attachLeft(GLDRBTreeNode *parent, GLDRBTreeNode *child) +{ + Q_ASSERT(!parent->left); + parent->left = child; + child->parent = parent; + update(child); +} + +template +inline void GLDRBTree::attachRight(GLDRBTreeNode *parent, GLDRBTreeNode *child) +{ + Q_ASSERT(!parent->right); + parent->right = child; + child->parent = parent; + update(child); +} + +template +void GLDRBTree::attachBefore(GLDRBTreeNode *parent, GLDRBTreeNode *child) +{ + if (!m_root) + { + update(m_root = child); + } + else if (!parent) + { + attachRight(back(m_root), child); + } + else if (parent->left) + { + attachRight(back(parent->left), child); + } + else + { + attachLeft(parent, child); + } +} + +template +void GLDRBTree::attachAfter(GLDRBTreeNode *parent, GLDRBTreeNode *child) +{ + if (!m_root) + { + update(m_root = child); + } + else if (!parent) + { + attachLeft(front(m_root), child); + } + else if (parent->right) + { + attachLeft(front(parent->right), child); + } + else + { + attachRight(parent, child); + } +} + +template +void GLDRBTree::swapNodes(GLDRBTreeNode *n1, GLDRBTreeNode *n2) +{ + // Since iterators must not be invalidated, it is not sufficient to only swap the data. + if (n1->parent == n2) + { + n1->parent = n2->parent; + n2->parent = n1; + } + else if (n2->parent == n1) + { + n2->parent = n1->parent; + n1->parent = n2; + } + else + { + qSwap(n1->parent, n2->parent); + } + + qSwap(n1->left, n2->left); + qSwap(n1->right, n2->right); + qSwap(n1->red, n2->red); + + if (n1->parent) + { + if (n1->parent->left == n2) + n1->parent->left = n1; + else + n1->parent->right = n1; + } + else + { + m_root = n1; + } + + if (n2->parent) + { + if (n2->parent->left == n1) + n2->parent->left = n2; + else + n2->parent->right = n2; + } + else + { + m_root = n2; + } + + if (n1->left) + n1->left->parent = n1; + if (n1->right) + n1->right->parent = n1; + + if (n2->left) + n2->left->parent = n2; + if (n2->right) + n2->right->parent = n2; +} + +template +void GLDRBTree::detach(GLDRBTreeNode *node) // call this before removing a node. +{ + if (node->right) + { + swapNodes(node, front(node->right)); + } + + GLDRBTreeNode *child = (node->left ? node->left : node->right); + + if (!node->red) + { + if (child && child->red) + { + child->red = false; + } + else + { + rebalance(node); + } + } + + GLDRBTreeNode *&ref = (node->parent ? (node == node->parent->left ? node->parent->left : node->parent->right) : m_root); + ref = child; + if (child) + { + child->parent = node->parent; + } + node->left = node->right = node->parent = 0; +} + +// 'node' must be black. rebalance will reduce the depth of black nodes by one in the sibling tree. +template +void GLDRBTree::rebalance(GLDRBTreeNode *node) +{ + Q_ASSERT(!node->red); + while (true) + { + if (!node->parent) return; + + // at this point, node is not a parent, it is black, thus it must have a sibling. + GLDRBTreeNode *sibling = (node == node->parent->left ? node->parent->right : node->parent->left); + Q_ASSERT(sibling); + + if (sibling->red) + { + sibling->red = false; + node->parent->red = true; + if (node == node->parent->left) + { + rotateLeft(node->parent); + } + else + { + rotateRight(node->parent); + } + sibling = (node == node->parent->left ? node->parent->right : node->parent->left); + Q_ASSERT(sibling); + } + + // at this point, the sibling is black. + Q_ASSERT(!sibling->red); + + if ((!sibling->left || !sibling->left->red) && (!sibling->right || !sibling->right->red)) + { + bool bParentWasRed = node->parent->red; + sibling->red = true; + node->parent->red = false; + if (bParentWasRed) + return; + node = node->parent; + continue; + } + + // at this point, at least one of the sibling's children is red. + + if (node == node->parent->left) + { + if (!sibling->right || !sibling->right->red) + { + Q_ASSERT(sibling->left); + sibling->red = true; + sibling->left->red = false; + rotateRight(sibling); + + sibling = sibling->parent; + Q_ASSERT(sibling); + } + sibling->red = node->parent->red; + node->parent->red = false; + + Q_ASSERT(sibling->right->red); + sibling->right->red = false; + rotateLeft(node->parent); + } + else + { + if (!sibling->left || !sibling->left->red) + { + Q_ASSERT(sibling->right); + sibling->red = true; + sibling->right->red = false; + rotateLeft(sibling); + + sibling = sibling->parent; + Q_ASSERT(sibling); + } + sibling->red = node->parent->red; + node->parent->red = false; + + Q_ASSERT(sibling->left->red); + sibling->left->red = false; + rotateRight(node->parent); + } + return; + } +} + +template +inline GLDRBTreeNode *GLDRBTree::front(GLDRBTreeNode *node) const +{ + while (node->left) + node = node->left; + return node; +} + +template +inline GLDRBTreeNode *GLDRBTree::back(GLDRBTreeNode *node) const +{ + while (node->right) + node = node->right; + return node; +} + +template +GLDRBTreeNode *GLDRBTree::next(GLDRBTreeNode *node) const +{ + if (node->right) + return front(node->right); + while (node->parent && node == node->parent->right) + { + node = node->parent; + } + return node->parent; +} + +template +GLDRBTreeNode *GLDRBTree::previous(GLDRBTreeNode *node) const +{ + if (node->left) + return back(node->left); + while (node->parent && node == node->parent->left) + node = node->parent; + return node->parent; +} + +template +int GLDRBTree::blackDepth(GLDRBTreeNode *top) const +{ + if (!top) + return 0; + int leftDepth = blackDepth(top->left); + int rightDepth = blackDepth(top->right); + if (leftDepth != rightDepth) + return -1; + if (!top->red) + ++leftDepth; + return leftDepth; +} + +template +bool GLDRBTree::checkRedBlackProperty(GLDRBTreeNode *top) const +{ + if (!top) + return true; + if (top->left && !checkRedBlackProperty(top->left)) + return false; + if (top->right && !checkRedBlackProperty(top->right)) + return false; + return !(top->red && ((top->left && top->left->red) || (top->right && top->right->red))); +} + +template +inline bool GLDRBTree::validate() const +{ + return checkRedBlackProperty(m_root) && blackDepth(m_root) != -1; +} + +template +inline void GLDRBTree::deleteNode(GLDRBTreeNode *&node) +{ + Q_ASSERT(node); + detach(node); + node->right = freeList; + freeList = node; + node = 0; +} + +template +inline GLDRBTreeNode *GLDRBTree::newNode() +{ + if (freeList) { + GLDRBTreeNode *node = freeList; + freeList = freeList->right; + node->parent = node->left = node->right = 0; + node->red = true; + return node; + } + return new GLDRBTreeNode; +} + +// Return 1 if 'left' comes after 'right', 0 if equal, and -1 otherwise. +// 'left' and 'right' cannot be null. +template +int GLDRBTree::order(GLDRBTreeNode *left, GLDRBTreeNode *right) +{ + Q_ASSERT(left && right); + if (left == right) + return 0; + + GLDVector *> leftAncestors; + GLDVector *> rightAncestors; + while (left) { + leftAncestors.push_back(left); + left = left->parent; + } + while (right) { + rightAncestors.push_back(right); + right = right->parent; + } + Q_ASSERT(leftAncestors.back() == m_root && rightAncestors.back() == m_root); + + while (!leftAncestors.empty() && !rightAncestors.empty() && leftAncestors.back() == rightAncestors.back()) { + leftAncestors.pop_back(); + rightAncestors.pop_back(); + } + + if (!leftAncestors.empty()) + return (leftAncestors.back() == leftAncestors.back()->parent->left ? -1 : 1); + + if (!rightAncestors.empty()) + return (rightAncestors.back() == rightAncestors.back()->parent->right ? -1 : 1); + + // The code should never reach this point. + Q_ASSERT(!leftAncestors.empty() || !rightAncestors.empty()); + return 0; +} + +#endif // GLDRBTREE_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDResourceDef.h b/GCR/trunk/Glodon/include/GLD/GLDResourceDef.h new file mode 100644 index 00000000..cd028eb6 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDResourceDef.h @@ -0,0 +1,52 @@ +#ifndef GLDRESOURCEDEF +#define GLDRESOURCEDEF +#include "GLDWidget_Global.h" + +#define DEF_RESOURCESTRING(name, value) extern const GString name +#define DEF_RESOURCESTRING2(name) extern const char *name +#define DEF_RESOURCESTRING3(name, value) extern const char *name +#define DEF_RESOURCESTRING4(name) extern const GString name +#define DEF_RESOURCESTRING5(name) extern GLDCOMMONSHARED_EXPORT const char *name +//#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) +//# define TRANS_STRING(value) GString::fromLocal8Bit(value) +//#else +# if defined(WIN32) || defined(WIN64) +# define GStringLiteral(str) QStringLiteral(str) +# elif defined(__APPLE__) +# define GStringLiteral(str) gbkToUnicode(str) +# else +# define GStringLiteral(str) gbkToUnicode(str) +# endif //WIN32 +# define TRANS_STRING(value) GStringLiteral(value) +//#endif + +//#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) +//# define DEFINE_RESOURCESTRING(name, value) const GString name = GString::fromLocal8Bit(value) +//#else +# define DEFINE_RESOURCESTRING(name, value) const GString name = TRANS_STRING(value) +//#endif + +#define DEF_CONSTSTRING(name, value) extern const GString name +//#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) +//# define DEFINE_CONSTSTRING(name, value) static GString name = GString::fromLocal8Bit(value) +//#else +# define DEFINE_CONSTSTRING(name, value) const GString name = TRANS_STRING(value) +//#endif + +//#ifdef QT_NO_DEPRECATED +//# define GLD_DECLARE_DEPRECATED_TR_FUNCTIONS(context) +//#else +# define GLD_DECLARE_DEPRECATED_TR_FUNCTIONS(context) \ + QT_DEPRECATED static inline GString trUtf8(const char *sourceText, const char *disambiguation = 0, int n = -1) \ + { return QCoreApplication::translate(#context, sourceText, disambiguation, n); } +//#endif + +#define GLD_DECLARE_TR_FUNCTIONS(context) \ +public: \ + static inline GString tr(const char *sourceText, const char *disambiguation = 0, int n = -1) \ + { return QCoreApplication::translate(#context, sourceText, disambiguation, n); } \ + GLD_DECLARE_DEPRECATED_TR_FUNCTIONS(context) \ +private: + +#endif // GLDRESOURCEDEF + diff --git a/GCR/trunk/Glodon/include/GLD/GLDRunnable.h b/GCR/trunk/Glodon/include/GLD/GLDRunnable.h new file mode 100644 index 00000000..e7b2c994 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDRunnable.h @@ -0,0 +1,9 @@ +#ifndef GLDRUNNABLE +#define GLDRUNNABLE + +#include + +typedef QRunnable GRunnable; + +#endif // GLDRUNNABLE + diff --git a/GCR/trunk/Glodon/include/GLD/GLDSHA1.h b/GCR/trunk/Glodon/include/GLD/GLDSHA1.h new file mode 100644 index 00000000..e097cdd6 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDSHA1.h @@ -0,0 +1,21 @@ +#ifndef GLDSHA1_H +#define GLDSHA1_H + +#include "GLDCrypt_Global.h" +#include "GLDString.h" +#include "GLDIODevice.h" +#include "GLDSystem.h" +#include "GLDCrypt_Global.h" + +GLDCRYPTSHARED_EXPORT GString getSHA1(const unsigned char *buffer, size_t bufSize); +GLDCRYPTSHARED_EXPORT GString getSHA1(GStream *stream); + +struct SHA1Digest +{ + byte bytes[20]; +}; + +GLDCRYPTSHARED_EXPORT void SHA1HashBuffer(SHA1Digest &digest, const unsigned char *buffer, size_t bufSize); +GLDCRYPTSHARED_EXPORT void SHA1HashStream(SHA1Digest &digest, GStream *stream); + +#endif // GLDSHA1_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDScopeExit.h b/GCR/trunk/Glodon/include/GLD/GLDScopeExit.h new file mode 100644 index 00000000..48f2bcc5 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDScopeExit.h @@ -0,0 +1,54 @@ +/*! + * @file GLDScopeExit.h + * + * Copyright (C) 1998-2015 Glodon Corporation + * + * @author xg + * @date 2015/04/17 + * @version v 1.0.0.0 + * @brief 退出作用域进行的操作 + * 使用方式如下, 当退出作用域(即作用域结束)时会调用到 delete pInt; 语句释放内存 + * //!在下面的作用域 + * {//作用域开始 + * int *pInt = new int(0); + * GLD_SCOPEEXIT + * { + * delete pInt; + * pInt = nullptr; + * }; + * }//作用域结束 + */ +#ifndef __D47C9781_7DE3_4B0E_897B_AC02646636FA_GLDSCOPEEXIT_H__ +#define __D47C9781_7DE3_4B0E_897B_AC02646636FA_GLDSCOPEEXIT_H__ + +template +class GLDScopeGuard +{ +public: + GLDScopeGuard(ReleaseFun fun) + : m_releaseFun(fun) + {} + ~GLDScopeGuard() + { + m_releaseFun(); + } + +private: + ReleaseFun m_releaseFun; +}; + +class GLDScopeGuardOnExit{}; +template +GLDScopeGuard operator+(GLDScopeGuardOnExit, ReleaseFun &&fn) +{ + return GLDScopeGuard(fn); +} + +#define _GLD_JOINT(s1, s2) s1##s2 +#define GLD_JOINT(s1, s2) _GLD_JOINT(s1, s2) +#define GLD_VARIABLE(str) GLD_JOINT(str, __LINE__) + +#define GLD_SCOPEEXIT \ + auto GLD_VARIABLE(SCOPE_EXIT_STATE) = GLDScopeGuardOnExit() + [&]() + +#endif /* __D47C9781_7DE3_4B0E_897B_AC02646636FA_GLDSCOPEEXIT_H__ */ diff --git a/GCR/trunk/Glodon/include/GLD/GLDScrollStyle.h b/GCR/trunk/Glodon/include/GLD/GLDScrollStyle.h new file mode 100644 index 00000000..46d1b1b7 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDScrollStyle.h @@ -0,0 +1,121 @@ +#ifndef GLDSCROLLSTYLE_H +#define GLDSCROLLSTYLE_H + +#include +#include "GLDWidget_Global.h" + +class GLDWIDGETSHARED_EXPORT GLDScrollStyle: public QProxyStyle +{ +public: + explicit GLDScrollStyle(QObject *parent, bool isSubControl = true); + ~GLDScrollStyle(); + +public: + inline void setIsShowArrow(bool isShow = false) { m_isShowArrow = isShow; } + inline bool isShowArrow() { return m_isShowArrow; } + void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, + QPainter *painter, const QWidget *widget) const; + int pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const; + QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, + SubControl sc, const QWidget *widget) const; + + /** + * @brief setHandleColor 设置滚柄默认颜色 + * @param handleColor + */ + inline void setHandleColor(const QColor &handleColor) { m_scrollBarHandleColor = handleColor; } + + /** + * @brief handleColor 滚柄默认颜色 + * @return + */ + inline QColor handleColor() const { return m_scrollBarHandleColor; } + + /** + * @brief setHandleHoverColor 设置鼠标划过时滚柄的颜色 + * @param handleHoverColor + */ + inline void setHandleHoverColor(const QColor &handleHoverColor) { m_scrollBarHandleHoverColor = handleHoverColor; } + + /** + * @brief handHoverColor 鼠标划过时滚柄的颜色 + * @return + */ + inline QColor handHoverColor() const { return m_scrollBarHandleHoverColor; } + + /** + * @brief setTrackColor 设置轨道默认颜色 + * @param trackColor + */ + inline void setTrackColor(const QColor &trackColor) { m_scrollBarTrackColor = trackColor; } + + /** + * @brief trackColor 轨道默认颜色 + * @return + */ + inline QColor trackColor() const { return m_scrollBarTrackColor; } + + /** + * @brief setTrackHoverColor 设置鼠标划过时轨道的颜色 + * @param trackHoverColor + */ + inline void setTrackHoverColor(const QColor &trackHoverColor) { m_scrollBarTrackHoverColor = trackHoverColor; } + + /** + * @brief trackHoverColor 鼠标划过时轨道的颜色 + * @return + */ + inline QColor trackHoverColor() const { return m_scrollBarTrackHoverColor; } + +private: + void loadStyleIniFile(const QString &path = ":/inis/scrollstyle.ini"); + void initScrollBar( + const QStyleOptionComplex * option, + const QWidget * widget, + QPainter * painter, + bool bMouseOver, + bool bHorizontal, + bool bIsMaxOut + ) const; + void getScrollBarColors(QColor &startColor, QColor &middleColor, + QColor &endColor, bool bMouseOver) const; + + void drawBackground(QRect drawRect, QPainter *painter, bool bMouseOver, bool bHorizontal) const; + void drawScrollbar(ComplexControl control, const QStyleOptionComplex *option, + QPainter *painter, const QWidget *widget) const; + void drawScrollBarAddLine(const QStyleOptionComplex *option, + QPainter *painter, const QWidget *widget, + bool bMouseOver, bool bHorizontal) const; + void drawScrollBarSubLine(const QStyleOptionComplex *option, + QPainter *painter, const QWidget *widget, + bool bMouseOver, bool bHorizontal) const; + void drawScrollBarGroove(const QStyleOptionComplex *option, + QPainter *painter, const QWidget *widget, + bool bMouseOver, bool bHorizontal) const; + void drawArrows(QPainter *painter, QRect drawRectAdd, QRect drawRectSub, + Qt::Orientation Direct, bool bMouseOver) const; + void drawSlider(QStyle::SubControls sc, QPainter *painter, + const QStyleOptionComplex *option, const QWidget *widget, + bool bHorizontal) const; + +private: + bool m_isShowArrow; + bool m_bFirstLoad; + int m_nSliderMinLength; + int m_nSliderSize; + int m_nArrowWidth; + int m_nArrowHeight; + int m_nSliderX; + int m_nSliderY; + int m_nArrowX; + int m_nArrowY; + int m_nSubSliderMinLength; + int m_nSliderAddOffset; + int m_nSliderSubOffset; + + QColor m_scrollBarHandleColor; // 滚动条滚柄的默认颜色 + QColor m_scrollBarHandleHoverColor; // 鼠标划过滚柄时的颜色 + QColor m_scrollBarTrackColor; // 滚动条轨道的默认颜色 + QColor m_scrollBarTrackHoverColor; // 鼠标划过轨道时的颜色 +}; +#endif // GLDSCROLLSTYLE_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDSearchEdit.h b/GCR/trunk/Glodon/include/GLD/GLDSearchEdit.h new file mode 100644 index 00000000..a583a0a5 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDSearchEdit.h @@ -0,0 +1,75 @@ +#ifndef GLDSEARCHEDIT_H +#define GLDSEARCHEDIT_H + +#include +#include +#include +#include +#include "GLDWidget_Global.h" + +class QCompleter; +class QResizeEvent; +class QMouseEvent; +class GLDSearchButton; + +class GLDWIDGETSHARED_EXPORT GLDSearchEdit : public QLineEdit +{ + Q_OBJECT + Q_PROPERTY(bool hasFocus READ hasFocus) +public: + GLDSearchEdit(QWidget *parent = 0); + ~GLDSearchEdit(); + +public: + void setRecentSearchs(QStringList &recentSearchs); + QStringList& recentSearchs(); + + bool hasFocus(); + +protected: + bool event(QEvent *e); + void resizeEvent(QResizeEvent *e); + void mousePressEvent(QMouseEvent *e); + +private: + void initButton(); + void initTipsView(); + void moveRecentTipsView(); + +private slots: + void onTextChange(const QString &); + void onButtonClick(); + void onEditingFinished(); + void onRecentTipsSelected(const QModelIndex &index); + +private: + GLDSearchButton *m_pSearchAndClearButton; + QStringList m_oRecentSearchs; + QCompleter *m_pRecentCompleter; + QString m_sQss; +}; + +class GLDWIDGETSHARED_EXPORT GLDSearchButton : public QPushButton +{ + Q_OBJECT + Q_PROPERTY(bool searching READ searching WRITE setSearching) + Q_PROPERTY(bool hasFocus READ hasFocus WRITE setHasFocus) +public: + GLDSearchButton(QWidget *parent = 0); + ~GLDSearchButton(); + +public: + void setSearching(bool searching); + bool searching(); + + void setHasFocus(bool value); + bool hasFocus(); + +protected: + bool event(QEvent *e); + +private: + bool m_bSearching; + bool m_bHasFocus; // Edit框是否有focus +}; +#endif // GLDSEARCHEDIT_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDSettings.h b/GCR/trunk/Glodon/include/GLD/GLDSettings.h new file mode 100644 index 00000000..204a1840 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDSettings.h @@ -0,0 +1,9 @@ +#ifndef GLDSETTINGS +#define GLDSETTINGS + +#include + +typedef QSettings GSettings; + +#endif // GLDSETTINGS + diff --git a/GCR/trunk/Glodon/include/GLD/GLDShadow.h b/GCR/trunk/Glodon/include/GLD/GLDShadow.h new file mode 100644 index 00000000..cf4cb95c --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDShadow.h @@ -0,0 +1,53 @@ +#ifndef GLDSHADOW_H +#define GLDSHADOW_H + +#include +#include +#include "GLDWidget_Global.h" + +class GLDWIDGETSHARED_EXPORT GLDShadow : public QObject +{ + class GLDShadowWidget : public QWidget + { + public: + explicit GLDShadowWidget(QWidget *parent = 0); + + protected: + bool event(QEvent *e); + }; + +public: + explicit GLDShadow(QWidget* parent = 0); + +public: + void removeShadow(); + +protected: + bool eventFilter(QObject *object, QEvent *event); + +private: + bool addShadow(QWidget *popup); + bool addShadow(QComboBox *popup); + void doRemoveShadow(); + /** + * @brief 拉伸容器,只适用于固定大小的容器 + * + * @fn extendWidth + * @param container 被拉伸的容器指针 + */ + void extendWidth(QWidget *container); + + /** + * @brief 还原容器大小,以免下次出现黑边 + * + * @fn doViewHide + * @param container + */ + void doViewHide(QWidget *container); + void paintShadow(QWidget *container); + +private: + bool m_bHandleResize; + QWidget *m_parent; +}; +#endif // GLDSHADOW_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDShellComboBoxEx.h b/GCR/trunk/Glodon/include/GLD/GLDShellComboBoxEx.h new file mode 100644 index 00000000..d7b029f0 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDShellComboBoxEx.h @@ -0,0 +1,189 @@ +/**** + * @file : GLDShellComboBoxEx.h + * @brief : 可以美化的GLDShellComboBox + * 需要注意cpp文件中的strShowComboBox、strComboBoxProp、strIsLineEdit + * 可以设置是否单行显示,默认为单行显示,使用setEditToLineEdit方法可以更改 + * 可以设置是否显示编辑框图标,默认为不显示 + * + * 可以自定义图标,在QSS的注释中,以下面字符串开头,紧接上对应图标的路径,随后换行 + * "QFileIconProviderComputer" + * "QFileIconProviderDesktop" + * "QFileIconProviderTrashcan" + * "QFileIconProviderNetwork" + * "QFileIconProviderDrive" + * "QFileIconProviderFolder" + * "QFileIconProviderFile"; + * + * 同样的方法可以自定义文件列表中的字体颜色,“RootColor”对应第一级节点(磁盘), + * "OthersColor"对应剩余的节点 + * + * @date : 2014-08-16 + * @author : chenyp-a + * @remarks: + ****/ +#ifndef GLDSHELLCOMBOBOXNOLINEICON_H +#define GLDSHELLCOMBOBOXNOLINEICON_H + +#include +#include + +#include "GLDShellWidgets.h" +#include "GLDTextEdit.h" +#include "GLDFileSystemModel.h" +#include "GLDWidget_Global.h" + +class GLDShellTreeViewEx; +class GLDFileSystemModelEX; +class GLDShellComboBoxItemDelegate; +class GLDFileIconProvider; +class GLDShellComboBoxEx; + +class GLDWIDGETSHARED_EXPORT GLDShellComboBoxItemDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + explicit GLDShellComboBoxItemDelegate(const QString &rootPath = QString(), QWidget *parent = 0); + +public: + QPixmap pixmap(const QModelIndex &index)const; + void setTreeView(GLDShellTreeViewEx *treeView); + void setFileSystemModel(GLDFileSystemModelEX *model); + void setExpandedIndex(const QModelIndex &index); + bool isParentExpandedRecently(const QModelIndex &index) const; + virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; + +protected: + void paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const; + +private: + QModelIndex findLonelyExpanded(const QModelIndex &root); + QPixmap icon(const QModelIndex &index); + +private slots: + void doAfterExpanded(const QModelIndex &index); + void doAfterCollapsed(const QModelIndex &index); + +private: + GLDShellTreeViewEx *m_treeView; + GLDFileSystemModelEX *m_model; + QModelIndex m_indexExpanded; +}; + +class GLDWIDGETSHARED_EXPORT GLDFileIconProvider : public QFileIconProvider +{ +public: + GLDFileIconProvider(); + virtual ~GLDFileIconProvider(); + +public: + virtual QIcon icon(IconType type) const; + virtual QIcon icon(const QFileInfo & info) const; + void loadIcon(QMap mapURL); + void loadSetting(const QString &setting); + +private: + QMap m_map_icon; +}; + +class GLDWIDGETSHARED_EXPORT GLDFileSystemModelEX : public GLDFileSystemModel +{ + Q_OBJECT +public: + explicit GLDFileSystemModelEX(bool includingFile = false, QObject *parent = 0); + ~GLDFileSystemModelEX(); + +public: + QVariant data(const QModelIndex &index, int role) const; + QIcon fileIcon(const QModelIndex &index) const; + QColor fileNameColor(const QModelIndex &index) const; + void setFontColor(const QString &setting); + inline void setDelegate(GLDShellComboBoxItemDelegate *delegate){ m_delegate = delegate; } + +protected: + GLDFileSystemModelEX(const QStringList &nameFilters, QDir::Filters filters, + QDir::SortFlags sort, QObject *parent = 0); + GLDFileSystemModelEX(GLDFileSystemModelPrivate &model, QObject *parent = 0); + +private: + QColor m_colorRoot; + QColor m_colorOthers; + GLDShellComboBoxItemDelegate *m_delegate; + GLDFileIconProvider *m_pIconProvider; + + Q_DECLARE_PRIVATE(GLDFileSystemModel) +}; + +/** + * @brief + * + * @class GLDShellComboBoxEx + */ +class GLDWIDGETSHARED_EXPORT GLDShellComboBoxEx : public GLDShellComboBox +{ + Q_OBJECT +public: + explicit GLDShellComboBoxEx(const QString &rootPath = QString(), QWidget *parent = 0); + +public: + void init(const QString &rootPath); + void setHasBorder(bool bHasBorder); + void setEditProperty(bool bShow); + void setFileModel(GLDCustomFileSystemModel *model); + + /*! + * \brief setShellListView + * \param 设置联动的GLDShellListView + *@warning 只能关联一个list + */ + void setShellListView(GLDShellListView *list); + +protected: + void paintEvent(QPaintEvent *event); + void resizeEvent(QResizeEvent *event); + bool eventFilter(QObject *object, QEvent *event); + void autoSetContainerHeight(); + void keyPressEvent(QKeyEvent *event); + void updateEditFieldGeometry(); + +signals: + void onHide(); + void shouldShowPopup(bool &value); + void afterPopupShowed();//信号,下拉框被显示 + void afterPopupHid();//信号,下拉框被隐藏 + void cursorPositionChanged(); + void expanded(const QModelIndex &index); + void collapsed(const QModelIndex &index); + +private slots: + void onSignalOnHide(); + void onShouldShowPopup(bool &value); + void doAfterEditCursorChanged(); + void doAfterExpanded(const QModelIndex &index); + void doAfterCollapsed(const QModelIndex &index); + +private: + void initConnection(); + void installEventFilters(); + void initShadow(); + void initFileModel(const QString &rootPath); + void initTreeView(QModelIndex pathIndex); + void initTreeViewIndentation(); + void initDelegate(GLDShellTreeViewEx *pTreeView); + void initPopupFlags(); + +private: + bool m_bIsShow; /** 下来框是否显示*/ + bool m_bIsLineEdit; /** 编辑框是否为行编辑框*/ + bool m_bIsShowIcon;/** 是否显示编辑框图标*/ + bool m_bIsDefaultIcon;/** 是否使用默认图标*/ + bool m_bIsDrag; + bool m_bIsPopMove; + int m_nCanSetCursor; + bool m_bHasShadow; + QString m_text; + GLDShellComboBoxItemDelegate *m_delegate; +}; + +#endif // GLDSHELLCOMBOBOXNOLINEICON_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDShellTreeViewEx.h b/GCR/trunk/Glodon/include/GLD/GLDShellTreeViewEx.h new file mode 100644 index 00000000..d56d6925 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDShellTreeViewEx.h @@ -0,0 +1,72 @@ +#ifndef GLDFILETREEVIEW_H +#define GLDFILETREEVIEW_H + +#include +#include +#include +#include +#include +#include +#include "GLDShellComboBoxEx.h" +#include "GLDShellWidgets.h" +#include "GLDWidget_Global.h" + + +class GLDWIDGETSHARED_EXPORT GLDShellTreeViewEx : public GLDShellTreeView +{ + Q_OBJECT +public: + explicit GLDShellTreeViewEx(QWidget *parent = 0); + explicit GLDShellTreeViewEx(bool popup, GLDShellComboBox *combo); + ~GLDShellTreeViewEx(); + +public: + //GLDShellComBoBox使用 + QModelIndex point2ModelIndex(const QPoint &pos); + void setModelIndexRect(const QModelIndex &index, const QRect &rect); + int countAllShownRows(); + inline QModelIndex hoverIndex(){ return m_indexHover; } + inline void setHoverIndex(const QModelIndex &index){ m_indexHover = index; } + + void setModel(QAbstractItemModel *model); + QModelIndex expandedIndex()const; + +protected: + void mouseMoveEvent(QMouseEvent *event); + +private slots: + void doAfterExpand(const QModelIndex &index); + void init(); + +private: + int countAllShownRows(const QModelIndex &root); + +private: + QMap m_map_arrowRect; + QModelIndex m_indexHover; + QModelIndex m_expandedIndex; + + friend class GLDShellComboBoxItemDelegate; + friend class GLDShellComboBoxEx; +}; + +class GLDWIDGETSHARED_EXPORT GLDShellTreeDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + GLDShellTreeDelegate(GLDShellTreeViewEx *parent); + + void paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const; +protected: + virtual QColor fontColor(const QModelIndex &index) const; + virtual QPixmap decorationIcon(const QModelIndex &index) const; + +private: + GLDShellTreeViewEx *m_pTreeView; + +}; + +#endif // GLDFILETREEVIEW_H + + diff --git a/GCR/trunk/Glodon/include/GLD/GLDShellWidgets.h b/GCR/trunk/Glodon/include/GLD/GLDShellWidgets.h new file mode 100644 index 00000000..ebb4d801 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDShellWidgets.h @@ -0,0 +1,411 @@ +#ifndef GLDSHELLTREEVIEW_H +#define GLDSHELLTREEVIEW_H + +#include +#include +#include +#include "GLDWidget_Global.h" +#include "GLDListView.h" +#include "GLDWindowComboBox.h" +#include "GLDAbstractItemView.h" + +class QDirModel; +class GLDShellComboBox; +class GLDShellListView; +class QFileSystemModel; +class GLDCustomFileSystemModel; + +class GLDWIDGETSHARED_EXPORT GLDDirFilter +{ +public: + enum DirName{ + RelativeName = 0, + AbsoluteName = 1 + }; + + enum ISDIR{ + ISFOLDER = 0, + ISFILE = 1, + NOITEMSELECTED = 2 + }; + + enum SLASHTYPE{ + FORWORDSLASH = 0, //正斜杠( slash '/' ) + BACKSLASH = 1 //反斜杠( backslash '\') + }; + + //主要是为Tree型,暂开放给单独的GLDShellTreeView使用 + enum TreeRootPolicyFlag{ + ROOTVISIBLESINGLETON = 0x01, //显示当前被设为root的对应的文件/目录所在的上一层目录,并不再显示该目录的兄弟目录 + HIDE = 0x02, //Qt的默认行为。与上一行的行为互斥 + ROOTWITHCURRENT = 0x04, //root跟随current。与下一行的行为互斥 + ROOTSTEADY = 0x08 //root不跟随current,受setRootIndex影响 + }; + Q_DECLARE_FLAGS(TreeRootPolicy, TreeRootPolicyFlag) + + virtual void setNameFilters(const QStringList &filters) = 0; + virtual QStringList nameFilters() const = 0; + virtual QString filePathByType(const QModelIndex ¤tIndex, DirName dirType) const; + virtual ISDIR getTheIndexDirType(const QModelIndex &index, const GLDCustomFileSystemModel *pModel) const; +protected: + virtual void doSetNameFilters(QAbstractItemModel *model, const QStringList &filters); + virtual QStringList doNameFilters(QAbstractItemModel *model) const; +}; + +class GLDWIDGETSHARED_EXPORT GLDShellTreeView : public QTreeView, public GLDDirFilter +{ + Q_OBJECT +public: + explicit GLDShellTreeView(QWidget *parent = 0); + ~GLDShellTreeView(); + + void setModel(QAbstractItemModel *model); + + /*! + * \brief setNameFilters 设置要显示的文件后缀列表,不在其中自动过滤掉 + * \param filters 其子项是形如"*.exe"的字符串,必须满足类似的正则表达 + *@warning 当调用setModel将model设置为其它非QFielSystemModel子类类型的实例对象时,此方法将无效,行为将是未定义的。 + *@see GLDShellComboBox::setNameFilters(const QStringList &filters) + */ + void setNameFilters(const QStringList &filters); + + /*! + * \brief nameFilters 获得当前的文件过滤后缀列表 + * \return + *@see GLDShellComboBox::nameFilters() + */ + QStringList nameFilters() const; + + /*! + * \brief currentPath + * \param dirType: RelativeName:相对路径,一般指文件名或者文件夹名,不包含路径。AbsoluteName:绝对路径名,包含路径 + * \return 路径名,如果没有选中,则返回当前的根结点路径 + */ + QString currentPath(DirName dirType = AbsoluteName, SLASHTYPE xieGang = BACKSLASH) const; + /*! + * \brief isCurrentPathDir + * \return ISFOLDER:当前选中的是文件夹。ISFILE:当前选中的是文件。NOITEMSELECTED:当前未选中项 + */ + ISDIR isCurrentPathDir() const; + + /*! + * \brief setRootWithCombo 当tree与shellcomboBox关联时,此属性决定root是否跟随combo下拉框选中的项而变化 + * \param withCombo + */ + void setRootWithCombo(bool withCombo) { m_bTreeRootWithCombo = withCombo; } + + bool rootWithCombo() const { return m_bTreeRootWithCombo; } + + /*! + * \brief setSingleRoot 兼容delphi版本的单一的根结点样式的显示方式 + * \param singleRoot + */ + void setSingleRoot(bool singleRoot); + bool singleRoot() const; + + void setRootIndex(const QModelIndex &index); + void setRootPath(const QString &path); + + inline bool neverChangeRoot() { return m_neverChangeRoot; } + inline void setNeverChangeRoot(bool value) { m_neverChangeRoot = value; } + + void doItemsLayout(); + + /*! + * \brief 设置当前tree的焦点,可触发联动 + * \param index + */ + void setCurrentIndexPro(const QModelIndex &index); + +signals: + void itemJustBeSelected(const QModelIndex &index); + void itemJustBeDoubleClicked(const QModelIndex &index); + void currentItemJustChanged(const QModelIndex ¤t, const QModelIndex &previous); + +public slots: + void adjustColumnWidth(const QModelIndex &); + +protected slots: + void upToParentDir(const QModelIndex &parentDirIndex); + void slotExpand(QModelIndex index); + void slotCollapse(QModelIndex index); + void setCurrentIndex(const QModelIndex &index); + void shellTreeOwnScrollTo(); +protected: + void mousePressEvent(QMouseEvent *event); + void currentChanged(const QModelIndex ¤t, const QModelIndex &previous); + void showEvent(QShowEvent *e); + + explicit GLDShellTreeView(bool popup, GLDShellComboBox *combo); + virtual void setAssociatedItemView(QAbstractItemView *view); + bool isAssociatedAComboBox() const { return NULL != m_comboBox; } + + QString getIndexFileName(QModelIndex pressedIndex); +private: + void makePreBuddiesVisible(); + void hideBuddiesAndInsertList(const QModelIndex &visibleChild, const QModelIndex &par, int buddyCount); + void makesureBuddyContainerExist(); + void makeRootParentAsRootAndHideBuddies(); + + void setTreeRootMode(TreeRootPolicy rootPolicy = TreeRootPolicy(5)); + inline TreeRootPolicy treeRootMode() { return m_treeRootPolicy; } +private: + DirName m_getPathType; + GLDShellComboBox *m_comboBox; + int m_iFirstShow; + TreeRootPolicy m_treeRootPolicy; + bool m_bTreeRootWithCombo; //暂时替代上面的属性工作 + bool m_bSelfClicked; + bool m_bComboClickeSignal; +// QDirModel *m_pDirModel; + GLDCustomFileSystemModel *m_pDirModel;//m_pFileModel; + QList *m_pHiddenBuddies; //for VISIBLESINGLETON 状态 + QList *m_pHiddenBuddys; //for VISIBLESINGLETON 状态 + QModelIndex m_preRoot; //for VISIBLESINGLETON 状态 + bool m_bSingleRoot; + bool m_bUsingVariant; + bool m_neverChangeRoot; //始终不改变根节点 +private: + Q_DISABLE_COPY(GLDShellTreeView) + friend class GLDShellComboBox; + typedef QTreeView inherit; +}; + +class GLDWIDGETSHARED_EXPORT GLDShellComboBox : public GLDWindowComboBox, public GLDDirFilter +{ +Q_OBJECT +public: + explicit GLDShellComboBox(const QString &rootPath = QString(), QWidget *parent = 0); + virtual ~GLDShellComboBox(); + +public: + /*! + * \brief setShellListView + * \param 设置联动的GLDShellListView + *@warning 只能关联一个list + */ + virtual void setShellListView(GLDShellListView *list); + + /*! + * \brief setShellTreeView + * \param 设置联动的GLDShellTreeView + *@warning 只能关联一个tree + */ + void setShellTreeView(GLDShellTreeView *tree); + + /*! + * \brief setCustomPath 设置用户目录,即指定根文件夹路径。也可不设置,默认是整个磁盘 + * \param rootPath + *@note !! 2014.1.23 直接转调用setCurrentPath + */ + void setCustomPath(const QString &rootPath); + + /*! + * \brief setCurrentPath 设置当前用户目录,即指定当前要定位到的文件夹路径 + * \param currentPath + *@warning currentPath需要在setCustomPath设置的rootPath下。否则请不要调用setCustomPath + *@see 参见GLDShellComboBox::setCustomPath(QString rootPath) + */ + void setCurrentPath(const QString ¤tPath); + + /*! + * \brief setCurrentFile 设置当前用户文件,即指定当前要选中的文件,并且关联的tree定位到该文件所在文件夹。文件处于选中状态 + * \param currentFilePath 需要包含路径 + *@note 直接调用setCurrentFile(),请不要在setCurrentPath()调用后再调用setCurrentFile()。 + */ + void setCurrentFile(const QString ¤tFilePath); + + /*! + * \brief setNameFilters 设置文件后缀名过滤 + * \param filters + *@warning 关联的List与Tree均将使用此过滤,只须此处设置一次。 + *@see GLDShellListView::setNameFilters(const QStringList &filters) + */ + void setNameFilters(const QStringList &filters); + QStringList nameFilters() const; + + /*! + * \brief setDirNameType 设置combo的编辑框中的文件名是否按照绝对路径显示 + * \param type + */ + void setDirNameType(DirName type); + DirName dirNameType() const; + + /*! + * \brief getPathInEdit 获取Edit中显示的路径,若该路径被改动过,为无效的,则返回下拉tree中对应的有效路径 + * \param type 指定要获得的路径的类型。 xieGang 指定要获得的路径中的斜杠类型 + * \return + */ + QString getCurrentPath(DirName type = AbsoluteName, SLASHTYPE xieGang = BACKSLASH) const; + + /*! + * \brief getIndexFilePath + * \param index 指定的QModelIndex,与当前combo关联的tree、list取得的QModelIndex均可。即只要是同一个GLDFileSystemModel下的 + * modelindex均可 + * \param xieGang + * \return + */ + QString getIndexFilePath(const QModelIndex &index, SLASHTYPE xieGang = BACKSLASH) const; + + QString text() const { return getCurrentPath(); } + + void setFileModel(GLDCustomFileSystemModel *model); + + /*! + * \brief 取消点击时更改root的联动 + * \param view外部绑定的控件 + * \return + */ + void disconnectClick(QAbstractItemView *view); +protected slots: + void synToComboAndTree(QModelIndex clickedIndex); + void synToComboAndList(QModelIndex clickedIndex); + +protected: + virtual void doAfterResize(); + QIcon itemIcon(const QModelIndex &index, const QAbstractItemModel *model); + void setEditTextByIndex(QModelIndex curIndex); + + void expandTreeTo(QModelIndex path); + void locateListTo(QModelIndex path); + void resizeEvent(QResizeEvent *event); + void paintEvent(QPaintEvent *event); + +public: + void setChildrenRootIndex(QModelIndex path); + void init(const QString &rootPath); + + //popup中的tree + GLDShellTreeView *m_popupShellTree; + //关联的其它单独的控件 + GLDShellListView *m_shellListView; + GLDShellTreeView *m_shellTreeView; + GLDCustomFileSystemModel *m_pFileModel; + bool m_showFullPath; + bool m_currentPathSetted; + +private: + Q_DISABLE_COPY(GLDShellComboBox) + friend class GLDShellTreeView; +}; + +class GLDWIDGETSHARED_EXPORT GLDShellHeaderView : public QHeaderView +{ + Q_OBJECT +public: + explicit GLDShellHeaderView(QWidget *parent = 0); + ~GLDShellHeaderView(); + void setSection0AutoResize(); + void setSectionsHiddenExcept0(); + +private: + Q_DISABLE_COPY(GLDShellHeaderView) +}; + +/*! + *@brief The GLDShellListView class + *@note :使用基类的slot作为选中与双击的信号,并连接自己的槽 + */ +class GLDWIDGETSHARED_EXPORT GLDShellListView : public GLDListView, public GLDDirFilter +{ + Q_OBJECT +public: + explicit GLDShellListView(QWidget *parent = 0); + ~GLDShellListView(){freeAndNil(commentFrame);} + + /*! + * \brief setCustomPath + * \param rootPath 指定顶层路径 + */ + virtual void setCustomPath(QString rootPath); + + /*! + * \brief currentPath + * \param dirType: RelativeName:相对路径,一般指文件名或者文件夹名,不包含路径。AbsoluteName:绝对路径名,包含路径 + * \return 路径名,如果没有选中,则返回当前的根结点路径 + */ + QString currentPath(DirName dirType = AbsoluteName, SLASHTYPE defType = BACKSLASH) const; + + /*! + * \brief isCurrentPathDir + * \return ISFOLDER:当前选中的是文件夹。ISFILE:当前选中的是文件。NOITEMSELECTED:当前未选中项 + */ + ISDIR isCurrentPathDir() const; + + /*! + * \brief upToParentIndex + * \return 向上层移动,并返回是否成功 + */ + bool upToParentDir(); + + /*! + * \brief setHintBeShown 设置是否显示提示小框。默认提示 + * \param show + */ + void setHintBeShown(bool show){m_bShowHint = show;} + + bool hintBeShown() const{return m_bShowHint;} + + /*! + * \brief setHintExistTime 设置提示小框的自动消失时间,单位:秒。默认2秒 + * \param seconds + */ + void setHintExistTime(int seconds){m_hintExistSeconds = qMax(1, seconds);} + + int hintExistTime() const{return m_hintExistSeconds;} + + /*! + * \brief setOpenFileWhileDoubleClicked 设置是否在双击文件时打开。默认关闭 + * \param openFile + */ + void setOpenFileWhileDoubleClicked(bool openFile){m_bOpenFileWhileDblClk = openFile;} + + bool openFileWhileDoubleClicked() const{return m_bOpenFileWhileDblClk;} + + /*! + * \brief setNameFilters 设置要显示的文件后缀列表 + * \param filters 其子项是形如"*.exe"的字符串 + *@warning 当调用setModel将model设置为其它非QFielSystemModel子类类型的实例对象时,此方法将无效,行为将是未定义的。 + */ + void setNameFilters(const QStringList &filters); + + /*! + * \brief nameFilters 获得当前的文件过滤后缀列表 + * \return + */ + QStringList nameFilters() const; + + /*! + * \brief 设置当前路径,为空,则跳转到根节点 add by hanll-a + * \return + */ + void setCurrentPath(const QString &path); + +signals: + void upToDir(const QModelIndex &parentDirIndex); + void rootIndexChanged(const QModelIndex &rootIndex); + +public slots: + void setRootIndex(const QModelIndex &index); + void showHint(const QModelIndex &index); + void mouseDoubleClickSlot(const QModelIndex &index); + +protected: + void mousePressEvent(QMouseEvent *event); + void drawComment(const QPersistentModelIndex &index); + bool adjustChildWidgetPos(QWidget *child); + +protected: + GCommentFrame *commentFrame; + int m_hintExistSeconds; + bool m_bShowHint; + bool m_bFirstShow; + bool m_bOpenFileWhileDblClk; + +private: + Q_DISABLE_COPY(GLDShellListView) + void init(); + friend class GLDShellComboBox; +}; + +#endif // GLDSHELLTREEVIEW_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDSingleInstance.h b/GCR/trunk/Glodon/include/GLD/GLDSingleInstance.h new file mode 100644 index 00000000..1e7da18c --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDSingleInstance.h @@ -0,0 +1,20 @@ +#ifndef GLDSINGLEINSTANCE_H +#define GLDSINGLEINSTANCE_H + +#include +#include "GLDString.h" +#include "GLDGlobal.h" + +class GLDUniqueAppInstancePrivate; +class GLDCOMMONSHARED_EXPORT GLDUniqueAppInstance +{ +public: + GLDUniqueAppInstance(const GString &uniqueKey); + ~GLDUniqueAppInstance(); + bool isRunning(); +private: + GLDUniqueAppInstancePrivate * const d_ptr; + Q_DECLARE_PRIVATE(GLDUniqueAppInstance); +}; + +#endif // GLDSINGLEINSTANCE_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDSortUtils.h b/GCR/trunk/Glodon/include/GLD/GLDSortUtils.h new file mode 100644 index 00000000..bd9f8fd3 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDSortUtils.h @@ -0,0 +1,293 @@ +#ifndef GLDSORTUTILS_H +#define GLDSORTUTILS_H + +#include "GLDVariant.h" +#include "GLDMathUtils.h" +#include "GLDInterfaceObject.h" + +enum GSeekOption +{ + soFirst, // 返回第一条匹配的记录下标 + soLast, // 返回最后一条匹配的记录下标 + soMatch // 返回二分查找时首次匹配的记录下标 +}; + +class GLDCOMMONSHARED_EXPORT CSortCompareEvent +{ +public: + virtual ~CSortCompareEvent() {} + + virtual CompareResult compare(void *item1, void *item2) = 0; +}; + +class GLDCOMMONSHARED_EXPORT ISearchCompareEvent +{ +public: + virtual CompareResult compare(void *item1, const GVariant &keyvalue) = 0; +}; + +inline CompareResult doSortCompare(void *item1, void *item2, CSortCompareEvent *compare, bool ascend) +{ + CompareResult result = compare->compare(item1, item2); + if (!ascend) + { + if (result == crEqual) + { + return result; + } + if (result == crGreaterThan) + { + result = crLessThan; + } + else + { + result = crGreaterThan; + } + } + return result; +} + +template +void merge(GLDVector &source, GLDVector &dest, int low, int mid, int high, CSortCompareEvent *compare, bool ascend) +{ + int nFirst = low; // 第一段的游标 + int nSecnd = mid + 1; // 第二段的游标 + int nResult = low; // 结果的游标 + // 只要在段中存在I和J,则不断进行归并 + while ((nFirst <= mid) && (nSecnd <= high)) + { + if (doSortCompare(source.at(nFirst), source.at(nSecnd), compare, ascend) != crGreaterThan) + { + dest[nResult] = source[nFirst]; + nResult++; + nFirst++; + } + else + { + dest[nResult] = source[nSecnd]; + nResult++; + nSecnd++; + } + } + // 考虑余下的部分 + if (nFirst > mid) + { + for (int i = nSecnd; i <= high; ++i) + { + dest[nResult] = source[i]; + nResult++; + } + } + else + { + for (int i = nFirst; i <= mid; ++i) + { + dest[nResult] = source[i]; + nResult++; + } + } +} + +template +void mergePass(GLDVector &source, GLDVector &dest, int subSection, int n, CSortCompareEvent *compare, bool ascend) +{ + int nIndex = 0; + // 归并两个大小为SubSection的相邻段 + while (nIndex <= n - 2 * subSection) + { + merge(source, dest, nIndex, nIndex + subSection - 1, nIndex + 2 * subSection - 1, compare, ascend); + nIndex = nIndex + 2 * subSection; + } + // 剩下不足两个元素 + if (nIndex + subSection < n) + { + merge(source, dest, nIndex, nIndex + subSection - 1, n - 1, compare, ascend); + } + else // 把最后一段复制到ADest + { + for (int j = nIndex; j <= n - 1; ++j) + { + dest[j] = source[j]; + } + } +} + +template +void doSort(int lowIndex, int highIndex, GLDVector &sortList, CSortCompareEvent *compare, bool ascend) +{ + int nIt1 = 0; + int nIt2 = 0; + PtrInt pInt1 = 0; + PtrInt pInt2 = 0; + do + { + nIt1 = lowIndex; + nIt2 = highIndex; + void *ptr = (sortList.at((lowIndex + highIndex) >> 1)); + pInt1 = (PtrInt)ptr; + do + { + while (doSortCompare(sortList.at(nIt1), (void*)(pInt1), compare, ascend) == crLessThan) + { + nIt1++; + } + while (doSortCompare(sortList.at(nIt2), (void*)(pInt1), compare, ascend) == crGreaterThan) + { + nIt2--; + } + if (nIt1 <= nIt2) + { + pInt2 = PtrInt(sortList.at(nIt1)); + sortList[nIt1] = sortList[nIt2]; + sortList[nIt2] = (T)(pInt2); + nIt1++; + nIt2--; + } + } while (nIt1 <= nIt2); + if (lowIndex < nIt2) + { + doSort(lowIndex, nIt2, sortList, compare, ascend); + } + lowIndex = nIt1; + } while (nIt1 < highIndex); +} + +template +void mergeSort(GLDVector &sortList, CSortCompareEvent *compare, bool ascend = true) +{ + int nSubSection = 1; // 段的大小 + int nCount = sortList.count(); + GLDVector oList; // 用于中间转换的数组列表 + for (int i = 0; i < nCount; i++) + { + oList.push_back(NULL); + } + while (nSubSection < nCount) + { + mergePass(sortList, oList, nSubSection, nCount, compare, ascend); // 从ASource归并到oList + nSubSection = nSubSection << 1; + mergePass(oList, sortList, nSubSection, nCount, compare, ascend); // 从oList归并到ASource + nSubSection = nSubSection << 1; + } +} + +template +void quickSort(GLDVector &sortList, CSortCompareEvent *compare, bool ascend = true) +{ + if (sortList.size() <= 1) + { + return; + } + doSort(0, int(sortList.size()) - 1, sortList, compare, ascend); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.08.29 + 功能:二分法查找 + 参数:searchList -- 查找列表 + compare -- 比较函数 + keyValue -- 键值 + *index -- 返回的匹配项在列表中的下标 + seekOption -- 查找选项 + 返回:是否找到标志 + 说明;假如找不到keyValue对应的项 + 如果seekOption = soFirst,*index值为小于AKeyValue在最近项, + 如果seekOption = soLast,*index值为大于AKeyValue在最近项 +-----------------------------------------------------------------------------*/ +template +bool binSearch(GLDVector &searchList, ISearchCompareEvent *compare, const GVariant &keyValue, long *index, GSeekOption seekOption) +{ + bool result = false; + if (searchList.size() == 0) + { + *index = 0; + return result; + } + int nLow = 0; + int nHigh = int(searchList.size()) - 1; + *index = nHigh; + while (nLow <= nHigh) // 二分法查找 + { + *index = (nLow + nHigh) / 2; + switch (compare->compare(searchList.at(*index), keyValue)) + { + case crLessThan: + nLow = *index + 1; + break; + case crGreaterThan: + nHigh = *index - 1; + break; + default: + result = true; + break; + } + if (result) + { + break; + } + } + + if (!result) // 处理找不到时的位置 + { + switch (seekOption) + { + case soFirst: + if (compare->compare(searchList.at(*index), keyValue) == crGreaterThan) + { + (*index)--; + } + break; + case soLast: + if (compare->compare(searchList.at(*index), keyValue) == crLessThan) + { + (*index)++; + } + break; + default: + break; + } + } + else // 找到匹配项,处理可能多项相同键值的情况 + { + switch (seekOption) + { + case soFirst: // 定位到第一条符合的数据 + { + for (int i = *index-1; i >= 0; i--) + { + if (compare->compare(searchList.at(i), keyValue) == crEqual) + { + *index = i; + } + else + { + break; + } + } + break; + } + case soLast: // 定位到最后一条符合的记录 + { + for (int i = *index + 1; i != searchList.count(); ++i) + { + if (compare->compare(searchList.at(i), keyValue) == crEqual) + { + *index = i; + } + else + { + break; + } + } + break; + } + default: + break; + } + } + return result; +} + +GLDCOMMONSHARED_EXPORT void fast_sort(int *ptr, int begin, int end); + +#endif // GLDSORTUTILS_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDSpinBox.h b/GCR/trunk/Glodon/include/GLD/GLDSpinBox.h new file mode 100644 index 00000000..101c60c3 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDSpinBox.h @@ -0,0 +1,148 @@ +#ifndef GLDDOUBLESPINBOX_H +#define GLDDOUBLESPINBOX_H + +#include +#include +#include +#include "qabstractspinbox.h" +#include "GLDNameSpace.h" +#include "GLDWidget_Global.h" + +G_GLODON_BEGIN_NAMESPACE + +class GLDWIDGETSHARED_EXPORT GLDSpinBox : public QSpinBox +{ + Q_OBJECT + Q_PROPERTY(bool hasSelectedText READ hasSelectedText) +public: + explicit GLDSpinBox(QWidget *parent = 0); + + void setWheelEnable(bool enabled) { m_wheelEnable = enabled; } + inline bool wheelEnabled() const { return m_wheelEnable; } + + void setUpAndDownEnable(bool enabled) { m_upAndDownEnable = enabled; } + inline bool upAndDownEnabled() const {return m_upAndDownEnable;} + + bool hasSelectedText(); + +signals: + void selectionChanged(); + void cursorPositionChanged(); + +public slots: + void cut(); + void copy(); + void paste(); + void deleteSelectedText(); + +protected: + void keyPressEvent(QKeyEvent *event); + void mouseReleaseEvent(QMouseEvent *event); +#ifndef QT_NO_WHEELEVENT + void wheelEvent(QWheelEvent *event); +#endif + +protected: + bool m_wheelEnable; + bool m_upAndDownEnable; + +private slots: + void doSelectionChanged(); + void doCursorPositionChanged(int, int); + +}; + +class GLDWIDGETSHARED_EXPORT GLDDoubleSpinBox : public QDoubleSpinBox +{ + Q_OBJECT + Q_PROPERTY(bool hasSelectedText READ hasSelectedText) +public: + explicit GLDDoubleSpinBox(QWidget *parent = 0); + ~GLDDoubleSpinBox(); +public: + virtual QValidator::State validate(QString &input, int &pos) const; + virtual double valueFromText(const QString &text) const; + virtual QString textFromValue(double val) const; + + inline bool decimalsEnable() const { return m_decimalsEnable; } + void setDecimalsEnable(bool value); + + void setWheelEnable(bool enabled) { m_wheelEnable = enabled; } + inline bool wheelEnabled() const { return m_wheelEnable; } + + void setUpAndDownEnable(bool enabled) { m_upAndDownEnable = enabled; } + inline bool upAndDownEnabled() const {return m_upAndDownEnable;} + + bool hasSelectedText(); +public slots: + void cut(); + void copy(); + void paste(); + void deleteSelectedText(); + +signals: + void selectionChanged(); + void cursorPositionChanged(); + +protected: + void keyPressEvent(QKeyEvent *event); +#ifndef QT_NO_WHEELEVENT + void wheelEvent(QWheelEvent *event); +#endif + //change public to protected + void setDecimals(int prec); + static const int normalDecimals = 15; +private: + +protected: + enum NumberMode { IntegerMode, DoubleStandardMode, DoubleScientificMode }; + +private: + bool m_decimalsEnable; + bool m_wheelEnable; + bool m_upAndDownEnable; + int m_orgDecimals; + mutable QDoubleValidator *m_validator; + +private slots: + void doSelectionChanged(); + void doCursorPositionChanged(int, int); +}; + +class GLDWIDGETSHARED_EXPORT GLDSpinBoxEx : public GLDSpinBox +{ + Q_OBJECT +public: + explicit GLDSpinBoxEx(QWidget *parent = 0); + ~GLDSpinBoxEx(){} + +public: + void setHasBorder(bool bHasBorder); + +protected: + void enterEvent(QEvent *event); + void leaveEvent(QEvent *event); + void resizeEvent(QResizeEvent *event); + void updateEditFieldGeometry(); +}; + +class GLDWIDGETSHARED_EXPORT GLDDoubleSpinBoxEx : public GLDDoubleSpinBox +{ + Q_OBJECT +public: + explicit GLDDoubleSpinBoxEx(QWidget *parent = 0); + ~GLDDoubleSpinBoxEx(){} + +public: + void setHasBorder(bool bHasBorder); + +protected: + void enterEvent(QEvent *event); + void leaveEvent(QEvent *event); + void resizeEvent(QResizeEvent *event); + void updateEditFieldGeometry(); +}; + +G_GLODON_END_NAMESPACE + +#endif // GLDDOUBLESPINBOX_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDSplitter.h b/GCR/trunk/Glodon/include/GLD/GLDSplitter.h new file mode 100644 index 00000000..e01d84bf --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDSplitter.h @@ -0,0 +1,143 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtWidgets module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef GLDSPLITTER_H +#define GLDSPLITTER_H + +#include + +#include "GLDNameSpace.h" +#include "GLDSplitterHandle.h" +#include "GLDWidget_Global.h" + +#ifndef QT_NO_SPLITTER + +class GLDSplitterPrivate; +class QTextStream; +class GLDSplitterHandle; + +class GLDWIDGETSHARED_EXPORT GLDSplitter : public QFrame +{ + Q_OBJECT + + Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation) + Q_PROPERTY(bool opaqueResize READ opaqueResize WRITE setOpaqueResize) + Q_PROPERTY(int handleWidth READ handleWidth WRITE setHandleWidth) + Q_PROPERTY(bool childrenCollapsible READ childrenCollapsible WRITE setChildrenCollapsible) + +public: + explicit GLDSplitter(QWidget *parent = 0); + explicit GLDSplitter(Qt::Orientation, QWidget *parent = 0); + ~GLDSplitter(); + +public: + void setOrientation(Qt::Orientation); + Qt::Orientation orientation() const; + + void setChildrenCollapsible(bool); + bool childrenCollapsible() const; + + void setCollapsible(int index, bool); + bool isCollapsible(int index) const; + + void setOpaqueResize(bool opaque = true); + bool opaqueResize() const; + +public: + void addWidget(QWidget *widget); + void insertWidget(int index, QWidget *widget); + void refresh(); + + QSize sizeHint() const; + QSize minimumSizeHint() const; + + QList sizes() const; + void setSizes(const QList &list); + + QByteArray saveState() const; + bool restoreState(const QByteArray &state); + + int handleWidth() const; + void setHandleWidth(int); + + int collapsedLength() const; + void setCollapsedLength(int length); + + int indexOf(QWidget *w) const; + QWidget *widget(int index) const; + int count() const; + + void getRange(int index, int *, int *) const; + GLDSplitterHandle *handle(int index) const; + + void setStretchFactor(int index, int stretch); + +Q_SIGNALS: + void splitterMoved(int pos, int index); + +protected: + virtual GLDSplitterHandle *createHandle(); + + void childEvent(QChildEvent *); + void resizeEvent(QResizeEvent *); + void changeEvent(QEvent *); + + bool event(QEvent *); + + void moveSplitter(int pos, int index); + void setRubberBand(int position); + + int closestLegalPosition(int, int); + +private: + Q_DISABLE_COPY(GLDSplitter) + Q_DECLARE_PRIVATE(GLDSplitter) + +private: + friend class GLDSplitterHandle; +}; + +QTextStream &operator<<(QTextStream &, const GLDSplitter &); +QTextStream &operator>>(QTextStream &, GLDSplitter &); + +#endif // QT_NO_SPLITTER + +#endif // QSPLITTER_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDSplitterHandle.h b/GCR/trunk/Glodon/include/GLD/GLDSplitterHandle.h new file mode 100644 index 00000000..05840503 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDSplitterHandle.h @@ -0,0 +1,42 @@ +#ifndef GLDSPLITTERHANDLE_H +#define GLDSPLITTERHANDLE_H + +#include + +class GLDSplitter; +class GLDSplitterHandlePrivate; +#include "GLDWidget_Global.h" + +class GLDWIDGETSHARED_EXPORT GLDSplitterHandle : public QWidget +{ + Q_OBJECT +public: + explicit GLDSplitterHandle(Qt::Orientation o, GLDSplitter *parent); + ~GLDSplitterHandle(); + + void setOrientation(Qt::Orientation o); + Qt::Orientation orientation() const; + + bool opaqueResize() const; + GLDSplitter *splitter() const; + + QSize sizeHint() const; + +protected: + void paintEvent(QPaintEvent *); + void mouseMoveEvent(QMouseEvent *); + void mousePressEvent(QMouseEvent *); + void mouseReleaseEvent(QMouseEvent *); + void resizeEvent(QResizeEvent *); + void moveSplitter(int p); + + bool event(QEvent *); + + int closestLegalPosition(int p); + +private: + Q_DISABLE_COPY(GLDSplitterHandle) + Q_DECLARE_PRIVATE(GLDSplitterHandle) +}; + +#endif // GLDSPLITTERHANDLE_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDSplitter_p.h b/GCR/trunk/Glodon/include/GLD/GLDSplitter_p.h new file mode 100644 index 00000000..57c61401 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDSplitter_p.h @@ -0,0 +1,185 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtWidgets module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSPLITTER_P_H +#define QSPLITTER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// It is copied from qt5.1.1/qsplitter_p.h by chenq-a for GLDNetScapeSpliter +// at 2014/6/19. +// We mean it. +// + +#include +#include "private/qwidget_p.h" +#include "qrubberband.h" +#include "GLDNameSpace.h" + +//G_GLODON_BEGIN_NAMESPACE + +template class QList; + +#define GLD_DECLARE_PUBLIC(Class) \ + inline Class* q_func() { return static_cast(q_ptr); } \ + inline const Class* q_func() const { return static_cast(q_ptr); } \ + friend class Class; + +static const uint Default = 2; + +class QFramePrivate : public QWidgetPrivate +{ +// GLD_DECLARE_PUBLIC(QFrame) +public: + QFramePrivate() : frect(QRect(0, 0, 0, 0)), frameStyle(QFrame::NoFrame | QFrame::Plain), + lineWidth(1), midLineWidth(0), frameWidth(0), leftFrameWidth(0), rightFrameWidth(0), + topFrameWidth(0), bottomFrameWidth(0){} + + void updateFrameWidth(){} + void updateStyledFrameWidths(){} + + QRect frect; + int frameStyle; + short lineWidth; + short midLineWidth; + short frameWidth; + short leftFrameWidth, rightFrameWidth; + short topFrameWidth, bottomFrameWidth; + + inline void init() { setLayoutItemMargins(QStyle::SE_FrameLayoutItem); } + +}; +class GLDSplitterHandle; +class GLDSplitterLayoutStruct +{ +public: + QRect rect; + int sizer; + uint collapsed : 1; + uint collapsible : 2; + QWidget *widget; + GLDSplitterHandle *handle; + + GLDSplitterLayoutStruct() : sizer(-1), collapsed(false), collapsible(Default), widget(0), handle(0) {} + ~GLDSplitterLayoutStruct() { delete handle; } + int getWidgetSize(Qt::Orientation orient); + int getHandleSize(Qt::Orientation orient); + int pick(const QSize &size, Qt::Orientation orient) + { return (orient == Qt::Horizontal) ? size.width() : size.height(); } +}; + +class GLDSplitter; +class GLDSplitterPrivate : public QFramePrivate +{ + GLD_DECLARE_PUBLIC(GLDSplitter) +public: + GLDSplitterPrivate() : rubberBand(0), opaque(true), firstShow(true), + childrenCollapsible(true), compatMode(false), handleWidth(-1), collapsedLength(-1), blockChildAdd(false) {} + + QPointer rubberBand; + mutable QList list; + Qt::Orientation orient; + bool opaque : 8; + bool firstShow : 8; + bool childrenCollapsible : 8; + bool compatMode : 8; + int handleWidth; + int collapsedLength; + bool blockChildAdd; + + inline int pick(const QPoint &pos) const + { return orient == Qt::Horizontal ? pos.x() : pos.y(); } + inline int pick(const QSize &s) const + { return orient == Qt::Horizontal ? s.width() : s.height(); } + + inline int trans(const QPoint &pos) const + { return orient == Qt::Vertical ? pos.x() : pos.y(); } + inline int trans(const QSize &s) const + { return orient == Qt::Vertical ? s.width() : s.height(); } + + void init(); + void recalc(bool update = false); + void doResize(const QList* pSizes = 0); + void storeSizes(); + void getRange(int index, int *, int *, int *, int *) const; + void addContribution(int, int *, int *, bool) const; + int adjustPos(int, int, int *, int *, int *, int *) const; + bool collapsible(GLDSplitterLayoutStruct *) const; + bool collapsible(int index) const + { return (index < 0 || index >= list.size()) ? true : collapsible(list.at(index)); } + GLDSplitterLayoutStruct *findWidget(QWidget *) const; + void insertWidget_helper(int index, QWidget *widget, bool show); + GLDSplitterLayoutStruct *insertWidget(int index, QWidget *); + void doMove(bool backwards, int pos, int index, int delta, + bool mayCollapse, int *positions, int *widths); + void setGeo(GLDSplitterLayoutStruct *s, int pos, int size, bool allowCollapse); + int findWidgetJustBeforeOrJustAfter(int index, int delta, int &collapsibleSize) const; + void updateHandles(); + void setSizes_helper(const QList &sizes, bool clampNegativeSize = false); + +}; + +class GLDSplitterHandlePrivate : public QWidgetPrivate +{ + GLD_DECLARE_PUBLIC(GLDSplitterHandle) +public: + GLDSplitterHandlePrivate() : s(0), orient(Qt::Horizontal), mouseOffset(0), opaq(false), hover(false), pressed(false) + {} + + inline int pick(const QPoint &pos) const + { return orient == Qt::Horizontal ? pos.x() : pos.y(); } + + GLDSplitter *s; + Qt::Orientation orient; + int mouseOffset; + bool opaq : 1; + bool hover : 1; + bool pressed : 1; +}; + +//G_GLODON_END_NAMESPACE + +#endif diff --git a/GCR/trunk/Glodon/include/GLD/GLDStack.h b/GCR/trunk/Glodon/include/GLD/GLDStack.h new file mode 100644 index 00000000..31957c6f --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDStack.h @@ -0,0 +1,19 @@ +#ifndef GLDSTACK_H +#define GLDSTACK_H + +#include +#include + +using namespace std; + +template +class GLDStack : public stack +{ +}; + +template +class GStack : public QStack +{ +}; + +#endif // GLDSTACK_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDStrUtils.h b/GCR/trunk/Glodon/include/GLD/GLDStrUtils.h new file mode 100644 index 00000000..cf093b84 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDStrUtils.h @@ -0,0 +1,316 @@ +#ifndef GLDSTRUTILS_H +#define GLDSTRUTILS_H + +#if defined(WIN32) || defined(WIN64) +#include "wtypes.h" +#endif + +#include "GLDChar.h" +#include "GLDString.h" +#include "GLDDateTime.h" +#include "GLDByteArray.h" +#include "GLDUuid.h" +#include "GLDStringList.h" +#include "GLDVariantList.h" +#include "GLDIODevice.h" +#include "GLDSystem.h" +#include "GLDGlobal.h" +#include "GLDEnum.h" +#include "GLDResourceDef.h" + +#if defined(WIN32) || defined(WIN64) + extern GLDCOMMONSHARED_EXPORT const GString sLineBreak; +#else + extern GLDCOMMONSHARED_EXPORT const GString sLineBreak; +#endif + +/* +//获取C风格字符串(\0结尾的字符串)的长度 +size_t CStrLength(const char *sz); +size_t CStrLength(const wchar_t *wsz); +size_t WideCStrLength(const wchar_t *wsz); +wchar_t *WideLowerCase(wchar_t **ppWsz); +//比较两个字符串,大小写敏感 +bool SameStr(const char *szA, const char *szB); +bool WideSameStr(const wchar_t *wszA, const wchar_t *wszB); +//比较两个字符串,大小写不敏感 +bool SameText(const char *szA, const char *szB); +bool WideSameText(const wchar_t *wszA, const wchar_t *wszB); + +wchar_t *charToWchar(const char *str); +char *wcharToChar(const wchar_t *pwstr); +*/ +GLDCOMMONSHARED_EXPORT GString utf8ToUnicode(const char *in, int length = -1); +GLDCOMMONSHARED_EXPORT GByteArray unicodeToUTF8(const GChar *in, int length = -1); +inline GByteArray unicodeToUTF8(const GString &in) { return unicodeToUTF8(in.constData(), in.length()); } + +GLDCOMMONSHARED_EXPORT GString asciiToUnicode(const char *in, int length = -1, const char *name = NULL); +GLDCOMMONSHARED_EXPORT GByteArray unicodeToAscii(const GChar *in, int length = -1, const char *name = NULL); +inline GByteArray unicodeToAscii(const GString &in, const char *name = NULL) { return unicodeToAscii(in.constData(), in.length(), name); } + +GLDCOMMONSHARED_EXPORT GString gbkToUnicode(const char *in, int length = -1); +GLDCOMMONSHARED_EXPORT GByteArray unicodeToGBK(const GChar *in, int length = -1); +inline GByteArray unicodeToGBK(const GString &in) { return unicodeToGBK(in.constData(), in.length()); } + +GLDCOMMONSHARED_EXPORT GString ansiUpperCase(const GString &value); +GLDCOMMONSHARED_EXPORT GString ansiLowerCase(const GString &value); + +GLDCOMMONSHARED_EXPORT GString upperCase(const GString &value); +GLDCOMMONSHARED_EXPORT GString lowerCase(const GString &value); + +GLDCOMMONSHARED_EXPORT char upperCase(const char ch); +GLDCOMMONSHARED_EXPORT char lowerCase(const char ch); + +GLDCOMMONSHARED_EXPORT wchar_t upperCase(const wchar_t ch); +GLDCOMMONSHARED_EXPORT wchar_t lowerCase(const wchar_t ch); + +GLDCOMMONSHARED_EXPORT int compareStr(const GStringRef &s1, const GStringRef &s2); +GLDCOMMONSHARED_EXPORT int compareStr(const GStringRef &s1, const GString &s2); +GLDCOMMONSHARED_EXPORT int compareStr(const GString &s1, const GString &s2); +GLDCOMMONSHARED_EXPORT int compareStr(const GByteArray &s1, const GByteArray &s2); + +GLDCOMMONSHARED_EXPORT int compareText(const GStringRef &s1, const GStringRef &s2); +GLDCOMMONSHARED_EXPORT int compareText(const GStringRef &s1, const GString &s2); +GLDCOMMONSHARED_EXPORT int compareText(const GString &s1, const GString &s2); +GLDCOMMONSHARED_EXPORT int compareText(const GByteArray &s1, const GByteArray &s2); + +GLDCOMMONSHARED_EXPORT GLDValueRelationship compareGVariant(const GVariant &v1, const GVariant &v2); +GLDCOMMONSHARED_EXPORT bool sameGVariant(const GVariant &v1, const GVariant &v2); + +GLDCOMMONSHARED_EXPORT bool sameStr(const GString &s1, const GString &s2); +// 不区分大小写 +inline bool sameText(const GString &s1, const GString &s2) +{ + return 0 == s1.compare(s2, Qt::CaseInsensitive); +} +// 不区分大小写 +inline bool sameText(const GString &s1, const GLatin1String &s2) +{ + return 0 == s1.compare(s2, Qt::CaseInsensitive); +} + +// 不区分大小写 +inline bool sameText(const GStringRef &s1, const GLatin1String &s2) +{ + return 0 == s1.compare(s2, Qt::CaseInsensitive); +} + +GLDCOMMONSHARED_EXPORT int length(const GString &s); +GLDCOMMONSHARED_EXPORT int pos(const GString &subs, const GString &s); +GLDCOMMONSHARED_EXPORT int pos(const GChar &subs, const GString &s); +GLDCOMMONSHARED_EXPORT int pos(const GString &subs, const GString &s, int nFrom); +GLDCOMMONSHARED_EXPORT int rPos(const GString &subs, const GString &s, int times = 1); +GLDCOMMONSHARED_EXPORT int rPos(const GChar &subs, const GString &s, int times = 1); +GLDCOMMONSHARED_EXPORT int rPosEx(const GChar &subs, const GString &s, int offset); +GLDCOMMONSHARED_EXPORT GString trim(const GString &s); +GLDCOMMONSHARED_EXPORT GString trimRight(const GString &s); +GLDCOMMONSHARED_EXPORT GString trimLeft(const GString &s); +GLDCOMMONSHARED_EXPORT GString copy(const GString &s, int position, int n = -1); +GLDCOMMONSHARED_EXPORT GString copyForDelphi(const GString &s, int position, int n = MaxInt); +GLDCOMMONSHARED_EXPORT GString stringReplace(const GString &s, const GString &before, const GString &after); +GLDCOMMONSHARED_EXPORT bool containsText(const GString &text, const GString subText); +GLDCOMMONSHARED_EXPORT GString leftStr(const GString &text, int count); +GLDCOMMONSHARED_EXPORT GString rightStr(const GString &text, int count); +GLDCOMMONSHARED_EXPORT GStringList split(const GString &s, GChar sep); +GLDCOMMONSHARED_EXPORT GStringList split(const GString &s, const GString &sep); + +GLDCOMMONSHARED_EXPORT bool isInt(const GString &s); +GLDCOMMONSHARED_EXPORT bool isInt64(const GString &s); +GLDCOMMONSHARED_EXPORT bool isUInt64(const GString &s); +GLDCOMMONSHARED_EXPORT bool isNumeric(const GString &s); +GLDCOMMONSHARED_EXPORT bool isDateTime(const GString &s); + +GLDCOMMONSHARED_EXPORT bool charIsDigit(const GChar &ch); + +GLDCOMMONSHARED_EXPORT bool variantTypeIsByte(const GVariant::Type type); +GLDCOMMONSHARED_EXPORT bool variantTypeIsShort(const GVariant::Type type); +GLDCOMMONSHARED_EXPORT bool variantTypeIsInt(const GVariant::Type type); +inline bool variantTypeIsInt64(const GVariant::Type type) +{ return (type == GVariant::LongLong || type == GVariant::ULongLong); } +GLDCOMMONSHARED_EXPORT bool variantTypeIsDigit(const GVariant::Type type); +GLDCOMMONSHARED_EXPORT bool variantTypeIsFloat(const GVariant::Type type); +GLDCOMMONSHARED_EXPORT bool variantTypeIsNumeric(const GVariant::Type type); +GLDCOMMONSHARED_EXPORT bool variantTypeIsDateTime(const GVariant::Type type); +GLDCOMMONSHARED_EXPORT bool variantTypeIsUnsigned(const GVariant::Type type); + +#ifdef WIN32 +GLDCOMMONSHARED_EXPORT GString BSTRToGString(const BSTR & s); +GLDCOMMONSHARED_EXPORT BSTR GStringToBSTR(const GString & s); +GLDCOMMONSHARED_EXPORT void freeBSTR(BSTR & s); +#endif + +GLDCOMMONSHARED_EXPORT GString format(const GString &s, const GVariantList &a); +GLDCOMMONSHARED_EXPORT GString format(const GString &s, const GString &a, const GString &before = GString("%s")); +GLDCOMMONSHARED_EXPORT GString format(const GString &s, int a); +GLDCOMMONSHARED_EXPORT GString format(const GString &s, long a); +GLDCOMMONSHARED_EXPORT GString format(const GString &s, long long a); +GLDCOMMONSHARED_EXPORT GString format(const GString &s, double a); +GLDCOMMONSHARED_EXPORT GString format(const GString &s, const GChar &a, const GString &before = GString("%s")); +//GString format(const GString &s, const GVariant &a); + +GLDCOMMONSHARED_EXPORT GString boolToStr(bool a, bool useBoolStrs = false); +GLDCOMMONSHARED_EXPORT bool strToBool(const GString &s); +GLDCOMMONSHARED_EXPORT bool strToBoolDef(const GString &s, bool def = false); +GLDCOMMONSHARED_EXPORT GString intToStr(int a); +GLDCOMMONSHARED_EXPORT GString int64ToStr(gint64 a); +GLDCOMMONSHARED_EXPORT GString uint64ToStr(guint64 a); +GLDCOMMONSHARED_EXPORT int strToInt(const GString &s); +GLDCOMMONSHARED_EXPORT int strToIntDef(const GString &s, int def); +GLDCOMMONSHARED_EXPORT gint64 strToInt64(const GString &s, int base = 10); +GLDCOMMONSHARED_EXPORT gint64 strToInt64Def(const GString &s, gint64 def); +GLDCOMMONSHARED_EXPORT guint64 strToUInt64(const GString &s); +GLDCOMMONSHARED_EXPORT guint64 strToUInt64Def(const GString &s, guint64 def); +GLDCOMMONSHARED_EXPORT GString floatToStr(double a); +GLDCOMMONSHARED_EXPORT double strToFloat(const GString &s); +GLDCOMMONSHARED_EXPORT double strToFloatDef(const GString &s, double def); +GLDCOMMONSHARED_EXPORT GString dateTimeToStr(const GDateTime &datetime, GString format = "yyyy-MM-dd hh:mm:ss"); +GLDCOMMONSHARED_EXPORT GDateTime strToDateTime(const GString &s, GString format = "yyyy-M-d hh:mm:ss"); +GLDCOMMONSHARED_EXPORT GString byteArrayToStr(const GByteArray &a); +GLDCOMMONSHARED_EXPORT GByteArray strToByteArray(const GString &s); +GLDCOMMONSHARED_EXPORT GString intToHex(int value, int digits); + +GLDCOMMONSHARED_EXPORT GString stuffString(const GString &text, int nStart, int nLength, const GString &subText); +GLDCOMMONSHARED_EXPORT int occurs(const char delimiter, const GString &srcStr); + +GLDCOMMONSHARED_EXPORT GByteArray base64Encode(const GByteArray &in); +GLDCOMMONSHARED_EXPORT GStream* base64Encode(GStream *in); + +GLDCOMMONSHARED_EXPORT GByteArray base64Decode(const GByteArray &in); +GLDCOMMONSHARED_EXPORT GStream* base64Decode(GStream *in); + +GLDCOMMONSHARED_EXPORT GString quotedStr(const GString &str, const char quote = '\''); +GLDCOMMONSHARED_EXPORT GByteArray quotedStr(const GByteArray &str, const char quote); + +GLDCOMMONSHARED_EXPORT GString dequotedStr(const GString &str, const char quote); +GLDCOMMONSHARED_EXPORT GByteArray dequotedStr(const GByteArray &str, const char quote); + +GLDCOMMONSHARED_EXPORT GString extractQuotedStr(GString &str, const char quote); + +GLDCOMMONSHARED_EXPORT GStream* stringToStream(const GString &in); +GLDCOMMONSHARED_EXPORT GString streamToString(GStream* in); + +GLDCOMMONSHARED_EXPORT GStream* byteArrayToStream(const GByteArray &in); +GLDCOMMONSHARED_EXPORT GByteArray streamToByteArray(GStream* in); + +GLDCOMMONSHARED_EXPORT GDate intToDate(int d); +GLDCOMMONSHARED_EXPORT int dateToInt(const GDate &date); + +GLDCOMMONSHARED_EXPORT GTime doubleToTime(double t); +GLDCOMMONSHARED_EXPORT double timeToDouble(const GTime &time); + +GLDCOMMONSHARED_EXPORT GDateTime doubleToDateTime(double d); +GLDCOMMONSHARED_EXPORT double dateTimeToDouble(const GDateTime &dateTime); + +GLDCOMMONSHARED_EXPORT GString intToColorHex(int value, int length = 6); + +GLDCOMMONSHARED_EXPORT int yearOf(double d); +GLDCOMMONSHARED_EXPORT int monthOf(double d); +GLDCOMMONSHARED_EXPORT int weekOf(double d); +GLDCOMMONSHARED_EXPORT int dayOf(double d); +GLDCOMMONSHARED_EXPORT int hourOf(double d); +GLDCOMMONSHARED_EXPORT int minuteOf(double d); +GLDCOMMONSHARED_EXPORT int secondOf(double d); +GLDCOMMONSHARED_EXPORT int milliSecondOf(double d); + +struct GFormatSettings +{ + byte currencyFormat; + byte negCurrFormat; + char thousandSeparator; + char decimalSeparator; + byte currencyDecimals; + char dateSeparator; + char timeSeparator; + char listSeparator; + GString currencyString; + GString shortDateFormat; + GString longDateFormat; + GString timeAMString; + GString timePMString; + GString shortTimeFormat; + GString longTimeFormat; + GString shortMonthNames[12]; + GString longMonthNames[12]; + GString shortDayNames[7]; + GString longDayNames[7]; + int twoDigitYearCenturyWindow; +}; + +GLDCOMMONSHARED_EXPORT double chsStrToDateTime(const GString &s); +GLDCOMMONSHARED_EXPORT GString dateTimeToChsStr(double dateTime); +GLDCOMMONSHARED_EXPORT bool isChsDateTime(const GString &s); +GLDCOMMONSHARED_EXPORT bool tryStrToDateTime(const GString &s, GDateTime &value); +GLDCOMMONSHARED_EXPORT bool tryStrToDateTime(const GString &s, GDateTime &value, + const GFormatSettings &formatSettings); + +GLDCOMMONSHARED_EXPORT bool sameDateTime(double dateTime1, double dateTime2); +GLDCOMMONSHARED_EXPORT GLDValueRelationship compareDateTime(double dateTime1, double dateTime2); + +GLDCOMMONSHARED_EXPORT GString getHZPY(const GString &src); +GLDCOMMONSHARED_EXPORT GString firstLetter(int nCode); +GLDCOMMONSHARED_EXPORT GString reverseString(const GString &s); +GLDCOMMONSHARED_EXPORT GString regExprReplace(const GString &text, const GString ®Ex, const GString &replacement); + +GLDCOMMONSHARED_EXPORT GString getSubString(const GString &srcStr, char delimiter, int index); +GLDCOMMONSHARED_EXPORT GString getSubString(const GString &srcStr, const GString &delimiter, int index); + +GLDCOMMONSHARED_EXPORT int posN(const char delimiter, const GString srcStr, int times = 1); +GLDCOMMONSHARED_EXPORT int posN(const GString subStr, const GString srcStr, int times = 1); + +GLDCOMMONSHARED_EXPORT GString stringOfChar(char Char, int count); + + +GLDCOMMONSHARED_EXPORT GString boolToXMLString(bool v); +GLDCOMMONSHARED_EXPORT bool xmlStringToBool(const GString &s); +GLDCOMMONSHARED_EXPORT GString floatToXMLString(double v); +GLDCOMMONSHARED_EXPORT GString encodeXMLString(const GString &value, bool encodeCrLf); + +/** + GUID 相关处理函数 +*/ +#include "GLDGuidDef.h" +GLDCOMMONSHARED_EXPORT GString createGuidString(); +GLDCOMMONSHARED_EXPORT GUID createGUID(); +GLDCOMMONSHARED_EXPORT GString GUIDToStr(const GUID &a); +GLDCOMMONSHARED_EXPORT GUID strToGUID(const GString &text); +GLDCOMMONSHARED_EXPORT GVariant GUIDToVariant(const GUID &a); +GLDCOMMONSHARED_EXPORT GUID variantToGUID(const GVariant &text); +GLDCOMMONSHARED_EXPORT GByteArray GUIDToByteArray(const GUID value); +GLDCOMMONSHARED_EXPORT GUID byteArrayToGUID(const GByteArray &ba); +GLDCOMMONSHARED_EXPORT int compareGUID(const GUID &g1, const GUID &g2); +GLDCOMMONSHARED_EXPORT bool isGUID(const GString &s); +GLDCOMMONSHARED_EXPORT bool variantTypeIsGUID(const GVariant::Type type); +GLDCOMMONSHARED_EXPORT GUuid GUIDToGUuid(const GUID &value); +GLDCOMMONSHARED_EXPORT GUID GUuidToGUID(const GUuid &value); + +template +inline void include(Set &set, const T t) +{ + set |= (byte(1) << byte(t)); +} + +template +inline void exclude(Set &set, const T t) +{ + set &= ~(byte(1) << byte(t)); +} + +template +inline bool contains(const Set &set, const T t) +{ + return set & (byte(1) << byte(t)); +} + +//type:0(), 1(], 2[), 3[] +template +Q_DECL_CONSTEXPR inline bool isInInterval( const T &val, const T &min, const T &max, int type = 3) +{ + return ((1 == (type & 1)) ? (val <= max) : (val < max)) + && ((2 == (type & 2)) ? (val >= min) : (val > min)); +} + +LONGLONG getStartTime(); +double getLastTime(LONGLONG startTime); + +#endif // GLDSTRUTILS_H + diff --git a/GCR/trunk/Glodon/include/GLD/GLDStream.h b/GCR/trunk/Glodon/include/GLD/GLDStream.h new file mode 100644 index 00000000..b819da16 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDStream.h @@ -0,0 +1,151 @@ +#ifndef GLDSTREAM_H +#define GLDSTREAM_H + +#include "GLDTypes.h" +#include "GLDVector.h" +#include "GLDObject.h" + +enum GSeekOrigin +{ + soBeginning = 0, + soCurrent = 1, + soEnd = 2 +}; + +class GMemoryStreamPrivate; +class GLDCOMMONSHARED_EXPORT GMemoryStream : public GBuffer +{ +#ifndef QT_NO_QOBJECT + Q_OBJECT +#endif +public: + GMemoryStream(OpenMode flags = GStream::ReadWrite); + explicit GMemoryStream(GByteArray *buf, bool ownerBuf, OpenMode flags = GStream::ReadWrite); + virtual ~GMemoryStream(); +/* gint64 read(char *data, gint64 maxlen); + GByteArray read(gint64 maxlen); + gint64 readData(char *data, gint64 maxlen); + gint64 writeData(const char *data, gint64 len); + gint64 write(const char *data, gint64 len); + gint64 write(const char *data); + gint64 write(const GByteArray &data); + bool seek(gint64 pos); + gint64 pos() const; + gint64 size() const; + GByteArray readAll(); + void close(); + bool open(OpenMode mode); + bool reset();*/ +private: + GMemoryStreamPrivate * const d_ptr; + Q_DECLARE_PRIVATE(GMemoryStream) +}; + +class GBlockMemoryStreamPrivate; +class GLDCOMMONSHARED_EXPORT GBlockMemoryStream : public GStream +{ +#ifndef QT_NO_QOBJECT + Q_OBJECT +#endif +public: + explicit GBlockMemoryStream(GStream::OpenMode flags = GStream::ReadWrite); + ~GBlockMemoryStream(); + + GObjectList &buffer(); + void setBuffer(GObjectList *a); + + bool open(GStream::OpenMode openMode); + void close(); + gint64 size() const; + gint64 pos() const; + bool seek(gint64 off); + bool atEnd() const; + bool canReadLine() const; + gint64 seek(gint64 nOffset, int nFlag); + bool reset(); + void clearData(); + + void loadFromStream(GStream *stream, gint64 len = -1); + void saveToStream(GStream *stream); + void loadFromFile(const GString &fileName); + void saveToFile(const GString &fileName); + +protected: + gint64 readData(char *data, gint64 maxlen); + gint64 writeData(const char *data, gint64 len); +private: + void doSetPosition(gint64 nPos); + void setCapacity(gint64 nNewCapacity); + void setSize(gint64 nNewSize); + void doRead(char* data, gint64 nReadCount); + void doWrite(const char* data, gint64 nWriteCount); + +private: + //GBlockMemoryStreamPrivate * d_ptr; + Q_DECLARE_PRIVATE(GBlockMemoryStream); +}; + +class GReadBufferedStreamPrivate; +class GLDCOMMONSHARED_EXPORT GReadBufferedStream : public GStream +{ +#ifndef QT_NO_QOBJECT + Q_OBJECT +#endif + +public: + GReadBufferedStream(GStream *baseStream, int bufferSize, bool autoDestroyWrappedStream = false); + ~GReadBufferedStream(); + + gint64 size() const; + gint64 pos() const; + bool seek(gint64 off); + gint64 seek(gint64 offset, GSeekOrigin origin); + +protected: + gint64 readData(char *data, gint64 maxlen); + gint64 writeData(const char *data, gint64 len); + +private: + bool autoDestroyWrappedStream(); + void setAutoDestroyWrappedStream(bool value); + GStream *wrappedStream(); +private: + gint64 currentPosition() const; + gint64 internalSeek(gint64 offset); +private: + Q_DECLARE_PRIVATE(GReadBufferedStream); +}; + +class GWriteBufferedStreamPrivate; +class GLDCOMMONSHARED_EXPORT GWriteBufferedStream : public GStream +{ +#ifndef QT_NO_QOBJECT + Q_OBJECT +#endif + +public: + GWriteBufferedStream(GStream *baseStream, int bufferSize, bool autoDestroyWrappedStream = false); + ~GWriteBufferedStream(); + + gint64 size() const; + gint64 pos() const; + bool seek(gint64 off); + + gint64 seek(const gint64 offset, GSeekOrigin origin); +protected: + gint64 readData(char *data, gint64 maxlen); + gint64 writeData(const char *data, gint64 len); + bool autoDestroyWrappedStream(); + void setAutoDestroyWrappedStream(bool value); + GStream *wrappedStream(); + +private: + gint64 currentPosition() const; + gint64 currentSize() const; + gint64 internalSeek(gint64 offset); + void flushStream(); +private: + Q_DECLARE_PRIVATE(GWriteBufferedStream); +}; + +#endif // GLDSTREAM_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDStreamUtils.h b/GCR/trunk/Glodon/include/GLD/GLDStreamUtils.h new file mode 100644 index 00000000..5ec6b5a1 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDStreamUtils.h @@ -0,0 +1,322 @@ +/********************************************************************** + * + * 广联达 streamhelper IStream流辅助单元 + * + * 设计:Linw 2012.03.31 + * 备注: + * 审核: + * 注意: + * + * Copyright (c) 1994-2012 GlodonSoft Corporation + * + **********************************************************************/ + +#ifndef GLDSTREAMHELPER_HPP +#define GLDSTREAMHELPER_HPP + +#ifdef WIN32 +# include "objidl.h" +#endif +#include "GLDIODevice.h" +#include "GLDString.h" +#include "GLDStream.h" +#include "GLDVariant.h" +#include "GLDUnknwn.h" + +// 基本数据类型 +enum GBaseDataType +{ + gbdtUnknown, // 未知 0 + gbdtInteger, // 整数 1 + gbdtFloat, // 浮点数 2 + gbdtString, // 字符串 3 + gbdtBoolean, // 布尔 + gbdtDateTime, // 日期时间 + gbdtTable, // 嵌套表 + gbdtInt64, // 长整数 + gbdtBlob, // 二进制OLE + gbdtGUID, // GUID + gbdtUInt64 // 无符号长整形 +}; + +class GStreamImplPrivate; +class GLDCOMMONSHARED_EXPORT GStreamImpl : public GStream +{ +public: + explicit GStreamImpl(IStream *stream = NULL, GStream::OpenMode flags = GStream::ReadWrite); + virtual ~GStreamImpl(); + gint64 size() const; + gint64 pos() const; + bool seek(gint64 off); +protected: + gint64 readData(char *data, gint64 maxlen); + gint64 writeData(const char *data, gint64 len); +public: + IStream *streamIntf() const; + +private: + Q_DECLARE_PRIVATE(GStreamImpl) +}; + +class GIStreamImplPrivate; +class GLDCOMMONSHARED_EXPORT GIStreamImpl : public GInterfaceObject, public IStream +{ +public: + GIStreamImpl(GStream *stream = NULL); + virtual ~GIStreamImpl(); +public: + DECLARE_IUNKNOWN + + virtual HRESULT STDMETHODCALLTYPE Read(void *pv, ULONG cb, ULONG *pcbRead); + + virtual HRESULT STDMETHODCALLTYPE Write(const void *pv, ULONG cb, ULONG *pcbWritten); + + virtual HRESULT STDMETHODCALLTYPE Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, + ULARGE_INTEGER *plibNewPosition); + + virtual HRESULT STDMETHODCALLTYPE SetSize(ULARGE_INTEGER libNewSize); + + virtual HRESULT STDMETHODCALLTYPE CopyTo(IStream *pstm, ULARGE_INTEGER cb, + ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten); + + virtual HRESULT STDMETHODCALLTYPE Commit(DWORD grfCommitFlags); + + virtual HRESULT STDMETHODCALLTYPE Revert(); + + virtual HRESULT STDMETHODCALLTYPE LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, + DWORD dwLockType); + + virtual HRESULT STDMETHODCALLTYPE UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, + DWORD dwLockType); + + virtual HRESULT STDMETHODCALLTYPE Stat(STATSTG *pstatstg, DWORD grfStatFlag); + + virtual HRESULT STDMETHODCALLTYPE Clone(IStream **ppstm); +protected: + HRESULT STDMETHODCALLTYPE _QueryInterface(REFIID riid, void **ppvObject); +public : + GStream *stream() const; + +private: + GIStreamImplPrivate * const d_ptr; + Q_DECLARE_PRIVATE(GIStreamImpl) +}; + +GLDCOMMONSHARED_EXPORT long long streamLength(IStream *stream); + +GLDCOMMONSHARED_EXPORT GString readFromStream(GStream *stream, uint length, bool useUnicode = false); +GLDCOMMONSHARED_EXPORT GByteArray readByteArrayFromStream(GStream *stream, uint length); +GLDCOMMONSHARED_EXPORT void readByteArrayFromStream(GStream *stream, GByteArray &value); +GLDCOMMONSHARED_EXPORT GByteArray readByteArrayFromStream(GStream *stream); + +GLDCOMMONSHARED_EXPORT void readStrFromStream(GStream *stream, GString &value, bool useUnicode = false); +GLDCOMMONSHARED_EXPORT void readMemoFromStream(GStream *stream, GString &value, bool useUnicode = false); +GLDCOMMONSHARED_EXPORT void readStreamFromStream(GStream *src, GStream *dst, unsigned int length); +GLDCOMMONSHARED_EXPORT unsigned int readStreamFromStream(GStream *src, GStream *dst); + +inline void readBoolFromStream(GStream *stream, bool &value) +{ + stream->read((char*)(&value), sizeof(bool)); +} + +inline void readByteFromStream(GStream *stream, unsigned char &value) +{ + stream->read((char*)(&value), sizeof(unsigned char)); +} + +inline void readWordFromStream(GStream *stream, unsigned short &value) +{ + stream->read((char*)(&value), sizeof(unsigned short)); +} + +inline void readUIntFromStream(GStream *stream, unsigned int &value) +{ + stream->read((char*)(&value), sizeof(unsigned int)); +} + +inline void readIntFromStream(GStream *stream, int &value) +{ + stream->read((char*)(&value), sizeof(int)); +} + +inline void readDoubleFromStream(GStream *stream, double &value) +{ + stream->read((char*)(&value), sizeof(double)); +} + +GLDCOMMONSHARED_EXPORT void readColorFromStream(GStream *stream, TColor &color); + +inline void readInt64FromStream(GStream *stream, long long &value) +{ + stream->read((char*)(&value), sizeof(long long)); +} + +inline void readUInt64FromStream(GStream *stream, guint64 &value) +{ + stream->read((char*)(&value), sizeof(guint64)); +} + +GLDCOMMONSHARED_EXPORT void readGUIDFromStream(GStream *stream, GUID &value); + +inline void readCharFromStream(GStream *stream, signed char &value) +{ + stream->read((char*)(&value), sizeof(signed char)); +} + +inline void readShortFromStream(GStream *stream, short &value) +{ + stream->read((char*)(&value), sizeof(short)); +} + +GLDCOMMONSHARED_EXPORT GString readStrFromStream(GStream *stream, bool useUnicode = false); +GLDCOMMONSHARED_EXPORT GString readMemoFromStream(GStream *stream, bool useUnicode = false); + +inline bool readBoolFromStream(GStream *stream) +{ + bool result; + readBoolFromStream(stream, result); + return result; +} + +inline unsigned char readByteFromStream(GStream *stream) +{ + unsigned char ucResult(0); + readByteFromStream(stream, ucResult); + return ucResult; +} + +inline unsigned short readWordFromStream(GStream *stream) +{ + unsigned short uResult(0); + readWordFromStream(stream, uResult); + return uResult; +} + +inline uint readUIntFromStream(GStream *stream) +{ + uint result(0); + readUIntFromStream(stream, result); + return result; +} + +inline int readIntFromStream(GStream *stream) +{ + int result = 0; + readIntFromStream(stream, result); + return result; +} + +GLDCOMMONSHARED_EXPORT TColor readColorFromStream(GStream *stream); + +inline double readDoubleFromStream(GStream *stream) +{ + double result; + readDoubleFromStream(stream, result); + return result; +} + +GLDCOMMONSHARED_EXPORT GVariant readGVariantFromStream(GStream *stream); +GLDCOMMONSHARED_EXPORT void readGVariantFromStream(GStream *stream, GVariant &result); + +GLDCOMMONSHARED_EXPORT void writeGVariantToStream(GStream *stream, const GVariant &value); + +inline gint64 readInt64FromStream(GStream *stream) +{ + long long result; + readInt64FromStream(stream, result); + return result; +} + +inline guint64 readUInt64FromStream(GStream *stream) +{ + guint64 result(0); + readUInt64FromStream(stream, result); + return result; +} + +inline GUID readGUIDFromStream(GStream *stream) +{ + GUID result; + readGUIDFromStream(stream, result); + return result; +} + +inline char readCharFromStream(GStream *stream) +{ + signed char result(0); + readCharFromStream(stream, result); + return result; +} + +inline short readShortFromStream(GStream *stream) +{ + short result; + readShortFromStream(stream, result); + return result; +} + +GLDCOMMONSHARED_EXPORT void writeByteArrayToStream(GStream *stream, const GByteArray &value); +GLDCOMMONSHARED_EXPORT void writeByteArrayToStream(GStream *stream, const char *value, int size); +GLDCOMMONSHARED_EXPORT void writeStrToStream(GStream *stream, const GString &value, bool useUnicode = false); +GLDCOMMONSHARED_EXPORT void writeStrToStream(GStream *stream, const char *value, int size, bool useUnicode = false); +GLDCOMMONSHARED_EXPORT void writeMemoToStream(GStream *stream, const char *value, int size, bool useUnicode = false); +GLDCOMMONSHARED_EXPORT void writeMemoToStream(GStream *stream, const GString &value, bool useUnicode = false); + +inline void writeBoolToStream(GStream *stream, const bool value) +{ + stream->write((const char *)(&value), sizeof(bool)); +} + +inline void writeByteToStream(GStream *stream, const unsigned char value) +{ + stream->write((const char *)(&value), sizeof(unsigned char)); +} + +inline void writeWordToStream(GStream *stream, const unsigned short value) +{ + stream->write((const char *)(&value), sizeof(unsigned short)); +} + +inline void writeUIntToStream(GStream *stream, const unsigned int value) +{ + stream->write((const char *)(&value), sizeof(unsigned int)); +} + +inline void writeIntToStream(GStream *stream, const int value) +{ + stream->write((const char *)(&value), sizeof(int)); +} + +inline void writeDoubleToStream(GStream *stream, const double value) +{ + stream->write((const char *)(&value), sizeof(double)); +} + +inline void writeInt64ToStream(GStream *stream, const long long value) +{ + stream->write((const char *)(&value), sizeof(long long)); +} + +inline void writeUInt64ToStream(GStream *stream, const guint64 value) +{ + stream->write((const char *)(&value), sizeof(guint64)); +} + +GLDCOMMONSHARED_EXPORT void writeGUIDToStream(GStream *stream, GUID value); + +inline void writeCharToStream(GStream *stream, const char value) +{ + stream->write((const char *)(&value), sizeof(char)); +} + +inline void writeShortToStream(GStream *stream, const short value) +{ + stream->write((const char *)(&value), sizeof(short)); +} + +GLDCOMMONSHARED_EXPORT void writeColorToStream(GStream *stream, const TColor color); + +GLDCOMMONSHARED_EXPORT GMemoryStream *createMemoryStream(); + +GLDCOMMONSHARED_EXPORT void copyStream(GStream *dst, GStream *src); +#endif /* GLDSTREAMHELPER_HPP */ diff --git a/GCR/trunk/Glodon/include/GLD/GLDString.h b/GCR/trunk/Glodon/include/GLD/GLDString.h new file mode 100644 index 00000000..6e3ebf9c --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDString.h @@ -0,0 +1,12 @@ +#ifndef GLDSTRING +#define GLDSTRING + +#include + +typedef QString GString; +typedef QLatin1String GLatin1String; +typedef QStringRef GStringRef; +typedef QCharRef GCharRef; + +#endif // GLDSTRING + diff --git a/GCR/trunk/Glodon/include/GLD/GLDStringList.h b/GCR/trunk/Glodon/include/GLD/GLDStringList.h new file mode 100644 index 00000000..00fc0835 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDStringList.h @@ -0,0 +1,10 @@ +#ifndef GLDSTRINGLIST +#define GLDSTRINGLIST + +#include + +typedef QStringList GStringList; +typedef GStringList GStrings; + +#endif // GLDSTRINGLIST + diff --git a/GCR/trunk/Glodon/include/GLD/GLDStringObjectList.h b/GCR/trunk/Glodon/include/GLD/GLDStringObjectList.h new file mode 100644 index 00000000..40b02fea --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDStringObjectList.h @@ -0,0 +1,203 @@ +#ifndef GSTRINGOBJECTLIST_H +#define GSTRINGOBJECTLIST_H + +/*! + * @brief 实现TStringList以及其基类 + * + * 详细说明 + * @author duanb + * @date 2013.08.23 + * @remarks 备注 + * Copyright (c) 1998-2013 Glodon Corporation +*/ + +#include "GLDHash.h" +#include "GLDString.h" +#include "GLDIODevice.h" +#include "GLDSortUtils.h" + +struct GStringItem +{ + GString str; + void* object; +}; + +class GStringObjectListPrivate; +class GLDCOMMONSHARED_EXPORT GStringObjectList +{ +public: + explicit GStringObjectList(); + GStringObjectList(GStringObjectListPrivate &dd); + //拷贝构造函数 + GStringObjectList(const GStringObjectList& other); + virtual ~GStringObjectList(); +public: + enum GDuplicates + { + dupIgnore, + dupAccept, + dupError + }; + enum GStringsDefined + { + sdDelimiter, + sdQuoteChar, + sdNameValueSeparator, + sdLineBreak, + sdStrictDelimiter + }; + + virtual int add(const GString &s); + virtual int add(GStringItem *item); + virtual int addObject(const GString &s, void *object); + virtual int addStrings(GStringObjectList *list); + + virtual void insert(int index, const GString &s); + virtual void insertObject(int index, const GString &s, void *object); + + virtual bool find(const GString &s, int &index); + virtual int indexOfObject(void *value); + virtual int indexOf(const GString &value); + + virtual void put(int index, const GString &s); + GString string(int index); + virtual void putString(int index, const GString &s); + + virtual void *object(int index); + virtual void putObject(int index, void *object); + + virtual void clear(); + bool isEmpty(); + virtual int count() const; + virtual int size(); + GStringItem *at(int index) const; + void setIndex(int index, GStringItem* item); + GStringItem* &operator[](int index); + + virtual void push_back(GStringItem *item); + virtual void append(GStringItem *item); + virtual void append(GObjectList &items); + GObjectList &list(); + virtual void Delete(int index); + virtual void removeAt(int index); + virtual void exchange(int index1, int index2); + virtual void swap(int index1, int index2); + + virtual void sort(bool ascend = true); + virtual void customSort(CSortCompareEvent *customSortEvent = NULL, bool ascend = false); + + GString value(const GString &name); + void setValue(const GString &name, const GString &value); + GString valueFromIndex(int index); + void setValueFromIndex(int index, const GString &value); + + GString names(int index); + virtual int indexOfName(const GString &name); + + bool caseSensitive() const; + void setCaseSensitive(bool caseSensitive); + + bool sorted() const; + void setSorted(bool sorted); + + GDuplicates duplicates() const; + void setDuplicates(const GDuplicates &duplicates); + + void checkIndex(int index) const; + virtual int compareStrings(const GString &s1, const GString &s2); + + virtual void setTextStr(const GString &value); + GString textStr(); + + virtual void loadFromFile(const GString &fileName); + virtual void loadFromStream(GStream *stream); + virtual void saveToFile(const GString &fileName); + virtual void saveToStream(GStream *stream); + + // 不允许使用此方法 + virtual void changed(); + + // 以下这些公共方法还没作用 + void beginUpdate(); + void endUpdate(); + void setUpdateState(bool updating); + + void assign(GStringObjectList *source); + + GString lineBreak(); + void setLineBreak(const GString &lineBreak); + + char quoteChar(); + void setQuoteChar(char quoteChar); + + char nameValueSeparator(); + void setNameValueSeparator(char nameValueSeparator); + + bool strictDelimiter(); + void setStrictDelimiter(bool strictDelimiter); + + char delimiter(); + void setDelimiter(char delimiter); + + GString delimitedText(); + void setDelimitedText(const GString &value); + + void setCommaText(const GString &value); + GString commaText(); +protected: + virtual void insertItem(int index, const GString &s, void *object); + virtual void insertItem(int index, GStringItem *item); + virtual void changing(); + GString extractName(const GString &s); +private: + int findItem(const GString &s, void *object); + bool containsBeforeSpace(const gint64 set); + template + inline bool contains(const Set &set, const T t) const + { + return 0 != (set & (byte(1) << byte(t)));//TODOREVIEW + } + inline bool containsOfGint64(const gint64 &set, const gint64 t) const + { + return 0 != (set & gint64(gint64(1) << gint64(t)));//TODOREVIEW + } + inline void includeOfGint64(gint64 &set, const gint64 t) + { + set |= (gint64(1) << gint64(t)); + } + + inline void excludeOfGint64(gint64 &set, const gint64 t) + { + set &= ~(gint64(1) << gint64(t)); + } + +protected: + GStringObjectListPrivate * const d_ptr; + Q_DECLARE_PRIVATE(GStringObjectList); +}; + +class GHashedStringObjectListPrivate; +/*! + *@ GHashedStringObjectList + *@brief 用于加快查找速度 + *@author duanb + *@date 2013.08.23 +*/ +class GLDCOMMONSHARED_EXPORT GHashedStringObjectList : public GStringObjectList +{ +public: + explicit GHashedStringObjectList(); + ~GHashedStringObjectList(); +public: + int indexOfName(const GString &name); + int indexOf(const GString &value); + void changed(); + +private: + void updateValueHash(); + void updateNameHash(); +private: + Q_DECLARE_PRIVATE(GHashedStringObjectList); +}; + +#endif // GSTRINGOBJECTLIST_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDStrings.h b/GCR/trunk/Glodon/include/GLD/GLDStrings.h new file mode 100644 index 00000000..0cae2afd --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDStrings.h @@ -0,0 +1,79 @@ +#ifndef GLDSTRINGS_H +#define GLDSTRINGS_H + +#include "GLDString.h" +#include "GLDResourceDef.h" +#include "GLDGlobal.h" + +DEF_RESOURCESTRING5(g_InvalidInteger); +DEF_RESOURCESTRING5(g_InvalidFloat); +DEF_RESOURCESTRING5(g_InvalidGUID); +DEF_RESOURCESTRING5(g_InvalidTypeCompare); + +DEF_RESOURCESTRING5(g_sInvalidBase64Data); +DEF_RESOURCESTRING5(g_rsInvalidTimeFormat); + +DEF_RESOURCESTRING5(g_MissingExtPropCode); +DEF_RESOURCESTRING5(g_ExtPropCodeExist); + +DEF_RESOURCESTRING5(g_InvalidFieldName); +DEF_RESOURCESTRING5(g_NeedRunState); +DEF_RESOURCESTRING5(g_InvalidFieldNameMark); +DEF_RESOURCESTRING5(g_NotExistVisibleCol); + +DEF_RESOURCESTRING5(g_InvalidXMLNode); +DEF_RESOURCESTRING5(g_NeedXMLNode); + +DEF_RESOURCESTRING5(g_InvalidBinFile); +DEF_RESOURCESTRING5(g_ReadBinFileError); + +DEF_RESOURCESTRING5(g_SelectImage); +DEF_RESOURCESTRING5(g_SquareReplace); +DEF_RESOURCESTRING5(g_CubeReplace); + +DEF_RESOURCESTRING5(g_rsInvalideRule); +DEF_RESOURCESTRING5(g_rsHasNoActiveSheet); +DEF_RESOURCESTRING5(g_rsGetMergeRectFailed); +DEF_RESOURCESTRING5(g_rsTitleIndex); +DEF_RESOURCESTRING5(g_rsTitleSelect); +DEF_RESOURCESTRING5(g_rsTitleSymbol); + +DEF_RESOURCESTRING5(g_rsMonth); +DEF_RESOURCESTRING5(g_rsYear); +DEF_RESOURCESTRING5(g_rsDay); +DEF_RESOURCESTRING5(g_rsMonDay); +DEF_RESOURCESTRING5(g_rsTueDay); +DEF_RESOURCESTRING5(g_rsWedDay); +DEF_RESOURCESTRING5(g_rsThuDay); +DEF_RESOURCESTRING5(g_rsFriDay); +DEF_RESOURCESTRING5(g_rsSatDay); +DEF_RESOURCESTRING5(g_rsSunDay); + +DEF_RESOURCESTRING5(g_rsFontEffect); +DEF_RESOURCESTRING5(g_rsEffect); +DEF_RESOURCESTRING5(g_rsNoLine); +DEF_RESOURCESTRING5(g_rsOtherLine); +DEF_RESOURCESTRING5(g_rsLineWidth); + +DEF_RESOURCESTRING5(g_rsAutoHide); +DEF_RESOURCESTRING5(g_rsLocked); + +DEF_RESOURCESTRING5(g_rsSimsun); +DEF_RESOURCESTRING5(g_rsAccount); +DEF_RESOURCESTRING5(g_rsPassword); +DEF_RESOURCESTRING5(g_rsLogin); +DEF_RESOURCESTRING5(g_rsCancel); +DEF_RESOURCESTRING5(g_rsRegisterAccount); +DEF_RESOURCESTRING5(g_rsGetBackPassword); +DEF_RESOURCESTRING5(g_rsRemeberPassword); +DEF_RESOURCESTRING5(g_rsAutoLogin); +DEF_RESOURCESTRING5(g_rsOpenVirtualKeyboard); +DEF_RESOURCESTRING5(g_rsAccountError); +DEF_RESOURCESTRING5(g_rsLoginError); +DEF_RESOURCESTRING5(g_rsNetworkError); + +GLDCOMMONSHARED_EXPORT GString getGLDi18nStr(const char *originalStr); +GLDCOMMONSHARED_EXPORT GString getGSPi18nStr(const char *originalStr); +GLDCOMMONSHARED_EXPORT GString getGEPEnginei18nStr(const char *originalStr); + +#endif // GLDSTRINGS_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDStylePaintUtils.h b/GCR/trunk/Glodon/include/GLD/GLDStylePaintUtils.h new file mode 100644 index 00000000..cbb2f7a3 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDStylePaintUtils.h @@ -0,0 +1,20 @@ +#ifndef GLDSTYLEPAINTUTILS_H +#define GLDSTYLEPAINTUTILS_H + +class QStyleOptionComboBox; +class QStyleOptionSpinBox; +class QStyleOptionButton; +class QRect; +class QString; +class GLDWIDGETSHARED_EXPORT GLDStylePaintUtils +{ +public: + static void initComboBoxOpt(QStyleOptionComboBox &opt, const QRect &rect); + static void initPushButtonOpt(QStyleOptionButton &opt, const QRect &rect, const QString &btnText); + static void initSpinBoxOpt(QStyleOptionSpinBox &opt, const QRect &rect); +protected: + explicit GLDStylePaintUtils(); + +}; + +#endif // GLDSTYLEPAINTUTILS_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDSysUtils.h b/GCR/trunk/Glodon/include/GLD/GLDSysUtils.h new file mode 100644 index 00000000..8c521f1a --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDSysUtils.h @@ -0,0 +1,56 @@ +/************************************************************************* +* * +* 广联达系统核心公共函数单元 H * +* * +* 设计:Zhangsk 2012.05.23 * +* 备注: * +* 审核: * +* * +* Copyright (c) 2012-2013 Glodon Corporation * +* * +*************************************************************************/ + +#ifndef GLDSYSUTILS_H +#define GLDSYSUTILS_H +#include "GLDNameSpace.h" +#include "GLDChar.h" +#include "GLDString.h" +#include "GLDSystem.h" +#include "GLDCommon_Global.h" + +G_GLODON_BEGIN_NAMESPACE +//G_SYSUTILS_BEGIN_NAMESPACE + +//G_SYSUTILS_END_NAMESPACE +G_GLODON_END_NAMESPACE + +GLDCOMMONSHARED_EXPORT GString includeTrailingBackslash(const GString &s); +GLDCOMMONSHARED_EXPORT GString includeTrailingPathDelimiter(const GString &s); +GLDCOMMONSHARED_EXPORT GString excludeTrailingBackslash(const GString &s); +GLDCOMMONSHARED_EXPORT GString excludeTrailingPathDelimiter(const GString &s); +GLDCOMMONSHARED_EXPORT GChar pathDelim(); +GLDCOMMONSHARED_EXPORT GChar driveDelim(); +GLDCOMMONSHARED_EXPORT GChar backSlashDelim(); +GLDCOMMONSHARED_EXPORT bool isPathDelimiter(const GString &s, int index); + +GLDCOMMONSHARED_EXPORT double fileDateToDateTime(int fileDate); +GLDCOMMONSHARED_EXPORT int DateTimeToFileDate(double value); + +GLDCOMMONSHARED_EXPORT GString getUserNameDef(); +GLDCOMMONSHARED_EXPORT GString getHostName(); +GLDCOMMONSHARED_EXPORT unsigned getCoreCount(); +GLDCOMMONSHARED_EXPORT GString getMacString(); +GLDCOMMONSHARED_EXPORT GString getCPUIdString(); +GLDCOMMONSHARED_EXPORT GString getDiskSerialNoString(); +GLDCOMMONSHARED_EXPORT GString getComputerGUID(); +GLDCOMMONSHARED_EXPORT GString valueFromRegistry(const GString ®Path, const GString ®Key); +GLDCOMMONSHARED_EXPORT GString environmentVariable(const GString &name); +GLDCOMMONSHARED_EXPORT bool setEnvironmentVariable(const GString &name, const GString &value); +GLDCOMMONSHARED_EXPORT GString getUserDocumentsPath(); +GLDCOMMONSHARED_EXPORT GString getUserAppDataPath(); +GLDCOMMONSHARED_EXPORT gint64 getAvailPhysMem(); +GLDCOMMONSHARED_EXPORT unsigned long memoryUsage(); + +GLDCOMMONSHARED_EXPORT GString getSpecialFolderPath(int CSIDL); + +#endif // GLDSYSUTILS_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDSystem.h b/GCR/trunk/Glodon/include/GLD/GLDSystem.h new file mode 100644 index 00000000..31a41d31 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDSystem.h @@ -0,0 +1,24 @@ +#ifndef GLDSYSTEM +#define GLDSYSTEM + +#ifdef __APPLE__ +#pragma clang diagnostic ignored "-Winvalid-source-encoding" +#pragma clang diagnostic ignored "-Woverloaded-virtual" +#endif + +#if defined(WIN64) || defined(_WIN64) || defined(__WIN64__) || defined(__APPLE__) || defined(__x86_64__) +typedef long long PtrInt; +typedef unsigned long long PtrUInt; +#else +typedef int PtrInt; +typedef unsigned int PtrUInt; +#endif + +typedef long long gint64; +typedef unsigned long long guint64; +typedef unsigned char byte; +typedef unsigned int GRgb; +typedef unsigned int TColor; + +#endif // GLDSYSTEM + diff --git a/GCR/trunk/Glodon/include/GLD/GLDTabDockContainer.h b/GCR/trunk/Glodon/include/GLD/GLDTabDockContainer.h new file mode 100644 index 00000000..8887effe --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDTabDockContainer.h @@ -0,0 +1,274 @@ +#ifndef GLD_TABDOCKCONTAINER_H +#define GLD_TABDOCKCONTAINER_H +/************************************************************************ +@author huy-a +@date 2014-08-28 +@note + +提供类似VS的停靠,采用工具栏+dockWidget实现 + +注意,如果停靠到有工具栏的停靠区,可能会出现在tab和dock 窗口之间插入工具栏的问题。 + + +************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "GLDComboBox.h" + +class GLDTabDockContainerWidget; +class GLDTabDockContainer; +class GLDTabDockContainerTitleWidget; +/** + * @brief 提供扁平button + */ +class GLDWIDGETSHARED_EXPORT GLDTabDockContainerWidgetAnchorButton : public QPushButton +{ + Q_OBJECT + friend class GLDTabDockContainerWidget; + friend class GLDTabDockContainerTitleWidget; +private: + GLDTabDockContainerWidgetAnchorButton(QWidget *parent): QPushButton(parent) + { + setFlat(true); + } + virtual void enterEvent(QEvent *) + { + setFlat(false); + } + virtual void leaveEvent(QEvent *) + { + setFlat(true); + } +}; + +/** + * @brief The Title Widget + */ +class GLDWIDGETSHARED_EXPORT GLDTabDockContainerTitleWidget : public QWidget +{ + Q_OBJECT + friend class GLDTabDockContainerWidget; +public: + explicit GLDTabDockContainerTitleWidget(QWidget *parent); + void setDockWidget(GLDTabDockContainerWidget *dockerWidget); + GLDTabDockContainerWidgetAnchorButton *addAnchorButton(); + QToolBar* toolBar(); +protected: + virtual void mouseMoveEvent(QMouseEvent *event); +private: + QLabel *m_title; + QToolBar *m_userToolBar; + QToolBar *m_toolBar; + GLDTabDockContainerWidgetAnchorButton *m_anchorButton; + QHBoxLayout *m_layout; + GLDTabDockContainerWidget *m_dockerWidget; + QAction *m_action; +}; + +/** + * @brief The Dock widget + */ +class GLDWIDGETSHARED_EXPORT GLDTabDockContainerWidget : public QDockWidget +{ + Q_OBJECT +public: + explicit GLDTabDockContainerWidget(const QString &title, QWidget *parent = 0); + explicit GLDTabDockContainerWidget(QWidget *parent = 0); +signals: + void anchorChanged(bool anchored); +public: + + /** + * @brief 设置和获得锁定/非锁定的图标 + * @param anchoredIcon + */ + void setAnchoredIcon(const QIcon &anchoredIcon); + void setNotAnchoredIcon(const QIcon ¬AnchoredIcon); + + QIcon anchoredIcon() const; + QIcon notAnchoredIcon() const; + + /** + * @brief 当前是否锁定 + * @return + */ + bool isAnchored() const; + + /** + * @brief 设置和获得锁定/非锁定的提示 + * @param anchoredToolTip + * @param notAnchoredToolTip + */ + void setAnchorToolTip(const QString &anchoredToolTip, const QString ¬AnchoredToolTip); + void anchorToolTip(QString &anchoredToolTip, QString ¬AnchoredToolTip) const; + + /** + * @brief 设置是否自动充满客户区。如果设定为真,则在浮动时,会试图使停靠创口保持客户区的高度/宽度。 + * 否则利用sizehint来计算浮动窗口大小 + * @param autoHeight + */ + void setAutoFillHeight(bool autoHeight); + bool isAutoFillHeight() const; + + /** + * @brief 设置标题 + * @param title + */ + void setTitle(const QString &title); + QString title() const; + /** + * @brief 获得title里的toolbar + * @param title + */ + QToolBar* titleToolBar(); + + /** + * @brief 设置隐藏停留时间,ms + * @param interval + */ + void setTimerInterval(int interval = 500); + int timerInterval(); + + +public slots: + /** + * @brief 当锚钉状态解除时 dockWidget隐藏 + */ + void hideWidget(); + + /** + * @brief 当锚钉状态解除时 dockWidget显示 + */ + void showWidget(); + void setAnchored(bool anchored); + + //暂停和恢复隐藏停留计时器 + void pauseTimer(); + void resumeTimer(); +protected: + virtual void leaveEvent(QEvent *); + virtual void enterEvent(QEvent *); + void timerEvent(QTimerEvent *e); +protected: + //不应放开,有了锚定,close和float不需要了,逻辑有误 + void setFloatable(bool floatable); + bool isFloatable() const; + void setClosable(bool closable); + bool isClosable() const; +private slots: + void anchorButtonClicked(); + void leaveHide(); + void setLeaved(bool isLeaved); +signals: + void setHideAndEntered(bool, bool); +private: + void updateFloatAndCloseState(); +private: + //GLDTabDockContainerWidgetAnchorButton *m_anchorButton; + GLDTabDockContainerTitleWidget *m_titleWidget; + QIcon m_anchordIcon; + QIcon m_notAnchoredIcon; + bool m_currentAnchoredState;//default:anchored,true. + bool m_floatable;//true; + bool m_closable;//false; + bool m_autoFillHeight;//true; + QString m_anchoredToolTip; + QString m_notAnchoredToolTip; + int m_timerID; + bool m_bisEntered; + bool m_bisHide; + bool m_bisFloating;//false + int m_interval; +}; + +class GLDWIDGETSHARED_EXPORT GLDTabDockContainerTabBar : public QTabBar +{ + Q_OBJECT +public: + explicit GLDTabDockContainerTabBar(QWidget *parent); + Qt::Orientation textOrientation() const {return m_textOrientation;} + void setTextOrientation(Qt::Orientation textOrientation){m_textOrientation = textOrientation;} + void setTimerInterval(int interval = 500); +signals: + void tabChanged(int currentTab, int preTab); + void tabLeave(); + void setLeaved(bool isLeave); +public slots: + void setHideAndEntered(bool isHide, bool isEntered); +protected: + virtual void mouseMoveEvent(QMouseEvent *event); + virtual void leaveEvent(QEvent *); + virtual void timerEvent(QTimerEvent *e); + virtual void paintEvent(QPaintEvent *event); +private: + int m_curIndex;//-1 + Qt::Orientation m_textOrientation;//Hor + int m_preIndex; + int m_timerID; + bool m_bisHide; + bool m_bisEntered; + int m_interval; +}; + +class GLDWIDGETSHARED_EXPORT GLDTabDockContainerBar : public QWidget +{ + Q_OBJECT + friend class GLDTabDockContainer; +public: + explicit GLDTabDockContainerBar(QWidget *parent); + //void setBar(GLDTabDockContainerInnerTabBar *bar); +public slots: + void selectTab(int idx); + void addDockWidget(GLDTabDockContainerWidget *widget); + void removeDockWidget(GLDTabDockContainerWidget *widget); +private slots: + void currentTabChanged(int cur, int pre); +private: + QToolBar *m_dockToolBar; + GLDTabDockContainerTabBar *m_tabBar; + QList m_tabIndexes; + QList m_dockWidgets; + int m_timerLong; +}; + +class GLDWIDGETSHARED_EXPORT GLDTabDockContainer : public QWidget +{ + Q_OBJECT +public: + // attention! "dockarea" must only have only one area. + explicit GLDTabDockContainer(Qt::DockWidgetArea dockArea, QMainWindow *mainWindow,QWidget *parent); + // the GLDTabDockContianer will delete the widget,before destroy; + //and will be the parent of the widget. + void addTabDockContainerWidget(GLDTabDockContainerWidget *widget); + void hideWidget(); + void showWidget(); + //单位 ms + void setTimerInterval(int interval); + + + // if the parent window is the main window,the fuction is not need. + // if not,the function must be called before addTabDockContainerWidget function. + void setMainWindow(QMainWindow *mainWindow); + void setTabTextForceVertical(bool isTextVertical); + bool isTabTextForceVertical() const; +private slots: + void anchorChanged(bool anchored); +private: + void updateAllWidget(); + Qt::DockWidgetArea m_dockArea; + QMainWindow *m_mainWindow; + GLDTabDockContainerBar *m_bar; + bool m_textForceVertical;//false; + int m_interval; + QList m_dockWidgets; +}; + +#endif//GLD_TABDOCKCONTAINER_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDTableCornerButton.h b/GCR/trunk/Glodon/include/GLD/GLDTableCornerButton.h new file mode 100644 index 00000000..18948f17 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDTableCornerButton.h @@ -0,0 +1,80 @@ +#ifndef GLDTABLECORNERBUTTON_H +#define GLDTABLECORNERBUTTON_H + +#include +#include +#include "GLDWidget_Global.h" + +class QAbstractItemModel; + +class GLDWIDGETSHARED_EXPORT GTableCornerWidget +{ +public: + virtual void setModel(QAbstractItemModel *model) + { + m_model = model; + } + +protected: + QAbstractItemModel *m_model; + +}; + +class GLDWIDGETSHARED_EXPORT GTableCornerbutton : public QAbstractButton, public GTableCornerWidget +{ + Q_OBJECT + +public: + explicit GTableCornerbutton(QWidget *parent = 0); + +signals: + +public slots: + +protected: + void paintEvent(QPaintEvent *); +}; + +class GLDWIDGETSHARED_EXPORT GTableCornerbuttonGraphicsEffect : public QGraphicsEffect +{ +public: + GTableCornerbuttonGraphicsEffect(QObject *parent) + : QGraphicsEffect(parent) + , m_clrStart("#A5AAB3") + , m_clrMid("#A5AAB3") + , m_clrEnd("#A5AAB3") + , m_shadowHeight(3) + { + m_clrMid.setAlpha(40); + m_clrEnd.setAlpha(20); + } + virtual void draw(QPainter *painter); + + virtual QRectF boundingRectFor(const QRectF &rect) const; + + void setStartColor(const QColor &color) + { + m_clrStart = color; + } + void setMidColor(const QColor &color) + { + m_clrMid = color; + } + void setEndColor(const QColor &color) + { + m_clrEnd = color; + } + + void setShadowHeight(int height) + { + m_shadowHeight = height; + } + +private: + QColor m_clrStart; + QColor m_clrMid; + QColor m_clrEnd; + int m_shadowHeight; +}; + +#endif // GLDTABLECORNERBUTTON_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDTableView.h b/GCR/trunk/Glodon/include/GLD/GLDTableView.h new file mode 100644 index 00000000..1f436de3 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDTableView.h @@ -0,0 +1,192 @@ +/*! + *@file GLDTableView.h + *@brief {网格编辑控件} + * + *@remarks {} + *Copyright (c) 1998-2015 Glodon Corporation + */ + +#pragma once + +#include "GLDTableViewBasic.h" + +const GString c_sTableViewQssFile = ":/qsses/GLDTableView.qss"; + +class GlodonTableViewPrivate; +class GlodonTreeDrawInfo; + +class GLDTABLEVIEWSHARED_EXPORT GlodonTableView : public GLDTableView +{ + Q_OBJECT + +public slots: + /*! + *隐藏一行 + *@param[in] row 逻辑行号 + *@return 无 + */ + virtual void hideRow(int row); + void groupChanged(QVector newGroup); + +public: + explicit GlodonTableView(QWidget *parent = 0); + ~GlodonTableView(); + /*! + *树形模式下,展开某一行,可指定是否发送信号 + *@param[in] row 逻辑行号 + *@param[in] emitSignal 是否发送信号 + *@return 无 + */ + void expand(int row, bool emitSignal); + + /*! + *树形模式下,折叠某一行,可指定是否发送信号 + *@param[in] row 逻辑行号 + *@param[in] emitSignal 是否发送信号 + *@return 无 + */ + void collapse(int row, bool emitSignal); + + /*! + *树形模式下,判断某一行是否展开 + *@param[in] row 逻辑行号 + *@return bool + */ + bool isRowExpanded(int row); + + /*! + *树形模式下,展开全部节点 + *@return 无 + */ + virtual void expandAll(); + + /*! + *树形模式下,折叠全部节点 + *@return 无 + */ + virtual void collapseAll(); + + /*! + *设置根节点,通常都是QModelIndex() + *@param[in] index 一般为QModelIndex() + *@return 无 + *@see 参见GlodonAbstractItemView::setRootIndex(const QModelIndex &index) + */ + void setRootIndex(const QModelIndex &index); + + /*! + *获取格子对应的treeModel中的index + *@return 无 + */ + virtual QModelIndex treeIndex(const QModelIndex &index) const; + + /*! + *获取格子对应的dataModel中的index + *@return 无 + */ + virtual QModelIndex dataIndex(const QModelIndex &index) const; + + /*! + *树形显示情况下,获取当前格子对应的dataModel中的index + *@return 无 + */ + QModelIndex currentDataIndex() const; + + /** + * @brief 设置是否树形结构显示 + * 在setModel后使用 + * 调用该方法,会导致之前设置的行高不起作用 + * 建议先调用该方法,再设置行高 + * @param value + */ + void setIsTree(bool value); + bool isTree() const; + + /** + * @brief 设置是否分组模式显示 + * @param value + */ + void setIsGroupMode(bool groupModeEnable); + + bool isGroupMode() const; + + /** + * @brief 设置树形显示下,展开/折叠图标的样式 + * @param style + */ + void setTreeDecorationStyle(TreeDecorationStyle style); + TreeDecorationStyle treeDecorationStyle() const; + + void setTreeDrawInfo(GlodonTreeDrawInfo *tableViewDrawInfo); + GlodonTreeDrawInfo *treeDrawInfo(); + + /** + * @brief 在树形结构时,选择折叠的父,是否同时选择子 + * @return + */ + bool isAddChildToSelection(); + void setAddChildToSelection(bool value); + + /** + * @brief 设置树形结构所在的列号 + * @param column + */ + void setTreeColumn(int column); + int treeColumn(); + +protected slots: + void reBuildTree(); + + virtual void dataChanged(const QModelIndex &topLeft, + const QModelIndex &bottomRight, + const QVector &roles); + +protected: + explicit GlodonTableView(GlodonTableViewPrivate &dd, QWidget *parent = 0); + + void doSetIsTree(bool value); + virtual void doSetModel(QAbstractItemModel *model); + + /*! + * \brief cellShowTreeWidthOffset + * \return 为了显示树形的格子的文字区将进行的水平方向的偏移(主要是树干的细线和branch图标占去的宽度) + */ + int treeCellDisplayHorizontalOffset(int row, int col, bool isOldMinTextHeightCalWay = true) const; + + virtual void onBoolCellPress(QMouseEvent *event); + virtual void onMousePress(QMouseEvent *event); + virtual bool event(QEvent *event); + + virtual QAbstractItemModel* itemModel(); + +private: + /** + * @brief 如果当前节点为折叠状态,那么当选择它时,把它所有的子都增加到selection中 + * @param topLeft + * @param bottomLeft + * @param selection 当前需要添加到selectionModel中的selection + * @param isRowSelect 如果是行选状态,则不需要判断该行是否处于折叠 + */ + void setChildSelection(const QModelIndex &topLeft, const QModelIndex &bottomRight, + QItemSelection &selection, bool isRowSelect); + + void doGMExpand(GLDEvent *event); + + void doGMQueryExpand(GLDEvent *event); + + void doGMCollapse(GLDEvent *event); + + void doGMQueryCollapse(GLDEvent *event); + + void doGMExpandAll(GLDEvent *event); + + void doGMQueryExpandAll(GLDEvent *event); + + void doGMCollapseAll(GLDEvent *event); + + void doGMQueryCollapseAll(GLDEvent *event); + +private: + Q_DECLARE_PRIVATE(GlodonTableView) + Q_DISABLE_COPY(GlodonTableView) +}; diff --git a/GCR/trunk/Glodon/include/GLD/GLDTableViewBasic.h b/GCR/trunk/Glodon/include/GLD/GLDTableViewBasic.h new file mode 100644 index 00000000..94354aa1 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDTableViewBasic.h @@ -0,0 +1,1755 @@ +/*! + *@brief {网格编辑控件} + * + *@date 2015.1.6 + *@remarks {} + *Copyright (c) 1998-2015 Glodon Corporation + */ + +#pragma once + +#include +#include + +#include "GLDHeaderView.h" +#include "GLDAbstractItemView.h" +#include "GLDTableCornerButton.h" +#include "GLDIntList.h" +#include "GLDList.h" +#include "GLDCustomCommentFrame.h" + +class GlodonScrollBar; + +struct GlodonTableViewPainterInfo; + +const int c_MinColWidth = 10; // 列双击自动调整宽度时最小宽度 +const int c_Indent = 10; // 标识层次关系的树线之间的距离 +const int c_HalfWidth = 5; // 内部有加减号的正方形的一半宽度 +const int c_CheckBoxWidth = 13; // 复选框宽度 + +/*! + *@class: GSpanCollection + *@brief {用于处理所有合并格相关功能} + *@author Gaosy + *@date 2012.9.7 + */ +class GLDTABLEVIEWSHARED_EXPORT GSpanCollection +{ +public: + struct GSpan + { + int m_top; + int m_left; + int m_bottom; + int m_right; + bool will_be_deleted; + GSpan() + : m_top(-1), m_left(-1), m_bottom(-1), m_right(-1), will_be_deleted(false) { } + + GSpan(int row, int column, int rowCount, int columnCount) + : m_top(row), m_left(column), m_bottom(row + rowCount - 1), m_right(column + columnCount - 1), + will_be_deleted(false) { } + + inline int top() const + { + return m_top; + } + inline int left() const + { + return m_left; + } + inline int bottom() const + { + return m_bottom; + } + inline int right() const + { + return m_right; + } + inline int height() const + { + return m_bottom - m_top + 1; + } + inline int width() const + { + return m_right - m_left + 1; + } + }; + + ~GSpanCollection() + { + clear(); + } + + void addSpan(GSpan *span); + void updateSpan(GSpan *span, int old_height); + GSpan *spanAt(int x, int y) const; + void clear(); + QList spansInRect(int x, int y, int w, int h) const; + + void updateInsertedRows(int start, int end); + void updateInsertedColumns(int start, int end); + void updateRemovedRows(int start, int end); + void updateRemovedColumns(int start, int end); + + typedef QLinkedList SpanList; + SpanList spans; + +private: + typedef QMap SubIndex; + typedef QMap Index; + Index m_nIndex; + + bool cleanSpanSubIndex(SubIndex &subindex, int end, bool update = false); +}; + +Q_DECLARE_TYPEINFO(GSpanCollection::GSpan, Q_MOVABLE_TYPE); + +/** + * @brief + * top<<0, bottom<<8, left<<16, right<<24 + */ +union GBorderLineWidthHelper +{ + enum + { + top, + bottom, + left, + right, + count + }; + + int widths; + unsigned char lineWiths[count]; +}; + +enum TreeDecorationStyle +{ + NoDecoration, + NormalStyle, + NormalNoLineStyle, + OSStyle +}; + +enum Margin +{ + LeftMargin, + RightMargin, + TopMargin, + BottomMargin +}; + +enum UpdateHeaderViewType +{ + uhVertical, + uhHorizontal, + uhBoth +}; + +enum RangeFillingStyle +{ + rfsVertical, + rfsHorizontal, + rfsBoth +}; + +enum SelectBorderWidth +{ + TwoPixel = 2, + ThreePixel = 3 +}; + +/*! + *@class: GlodonTableView + *@brief {网格编辑控件,提供了数据编辑、显示等功能,支持树形结构显示} + *@author Gaosy + *@date 2012.9.7 + */ +class GLDTABLEVIEWSHARED_EXPORT GLDTableView : public GlodonAbstractItemView +{ + Q_OBJECT + + Q_PROPERTY(bool showGrid READ showGrid WRITE setShowGrid) + Q_PROPERTY(Qt::PenStyle gridStyle READ gridStyle WRITE setGridStyle) + Q_PROPERTY(bool sortingEnabled READ isSortingEnabled WRITE setSortingEnabled) + Q_PROPERTY(bool wordWrap READ wordWrap WRITE setWordWrap) + Q_PROPERTY(bool cornerButtonEnabled READ isCornerButtonEnabled WRITE setCornerButtonEnabled) + Q_PROPERTY(int fixedRowCount READ fixedRowCount WRITE setFixedRowCount) + Q_PROPERTY(int fixedColCount READ fixedColCount WRITE setFixedColCount) + +public: + explicit GLDTableView(QWidget *parent = 0); + ~GLDTableView(); + + /** + * @brief 设置tableView的Model + * @param model + */ + void setModel(QAbstractItemModel *model); + + /*功能选项相关*/ + + /** + * @brief 是否处于编辑状态 + * @return + */ + bool isEditing() const; + /** + * @brief 判断给定的行,列对应的格子是否能进入编辑状态(与ReadOnly不同) + * @param row + * @param column + * @return + */ + bool cellCanGetEdit(int row, int column); + + /** + * @brief 是否显示过滤行 + * @return + */ + virtual bool isDisplayFilter(); + + /** + * @brief 是否是合计行位于表脚 + * @return + */ + virtual bool totalRowAtFooter() const; + + /** + * @brief 设置是否允许排序 + * @param enable + */ + void setSortingEnabled(bool enable); + bool isSortingEnabled() const; + + /** + * @brief + * 设置自动行高 + * + * @details + * 表格会根据列宽和控件默认大小来自动计算给定的行高 + * + * @param accordingCols 自动计算行高参考的列宽的列 + */ + void setSuitRowHeights(const GIntList &accordingCols); + GIntList suitRowHeights(); + + /** + * @brief + * 设置自动列宽 + * + * @details + * 表格会根据列中的内容和控件默认大小自动计算给定的列宽 + * + * @param suitColWidths 自动计算列宽的列 + */ + void setSuitColWidths(const GIntList &suitColWidthCols); + GIntList suitColWidths(); + + /** + * @brief + * 设置合适列宽 + * + * @details + * 表格会根据其它列的情况自动计算给定的列宽 + * + * @param fitColWidths 固定列宽的列 + */ + void setFitColWidths(const GIntList &fitColWidthsCols); + GIntList fitColWidths(); + + /** + * @brief 设置是否允许复制 + * @param allowCopy + */ + void setAllowCopy(bool allowCopy); + bool allowCopy() const; + + /** + * @brief 设置是否允许粘贴 + * @param allowPaste + */ + void setAllowPaste(bool allowPaste); + bool allowPaste() const; + + /** + * @brief 设置左上角Button是否可用 + * @param enable + */ + void setCornerButtonEnabled(bool enable); + bool isCornerButtonEnabled() const; + + /** + * @brief 设置新的控件(如果是可以设置模型的则会自动绑定) + * @param widget + */ + void setCornerWidget(QWidget *widget); + QWidget *cornerWidget() const; + + /** + * @brief 设置是否允许选择填充(与行选互斥) + * @param enable + */ + void setAllowRangeFilling(bool enable); + bool allowRangeFilling() const; + + /** + * @brief 选择填充的样式(只允许垂直,水平,或者都可以) + * @param style + */ + void setRangeFillingStyle(RangeFillingStyle style); + RangeFillingStyle rangeFillingStyle(); + + /** + * @brief 设置是否允许行选(点击垂直表头,选中一整行) + * @return + */ + bool allowSelectRow() const; + void setAllowSelectRow(bool value); + + /** + * @brief 设置是否允许列选(点击水平表头,选中一整列) + * @return + */ + bool allowSelectCol() const; + void setAllowSelectCol(bool value); + + /** + * @brief 设置选中填充时,是否使用EditRole + * @return + */ + bool cellFillEditField() const; + void setCellFillEditField(bool value); + + /*! + *设置固定可编辑列数 + *@param[in] fixedColCount 固定可编辑列数 + *@return 无 + */ + virtual void setFixedColCount(int fixedColCount); + int fixedColCount() const; + + /*! + *设置固定可编辑行数 + *@param[in] fixedRowCount 固定可编辑行数 + *@return 无 + */ + void setFixedRowCount(int fixedRowCount); + int fixedRowCount() const; + + /** + * @brief 设置是否延迟刷新 + * @param delay + */ + void setResizeDelay(bool delay); + + /** + * @brief 设置是否允许框选拖拽 + * @param value + */ + void setAllowRangeMoving(bool value); + bool allowRangeMoving() const; + + /*! + *判断给定逻辑行是否隐藏,true表示隐藏,false表示显示 + *@param[in] row 逻辑行号 + *@return bool + */ + bool isRowHidden(int row) const; + + /*! + *设置给定逻辑行的隐藏状态 + *@param[in] row 逻辑行号 + *@param[in] hide true表示隐藏,false表示显示 + *@return 无 + */ + void setRowHidden(int row, bool hide); + + /*! + *判断给定逻辑列是否隐藏,true表示隐藏,false表示显示 + *@param[in] column 逻辑列号 + *@return bool + */ + bool isColumnHidden(int column) const; + /*! + *设置给定逻辑列的隐藏状态 + *@param[in] column 逻辑列号 + *@param[in] hide true表示隐藏,false表示显示 + *@return 无 + */ + void setColumnHidden(int column, bool hide); + + /*! + *滚动到给定的index处 + *@param[in] index + *@param[in] hint 滚动方式 + *@return 无 + */ + void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible); + + /*! + *根据给定的逻辑行列号,返回该格子所处合并格包含的行数 + *@param[in] row 逻辑行号 + *@param[in] column 逻辑列号 + *@return int + */ + int rowSpan(int row, int column) const; + + /*! + *根据给定的逻辑行列号,返回该格子所处合并格包含的列数 + *@param[in] row 逻辑行号 + *@param[in] column 逻辑列号 + *@return int + */ + int columnSpan(int row, int column) const; + + /*! + * \brief 根据绝对行列号,返回合并格最左上角格子的QModelIndex(仅限可见区域) + * \param row + * \param column + * \return + */ + QModelIndex spanAt(int row, int column); + + /** + * @brief 根据给定的列排序 + * @param column + * @param order + */ + void sortByColumn(int column, Qt::SortOrder order); + + /** + * @brief 框选拖拽时,把原位置的内容清除,填充到新的位置 + * @param src + * @param dest + */ + void doRangeMoving(QRect src, QRect dest); + + /** + * @author duanb + * @param bCanCopyText 通知用户改选择区域是否可以进行复制 + * @return GString + * 复制选中内容到剪切板 + */ + GString copyTextFromSelections(bool* bCanCopyText = 0); + bool pasteFromClipboard(); + + /** + * @brief 把区域转换成一个QModelIndex的List集合 + * @param rect 需要转换的区域 + * @return + */ + QList rangeToList(QRect rect); + + /** + * @brief 把焦点设置到当前正在处于编辑状态的控件上 + */ + void resetEditorFocus(); + /** + * @brief 水平表头 + * @return + */ + GlodonHeaderView *horizontalHeader() const; + virtual void setHorizontalHeader(GlodonHeaderView *header); + + /** + * @brief 垂直表头 + * @return + */ + GlodonHeaderView *verticalHeader() const; + void setVerticalHeader(GlodonHeaderView *header); + + /** + * @brief 设置在tableView的右下角显示一个带省略号的button + * @param value + */ + void setShowEllipsisButton(bool value); + bool isShowEllipsisButton(); + + /** + * @brief 设置非编辑状态时,显示编辑方式 + * @return + */ + GlodonAbstractItemView::EditStyleDrawType editStyleDrawType() const; + void setEditStyleDrawType(GlodonAbstractItemView::EditStyleDrawType drawType); + + /*外观相关选项*/ + /** + * @brief 设置是否显示格线 + * @param show + */ + void setShowGrid(bool show); + bool showGrid() const; + + /*! + * \brief 在横向表头或则纵向表头隐藏时,是否绘制边框线 + * \param value + */ + void setDrawTopAndLeftBorderLine(bool value); + bool drawTopAndLeftBorderLine(); + + /** + * @brief 设置格线样式(实线,虚线等) + * @return + */ + void setGridStyle(Qt::PenStyle style); + Qt::PenStyle gridStyle() const; + + void setWordWrap(bool on); + bool wordWrap() const; + + /** + * @brief 设置选中单元格对应的表头是否高亮显示 + * @return + */ + void setHighlightSections(bool value); + bool highlightSections() const; + + /** + * @brief 设置格线宽度 + * @param value + */ + void setGridLineWidth(int value); + int gridLineWidth() const; + + /** + * @brief 设置格线颜色 + * @param value + */ + virtual void setGridLineColor(QColor value); + QColor gridLineColor() const; + + /*! + * \brief 在表头隐藏,且滚动模式为Item时,绘制的整个表格上边框或者左边框线的颜色 + * \param value + */ + void setFrameLineColor(QColor value); + QColor frameLineColor() const; + + /*! + *设置选择框的颜色 + * \param value + */ + void setSelectedBoundLineColor(QColor value); + QColor selectedBoundLineColor() const; + + /*! + *设置选择框的线宽(默认为2) + * \param value + */ + void setSelectedBoundLineWidth(SelectBorderWidth lineWidth); + int selectedBoundLineWidth() const; + + /*! + *设置失去焦点,选择框的颜色 + * \param value + */ + void setNoFocusSelectedBoundLineColor(QColor value); + QColor NoFocusSelectedBoundLineColor() const; + + /** + * @brief 设置是否有垂直方向格线 + * @param value + */ + void setShowVerticalGridLine(bool value); + bool showVerticalGridLine() const; + + /** + * @brief 是否有水平方向的格线 + * @return + */ + void setShowHorizontalGridLine(bool value); + bool showHorizontalGridLine() const; + + /** + * @brief 设置表格背景色 + * @param value + */ + void setGridColor(QColor value); + + /** + * @brief 设置显示当前选中格子的背景色 + * @param showBackColor + */ + void setShowCurCellBackgroundColor(bool showBackColor) { m_bShowCurCellBackgroundColor = showBackColor; } + bool showCurCellBackgroundColor() { return m_bShowCurCellBackgroundColor; } + + /** + * @brief 设置是否是自定义风格 + * @return + */ + bool isCustomStyle() const; + void setIsCustomStyle(bool value); + + /** + * @brief 根据提供的缩放英子,缩放TableView + * @param factor + */ + void zoomTableView(double factor); + + /** + * @brief 设置焦点格所在的行的背景色都变成被选择时的颜色 + * @param isShow + */ + void setAlwaysShowRowSelectedBgColor(bool isShow); + bool alwaysShowRowSelectedBgColor(); + + /*! + *是否允许通过单元格格线改变行高列宽,默认值为false + *@return 无 + */ + void setAllowResizeCellByDragGridLine(bool canResize); + bool allowResizeCellByDragGridLine(); + + /** + * @brief 设置回车跳格,如果只开启enterJump时,跳格的执行流程为 + * 1、如果没有进入编辑方式,按Enter—》进入编辑方式-》按Enter-》退出编辑方式并且焦点移动到下一格子-》按Enter + * -》进入编辑方式 + * 2、如果已经处于编辑方式,按Enter-》退出编辑方式并且焦点移动到下一个格子 + * @return + */ + bool enterJump() const; + void setEnterJump(bool value); + + /** + * @brief 设置简化版回车跳格,开启enterJump,同时开启enterJumpPro时,跳格的执行流程为 + * 1、如果没有进入编辑方式,按Enter-》进入编辑方式-》按Enter-》退出编辑方式,焦点移动到下一个格子,并且使 + * 下一格子进入编辑方式-》按Enter-》退出编辑方式,焦点移动到下一个格子,并且使下一格子进入编辑方式 + * 2、如果已经处于编辑方式,按Enter-》退出编辑方式,焦点移动到下一个格子,并且使下一格子进入编辑方式 + * @return + */ + bool enterJumpPro() const; + void setEnterJumpPro(bool value); + + /** + * @brief 设置是否使用混合背景色(当前选中格子的背景色为格子本身的颜色的混色,默认为蓝色) + * @return + */ + void setUseBlendColor(bool value); + bool useBlendColor() const; + + /** + * @brief 设置选择区域的背景颜色 + * @return + */ + void setSelectedCellBackgroundColor(QColor value); + QColor selectedCellBackgroundColor() const; + + /*编辑相关*/ + /*! + *给定的index格子进入编辑状态 + *@param[in] index + *@return 无 + */ + void edit(const QModelIndex &index); + + /** + * @brief 强制退出编辑状态,与按Esc效果一致 + */ + void forceCloseEditor(); + + /** + * @brief 设置是否显示调整列宽,行高时的信息提示框,默认值为true + * @param value + */ + void setDisplayResizeInfoFrame(bool value); + + /*! + * \brief 插入批注 + * \param index + * \param value + */ + GCustomCommentFrame *addComment(const QModelIndex &index, QString value); + + /*! + * \brief 编辑批注 + * \param index + */ + GCustomCommentFrame *editComment(const QModelIndex &index); + + /*! + * \brief 显示/隐藏批注 + * \param index + * \param isShow + */ + GCustomCommentFrame *showOrHideCommentPersistent(const QModelIndex &index, bool isShow = true); + + /*! + * \brief 该备注框是否是显示 + * \param index + * \return + */ + bool isShowComment(const QModelIndex &index); + + /*! + * \brief 删除批注 + * \param index + */ + void deleteComment(const QModelIndex &index); + + /*! + * \brief 显示或隐藏所有批注 + * \param isShow + */ + void showOrHideAllCommentPersistent(bool isShow = true); + + /*! + * \brief 返回当前index的批注框对象 + * \param index + */ + const GCustomCommentFrame *findComment(const QModelIndex &index) const; + + /** + * @brief 设置所有标注框是否刷新。该接口是为了避免标注框的连续多次绘制,导致tableview reset时行高失效。 + * 将多次绘制汇聚到最后一次,加快程序效率,也避免了tableview属性失效问题 + * @param enable 参数为真,所有标注框设置为刷新,并且所有标注框立即刷新一次 + */ + void setCommentsUpdatesEnabled(bool enable); + + /** + * @brief 是否失去焦点退出编辑状态 + * @return + */ + bool closeEditorOnFocusOut(); + /** + * @brief 设置是否失去焦点退出编辑状态 + * @param value + * @param ignoreActiveWindowFocusReason 是否忽略由其他程序引起的失去焦点 + */ + void setCloseEditorOnFocusOut(bool value, bool ignoreActiveWindowFocusReason = false); + + /*! + * \brief 设置在创建comboBox编辑方式时,是否使用自动提示功能,默认为提示 + * \return + */ + bool useComboBoxCompleter() const; + void setUseComboBoxCompleter(bool value); + + /*刷新相关*/ + + /*! + *重置整个表体,重新绘制 + *@return 无 + *@see 参见GlodonAbstractItemView::doItemsLayout() + */ + void doItemsLayout(); + + /** + * @brief 重新计算自动行高列宽,合适列宽 + */ + virtual void refreshDisplayColRow(); + /** + * @brief 刷新一个格子(在开启填充或者选择移动功能的时候,黑框不在刷新范围之内) + * @param logicIndex只在有行列移动时,logicalIndex和visualIndex不同 + */ + void updateModelIndex(const QModelIndex &logicIndex); + + virtual void update(const QModelIndex &logicalIndex); + + /** + * @brief 刷新一列 + * @param col + */ + void updateCol(int col); + + /** + * @brief 刷新一行 + * @param row + */ + void updateRow(int row); + + /** + * @brief 刷新整个tableView + */ + void updateAll(); + + /** + * 更新类型 + */ + void updateHeaderView(const UpdateHeaderViewType updateType); + + /*QModelIndex相关*/ + /*! + * TODO: delete + *@return 无 + */ + virtual QModelIndex treeIndex(const QModelIndex &index) const; + + /*! + *TODO: delete + *@return 无 + */ + virtual QModelIndex dataIndex(const QModelIndex &index) const; + /*! + *TODO: delete + *@param[in] pos 坐标点 + *@return QModelIndex + */ + QModelIndex indexAt(const QPoint &pos) const; + + /** + * @brief 显示Index转换为逻辑Index + * @param visualIndex + * @return + */ + QModelIndex logicalIndex(QModelIndex visualIndex); + /** + * @brief 逻辑Index转换为显示Index + * @param logicalIndex + * @return + */ + QModelIndex visualIndex(const QModelIndex &logicalIndex); + + /*! + *返回所有被选中的QModelIndex + *@return QModelIndexList + */ + QModelIndexList selectedIndexes() const; + + /** + * @brief 传入一个有行号列号组成的rect,返回一个dataIndex集合 + * @param rect + * @return + */ + QModelIndexList indexesFromRect(QRect rect, int &rowCount, int &columnCount); + + /*计算位置相关*/ + /*! + *根据给定的逻辑行号,返回其绘制位置 + *@param[in] row 逻辑行号 + *@return int + */ + int rowViewportPosition(int row) const; + + /** + * @brief 根据给定的显示行号,返回其绘制位置(减去了滚动条偏移) + * @param visualRow 显示行号 + * @return + */ + int rowVisualPosition(int visualRow) const; + + /*! + *根据给定y坐标,返回该位置的逻辑行号 + *@param[in] y y方向坐标 + *@return int + */ + int rowAt(int y) const; + /** + * @brief 根据给定的y坐标,返回该位置的显示行号 + * @param y + * @return + */ + int visualRowAt(int y) const; + + /*! + *设置行高 + *@param[in] row 逻辑行号 + *@param[in] height 新行高 + *@param[in] isManual 是否自定义,影响是否写入Model + *@return 无 + */ + void setRowHeight(int row, int height, bool isManual = true); + + /*! + *根据给定逻辑行号,返回行高 + *@param[in] row 逻辑行号 + *@return int + */ + int rowHeight(int row) const; + + /** + * @brief 根据给定显示列号,返回行高 + * @param visualRow 显示列号 + * @return + */ + int visualRowHeight(int visualRow) const; + + /*! + *根据给定的逻辑列号,返回其绘制位置 + *@param[in] column 逻辑列号 + *@return int + */ + int columnViewportPosition(int column) const; + + /** + * @brief 根据给定的显示列号,返回其绘制位置(减去了滚动条偏移) + * @param visualColumn 显示列号 + * @return + */ + int columnVisualPosition(int visualColumn) const; + + /*! + *根据给定x坐标,返回该位置的逻辑列号 + *@param[in] x x方向坐标 + *@return int + */ + int columnAt(int x) const; + + /** + * @brief 根据给定x坐标,返回该位置的显示列号 + * @param x + * @return + */ + int visualColumnAt(int x) const; + + /*! + *设置列宽 + *@param[in] column 逻辑列号 + *@param[in] width 新列宽 + *@return 无 + */ + void setColumnWidth(int column, int width); + + /*! + *根据给定逻辑列号,返回列宽 + *@param[in] column 逻辑列号 + *@return int + */ + int columnWidth(int column) const; + + /** + * @brief 根据给定显示列号,返回列宽 + * @param visualColumn 显示列号 + * @return + */ + int visualColumnWidth(int visualColumn) const; + + /*! + *返回给定logicIndex的绘制位置 + *@param[in] index + *@return QRect + */ + QRect visualRect(const QModelIndex &index) const; + + /** + * @brief 根据显示行列组成的Rect计算出绘制的位置 + * @param rowColNo + * @return + */ + QRect visualRectForRowColNo(const QRect &rowColNo); + + /*! + *设置QItemselectionModel,用于记录当前已选择区域 + *@param[in] selectionModel + *@return 无 + *@see 参见GlodonAbstractItemView::setSelectionModel(QItemSelectionModel *selectionModel) + */ + void setSelectionModel(QItemSelectionModel *selectionModel); + + /*! + *打印功能,尚未实现 + *@return 无 + */ + void print(); + + /*! + * \brief 设置格线是否分段绘制,关闭这功能,能提高绘制效率 + * \param drawBoundLine + */ + void setDrawBoundLine(bool drawBoundLine); + bool drawBoundLine(); + +public Q_SLOTS: + /*! + *选择一行 + *@param[in] row 逻辑行号 + *@return 无 + */ + void selectRow(int row); + + /*! + *选择一列 + *@param[in] column 逻辑列号 + *@return 无 + */ + void selectColumn(int column); + + /*! + *隐藏一行 + *@param[in] row 逻辑行号 + *@return 无 + */ + virtual void hideRow(int row); + + /*! + *隐藏一列 + *@param[in] column 逻辑列号 + *@return 无 + */ + void hideColumn(int column); + + /*! + *显示一行 + *@param[in] row 逻辑行号 + *@return 无 + */ + void showRow(int row); + + /*! + *显示一列 + *@param[in] column 逻辑列号 + *@return 无 + */ + void showColumn(int column); + + /*! + *将给定逻辑行resize到适合内容的高度 + *@param[in] row 逻辑行号 + *@return 无 + */ + void resizeRowToContents(int row); + + /*! + * \brief 根据格子内容计算所有行的行高,并应用 + */ + void resizeRowsToContents(); + + /*! + *将给定逻辑行resize到适合内容的高度 + *@param[in] column 逻辑列号 + *@return 无 + */ + void resizeColumnToContents(int column); + + /*! + * \brief 根据格子内容计算所有列的列宽,并应用 + */ + void resizeColumnsToContents(); + + /*! + *将所有的行高调整到合适高度 + *@param[in] calcAllColumns 是否依照所有列进行计算 + *@return 无 + */ + void setSuitRowHeightForAll(bool value, bool calcAllColumns = false); + + /*! + *将所有的列宽调整到合适宽度 + *@param[in] calcAllRows 是否依照所有行进行计算 + *@return 无 + */ + void setSuitColWidthForAll(bool value, bool calcAllRows = false); + + void sortByColumn(int column); + + /*! + *选择连续的逻辑列 + *@param[in] start 逻辑列号 + *@param[in] end 逻辑列号 + *@return 无 + */ + void selectColumns(int start, int end); + + /*! + *选择连续的逻辑行 + *@param[in] start 逻辑行号 + *@param[in] end 逻辑行号 + *@return 无 + */ + void selectRows(int start, int end); + void setCurrentIndex(const QModelIndex &dataIndex); + /** + * @brief 通过行号,列号,设置焦点格,改行号,列号为绝对行号列号,没有父子结构 + * @param row + * @param column + */ + void setCurrentIndex(int row, int column); + void onScrolled(int offset); + +protected slots: + void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles = QVector()); + + void closeEditor(QWidget *editor, bool &canCloseEditor, GlodonDefaultItemDelegate::EndEditHint hint); + void commitData(QWidget *editor, bool &canCloseEditor); + + void canRowMoved(int from, int to, bool &canMove); + void rowMoved(int row, int oldIndex, int newIndex); + void canColumnMoved(int from, int to, bool &canMove); + void columnMoved(int column, int oldIndex, int newIndex); + void rowResized(int row, int oldHeight, int newHeight, bool isManual); + /** + * @brief ColumnHeaderView调整大小时,会调用该槽,当用了filterTableView,footTableView,GSPTableView + * 时,会先调用子类的调整大小方法,然后调用该方法,这样就避免了在自动列宽,合适列宽出现filterTableView + * 大小调整不对的情况 + * @param column + * @param oldWidth + * @param newWidth + */ + virtual void columnResized(int column, int oldWidth, int newWidth, bool isManual = false); + void rowCountChanged(int oldCount, int newCount); + void columnCountChanged(int oldCount, int newCount); + + /** + * @brief 调整行(列)大小时,计算当前行(列)调整的大小,并且画提示框(黑线在paint方法中) + * @param mousePostion 鼠标的位置 + * @param direction headerview的方向 + * @param state 当前动作的状态(mousePress, mouseMove, mouseRelease) + */ + virtual void showSectionResizingInfoFrame(const QPoint &mousePosition, Qt::Orientation direction, GlodonHeaderView::ResizeState state); + +Q_SIGNALS: + void rangeFill(QRect src, QRect dest, bool &handled); + void rangeFill(QModelIndexList src, QModelIndexList dest, int rowCount, int ColumnCount, bool &handled); + + void expanded(int index); + void collapsed(int index); + + void onEllipsisButtonClick(); + + //for分页表格 + void columnNewWidths(GIntList *newWidths); + void enableFitColWidths(bool enable); + +protected: + GLDTableView(GLDTableViewPrivate &, QWidget *parent); + + virtual void doSetModel(QAbstractItemModel *model); + virtual bool canRangeFill(const QRect &rect); + bool doCanRangeFill(const QRect &rect); + + void scrollContentsBy(int dx, int dy); + bool isEditorInFixedColAfterHScroll(); + bool isEditorInFixedRowAfterVScroll(); + + QStyleOptionViewItem viewOptions() const; + + /*! + *调整TableView中各个部件的布局 + *@return 无 + */ + void updateGeometries(); + + void paintEvent(QPaintEvent *e); + void timerEvent(QTimerEvent *event); + + virtual void onBoolCellPress(QMouseEvent *event); + virtual void onMousePress(QMouseEvent *event); + virtual void mousePressEvent(QMouseEvent *event); + + bool viewportEvent(QEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mouseDoubleClickEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void keyPressEvent(QKeyEvent *event); + void resizeEvent(QResizeEvent *event); + void leaveEvent(QEvent *event); + void wheelEvent(QWheelEvent *event); + void focusOutEvent(QFocusEvent *event); + void showEvent(QShowEvent *event); + + int horizontalOffset() const; + int verticalOffset() const; + QModelIndex moveCursor(GlodonAbstractItemView::CursorAction cursorAction, Qt::KeyboardModifiers modifiers); + + void setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command); + /** + * @brief 根据实际选择的区域设置selection(实际选择区域与逻辑选择区域在有行列移动时有区别) + * @param visualTL 实际选择区域的topLeftModelIndex + * @param visualBR 实际选择区域的bottomRightModelIndex + * @param command + */ + void setSelectionByIndex( + const QModelIndex &visualTL, const QModelIndex &visualBR, + QItemSelectionModel::SelectionFlags command); + + QRegion visualRegionForSelection(const QItemSelection &selection) const; + QRegion visualRegionForSelectionWithSelectionBounding(const QItemSelection &selection) const; + int sizeHintForRow(int row) const; + int sizeHintForColumn(int column) const; + + int calcSuitHeight(const QList &oNeedCalcHeightCols, int nLogicalRow); + int calcSuitWidth(int nLogicalCol); + + void verticalScrollbarAction(int action); + void horizontalScrollbarAction(int action); + + bool isIndexHidden(const QModelIndex &index) const; + + bool inBoolCell(const QPoint pos) const; + + void selectionChanged(const QItemSelection &selected, + const QItemSelection &deselected); + void currentChanged(const QModelIndex ¤t, + const QModelIndex &previous); + + bool isLegalData(); + void setLegalData(bool value); + + bool event(QEvent *event); + + /*! + * \brief 获取第一个可见行,在有固定行时,获取的是第一个非固定区域的可见行 + * \return + */ + int firstVisualRow() const; + int lastVisualRow() const; + + /*! + * \brief 获取第一个可见列,在有固定列时,获取的是第一个非固定区域的可见列 + * \return + */ + int firstVisualCol() const; + int lastVisualCol() const; + + GIntList needCalcSuitRowHeightColsInViewport(); + + /** + * @brief 获取传入的Rect左上角的ModelIndex + * @param rowColRect + * @return + */ + QModelIndex topLeftIndex(const QRect &rowColRect) const; + /** + * @brief 获取传入的Rect的右下角的ModelIndex + * @param rowColRect + * @return + */ + QModelIndex bottomRightIndex(const QRect &rowColRect) const; + + void bindMergeCell(); + + virtual void rebuildGridRows(const GLDList &arrRows); + + /*! + * TODO: delete + * \return 为了显示树形的格子的文字区将进行的水平方向的偏移(主要是树干的细线和branch图标占去的宽度) + */ + virtual int treeCellDisplayHorizontalOffset(int row, int col, bool isOldMinTextHeightCalWay = true) const; + void doMoveCurrent(const QModelIndex &oldIndex, const QModelIndex &newIndex, + QItemSelectionModel::SelectionFlags command, MoveReason moveReason); + + virtual QAbstractItemModel* itemModel() + { + return model(); + } + + inline int currentGridLineWidth() const; + inline QPen currentGridPen(); + + bool edit(const QModelIndex &index, EditTrigger trigger, QEvent *event); + void syncStateToDelegate(GlodonDefaultItemDelegate *delegate); + + void beforeReset(); + void doReset(); + void afterReset(); + + /** + * @brief 拖拉复制时,填充内容(src,和dest都是由ModelIndex组成,且都是界面显示的位置,重写该方法,实现自己的填充逻辑 + * 时,需要将显示的位置改为逻辑位置) + * @param src 原选择区域 + * @param dest 填充的目标区域 + */ + virtual void doRangeFill(); + + /*! + *@brief 整个表体的绘制 + *@param[in] painter 画笔 + *@param[in] drawRegion 绘制区域 + *@return 无 + */ + void paint(QPainter &painter, const QRegion &drawRegion); + +protected: + virtual void afterCurrentChanged(const QModelIndex ¤t, const QModelIndex &previous); + virtual void afterExpandedChanged(int index, bool expand, bool emitSignal); + virtual void afterManualChangedRowHeight(int index, int rowHeight); + virtual void afterManualChangedColWidth(int index, int colWidth); + +protected: + QRect m_oRangeSrc; + QRect m_oRangeDest; + QRect m_tempRangeRect;//用来临时存储选择移动时计算出来的Rect + QRect m_preTempRangeRect;//用来临时存储选择移动时,之前的Rect + int m_nRangeCurRow; + int m_nRangeCurCol; + QRect m_dirtyArea; + bool m_bShowCurCellBackgroundColor; //是否显示选中区域中当前单元格的背景色 + +protected: + void drawCellBorderLine( + QPainter &painter, const QRect &cellRect, const QRegion &spans, + int gridLineWidth, int borderLineWidth, const QVariant &borderLineColor, Qt::Orientation direction); + + void drawCellBorderLine( + QPainter &painter, const QLine& line, bool needDraw); + + virtual void drawCellBorderLine( + QPainter &painter, const QRect &cellRect, const QRegion &spans, + const QModelIndex &index); + + /** + * @brief 重置EllipsisButton的位置 + */ + virtual void resetEllipsisButtonLocation(); + + /** + * @brief + * 如果水平和垂直表头不可见,则需要在表格的上边和左边绘制框线. + + @details + 我们只需要在滚动相关的函数被调用时更新这两条线即可 + + * @param painter + */ + virtual void drawTopAndLeftBorderLine(QPainter &painter); + + void drawEachRow(QPainter &painter, QRegion &spans, const QRect ¶ms); + void drawEachColumn(QPainter &painter, QRegion &spans, const QRect ¶ms); + + /** + * @brief 设置bool值到model中 + * @param currIndex + */ + void setBoolEditValue(QModelIndex &currIndex); + +protected: + // 重构updateGeometries + void updateVerticalHeaderGeometry(int nVerticalHeaderWidth); + void updateHorizontalHeaderGeometry(int nHorizontalHeaderHeight); + void updateConrnerWidgetGeometry(int nVerticalHeaderWidth, int nHorizontalHeaderHeight); + void updateHorizontalScrollBar(const QSize &oViewportSize); + void updateVerticalScrollBar(const QSize &oViewportSize); + int colCountBackwardsInViewPort(const QSize &oViewportSize); + int rowCountBackwardsInViewPort(const QSize &oViewportSize); + +private: + int lastVisualRowInDirtyArea(const GlodonHeaderView *verticalHeader) const; + void adjustCurrentDirtyArea(uint verticalBottom, uint horizontalRight); + void adjustColumnByLayoutDirection(int &firstVisualColumn, int &lastVisualColumn); + void drawGridCellFromRowToColumn(QPainter &painter, GlodonTableViewPainterInfo &info, QBitArray &drawn, QStyleOptionViewItem &option); + void calcTopRowAndAlternateBase(int bottom, int &top, bool &balternateBase); + +private: + /** + * @brief 绘制各种格子边框 + * @param painter + * @param params + * @param spans + * @param option + */ + void drawCellBorderLines(QPainter &painter, const QRect ¶ms, QRegion &spans, QStyleOptionViewItem &option); + + /** + * @brief 按行绘制边框线 + * @param painter + * @param params + * @param spans + * @param option + */ + void drawBorderLinesByRow(QPainter &painter, const QRect ¶ms, QRegion &spans, QStyleOptionViewItem &option); + + /** + * @brief 按列绘制边框线 + * @param painter + * @param params + * @param spans + * @param option + */ + void drawBorderLinesByCol(QPainter &painter, const QRect ¶ms, QRegion &spans, QStyleOptionViewItem &option, int row); + + /** + * @brief 根据当前状态绘制选择框 + * @param painter + * @param offset + */ + void drawSelectionBorderLines(QPainter &painter, const QPoint &offset); + + /** + * @brief 绘制正常状态(非选择填充,非选择移动)下,选择区域的边框线 + * @param painter + */ + void drawSelectionBorderLines(QPainter &painter); + + void drawGridLines(QPainter &painter, const QRect ¶ms, QRegion &spans); + + //用于当个单元格右下角的单元格的index + QModelIndex calculationRightBottomIndex(QModelIndex drawIndex); + + int firstVisableColumn(); + int firstVisableRow(); + + void adjustCommonBorder(const QLine &line, QList &rectVisablelBorders); + void adjustCommonBorder(const QLine &lineTopOfCell, QList &rectVisablelBorders, + const QLine& adjustedLineTopOfCell); + void adjustCommonBorder(const QRect &rect, QList &rectVisablelBorders); + + void appendHideCellBorder(const QRect &rect, QList &rectHideBorder); + + /*! + *@brief 画填充虚线框 + *@param[in] painter + *@param[in] offset 偏移点 + *@return 无 + */ + void drawRangeFillingState(QPainter &painter, const QPoint &offset); + + /** + * @brief 框选可拖拽时,画拖拽时灰色实线框 + * @param painter + * @param offset + */ + void drawRangeMovingState(QPainter &painter); + + QRect initRangeFillingDest(); + /** + * @brief 判断Point是否处于可以允许移动的范围 + * @param p + * @return + */ + bool inRangeMovingRegion(const QPoint &p); + + /** + * @brief 初始化选择拖拽时,目标位rangeDest的值 + * @return 返回值为false则说明存在合并,且操作不合法,不再执行本次操作的后续动作 + */ + bool initRangeMovingDest(); + + /** + * @brief 获取当前选中区域的矩形大小 + * @return ModelIndex组合成的Rect + */ + QRect visualRectForSelection(); + void initRangeAction(); + /** + * @brief 计算选择移动时的区域 + * @return + */ + QRect calcRangeMovingRegion(); + /** + * @brief 选择填充,选择移动时,设置CurrentRow和CurrentColumn + * @param pos + */ + void setCurRangeRowAndCol(QPoint pos); + //void doRangeFill(); + void addNewRow(int newRowCount); + /** + * @brief 调整行(列)大小时,设置提示框中的信息 + * @param mousePosition + * @return + */ + QString resizeInfoText(QPoint mousePosition, Qt::Orientation); + /** + * @brief 根据headerview方向,设置调整行(列)大小时,初始高度(宽度) + */ + void setResizeStartPosition(Qt::Orientation); + + /** + * @brief 计算自动列宽 + * @param col + */ + void setGridDisplayColWidths(); + + void refreshDisplayRows(GLDList &arrRows); + void refreshDisplayRows(); + + /** + * @brief 计算自动行高 + * @param cols 需要计算的自动行高的列 + */ + void setGridDisplayRowHeights(); + + int getSuitRowHeight(int row); + + /** + * @brief 计算合适列宽 + * @param col + */ + void adjustColWidths(int currentResizeCol); + + /** + * @brief 通过枚举类型Margin,获取top,left,right,bottom的margin + * @param modelIndex + * @param margin + * @return + */ + int cellMargin(const QModelIndex &modelIndex, Margin margin) const; + + GCustomCommentFrame *findOrCreateCommentFrame(const QModelIndex &index, bool createCommentIfNotFind = true); + + /** + * @brief 获取右边或者底边线宽 + * @param boundLine + * @param isRightBoundLine 是否是右边 + * @param compareWithGridLine 是否跟格线比较 + * @return + */ + int borderLineWidth(const QVariant &boundLine, bool isRightBoundLine) const; + + int borderLineSubtractGridLineWidth(const QVariant &boundLine, bool isRightBoundLine) const; + + /*! + *@brief 滚动到给定的index处 + *@param[in] index + *@param[in] hint 滚动方式 + *@param[in] cellHeight 单元格的高度 + *@return 无 + */ + void scrollVerticalTo(const QModelIndex &index, ScrollHint &hint, int nCellHeight); + + /*! + *@brief 纵向滚动条,按格子滚动,滚动到指定的Index处 + *@param[in] index + *@param[in] hint 滚动方式 + *@param[in] cellHeight 单元格的宽度 + *@return 无 + */ + void scrollVerticalPerItemTo(const QModelIndex &index, ScrollHint &hint, int nCellHeight); + + /*! + *@brief 纵向滚动条,按像素滚动,滚动到指定的Index处 + *@param[in] index + *@param[in] hint 滚动方式 + *@param[in] cellHeight 单元格的宽度 + *@return 无 + */ + void scrollVerticalPerPixelTo(const QModelIndex &index, ScrollHint &hint, int nCellWidth); + + /*! + *@brief 滚动到给定的index处 + *@param[in] index + *@param[in] hint 滚动方式 + *@param[in] cellWidth 单元格的宽度 + *@return 无 + */ + void scrollHorizontalTo(const QModelIndex &index, ScrollHint &hint, int nCellWidth); + + /*! + *@brief 横向滚动条,按格子滚动,滚动到指定的Index处 + *@param[in] index + *@param[in] hint 滚动方式 + *@param[in] cellWidth 单元格的宽度 + *@return 无 + */ + void scrollHorizontalPerItemTo(const QModelIndex &index, ScrollHint &hint, int nCellWidth); + + /*! + *@brief 横向滚动条,按像素滚动,滚动到指定的Index处 + *@param[in] index + *@param[in] hint 滚动方式 + *@param[in] cellWidth 单元格的宽度 + *@return 无 + */ + void scrollHorizontalPerPixelTo(const QModelIndex &index, ScrollHint &hint, int nCellWidth); + + /** + * @brief 判断选中区域能否进行复制 + * @param[in] indexList + */ + bool checkSelectionCopyEnable(const QModelIndexList& indexList) const; + + /** + * @brief 从一个有序的QModelIndexList中获取所有单元格的内容 + * @param indexList + * @return + */ + GString getContentsFromOrderedIndexList(const QModelIndexList & indexList); + + /** + * @brief 根据剪贴板中内容来填充单元格 + * @param[in] indexList 被填充的单元格QModelIndex + * @param[in] sClipBoardText 剪贴板中内容 + * @param[out] nPasteRowCount 填充行数 + * @param[out] nPasteColCount 填充列数 + */ + void fillCellsOnClipBoardText(const QModelIndexList &indexList, GString &sClipBoardText, + int & nPasteRowCount, int & nPasteColCount); + + /** + * @brief 设置选中区域 + * @param[in] indexList 被填充的单元格QModelIndex + * @param[in] nPasteRowCount 粘贴函数 + * @param[in] nPasteColCount 粘贴列数 + */ + void setNewSelection(const QModelIndexList &indexList, int & nPasteRowCount, int & nPasteColCount); + + /** + * @brief 给单元格设值,设值过程中需要考虑单元格的只读性问题,该函数主要用于pasteFromClipboard()函数中 + * @param index QModelIndex + * @param variant 需要设定的值 + */ + void setCellData(const QModelIndex &index, const QVariant &variant); + + /*! + * \brief 返回给定logicIndex的绘制位置,其中包含边框线 + * \param index + * \return + */ + QRect visualRectIncludeBoundingLineWidth(const QModelIndex &index) const; + + // MoveCursor重构 + int getBottomVisibleRow(); + int getRightVisibleCol(); + int getLastVisualRow(int nBottom); + int getLastVisualCol(int nRight); + + QModelIndex leftTopVisualIndex(int nRight, int nBottom); + + void updateVisualCursor(); + void adjustRightToLeftCursorAction(CursorAction cursorAction); + + void dealWithMoveUp(int &nLastVisualRow, int &nLastVisualCol); + void dealWithMoveDown(int &nLastVisualRow, int &nLastVisualCol, int nBottom); + + QModelIndex getLeftPageCursorIndex(); + void dealWithMoveLeft(int &nLastVisualRow, int &nLastVisualCol, int nRight, int nBottom, CursorAction cursorAction); + + QModelIndex getRightPageCursorIndex(int nRight); + void dealWithMoveRight(int &nLastVisualRow, int &nLastVisualCol, int nRight, int nBottom, CursorAction cursorAction); + + void dealWithMoveHome(int &nLastVisualRow, int &nLastVisualCol, int nRight, int nBottom, Qt::KeyboardModifiers modifiers); + void dealWithMoveEnd(int &nLastVisualRow, int &nLastVisualCol, int nRight, int nBottom, Qt::KeyboardModifiers modifiers); + + QModelIndex getUpPageCursorIndex(); + QModelIndex getDownPageCursorIndex(int nBottom); + + QModelIndex getCursorIndex(int nLastVisualRow, int nLastVisualCol); + + bool copyOrPastOperation(QKeyEvent *event); + bool openEditOrScrollContent(QKeyEvent *event); + void dealWithKeyEnterPress(QKeyEvent *event); + + void clickEditorButtonAccordingToEditStyleDrawType(QModelIndex index, QMouseEvent *event); + void processEnterJumpAfterCloseEdit(GlodonDefaultItemDelegate::EndEditHint hint); + void resetEnterJumpPreState(); + + /** + *@brief 是否需要显示编辑方式的画法 + *@param[in] testIndex 被测试modelIndex + *@return true:需要 false:不需要 + */ + bool shouldDoEditorDraw(const QModelIndex &testIndex) const; + + // ScrollTo重构 + int firstVisualIndexAfterHorizontalScroll(const QModelIndex &index, ScrollHint &hint, int nCellWidth); + int getHorizontalHiddenSectionCountBeforeIndex(int nHorizontalIndex); + + bool isPositionAtTopForRowExchange(int nVerticalPosition, int nVerticalOffset); + int firstVisualIndexAfterVerticalScroll(const QModelIndex &index, ScrollHint &hint, int nCellHeight); + int getVerticalHiddenSectionCountBeforeIndex(int nVerticalIndex); + + /*! + *设置合并格 + *@param[in] row 合并格左上角逻辑行号 + *@param[in] column 合并格左上角逻辑列号 + *@param[in] rowSpan 合并格包含的行数,即该合并格的纵向包含的格子数 + *@param[in] columnSpan 合并格包含的列数,即该合并格的横向包含的格子数 + *@return 无 + */ + void setSpan(int row, int column, int rowSpan, int columnSpan); + + /*! + *清除所有合并 + *@return 无 + */ + void clearSpans(); + + /** + * @brief 此函数主要修复在开启失去焦点退出编辑状态时,在与onCommitEditor信号相连接的槽中 + * 若将canCloseEditor设置为false,滚动条会自动滚动的问题 + */ + void processScrollBarAfterCanNotCloseEditor(); + +private: + // 重构ScrollContentsBy + void scrollHorizontalContentsBy(int dx); + void scrollVerticalContentsBy(int dy); + void updateFirstLine(int dx, int dy); + + bool commitDataAndCloseEditorInIngnoreFocusOut(); + + // 重构MousePressEvent + void dealWithSpecialMousePressOperations(const QModelIndex &index, QMouseEvent *event); + void dealWithResizeCellWhenPressGridLine(QMouseEvent *event); + bool shouldDoRangeFill(QMouseEvent *event); + bool shouldDoRangeMove(QMouseEvent *event); + bool shoudDoResizeCellByDragGridLine(QMouseEvent *event); + + // 重构MouseMoveEvent + bool shouldSetRangeFillMouseShape(const QPoint &pos); + void setRangeFillMouseShape(bool bHasCursor); + void getRangeFillingCurRowAndCol(int nOldRow, int nOldColumn, const QPoint &pos); + bool shouldSetRangeMoveMouseShape(const QPoint &pos); + void setRangeMoveMouseShape(bool bHasCursor); + void updateTempRangeRect(); + bool shouldSetResizeCellByDragGridLineMouseShape(QMouseEvent *event); + void setResizeCellByDragGridLineMouseShape(QMouseEvent *event); + void dealWithResizeCellWhenDragGridLine(QMouseEvent *event); + void recoverCursor(); + void dealWithCurCommet(const QPoint &pos); + void dealWithRangeFillingOnMouseMove(bool bHasCursor, const QPoint &pos); + void dealWithRangeMovingOnMouseMove(const QPoint &pos); + bool isInRangeFilling(); + bool isInRangeMoving(); + bool isInResizingCellByDragGridLine(QMouseEvent *event); + void updateRangeFillingRect(int nOldRow, int nOldColumn); + + // 重构mouseReleaseEvent + void completeRangeFilling(); + void completeRangeMoving(); + void completeResizeCellByDragGridLine(QMouseEvent *event); + void initRangeValuesAndUpdateViewport(); + + // 重构doRangeFill + bool doRangeFillHandled(); + void doRangeFillToTop(); + void doRangeFillToBottom(); + void doRangeFillToLeft(); + void doRangeFillToRight(); + void setSrcIndexDataToDestIndex(const QModelIndex &oSrcLogicalIndex, QModelIndex &oDestLogicalIndex); + + // 重构SectionResizing + void initSectionResizingInfoFrame(const QPoint &mousePostion, Qt::Orientation direction); + void updateSectionResizingInfoFrameText(Qt::Orientation direction); + + // 重构bindMergeCell + void adjustVisualRect(int &nFirstVisualRow, int &nFirstVisualCol, int &nLastVisualRow, int &nLastVisualCol); + void adjustVisualRow(int &nFirstVisualRow, int &nLastVisualRow) const; + void adjustVisualCol(int &nFirstVisualCol, int &nLastVisualCol) const; + + void calcAndSetSpan(const int nFirstVisualRow, const int nLastVisualRow, const int nFirstVisualCol, const int nLastVisualCol); + void initMergeCellState(const int nFirstVisualRow, const int nLastVisualRow, const int nFirstVisualCol, const int nLastVisualCol, + QVector &oCellMergeState); + int findLastSpanRow( + const int nCurMergeID, const int nRow, const int nLastVisualRow, const int nCurLogicalCol); + int findLastSpanCol(const int nCurMergeID, const int nCol, const int nLastVisualCol, const int nCurLogicalRow); + void setMergeCellState(int nRow, int nSpanRow, int nCol, int nSpanCol, QVector &oCellMergeState); + + void initResizeInfoFrames(Qt::Orientation direction); + +private Q_SLOTS: + void _q_selectRow(int row); + void _q_selectColumn(int column); + void _q_selectRows(int left, int top, int right, int bottom); + void _q_selectColumns(int left, int top, int right, int bottom); + void _q_updateSpanInsertedRows(const QModelIndex &parent, int start, int end); + void _q_updateSpanInsertedColumns(const QModelIndex &parent, int start, int end); + void _q_updateSpanRemovedRows(const QModelIndex &parent, int start, int end); + void _q_updateSpanRemovedColumns(const QModelIndex &parent, int start, int end); + + void writeComment(const QString &value); + void onDrawComment(const QModelIndex &index, bool &canShow); +protected Q_SLOTS: + void resetCommentPosition(bool isMove = false, int dx = 0, int dy = 0); +private: + Q_DECLARE_PRIVATE(GLDTableView) + Q_DISABLE_COPY(GLDTableView) + +private: + friend class GlodonTableViewToExcel; + friend class GlodonDefaultItemDelegate; +}; + +class GlodonScrollBar : public QScrollBar +{ + Q_OBJECT +public: + explicit GlodonScrollBar(QWidget *parent=0); + explicit GlodonScrollBar(Qt::Orientation orientation, QWidget *parent=0); + +protected: + void enterEvent(QEvent *event); + +private: + QWidget *m_pParent; +}; + diff --git a/GCR/trunk/Glodon/include/GLD/GLDTableViewBasic_p.h b/GCR/trunk/Glodon/include/GLD/GLDTableViewBasic_p.h new file mode 100644 index 00000000..0b105f19 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDTableViewBasic_p.h @@ -0,0 +1,472 @@ +#pragma once + +#include "GLDAbstractItemView_p.h" +#include "GLDTableViewBasic.h" + +class QPushButton; + +enum RangeFillHandlePositon +{ + LeftBottom, + RightBottom, + RightTop +}; + +/*! + *@GLDTableViewPrivate + *@brief { GLDTableView 对应的“私有类”,方法不对外公布} + *@author Gaosy + *@date 2012.9.7 + */ +class GLDTABLEVIEWSHARED_EXPORT GLDTableViewPrivate : public GlodonAbstractItemViewPrivate +{ + Q_DECLARE_PUBLIC(GLDTableView) +public: + GLDTableViewPrivate() : + m_allowCopy(false), + m_allowPaste(false), + m_allowRangeFilling(false), + m_allowSelectCol(true), + m_allowSelectRow(true), + m_allowToResizeCellByDragGridLine(false), + m_alwaysShowRowSelectedColor(false), + m_bRangeMoving(false), + m_cellFillEditField(true), + m_bDrawTopAndLeftBorderLine(false), + m_geometryRecursionBlock(false), + m_bShowHorizontalGridLine(true), + m_bIsInAdjustFitCols(false), + m_inCommitData(false), + m_bIsCustomStyle(false), + m_isShowResizeInfoFrame(true), + m_legalData(true), + m_showEllipsisButton(false), + m_showGrid(true), + m_sortingEnabled(false), + m_bShowVerticalGridLine(true), + m_columnResizeTimerID(0), + m_columnSectionAnchor(-1), + m_currResizeWidth(0), + m_nCurrentResizeCol(-1), + m_nFixedColCount(0), + m_nFixedRowCount(0), + m_nFixedColWidth(0), + m_nFixedRowHeight(0), + m_gridLineWidth(1), + m_nResizeCellStartPosition(0), + m_nResizeCellEndPosition(0), + m_rowResizeTimerID(0), + m_rowSectionAnchor(-1), + m_infoFrame(NULL), + m_pResizeInfoLineFrame(NULL), + m_bAllRowsResizeToContents(false), + m_bCalcAllColumns(false), + m_bAllColumnsResizeToContents(false), + m_bCalcAllRows(false), + m_horizontalHeader(NULL), + m_verticalHeader(NULL), + m_ellipsisButton(NULL), + m_cornerWidget(NULL), + m_visualCursor(QPoint()), + m_gridStyle(Qt::SolidLine), + m_borderLineColor(QColor(192,192,192)), + m_gridLineColor(QColor(192,192,192)), + m_oFrameLineColor(QColor(192,192,192)), + m_selectBoundLineColor(QColor("#39a9d1")), + m_selectBoundLineWidth(2), + m_oNoFocusSelectedBoundLineColor(QColor(Qt::darkGray)), + m_rangeFillingStyle(rfsVertical), + m_bDrawBoundLine(false), + m_prevState(GlodonAbstractItemView::FirstFocus), + m_bEnterJump(true), + m_bEnterJumpPro(false), + m_editStyleDrawType(GlodonAbstractItemView::SdtNone), + m_pCommentFrame(NULL), + m_bCloseEditorOnFocusOut(false), + m_bUseBlendColor(false), + m_oSelectedCellBackgroundColor("#f9f9f9"), + m_bUseComboBoxCompleter(true), + m_bIsInReset(false), + m_rangeFillHandlePositon(RightBottom) + { + m_bWrapItemText = true; +#ifndef QT_NO_DRAGANDDROP + m_bDragDropOverwrite = true; +#endif + } + + ~GLDTableViewPrivate(); + + void init(); + + void trimHiddenSelections(QItemSelectionRange *range) const; + + int sectionSpanEndLogical(const GlodonHeaderView *header, int logical, int span) const; + int sectionSpanSize(const GlodonHeaderView *header, int logical, int span) const; + bool spanContainsSection(const GlodonHeaderView *header, int logical, int spanLogical, int span) const; + + /*! + *绘制所有合并格,并将它们所在区域标记为已绘制 + *@param[in] area 整个TableView的绘制区域 + *@param[in] painter + *@param[in] option + *@param[in] drawn 记录已绘制区域的数组 + *@param[in] firstVisualRow 第一个可见行的虚拟行号 + *@param[in] lastVisualRow 最后一个可见行的虚拟行号 + *@param[in] firstVisualColumn 第一个可见列的虚拟列号 + *@param[in] lastVisualColumn 最后一个可见列的虚拟列号 + *@return 无 + */ + virtual void drawAndClipSpans(const QRegion &area, QPainter *painter, + const QStyleOptionViewItem &option, QBitArray *drawn, + int firstVisualRow, int lastVisualRow, int firstVisualColumn, int lastVisualColumn); + + /*! + *绘制格子 + *@param[in] painter + *@param[in] option + *@param[in] index 所绘制格子对应的model中的QModelIndex + *@return 无 + */ + virtual void drawCell(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index); + + void setSpan(int row, int column, int rowSpan, int columnSpan); + GSpanCollection::GSpan span(int row, int column) const; + QRect visualSpanRect(const GSpanCollection::GSpan &span) const; + QRect visualSpanRectIncludeBoundingLineWidth(const GSpanCollection::GSpan &span) const; + + QRect visualRectIncludeBoundingLineWidth(const QModelIndex &index) const; + + void spanTopRowLeftColumn(const GSpanCollection::GSpan &span, int &row, int &column) const; + + QRect viewportScrollArea(Qt::Orientation orientation); + + void _q_selectRow(int row); + void _q_selectColumn(int column); + void _q_selectRows(int left, int top, int right, int bottom); + void _q_selectColumns(int left, int top, int right, int bottom); + + void selectRow(int row, bool anchor); + void selectColumn(int column, bool anchor); + bool selectColumns(int start, int end, bool anchor); + bool selectRows(int start, int end, bool anchor); + + void _q_updateSpanInsertedRows(const QModelIndex &parent, int start, int end); + void _q_updateSpanInsertedColumns(const QModelIndex &parent, int start, int end); + void _q_updateSpanRemovedRows(const QModelIndex &parent, int start, int end); + void _q_updateSpanRemovedColumns(const QModelIndex &parent, int start, int end); + + void drawTriangles(QRect rect, QPainter *painter); + +public: // Inline + inline bool isHidden(int row, int col) const + { + return m_verticalHeader->isSectionHidden(row) + || m_horizontalHeader->isSectionHidden(col); + } + inline int visualRow(int logicalRow) const + { + return m_verticalHeader->visualIndex(logicalRow); + } + inline int visualColumn(int logicalCol) const + { + return m_horizontalHeader->visualIndex(logicalCol); + } + inline int logicalRow(int visualRow) const + { + return m_verticalHeader->logicalIndex(visualRow); + } + inline int logicalColumn(int visualCol) const + { + return m_horizontalHeader->logicalIndex(visualCol); + } + inline int accessibleTable2Index(const QModelIndex &index) const + { + return (index.row() + (m_horizontalHeader ? 1 : 0)) * (index.model()->columnCount() + (m_verticalHeader ? 1 : 0)) + + index.column() + (m_verticalHeader ? 1 : 0) + 1; + } + inline int rowSpan(int row, int column) const + { + return span(row, column).height(); + } + inline int columnSpan(int row, int column) const + { + return span(row, column).width(); + } + inline bool hasSpans() const + { + return !m_spans.spans.isEmpty(); + } + inline int rowSpanHeight(int row, int span) const + { + return sectionSpanSize(m_verticalHeader, row, span); + } + inline int columnSpanWidth(int column, int span) const + { + return sectionSpanSize(m_horizontalHeader, column, span); + } + inline int rowSpanEndLogical(int row, int span) const + { + return sectionSpanEndLogical(m_verticalHeader, row, span); + } + inline int columnSpanEndLogical(int column, int span) const + { + return sectionSpanEndLogical(m_horizontalHeader, column, span); + } + inline bool isRowHidden(int row) const + { + return m_verticalHeader->isSectionHidden(row); + } + inline bool isColumnHidden(int column) const + { + return m_horizontalHeader->isSectionHidden(column); + } + inline bool isCellEnabled(int row, int column) const + { + return isIndexEnabled(m_model->index(row, column, m_root)); + } + inline bool isCellEnabledAndSelectabled(int row, int column) const + { + return (isIndexEnabled(m_model->index(row, column, m_root)) && isIndexSelectable(m_model->index(row, column, m_root))); + } + inline bool isVisualRowHiddenOrDisabled(int row, int column) const + { + int nRow = logicalRow(row); + int nCol = logicalColumn(column); + + return isRowHidden(nRow) || !isCellEnabled(nRow, nCol); + } + inline bool isVisualColumnHiddenOrDisabled(int row, int column) const + { + int nRow = logicalRow(row); + int nCol = logicalColumn(column); + + return isColumnHidden(nCol) || !isCellEnabled(nRow, nCol); + } + inline bool isVisibleColumn(int column) const + { + int nCol = logicalColumn(column); + + return (hbar != NULL) ? m_horizontalHeader->isSectionVisible(nCol) : true; + } + inline bool isVisibleRow(int row)const + { + int nRow = logicalRow(row); + + return (vbar != NULL) ? m_verticalHeader->isSectionVisible(nRow) : true; + } + +public: // bool + bool m_allowCopy; //是否允许复制 + bool m_allowPaste; //是否允许粘贴 + bool m_allowRangeFilling; //是否允许下拉填充 + bool m_allowSelectCol; //是否允许列选 + bool m_allowSelectRow; //是否允许行选 + bool m_allowToResizeCellByDragGridLine; //是否允许改变大小 + bool m_alwaysShowRowSelectedColor; //是否总是显示当前焦点格所在行选择背景色 + bool m_bRangeMoving; //是否允许框选可拖拽 + bool m_cellFillEditField; //是否允许填充编辑字段 + bool m_bDrawTopAndLeftBorderLine; //是否绘制无表头时候的上/左框线 + bool m_geometryRecursionBlock; + bool m_bShowHorizontalGridLine; //是否显示水平格线 + bool m_bIsInAdjustFitCols; //是否处于计算合适列宽标示符,防止设置超过一列的合适列宽后,出现循环调用,栈溢出 + bool m_inCommitData; //当onCommitEditor有弹窗并且按Tabel键或Enter键时,在QItemDelegate的EventFilter中,会出现发送两次commit和closeEdit信号现象(按键一次,失去焦点一次),用该变量处理 + bool m_bIsCustomStyle; //是否是自定义风格,用于GSF选项:格线颜色、宽度、固定格背景色、表格背景色 + bool m_isShowResizeInfoFrame; //是否显示调整行高列宽的信息窗 + bool m_legalData; //是否是合法数据:details: 当commitData失败时,为false,不允许closeEditor + bool m_showEllipsisButton; //是否显示带三点按钮在tableView的右下角 + bool m_showGrid; //是否显示格线 + bool m_sortingEnabled; //是否支持排序 + bool m_bShowVerticalGridLine; //是否显示垂直格线 + +public: // int + int m_columnResizeTimerID; + int m_columnSectionAnchor; + int m_currResizeWidth; + int m_nCurrentResizeCol; + int m_nFixedColCount; //固定列数 + int m_nFixedRowCount; //固定行数 + mutable int m_nFixedColWidth; // 存储可编辑固定列宽度,包括固定列之间的线宽和最后一根线的线宽 + mutable int m_nFixedRowHeight; // 存储可编辑固定列高度,同上 + int m_gridLineWidth; //格线宽度 + int m_nResizeCellStartPosition; + int m_nResizeCellEndPosition; + int m_rowResizeTimerID; + int m_rowSectionAnchor; + +public: // pointer + GInfoFrame *m_infoFrame; + QFrame *m_pResizeInfoLineFrame; + + GIntList m_oFitColWidthCols; + GIntList m_oSuitColWidthCols; // 存放计算自动列宽的时候,需要参考的列号 + GIntList m_oSuitRowHeightAccordingCols; // 存放计算自动行高的时候,需要参考的列号 + + bool m_bAllRowsResizeToContents; + bool m_bCalcAllColumns; + + bool m_bAllColumnsResizeToContents; + bool m_bCalcAllRows; + + GlodonHeaderView *m_horizontalHeader; + GlodonHeaderView *m_verticalHeader; + + QPushButton *m_ellipsisButton; + + QWidget *m_cornerWidget; + +public: // type + GSpanCollection m_spans; + + QMap m_oCommentFrames; + QPoint m_visualCursor; // (Row,column) cell coordinates to track through span navigation. + + Qt::PenStyle m_gridStyle; + + QColor m_borderLineColor; //框线颜色 + QColor m_gridLineColor; //格线颜色 + QColor m_oFrameLineColor; // 在表头隐藏,且滚动模式为Item时,绘制的整个表格上边框或者左边框线的颜色 + + QColor m_selectBoundLineColor; //选择的的单元格,绘制的框线颜色 + int m_selectBoundLineWidth; //选择的的单元格,绘制的框线宽度 + QColor m_oNoFocusSelectedBoundLineColor; // 失去焦点时,选择的的单元格,绘制的框线颜色 + + QList m_columnsToUpdate; + QList m_rowsToUpdate; + + RangeFillingStyle m_rangeFillingStyle; + + QHash m_borderLines; // 用于缓存绘制时的边框线值 + bool m_bDrawBoundLine; // 格线分段绘制 + QRect m_oRangeFillHandleRect; // 缓存选择填充时,右下角矩形的大小 + + QModelIndex m_oTopLeftSelectIndex; // 如果有span或者行,列移动之后,selectionModel里面存储的ItemRange为多个,所以用此缓存仅选择一个区域时的TopLeft + QModelIndex m_oBottomRightSelectIndex; // 缓存仅选择一个区域时的BottomRight + GlodonAbstractItemView::EnterMovingState m_prevState; + bool m_bEnterJump; //回车跳格 + bool m_bEnterJumpPro; //开启回车跳格后,再开启这个,减少设置焦点的一步(处于编辑状态时,如果下一个能编辑,则直接进入下一个的编辑状态) + GlodonAbstractItemView::EditStyleDrawType m_editStyleDrawType; + + GCommentFrame *m_pCommentFrame; + bool m_bCloseEditorOnFocusOut; + bool m_bUseBlendColor; //使用混合色 + QColor m_oSelectedCellBackgroundColor; //选择区域的背景颜色 + bool m_bUseComboBoxCompleter;//设置是否使用comboBox自动提示功能 + + bool m_bIsInReset; // 防止批注框在reset时,会一致移动,添加,后续改批注框或者GSPTableView的reset恢复rowHeight流程时再考虑去掉 + + RangeFillHandlePositon m_rangeFillHandlePositon; + + void mergeOriginColsWidthAndAdjustColsWidth(GIntList &colWidths, const GIntList &originColsWidth, const GIntList &adjustColsWidth); +protected: + virtual void doSelect(const QModelIndex& tl, const QModelIndex& br, QItemSelectionModel::SelectionFlags command, bool isRowSelect); + virtual void itemDelegatePaint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index); + +private: + // duanb cuidc 注释小三角 + void drawTriangles(QPainter *painter, const QStyleOptionViewItem &opt, const QModelIndex &index); + + /** + * @brief 根据传入的样式和当前上下文来配置新的绘制样式 + * @param option 当前样式 + * @param index + * @param opt 新样式 + */ + void adjustStyleOption(QStyleOptionViewItem &opt, const QModelIndex &index); + + bool nothingToDraw(); + bool currentCellDrawn(GlodonTableViewPainterInfo &info, int nVisualCol, QBitArray &drawn, int nColumnCount, int nVisualRow); + bool isCoverByFixedRow(int row, int rowYEndPos, bool addGridLineWidth); + bool isCoverByFixedColumn(int column, int columnXEndPos, bool addGridLineWidth); + void setOptionFeaturesAlternateProperty(bool bAlternateBase, bool balternate, QStyleOptionViewItem &option); + QRect cellPainterRect(QRect srcRect, int visualRow, int visualCol); + + void calculateFixedRegion(); + void calculateFixedColumnWidth() const; + void calculateFixedRowHeight() const; + + void setOptionSelectedState(QStyleOptionViewItem& opt, const QModelIndex &index); + void setOptionMouseOverState(const QModelIndex &index, QStyleOptionViewItem& opt); + void setOptionEnabledState(QStyleOptionViewItem& opt, const QModelIndex &index); + void setOptionHasFocusState(const QModelIndex &index, QStyleOptionViewItem& opt); + + QItemSelection getItemSelectionAccordingToSelectState(); + void adjustSelectionBoundingRectAccordingToFixedColumn(const QRegion &bordingRegion, QRect &srcRect); + void adjustSelectionBoundingRectAccordingToFixedRow(const QRegion &bordingRegion, QRect &srcRect); + void drawNormalSelectionBoundingLine(QPainter &painter, QRect rect); + void drawBorderWithFillHandle(QPainter &painter, QRect rect); + + QList getVisibleSpansAccordingToIsSectionMove(int firstVisualRow, int firstVisualColumn, int lastVisualRow, int lastVisualColumn); + void adjustOptionAlternateFeature(QStyleOptionViewItem &opt, bool bAlternateBase); + + bool isRangeFillingHandleSelected(const QPoint &p); + bool isInMutiSelect() const; + inline bool isEnterJump() { return m_bEnterJump && !m_bEnterJumpPro; } + inline bool isEnterJumpPro() { return m_bEnterJump && m_bEnterJumpPro; } + + void drawComment(const QPersistentModelIndex &index); + void hideCommentFrame(); + + void setGridLineWidthToHorizontalHeader(int gridLineWidth); + void setGridLineWidthToVertialHeader(int gridLineWidth); + + // 重构自动行高 + int heightHintForIndex(const QModelIndex &index, int nHint, QStyleOptionViewItem &option) const; + int calcSizeHintForRow(int row, const QList &oNeedCalcSizeHintCols) const; + int widthHintForIndex(const QModelIndex &index, int hint, const QStyleOptionViewItem &option) const; + int widthHintForIndex(int visualRow, int column, int hint, const QStyleOptionViewItem &option) const; + + int sizeHintForColumn(int column, bool calcAllRows) const; + + void calcFixedColSuitWidth(bool &shouldResetCommentPosition); + void calcNormalColSuitWidth(bool &shouldResetCommentPosition); + + void calcFixedRowSuitHeight(const QList &oNeedCalcHeightCols, bool &shouldResetCommentPosition); + void calcNormalRowSuitHeight(const QList &oNeedCalcHeightCols, bool &shouldResetCommentPosition); + + int calcSuitWidth(int nCol, bool calcAllRows = false); + int calcSuitHeight(const QList &oNeedCalcHeightCols, int nLogicalRow); + + void adjustRectWidthByTreeColumn(const QModelIndex &index, QRect &rect) const; + void adjustRectWidthBySpan(const QModelIndex &index, QRect &rect) const; + + QColor getPenColor(); + bool isNearHorizontalGridLine(QMouseEvent *event); + bool isNearVerticalGridLine(QMouseEvent *event); + + // 重构合适列宽 + void doAdjustColWidths(int currentResizeCol); + void adjustFitColWidths(GIntList &originColWidths); + void applyAdjustFitColsWidth(const GIntList &originColsWidth, const GIntList &adjustColsWidth); + GIntList getAdjustedColWidths(const GIntList &originColWidths, int currentResizeColWidth); + + /*! + * \brief 如果当前调整的列宽的列是合适列宽的列,就调整origineCols中的值 + * \param adjustedColWidths + * \param currentResizeColIndexInFitCols + * \param currentResizeCol + * \param currentResizeColWidth + * \param originColWidths + */ + void adjustOriginColWidthWhenResizeColIsInFitCols(const GIntList &adjustedColWidths, int currentResizeColIndexInFitCols, + int currentResizeColWidth, GIntList &originColWidths); + void calcOldAdjustColsTotalWidth(const GIntList &oAdjustedColsWidth, + int &nOldAdjustColsTotalWidth, int &nCurrentResizeColIndexInFitCols); + void calcAdjustColsWidth(const int nAvailableAdjustWidth, const int nOldAdjustColsTotalWidth, GIntList &oAdjustedColsWidth, + int &nNewAdjustColsTotalWidth); + + int getTotalColWidth(const GIntList &originColsWidth, int nColWidth); + GIntList getOriginColWidthsFromView(); + + int getMinTotalColWidth(const GIntList &originColWidths, const int nOriginTotalColWidth); + int getDefaultColWidth(int col); + + bool isVisibleIndex(const QModelIndex &visualIndex); + int defaultRowHeight(const QModelIndex &logicalIndex); + + bool isInTableView(QMouseEvent *event); + QPoint calcResizeInfoLineFramePosition(Qt::Orientation direction); + + void fillSuitColWidthCols(); + void fillSuitRowHeightCols(); +}; diff --git a/GCR/trunk/Glodon/include/GLD/GLDTableViewExport.h b/GCR/trunk/Glodon/include/GLD/GLDTableViewExport.h new file mode 100644 index 00000000..bc4c60ca --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDTableViewExport.h @@ -0,0 +1,208 @@ +#ifndef GLDTABLEVIEWEXPORT_H +#define GLDTABLEVIEWEXPORT_H + +#include +#include "GLDMap.h" +#include "GLDTableView.h" +#include "GLDDocView.h" +#include "libxl.h" + +using namespace libxl; + +enum ExportState {EXPORT_SUCCESS, EXPORT_NOTWRITING, EXPORT_ERRSAVE}; + +struct TableCellFormat +{ + TableCellFormat() + : fontName(NULL), fontSize(0), fontIsBold(false), + fontIsUnderline(false), fontIsStrikeOut(false), + fontIsItalic(false), foregroundRed(0), foregroundGreen(0), + foregroundBlue(0), textAlignment(0), backColorRed(0), + backColorGreen(0), backColorBlue(0), diffFormat(NULL) + {} + //Qt::FontRole对应的格式参数 + QChar *fontName; + int fontSize; + bool fontIsBold; + bool fontIsUnderline; + bool fontIsStrikeOut; + bool fontIsItalic; + + //Qt::ForegroundRole对应的格式参数 + int foregroundRed; + int foregroundGreen; + int foregroundBlue; + + //Qt::TextAlignmentRole对应的格式参数 + Qt::Alignment textAlignment; + + //Qt::BackgroundColorRole对应的格式参数 + int backColorRed; + int backColorGreen; + int backColorBlue; + + //由GlodonTableView生成的Excel对应的Format对象 + Format *diffFormat; +}; + +struct TableCellLocation +{ +public: + TableCellLocation(int row, int col) + : xCoordinate(row), yCoordinate(col) + {} + inline bool operator==(const TableCellLocation &tableCell) const + { + return (tableCell.xCoordinate == xCoordinate) && (tableCell.yCoordinate == yCoordinate); + } + +private: + int xCoordinate; + int yCoordinate; +}; + +class GlodonTableViewToExcelPrivate; +class GLDTABLEVIEWSHARED_EXPORT GlodonTableViewToExcel +{ + Q_DECLARE_TR_FUNCTIONS(GlodonTableViewToExcel) + + struct GlodonExcelGroupStruct + { + int start; + int end; + bool visible; + + GlodonExcelGroupStruct() + { + start = -1; + end = INT_MAX; + visible = true; + } + GlodonExcelGroupStruct(const GlodonExcelGroupStruct &other) + { + operator=(other); + } + GlodonExcelGroupStruct &operator=(const GlodonExcelGroupStruct &other) + { + start = other.start; + end = other.end; + visible = other.visible; + return *this; + } + }; + +public: + GlodonTableViewToExcel(); + ~GlodonTableViewToExcel(); +public: + static ExportState execute(GlodonTableView *tableView, + const GString &fileName, + const GString &sheetName, + bool isCollapsed = false, + bool isToSingleSheet = false, + bool isOverWrite = true, + bool showPrompt = true); +public: + ExportState save(const GString &fileName); + void load(const GString &fileName = ""); + void setTableView(GlodonTableView *tableView); + void doExport(const GString &sheetName); + void setExportIcon(bool value); + void setIsOverWrite(bool isOverWrite); + void setIsToSingleSheet(bool isToSingleSheet); + void setShowPrompt(bool value); + void setGroupCollapsed(bool collapse); + +private: + void initExcel(const GString &sheetName); + void initSheet(); + void transTitleData(); + void transCellDatas(); + void transTitleAllMergeCells(); + void transMergeCells(); + void transFootData(); + void writeCellValue(const GVariant &value, Format *format, int row, int col); + void writeIcon(const QAbstractItemModel *model, QModelIndex oIndex, Format *format, int row, int col); + void writeCellIcon(int row, int col, const GVariant value, const Format *format); + void writeCellSymbol(int row, int col); + void groupRows(); + int recursiveGroupRowsParent(int parentIndex, GMap *groups); + GlodonExcelGroupStruct getLastParentGroup(const GlodonExcelGroupStruct &group, GMap *groups); + void setFomatIndentSize(Format *format, int pixMaSize); + libxl::Format *getFormat(const QAbstractItemModel *model, int row, int col); + libxl::Format *addDiffFormat(const QAbstractItemModel *model, int row, int col); + bool hasMatchedFormat(const QAbstractItemModel *model, int row, int col); + libxl::Format *getTitleFormat(const QAbstractItemModel *model, int section, Qt::Orientation orientation); + libxl::Format *addDiffTitleFormat(const QAbstractItemModel *model, int section, Qt::Orientation orientation); + bool hasMatchedTitleFormat(const QAbstractItemModel *model, int section, Qt::Orientation orientation); + void initBorderFormat(); + +private: + GlodonTableViewToExcelPrivate * const d_ptr; + Q_DECLARE_PRIVATE(GlodonTableViewToExcel); +}; + +/** + * @brief 将分页表格中的数据导出到Excel + * @warning 现在只支持导出到同一个sheet + */ +class GLDDocViewToExcelPrivate; +class GLDTABLEVIEWSHARED_EXPORT GLDDocViewToExcel +{ + Q_DECLARE_TR_FUNCTIONS(GLDDocViewToExcel) +public: + GLDDocViewToExcel(); + ~GLDDocViewToExcel(); + +public: + static bool execute(GLDDocView *docView, + const GString &fileName, + const GString &sheetName, + bool isToSingleSheet = false, + bool isOverWrite = true, + bool showPrompt = true); + +public: + void setDocView(GLDDocView *docView); + ExportState exportToExcel(bool isToSingleSheet = false, + bool isOverWrite = true, + bool showPrompt = true); + +public: + /** + * @brief 设置开始导出到Excel的页码 + * @param startExportPage + */ + void setStartExportPage(int startExportPage); + + /** + * @brief 设置结束导出到Excel的页码 + * @param entExportPage + * @warning 必须在setDocView后面设置 + */ + void setEndExportPage(int endExportPage); + + /** + * @brief 设置加载的文件名 + * @param fileName + */ + void setLoadFileName(QString fileName); + + /** + * @brief 设置保存的文件名 + * @param fileName + */ + void setSaveFileName(QString fileName); + + /** + * @brief 设置导出到的页签的名称 + * @param sheetName + */ + void setSheetName(QString sheetName); + +private: + GLDDocViewToExcelPrivate * const d_ptr; + Q_DECLARE_PRIVATE(GLDDocViewToExcel); +}; + +#endif // GLDTABLEVIEWEXPORT_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDTableView_Global.h b/GCR/trunk/Glodon/include/GLD/GLDTableView_Global.h new file mode 100644 index 00000000..5cf65662 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDTableView_Global.h @@ -0,0 +1,16 @@ +#ifndef GLDTABLEVIEW_GLOBAL_H +#define GLDTABLEVIEW_GLOBAL_H + +#include + +#ifndef GLD_FULLSOURCE + #if defined(GLDTABLEVIEW_LIBRARY) + # define GLDTABLEVIEWSHARED_EXPORT Q_DECL_EXPORT + #else + # define GLDTABLEVIEWSHARED_EXPORT Q_DECL_IMPORT + #endif +#else + #define GLDTABLEVIEWSHARED_EXPORT +#endif + +#endif // GLDTABLEVIEW_GLOBAL_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDTableView_p.h b/GCR/trunk/Glodon/include/GLD/GLDTableView_p.h new file mode 100644 index 00000000..49420044 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDTableView_p.h @@ -0,0 +1,103 @@ +#ifndef GLDTABLEVIEW_P_H +#define GLDTABLEVIEW_P_H + +#include "GLDAbstractItemView_p.h" +#include "GLDTableView.h" +#include "GLDTableViewBasic_p.h" + +struct GTreeViewItem; + +#define CON_INDENT 10 +#define CON_HALF_DECORATION_WIDTH 6 +#define CON_DECORATION_WIDTH (CON_HALF_DECORATION_WIDTH*2) + +const int c_nTreeDecorationLeftMargin = 2; +const int c_nTreeDecorationRightMargin = 3; + +const int c_rightSelectedDashLineWidth = 1; + +class GLDTABLEVIEWSHARED_EXPORT GlodonTableViewPrivate : public GLDTableViewPrivate +{ + Q_DECLARE_PUBLIC(GlodonTableView) + +public: + GlodonTableViewPrivate() : + m_isTree(false), + m_isGroupMode(false), + m_addChildInSelection(true), + m_treeColumn(0), + m_drawInfo(NULL), + m_treeDecorationStyle(NormalStyle) + { + + } + + virtual bool drawTree(QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index); + + virtual bool expandOrCollapseItemAtPos(const QPoint &pos); + + int itemDecorationAt(const QPoint &pos); + + virtual QRect itemDecorationRect(int row); + + void expand(int item, bool emitSignal); + + void collapse(int item, bool emitSignal); + + virtual void doExpand(int item, bool emitSignal); + + virtual void doCollapse(int item, bool emitSignal); + + void drawOSStyle(QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index, const GTreeViewItem &viewItem); + void drawBranch(QPainter *painter, const QRect &rect, const QModelIndex &index, const GTreeViewItem &viewItem); + + void drawNormalStyle( + QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index, + const GTreeViewItem &viewItem); + void drawNormalStyleTreeDecoration( + QPainter *painter, const QRect &rect, bool expanded, const QStyleOptionViewItem &option); + void drawNormalStyleLines( + const GTreeViewItem &viewItem, int ngridWidth, QPoint levelCenter, + const QModelIndex &index, QRect rect, QPainter *painter); + + QPen normalStylePen(QStyleOptionViewItem &option); + QRect beforeTextRect(const QRect &cellRect, int indentation); + + inline QRect afterDecorationRect(const QPoint &decorationCenter, const QRect &cellRect, const QRect &beforeTextRect) + { + return QRect(decorationCenter.x() + CON_HALF_DECORATION_WIDTH + 2, cellRect.top(), + cellRect.width() - beforeTextRect.width() + 1, cellRect.height()); + } + + inline QPoint decorationCenter(const QRect &cellRect, int indentation) + { + return QPoint(cellRect.left() + indentation + CON_HALF_DECORATION_WIDTH + c_nTreeDecorationLeftMargin, + (cellRect.top() + cellRect.bottom()) / 2); + } + + inline QRect decorationRect(const QPoint &decorationRect) + { + return QRect(decorationRect.x() - CON_HALF_DECORATION_WIDTH, + decorationRect.y() - CON_HALF_DECORATION_WIDTH, + 2 * CON_HALF_DECORATION_WIDTH + 1, + 2 * CON_HALF_DECORATION_WIDTH + 1); + } + +protected: + virtual void itemDelegatePaint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index); + virtual void doSelect(const QModelIndex& tl, const QModelIndex& br, QItemSelectionModel::SelectionFlags command, bool isRowSelect); + /** + * @brief 当树形节点收起时,隐藏对应的批注框 + */ + void hideCommentWhenCollapse(); +public: + bool m_isTree; + bool m_isGroupMode; + bool m_addChildInSelection; //树形结构时,是否把选中且折叠的子加入到selection中 + int m_treeColumn; //显示树形结构的列 + + GlodonTreeDrawInfo *m_drawInfo; + TreeDecorationStyle m_treeDecorationStyle; +}; + +#endif // GLDTABLEVIEW_P_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDTextEdit.h b/GCR/trunk/Glodon/include/GLD/GLDTextEdit.h new file mode 100644 index 00000000..abd49673 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDTextEdit.h @@ -0,0 +1,66 @@ +#ifndef GLDTEXTEDIT_H +#define GLDTEXTEDIT_H + +#include +#include +#include "GLDWidget_Global.h" + +class GLDWIDGETSHARED_EXPORT GLDPlainTextEdit : public QPlainTextEdit +{ + Q_OBJECT + + Q_PROPERTY(bool hasSelectedText READ hasSelectedText) +public: + explicit GLDPlainTextEdit(QWidget *parent = 0); + + bool hasSelectedText(); + QString text(); + void setText(QString text); + + QString placeholderText() const; + void setPlaceholderText(const QString &placeholderText); + //强制选择颜色为蓝色(在右键快捷菜单的时候,仍然是蓝色) + void forceSelectColorToBlue(); + void setFouseIsKeepInLineEdit(bool isAddFouseSetting);//设置是否在peintevent中添加设置焦点的函数,用于实现gldwindowcombobox的焦点问题 + +signals: + void textChanged(const QString &str); + +protected: + virtual void mousePressEvent(QMouseEvent *e); + void paintEvent(QPaintEvent *e); +public slots: + void deleteSelectedText(); + friend class GLDWAbstractSpinBox; + +private slots: + void onTextChanged(); + +private: + QString m_text; + QString m_placeholderText; + bool m_isFouseKeepInLineEdit; +}; + +class GLDWIDGETSHARED_EXPORT GLDPlainTextEditEx : public GLDPlainTextEdit +{ + Q_OBJECT +public: + explicit GLDPlainTextEditEx(QWidget *parent = 0); +}; + +class GLDWIDGETSHARED_EXPORT GLDCustomLineEdit : public QLineEdit +{ + Q_OBJECT +public: + explicit GLDCustomLineEdit(QWidget *parent = 0); + void setHasBorder(bool bValue); + +public slots: + void deleteSelectedText(); + +private: + bool m_hasBorder; +}; + +#endif // GLDTEXTEDIT_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDTextStream.h b/GCR/trunk/Glodon/include/GLD/GLDTextStream.h new file mode 100644 index 00000000..857679c7 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDTextStream.h @@ -0,0 +1,9 @@ +#ifndef GLDTEXTSTREAM +#define GLDTEXTSTREAM + +#include + +typedef QTextStream GTextStream; + +#endif // GLDTEXTSTREAM + diff --git a/GCR/trunk/Glodon/include/GLD/GLDThread.h b/GCR/trunk/Glodon/include/GLD/GLDThread.h new file mode 100644 index 00000000..fe635c5c --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDThread.h @@ -0,0 +1,14 @@ +#ifndef GLDTHREAD +#define GLDTHREAD + +//#ifndef QT_NO_QOBJECT + +#include + +//typedef QObject GQObject; +typedef QThread GThread; + +//#endif + +#endif // GLDTHREAD + diff --git a/GCR/trunk/Glodon/include/GLD/GLDToolBox.h b/GCR/trunk/Glodon/include/GLD/GLDToolBox.h new file mode 100644 index 00000000..99ffe0ec --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDToolBox.h @@ -0,0 +1,298 @@ +#ifndef GLDTOOLBOX_H +#define GLDTOOLBOX_H + +#include +#include +#include +#include +#include + +#include "GLDString.h" +#include "GLDSystem.h" +#include "GLDObjectList.h" +#include "GLDWidget_Global.h" + +class QScrollArea; +class QVBoxLayout; +class GLDTreeWidgetItem; +class GLDToolBoxTreeItem; + +class GLDWIDGETSHARED_EXPORT GLDToolBoxButton : public QAbstractButton +{ + Q_OBJECT +public: + GLDToolBoxButton(QWidget *parent); + + inline void setSelected(bool b) { m_bSelected = b; update(); } + inline void setIndex(int newIndex) { m_nIndexInPage = newIndex; } + + QSize sizeHint() const; + QSize minimumSizeHint() const; + +protected: + void initStyleOption(QStyleOptionToolBox *opt) const; + void paintEvent(QPaintEvent *); + +private: + bool m_bSelected; + int m_nIndexInPage; +}; + +class GLDIconList : public QList +{ +public: + explicit GLDIconList(const QIcon &icon); + explicit GLDIconList(); +}; + +enum GLDToolBoxType +{ + gtbtHeader, + gtbtItem +}; + +class GLDToolBox; +class GLDToolBoxHeader; + +class GLDWIDGETSHARED_EXPORT GLDToolBoxItem : public QObject +{ + Q_OBJECT +public: + explicit GLDToolBoxItem(GLDToolBox *toolBox, GLDToolBoxItem *parent); + virtual ~GLDToolBoxItem(); +public: + enum ItemMode { ListWidget, TreeWidget }; + virtual GLDToolBoxItem *insertItem(int index, const QString &text, const QIcon &icon = QIcon()); + virtual GLDToolBoxType type() const = 0; + virtual void updateItem(int index, const QString &text, const QIcon &icon = QIcon()); + virtual void deleteItem(int index); + virtual void removeItem(GLDToolBoxItem *item); + + inline QString text() const { return m_text; } + inline void setText(const QString &value) { m_text = value; } + void setText(int index, const QString &text); + QIcon icon() const { return m_icon; } + void setIcon(const QIcon &value) { m_icon = value; } + void setIcon(int index, const QIcon &icon); + inline GLDToolBox *toolBox() const { return m_toolBox; } + inline GLDToolBoxItem *parent() const { return m_parent; } + GLDToolBoxHeader *header(); + GLDToolBoxItem *items(int index) const; + inline int count() const { return m_items.count(); } + void clearItems(); + + inline GString name() const { return m_name; } + void setName(const GString &value) { m_name = value; } + + inline PtrInt tag() const { return m_tag; } + void setTag(const PtrInt &value) { m_tag = value; } + +protected: + virtual GLDToolBoxItem *createItem() = 0; +private: + GLDToolBox *m_toolBox; + GLDToolBoxItem *m_parent; + GObjectList m_items; + GString m_text; + GString m_name; + PtrInt m_tag; + QIcon m_icon; + friend class GLDToolBox; +}; + +class GLDWIDGETSHARED_EXPORT GLDToolBoxHeader : public GLDToolBoxItem +{ + Q_OBJECT +public: + explicit GLDToolBoxHeader(GLDToolBox *toolBox, GLDToolBoxItem *parent); + ~GLDToolBoxHeader(); +public: + enum ItemMode { ListWidget, TreeWidget }; + void deleteItem(int index); + void removeItem(GLDToolBoxItem *item); + + GLDToolBoxButton *button() const { return m_button; } + + QWidget *widget() const { return m_widget; } + + void setButtonText(const QString &text) { m_button->setText(text); setText(text); } + + void setButtonIcon(const QIcon &is) { m_button->setIcon(is); setIcon(is); } + + ItemMode itemMode() { return m_itemMode; } + +#ifndef QT_NO_TOOLTIP + void setToolTip(const QString &tip); + QString toolTip() const; +#endif + QString buttonText() const { return m_button->text(); } + + QIcon buttonIcon() const { return m_button->icon(); } + + inline bool operator==(const GLDToolBoxHeader& other) const + { + return widget() == other.widget(); + } + + void setViewMode(QListWidget::ViewMode value); + void expandAll(); + GLDToolBoxItem *find(QListWidgetItem *value); + /* GLDToolBoxItem */ + GLDToolBoxItem *insertItem(int index, const QString &text, const QIcon &icon = QIcon()); + GLDToolBoxType type() const; + void setCurrentItem(GLDToolBoxItem *item); + inline QListWidget *listWidget() const { return dynamic_cast(m_widget); } + inline QTreeWidget *treeWidget() const { return dynamic_cast(m_widget); } +protected: + GLDToolBoxItem *createItem(); +private: + void checkCanUseThisMethod(); +// GLDTreeWidgetItem *treeWidgetItem(int index); + + GLDToolBoxItem *insertItem(int index, const QIcon &icon, const QString &text); + GLDToolBoxItem *addItem(const QIcon &icon, const QString &text); + GLDToolBoxItem *addItem(const QString &text); + + GLDToolBoxItem *insertItem(int index, const GLDIconList &icon, const QStringList &text); + GLDToolBoxItem *insertItem(int index, const QStringList &text); + GLDToolBoxItem *addItem(const GLDIconList &icon, const QStringList &text); + GLDToolBoxItem *addItem(const QStringList &text); + + void setButton(GLDToolBoxButton *value) { m_button = value; } + + void setWidget(QWidget *value); + void setSv(QScrollArea *value) { m_sv = value; } + + QScrollArea *sv() const { return m_sv; } + + bool useOwnWidget() const; + void setUseOwnWidget(bool useOwnWidget); +private: + GLDToolBoxButton *m_button; + QScrollArea *m_sv; + QWidget *m_widget; + ItemMode m_itemMode; + bool m_useOwnWidget; + + friend class GLDToolBox; + friend class GLDToolBoxItem; +}; + +class GLDWIDGETSHARED_EXPORT GLDToolBox : public QScrollArea +{ + Q_OBJECT + Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentChanged) + Q_PROPERTY(int count READ count) + +public: + enum ItemMode { ListWidget, TreeWidget}; + explicit GLDToolBox(QWidget *parent = 0); + ~GLDToolBox(); + + inline ItemMode itemMode() { return m_itemMode; } + void setItemMode(ItemMode mode); + inline GLDToolBoxHeader *currentPage() { return m_pCurrentPage; } + + GLDToolBoxHeader *addItem(QWidget *widget, const QString &text); + GLDToolBoxHeader *addItem(QWidget *widget, const QIcon &icon, const QString &text); + GLDToolBoxHeader *addItem(const QString &text); + GLDToolBoxHeader *addItem(const QIcon &icon, const QString &text); + GLDToolBoxHeader *insertItem(int index, QWidget *widget, const QString &text); + GLDToolBoxHeader *insertItem(int index, QWidget *widget, const QIcon &icon, const QString &text); + GLDToolBoxHeader *insertItem(int index, const QString &text); + GLDToolBoxHeader *insertItem(int index, const QIcon &icon, const QString &text); + + void removeItem(int index); + + void setItemEnabled(int index, bool enabled); + bool isItemEnabled(int index) const; + + void setItemText(int index, const QString &text); + QString itemText(int index) const; + + void setItemIcon(int index, const QIcon &icon); + QIcon itemIcon(int index) const; + +#ifndef QT_NO_TOOLTIP + void setItemToolTip(int index, const QString &toolTip); + QString itemToolTip(int index) const; +#endif + + int currentIndex() const; + QWidget *currentWidget() const; + QWidget *widget(int index) const; + int indexOf(QWidget *widget) const; + int count() const; + + int indexOf(const GString &name); + GLDToolBoxHeader *header(int index); + GLDToolBoxHeader *header(const GString &name); + +public Q_SLOTS: + void setCurrentIndex(int index); + void setCurrentWidget(QWidget *widget); +private Q_SLOTS: + void itemChanging(QListWidgetItem *current, QListWidgetItem *previous); + void itemChanged(QListWidgetItem *item); + + void itemChanging(QTreeWidgetItem *current, QTreeWidgetItem *previous); + void itemChanged(QTreeWidgetItem *item, int column); +Q_SIGNALS: + void currentChanged(int index); + + void headerChanging(GLDToolBoxHeader *headerCurrent, GLDToolBoxHeader *headerNext, bool &canChange); + void headerChanged(GLDToolBoxHeader *headerPrevious, GLDToolBoxHeader *headerCurrent); + + void itemChanging(GLDToolBoxItem *itemCurrent, GLDToolBoxItem *itemNext, bool &canChange); + void itemChanged(GLDToolBoxItem *itemPrevious, GLDToolBoxItem *itemCurrent); + +protected: + bool event(QEvent *e); + virtual void itemInserted(int index); + virtual void itemRemoved(int index); + void showEvent(QShowEvent *e); + void changeEvent(QEvent *); +private: + QWidget *newItem(); +private: + typedef GObjectList PageList; + QListWidgetItem *m_currentListWidgetItem; + QTreeWidgetItem *m_currentTreeWidgetItem; + GLDToolBoxHeader *page(QWidget *widget) const; + const GLDToolBoxHeader *page(int index) const; + GLDToolBoxHeader *page(int index); + GLDToolBoxHeader *page(const GString &name); + + void updateTabs(); + void relayout(); + + ItemMode m_itemMode; + PageList m_pageList; + QVBoxLayout *m_layout; + GLDToolBoxHeader *m_pCurrentPage; + bool m_useOwnWidget; + typedef QScrollArea inherited; +private Q_SLOTS: + void _q_buttonClicked(); + void _q_widgetDestroyed(QObject*); +}; + +class GLDWIDGETSHARED_EXPORT GLDToolBoxTreeItem : public GLDToolBoxItem +{ +public: + explicit GLDToolBoxTreeItem(GLDToolBox *toolBox, GLDToolBoxItem *parent); + ~GLDToolBoxTreeItem(); + GLDToolBoxItem *insertItem(int index, const QString &text, const QIcon &icon = QIcon()); + GLDToolBoxType type() const; + void deleteItem(int index); + void removeItem(GLDToolBoxItem *item); + + GLDTreeWidgetItem *item() { return m_item; } + +protected: + GLDToolBoxItem *createItem(); +private: + GLDTreeWidgetItem *m_item; +}; + +#endif // GLDTOOLBOX_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDTranslations.h b/GCR/trunk/Glodon/include/GLD/GLDTranslations.h new file mode 100644 index 00000000..35453d71 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDTranslations.h @@ -0,0 +1,34 @@ +/*! +*@file +*@brief GLD程序翻译配置文件加载 +*@author cuidc +*@date 2014年3月11日 +*@remarks +*@version 3.0 +*Copyright (c) 1998-2014 Glodon Corporation +*/ +#ifndef GLDTRANSLATIONS_H +#define GLDTRANSLATIONS_H + +#include +#include +#include "GLDCommon_Global.h" +#include "GLDString.h" +#include "GLDXMLTypes.h" + +class GLDTranslationsPrivate; +class GLDCOMMONSHARED_EXPORT GLDTranslations : public QObject +{ + Q_OBJECT +public: + GLDTranslations(QObject *parent = NULL); + ~GLDTranslations(); + // 加载翻译配置文件 + bool loadConfigFile(const GString filePath, const GString configfileName = "TranslationsConfig.xml"); + // 加载翻译文件 + bool installTranslators(); +private: + Q_DECLARE_PRIVATE(GLDTranslations); +}; + +#endif // GLDTRANSLATIONS_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDTreeDrawInfo.h b/GCR/trunk/Glodon/include/GLD/GLDTreeDrawInfo.h new file mode 100644 index 00000000..04ab5318 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDTreeDrawInfo.h @@ -0,0 +1,207 @@ +/*! + *@file glodontreedrawinfo.h + *@brief {辅助绘制树形结构} + * + *@author Gaosy + *@date 2012.9.7 + *@remarks {remarks} + *Copyright (c) 1998-2012 Glodon Corporation + */ + +#ifndef GLDTREEDRAWINFO_H +#define GLDTREEDRAWINFO_H + +#include +#include +#include "GLDHeaderView.h" +#include "GLDIntList.h" + +/*! + *@struct: TreeViewItem + *@brief {树形结构的一个节点,存储了这一行的所有树形结构相关信息,用于树形显示} + *@author Gaosy + *@date 2012.9.10 + */ +struct GTreeViewItem +{ + GTreeViewItem() : parentIndex(-1), expanded(true), hasChildren(false), + hasMoreSiblings(false), childCount(0), hidden(0), treeLevel(0), modelIndex(QModelIndex()) {} + + int parentIndex; // parent item index in viewItems + uint expanded : 1; + uint hasChildren : 1; // if the item has visible children (even if collapsed) + uint hasMoreSiblings : 1; + uint childCount : 28; // total number of children + uint hidden : 1; + uint treeLevel : 16; + QModelIndex modelIndex; +}; + +/*! + *@class: GlodonTreeDrawInfo + *@brief {辅助绘制TableView的树形结构,记录了树形结构的全部信息} + *@author Gaosy + *@date 2012.9.10 + */ +class GLDTABLEVIEWSHARED_EXPORT GlodonTreeDrawInfo : public QObject +{ +public: + GlodonTreeDrawInfo(QObject *parent) : QObject(parent) + { + m_treeColumn = 0; + m_header = NULL; + model = NULL; + } + ~GlodonTreeDrawInfo(); + + /*! + *从model获取树形结构的全部数据的行数 + *@return int + */ + int modelSectionCount() const; + + /*! + *通过TableView中的数据model来初始化树形结构 + *@param[in] newModel TableView中的数据model + *@return 无 + */ + void setModel(QAbstractItemModel *newModel); + + /*! + *根据给定的index获取其对应的行号 + *@param[in] index + *@return int + */ + int rowNo(QModelIndex index); + /** + * @brief 设置哪列是树形结显示列 + * @param value + */ + void setTreeColumn(int value); + int treeColumn(); + + /** + * @brief 传入一个界面上显示的Row,得到该节点最后一个属于它的节点的行 + * @param parentRow + * @return + */ + int lastChildRow(int parentRow); + + void reset(); + + void calculateRollOut(); + /** + * @brief 传入一个界面上显示的row,得到该节点的根节点 + * @param row + * @return + */ + int calculateRoot(int row); + +public: + + //树形结构需要的所有节点的集合 + QVector m_viewItems; + + //TableView的竖直表头,用于树形结构的展开(折叠)动作发生时 + //显示(隐藏)被展开(折叠)的子行 + GlodonHeaderView *m_header; + + //TableView中的数据model + QAbstractItemModel *model; + + void doExpandItem(int row, QSet &oExpandRows); + int doCollapseItem(int row, QSet &oCollapseRows); + +public Q_SLOTS: + + /*! + *为parent行加入一个子行,并返回新插入行所在的行号 + *@param[in] parent + *@return int + */ + int insertViewItem(int parent, QModelIndex index); + + /*! + *删除一行 + *@param[in] row 要删除的行 + *@return 无 + */ + void removeViewItem(int row); + + /*! + *移动一(多)行 + *@param[in] parent 要移动的行的父节点行号 + *@param[in] first 要移动的行在其父节点下的起始行号 + *@param[in] last 要移动的行在其父节点下的末尾行号 + *@param[in] destinationParent 移动目的地的父节点行号 + *@param[in] row 移动目的地在其父节点下的位置 + *@return 无 + */ + void moveViewItem(int parent, int first, int last, int destinationParent, int row); + + /*! + *展开一行 + *@param[in] row + *@return 无 + */ + void expandItem(int row); + + /*! + *折叠一行 + *@param[in] row + *@return 无 + */ + int collapseItem(int row); + + /*! + *展开全部节点 + *@return 无 + */ + void expandAll(); + + /*! + *折叠全部节点 + *@return 无 + */ + void collapseAll(); + + /*! + *根据model中的父子关系,初始化整个树形结构 + *@param[in] expandAll 默认全部展开 + *@return 无 + */ + void init(bool expandAllLevel = true); + +private: + void setChildItemsExpand(QSet &oExpandRows, int row); + + /** + * @brief 把树形结构前序遍历转储为线性结构 + */ + void transformTreeByLevel(int &index, const QModelIndex &parent, int level); + void transformModelFromTreeToLine(); + + void refreshModelIndexAfterMove(int parent, int row); + void refreshModelIndexAfterInsertOrRemove(int row, int parent, bool insert); + void refreshChildModelIndex(int parent); + + // Todo: 前序遍历和treeBuild应该合并 + void buildTree(bool shouldExpandAllLevel, bool buildHeaderLater = false); + void switchNodeExpandState( + bool shouldExpandAllLevel, bool buildHeaderLater, int i, + QSet &hiddenSections, QSet &visibleSections); + + int setChildItemsCollapse(int row, QSet &oCollapseRows); + + /** + * @brief 递归获取所有行 + * @param index + * @return 所有行,包括子节点的行 + */ + int childRowCount(QModelIndex index = QModelIndex()) const; + +private: + int m_treeColumn;//显示树形结构的列 +}; + +#endif // GLDTREEDRAWINFO_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDTreeModel.h b/GCR/trunk/Glodon/include/GLD/GLDTreeModel.h new file mode 100644 index 00000000..7f8efade --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDTreeModel.h @@ -0,0 +1,89 @@ +/*! + *@file glodontreemodel.h + *@brief {专门为树形结构显示时使用的中间态Model} + * + *@author gaosy-a + *@date 2012.9.7 + *@remarks {remarks} + *Copyright (c) 1998-2012 Glodon Corporation + */ + +#ifndef GLDTREEMODEL_H +#define GLDTREEMODEL_H + +#include +#include +#include "GLDTreeDrawInfo.h" +#include "GLDAbstractItemModel.h" +#include "GLDGlobal.h" + +/*! + *@class: GlodonTreeModel + *@brief {专门为TableView的树形结构显示而使用的中间态Model,将含有树形关系的Model转化去掉树形关系使用} + *@author Gaosy + *@date 2012.9.10 + */ +class GLDTABLEVIEWSHARED_EXPORT GlodonTreeModel : public GlodonAbstractItemModel +{ + Q_OBJECT +public: + /*! + *GlodonTreeModel的构造方法,将原始含有父子结构的model的父子结构去掉 + *@param[in] pModel 含有父子结构的原始model + *@param[in] parent + *@return 无 + */ + explicit GlodonTreeModel(QAbstractItemModel *pModel, QObject *parent = 0); + + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex &child) const; + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + + QMap itemData(const QModelIndex &index) const; + bool setItemData(const QModelIndex &index, const QMap &roles); + + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, + int role = Qt::EditRole); + Qt::ItemFlags flags(const QModelIndex &index) const; + QStringList mimeTypes() const; + QMimeData *mimeData(const QModelIndexList &indexes) const; + bool dropMimeData(const QMimeData *data, Qt::DropAction action, + int row, int column, const QModelIndex &parent); + bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, + int column, const QModelIndex &parent) const; + QModelIndex dataIndex(int row, int column) const; + QModelIndex dataIndex(const QModelIndex &index) const; + + QModelIndex treeIndex(const QModelIndex &dataIndex) const; + + void sort(int column, Qt::SortOrder order = Qt::AscendingOrder); + +public: + //存储树结构对应的信息,即每一行的level、是否有子节点、是否有父节点、是否展开、是否显示、是否有兄弟 + GlodonTreeDrawInfo *drawInfo; + + //原始含有父子结构的model + QAbstractItemModel *model; + + //统一的根节点 + QModelIndex root; + +private Q_SLOTS: + void onRowRemoved(const QModelIndex &parent, int first, int last); + void onRowInserted(const QModelIndex &parent, int first, int last); + void onRowMoved(const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row); + void onUpdate(const QModelIndex &topLeft, const QModelIndex &bottomRight, + const QVector&roles = QVector()); + void onResetModel(); + + int visualRowNo(const QModelIndex &parent, int row) const; +}; + +#endif // GLDTREEMODEL_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDTreeView.h b/GCR/trunk/Glodon/include/GLD/GLDTreeView.h new file mode 100644 index 00000000..0cae32ab --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDTreeView.h @@ -0,0 +1,112 @@ +#ifndef GLDTREEVIEW_H +#define GLDTREEVIEW_H + +#include +#include +#include +#include "GLDTableView_Global.h" + +class GLDTreeDefaultDelegaet; + +class GLDTABLEVIEWSHARED_EXPORT GlodonTreeView : public QTreeView +{ + Q_OBJECT +public: + enum STATE{ + NONE, + DragSection + }; + + enum DragStyle + { + DotLineStyle, + LabelStyle + }; + +public: + GlodonTreeView(QWidget *parent = 0); + +public: + inline bool childNodeDragable() const { return m_rowDragable; } + inline void setChildNodeDragable(bool val) { m_rowDragable = val; } + + /*! + * \brief 节点展开时,自动调整滚动条位置 + * \param value + * \warning 如果通过expand信号,来进行懒加载,则需要在连接了懒加载信号之后,再设置改选项 + */ + void setAutoResetScrollBarAfterExpand(bool value); + inline bool autoResetScrollBarAfterExpand() { return m_autoResetScrollBarAfterExpand; } + + void reset(); + +signals: + void canSectionMove(QModelIndexList from, QModelIndex to, Qt::KeyboardModifiers keyModifiers, bool &canMove, QCursor &cursor); + void sectionMove(QModelIndexList from, QModelIndex to, Qt::KeyboardModifiers keyModifiers); + +protected: + bool viewportEvent(QEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + +protected: + virtual QStyleOptionViewItem initOption(); + virtual void afterExpandedChanged(const QModelIndex &index, bool expanded); + virtual void canDrag(QModelIndexList from, QModelIndex to, Qt::KeyboardModifiers keyModifiers, bool &canMove, QCursor &cursor); + virtual void moveIndex(QModelIndexList from, QModelIndex to, Qt::KeyboardModifiers keyModifiers); + +private slots: + void doExpanded(const QModelIndex &index); + void doCollapsed(const QModelIndex &index); + void autoResetScrollBarOnExpand(const QModelIndex &index); + /*! + * \brief 在关闭编辑后,将编辑中产生的异常抛出 + * \param editor + * \param hint + */ + void afterCloseEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint = QAbstractItemDelegate::NoHint); + +private: + void init(); + void setupIndexIndicator(QModelIndexList indexs, QPoint pt); + void updateIndexIndicator(QPoint pt); + QModelIndex findLastModelIndex(const QModelIndex &index, const QModelIndex &parentIndex, int nCurrentHeight); + /*! + * \brief 设置异常信息,仅用于编辑完成后将编辑中产生的异常抛出 + * \param errCode + * \param errMessage + */ + void setErrorMessage(int errCode, const QString &errMessage); + +private: + bool m_rowDragable; + QPoint m_ptStart; + QLabel *m_pIndicator; + QModelIndexList m_indexFrom; + DragStyle m_dragStyle; + + STATE m_state; + bool m_canSectionMove; + QModelIndex m_expandIndex; + bool m_autoResetScrollBarAfterExpand; + int m_errCode; + QString m_errMessage; +private: + friend class GLDTreeDefaultDelegaet; +}; + +class GLDTABLEVIEWSHARED_EXPORT GLDTreeDefaultDelegaet : public QStyledItemDelegate +{ +public: + GLDTreeDefaultDelegaet(QObject *parent = 0); + virtual ~GLDTreeDefaultDelegaet() {} +public: + void setModelData(QWidget *editor, + QAbstractItemModel *model, + const QModelIndex &index) const; +private: + void doSetModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index); +}; + +#endif // GLDTREEVIEW_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDTreeViewEx.h b/GCR/trunk/Glodon/include/GLD/GLDTreeViewEx.h new file mode 100644 index 00000000..75824222 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDTreeViewEx.h @@ -0,0 +1,68 @@ +#ifndef GLDTREEVIEWEX_H +#define GLDTREEVIEWEX_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "GLDTreeView.h" + +class GlodonTreeViewEx; +class GLDTABLEVIEWSHARED_EXPORT GlodonTreeDelegateEx : public QStyledItemDelegate +{ + Q_OBJECT +public: + GlodonTreeDelegateEx(GlodonTreeViewEx *parent = 0); + + void paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const; + inline void setRootFont(const QFont &font) { m_rootFont = font; } + inline void setOtherFont(const QFont &font) { m_otherFont = font; } + inline QFont rootFont() { return m_rootFont; } + inline QFont otherFont() { return m_otherFont; } + +protected: + virtual QFont fontSize(const QModelIndex &index) const; + virtual QPixmap decorationIcon(const QModelIndex &index) const; + +private: + GlodonTreeViewEx *m_pTreeView; + QFont m_rootFont; + QFont m_otherFont; + +}; + +class GLDTABLEVIEWSHARED_EXPORT GlodonTreeViewEx : public GlodonTreeView +{ + Q_OBJECT +public: + GlodonTreeViewEx(QWidget *parent = 0); + + void setModel(QAbstractItemModel *model); + QModelIndex topParentIndex(const QModelIndex &index); + int currentIndexlLevel(const QModelIndex &index); + QModelIndex expandedIndex(); + + inline void setRootFont(const QFont &font) { m_defaultDelegate->setRootFont(font); } + inline void setOtherFont(const QFont &font) { m_defaultDelegate->setOtherFont(font); } + inline QFont rootFont() { return m_defaultDelegate->rootFont(); } + inline QFont otherFont() { return m_defaultDelegate->otherFont(); } + +private: + void init(); + +private slots: + void doAfterExpand(const QModelIndex &index); + +private: + QModelIndex m_expandedIndex; + GlodonTreeDelegateEx *m_defaultDelegate; +}; + + +#endif // GLDTREEVIEWEX_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDTreeWidget.h b/GCR/trunk/Glodon/include/GLD/GLDTreeWidget.h new file mode 100644 index 00000000..839d34b9 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDTreeWidget.h @@ -0,0 +1,14 @@ +#ifndef GLDTREEWIDGET_H +#define GLDTREEWIDGET_H + +#include +#include "GLDTableView_Global.h" + +class GLDTABLEVIEWSHARED_EXPORT GlodonTreeWidget : public QTreeWidget +{ + Q_OBJECT +public: + inline GlodonTreeWidget(QWidget *parent = 0) : QTreeWidget(parent) {} +}; + +#endif // GLDTREEWIDGET_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDTypes.h b/GCR/trunk/Glodon/include/GLD/GLDTypes.h new file mode 100644 index 00000000..43611963 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDTypes.h @@ -0,0 +1,41 @@ +#ifndef GLDTYPES_H +#define GLDTYPES_H + +#include "GLDSystem.h" +#include "GLDEnum.h" + +#include "GLDChar.h" +#include "GLDString.h" +#include "GLDByteArray.h" +#include "GLDUuid.h" +#include "GLDDateTime.h" +#include "GLDVariant.h" + +#include "GLDList.h" +#include "GLDMap.h" +#include "GLDStack.h" + +#include "GLDIntList.h" +#include "GLDStringList.h" +#include "GLDVariantList.h" + +#include "GLDIODevice.h" +#include "GLDBuffer.h" +#include "GLDFile.h" +#include "GLDFileInfo.h" +#include "GLDMutex.h" +#include "GLDRunnable.h" +#include "GLDThread.h" +#include "GLDDir.h" +#include "GLDSettings.h" +#include "GLDTextStream.h" + +#include "GLDResourceDef.h" +#include "GLDGlobal.h" + +namespace GLD +{ + using namespace Qt; +} + +#endif // GLDTYPES_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDUITypes.h b/GCR/trunk/Glodon/include/GLD/GLDUITypes.h new file mode 100644 index 00000000..3e0aea0d --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDUITypes.h @@ -0,0 +1,12 @@ +#ifndef GLDUITYPES_H +#define GLDUITYPES_H + +#include +#include +#include + +typedef QFont GFont; +typedef QColor GColor; +typedef QIcon GIcon; + +#endif // GLDUITYPES_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDUIUtils.h b/GCR/trunk/Glodon/include/GLD/GLDUIUtils.h new file mode 100644 index 00000000..bcefedf2 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDUIUtils.h @@ -0,0 +1,52 @@ +/******************************************************************** +这个模块会使用到Qt GUI,如果包含该单元,请使用Qt+=GUI,否则编译不通过。by huy-a. +********************************************************************/ +#ifndef GLDUIUTILS_H +#define GLDUIUTILS_H + +#include "GLDStrUtils.h" +#include +#include "GLDStrings.h" +extern const char *rsConfirmCaption; + +GLDCOMMONSHARED_EXPORT void showPrompt(const GString &msg, bool bShowClose = true, QWidget *parent = NULL); +GLDCOMMONSHARED_EXPORT void showError(const GString &msg, QWidget *parent = NULL); +GLDCOMMONSHARED_EXPORT void showWarnning(const GString &msg, QWidget *parent = NULL); +GLDCOMMONSHARED_EXPORT int showConfirm(const GString &msg, QWidget *parent = NULL); + +GLDCOMMONSHARED_EXPORT int confirmDlg(const GString msg, bool cancelButton = false, QWidget *parent = NULL); + +//bool createDesktopPromtInfo(const GString &linkPath, const GString &iconPath, int nInfoNumber); + +//缺省的设置MessageBox函数 +class GLDCOMMONSHARED_EXPORT GLDDefaultConfirmSettingFuc +{ +public: + inline void operator()(QMessageBox &box) + { + box.setDefaultButton(QMessageBox::Ok); + box.setStyleSheet("QPushButton:default {color: blue}"); + } +}; + +template +int confirmDlg(const GString msg, bool cancelButton, QWidget *parent, T Func) +{ + QMessageBox::StandardButtons standardBtns = QMessageBox::Ok | QMessageBox::No; + + if (cancelButton) + { + standardBtns |= QMessageBox::Cancel; + } + + QMessageBox tempBox(QMessageBox::Question, getGLDi18nStr(rsConfirmCaption), msg, standardBtns, parent); + Func(tempBox); + return tempBox.exec(); +} + +inline int confirmDlgEx(const GString msg, bool cancelButton = false, QWidget *parent = NULL) +{ + return confirmDlg(msg, cancelButton, parent, GLDDefaultConfirmSettingFuc()); +} + +#endif // GLDUIUTILS_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDUnknwn.h b/GCR/trunk/Glodon/include/GLD/GLDUnknwn.h new file mode 100644 index 00000000..652db539 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDUnknwn.h @@ -0,0 +1,450 @@ +#ifndef GUNKNWN_H +#define GUNKNWN_H + + +/********************************************************************** + * + * 广联达接口定义单元 + * + * 设计:linw 2012.03.26 + * 备注: + * 审核: + * + * Copyright (c) 1994-2012 GlodonSoft Corporation + * + **********************************************************************/ + +//TODO: #define INITGUID +#if defined(WIN32) || defined(WIN64) +# include +# include +#else +# include "GLDObjBase.h" +# include "GLDGuidDef.h" +# include "GLDWinErrorDef.h" +#endif //WIN32 + +#ifndef WIN32 +inline unsigned long wcharToULong(wchar_t *p, unsigned char size) +{ + unsigned long result = 0; + for (unsigned char i = 0; i != size; ++i) + { + wchar_t ch = *p; + if (ch >= L'a') + ch -= 32; + if (ch >= L'A') + ch -= 7; + ch -= L'0'; + result = result << 4; + result += ch; + ++p; + } + return result; +} + +inline HRESULT CLSIDFromString(LPCOLESTR lpsz, LPCLSID pclsid) +{ + wchar_t *p = (wchar_t *)lpsz + 1; // '{' + pclsid->Data1 = wcharToULong(p, 8); + p += 9; // '-' + pclsid->Data2 = (unsigned short)wcharToULong(p, 4); + p += 5; // '-' + pclsid->Data3 = (unsigned short)wcharToULong(p, 4); + p += 5; // '-' + pclsid->Data4[0] = (unsigned char)wcharToULong(p, 2); + p += 2; + pclsid->Data4[1] = (unsigned char)wcharToULong(p, 2); + p += 3; // '-' + pclsid->Data4[2] = (unsigned char)wcharToULong(p, 2); + p += 2; + pclsid->Data4[3] = (unsigned char)wcharToULong(p, 2); + p += 2; + pclsid->Data4[4] = (unsigned char)wcharToULong(p, 2); + p += 2; + pclsid->Data4[5] = (unsigned char)wcharToULong(p, 2); + p += 2; + pclsid->Data4[6] = (unsigned char)wcharToULong(p, 2); + p += 2; + pclsid->Data4[7] = (unsigned char)wcharToULong(p, 2); + return 0; +} +#endif //WIN32 + +/**************************************************************************** + * __uuidof + ****************************************************************************/ +inline GUID GUIDFromString(LPOLESTR lpsz) +{ + GUID guid; + CLSIDFromString(lpsz, &guid); + return guid; +} + +#if defined(WIN32) || defined(WIN64) +//Microsoft OS Platform +# define _DEFINE_UUID(Class, uid) \ + struct __declspec(uuid(uid)) Class; +#else + template + struct GuidTraits {}; +# define _DEFINE_UUID(Class, uuid) \ + template <> \ + struct GuidTraits { \ + static const GUID& Guid() { \ + static const wchar_t *str = L ## uuid; \ + static GUID guid = GUIDFromString((LPOLESTR)str); \ + return guid; \ + } \ + } +# ifdef __MINGW32__ +# undef __uuidof +# endif +# define __uuidof(Class) GuidTraits::Guid() +#endif //OS Platform + +#define DEFINE_CLSID(Class, guid) \ +class Class; \ +_DEFINE_UUID(Class, guid) + +#define DEFINE_IID(Interface, iid) \ +struct Interface; \ +_DEFINE_UUID(Interface, iid) + +//struct __declspec(uuid(iid)) Interface + +#define GLD_OK S_OK +#define GLD_FALSE S_FALSE + +#define GLDMETHODCALLTYPE STDMETHODCALLTYPE +#define GLDMETHOD(type, method) virtual type GLDMETHODCALLTYPE method + +#define GSPMETHODCALLTYPE STDMETHODCALLTYPE +#define GSPMETHOD(type, method) virtual type GSPMETHODCALLTYPE method + +#define GRPMETHODCALLTYPE STDMETHODCALLTYPE +#define GRPMETHOD(type, method) virtual type GRPMETHODCALLTYPE method + +#ifdef GDP_QT +# define GSPMETHODIMP void GSPMETHODCALLTYPE +# define GSP_OK +# define GSP_FALSE +#else +# define GSPMETHODIMP STDMETHODIMP +# define GSP_OK GLD_OK +# define GSP_FALSE GLD_FALSE +#endif + +DEFINE_IID(IUnknown, "{00000000-0000-0000-C000-000000000046}"); +//DEFINE_IID(IClassFactory, "{00000001-0000-0000-C000-000000000046}"); +//DEFINE_IID(ITypeInfo, "{00020401-0000-0000-C000-000000000046}"); +//DEFINE_IID(IDispatch, "00020400-0000-0000-C000-000000000046"); +//DEFINE_IID(ISequentialStream, "{0C733A30-2A1C-11CE-ADE5-00AA0044773D}"); +//DEFINE_IID(IStream, "{0000000C-0000-0000-C000-000000000046}"); + +#ifndef WIN32 + +const IID IID_IUnknown = + { 0x00000000, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } }; +const IID IID_IClassFactory = + { 0x00000001, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } }; +const IID IID_ITypeInfo = + { 0x00020401, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } }; +const IID IID_IDispatch = + { 0x00020400, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } }; +const IID IID_ISequentialStream = + { 0x0C733A30, 0x2A1C, 0x11CE, { 0xAD, 0xE5, 0x00, 0xAA, 0x00, 0x44, 0x77, 0x3D } }; +const IID IID_IStream = + { 0x0000000C, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } }; + +#define __RPC__out +#define __RPC__in +#define __RPC__deref_out_opt +#define __RPC__in_ecount_full(cNames) +#define __RPC__in_range(a, b) +#define _In_reads_bytes_(a) +#define __RPC__out_ecount_full(cNames) +#define _Out_writes_bytes_to_(a, b) +#define _In_ +#define _Out_opt_ + +//COM定义IUnknown, Factory接口 + +//#ifdef __cplusplus +//extern "C"{ +//#endif + + +//+------------------------------------------------------------------------- +// +// Modi By Microsoft Windows +// +//-------------------------------------------------------------------------- + +#ifndef __IUnknown_INTERFACE_DEFINED__ +#define __IUnknown_INTERFACE_DEFINED__ + +/*EXTERN_C*/ + +DECLARE_INTERFACE(IUnknown) +{ +public: + BEGIN_INTERFACE + + virtual HRESULT STDMETHODCALLTYPE QueryInterface( + /* [in] */ REFIID riid, + /* [iid_is][out] */ void **ppvObject) = 0; + + virtual ULONG STDMETHODCALLTYPE AddRef(void) = 0; + + virtual ULONG STDMETHODCALLTYPE Release(void) = 0; + + END_INTERFACE +}; + +typedef /* [unique] */ IUnknown *LPUNKNOWN; + +#endif /* __IUnknown_INTERFACE_DEFINED__ */ + + + +////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////// + +#ifndef __IClassFactory_INTERFACE_DEFINED__ +#define __IClassFactory_INTERFACE_DEFINED__ + +DECLARE_INTERFACE_(IClassFactory, IUnknown) +{ +public: + virtual /* [local] */ HRESULT STDMETHODCALLTYPE CreateInstance( + /* [unique][in] */ IUnknown *pUnkOuter, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void **ppvObject) = 0; + + virtual /* [local] */ HRESULT STDMETHODCALLTYPE LockServer( + /* [in] */ BOOL fLock) = 0; +}; + +typedef /* [unique] */ IClassFactory *LPCLASSFACTORY; + +#endif /* __IClassFactory_INTERFACE_DEFINED__ */ + + + +//#ifdef __cplusplus +//} +//#endif + +DECLARE_INTERFACE_(ITypeInfo, IUnknown) +{ +public: +// virtual /* [local] */ HRESULT STDMETHODCALLTYPE GetTypeAttr( +// /* [out] */ TYPEATTR **ppTypeAttr) = 0; + +// virtual HRESULT STDMETHODCALLTYPE GetTypeComp( +// /* [out] */ __RPC__deref_out_opt ITypeComp **ppTComp) = 0; + +// virtual /* [local] */ HRESULT STDMETHODCALLTYPE GetFuncDesc( +// /* [in] */ UINT index, +// /* [out] */ FUNCDESC **ppFuncDesc) = 0; + +// virtual /* [local] */ HRESULT STDMETHODCALLTYPE GetVarDesc( +// /* [in] */ UINT index, +// /* [out] */ VARDESC **ppVarDesc) = 0; + +// virtual /* [local] */ HRESULT STDMETHODCALLTYPE GetNames( +// /* [in] */ MEMBERID memid, +// /* [length_is][size_is][out] */ BSTR *rgBstrNames, +// /* [in] */ UINT cMaxNames, +// /* [out] */ UINT *pcNames) = 0; + +// virtual HRESULT STDMETHODCALLTYPE GetRefTypeOfImplType( +// /* [in] */ UINT index, +// /* [out] */ __RPC__out HREFTYPE *pRefType) = 0; + +// virtual HRESULT STDMETHODCALLTYPE GetImplTypeFlags( +// /* [in] */ UINT index, +// /* [out] */ __RPC__out INT *pImplTypeFlags) = 0; + +// virtual /* [local] */ HRESULT STDMETHODCALLTYPE GetIDsOfNames( +// /* [annotation][size_is][in] */ +// __RPC__in_ecount(cNames) LPOLESTR *rgszNames, +// /* [in] */ UINT cNames, +// /* [size_is][out] */ MEMBERID *pMemId) = 0; + +// virtual /* [local] */ HRESULT STDMETHODCALLTYPE Invoke( +// /* [in] */ PVOID pvInstance, +// /* [in] */ MEMBERID memid, +// /* [in] */ WORD wFlags, +// /* [out][in] */ DISPPARAMS *pDispParams, +// /* [out] */ VARIANT *pVarResult, +// /* [out] */ EXCEPINFO *pExcepInfo, +// /* [out] */ UINT *puArgErr) = 0; + +// virtual /* [local] */ HRESULT STDMETHODCALLTYPE GetDocumentation( +// /* [in] */ MEMBERID memid, +// /* [out] */ BSTR *pBstrName, +// /* [out] */ BSTR *pBstrDocString, +// /* [out] */ DWORD *pdwHelpContext, +// /* [out] */ BSTR *pBstrHelpFile) = 0; + +// virtual /* [local] */ HRESULT STDMETHODCALLTYPE GetDllEntry( +// /* [in] */ MEMBERID memid, +// /* [in] */ INVOKEKIND invKind, +// /* [out] */ BSTR *pBstrDllName, +// /* [out] */ BSTR *pBstrName, +// /* [out] */ WORD *pwOrdinal) = 0; + +// virtual HRESULT STDMETHODCALLTYPE GetRefTypeInfo( +// /* [in] */ HREFTYPE hRefType, +// /* [out] */ __RPC__deref_out_opt ITypeInfo **ppTInfo) = 0; + +// virtual /* [local] */ HRESULT STDMETHODCALLTYPE AddressOfMember( +// /* [in] */ MEMBERID memid, +// /* [in] */ INVOKEKIND invKind, +// /* [out] */ PVOID *ppv) = 0; + +// virtual /* [local] */ HRESULT STDMETHODCALLTYPE CreateInstance( +// /* [in] */ IUnknown *pUnkOuter, +// /* [in] */ REFIID riid, +// /* [iid_is][out] */ PVOID *ppvObj) = 0; + +// virtual HRESULT STDMETHODCALLTYPE GetMops( +// /* [in] */ MEMBERID memid, +// /* [out] */ __RPC__deref_out_opt BSTR *pBstrMops) = 0; + +// virtual /* [local] */ HRESULT STDMETHODCALLTYPE GetContainingTypeLib( +// /* [out] */ ITypeLib **ppTLib, +// /* [out] */ UINT *pIndex) = 0; + +// virtual /* [local] */ void STDMETHODCALLTYPE ReleaseTypeAttr( +// /* [in] */ TYPEATTR *pTypeAttr) = 0; + +// virtual /* [local] */ void STDMETHODCALLTYPE ReleaseFuncDesc( +// /* [in] */ FUNCDESC *pFuncDesc) = 0; + +// virtual /* [local] */ void STDMETHODCALLTYPE ReleaseVarDesc( +// /* [in] */ VARDESC *pVarDesc) = 0; +}; + +typedef struct tagSTATSTG +{ + LPOLESTR pwcsName; + DWORD type; + ULARGE_INTEGER cbSize; + FILETIME mtime; + FILETIME ctime; + FILETIME atime; + DWORD grfMode; + DWORD grfLocksSupported; + CLSID clsid; + DWORD grfStateBits; + DWORD reserved; +} STATSTG; + +DECLARE_INTERFACE_(IDispatch, IUnknown) +{ +public: + virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount( + /* [out] */ __RPC__out UINT *pctinfo) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetTypeInfo( + /* [in] */ UINT iTInfo, + /* [in] */ LCID lcid, + /* [out] */ __RPC__deref_out_opt ITypeInfo **ppTInfo) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames( + /* [in] */ __RPC__in REFIID riid, + /* [size_is][in] */ __RPC__in_ecount_full(cNames) LPOLESTR *rgszNames, + /* [range][in] */ __RPC__in_range(0,16384) UINT cNames, + /* [in] */ LCID lcid, + /* [size_is][out] */ __RPC__out_ecount_full(cNames) DISPID *rgDispId) = 0; + + virtual /* [local] */ HRESULT STDMETHODCALLTYPE Invoke( + /* [annotation][in] */ + _In_ DISPID dispIdMember, + /* [annotation][in] */ + _In_ REFIID riid, + /* [annotation][in] */ + _In_ LCID lcid, + /* [annotation][in] */ + _In_ WORD wFlags, + /* [annotation][out][in] */ + _In_ DISPPARAMS *pDispParams, + /* [annotation][out] */ + _Out_opt_ VARIANT *pVarResult, + /* [annotation][out] */ + _Out_opt_ EXCEPINFO *pExcepInfo, + /* [annotation][out] */ + _Out_opt_ UINT *puArgErr) = 0; + +}; + +DECLARE_INTERFACE_(ISequentialStream, IUnknown) +{ +public: + virtual /* [local] */ HRESULT STDMETHODCALLTYPE Read( + /* [annotation] */ + _Out_writes_bytes_to_(cb, *pcbRead) void *pv, + /* [annotation][in] */ + _In_ ULONG cb, + /* [annotation] */ + _Out_opt_ ULONG *pcbRead) = 0; + + virtual /* [local] */ HRESULT STDMETHODCALLTYPE Write( + /* [annotation] */ + _In_reads_bytes_(cb) const void *pv, + /* [annotation][in] */ + _In_ ULONG cb, + /* [annotation] */ + _Out_opt_ ULONG *pcbWritten) = 0; +}; + +DECLARE_INTERFACE_(IStream, ISequentialStream) +{ +public: + virtual /* [local] */ HRESULT STDMETHODCALLTYPE Seek( + /* [in] */ LARGE_INTEGER dlibMove, + /* [in] */ DWORD dwOrigin, + /* [annotation] */ + _Out_opt_ ULARGE_INTEGER *plibNewPosition) = 0; + + virtual HRESULT STDMETHODCALLTYPE SetSize( + /* [in] */ ULARGE_INTEGER libNewSize) = 0; + + virtual /* [local] */ HRESULT STDMETHODCALLTYPE CopyTo( + /* [annotation][unique][in] */ + _In_ IStream *pstm, + /* [in] */ ULARGE_INTEGER cb, + /* [annotation] */ + _Out_opt_ ULARGE_INTEGER *pcbRead, + /* [annotation] */ + _Out_opt_ ULARGE_INTEGER *pcbWritten) = 0; + + virtual HRESULT STDMETHODCALLTYPE Commit( + /* [in] */ DWORD grfCommitFlags) = 0; + + virtual HRESULT STDMETHODCALLTYPE Revert( void) = 0; + + virtual HRESULT STDMETHODCALLTYPE LockRegion( + /* [in] */ ULARGE_INTEGER libOffset, + /* [in] */ ULARGE_INTEGER cb, + /* [in] */ DWORD dwLockType) = 0; + + virtual HRESULT STDMETHODCALLTYPE UnlockRegion( + /* [in] */ ULARGE_INTEGER libOffset, + /* [in] */ ULARGE_INTEGER cb, + /* [in] */ DWORD dwLockType) = 0; + + virtual HRESULT STDMETHODCALLTYPE Stat( + /* [out] */ __RPC__out STATSTG *pstatstg, + /* [in] */ DWORD grfStatFlag) = 0; + + virtual HRESULT STDMETHODCALLTYPE Clone( + /* [out] */ __RPC__deref_out_opt IStream **ppstm) = 0; +}; + +#endif //WIN32 + +#endif // GUNKNWN_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDUuid.h b/GCR/trunk/Glodon/include/GLD/GLDUuid.h new file mode 100644 index 00000000..a0e41d41 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDUuid.h @@ -0,0 +1,8 @@ +#ifndef GLDUUID +#define GLDUUID + +#include +typedef QUuid GUuid; + +#endif // GLDUUID + diff --git a/GCR/trunk/Glodon/include/GLD/GLDVariant.h b/GCR/trunk/Glodon/include/GLD/GLDVariant.h new file mode 100644 index 00000000..32157419 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDVariant.h @@ -0,0 +1,9 @@ +#ifndef GLDVARIANT +#define GLDVARIANT + +#include + +typedef QVariant GVariant; + +#endif // GLDVARIANT + diff --git a/GCR/trunk/Glodon/include/GLD/GLDVariantList.h b/GCR/trunk/Glodon/include/GLD/GLDVariantList.h new file mode 100644 index 00000000..36e2cd6e --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDVariantList.h @@ -0,0 +1,10 @@ +#ifndef GLDVARIANTLIST +#define GLDVARIANTLIST + +#include +#include "GLDVariant.h" + +typedef QList GVariantList; + +#endif // GLDVARIANTLIST + diff --git a/GCR/trunk/Glodon/include/GLD/GLDVector.h b/GCR/trunk/Glodon/include/GLD/GLDVector.h new file mode 100644 index 00000000..217a3c95 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDVector.h @@ -0,0 +1,149 @@ +#ifndef GLDVECTOR_H +#define GLDVECTOR_H + +#include + +using namespace std; + +template +class GLDVector : public vector +{ +public: + typedef typename vector::size_type size_type; + typedef typename vector::const_iterator const_iterator; + typedef typename vector::iterator iterator; +public: + GLDVector() : vector() + { + } + + GLDVector(size_type count) : vector(count) + { + } + + inline int count() const { return (int)vector::size(); } + + int count(const T &value) + { + iterator cit = std::remove(begin(), end(), value); + int nCount = std::distance(cit, vector::end()); + return nCount; + } + + const_iterator find(const T &value, int from = 0) const + { + const_iterator it = vector::begin() + from; + for (; it != vector::end(); ++it) + { + if (*it == value) + break; + } + return it; + } + + int indexOf(const T &value, int from = 0) const + { + const_iterator itor = find(value, from); + if (itor != vector::end()) + return int(itor - vector::begin()); + else + return -1; + } + + int lastIndexOf(const T &value, int from = -1) const + { + if (from < 0) + { + from += size(); + } + else if (from >= int(size())) + { + from = size() - 1; + } + else + { + const_iterator b = vector::begin(); + const_iterator n = vector::begin() + from + 1; + while (n != b) { + if (*--n == value) + return n - b; + } + } + return -1; + } + + void insert(int index, const T &t) + { + vector::insert(vector::begin() + index, t); + } + + void Delete(int index) + { + vector::erase(vector::begin() + index); + } + + int remove(const T &value) + { +#ifdef _MSC_VER + for (const_iterator it = vector::begin(); it != vector::end(); ++it) +#else + for (iterator it = vector::begin(); it != vector::end(); ++it) +#endif + { + if (*it == value) + { + int result = int(it - vector::begin()); + vector::erase(it); + return result; + } + } + return -1; + } + + int removeAll(const T &value) + { + const iterator cit = std::remove(vector::begin(), vector::end(), value); + int nCount = std::distance(cit, vector::end()); + vector::erase(cit, vector::end()); + return nCount; + } + + void move(int from, int to) + { + if (from == to) + return; + iterator itorFrom = vector::begin() + from; + iterator itorTo = vector::begin() + to; + const T c_value = *itorFrom; + if (from > to) + { + for (; itorFrom != itorTo; itorFrom--) + { + *itorFrom = *(itorFrom - 1); + } + } + else if (from < to) + { + for (; itorFrom != itorTo; itorFrom++) + { + *itorFrom = *(itorFrom + 1); + } + } + *itorTo = c_value; + } + + inline GLDVector &operator<< (const T &t) + { + push_back(t); + return *this; + } + +#ifdef CPP11PRE + inline const_iterator cbegin() const { return begin(); } + inline const_iterator cend() const { return end(); } + inline const_reverse_iterator crbegin() const { return rbegin(); } + inline const_reverse_iterator crend() const { return rend(); } +#endif +}; + +#endif // GLDVECTOR_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDWAbstractspinbox.h b/GCR/trunk/Glodon/include/GLD/GLDWAbstractspinbox.h new file mode 100644 index 00000000..35aeba2b --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDWAbstractspinbox.h @@ -0,0 +1,164 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtWidgets module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef GLDWABSTRACTSPINBOX_H +#define GLDWABSTRACTSPINBOX_H + +#include +#include +#include +//#include "GLDWAbstractspinbox_p.h" +#include "GLDWidget_Global.h" + +#ifndef QT_NO_SPINBOX + +class GLDPlainTextEdit; + +class GLDWAbstractSpinBoxPrivate; +class QStyleOptionSpinBox; + +class GLDWIDGETSHARED_EXPORT GLDWAbstractSpinBox : public QWidget +{ + Q_OBJECT + + Q_ENUMS(ButtonSymbols) + Q_ENUMS(CorrectionMode) + Q_PROPERTY(bool wrapping READ wrapping WRITE setWrapping) + Q_PROPERTY(bool frame READ hasFrame WRITE setFrame) + Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment) + Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly) +// Q_PROPERTY(ButtonSymbols buttonSymbols READ buttonSymbols WRITE setButtonSymbols) + Q_PROPERTY(QString specialValueText READ specialValueText WRITE setSpecialValueText) + Q_PROPERTY(QString text READ text) + Q_PROPERTY(bool accelerated READ isAccelerated WRITE setAccelerated) +// Q_PROPERTY(CorrectionMode correctionMode READ correctionMode WRITE setCorrectionMode) + Q_PROPERTY(bool acceptableInput READ hasAcceptableInput) + Q_PROPERTY(bool keyboardTracking READ keyboardTracking WRITE setKeyboardTracking) +public: + explicit GLDWAbstractSpinBox(QWidget *parent = 0); + ~GLDWAbstractSpinBox(); + +// Q_DECLARE_FLAGS(StepEnabled, StepEnabledFlag) + + QAbstractSpinBox::ButtonSymbols buttonSymbols() const; + void setButtonSymbols(QAbstractSpinBox::ButtonSymbols bs); + + void setCorrectionMode(QAbstractSpinBox::CorrectionMode cm); + QAbstractSpinBox::CorrectionMode correctionMode() const; + + bool hasAcceptableInput() const; + QString text() const; + + QString specialValueText() const; + void setSpecialValueText(const QString &txt); + + bool wrapping() const; + void setWrapping(bool w); + + void setReadOnly(bool r); + bool isReadOnly() const; + + void setKeyboardTracking(bool kt); + bool keyboardTracking() const; + + void setAlignment(Qt::Alignment flag); + Qt::Alignment alignment() const; + + void setFrame(bool); + bool hasFrame() const; + + void setAccelerated(bool on); + bool isAccelerated() const; + + QSize sizeHint() const; + QSize minimumSizeHint() const; + void interpretText(); + bool event(QEvent *event); + + QVariant inputMethodQuery(Qt::InputMethodQuery) const; +public Q_SLOTS: +// void stepUp(); +// void stepDown(); + void selectAll(); + virtual void clear(); +protected: + void resizeEvent(QResizeEvent *event); + void keyPressEvent(QKeyEvent *event); + void keyReleaseEvent(QKeyEvent *event); +#ifndef QT_NO_WHEELEVENT + void wheelEvent(QWheelEvent *event); +#endif + void focusInEvent(QFocusEvent *event); + void focusOutEvent(QFocusEvent *event); + void contextMenuEvent(QContextMenuEvent *event); + void changeEvent(QEvent *event); + void closeEvent(QCloseEvent *event); + void hideEvent(QHideEvent *event); + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void timerEvent(QTimerEvent *event); + void paintEvent(QPaintEvent *event); + void showEvent(QShowEvent *event); + void initStyleOption(QStyleOptionSpinBox *option) const; + + GLDPlainTextEdit *lineEdit() const; + void setLineEdit(GLDPlainTextEdit *edit); + +// virtual StepEnabled stepEnabled() const; +Q_SIGNALS: + void editingFinished(); +protected: + GLDWAbstractSpinBox(GLDWAbstractSpinBoxPrivate &dd, QWidget *parent = 0); + +private: +// Q_PRIVATE_SLOT(d_func(), void _q_editorTextChanged(const QString &)) +// Q_PRIVATE_SLOT(d_func(), void _q_editorCursorPositionChanged(int, int)) + + Q_DECLARE_PRIVATE(GLDWAbstractSpinBox) + Q_DISABLE_COPY(GLDWAbstractSpinBox) +}; + +//Q_DECLARE_OPERATORS_FOR_FLAGS(QAbstractSpinBox::StepEnabled) + +#endif // QT_NO_SPINBOX + +#endif // GLDWABSTRACTSPINBOX_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDWAbstractspinbox_p.h b/GCR/trunk/Glodon/include/GLD/GLDWAbstractspinbox_p.h new file mode 100644 index 00000000..10cfb7f7 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDWAbstractspinbox_p.h @@ -0,0 +1,152 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtWidgets module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef GLDWABSTRACTSPINBOX_P_H +#define GLDWABSTRACTSPINBOX_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "GLDWAbstractspinbox.h" +class GLDPlainTextEdit; + +#ifndef QT_NO_SPINBOX + +#include "QtWidgets/qlineedit.h" +#include "QtWidgets/qstyleoption.h" +#include "QtGui/qvalidator.h" +#include "QtCore/qdatetime.h" +#include "QtCore/qvariant.h" +#include "private/qwidget_p.h" +#include "private/qdatetime_p.h" +#include "private/qabstractspinbox_p.h" + +QVariant operator+(const QVariant &arg1, const QVariant &arg2); +QVariant operator-(const QVariant &arg1, const QVariant &arg2); +QVariant operator*(const QVariant &arg1, double multiplier); +double operator/(const QVariant &arg1, const QVariant &arg2); + +class GLDWSpinBoxValidator; +class GLDWAbstractSpinBoxPrivate : public QWidgetPrivate +{ + Q_DECLARE_PUBLIC(GLDWAbstractSpinBox) +public: + GLDWAbstractSpinBoxPrivate(); + ~GLDWAbstractSpinBoxPrivate(); + + void init(); + void reset(); + void updateState(bool up, bool fromKeyboard = false); + QString stripped(const QString &text, int *pos = 0) const; + bool specialValue() const; + virtual QVariant getZeroVariant() const; + virtual void setRange(const QVariant &min, const QVariant &max); + void setValue(const QVariant &val, EmitPolicy ep, bool updateEdit = true); + virtual QVariant bound(const QVariant &val, const QVariant &old = QVariant(), int steps = 0) const; + virtual void updateEdit(); + + virtual void emitSignals(EmitPolicy ep, const QVariant &old); + virtual void interpret(EmitPolicy ep); + virtual QString textFromValue(const QVariant &n) const; + virtual QVariant valueFromText(const QString &input) const; + + void _q_editorTextChanged(const QString &); + virtual void _q_editorCursorPositionChanged(int oldpos, int newpos); + + virtual QStyle::SubControl newHoverControl(const QPoint &pos); + bool updateHoverControl(const QPoint &pos); + + virtual void clearCache() const; + virtual void updateEditFieldGeometry(); + + static int variantCompare(const QVariant &arg1, const QVariant &arg2); + static QVariant variantBound(const QVariant &min, const QVariant &value, const QVariant &max); + + GLDPlainTextEdit *edit; + QString prefix, suffix, specialValueText; + QVariant value, minimum, maximum, singleStep; + QVariant::Type type; + int spinClickTimerId, spinClickTimerInterval, spinClickThresholdTimerId, spinClickThresholdTimerInterval; + int effectiveSpinRepeatRate; + uint buttonState; + mutable QString cachedText; + mutable QVariant cachedValue; + mutable QValidator::State cachedState; + mutable QSize cachedSizeHint, cachedMinimumSizeHint; + uint pendingEmit : 1; + uint readOnly : 1; + uint wrapping : 1; + uint ignoreCursorPositionChanged : 1; + uint frame : 1; + uint accelerate : 1; + uint keyboardTracking : 1; + uint cleared : 1; + uint ignoreUpdateEdit : 1; + QAbstractSpinBox::CorrectionMode correctionMode; + int acceleration; + QStyle::SubControl hoverControl; + QRect hoverRect; + QAbstractSpinBox::ButtonSymbols buttonSymbols; +// GLDWSpinBoxValidator *validator; +}; + +//class GLDWSpinBoxValidator : public QValidator +//{ +//public: +// GLDWSpinBoxValidator(GLDWAbstractSpinBox *qptr, GLDWAbstractSpinBoxPrivate *dptr); +// QValidator::State validate(QString &input, int &) const; +// void fixup(QString &) const; +//private: +// GLDWAbstractSpinBox *qptr; +// GLDWAbstractSpinBoxPrivate *dptr; +//}; + +#endif // QT_NO_SPINBOX + +#endif // GLDWABSTRACTSPINBOX_P_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDWebLogin.h b/GCR/trunk/Glodon/include/GLD/GLDWebLogin.h new file mode 100644 index 00000000..6a467fad --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDWebLogin.h @@ -0,0 +1,100 @@ +#ifndef GLDWEBLOGIN_H +#define GLDWEBLOGIN_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "GLDString.h" +#include "GLDWidget_Global.h" + +class QPushButton; +class GLDKeyboardInput; + +enum GLDLoginState +{ + seSuccess = 0, + seAccountError = 1, + sePasswordError = 2, + seUnknow = 3, + seNetworkError =4 +}; + +class GLDWIDGETSHARED_EXPORT GLDWebLogin : public QDialog +{ + Q_OBJECT +public: + explicit GLDWebLogin(QWidget *parent = 0); + ~GLDWebLogin(); + +public: + void setRegisterAccountURL(const GString ®isterAccountURL); + GString registerAccountURL(); + void setRetrievePasswordURL(const GString &retrievePasswordURL); + GString retrievePasswordURL(); + void setLoginState(GLDLoginState loginState); + GLDLoginState loginState(); + +protected: + void setUpUI(); + void setUIEnable(bool enable); + void mouseMoveEvent(QMouseEvent *event); + void resizeEvent(QResizeEvent *event); + void mousePressEvent(QMouseEvent *event); + void showErrorNotifiy(GLDLoginState error, const GString &msg); + +private: + void addTitle(QVBoxLayout *pMainlayout); + void addCenter(QVBoxLayout *pMainlayout); + void addErrorInfo(QVBoxLayout *pMainlayout); + void addLoginButton(QVBoxLayout *pMainlayout); + void addUserName(QVBoxLayout *pCenterlayout); + void addPassword(QVBoxLayout *pCenterlayout); + void addCheckBoxes(QVBoxLayout *pCenterlayout); + +signals: + void loginSuccess(const GString& sAccountName); + +public slots: + void login(); + void registerAcc(); + void retrievePass(); + void openKeyboard(); + void onClickedDeletebtn(); + void onClickedBtn(const QString &string); + +private: + QLineEdit *m_edtAccount; //用户名 + QLineEdit *m_edtPassword; //密码 + QPushButton *m_btnInfo; //用户名或密码错误时,提示信息 + QPushButton *m_btnLogin; //登陆按钮 + QPushButton *m_btnKeyboard; //弹出虚拟键盘 + + QPoint m_dragPoint; + + GString m_password; + GString m_sRegisterAccountURL; + GString m_sRetrievePasswordURL; + GLDLoginState m_loginState; +}; + + +class GLDWIDGETSHARED_EXPORT GLDLoginTitle : public QLabel +{ + Q_OBJECT +public: + explicit GLDLoginTitle(QWidget *parent = 0); + ~GLDLoginTitle() {} + +signals: + void sigCloseClicked(); + +private: + void buildUI(); +}; +#endif // GLDWEBLOGIN_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDWidget_Global.h b/GCR/trunk/Glodon/include/GLD/GLDWidget_Global.h new file mode 100644 index 00000000..4a3f8e94 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDWidget_Global.h @@ -0,0 +1,16 @@ +#ifndef GLDWIDGET_GLOBAL_H +#define GLDWIDGET_GLOBAL_H + +#include + +#ifndef GLD_FULLSOURCE + #if defined(GLDWIDGET_LIBRARY) + # define GLDWIDGETSHARED_EXPORT Q_DECL_EXPORT + #else + # define GLDWIDGETSHARED_EXPORT Q_DECL_IMPORT + #endif +#else + #define GLDWIDGETSHARED_EXPORT +#endif + +#endif // GLDWIDGET_GLOBAL_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDWinErrorDef.h b/GCR/trunk/Glodon/include/GLD/GLDWinErrorDef.h new file mode 100644 index 00000000..7b5ed3f6 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDWinErrorDef.h @@ -0,0 +1,27393 @@ +/************************************************************************* +* * +* 广联达Windows平台错误代码定义单元 H * +* * +* 设计:Zhangsk 2012.05.24 * +* 备注:从 winerror.h 单元移植 * +* 审核: * +* * +* Copyright (c) 2012-2013 Glodon Corporation * +* * +*************************************************************************/ + +/************************************************************************ +* * +* winerror.h -- error code definitions for the Win32 API functions * +* * +* Copyright (c) Microsoft Corp. All rights reserved. * +* * +************************************************************************/ + +#ifndef GLDWINERRORDEF_H +#define GLDWINERRORDEF_H + + +#if defined (_MSC_VER) && (_MSC_VER >= 1020) && !defined(__midl) +#pragma once +#endif + +// +// Values are 32 bit values layed out as follows: +// +// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 +// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 +// +---+-+-+-----------------------+-------------------------------+ +// |Sev|C|R| Facility | Code | +// +---+-+-+-----------------------+-------------------------------+ +// +// where +// +// Sev - is the severity code +// +// 00 - Success +// 01 - Informational +// 10 - Warning +// 11 - Error +// +// C - is the Customer code flag +// +// R - is a reserved bit +// +// Facility - is the facility code +// +// Code - is the facility's status code +// +// +// Define the facility codes +// +#define FACILITY_WINDOWSUPDATE 36 +#define FACILITY_WINDOWS_CE 24 +#define FACILITY_WINDOWS 8 +#define FACILITY_URT 19 +#define FACILITY_UMI 22 +#define FACILITY_SXS 23 +#define FACILITY_STORAGE 3 +#define FACILITY_STATE_MANAGEMENT 34 +#define FACILITY_SSPI 9 +#define FACILITY_SCARD 16 +#define FACILITY_SETUPAPI 15 +#define FACILITY_SECURITY 9 +#define FACILITY_RPC 1 +#define FACILITY_WIN32 7 +#define FACILITY_CONTROL 10 +#define FACILITY_NULL 0 +#define FACILITY_METADIRECTORY 35 +#define FACILITY_MSMQ 14 +#define FACILITY_MEDIASERVER 13 +#define FACILITY_INTERNET 12 +#define FACILITY_ITF 4 +#define FACILITY_HTTP 25 +#define FACILITY_DPLAY 21 +#define FACILITY_DISPATCH 2 +#define FACILITY_DIRECTORYSERVICE 37 +#define FACILITY_CONFIGURATION 33 +#define FACILITY_COMPLUS 17 +#define FACILITY_CERT 11 +#define FACILITY_BACKGROUNDCOPY 32 +#define FACILITY_ACS 20 +#define FACILITY_AAF 18 + + +// +// Define the severity codes +// + + +// +// MessageId: ERROR_SUCCESS +// +// MessageText: +// +// The operation completed successfully. +// +#define ERROR_SUCCESS 0L + +#define NO_ERROR 0L // dderror +#define SEC_E_OK ((HRESULT)0x00000000L) + +// +// MessageId: ERROR_INVALID_FUNCTION +// +// MessageText: +// +// Incorrect function. +// +#define ERROR_INVALID_FUNCTION 1L // dderror + +// +// MessageId: ERROR_FILE_NOT_FOUND +// +// MessageText: +// +// The system cannot find the file specified. +// +#define ERROR_FILE_NOT_FOUND 2L + +// +// MessageId: ERROR_PATH_NOT_FOUND +// +// MessageText: +// +// The system cannot find the path specified. +// +#define ERROR_PATH_NOT_FOUND 3L + +// +// MessageId: ERROR_TOO_MANY_OPEN_FILES +// +// MessageText: +// +// The system cannot open the file. +// +#define ERROR_TOO_MANY_OPEN_FILES 4L + +// +// MessageId: ERROR_ACCESS_DENIED +// +// MessageText: +// +// Access is denied. +// +#define ERROR_ACCESS_DENIED 5L + +// +// MessageId: ERROR_INVALID_HANDLE +// +// MessageText: +// +// The handle is invalid. +// +#define ERROR_INVALID_HANDLE 6L + +// +// MessageId: ERROR_ARENA_TRASHED +// +// MessageText: +// +// The storage control blocks were destroyed. +// +#define ERROR_ARENA_TRASHED 7L + +// +// MessageId: ERROR_NOT_ENOUGH_MEMORY +// +// MessageText: +// +// Not enough storage is available to process this command. +// +#define ERROR_NOT_ENOUGH_MEMORY 8L // dderror + +// +// MessageId: ERROR_INVALID_BLOCK +// +// MessageText: +// +// The storage control block address is invalid. +// +#define ERROR_INVALID_BLOCK 9L + +// +// MessageId: ERROR_BAD_ENVIRONMENT +// +// MessageText: +// +// The environment is incorrect. +// +#define ERROR_BAD_ENVIRONMENT 10L + +// +// MessageId: ERROR_BAD_FORMAT +// +// MessageText: +// +// An attempt was made to load a program with an incorrect format. +// +#define ERROR_BAD_FORMAT 11L + +// +// MessageId: ERROR_INVALID_ACCESS +// +// MessageText: +// +// The access code is invalid. +// +#define ERROR_INVALID_ACCESS 12L + +// +// MessageId: ERROR_INVALID_DATA +// +// MessageText: +// +// The data is invalid. +// +#define ERROR_INVALID_DATA 13L + +// +// MessageId: ERROR_OUTOFMEMORY +// +// MessageText: +// +// Not enough storage is available to complete this operation. +// +#define ERROR_OUTOFMEMORY 14L + +// +// MessageId: ERROR_INVALID_DRIVE +// +// MessageText: +// +// The system cannot find the drive specified. +// +#define ERROR_INVALID_DRIVE 15L + +// +// MessageId: ERROR_CURRENT_DIRECTORY +// +// MessageText: +// +// The directory cannot be removed. +// +#define ERROR_CURRENT_DIRECTORY 16L + +// +// MessageId: ERROR_NOT_SAME_DEVICE +// +// MessageText: +// +// The system cannot move the file to a different disk drive. +// +#define ERROR_NOT_SAME_DEVICE 17L + +// +// MessageId: ERROR_NO_MORE_FILES +// +// MessageText: +// +// There are no more files. +// +#define ERROR_NO_MORE_FILES 18L + +// +// MessageId: ERROR_WRITE_PROTECT +// +// MessageText: +// +// The media is write protected. +// +#define ERROR_WRITE_PROTECT 19L + +// +// MessageId: ERROR_BAD_UNIT +// +// MessageText: +// +// The system cannot find the device specified. +// +#define ERROR_BAD_UNIT 20L + +// +// MessageId: ERROR_NOT_READY +// +// MessageText: +// +// The device is not ready. +// +#define ERROR_NOT_READY 21L + +// +// MessageId: ERROR_BAD_COMMAND +// +// MessageText: +// +// The device does not recognize the command. +// +#define ERROR_BAD_COMMAND 22L + +// +// MessageId: ERROR_CRC +// +// MessageText: +// +// Data error (cyclic redundancy check). +// +#define ERROR_CRC 23L + +// +// MessageId: ERROR_BAD_LENGTH +// +// MessageText: +// +// The program issued a command but the command length is incorrect. +// +#define ERROR_BAD_LENGTH 24L + +// +// MessageId: ERROR_SEEK +// +// MessageText: +// +// The drive cannot locate a specific area or track on the disk. +// +#define ERROR_SEEK 25L + +// +// MessageId: ERROR_NOT_DOS_DISK +// +// MessageText: +// +// The specified disk or diskette cannot be accessed. +// +#define ERROR_NOT_DOS_DISK 26L + +// +// MessageId: ERROR_SECTOR_NOT_FOUND +// +// MessageText: +// +// The drive cannot find the sector requested. +// +#define ERROR_SECTOR_NOT_FOUND 27L + +// +// MessageId: ERROR_OUT_OF_PAPER +// +// MessageText: +// +// The printer is out of paper. +// +#define ERROR_OUT_OF_PAPER 28L + +// +// MessageId: ERROR_WRITE_FAULT +// +// MessageText: +// +// The system cannot write to the specified device. +// +#define ERROR_WRITE_FAULT 29L + +// +// MessageId: ERROR_READ_FAULT +// +// MessageText: +// +// The system cannot read from the specified device. +// +#define ERROR_READ_FAULT 30L + +// +// MessageId: ERROR_GEN_FAILURE +// +// MessageText: +// +// A device attached to the system is not functioning. +// +#define ERROR_GEN_FAILURE 31L + +// +// MessageId: ERROR_SHARING_VIOLATION +// +// MessageText: +// +// The process cannot access the file because it is being used by another process. +// +#define ERROR_SHARING_VIOLATION 32L + +// +// MessageId: ERROR_LOCK_VIOLATION +// +// MessageText: +// +// The process cannot access the file because another process has locked a portion of the file. +// +#define ERROR_LOCK_VIOLATION 33L + +// +// MessageId: ERROR_WRONG_DISK +// +// MessageText: +// +// The wrong diskette is in the drive. +// Insert %2 (Volume Serial Number: %3) into drive %1. +// +#define ERROR_WRONG_DISK 34L + +// +// MessageId: ERROR_SHARING_BUFFER_EXCEEDED +// +// MessageText: +// +// Too many files opened for sharing. +// +#define ERROR_SHARING_BUFFER_EXCEEDED 36L + +// +// MessageId: ERROR_HANDLE_EOF +// +// MessageText: +// +// Reached the end of the file. +// +#define ERROR_HANDLE_EOF 38L + +// +// MessageId: ERROR_HANDLE_DISK_FULL +// +// MessageText: +// +// The disk is full. +// +#define ERROR_HANDLE_DISK_FULL 39L + +// +// MessageId: ERROR_NOT_SUPPORTED +// +// MessageText: +// +// The request is not supported. +// +#define ERROR_NOT_SUPPORTED 50L + +// +// MessageId: ERROR_REM_NOT_LIST +// +// MessageText: +// +// Windows cannot find the network path. Verify that the network path is correct and the destination computer is not busy or turned off. If Windows still cannot find the network path, contact your network administrator. +// +#define ERROR_REM_NOT_LIST 51L + +// +// MessageId: ERROR_DUP_NAME +// +// MessageText: +// +// You were not connected because a duplicate name exists on the network. Go to System in Control Panel to change the computer name and try again. +// +#define ERROR_DUP_NAME 52L + +// +// MessageId: ERROR_BAD_NETPATH +// +// MessageText: +// +// The network path was not found. +// +#define ERROR_BAD_NETPATH 53L + +// +// MessageId: ERROR_NETWORK_BUSY +// +// MessageText: +// +// The network is busy. +// +#define ERROR_NETWORK_BUSY 54L + +// +// MessageId: ERROR_DEV_NOT_EXIST +// +// MessageText: +// +// The specified network resource or device is no longer available. +// +#define ERROR_DEV_NOT_EXIST 55L // dderror + +// +// MessageId: ERROR_TOO_MANY_CMDS +// +// MessageText: +// +// The network BIOS command limit has been reached. +// +#define ERROR_TOO_MANY_CMDS 56L + +// +// MessageId: ERROR_ADAP_HDW_ERR +// +// MessageText: +// +// A network adapter hardware error occurred. +// +#define ERROR_ADAP_HDW_ERR 57L + +// +// MessageId: ERROR_BAD_NET_RESP +// +// MessageText: +// +// The specified server cannot perform the requested operation. +// +#define ERROR_BAD_NET_RESP 58L + +// +// MessageId: ERROR_UNEXP_NET_ERR +// +// MessageText: +// +// An unexpected network error occurred. +// +#define ERROR_UNEXP_NET_ERR 59L + +// +// MessageId: ERROR_BAD_REM_ADAP +// +// MessageText: +// +// The remote adapter is not compatible. +// +#define ERROR_BAD_REM_ADAP 60L + +// +// MessageId: ERROR_PRINTQ_FULL +// +// MessageText: +// +// The printer queue is full. +// +#define ERROR_PRINTQ_FULL 61L + +// +// MessageId: ERROR_NO_SPOOL_SPACE +// +// MessageText: +// +// Space to store the file waiting to be printed is not available on the server. +// +#define ERROR_NO_SPOOL_SPACE 62L + +// +// MessageId: ERROR_PRINT_CANCELLED +// +// MessageText: +// +// Your file waiting to be printed was deleted. +// +#define ERROR_PRINT_CANCELLED 63L + +// +// MessageId: ERROR_NETNAME_DELETED +// +// MessageText: +// +// The specified network name is no longer available. +// +#define ERROR_NETNAME_DELETED 64L + +// +// MessageId: ERROR_NETWORK_ACCESS_DENIED +// +// MessageText: +// +// Network access is denied. +// +#define ERROR_NETWORK_ACCESS_DENIED 65L + +// +// MessageId: ERROR_BAD_DEV_TYPE +// +// MessageText: +// +// The network resource type is not correct. +// +#define ERROR_BAD_DEV_TYPE 66L + +// +// MessageId: ERROR_BAD_NET_NAME +// +// MessageText: +// +// The network name cannot be found. +// +#define ERROR_BAD_NET_NAME 67L + +// +// MessageId: ERROR_TOO_MANY_NAMES +// +// MessageText: +// +// The name limit for the local computer network adapter card was exceeded. +// +#define ERROR_TOO_MANY_NAMES 68L + +// +// MessageId: ERROR_TOO_MANY_SESS +// +// MessageText: +// +// The network BIOS session limit was exceeded. +// +#define ERROR_TOO_MANY_SESS 69L + +// +// MessageId: ERROR_SHARING_PAUSED +// +// MessageText: +// +// The remote server has been paused or is in the process of being started. +// +#define ERROR_SHARING_PAUSED 70L + +// +// MessageId: ERROR_REQ_NOT_ACCEP +// +// MessageText: +// +// No more connections can be made to this remote computer at this time because there are already as many connections as the computer can accept. +// +#define ERROR_REQ_NOT_ACCEP 71L + +// +// MessageId: ERROR_REDIR_PAUSED +// +// MessageText: +// +// The specified printer or disk device has been paused. +// +#define ERROR_REDIR_PAUSED 72L + +// +// MessageId: ERROR_FILE_EXISTS +// +// MessageText: +// +// The file exists. +// +#define ERROR_FILE_EXISTS 80L + +// +// MessageId: ERROR_CANNOT_MAKE +// +// MessageText: +// +// The directory or file cannot be created. +// +#define ERROR_CANNOT_MAKE 82L + +// +// MessageId: ERROR_FAIL_I24 +// +// MessageText: +// +// Fail on INT 24. +// +#define ERROR_FAIL_I24 83L + +// +// MessageId: ERROR_OUT_OF_STRUCTURES +// +// MessageText: +// +// Storage to process this request is not available. +// +#define ERROR_OUT_OF_STRUCTURES 84L + +// +// MessageId: ERROR_ALREADY_ASSIGNED +// +// MessageText: +// +// The local device name is already in use. +// +#define ERROR_ALREADY_ASSIGNED 85L + +// +// MessageId: ERROR_INVALID_PASSWORD +// +// MessageText: +// +// The specified network password is not correct. +// +#define ERROR_INVALID_PASSWORD 86L + +// +// MessageId: ERROR_INVALID_PARAMETER +// +// MessageText: +// +// The parameter is incorrect. +// +#define ERROR_INVALID_PARAMETER 87L // dderror + +// +// MessageId: ERROR_NET_WRITE_FAULT +// +// MessageText: +// +// A write fault occurred on the network. +// +#define ERROR_NET_WRITE_FAULT 88L + +// +// MessageId: ERROR_NO_PROC_SLOTS +// +// MessageText: +// +// The system cannot start another process at this time. +// +#define ERROR_NO_PROC_SLOTS 89L + +// +// MessageId: ERROR_TOO_MANY_SEMAPHORES +// +// MessageText: +// +// Cannot create another system semaphore. +// +#define ERROR_TOO_MANY_SEMAPHORES 100L + +// +// MessageId: ERROR_EXCL_SEM_ALREADY_OWNED +// +// MessageText: +// +// The exclusive semaphore is owned by another process. +// +#define ERROR_EXCL_SEM_ALREADY_OWNED 101L + +// +// MessageId: ERROR_SEM_IS_SET +// +// MessageText: +// +// The semaphore is set and cannot be closed. +// +#define ERROR_SEM_IS_SET 102L + +// +// MessageId: ERROR_TOO_MANY_SEM_REQUESTS +// +// MessageText: +// +// The semaphore cannot be set again. +// +#define ERROR_TOO_MANY_SEM_REQUESTS 103L + +// +// MessageId: ERROR_INVALID_AT_INTERRUPT_TIME +// +// MessageText: +// +// Cannot request exclusive semaphores at interrupt time. +// +#define ERROR_INVALID_AT_INTERRUPT_TIME 104L + +// +// MessageId: ERROR_SEM_OWNER_DIED +// +// MessageText: +// +// The previous ownership of this semaphore has ended. +// +#define ERROR_SEM_OWNER_DIED 105L + +// +// MessageId: ERROR_SEM_USER_LIMIT +// +// MessageText: +// +// Insert the diskette for drive %1. +// +#define ERROR_SEM_USER_LIMIT 106L + +// +// MessageId: ERROR_DISK_CHANGE +// +// MessageText: +// +// The program stopped because an alternate diskette was not inserted. +// +#define ERROR_DISK_CHANGE 107L + +// +// MessageId: ERROR_DRIVE_LOCKED +// +// MessageText: +// +// The disk is in use or locked by another process. +// +#define ERROR_DRIVE_LOCKED 108L + +// +// MessageId: ERROR_BROKEN_PIPE +// +// MessageText: +// +// The pipe has been ended. +// +#define ERROR_BROKEN_PIPE 109L + +// +// MessageId: ERROR_OPEN_FAILED +// +// MessageText: +// +// The system cannot open the device or file specified. +// +#define ERROR_OPEN_FAILED 110L + +// +// MessageId: ERROR_BUFFER_OVERFLOW +// +// MessageText: +// +// The file name is too long. +// +#define ERROR_BUFFER_OVERFLOW 111L + +// +// MessageId: ERROR_DISK_FULL +// +// MessageText: +// +// There is not enough space on the disk. +// +#define ERROR_DISK_FULL 112L + +// +// MessageId: ERROR_NO_MORE_SEARCH_HANDLES +// +// MessageText: +// +// No more internal file identifiers available. +// +#define ERROR_NO_MORE_SEARCH_HANDLES 113L + +// +// MessageId: ERROR_INVALID_TARGET_HANDLE +// +// MessageText: +// +// The target internal file identifier is incorrect. +// +#define ERROR_INVALID_TARGET_HANDLE 114L + +// +// MessageId: ERROR_INVALID_CATEGORY +// +// MessageText: +// +// The IOCTL call made by the application program is not correct. +// +#define ERROR_INVALID_CATEGORY 117L + +// +// MessageId: ERROR_INVALID_VERIFY_SWITCH +// +// MessageText: +// +// The verify-on-write switch parameter value is not correct. +// +#define ERROR_INVALID_VERIFY_SWITCH 118L + +// +// MessageId: ERROR_BAD_DRIVER_LEVEL +// +// MessageText: +// +// The system does not support the command requested. +// +#define ERROR_BAD_DRIVER_LEVEL 119L + +// +// MessageId: ERROR_CALL_NOT_IMPLEMENTED +// +// MessageText: +// +// This function is not supported on this system. +// +#define ERROR_CALL_NOT_IMPLEMENTED 120L + +// +// MessageId: ERROR_SEM_TIMEOUT +// +// MessageText: +// +// The semaphore timeout period has expired. +// +#define ERROR_SEM_TIMEOUT 121L + +// +// MessageId: ERROR_INSUFFICIENT_BUFFER +// +// MessageText: +// +// The data area passed to a system call is too small. +// +#define ERROR_INSUFFICIENT_BUFFER 122L // dderror + +// +// MessageId: ERROR_INVALID_NAME +// +// MessageText: +// +// The filename, directory name, or volume label syntax is incorrect. +// +#define ERROR_INVALID_NAME 123L // dderror + +// +// MessageId: ERROR_INVALID_LEVEL +// +// MessageText: +// +// The system call level is not correct. +// +#define ERROR_INVALID_LEVEL 124L + +// +// MessageId: ERROR_NO_VOLUME_LABEL +// +// MessageText: +// +// The disk has no volume label. +// +#define ERROR_NO_VOLUME_LABEL 125L + +// +// MessageId: ERROR_MOD_NOT_FOUND +// +// MessageText: +// +// The specified module could not be found. +// +#define ERROR_MOD_NOT_FOUND 126L + +// +// MessageId: ERROR_PROC_NOT_FOUND +// +// MessageText: +// +// The specified procedure could not be found. +// +#define ERROR_PROC_NOT_FOUND 127L + +// +// MessageId: ERROR_WAIT_NO_CHILDREN +// +// MessageText: +// +// There are no child processes to wait for. +// +#define ERROR_WAIT_NO_CHILDREN 128L + +// +// MessageId: ERROR_CHILD_NOT_COMPLETE +// +// MessageText: +// +// The %1 application cannot be run in Win32 mode. +// +#define ERROR_CHILD_NOT_COMPLETE 129L + +// +// MessageId: ERROR_DIRECT_ACCESS_HANDLE +// +// MessageText: +// +// Attempt to use a file handle to an open disk partition for an operation other than raw disk I/O. +// +#define ERROR_DIRECT_ACCESS_HANDLE 130L + +// +// MessageId: ERROR_NEGATIVE_SEEK +// +// MessageText: +// +// An attempt was made to move the file pointer before the beginning of the file. +// +#define ERROR_NEGATIVE_SEEK 131L + +// +// MessageId: ERROR_SEEK_ON_DEVICE +// +// MessageText: +// +// The file pointer cannot be set on the specified device or file. +// +#define ERROR_SEEK_ON_DEVICE 132L + +// +// MessageId: ERROR_IS_JOIN_TARGET +// +// MessageText: +// +// A JOIN or SUBST command cannot be used for a drive that contains previously joined drives. +// +#define ERROR_IS_JOIN_TARGET 133L + +// +// MessageId: ERROR_IS_JOINED +// +// MessageText: +// +// An attempt was made to use a JOIN or SUBST command on a drive that has already been joined. +// +#define ERROR_IS_JOINED 134L + +// +// MessageId: ERROR_IS_SUBSTED +// +// MessageText: +// +// An attempt was made to use a JOIN or SUBST command on a drive that has already been substituted. +// +#define ERROR_IS_SUBSTED 135L + +// +// MessageId: ERROR_NOT_JOINED +// +// MessageText: +// +// The system tried to delete the JOIN of a drive that is not joined. +// +#define ERROR_NOT_JOINED 136L + +// +// MessageId: ERROR_NOT_SUBSTED +// +// MessageText: +// +// The system tried to delete the substitution of a drive that is not substituted. +// +#define ERROR_NOT_SUBSTED 137L + +// +// MessageId: ERROR_JOIN_TO_JOIN +// +// MessageText: +// +// The system tried to join a drive to a directory on a joined drive. +// +#define ERROR_JOIN_TO_JOIN 138L + +// +// MessageId: ERROR_SUBST_TO_SUBST +// +// MessageText: +// +// The system tried to substitute a drive to a directory on a substituted drive. +// +#define ERROR_SUBST_TO_SUBST 139L + +// +// MessageId: ERROR_JOIN_TO_SUBST +// +// MessageText: +// +// The system tried to join a drive to a directory on a substituted drive. +// +#define ERROR_JOIN_TO_SUBST 140L + +// +// MessageId: ERROR_SUBST_TO_JOIN +// +// MessageText: +// +// The system tried to SUBST a drive to a directory on a joined drive. +// +#define ERROR_SUBST_TO_JOIN 141L + +// +// MessageId: ERROR_BUSY_DRIVE +// +// MessageText: +// +// The system cannot perform a JOIN or SUBST at this time. +// +#define ERROR_BUSY_DRIVE 142L + +// +// MessageId: ERROR_SAME_DRIVE +// +// MessageText: +// +// The system cannot join or substitute a drive to or for a directory on the same drive. +// +#define ERROR_SAME_DRIVE 143L + +// +// MessageId: ERROR_DIR_NOT_ROOT +// +// MessageText: +// +// The directory is not a subdirectory of the root directory. +// +#define ERROR_DIR_NOT_ROOT 144L + +// +// MessageId: ERROR_DIR_NOT_EMPTY +// +// MessageText: +// +// The directory is not empty. +// +#define ERROR_DIR_NOT_EMPTY 145L + +// +// MessageId: ERROR_IS_SUBST_PATH +// +// MessageText: +// +// The path specified is being used in a substitute. +// +#define ERROR_IS_SUBST_PATH 146L + +// +// MessageId: ERROR_IS_JOIN_PATH +// +// MessageText: +// +// Not enough resources are available to process this command. +// +#define ERROR_IS_JOIN_PATH 147L + +// +// MessageId: ERROR_PATH_BUSY +// +// MessageText: +// +// The path specified cannot be used at this time. +// +#define ERROR_PATH_BUSY 148L + +// +// MessageId: ERROR_IS_SUBST_TARGET +// +// MessageText: +// +// An attempt was made to join or substitute a drive for which a directory on the drive is the target of a previous substitute. +// +#define ERROR_IS_SUBST_TARGET 149L + +// +// MessageId: ERROR_SYSTEM_TRACE +// +// MessageText: +// +// System trace information was not specified in your CONFIG.SYS file, or tracing is disallowed. +// +#define ERROR_SYSTEM_TRACE 150L + +// +// MessageId: ERROR_INVALID_EVENT_COUNT +// +// MessageText: +// +// The number of specified semaphore events for DosMuxSemWait is not correct. +// +#define ERROR_INVALID_EVENT_COUNT 151L + +// +// MessageId: ERROR_TOO_MANY_MUXWAITERS +// +// MessageText: +// +// DosMuxSemWait did not execute; too many semaphores are already set. +// +#define ERROR_TOO_MANY_MUXWAITERS 152L + +// +// MessageId: ERROR_INVALID_LIST_FORMAT +// +// MessageText: +// +// The DosMuxSemWait list is not correct. +// +#define ERROR_INVALID_LIST_FORMAT 153L + +// +// MessageId: ERROR_LABEL_TOO_LONG +// +// MessageText: +// +// The volume label you entered exceeds the label character limit of the target file system. +// +#define ERROR_LABEL_TOO_LONG 154L + +// +// MessageId: ERROR_TOO_MANY_TCBS +// +// MessageText: +// +// Cannot create another thread. +// +#define ERROR_TOO_MANY_TCBS 155L + +// +// MessageId: ERROR_SIGNAL_REFUSED +// +// MessageText: +// +// The recipient process has refused the signal. +// +#define ERROR_SIGNAL_REFUSED 156L + +// +// MessageId: ERROR_DISCARDED +// +// MessageText: +// +// The segment is already discarded and cannot be locked. +// +#define ERROR_DISCARDED 157L + +// +// MessageId: ERROR_NOT_LOCKED +// +// MessageText: +// +// The segment is already unlocked. +// +#define ERROR_NOT_LOCKED 158L + +// +// MessageId: ERROR_BAD_THREADID_ADDR +// +// MessageText: +// +// The address for the thread ID is not correct. +// +#define ERROR_BAD_THREADID_ADDR 159L + +// +// MessageId: ERROR_BAD_ARGUMENTS +// +// MessageText: +// +// One or more arguments are not correct. +// +#define ERROR_BAD_ARGUMENTS 160L + +// +// MessageId: ERROR_BAD_PATHNAME +// +// MessageText: +// +// The specified path is invalid. +// +#define ERROR_BAD_PATHNAME 161L + +// +// MessageId: ERROR_SIGNAL_PENDING +// +// MessageText: +// +// A signal is already pending. +// +#define ERROR_SIGNAL_PENDING 162L + +// +// MessageId: ERROR_MAX_THRDS_REACHED +// +// MessageText: +// +// No more threads can be created in the system. +// +#define ERROR_MAX_THRDS_REACHED 164L + +// +// MessageId: ERROR_LOCK_FAILED +// +// MessageText: +// +// Unable to lock a region of a file. +// +#define ERROR_LOCK_FAILED 167L + +// +// MessageId: ERROR_BUSY +// +// MessageText: +// +// The requested resource is in use. +// +#define ERROR_BUSY 170L // dderror + +// +// MessageId: ERROR_CANCEL_VIOLATION +// +// MessageText: +// +// A lock request was not outstanding for the supplied cancel region. +// +#define ERROR_CANCEL_VIOLATION 173L + +// +// MessageId: ERROR_ATOMIC_LOCKS_NOT_SUPPORTED +// +// MessageText: +// +// The file system does not support atomic changes to the lock type. +// +#define ERROR_ATOMIC_LOCKS_NOT_SUPPORTED 174L + +// +// MessageId: ERROR_INVALID_SEGMENT_NUMBER +// +// MessageText: +// +// The system detected a segment number that was not correct. +// +#define ERROR_INVALID_SEGMENT_NUMBER 180L + +// +// MessageId: ERROR_INVALID_ORDINAL +// +// MessageText: +// +// The operating system cannot run %1. +// +#define ERROR_INVALID_ORDINAL 182L + +// +// MessageId: ERROR_ALREADY_EXISTS +// +// MessageText: +// +// Cannot create a file when that file already exists. +// +#define ERROR_ALREADY_EXISTS 183L + +// +// MessageId: ERROR_INVALID_FLAG_NUMBER +// +// MessageText: +// +// The flag passed is not correct. +// +#define ERROR_INVALID_FLAG_NUMBER 186L + +// +// MessageId: ERROR_SEM_NOT_FOUND +// +// MessageText: +// +// The specified system semaphore name was not found. +// +#define ERROR_SEM_NOT_FOUND 187L + +// +// MessageId: ERROR_INVALID_STARTING_CODESEG +// +// MessageText: +// +// The operating system cannot run %1. +// +#define ERROR_INVALID_STARTING_CODESEG 188L + +// +// MessageId: ERROR_INVALID_STACKSEG +// +// MessageText: +// +// The operating system cannot run %1. +// +#define ERROR_INVALID_STACKSEG 189L + +// +// MessageId: ERROR_INVALID_MODULETYPE +// +// MessageText: +// +// The operating system cannot run %1. +// +#define ERROR_INVALID_MODULETYPE 190L + +// +// MessageId: ERROR_INVALID_EXE_SIGNATURE +// +// MessageText: +// +// Cannot run %1 in Win32 mode. +// +#define ERROR_INVALID_EXE_SIGNATURE 191L + +// +// MessageId: ERROR_EXE_MARKED_INVALID +// +// MessageText: +// +// The operating system cannot run %1. +// +#define ERROR_EXE_MARKED_INVALID 192L + +// +// MessageId: ERROR_BAD_EXE_FORMAT +// +// MessageText: +// +// %1 is not a valid Win32 application. +// +#define ERROR_BAD_EXE_FORMAT 193L + +// +// MessageId: ERROR_ITERATED_DATA_EXCEEDS_64k +// +// MessageText: +// +// The operating system cannot run %1. +// +#define ERROR_ITERATED_DATA_EXCEEDS_64k 194L + +// +// MessageId: ERROR_INVALID_MINALLOCSIZE +// +// MessageText: +// +// The operating system cannot run %1. +// +#define ERROR_INVALID_MINALLOCSIZE 195L + +// +// MessageId: ERROR_DYNLINK_FROM_INVALID_RING +// +// MessageText: +// +// The operating system cannot run this application program. +// +#define ERROR_DYNLINK_FROM_INVALID_RING 196L + +// +// MessageId: ERROR_IOPL_NOT_ENABLED +// +// MessageText: +// +// The operating system is not presently configured to run this application. +// +#define ERROR_IOPL_NOT_ENABLED 197L + +// +// MessageId: ERROR_INVALID_SEGDPL +// +// MessageText: +// +// The operating system cannot run %1. +// +#define ERROR_INVALID_SEGDPL 198L + +// +// MessageId: ERROR_AUTODATASEG_EXCEEDS_64k +// +// MessageText: +// +// The operating system cannot run this application program. +// +#define ERROR_AUTODATASEG_EXCEEDS_64k 199L + +// +// MessageId: ERROR_RING2SEG_MUST_BE_MOVABLE +// +// MessageText: +// +// The code segment cannot be greater than or equal to 64K. +// +#define ERROR_RING2SEG_MUST_BE_MOVABLE 200L + +// +// MessageId: ERROR_RELOC_CHAIN_XEEDS_SEGLIM +// +// MessageText: +// +// The operating system cannot run %1. +// +#define ERROR_RELOC_CHAIN_XEEDS_SEGLIM 201L + +// +// MessageId: ERROR_INFLOOP_IN_RELOC_CHAIN +// +// MessageText: +// +// The operating system cannot run %1. +// +#define ERROR_INFLOOP_IN_RELOC_CHAIN 202L + +// +// MessageId: ERROR_ENVVAR_NOT_FOUND +// +// MessageText: +// +// The system could not find the environment option that was entered. +// +#define ERROR_ENVVAR_NOT_FOUND 203L + +// +// MessageId: ERROR_NO_SIGNAL_SENT +// +// MessageText: +// +// No process in the command subtree has a signal handler. +// +#define ERROR_NO_SIGNAL_SENT 205L + +// +// MessageId: ERROR_FILENAME_EXCED_RANGE +// +// MessageText: +// +// The filename or extension is too long. +// +#define ERROR_FILENAME_EXCED_RANGE 206L + +// +// MessageId: ERROR_RING2_STACK_IN_USE +// +// MessageText: +// +// The ring 2 stack is in use. +// +#define ERROR_RING2_STACK_IN_USE 207L + +// +// MessageId: ERROR_META_EXPANSION_TOO_LONG +// +// MessageText: +// +// The global filename characters, * or ?, are entered incorrectly or too many global filename characters are specified. +// +#define ERROR_META_EXPANSION_TOO_LONG 208L + +// +// MessageId: ERROR_INVALID_SIGNAL_NUMBER +// +// MessageText: +// +// The signal being posted is not correct. +// +#define ERROR_INVALID_SIGNAL_NUMBER 209L + +// +// MessageId: ERROR_THREAD_1_INACTIVE +// +// MessageText: +// +// The signal handler cannot be set. +// +#define ERROR_THREAD_1_INACTIVE 210L + +// +// MessageId: ERROR_LOCKED +// +// MessageText: +// +// The segment is locked and cannot be reallocated. +// +#define ERROR_LOCKED 212L + +// +// MessageId: ERROR_TOO_MANY_MODULES +// +// MessageText: +// +// Too many dynamic-link modules are attached to this program or dynamic-link module. +// +#define ERROR_TOO_MANY_MODULES 214L + +// +// MessageId: ERROR_NESTING_NOT_ALLOWED +// +// MessageText: +// +// Cannot nest calls to LoadModule. +// +#define ERROR_NESTING_NOT_ALLOWED 215L + +// +// MessageId: ERROR_EXE_MACHINE_TYPE_MISMATCH +// +// MessageText: +// +// The image file %1 is valid, but is for a machine type other than the current machine. +// +#define ERROR_EXE_MACHINE_TYPE_MISMATCH 216L + +// +// MessageId: ERROR_EXE_CANNOT_MODIFY_SIGNED_BINARY +// +// MessageText: +// +// The image file %1 is signed, unable to modify. +// +#define ERROR_EXE_CANNOT_MODIFY_SIGNED_BINARY 217L + +// +// MessageId: ERROR_EXE_CANNOT_MODIFY_STRONG_SIGNED_BINARY +// +// MessageText: +// +// The image file %1 is strong signed, unable to modify. +// +#define ERROR_EXE_CANNOT_MODIFY_STRONG_SIGNED_BINARY 218L + +// +// MessageId: ERROR_BAD_PIPE +// +// MessageText: +// +// The pipe state is invalid. +// +#define ERROR_BAD_PIPE 230L + +// +// MessageId: ERROR_PIPE_BUSY +// +// MessageText: +// +// All pipe instances are busy. +// +#define ERROR_PIPE_BUSY 231L + +// +// MessageId: ERROR_NO_DATA +// +// MessageText: +// +// The pipe is being closed. +// +#define ERROR_NO_DATA 232L + +// +// MessageId: ERROR_PIPE_NOT_CONNECTED +// +// MessageText: +// +// No process is on the other end of the pipe. +// +#define ERROR_PIPE_NOT_CONNECTED 233L + +// +// MessageId: ERROR_MORE_DATA +// +// MessageText: +// +// More data is available. +// +#define ERROR_MORE_DATA 234L // dderror + +// +// MessageId: ERROR_VC_DISCONNECTED +// +// MessageText: +// +// The session was canceled. +// +#define ERROR_VC_DISCONNECTED 240L + +// +// MessageId: ERROR_INVALID_EA_NAME +// +// MessageText: +// +// The specified extended attribute name was invalid. +// +#define ERROR_INVALID_EA_NAME 254L + +// +// MessageId: ERROR_EA_LIST_INCONSISTENT +// +// MessageText: +// +// The extended attributes are inconsistent. +// +#define ERROR_EA_LIST_INCONSISTENT 255L + +// +// MessageId: WAIT_TIMEOUT +// +// MessageText: +// +// The wait operation timed out. +// +#define WAIT_TIMEOUT 258L // dderror + +// +// MessageId: ERROR_NO_MORE_ITEMS +// +// MessageText: +// +// No more data is available. +// +#define ERROR_NO_MORE_ITEMS 259L + +// +// MessageId: ERROR_CANNOT_COPY +// +// MessageText: +// +// The copy functions cannot be used. +// +#define ERROR_CANNOT_COPY 266L + +// +// MessageId: ERROR_DIRECTORY +// +// MessageText: +// +// The directory name is invalid. +// +#define ERROR_DIRECTORY 267L + +// +// MessageId: ERROR_EAS_DIDNT_FIT +// +// MessageText: +// +// The extended attributes did not fit in the buffer. +// +#define ERROR_EAS_DIDNT_FIT 275L + +// +// MessageId: ERROR_EA_FILE_CORRUPT +// +// MessageText: +// +// The extended attribute file on the mounted file system is corrupt. +// +#define ERROR_EA_FILE_CORRUPT 276L + +// +// MessageId: ERROR_EA_TABLE_FULL +// +// MessageText: +// +// The extended attribute table file is full. +// +#define ERROR_EA_TABLE_FULL 277L + +// +// MessageId: ERROR_INVALID_EA_HANDLE +// +// MessageText: +// +// The specified extended attribute handle is invalid. +// +#define ERROR_INVALID_EA_HANDLE 278L + +// +// MessageId: ERROR_EAS_NOT_SUPPORTED +// +// MessageText: +// +// The mounted file system does not support extended attributes. +// +#define ERROR_EAS_NOT_SUPPORTED 282L + +// +// MessageId: ERROR_NOT_OWNER +// +// MessageText: +// +// Attempt to release mutex not owned by caller. +// +#define ERROR_NOT_OWNER 288L + +// +// MessageId: ERROR_TOO_MANY_POSTS +// +// MessageText: +// +// Too many posts were made to a semaphore. +// +#define ERROR_TOO_MANY_POSTS 298L + +// +// MessageId: ERROR_PARTIAL_COPY +// +// MessageText: +// +// Only part of a ReadProcessMemory or WriteProcessMemory request was completed. +// +#define ERROR_PARTIAL_COPY 299L + +// +// MessageId: ERROR_OPLOCK_NOT_GRANTED +// +// MessageText: +// +// The oplock request is denied. +// +#define ERROR_OPLOCK_NOT_GRANTED 300L + +// +// MessageId: ERROR_INVALID_OPLOCK_PROTOCOL +// +// MessageText: +// +// An invalid oplock acknowledgment was received by the system. +// +#define ERROR_INVALID_OPLOCK_PROTOCOL 301L + +// +// MessageId: ERROR_DISK_TOO_FRAGMENTED +// +// MessageText: +// +// The volume is too fragmented to complete this operation. +// +#define ERROR_DISK_TOO_FRAGMENTED 302L + +// +// MessageId: ERROR_DELETE_PENDING +// +// MessageText: +// +// The file cannot be opened because it is in the process of being deleted. +// +#define ERROR_DELETE_PENDING 303L + +// +// MessageId: ERROR_MR_MID_NOT_FOUND +// +// MessageText: +// +// The system cannot find message text for message number 0x%1 in the message file for %2. +// +#define ERROR_MR_MID_NOT_FOUND 317L + +// +// MessageId: ERROR_SCOPE_NOT_FOUND +// +// MessageText: +// +// The scope specified was not found. +// +#define ERROR_SCOPE_NOT_FOUND 318L + +// +// MessageId: ERROR_INVALID_ADDRESS +// +// MessageText: +// +// Attempt to access invalid address. +// +#define ERROR_INVALID_ADDRESS 487L + +// +// MessageId: ERROR_ARITHMETIC_OVERFLOW +// +// MessageText: +// +// Arithmetic result exceeded 32 bits. +// +#define ERROR_ARITHMETIC_OVERFLOW 534L + +// +// MessageId: ERROR_PIPE_CONNECTED +// +// MessageText: +// +// There is a process on other end of the pipe. +// +#define ERROR_PIPE_CONNECTED 535L + +// +// MessageId: ERROR_PIPE_LISTENING +// +// MessageText: +// +// Waiting for a process to open the other end of the pipe. +// +#define ERROR_PIPE_LISTENING 536L + +// +// MessageId: ERROR_EA_ACCESS_DENIED +// +// MessageText: +// +// Access to the extended attribute was denied. +// +#define ERROR_EA_ACCESS_DENIED 994L + +// +// MessageId: ERROR_OPERATION_ABORTED +// +// MessageText: +// +// The I/O operation has been aborted because of either a thread exit or an application request. +// +#define ERROR_OPERATION_ABORTED 995L + +// +// MessageId: ERROR_IO_INCOMPLETE +// +// MessageText: +// +// Overlapped I/O event is not in a signaled state. +// +#define ERROR_IO_INCOMPLETE 996L + +// +// MessageId: ERROR_IO_PENDING +// +// MessageText: +// +// Overlapped I/O operation is in progress. +// +#define ERROR_IO_PENDING 997L // dderror + +// +// MessageId: ERROR_NOACCESS +// +// MessageText: +// +// Invalid access to memory location. +// +#define ERROR_NOACCESS 998L + +// +// MessageId: ERROR_SWAPERROR +// +// MessageText: +// +// Error performing inpage operation. +// +#define ERROR_SWAPERROR 999L + +// +// MessageId: ERROR_STACK_OVERFLOW +// +// MessageText: +// +// Recursion too deep; the stack overflowed. +// +#define ERROR_STACK_OVERFLOW 1001L + +// +// MessageId: ERROR_INVALID_MESSAGE +// +// MessageText: +// +// The window cannot act on the sent message. +// +#define ERROR_INVALID_MESSAGE 1002L + +// +// MessageId: ERROR_CAN_NOT_COMPLETE +// +// MessageText: +// +// Cannot complete this function. +// +#define ERROR_CAN_NOT_COMPLETE 1003L + +// +// MessageId: ERROR_INVALID_FLAGS +// +// MessageText: +// +// Invalid flags. +// +#define ERROR_INVALID_FLAGS 1004L + +// +// MessageId: ERROR_UNRECOGNIZED_VOLUME +// +// MessageText: +// +// The volume does not contain a recognized file system. +// Please make sure that all required file system drivers are loaded and that the volume is not corrupted. +// +#define ERROR_UNRECOGNIZED_VOLUME 1005L + +// +// MessageId: ERROR_FILE_INVALID +// +// MessageText: +// +// The volume for a file has been externally altered so that the opened file is no longer valid. +// +#define ERROR_FILE_INVALID 1006L + +// +// MessageId: ERROR_FULLSCREEN_MODE +// +// MessageText: +// +// The requested operation cannot be performed in full-screen mode. +// +#define ERROR_FULLSCREEN_MODE 1007L + +// +// MessageId: ERROR_NO_TOKEN +// +// MessageText: +// +// An attempt was made to reference a token that does not exist. +// +#define ERROR_NO_TOKEN 1008L + +// +// MessageId: ERROR_BADDB +// +// MessageText: +// +// The configuration registry database is corrupt. +// +#define ERROR_BADDB 1009L + +// +// MessageId: ERROR_BADKEY +// +// MessageText: +// +// The configuration registry key is invalid. +// +#define ERROR_BADKEY 1010L + +// +// MessageId: ERROR_CANTOPEN +// +// MessageText: +// +// The configuration registry key could not be opened. +// +#define ERROR_CANTOPEN 1011L + +// +// MessageId: ERROR_CANTREAD +// +// MessageText: +// +// The configuration registry key could not be read. +// +#define ERROR_CANTREAD 1012L + +// +// MessageId: ERROR_CANTWRITE +// +// MessageText: +// +// The configuration registry key could not be written. +// +#define ERROR_CANTWRITE 1013L + +// +// MessageId: ERROR_REGISTRY_RECOVERED +// +// MessageText: +// +// One of the files in the registry database had to be recovered by use of a log or alternate copy. The recovery was successful. +// +#define ERROR_REGISTRY_RECOVERED 1014L + +// +// MessageId: ERROR_REGISTRY_CORRUPT +// +// MessageText: +// +// The registry is corrupted. The structure of one of the files containing registry data is corrupted, or the system's memory image of the file is corrupted, or the file could not be recovered because the alternate copy or log was absent or corrupted. +// +#define ERROR_REGISTRY_CORRUPT 1015L + +// +// MessageId: ERROR_REGISTRY_IO_FAILED +// +// MessageText: +// +// An I/O operation initiated by the registry failed unrecoverably. The registry could not read in, or write out, or flush, one of the files that contain the system's image of the registry. +// +#define ERROR_REGISTRY_IO_FAILED 1016L + +// +// MessageId: ERROR_NOT_REGISTRY_FILE +// +// MessageText: +// +// The system has attempted to load or restore a file into the registry, but the specified file is not in a registry file format. +// +#define ERROR_NOT_REGISTRY_FILE 1017L + +// +// MessageId: ERROR_KEY_DELETED +// +// MessageText: +// +// Illegal operation attempted on a registry key that has been marked for deletion. +// +#define ERROR_KEY_DELETED 1018L + +// +// MessageId: ERROR_NO_LOG_SPACE +// +// MessageText: +// +// System could not allocate the required space in a registry log. +// +#define ERROR_NO_LOG_SPACE 1019L + +// +// MessageId: ERROR_KEY_HAS_CHILDREN +// +// MessageText: +// +// Cannot create a symbolic link in a registry key that already has subkeys or values. +// +#define ERROR_KEY_HAS_CHILDREN 1020L + +// +// MessageId: ERROR_CHILD_MUST_BE_VOLATILE +// +// MessageText: +// +// Cannot create a stable subkey under a volatile parent key. +// +#define ERROR_CHILD_MUST_BE_VOLATILE 1021L + +// +// MessageId: ERROR_NOTIFY_ENUM_DIR +// +// MessageText: +// +// A notify change request is being completed and the information is not being returned in the caller's buffer. The caller now needs to enumerate the files to find the changes. +// +#define ERROR_NOTIFY_ENUM_DIR 1022L + +// +// MessageId: ERROR_DEPENDENT_SERVICES_RUNNING +// +// MessageText: +// +// A stop control has been sent to a service that other running services are dependent on. +// +#define ERROR_DEPENDENT_SERVICES_RUNNING 1051L + +// +// MessageId: ERROR_INVALID_SERVICE_CONTROL +// +// MessageText: +// +// The requested control is not valid for this service. +// +#define ERROR_INVALID_SERVICE_CONTROL 1052L + +// +// MessageId: ERROR_SERVICE_REQUEST_TIMEOUT +// +// MessageText: +// +// The service did not respond to the start or control request in a timely fashion. +// +#define ERROR_SERVICE_REQUEST_TIMEOUT 1053L + +// +// MessageId: ERROR_SERVICE_NO_THREAD +// +// MessageText: +// +// A thread could not be created for the service. +// +#define ERROR_SERVICE_NO_THREAD 1054L + +// +// MessageId: ERROR_SERVICE_DATABASE_LOCKED +// +// MessageText: +// +// The service database is locked. +// +#define ERROR_SERVICE_DATABASE_LOCKED 1055L + +// +// MessageId: ERROR_SERVICE_ALREADY_RUNNING +// +// MessageText: +// +// An instance of the service is already running. +// +#define ERROR_SERVICE_ALREADY_RUNNING 1056L + +// +// MessageId: ERROR_INVALID_SERVICE_ACCOUNT +// +// MessageText: +// +// The account name is invalid or does not exist, or the password is invalid for the account name specified. +// +#define ERROR_INVALID_SERVICE_ACCOUNT 1057L + +// +// MessageId: ERROR_SERVICE_DISABLED +// +// MessageText: +// +// The service cannot be started, either because it is disabled or because it has no enabled devices associated with it. +// +#define ERROR_SERVICE_DISABLED 1058L + +// +// MessageId: ERROR_CIRCULAR_DEPENDENCY +// +// MessageText: +// +// Circular service dependency was specified. +// +#define ERROR_CIRCULAR_DEPENDENCY 1059L + +// +// MessageId: ERROR_SERVICE_DOES_NOT_EXIST +// +// MessageText: +// +// The specified service does not exist as an installed service. +// +#define ERROR_SERVICE_DOES_NOT_EXIST 1060L + +// +// MessageId: ERROR_SERVICE_CANNOT_ACCEPT_CTRL +// +// MessageText: +// +// The service cannot accept control messages at this time. +// +#define ERROR_SERVICE_CANNOT_ACCEPT_CTRL 1061L + +// +// MessageId: ERROR_SERVICE_NOT_ACTIVE +// +// MessageText: +// +// The service has not been started. +// +#define ERROR_SERVICE_NOT_ACTIVE 1062L + +// +// MessageId: ERROR_FAILED_SERVICE_CONTROLLER_CONNECT +// +// MessageText: +// +// The service process could not connect to the service controller. +// +#define ERROR_FAILED_SERVICE_CONTROLLER_CONNECT 1063L + +// +// MessageId: ERROR_EXCEPTION_IN_SERVICE +// +// MessageText: +// +// An exception occurred in the service when handling the control request. +// +#define ERROR_EXCEPTION_IN_SERVICE 1064L + +// +// MessageId: ERROR_DATABASE_DOES_NOT_EXIST +// +// MessageText: +// +// The database specified does not exist. +// +#define ERROR_DATABASE_DOES_NOT_EXIST 1065L + +// +// MessageId: ERROR_SERVICE_SPECIFIC_ERROR +// +// MessageText: +// +// The service has returned a service-specific error code. +// +#define ERROR_SERVICE_SPECIFIC_ERROR 1066L + +// +// MessageId: ERROR_PROCESS_ABORTED +// +// MessageText: +// +// The process terminated unexpectedly. +// +#define ERROR_PROCESS_ABORTED 1067L + +// +// MessageId: ERROR_SERVICE_DEPENDENCY_FAIL +// +// MessageText: +// +// The dependency service or group failed to start. +// +#define ERROR_SERVICE_DEPENDENCY_FAIL 1068L + +// +// MessageId: ERROR_SERVICE_LOGON_FAILED +// +// MessageText: +// +// The service did not start due to a logon failure. +// +#define ERROR_SERVICE_LOGON_FAILED 1069L + +// +// MessageId: ERROR_SERVICE_START_HANG +// +// MessageText: +// +// After starting, the service hung in a start-pending state. +// +#define ERROR_SERVICE_START_HANG 1070L + +// +// MessageId: ERROR_INVALID_SERVICE_LOCK +// +// MessageText: +// +// The specified service database lock is invalid. +// +#define ERROR_INVALID_SERVICE_LOCK 1071L + +// +// MessageId: ERROR_SERVICE_MARKED_FOR_DELETE +// +// MessageText: +// +// The specified service has been marked for deletion. +// +#define ERROR_SERVICE_MARKED_FOR_DELETE 1072L + +// +// MessageId: ERROR_SERVICE_EXISTS +// +// MessageText: +// +// The specified service already exists. +// +#define ERROR_SERVICE_EXISTS 1073L + +// +// MessageId: ERROR_ALREADY_RUNNING_LKG +// +// MessageText: +// +// The system is currently running with the last-known-good configuration. +// +#define ERROR_ALREADY_RUNNING_LKG 1074L + +// +// MessageId: ERROR_SERVICE_DEPENDENCY_DELETED +// +// MessageText: +// +// The dependency service does not exist or has been marked for deletion. +// +#define ERROR_SERVICE_DEPENDENCY_DELETED 1075L + +// +// MessageId: ERROR_BOOT_ALREADY_ACCEPTED +// +// MessageText: +// +// The current boot has already been accepted for use as the last-known-good control set. +// +#define ERROR_BOOT_ALREADY_ACCEPTED 1076L + +// +// MessageId: ERROR_SERVICE_NEVER_STARTED +// +// MessageText: +// +// No attempts to start the service have been made since the last boot. +// +#define ERROR_SERVICE_NEVER_STARTED 1077L + +// +// MessageId: ERROR_DUPLICATE_SERVICE_NAME +// +// MessageText: +// +// The name is already in use as either a service name or a service display name. +// +#define ERROR_DUPLICATE_SERVICE_NAME 1078L + +// +// MessageId: ERROR_DIFFERENT_SERVICE_ACCOUNT +// +// MessageText: +// +// The account specified for this service is different from the account specified for other services running in the same process. +// +#define ERROR_DIFFERENT_SERVICE_ACCOUNT 1079L + +// +// MessageId: ERROR_CANNOT_DETECT_DRIVER_FAILURE +// +// MessageText: +// +// Failure actions can only be set for Win32 services, not for drivers. +// +#define ERROR_CANNOT_DETECT_DRIVER_FAILURE 1080L + +// +// MessageId: ERROR_CANNOT_DETECT_PROCESS_ABORT +// +// MessageText: +// +// This service runs in the same process as the service control manager. +// Therefore, the service control manager cannot take action if this service's process terminates unexpectedly. +// +#define ERROR_CANNOT_DETECT_PROCESS_ABORT 1081L + +// +// MessageId: ERROR_NO_RECOVERY_PROGRAM +// +// MessageText: +// +// No recovery program has been configured for this service. +// +#define ERROR_NO_RECOVERY_PROGRAM 1082L + +// +// MessageId: ERROR_SERVICE_NOT_IN_EXE +// +// MessageText: +// +// The executable program that this service is configured to run in does not implement the service. +// +#define ERROR_SERVICE_NOT_IN_EXE 1083L + +// +// MessageId: ERROR_NOT_SAFEBOOT_SERVICE +// +// MessageText: +// +// This service cannot be started in Safe Mode +// +#define ERROR_NOT_SAFEBOOT_SERVICE 1084L + +// +// MessageId: ERROR_END_OF_MEDIA +// +// MessageText: +// +// The physical end of the tape has been reached. +// +#define ERROR_END_OF_MEDIA 1100L + +// +// MessageId: ERROR_FILEMARK_DETECTED +// +// MessageText: +// +// A tape access reached a filemark. +// +#define ERROR_FILEMARK_DETECTED 1101L + +// +// MessageId: ERROR_BEGINNING_OF_MEDIA +// +// MessageText: +// +// The beginning of the tape or a partition was encountered. +// +#define ERROR_BEGINNING_OF_MEDIA 1102L + +// +// MessageId: ERROR_SETMARK_DETECTED +// +// MessageText: +// +// A tape access reached the end of a set of files. +// +#define ERROR_SETMARK_DETECTED 1103L + +// +// MessageId: ERROR_NO_DATA_DETECTED +// +// MessageText: +// +// No more data is on the tape. +// +#define ERROR_NO_DATA_DETECTED 1104L + +// +// MessageId: ERROR_PARTITION_FAILURE +// +// MessageText: +// +// Tape could not be partitioned. +// +#define ERROR_PARTITION_FAILURE 1105L + +// +// MessageId: ERROR_INVALID_BLOCK_LENGTH +// +// MessageText: +// +// When accessing a new tape of a multivolume partition, the current block size is incorrect. +// +#define ERROR_INVALID_BLOCK_LENGTH 1106L + +// +// MessageId: ERROR_DEVICE_NOT_PARTITIONED +// +// MessageText: +// +// Tape partition information could not be found when loading a tape. +// +#define ERROR_DEVICE_NOT_PARTITIONED 1107L + +// +// MessageId: ERROR_UNABLE_TO_LOCK_MEDIA +// +// MessageText: +// +// Unable to lock the media eject mechanism. +// +#define ERROR_UNABLE_TO_LOCK_MEDIA 1108L + +// +// MessageId: ERROR_UNABLE_TO_UNLOAD_MEDIA +// +// MessageText: +// +// Unable to unload the media. +// +#define ERROR_UNABLE_TO_UNLOAD_MEDIA 1109L + +// +// MessageId: ERROR_MEDIA_CHANGED +// +// MessageText: +// +// The media in the drive may have changed. +// +#define ERROR_MEDIA_CHANGED 1110L + +// +// MessageId: ERROR_BUS_RESET +// +// MessageText: +// +// The I/O bus was reset. +// +#define ERROR_BUS_RESET 1111L + +// +// MessageId: ERROR_NO_MEDIA_IN_DRIVE +// +// MessageText: +// +// No media in drive. +// +#define ERROR_NO_MEDIA_IN_DRIVE 1112L + +// +// MessageId: ERROR_NO_UNICODE_TRANSLATION +// +// MessageText: +// +// No mapping for the Unicode character exists in the target multi-byte code page. +// +#define ERROR_NO_UNICODE_TRANSLATION 1113L + +// +// MessageId: ERROR_DLL_INIT_FAILED +// +// MessageText: +// +// A dynamic link library (DLL) initialization routine failed. +// +#define ERROR_DLL_INIT_FAILED 1114L + +// +// MessageId: ERROR_SHUTDOWN_IN_PROGRESS +// +// MessageText: +// +// A system shutdown is in progress. +// +#define ERROR_SHUTDOWN_IN_PROGRESS 1115L + +// +// MessageId: ERROR_NO_SHUTDOWN_IN_PROGRESS +// +// MessageText: +// +// Unable to abort the system shutdown because no shutdown was in progress. +// +#define ERROR_NO_SHUTDOWN_IN_PROGRESS 1116L + +// +// MessageId: ERROR_IO_DEVICE +// +// MessageText: +// +// The request could not be performed because of an I/O device error. +// +#define ERROR_IO_DEVICE 1117L + +// +// MessageId: ERROR_SERIAL_NO_DEVICE +// +// MessageText: +// +// No serial device was successfully initialized. The serial driver will unload. +// +#define ERROR_SERIAL_NO_DEVICE 1118L + +// +// MessageId: ERROR_IRQ_BUSY +// +// MessageText: +// +// Unable to open a device that was sharing an interrupt request (IRQ) with other devices. At least one other device that uses that IRQ was already opened. +// +#define ERROR_IRQ_BUSY 1119L + +// +// MessageId: ERROR_MORE_WRITES +// +// MessageText: +// +// A serial I/O operation was completed by another write to the serial port. +// (The IOCTL_SERIAL_XOFF_COUNTER reached zero.) +// +#define ERROR_MORE_WRITES 1120L + +// +// MessageId: ERROR_COUNTER_TIMEOUT +// +// MessageText: +// +// A serial I/O operation completed because the timeout period expired. +// (The IOCTL_SERIAL_XOFF_COUNTER did not reach zero.) +// +#define ERROR_COUNTER_TIMEOUT 1121L + +// +// MessageId: ERROR_FLOPPY_ID_MARK_NOT_FOUND +// +// MessageText: +// +// No ID address mark was found on the floppy disk. +// +#define ERROR_FLOPPY_ID_MARK_NOT_FOUND 1122L + +// +// MessageId: ERROR_FLOPPY_WRONG_CYLINDER +// +// MessageText: +// +// Mismatch between the floppy disk sector ID field and the floppy disk controller track address. +// +#define ERROR_FLOPPY_WRONG_CYLINDER 1123L + +// +// MessageId: ERROR_FLOPPY_UNKNOWN_ERROR +// +// MessageText: +// +// The floppy disk controller reported an error that is not recognized by the floppy disk driver. +// +#define ERROR_FLOPPY_UNKNOWN_ERROR 1124L + +// +// MessageId: ERROR_FLOPPY_BAD_REGISTERS +// +// MessageText: +// +// The floppy disk controller returned inconsistent results in its registers. +// +#define ERROR_FLOPPY_BAD_REGISTERS 1125L + +// +// MessageId: ERROR_DISK_RECALIBRATE_FAILED +// +// MessageText: +// +// While accessing the hard disk, a recalibrate operation failed, even after retries. +// +#define ERROR_DISK_RECALIBRATE_FAILED 1126L + +// +// MessageId: ERROR_DISK_OPERATION_FAILED +// +// MessageText: +// +// While accessing the hard disk, a disk operation failed even after retries. +// +#define ERROR_DISK_OPERATION_FAILED 1127L + +// +// MessageId: ERROR_DISK_RESET_FAILED +// +// MessageText: +// +// While accessing the hard disk, a disk controller reset was needed, but even that failed. +// +#define ERROR_DISK_RESET_FAILED 1128L + +// +// MessageId: ERROR_EOM_OVERFLOW +// +// MessageText: +// +// Physical end of tape encountered. +// +#define ERROR_EOM_OVERFLOW 1129L + +// +// MessageId: ERROR_NOT_ENOUGH_SERVER_MEMORY +// +// MessageText: +// +// Not enough server storage is available to process this command. +// +#define ERROR_NOT_ENOUGH_SERVER_MEMORY 1130L + +// +// MessageId: ERROR_POSSIBLE_DEADLOCK +// +// MessageText: +// +// A potential deadlock condition has been detected. +// +#define ERROR_POSSIBLE_DEADLOCK 1131L + +// +// MessageId: ERROR_MAPPED_ALIGNMENT +// +// MessageText: +// +// The base address or the file offset specified does not have the proper alignment. +// +#define ERROR_MAPPED_ALIGNMENT 1132L + +// +// MessageId: ERROR_SET_POWER_STATE_VETOED +// +// MessageText: +// +// An attempt to change the system power state was vetoed by another application or driver. +// +#define ERROR_SET_POWER_STATE_VETOED 1140L + +// +// MessageId: ERROR_SET_POWER_STATE_FAILED +// +// MessageText: +// +// The system BIOS failed an attempt to change the system power state. +// +#define ERROR_SET_POWER_STATE_FAILED 1141L + +// +// MessageId: ERROR_TOO_MANY_LINKS +// +// MessageText: +// +// An attempt was made to create more links on a file than the file system supports. +// +#define ERROR_TOO_MANY_LINKS 1142L + +// +// MessageId: ERROR_OLD_WIN_VERSION +// +// MessageText: +// +// The specified program requires a newer version of Windows. +// +#define ERROR_OLD_WIN_VERSION 1150L + +// +// MessageId: ERROR_APP_WRONG_OS +// +// MessageText: +// +// The specified program is not a Windows or MS-DOS program. +// +#define ERROR_APP_WRONG_OS 1151L + +// +// MessageId: ERROR_SINGLE_INSTANCE_APP +// +// MessageText: +// +// Cannot start more than one instance of the specified program. +// +#define ERROR_SINGLE_INSTANCE_APP 1152L + +// +// MessageId: ERROR_RMODE_APP +// +// MessageText: +// +// The specified program was written for an earlier version of Windows. +// +#define ERROR_RMODE_APP 1153L + +// +// MessageId: ERROR_INVALID_DLL +// +// MessageText: +// +// One of the library files needed to run this application is damaged. +// +#define ERROR_INVALID_DLL 1154L + +// +// MessageId: ERROR_NO_ASSOCIATION +// +// MessageText: +// +// No application is associated with the specified file for this operation. +// +#define ERROR_NO_ASSOCIATION 1155L + +// +// MessageId: ERROR_DDE_FAIL +// +// MessageText: +// +// An error occurred in sending the command to the application. +// +#define ERROR_DDE_FAIL 1156L + +// +// MessageId: ERROR_DLL_NOT_FOUND +// +// MessageText: +// +// One of the library files needed to run this application cannot be found. +// +#define ERROR_DLL_NOT_FOUND 1157L + +// +// MessageId: ERROR_NO_MORE_USER_HANDLES +// +// MessageText: +// +// The current process has used all of its system allowance of handles for Window Manager objects. +// +#define ERROR_NO_MORE_USER_HANDLES 1158L + +// +// MessageId: ERROR_MESSAGE_SYNC_ONLY +// +// MessageText: +// +// The message can be used only with synchronous operations. +// +#define ERROR_MESSAGE_SYNC_ONLY 1159L + +// +// MessageId: ERROR_SOURCE_ELEMENT_EMPTY +// +// MessageText: +// +// The indicated source element has no media. +// +#define ERROR_SOURCE_ELEMENT_EMPTY 1160L + +// +// MessageId: ERROR_DESTINATION_ELEMENT_FULL +// +// MessageText: +// +// The indicated destination element already contains media. +// +#define ERROR_DESTINATION_ELEMENT_FULL 1161L + +// +// MessageId: ERROR_ILLEGAL_ELEMENT_ADDRESS +// +// MessageText: +// +// The indicated element does not exist. +// +#define ERROR_ILLEGAL_ELEMENT_ADDRESS 1162L + +// +// MessageId: ERROR_MAGAZINE_NOT_PRESENT +// +// MessageText: +// +// The indicated element is part of a magazine that is not present. +// +#define ERROR_MAGAZINE_NOT_PRESENT 1163L + +// +// MessageId: ERROR_DEVICE_REINITIALIZATION_NEEDED +// +// MessageText: +// +// The indicated device requires reinitialization due to hardware errors. +// +#define ERROR_DEVICE_REINITIALIZATION_NEEDED 1164L // dderror + +// +// MessageId: ERROR_DEVICE_REQUIRES_CLEANING +// +// MessageText: +// +// The device has indicated that cleaning is required before further operations are attempted. +// +#define ERROR_DEVICE_REQUIRES_CLEANING 1165L + +// +// MessageId: ERROR_DEVICE_DOOR_OPEN +// +// MessageText: +// +// The device has indicated that its door is open. +// +#define ERROR_DEVICE_DOOR_OPEN 1166L + +// +// MessageId: ERROR_DEVICE_NOT_CONNECTED +// +// MessageText: +// +// The device is not connected. +// +#define ERROR_DEVICE_NOT_CONNECTED 1167L + +// +// MessageId: ERROR_NOT_FOUND +// +// MessageText: +// +// Element not found. +// +#define ERROR_NOT_FOUND 1168L + +// +// MessageId: ERROR_NO_MATCH +// +// MessageText: +// +// There was no match for the specified key in the index. +// +#define ERROR_NO_MATCH 1169L + +// +// MessageId: ERROR_SET_NOT_FOUND +// +// MessageText: +// +// The property set specified does not exist on the object. +// +#define ERROR_SET_NOT_FOUND 1170L + +// +// MessageId: ERROR_POINT_NOT_FOUND +// +// MessageText: +// +// The point passed to GetMouseMovePoints is not in the buffer. +// +#define ERROR_POINT_NOT_FOUND 1171L + +// +// MessageId: ERROR_NO_TRACKING_SERVICE +// +// MessageText: +// +// The tracking (workstation) service is not running. +// +#define ERROR_NO_TRACKING_SERVICE 1172L + +// +// MessageId: ERROR_NO_VOLUME_ID +// +// MessageText: +// +// The Volume ID could not be found. +// +#define ERROR_NO_VOLUME_ID 1173L + +// +// MessageId: ERROR_UNABLE_TO_REMOVE_REPLACED +// +// MessageText: +// +// Unable to remove the file to be replaced. +// +#define ERROR_UNABLE_TO_REMOVE_REPLACED 1175L + +// +// MessageId: ERROR_UNABLE_TO_MOVE_REPLACEMENT +// +// MessageText: +// +// Unable to move the replacement file to the file to be replaced. The file to be replaced has retained its original name. +// +#define ERROR_UNABLE_TO_MOVE_REPLACEMENT 1176L + +// +// MessageId: ERROR_UNABLE_TO_MOVE_REPLACEMENT_2 +// +// MessageText: +// +// Unable to move the replacement file to the file to be replaced. The file to be replaced has been renamed using the backup name. +// +#define ERROR_UNABLE_TO_MOVE_REPLACEMENT_2 1177L + +// +// MessageId: ERROR_JOURNAL_DELETE_IN_PROGRESS +// +// MessageText: +// +// The volume change journal is being deleted. +// +#define ERROR_JOURNAL_DELETE_IN_PROGRESS 1178L + +// +// MessageId: ERROR_JOURNAL_NOT_ACTIVE +// +// MessageText: +// +// The volume change journal is not active. +// +#define ERROR_JOURNAL_NOT_ACTIVE 1179L + +// +// MessageId: ERROR_POTENTIAL_FILE_FOUND +// +// MessageText: +// +// A file was found, but it may not be the correct file. +// +#define ERROR_POTENTIAL_FILE_FOUND 1180L + +// +// MessageId: ERROR_JOURNAL_ENTRY_DELETED +// +// MessageText: +// +// The journal entry has been deleted from the journal. +// +#define ERROR_JOURNAL_ENTRY_DELETED 1181L + +// +// MessageId: ERROR_BAD_DEVICE +// +// MessageText: +// +// The specified device name is invalid. +// +#define ERROR_BAD_DEVICE 1200L + +// +// MessageId: ERROR_CONNECTION_UNAVAIL +// +// MessageText: +// +// The device is not currently connected but it is a remembered connection. +// +#define ERROR_CONNECTION_UNAVAIL 1201L + +// +// MessageId: ERROR_DEVICE_ALREADY_REMEMBERED +// +// MessageText: +// +// The local device name has a remembered connection to another network resource. +// +#define ERROR_DEVICE_ALREADY_REMEMBERED 1202L + +// +// MessageId: ERROR_NO_NET_OR_BAD_PATH +// +// MessageText: +// +// No network provider accepted the given network path. +// +#define ERROR_NO_NET_OR_BAD_PATH 1203L + +// +// MessageId: ERROR_BAD_PROVIDER +// +// MessageText: +// +// The specified network provider name is invalid. +// +#define ERROR_BAD_PROVIDER 1204L + +// +// MessageId: ERROR_CANNOT_OPEN_PROFILE +// +// MessageText: +// +// Unable to open the network connection profile. +// +#define ERROR_CANNOT_OPEN_PROFILE 1205L + +// +// MessageId: ERROR_BAD_PROFILE +// +// MessageText: +// +// The network connection profile is corrupted. +// +#define ERROR_BAD_PROFILE 1206L + +// +// MessageId: ERROR_NOT_CONTAINER +// +// MessageText: +// +// Cannot enumerate a noncontainer. +// +#define ERROR_NOT_CONTAINER 1207L + +// +// MessageId: ERROR_EXTENDED_ERROR +// +// MessageText: +// +// An extended error has occurred. +// +#define ERROR_EXTENDED_ERROR 1208L + +// +// MessageId: ERROR_INVALID_GROUPNAME +// +// MessageText: +// +// The format of the specified group name is invalid. +// +#define ERROR_INVALID_GROUPNAME 1209L + +// +// MessageId: ERROR_INVALID_COMPUTERNAME +// +// MessageText: +// +// The format of the specified computer name is invalid. +// +#define ERROR_INVALID_COMPUTERNAME 1210L + +// +// MessageId: ERROR_INVALID_EVENTNAME +// +// MessageText: +// +// The format of the specified event name is invalid. +// +#define ERROR_INVALID_EVENTNAME 1211L + +// +// MessageId: ERROR_INVALID_DOMAINNAME +// +// MessageText: +// +// The format of the specified domain name is invalid. +// +#define ERROR_INVALID_DOMAINNAME 1212L + +// +// MessageId: ERROR_INVALID_SERVICENAME +// +// MessageText: +// +// The format of the specified service name is invalid. +// +#define ERROR_INVALID_SERVICENAME 1213L + +// +// MessageId: ERROR_INVALID_NETNAME +// +// MessageText: +// +// The format of the specified network name is invalid. +// +#define ERROR_INVALID_NETNAME 1214L + +// +// MessageId: ERROR_INVALID_SHARENAME +// +// MessageText: +// +// The format of the specified share name is invalid. +// +#define ERROR_INVALID_SHARENAME 1215L + +// +// MessageId: ERROR_INVALID_PASSWORDNAME +// +// MessageText: +// +// The format of the specified password is invalid. +// +#define ERROR_INVALID_PASSWORDNAME 1216L + +// +// MessageId: ERROR_INVALID_MESSAGENAME +// +// MessageText: +// +// The format of the specified message name is invalid. +// +#define ERROR_INVALID_MESSAGENAME 1217L + +// +// MessageId: ERROR_INVALID_MESSAGEDEST +// +// MessageText: +// +// The format of the specified message destination is invalid. +// +#define ERROR_INVALID_MESSAGEDEST 1218L + +// +// MessageId: ERROR_SESSION_CREDENTIAL_CONFLICT +// +// MessageText: +// +// Multiple connections to a server or shared resource by the same user, using more than one user name, are not allowed. Disconnect all previous connections to the server or shared resource and try again. +// +#define ERROR_SESSION_CREDENTIAL_CONFLICT 1219L + +// +// MessageId: ERROR_REMOTE_SESSION_LIMIT_EXCEEDED +// +// MessageText: +// +// An attempt was made to establish a session to a network server, but there are already too many sessions established to that server. +// +#define ERROR_REMOTE_SESSION_LIMIT_EXCEEDED 1220L + +// +// MessageId: ERROR_DUP_DOMAINNAME +// +// MessageText: +// +// The workgroup or domain name is already in use by another computer on the network. +// +#define ERROR_DUP_DOMAINNAME 1221L + +// +// MessageId: ERROR_NO_NETWORK +// +// MessageText: +// +// The network is not present or not started. +// +#define ERROR_NO_NETWORK 1222L + +// +// MessageId: ERROR_CANCELLED +// +// MessageText: +// +// The operation was canceled by the user. +// +#define ERROR_CANCELLED 1223L + +// +// MessageId: ERROR_USER_MAPPED_FILE +// +// MessageText: +// +// The requested operation cannot be performed on a file with a user-mapped section open. +// +#define ERROR_USER_MAPPED_FILE 1224L + +// +// MessageId: ERROR_CONNECTION_REFUSED +// +// MessageText: +// +// The remote system refused the network connection. +// +#define ERROR_CONNECTION_REFUSED 1225L + +// +// MessageId: ERROR_GRACEFUL_DISCONNECT +// +// MessageText: +// +// The network connection was gracefully closed. +// +#define ERROR_GRACEFUL_DISCONNECT 1226L + +// +// MessageId: ERROR_ADDRESS_ALREADY_ASSOCIATED +// +// MessageText: +// +// The network transport endpoint already has an address associated with it. +// +#define ERROR_ADDRESS_ALREADY_ASSOCIATED 1227L + +// +// MessageId: ERROR_ADDRESS_NOT_ASSOCIATED +// +// MessageText: +// +// An address has not yet been associated with the network endpoint. +// +#define ERROR_ADDRESS_NOT_ASSOCIATED 1228L + +// +// MessageId: ERROR_CONNECTION_INVALID +// +// MessageText: +// +// An operation was attempted on a nonexistent network connection. +// +#define ERROR_CONNECTION_INVALID 1229L + +// +// MessageId: ERROR_CONNECTION_ACTIVE +// +// MessageText: +// +// An invalid operation was attempted on an active network connection. +// +#define ERROR_CONNECTION_ACTIVE 1230L + +// +// MessageId: ERROR_NETWORK_UNREACHABLE +// +// MessageText: +// +// The network location cannot be reached. For information about network troubleshooting, see Windows Help. +// +#define ERROR_NETWORK_UNREACHABLE 1231L + +// +// MessageId: ERROR_HOST_UNREACHABLE +// +// MessageText: +// +// The network location cannot be reached. For information about network troubleshooting, see Windows Help. +// +#define ERROR_HOST_UNREACHABLE 1232L + +// +// MessageId: ERROR_PROTOCOL_UNREACHABLE +// +// MessageText: +// +// The network location cannot be reached. For information about network troubleshooting, see Windows Help. +// +#define ERROR_PROTOCOL_UNREACHABLE 1233L + +// +// MessageId: ERROR_PORT_UNREACHABLE +// +// MessageText: +// +// No service is operating at the destination network endpoint on the remote system. +// +#define ERROR_PORT_UNREACHABLE 1234L + +// +// MessageId: ERROR_REQUEST_ABORTED +// +// MessageText: +// +// The request was aborted. +// +#define ERROR_REQUEST_ABORTED 1235L + +// +// MessageId: ERROR_CONNECTION_ABORTED +// +// MessageText: +// +// The network connection was aborted by the local system. +// +#define ERROR_CONNECTION_ABORTED 1236L + +// +// MessageId: ERROR_RETRY +// +// MessageText: +// +// The operation could not be completed. A retry should be performed. +// +#define ERROR_RETRY 1237L + +// +// MessageId: ERROR_CONNECTION_COUNT_LIMIT +// +// MessageText: +// +// A connection to the server could not be made because the limit on the number of concurrent connections for this account has been reached. +// +#define ERROR_CONNECTION_COUNT_LIMIT 1238L + +// +// MessageId: ERROR_LOGIN_TIME_RESTRICTION +// +// MessageText: +// +// Attempting to log in during an unauthorized time of day for this account. +// +#define ERROR_LOGIN_TIME_RESTRICTION 1239L + +// +// MessageId: ERROR_LOGIN_WKSTA_RESTRICTION +// +// MessageText: +// +// The account is not authorized to log in from this station. +// +#define ERROR_LOGIN_WKSTA_RESTRICTION 1240L + +// +// MessageId: ERROR_INCORRECT_ADDRESS +// +// MessageText: +// +// The network address could not be used for the operation requested. +// +#define ERROR_INCORRECT_ADDRESS 1241L + +// +// MessageId: ERROR_ALREADY_REGISTERED +// +// MessageText: +// +// The service is already registered. +// +#define ERROR_ALREADY_REGISTERED 1242L + +// +// MessageId: ERROR_SERVICE_NOT_FOUND +// +// MessageText: +// +// The specified service does not exist. +// +#define ERROR_SERVICE_NOT_FOUND 1243L + +// +// MessageId: ERROR_NOT_AUTHENTICATED +// +// MessageText: +// +// The operation being requested was not performed because the user has not been authenticated. +// +#define ERROR_NOT_AUTHENTICATED 1244L + +// +// MessageId: ERROR_NOT_LOGGED_ON +// +// MessageText: +// +// The operation being requested was not performed because the user has not logged on to the network. +// The specified service does not exist. +// +#define ERROR_NOT_LOGGED_ON 1245L + +// +// MessageId: ERROR_CONTINUE +// +// MessageText: +// +// Continue with work in progress. +// +#define ERROR_CONTINUE 1246L // dderror + +// +// MessageId: ERROR_ALREADY_INITIALIZED +// +// MessageText: +// +// An attempt was made to perform an initialization operation when initialization has already been completed. +// +#define ERROR_ALREADY_INITIALIZED 1247L + +// +// MessageId: ERROR_NO_MORE_DEVICES +// +// MessageText: +// +// No more local devices. +// +#define ERROR_NO_MORE_DEVICES 1248L // dderror + +// +// MessageId: ERROR_NO_SUCH_SITE +// +// MessageText: +// +// The specified site does not exist. +// +#define ERROR_NO_SUCH_SITE 1249L + +// +// MessageId: ERROR_DOMAIN_CONTROLLER_EXISTS +// +// MessageText: +// +// A domain controller with the specified name already exists. +// +#define ERROR_DOMAIN_CONTROLLER_EXISTS 1250L + +// +// MessageId: ERROR_ONLY_IF_CONNECTED +// +// MessageText: +// +// This operation is supported only when you are connected to the server. +// +#define ERROR_ONLY_IF_CONNECTED 1251L + +// +// MessageId: ERROR_OVERRIDE_NOCHANGES +// +// MessageText: +// +// The group policy framework should call the extension even if there are no changes. +// +#define ERROR_OVERRIDE_NOCHANGES 1252L + +// +// MessageId: ERROR_BAD_USER_PROFILE +// +// MessageText: +// +// The specified user does not have a valid profile. +// +#define ERROR_BAD_USER_PROFILE 1253L + +// +// MessageId: ERROR_NOT_SUPPORTED_ON_SBS +// +// MessageText: +// +// This operation is not supported on a computer running Windows Server 2003 for Small Business Server +// +#define ERROR_NOT_SUPPORTED_ON_SBS 1254L + +// +// MessageId: ERROR_SERVER_SHUTDOWN_IN_PROGRESS +// +// MessageText: +// +// The server machine is shutting down. +// +#define ERROR_SERVER_SHUTDOWN_IN_PROGRESS 1255L + +// +// MessageId: ERROR_HOST_DOWN +// +// MessageText: +// +// The remote system is not available. For information about network troubleshooting, see Windows Help. +// +#define ERROR_HOST_DOWN 1256L + +// +// MessageId: ERROR_NON_ACCOUNT_SID +// +// MessageText: +// +// The security identifier provided is not from an account domain. +// +#define ERROR_NON_ACCOUNT_SID 1257L + +// +// MessageId: ERROR_NON_DOMAIN_SID +// +// MessageText: +// +// The security identifier provided does not have a domain component. +// +#define ERROR_NON_DOMAIN_SID 1258L + +// +// MessageId: ERROR_APPHELP_BLOCK +// +// MessageText: +// +// AppHelp dialog canceled thus preventing the application from starting. +// +#define ERROR_APPHELP_BLOCK 1259L + +// +// MessageId: ERROR_ACCESS_DISABLED_BY_POLICY +// +// MessageText: +// +// Windows cannot open this program because it has been prevented by a software restriction policy. For more information, open Event Viewer or contact your system administrator. +// +#define ERROR_ACCESS_DISABLED_BY_POLICY 1260L + +// +// MessageId: ERROR_REG_NAT_CONSUMPTION +// +// MessageText: +// +// A program attempt to use an invalid register value. Normally caused by an uninitialized register. This error is Itanium specific. +// +#define ERROR_REG_NAT_CONSUMPTION 1261L + +// +// MessageId: ERROR_CSCSHARE_OFFLINE +// +// MessageText: +// +// The share is currently offline or does not exist. +// +#define ERROR_CSCSHARE_OFFLINE 1262L + +// +// MessageId: ERROR_PKINIT_FAILURE +// +// MessageText: +// +// The kerberos protocol encountered an error while validating the +// KDC certificate during smartcard logon. There is more information in the +// system event log. +// +#define ERROR_PKINIT_FAILURE 1263L + +// +// MessageId: ERROR_SMARTCARD_SUBSYSTEM_FAILURE +// +// MessageText: +// +// The kerberos protocol encountered an error while attempting to utilize +// the smartcard subsystem. +// +#define ERROR_SMARTCARD_SUBSYSTEM_FAILURE 1264L + +// +// MessageId: ERROR_DOWNGRADE_DETECTED +// +// MessageText: +// +// The system detected a possible attempt to compromise security. Please ensure that you can contact the server that authenticated you. +// +#define ERROR_DOWNGRADE_DETECTED 1265L + +// +// Do not use ID's 1266 - 1270 as the symbolicNames have been moved to SEC_E_* +// +// +// MessageId: ERROR_MACHINE_LOCKED +// +// MessageText: +// +// The machine is locked and can not be shut down without the force option. +// +#define ERROR_MACHINE_LOCKED 1271L + +// +// MessageId: ERROR_CALLBACK_SUPPLIED_INVALID_DATA +// +// MessageText: +// +// An application-defined callback gave invalid data when called. +// +#define ERROR_CALLBACK_SUPPLIED_INVALID_DATA 1273L + +// +// MessageId: ERROR_SYNC_FOREGROUND_REFRESH_REQUIRED +// +// MessageText: +// +// The group policy framework should call the extension in the synchronous foreground policy refresh. +// +#define ERROR_SYNC_FOREGROUND_REFRESH_REQUIRED 1274L + +// +// MessageId: ERROR_DRIVER_BLOCKED +// +// MessageText: +// +// This driver has been blocked from loading +// +#define ERROR_DRIVER_BLOCKED 1275L + +// +// MessageId: ERROR_INVALID_IMPORT_OF_NON_DLL +// +// MessageText: +// +// A dynamic link library (DLL) referenced a module that was neither a DLL nor the process's executable image. +// +#define ERROR_INVALID_IMPORT_OF_NON_DLL 1276L + +// +// MessageId: ERROR_ACCESS_DISABLED_WEBBLADE +// +// MessageText: +// +// Windows cannot open this program since it has been disabled. +// +#define ERROR_ACCESS_DISABLED_WEBBLADE 1277L + +// +// MessageId: ERROR_ACCESS_DISABLED_WEBBLADE_TAMPER +// +// MessageText: +// +// Windows cannot open this program because the license enforcement system has been tampered with or become corrupted. +// +#define ERROR_ACCESS_DISABLED_WEBBLADE_TAMPER 1278L + +// +// MessageId: ERROR_RECOVERY_FAILURE +// +// MessageText: +// +// A transaction recover failed. +// +#define ERROR_RECOVERY_FAILURE 1279L + +// +// MessageId: ERROR_ALREADY_FIBER +// +// MessageText: +// +// The current thread has already been converted to a fiber. +// +#define ERROR_ALREADY_FIBER 1280L + +// +// MessageId: ERROR_ALREADY_THREAD +// +// MessageText: +// +// The current thread has already been converted from a fiber. +// +#define ERROR_ALREADY_THREAD 1281L + +// +// MessageId: ERROR_STACK_BUFFER_OVERRUN +// +// MessageText: +// +// The system detected an overrun of a stack-based buffer in this application. This +// overrun could potentially allow a malicious user to gain control of this application. +// +#define ERROR_STACK_BUFFER_OVERRUN 1282L + +// +// MessageId: ERROR_PARAMETER_QUOTA_EXCEEDED +// +// MessageText: +// +// Data present in one of the parameters is more than the function can operate on. +// +#define ERROR_PARAMETER_QUOTA_EXCEEDED 1283L + +// +// MessageId: ERROR_DEBUGGER_INACTIVE +// +// MessageText: +// +// An attempt to do an operation on a debug object failed because the object is in the process of being deleted. +// +#define ERROR_DEBUGGER_INACTIVE 1284L + +// +// MessageId: ERROR_DELAY_LOAD_FAILED +// +// MessageText: +// +// An attempt to delay-load a .dll or get a function address in a delay-loaded .dll failed. +// +#define ERROR_DELAY_LOAD_FAILED 1285L + +// +// MessageId: ERROR_VDM_DISALLOWED +// +// MessageText: +// +// %1 is a 16-bit application. You do not have permissions to execute 16-bit applications. Check your permissions with your system administrator. +// +#define ERROR_VDM_DISALLOWED 1286L + +// +// MessageId: ERROR_UNIDENTIFIED_ERROR +// +// MessageText: +// +// Insufficient information exists to identify the cause of failure. +// +#define ERROR_UNIDENTIFIED_ERROR 1287L + + +/////////////////////////// +// +// Add new status codes before this point unless there is a component specific section below. +// +/////////////////////////// + + +/////////////////////////// +// // +// Security Status Codes // +// // +/////////////////////////// + + +// +// MessageId: ERROR_NOT_ALL_ASSIGNED +// +// MessageText: +// +// Not all privileges referenced are assigned to the caller. +// +#define ERROR_NOT_ALL_ASSIGNED 1300L + +// +// MessageId: ERROR_SOME_NOT_MAPPED +// +// MessageText: +// +// Some mapping between account names and security IDs was not done. +// +#define ERROR_SOME_NOT_MAPPED 1301L + +// +// MessageId: ERROR_NO_QUOTAS_FOR_ACCOUNT +// +// MessageText: +// +// No system quota limits are specifically set for this account. +// +#define ERROR_NO_QUOTAS_FOR_ACCOUNT 1302L + +// +// MessageId: ERROR_LOCAL_USER_SESSION_KEY +// +// MessageText: +// +// No encryption key is available. A well-known encryption key was returned. +// +#define ERROR_LOCAL_USER_SESSION_KEY 1303L + +// +// MessageId: ERROR_NULL_LM_PASSWORD +// +// MessageText: +// +// The password is too complex to be converted to a LAN Manager password. The LAN Manager password returned is a NULL string. +// +#define ERROR_NULL_LM_PASSWORD 1304L + +// +// MessageId: ERROR_UNKNOWN_REVISION +// +// MessageText: +// +// The revision level is unknown. +// +#define ERROR_UNKNOWN_REVISION 1305L + +// +// MessageId: ERROR_REVISION_MISMATCH +// +// MessageText: +// +// Indicates two revision levels are incompatible. +// +#define ERROR_REVISION_MISMATCH 1306L + +// +// MessageId: ERROR_INVALID_OWNER +// +// MessageText: +// +// This security ID may not be assigned as the owner of this object. +// +#define ERROR_INVALID_OWNER 1307L + +// +// MessageId: ERROR_INVALID_PRIMARY_GROUP +// +// MessageText: +// +// This security ID may not be assigned as the primary group of an object. +// +#define ERROR_INVALID_PRIMARY_GROUP 1308L + +// +// MessageId: ERROR_NO_IMPERSONATION_TOKEN +// +// MessageText: +// +// An attempt has been made to operate on an impersonation token by a thread that is not currently impersonating a client. +// +#define ERROR_NO_IMPERSONATION_TOKEN 1309L + +// +// MessageId: ERROR_CANT_DISABLE_MANDATORY +// +// MessageText: +// +// The group may not be disabled. +// +#define ERROR_CANT_DISABLE_MANDATORY 1310L + +// +// MessageId: ERROR_NO_LOGON_SERVERS +// +// MessageText: +// +// There are currently no logon servers available to service the logon request. +// +#define ERROR_NO_LOGON_SERVERS 1311L + +// +// MessageId: ERROR_NO_SUCH_LOGON_SESSION +// +// MessageText: +// +// A specified logon session does not exist. It may already have been terminated. +// +#define ERROR_NO_SUCH_LOGON_SESSION 1312L + +// +// MessageId: ERROR_NO_SUCH_PRIVILEGE +// +// MessageText: +// +// A specified privilege does not exist. +// +#define ERROR_NO_SUCH_PRIVILEGE 1313L + +// +// MessageId: ERROR_PRIVILEGE_NOT_HELD +// +// MessageText: +// +// A required privilege is not held by the client. +// +#define ERROR_PRIVILEGE_NOT_HELD 1314L + +// +// MessageId: ERROR_INVALID_ACCOUNT_NAME +// +// MessageText: +// +// The name provided is not a properly formed account name. +// +#define ERROR_INVALID_ACCOUNT_NAME 1315L + +// +// MessageId: ERROR_USER_EXISTS +// +// MessageText: +// +// The specified user already exists. +// +#define ERROR_USER_EXISTS 1316L + +// +// MessageId: ERROR_NO_SUCH_USER +// +// MessageText: +// +// The specified user does not exist. +// +#define ERROR_NO_SUCH_USER 1317L + +// +// MessageId: ERROR_GROUP_EXISTS +// +// MessageText: +// +// The specified group already exists. +// +#define ERROR_GROUP_EXISTS 1318L + +// +// MessageId: ERROR_NO_SUCH_GROUP +// +// MessageText: +// +// The specified group does not exist. +// +#define ERROR_NO_SUCH_GROUP 1319L + +// +// MessageId: ERROR_MEMBER_IN_GROUP +// +// MessageText: +// +// Either the specified user account is already a member of the specified group, or the specified group cannot be deleted because it contains a member. +// +#define ERROR_MEMBER_IN_GROUP 1320L + +// +// MessageId: ERROR_MEMBER_NOT_IN_GROUP +// +// MessageText: +// +// The specified user account is not a member of the specified group account. +// +#define ERROR_MEMBER_NOT_IN_GROUP 1321L + +// +// MessageId: ERROR_LAST_ADMIN +// +// MessageText: +// +// The last remaining administration account cannot be disabled or deleted. +// +#define ERROR_LAST_ADMIN 1322L + +// +// MessageId: ERROR_WRONG_PASSWORD +// +// MessageText: +// +// Unable to update the password. The value provided as the current password is incorrect. +// +#define ERROR_WRONG_PASSWORD 1323L + +// +// MessageId: ERROR_ILL_FORMED_PASSWORD +// +// MessageText: +// +// Unable to update the password. The value provided for the new password contains values that are not allowed in passwords. +// +#define ERROR_ILL_FORMED_PASSWORD 1324L + +// +// MessageId: ERROR_PASSWORD_RESTRICTION +// +// MessageText: +// +// Unable to update the password. The value provided for the new password does not meet the length, complexity, or history requirement of the domain. +// +#define ERROR_PASSWORD_RESTRICTION 1325L + +// +// MessageId: ERROR_LOGON_FAILURE +// +// MessageText: +// +// Logon failure: unknown user name or bad password. +// +#define ERROR_LOGON_FAILURE 1326L + +// +// MessageId: ERROR_ACCOUNT_RESTRICTION +// +// MessageText: +// +// Logon failure: user account restriction. Possible reasons are blank passwords not allowed, logon hour restrictions, or a policy restriction has been enforced. +// +#define ERROR_ACCOUNT_RESTRICTION 1327L + +// +// MessageId: ERROR_INVALID_LOGON_HOURS +// +// MessageText: +// +// Logon failure: account logon time restriction violation. +// +#define ERROR_INVALID_LOGON_HOURS 1328L + +// +// MessageId: ERROR_INVALID_WORKSTATION +// +// MessageText: +// +// Logon failure: user not allowed to log on to this computer. +// +#define ERROR_INVALID_WORKSTATION 1329L + +// +// MessageId: ERROR_PASSWORD_EXPIRED +// +// MessageText: +// +// Logon failure: the specified account password has expired. +// +#define ERROR_PASSWORD_EXPIRED 1330L + +// +// MessageId: ERROR_ACCOUNT_DISABLED +// +// MessageText: +// +// Logon failure: account currently disabled. +// +#define ERROR_ACCOUNT_DISABLED 1331L + +// +// MessageId: ERROR_NONE_MAPPED +// +// MessageText: +// +// No mapping between account names and security IDs was done. +// +#define ERROR_NONE_MAPPED 1332L + +// +// MessageId: ERROR_TOO_MANY_LUIDS_REQUESTED +// +// MessageText: +// +// Too many local user identifiers (LUIDs) were requested at one time. +// +#define ERROR_TOO_MANY_LUIDS_REQUESTED 1333L + +// +// MessageId: ERROR_LUIDS_EXHAUSTED +// +// MessageText: +// +// No more local user identifiers (LUIDs) are available. +// +#define ERROR_LUIDS_EXHAUSTED 1334L + +// +// MessageId: ERROR_INVALID_SUB_AUTHORITY +// +// MessageText: +// +// The subauthority part of a security ID is invalid for this particular use. +// +#define ERROR_INVALID_SUB_AUTHORITY 1335L + +// +// MessageId: ERROR_INVALID_ACL +// +// MessageText: +// +// The access control list (ACL) structure is invalid. +// +#define ERROR_INVALID_ACL 1336L + +// +// MessageId: ERROR_INVALID_SID +// +// MessageText: +// +// The security ID structure is invalid. +// +#define ERROR_INVALID_SID 1337L + +// +// MessageId: ERROR_INVALID_SECURITY_DESCR +// +// MessageText: +// +// The security descriptor structure is invalid. +// +#define ERROR_INVALID_SECURITY_DESCR 1338L + +// +// MessageId: ERROR_BAD_INHERITANCE_ACL +// +// MessageText: +// +// The inherited access control list (ACL) or access control entry (ACE) could not be built. +// +#define ERROR_BAD_INHERITANCE_ACL 1340L + +// +// MessageId: ERROR_SERVER_DISABLED +// +// MessageText: +// +// The server is currently disabled. +// +#define ERROR_SERVER_DISABLED 1341L + +// +// MessageId: ERROR_SERVER_NOT_DISABLED +// +// MessageText: +// +// The server is currently enabled. +// +#define ERROR_SERVER_NOT_DISABLED 1342L + +// +// MessageId: ERROR_INVALID_ID_AUTHORITY +// +// MessageText: +// +// The value provided was an invalid value for an identifier authority. +// +#define ERROR_INVALID_ID_AUTHORITY 1343L + +// +// MessageId: ERROR_ALLOTTED_SPACE_EXCEEDED +// +// MessageText: +// +// No more memory is available for security information updates. +// +#define ERROR_ALLOTTED_SPACE_EXCEEDED 1344L + +// +// MessageId: ERROR_INVALID_GROUP_ATTRIBUTES +// +// MessageText: +// +// The specified attributes are invalid, or incompatible with the attributes for the group as a whole. +// +#define ERROR_INVALID_GROUP_ATTRIBUTES 1345L + +// +// MessageId: ERROR_BAD_IMPERSONATION_LEVEL +// +// MessageText: +// +// Either a required impersonation level was not provided, or the provided impersonation level is invalid. +// +#define ERROR_BAD_IMPERSONATION_LEVEL 1346L + +// +// MessageId: ERROR_CANT_OPEN_ANONYMOUS +// +// MessageText: +// +// Cannot open an anonymous level security token. +// +#define ERROR_CANT_OPEN_ANONYMOUS 1347L + +// +// MessageId: ERROR_BAD_VALIDATION_CLASS +// +// MessageText: +// +// The validation information class requested was invalid. +// +#define ERROR_BAD_VALIDATION_CLASS 1348L + +// +// MessageId: ERROR_BAD_TOKEN_TYPE +// +// MessageText: +// +// The type of the token is inappropriate for its attempted use. +// +#define ERROR_BAD_TOKEN_TYPE 1349L + +// +// MessageId: ERROR_NO_SECURITY_ON_OBJECT +// +// MessageText: +// +// Unable to perform a security operation on an object that has no associated security. +// +#define ERROR_NO_SECURITY_ON_OBJECT 1350L + +// +// MessageId: ERROR_CANT_ACCESS_DOMAIN_INFO +// +// MessageText: +// +// Configuration information could not be read from the domain controller, either because the machine is unavailable, or access has been denied. +// +#define ERROR_CANT_ACCESS_DOMAIN_INFO 1351L + +// +// MessageId: ERROR_INVALID_SERVER_STATE +// +// MessageText: +// +// The security account manager (SAM) or local security authority (LSA) server was in the wrong state to perform the security operation. +// +#define ERROR_INVALID_SERVER_STATE 1352L + +// +// MessageId: ERROR_INVALID_DOMAIN_STATE +// +// MessageText: +// +// The domain was in the wrong state to perform the security operation. +// +#define ERROR_INVALID_DOMAIN_STATE 1353L + +// +// MessageId: ERROR_INVALID_DOMAIN_ROLE +// +// MessageText: +// +// This operation is only allowed for the Primary Domain Controller of the domain. +// +#define ERROR_INVALID_DOMAIN_ROLE 1354L + +// +// MessageId: ERROR_NO_SUCH_DOMAIN +// +// MessageText: +// +// The specified domain either does not exist or could not be contacted. +// +#define ERROR_NO_SUCH_DOMAIN 1355L + +// +// MessageId: ERROR_DOMAIN_EXISTS +// +// MessageText: +// +// The specified domain already exists. +// +#define ERROR_DOMAIN_EXISTS 1356L + +// +// MessageId: ERROR_DOMAIN_LIMIT_EXCEEDED +// +// MessageText: +// +// An attempt was made to exceed the limit on the number of domains per server. +// +#define ERROR_DOMAIN_LIMIT_EXCEEDED 1357L + +// +// MessageId: ERROR_INTERNAL_DB_CORRUPTION +// +// MessageText: +// +// Unable to complete the requested operation because of either a catastrophic media failure or a data structure corruption on the disk. +// +#define ERROR_INTERNAL_DB_CORRUPTION 1358L + +// +// MessageId: ERROR_INTERNAL_ERROR +// +// MessageText: +// +// An internal error occurred. +// +#define ERROR_INTERNAL_ERROR 1359L + +// +// MessageId: ERROR_GENERIC_NOT_MAPPED +// +// MessageText: +// +// Generic access types were contained in an access mask which should already be mapped to nongeneric types. +// +#define ERROR_GENERIC_NOT_MAPPED 1360L + +// +// MessageId: ERROR_BAD_DESCRIPTOR_FORMAT +// +// MessageText: +// +// A security descriptor is not in the right format (absolute or self-relative). +// +#define ERROR_BAD_DESCRIPTOR_FORMAT 1361L + +// +// MessageId: ERROR_NOT_LOGON_PROCESS +// +// MessageText: +// +// The requested action is restricted for use by logon processes only. The calling process has not registered as a logon process. +// +#define ERROR_NOT_LOGON_PROCESS 1362L + +// +// MessageId: ERROR_LOGON_SESSION_EXISTS +// +// MessageText: +// +// Cannot start a new logon session with an ID that is already in use. +// +#define ERROR_LOGON_SESSION_EXISTS 1363L + +// +// MessageId: ERROR_NO_SUCH_PACKAGE +// +// MessageText: +// +// A specified authentication package is unknown. +// +#define ERROR_NO_SUCH_PACKAGE 1364L + +// +// MessageId: ERROR_BAD_LOGON_SESSION_STATE +// +// MessageText: +// +// The logon session is not in a state that is consistent with the requested operation. +// +#define ERROR_BAD_LOGON_SESSION_STATE 1365L + +// +// MessageId: ERROR_LOGON_SESSION_COLLISION +// +// MessageText: +// +// The logon session ID is already in use. +// +#define ERROR_LOGON_SESSION_COLLISION 1366L + +// +// MessageId: ERROR_INVALID_LOGON_TYPE +// +// MessageText: +// +// A logon request contained an invalid logon type value. +// +#define ERROR_INVALID_LOGON_TYPE 1367L + +// +// MessageId: ERROR_CANNOT_IMPERSONATE +// +// MessageText: +// +// Unable to impersonate using a named pipe until data has been read from that pipe. +// +#define ERROR_CANNOT_IMPERSONATE 1368L + +// +// MessageId: ERROR_RXACT_INVALID_STATE +// +// MessageText: +// +// The transaction state of a registry subtree is incompatible with the requested operation. +// +#define ERROR_RXACT_INVALID_STATE 1369L + +// +// MessageId: ERROR_RXACT_COMMIT_FAILURE +// +// MessageText: +// +// An internal security database corruption has been encountered. +// +#define ERROR_RXACT_COMMIT_FAILURE 1370L + +// +// MessageId: ERROR_SPECIAL_ACCOUNT +// +// MessageText: +// +// Cannot perform this operation on built-in accounts. +// +#define ERROR_SPECIAL_ACCOUNT 1371L + +// +// MessageId: ERROR_SPECIAL_GROUP +// +// MessageText: +// +// Cannot perform this operation on this built-in special group. +// +#define ERROR_SPECIAL_GROUP 1372L + +// +// MessageId: ERROR_SPECIAL_USER +// +// MessageText: +// +// Cannot perform this operation on this built-in special user. +// +#define ERROR_SPECIAL_USER 1373L + +// +// MessageId: ERROR_MEMBERS_PRIMARY_GROUP +// +// MessageText: +// +// The user cannot be removed from a group because the group is currently the user's primary group. +// +#define ERROR_MEMBERS_PRIMARY_GROUP 1374L + +// +// MessageId: ERROR_TOKEN_ALREADY_IN_USE +// +// MessageText: +// +// The token is already in use as a primary token. +// +#define ERROR_TOKEN_ALREADY_IN_USE 1375L + +// +// MessageId: ERROR_NO_SUCH_ALIAS +// +// MessageText: +// +// The specified local group does not exist. +// +#define ERROR_NO_SUCH_ALIAS 1376L + +// +// MessageId: ERROR_MEMBER_NOT_IN_ALIAS +// +// MessageText: +// +// The specified account name is not a member of the local group. +// +#define ERROR_MEMBER_NOT_IN_ALIAS 1377L + +// +// MessageId: ERROR_MEMBER_IN_ALIAS +// +// MessageText: +// +// The specified account name is already a member of the local group. +// +#define ERROR_MEMBER_IN_ALIAS 1378L + +// +// MessageId: ERROR_ALIAS_EXISTS +// +// MessageText: +// +// The specified local group already exists. +// +#define ERROR_ALIAS_EXISTS 1379L + +// +// MessageId: ERROR_LOGON_NOT_GRANTED +// +// MessageText: +// +// Logon failure: the user has not been granted the requested logon type at this computer. +// +#define ERROR_LOGON_NOT_GRANTED 1380L + +// +// MessageId: ERROR_TOO_MANY_SECRETS +// +// MessageText: +// +// The maximum number of secrets that may be stored in a single system has been exceeded. +// +#define ERROR_TOO_MANY_SECRETS 1381L + +// +// MessageId: ERROR_SECRET_TOO_LONG +// +// MessageText: +// +// The length of a secret exceeds the maximum length allowed. +// +#define ERROR_SECRET_TOO_LONG 1382L + +// +// MessageId: ERROR_INTERNAL_DB_ERROR +// +// MessageText: +// +// The local security authority database contains an internal inconsistency. +// +#define ERROR_INTERNAL_DB_ERROR 1383L + +// +// MessageId: ERROR_TOO_MANY_CONTEXT_IDS +// +// MessageText: +// +// During a logon attempt, the user's security context accumulated too many security IDs. +// +#define ERROR_TOO_MANY_CONTEXT_IDS 1384L + +// +// MessageId: ERROR_LOGON_TYPE_NOT_GRANTED +// +// MessageText: +// +// Logon failure: the user has not been granted the requested logon type at this computer. +// +#define ERROR_LOGON_TYPE_NOT_GRANTED 1385L + +// +// MessageId: ERROR_NT_CROSS_ENCRYPTION_REQUIRED +// +// MessageText: +// +// A cross-encrypted password is necessary to change a user password. +// +#define ERROR_NT_CROSS_ENCRYPTION_REQUIRED 1386L + +// +// MessageId: ERROR_NO_SUCH_MEMBER +// +// MessageText: +// +// A member could not be added to or removed from the local group because the member does not exist. +// +#define ERROR_NO_SUCH_MEMBER 1387L + +// +// MessageId: ERROR_INVALID_MEMBER +// +// MessageText: +// +// A new member could not be added to a local group because the member has the wrong account type. +// +#define ERROR_INVALID_MEMBER 1388L + +// +// MessageId: ERROR_TOO_MANY_SIDS +// +// MessageText: +// +// Too many security IDs have been specified. +// +#define ERROR_TOO_MANY_SIDS 1389L + +// +// MessageId: ERROR_LM_CROSS_ENCRYPTION_REQUIRED +// +// MessageText: +// +// A cross-encrypted password is necessary to change this user password. +// +#define ERROR_LM_CROSS_ENCRYPTION_REQUIRED 1390L + +// +// MessageId: ERROR_NO_INHERITANCE +// +// MessageText: +// +// Indicates an ACL contains no inheritable components. +// +#define ERROR_NO_INHERITANCE 1391L + +// +// MessageId: ERROR_FILE_CORRUPT +// +// MessageText: +// +// The file or directory is corrupted and unreadable. +// +#define ERROR_FILE_CORRUPT 1392L + +// +// MessageId: ERROR_DISK_CORRUPT +// +// MessageText: +// +// The disk structure is corrupted and unreadable. +// +#define ERROR_DISK_CORRUPT 1393L + +// +// MessageId: ERROR_NO_USER_SESSION_KEY +// +// MessageText: +// +// There is no user session key for the specified logon session. +// +#define ERROR_NO_USER_SESSION_KEY 1394L + +// +// MessageId: ERROR_LICENSE_QUOTA_EXCEEDED +// +// MessageText: +// +// The service being accessed is licensed for a particular number of connections. +// No more connections can be made to the service at this time because there are already as many connections as the service can accept. +// +#define ERROR_LICENSE_QUOTA_EXCEEDED 1395L + +// +// MessageId: ERROR_WRONG_TARGET_NAME +// +// MessageText: +// +// Logon Failure: The target account name is incorrect. +// +#define ERROR_WRONG_TARGET_NAME 1396L + +// +// MessageId: ERROR_MUTUAL_AUTH_FAILED +// +// MessageText: +// +// Mutual Authentication failed. The server's password is out of date at the domain controller. +// +#define ERROR_MUTUAL_AUTH_FAILED 1397L + +// +// MessageId: ERROR_TIME_SKEW +// +// MessageText: +// +// There is a time and/or date difference between the client and server. +// +#define ERROR_TIME_SKEW 1398L + +// +// MessageId: ERROR_CURRENT_DOMAIN_NOT_ALLOWED +// +// MessageText: +// +// This operation can not be performed on the current domain. +// +#define ERROR_CURRENT_DOMAIN_NOT_ALLOWED 1399L + +// End of security error codes + + + +/////////////////////////// +// // +// WinUser Error Codes // +// // +/////////////////////////// + + +// +// MessageId: ERROR_INVALID_WINDOW_HANDLE +// +// MessageText: +// +// Invalid window handle. +// +#define ERROR_INVALID_WINDOW_HANDLE 1400L + +// +// MessageId: ERROR_INVALID_MENU_HANDLE +// +// MessageText: +// +// Invalid menu handle. +// +#define ERROR_INVALID_MENU_HANDLE 1401L + +// +// MessageId: ERROR_INVALID_CURSOR_HANDLE +// +// MessageText: +// +// Invalid cursor handle. +// +#define ERROR_INVALID_CURSOR_HANDLE 1402L + +// +// MessageId: ERROR_INVALID_ACCEL_HANDLE +// +// MessageText: +// +// Invalid accelerator table handle. +// +#define ERROR_INVALID_ACCEL_HANDLE 1403L + +// +// MessageId: ERROR_INVALID_HOOK_HANDLE +// +// MessageText: +// +// Invalid hook handle. +// +#define ERROR_INVALID_HOOK_HANDLE 1404L + +// +// MessageId: ERROR_INVALID_DWP_HANDLE +// +// MessageText: +// +// Invalid handle to a multiple-window position structure. +// +#define ERROR_INVALID_DWP_HANDLE 1405L + +// +// MessageId: ERROR_TLW_WITH_WSCHILD +// +// MessageText: +// +// Cannot create a top-level child window. +// +#define ERROR_TLW_WITH_WSCHILD 1406L + +// +// MessageId: ERROR_CANNOT_FIND_WND_CLASS +// +// MessageText: +// +// Cannot find window class. +// +#define ERROR_CANNOT_FIND_WND_CLASS 1407L + +// +// MessageId: ERROR_WINDOW_OF_OTHER_THREAD +// +// MessageText: +// +// Invalid window; it belongs to other thread. +// +#define ERROR_WINDOW_OF_OTHER_THREAD 1408L + +// +// MessageId: ERROR_HOTKEY_ALREADY_REGISTERED +// +// MessageText: +// +// Hot key is already registered. +// +#define ERROR_HOTKEY_ALREADY_REGISTERED 1409L + +// +// MessageId: ERROR_CLASS_ALREADY_EXISTS +// +// MessageText: +// +// Class already exists. +// +#define ERROR_CLASS_ALREADY_EXISTS 1410L + +// +// MessageId: ERROR_CLASS_DOES_NOT_EXIST +// +// MessageText: +// +// Class does not exist. +// +#define ERROR_CLASS_DOES_NOT_EXIST 1411L + +// +// MessageId: ERROR_CLASS_HAS_WINDOWS +// +// MessageText: +// +// Class still has open windows. +// +#define ERROR_CLASS_HAS_WINDOWS 1412L + +// +// MessageId: ERROR_INVALID_INDEX +// +// MessageText: +// +// Invalid index. +// +#define ERROR_INVALID_INDEX 1413L + +// +// MessageId: ERROR_INVALID_ICON_HANDLE +// +// MessageText: +// +// Invalid icon handle. +// +#define ERROR_INVALID_ICON_HANDLE 1414L + +// +// MessageId: ERROR_PRIVATE_DIALOG_INDEX +// +// MessageText: +// +// Using private DIALOG window words. +// +#define ERROR_PRIVATE_DIALOG_INDEX 1415L + +// +// MessageId: ERROR_LISTBOX_ID_NOT_FOUND +// +// MessageText: +// +// The list box identifier was not found. +// +#define ERROR_LISTBOX_ID_NOT_FOUND 1416L + +// +// MessageId: ERROR_NO_WILDCARD_CHARACTERS +// +// MessageText: +// +// No wildcards were found. +// +#define ERROR_NO_WILDCARD_CHARACTERS 1417L + +// +// MessageId: ERROR_CLIPBOARD_NOT_OPEN +// +// MessageText: +// +// Thread does not have a clipboard open. +// +#define ERROR_CLIPBOARD_NOT_OPEN 1418L + +// +// MessageId: ERROR_HOTKEY_NOT_REGISTERED +// +// MessageText: +// +// Hot key is not registered. +// +#define ERROR_HOTKEY_NOT_REGISTERED 1419L + +// +// MessageId: ERROR_WINDOW_NOT_DIALOG +// +// MessageText: +// +// The window is not a valid dialog window. +// +#define ERROR_WINDOW_NOT_DIALOG 1420L + +// +// MessageId: ERROR_CONTROL_ID_NOT_FOUND +// +// MessageText: +// +// Control ID not found. +// +#define ERROR_CONTROL_ID_NOT_FOUND 1421L + +// +// MessageId: ERROR_INVALID_COMBOBOX_MESSAGE +// +// MessageText: +// +// Invalid message for a combo box because it does not have an edit control. +// +#define ERROR_INVALID_COMBOBOX_MESSAGE 1422L + +// +// MessageId: ERROR_WINDOW_NOT_COMBOBOX +// +// MessageText: +// +// The window is not a combo box. +// +#define ERROR_WINDOW_NOT_COMBOBOX 1423L + +// +// MessageId: ERROR_INVALID_EDIT_HEIGHT +// +// MessageText: +// +// Height must be less than 256. +// +#define ERROR_INVALID_EDIT_HEIGHT 1424L + +// +// MessageId: ERROR_DC_NOT_FOUND +// +// MessageText: +// +// Invalid device context (DC) handle. +// +#define ERROR_DC_NOT_FOUND 1425L + +// +// MessageId: ERROR_INVALID_HOOK_FILTER +// +// MessageText: +// +// Invalid hook procedure type. +// +#define ERROR_INVALID_HOOK_FILTER 1426L + +// +// MessageId: ERROR_INVALID_FILTER_PROC +// +// MessageText: +// +// Invalid hook procedure. +// +#define ERROR_INVALID_FILTER_PROC 1427L + +// +// MessageId: ERROR_HOOK_NEEDS_HMOD +// +// MessageText: +// +// Cannot set nonlocal hook without a module handle. +// +#define ERROR_HOOK_NEEDS_HMOD 1428L + +// +// MessageId: ERROR_GLOBAL_ONLY_HOOK +// +// MessageText: +// +// This hook procedure can only be set globally. +// +#define ERROR_GLOBAL_ONLY_HOOK 1429L + +// +// MessageId: ERROR_JOURNAL_HOOK_SET +// +// MessageText: +// +// The journal hook procedure is already installed. +// +#define ERROR_JOURNAL_HOOK_SET 1430L + +// +// MessageId: ERROR_HOOK_NOT_INSTALLED +// +// MessageText: +// +// The hook procedure is not installed. +// +#define ERROR_HOOK_NOT_INSTALLED 1431L + +// +// MessageId: ERROR_INVALID_LB_MESSAGE +// +// MessageText: +// +// Invalid message for single-selection list box. +// +#define ERROR_INVALID_LB_MESSAGE 1432L + +// +// MessageId: ERROR_SETCOUNT_ON_BAD_LB +// +// MessageText: +// +// LB_SETCOUNT sent to non-lazy list box. +// +#define ERROR_SETCOUNT_ON_BAD_LB 1433L + +// +// MessageId: ERROR_LB_WITHOUT_TABSTOPS +// +// MessageText: +// +// This list box does not support tab stops. +// +#define ERROR_LB_WITHOUT_TABSTOPS 1434L + +// +// MessageId: ERROR_DESTROY_OBJECT_OF_OTHER_THREAD +// +// MessageText: +// +// Cannot destroy object created by another thread. +// +#define ERROR_DESTROY_OBJECT_OF_OTHER_THREAD 1435L + +// +// MessageId: ERROR_CHILD_WINDOW_MENU +// +// MessageText: +// +// Child windows cannot have menus. +// +#define ERROR_CHILD_WINDOW_MENU 1436L + +// +// MessageId: ERROR_NO_SYSTEM_MENU +// +// MessageText: +// +// The window does not have a system menu. +// +#define ERROR_NO_SYSTEM_MENU 1437L + +// +// MessageId: ERROR_INVALID_MSGBOX_STYLE +// +// MessageText: +// +// Invalid message box style. +// +#define ERROR_INVALID_MSGBOX_STYLE 1438L + +// +// MessageId: ERROR_INVALID_SPI_VALUE +// +// MessageText: +// +// Invalid system-wide (SPI_*) parameter. +// +#define ERROR_INVALID_SPI_VALUE 1439L + +// +// MessageId: ERROR_SCREEN_ALREADY_LOCKED +// +// MessageText: +// +// Screen already locked. +// +#define ERROR_SCREEN_ALREADY_LOCKED 1440L + +// +// MessageId: ERROR_HWNDS_HAVE_DIFF_PARENT +// +// MessageText: +// +// All handles to windows in a multiple-window position structure must have the same parent. +// +#define ERROR_HWNDS_HAVE_DIFF_PARENT 1441L + +// +// MessageId: ERROR_NOT_CHILD_WINDOW +// +// MessageText: +// +// The window is not a child window. +// +#define ERROR_NOT_CHILD_WINDOW 1442L + +// +// MessageId: ERROR_INVALID_GW_COMMAND +// +// MessageText: +// +// Invalid GW_* command. +// +#define ERROR_INVALID_GW_COMMAND 1443L + +// +// MessageId: ERROR_INVALID_THREAD_ID +// +// MessageText: +// +// Invalid thread identifier. +// +#define ERROR_INVALID_THREAD_ID 1444L + +// +// MessageId: ERROR_NON_MDICHILD_WINDOW +// +// MessageText: +// +// Cannot process a message from a window that is not a multiple document interface (MDI) window. +// +#define ERROR_NON_MDICHILD_WINDOW 1445L + +// +// MessageId: ERROR_POPUP_ALREADY_ACTIVE +// +// MessageText: +// +// Popup menu already active. +// +#define ERROR_POPUP_ALREADY_ACTIVE 1446L + +// +// MessageId: ERROR_NO_SCROLLBARS +// +// MessageText: +// +// The window does not have scroll bars. +// +#define ERROR_NO_SCROLLBARS 1447L + +// +// MessageId: ERROR_INVALID_SCROLLBAR_RANGE +// +// MessageText: +// +// Scroll bar range cannot be greater than MAXLONG. +// +#define ERROR_INVALID_SCROLLBAR_RANGE 1448L + +// +// MessageId: ERROR_INVALID_SHOWWIN_COMMAND +// +// MessageText: +// +// Cannot show or remove the window in the way specified. +// +#define ERROR_INVALID_SHOWWIN_COMMAND 1449L + +// +// MessageId: ERROR_NO_SYSTEM_RESOURCES +// +// MessageText: +// +// Insufficient system resources exist to complete the requested service. +// +#define ERROR_NO_SYSTEM_RESOURCES 1450L + +// +// MessageId: ERROR_NONPAGED_SYSTEM_RESOURCES +// +// MessageText: +// +// Insufficient system resources exist to complete the requested service. +// +#define ERROR_NONPAGED_SYSTEM_RESOURCES 1451L + +// +// MessageId: ERROR_PAGED_SYSTEM_RESOURCES +// +// MessageText: +// +// Insufficient system resources exist to complete the requested service. +// +#define ERROR_PAGED_SYSTEM_RESOURCES 1452L + +// +// MessageId: ERROR_WORKING_SET_QUOTA +// +// MessageText: +// +// Insufficient quota to complete the requested service. +// +#define ERROR_WORKING_SET_QUOTA 1453L + +// +// MessageId: ERROR_PAGEFILE_QUOTA +// +// MessageText: +// +// Insufficient quota to complete the requested service. +// +#define ERROR_PAGEFILE_QUOTA 1454L + +// +// MessageId: ERROR_COMMITMENT_LIMIT +// +// MessageText: +// +// The paging file is too small for this operation to complete. +// +#define ERROR_COMMITMENT_LIMIT 1455L + +// +// MessageId: ERROR_MENU_ITEM_NOT_FOUND +// +// MessageText: +// +// A menu item was not found. +// +#define ERROR_MENU_ITEM_NOT_FOUND 1456L + +// +// MessageId: ERROR_INVALID_KEYBOARD_HANDLE +// +// MessageText: +// +// Invalid keyboard layout handle. +// +#define ERROR_INVALID_KEYBOARD_HANDLE 1457L + +// +// MessageId: ERROR_HOOK_TYPE_NOT_ALLOWED +// +// MessageText: +// +// Hook type not allowed. +// +#define ERROR_HOOK_TYPE_NOT_ALLOWED 1458L + +// +// MessageId: ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION +// +// MessageText: +// +// This operation requires an interactive window station. +// +#define ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION 1459L + +// +// MessageId: ERROR_TIMEOUT +// +// MessageText: +// +// This operation returned because the timeout period expired. +// +#define ERROR_TIMEOUT 1460L + +// +// MessageId: ERROR_INVALID_MONITOR_HANDLE +// +// MessageText: +// +// Invalid monitor handle. +// +#define ERROR_INVALID_MONITOR_HANDLE 1461L + +// +// MessageId: ERROR_INCORRECT_SIZE +// +// MessageText: +// +// Incorrect size argument. +// +#define ERROR_INCORRECT_SIZE 1462L + +// End of WinUser error codes + + + +/////////////////////////// +// // +// Eventlog Status Codes // +// // +/////////////////////////// + + +// +// MessageId: ERROR_EVENTLOG_FILE_CORRUPT +// +// MessageText: +// +// The event log file is corrupted. +// +#define ERROR_EVENTLOG_FILE_CORRUPT 1500L + +// +// MessageId: ERROR_EVENTLOG_CANT_START +// +// MessageText: +// +// No event log file could be opened, so the event logging service did not start. +// +#define ERROR_EVENTLOG_CANT_START 1501L + +// +// MessageId: ERROR_LOG_FILE_FULL +// +// MessageText: +// +// The event log file is full. +// +#define ERROR_LOG_FILE_FULL 1502L + +// +// MessageId: ERROR_EVENTLOG_FILE_CHANGED +// +// MessageText: +// +// The event log file has changed between read operations. +// +#define ERROR_EVENTLOG_FILE_CHANGED 1503L + +// End of eventlog error codes + + + +/////////////////////////// +// // +// MSI Error Codes // +// // +/////////////////////////// + + +// +// MessageId: ERROR_INSTALL_SERVICE_FAILURE +// +// MessageText: +// +// The Windows Installer Service could not be accessed. This can occur if you are running Windows in safe mode, or if the Windows Installer is not correctly installed. Contact your support personnel for assistance. +// +#define ERROR_INSTALL_SERVICE_FAILURE 1601L + +// +// MessageId: ERROR_INSTALL_USEREXIT +// +// MessageText: +// +// User cancelled installation. +// +#define ERROR_INSTALL_USEREXIT 1602L + +// +// MessageId: ERROR_INSTALL_FAILURE +// +// MessageText: +// +// Fatal error during installation. +// +#define ERROR_INSTALL_FAILURE 1603L + +// +// MessageId: ERROR_INSTALL_SUSPEND +// +// MessageText: +// +// Installation suspended, incomplete. +// +#define ERROR_INSTALL_SUSPEND 1604L + +// +// MessageId: ERROR_UNKNOWN_PRODUCT +// +// MessageText: +// +// This action is only valid for products that are currently installed. +// +#define ERROR_UNKNOWN_PRODUCT 1605L + +// +// MessageId: ERROR_UNKNOWN_FEATURE +// +// MessageText: +// +// Feature ID not registered. +// +#define ERROR_UNKNOWN_FEATURE 1606L + +// +// MessageId: ERROR_UNKNOWN_COMPONENT +// +// MessageText: +// +// Component ID not registered. +// +#define ERROR_UNKNOWN_COMPONENT 1607L + +// +// MessageId: ERROR_UNKNOWN_PROPERTY +// +// MessageText: +// +// Unknown property. +// +#define ERROR_UNKNOWN_PROPERTY 1608L + +// +// MessageId: ERROR_INVALID_HANDLE_STATE +// +// MessageText: +// +// Handle is in an invalid state. +// +#define ERROR_INVALID_HANDLE_STATE 1609L + +// +// MessageId: ERROR_BAD_CONFIGURATION +// +// MessageText: +// +// The configuration data for this product is corrupt. Contact your support personnel. +// +#define ERROR_BAD_CONFIGURATION 1610L + +// +// MessageId: ERROR_INDEX_ABSENT +// +// MessageText: +// +// Component qualifier not present. +// +#define ERROR_INDEX_ABSENT 1611L + +// +// MessageId: ERROR_INSTALL_SOURCE_ABSENT +// +// MessageText: +// +// The installation source for this product is not available. Verify that the source exists and that you can access it. +// +#define ERROR_INSTALL_SOURCE_ABSENT 1612L + +// +// MessageId: ERROR_INSTALL_PACKAGE_VERSION +// +// MessageText: +// +// This installation package cannot be installed by the Windows Installer service. You must install a Windows service pack that contains a newer version of the Windows Installer service. +// +#define ERROR_INSTALL_PACKAGE_VERSION 1613L + +// +// MessageId: ERROR_PRODUCT_UNINSTALLED +// +// MessageText: +// +// Product is uninstalled. +// +#define ERROR_PRODUCT_UNINSTALLED 1614L + +// +// MessageId: ERROR_BAD_QUERY_SYNTAX +// +// MessageText: +// +// SQL query syntax invalid or unsupported. +// +#define ERROR_BAD_QUERY_SYNTAX 1615L + +// +// MessageId: ERROR_INVALID_FIELD +// +// MessageText: +// +// Record field does not exist. +// +#define ERROR_INVALID_FIELD 1616L + +// +// MessageId: ERROR_DEVICE_REMOVED +// +// MessageText: +// +// The device has been removed. +// +#define ERROR_DEVICE_REMOVED 1617L + +// +// MessageId: ERROR_INSTALL_ALREADY_RUNNING +// +// MessageText: +// +// Another installation is already in progress. Complete that installation before proceeding with this install. +// +#define ERROR_INSTALL_ALREADY_RUNNING 1618L + +// +// MessageId: ERROR_INSTALL_PACKAGE_OPEN_FAILED +// +// MessageText: +// +// This installation package could not be opened. Verify that the package exists and that you can access it, or contact the application vendor to verify that this is a valid Windows Installer package. +// +#define ERROR_INSTALL_PACKAGE_OPEN_FAILED 1619L + +// +// MessageId: ERROR_INSTALL_PACKAGE_INVALID +// +// MessageText: +// +// This installation package could not be opened. Contact the application vendor to verify that this is a valid Windows Installer package. +// +#define ERROR_INSTALL_PACKAGE_INVALID 1620L + +// +// MessageId: ERROR_INSTALL_UI_FAILURE +// +// MessageText: +// +// There was an error starting the Windows Installer service user interface. Contact your support personnel. +// +#define ERROR_INSTALL_UI_FAILURE 1621L + +// +// MessageId: ERROR_INSTALL_LOG_FAILURE +// +// MessageText: +// +// Error opening installation log file. Verify that the specified log file location exists and that you can write to it. +// +#define ERROR_INSTALL_LOG_FAILURE 1622L + +// +// MessageId: ERROR_INSTALL_LANGUAGE_UNSUPPORTED +// +// MessageText: +// +// The language of this installation package is not supported by your system. +// +#define ERROR_INSTALL_LANGUAGE_UNSUPPORTED 1623L + +// +// MessageId: ERROR_INSTALL_TRANSFORM_FAILURE +// +// MessageText: +// +// Error applying transforms. Verify that the specified transform paths are valid. +// +#define ERROR_INSTALL_TRANSFORM_FAILURE 1624L + +// +// MessageId: ERROR_INSTALL_PACKAGE_REJECTED +// +// MessageText: +// +// This installation is forbidden by system policy. Contact your system administrator. +// +#define ERROR_INSTALL_PACKAGE_REJECTED 1625L + +// +// MessageId: ERROR_FUNCTION_NOT_CALLED +// +// MessageText: +// +// Function could not be executed. +// +#define ERROR_FUNCTION_NOT_CALLED 1626L + +// +// MessageId: ERROR_FUNCTION_FAILED +// +// MessageText: +// +// Function failed during execution. +// +#define ERROR_FUNCTION_FAILED 1627L + +// +// MessageId: ERROR_INVALID_TABLE +// +// MessageText: +// +// Invalid or unknown table specified. +// +#define ERROR_INVALID_TABLE 1628L + +// +// MessageId: ERROR_DATATYPE_MISMATCH +// +// MessageText: +// +// Data supplied is of wrong type. +// +#define ERROR_DATATYPE_MISMATCH 1629L + +// +// MessageId: ERROR_UNSUPPORTED_TYPE +// +// MessageText: +// +// Data of this type is not supported. +// +#define ERROR_UNSUPPORTED_TYPE 1630L + +// +// MessageId: ERROR_CREATE_FAILED +// +// MessageText: +// +// The Windows Installer service failed to start. Contact your support personnel. +// +#define ERROR_CREATE_FAILED 1631L + +// +// MessageId: ERROR_INSTALL_TEMP_UNWRITABLE +// +// MessageText: +// +// The Temp folder is on a drive that is full or is inaccessible. Free up space on the drive or verify that you have write permission on the Temp folder. +// +#define ERROR_INSTALL_TEMP_UNWRITABLE 1632L + +// +// MessageId: ERROR_INSTALL_PLATFORM_UNSUPPORTED +// +// MessageText: +// +// This installation package is not supported by this processor type. Contact your product vendor. +// +#define ERROR_INSTALL_PLATFORM_UNSUPPORTED 1633L + +// +// MessageId: ERROR_INSTALL_NOTUSED +// +// MessageText: +// +// Component not used on this computer. +// +#define ERROR_INSTALL_NOTUSED 1634L + +// +// MessageId: ERROR_PATCH_PACKAGE_OPEN_FAILED +// +// MessageText: +// +// This patch package could not be opened. Verify that the patch package exists and that you can access it, or contact the application vendor to verify that this is a valid Windows Installer patch package. +// +#define ERROR_PATCH_PACKAGE_OPEN_FAILED 1635L + +// +// MessageId: ERROR_PATCH_PACKAGE_INVALID +// +// MessageText: +// +// This patch package could not be opened. Contact the application vendor to verify that this is a valid Windows Installer patch package. +// +#define ERROR_PATCH_PACKAGE_INVALID 1636L + +// +// MessageId: ERROR_PATCH_PACKAGE_UNSUPPORTED +// +// MessageText: +// +// This patch package cannot be processed by the Windows Installer service. You must install a Windows service pack that contains a newer version of the Windows Installer service. +// +#define ERROR_PATCH_PACKAGE_UNSUPPORTED 1637L + +// +// MessageId: ERROR_PRODUCT_VERSION +// +// MessageText: +// +// Another version of this product is already installed. Installation of this version cannot continue. To configure or remove the existing version of this product, use Add/Remove Programs on the Control Panel. +// +#define ERROR_PRODUCT_VERSION 1638L + +// +// MessageId: ERROR_INVALID_COMMAND_LINE +// +// MessageText: +// +// Invalid command line argument. Consult the Windows Installer SDK for detailed command line help. +// +#define ERROR_INVALID_COMMAND_LINE 1639L + +// +// MessageId: ERROR_INSTALL_REMOTE_DISALLOWED +// +// MessageText: +// +// Only administrators have permission to add, remove, or configure server software during a Terminal services remote session. If you want to install or configure software on the server, contact your network administrator. +// +#define ERROR_INSTALL_REMOTE_DISALLOWED 1640L + +// +// MessageId: ERROR_SUCCESS_REBOOT_INITIATED +// +// MessageText: +// +// The requested operation completed successfully. The system will be restarted so the changes can take effect. +// +#define ERROR_SUCCESS_REBOOT_INITIATED 1641L + +// +// MessageId: ERROR_PATCH_TARGET_NOT_FOUND +// +// MessageText: +// +// The upgrade patch cannot be installed by the Windows Installer service because the program to be upgraded may be missing, or the upgrade patch may update a different version of the program. Verify that the program to be upgraded exists on your computer an +// d that you have the correct upgrade patch. +// +#define ERROR_PATCH_TARGET_NOT_FOUND 1642L + +// +// MessageId: ERROR_PATCH_PACKAGE_REJECTED +// +// MessageText: +// +// The patch package is not permitted by software restriction policy. +// +#define ERROR_PATCH_PACKAGE_REJECTED 1643L + +// +// MessageId: ERROR_INSTALL_TRANSFORM_REJECTED +// +// MessageText: +// +// One or more customizations are not permitted by software restriction policy. +// +#define ERROR_INSTALL_TRANSFORM_REJECTED 1644L + +// +// MessageId: ERROR_INSTALL_REMOTE_PROHIBITED +// +// MessageText: +// +// The Windows Installer does not permit installation from a Remote Desktop Connection. +// +#define ERROR_INSTALL_REMOTE_PROHIBITED 1645L + +// End of MSI error codes + + + +/////////////////////////// +// // +// RPC Status Codes // +// // +/////////////////////////// + + +// +// MessageId: RPC_S_INVALID_STRING_BINDING +// +// MessageText: +// +// The string binding is invalid. +// +#define RPC_S_INVALID_STRING_BINDING 1700L + +// +// MessageId: RPC_S_WRONG_KIND_OF_BINDING +// +// MessageText: +// +// The binding handle is not the correct type. +// +#define RPC_S_WRONG_KIND_OF_BINDING 1701L + +// +// MessageId: RPC_S_INVALID_BINDING +// +// MessageText: +// +// The binding handle is invalid. +// +#define RPC_S_INVALID_BINDING 1702L + +// +// MessageId: RPC_S_PROTSEQ_NOT_SUPPORTED +// +// MessageText: +// +// The RPC protocol sequence is not supported. +// +#define RPC_S_PROTSEQ_NOT_SUPPORTED 1703L + +// +// MessageId: RPC_S_INVALID_RPC_PROTSEQ +// +// MessageText: +// +// The RPC protocol sequence is invalid. +// +#define RPC_S_INVALID_RPC_PROTSEQ 1704L + +// +// MessageId: RPC_S_INVALID_STRING_UUID +// +// MessageText: +// +// The string universal unique identifier (UUID) is invalid. +// +#define RPC_S_INVALID_STRING_UUID 1705L + +// +// MessageId: RPC_S_INVALID_ENDPOINT_FORMAT +// +// MessageText: +// +// The endpoint format is invalid. +// +#define RPC_S_INVALID_ENDPOINT_FORMAT 1706L + +// +// MessageId: RPC_S_INVALID_NET_ADDR +// +// MessageText: +// +// The network address is invalid. +// +#define RPC_S_INVALID_NET_ADDR 1707L + +// +// MessageId: RPC_S_NO_ENDPOINT_FOUND +// +// MessageText: +// +// No endpoint was found. +// +#define RPC_S_NO_ENDPOINT_FOUND 1708L + +// +// MessageId: RPC_S_INVALID_TIMEOUT +// +// MessageText: +// +// The timeout value is invalid. +// +#define RPC_S_INVALID_TIMEOUT 1709L + +// +// MessageId: RPC_S_OBJECT_NOT_FOUND +// +// MessageText: +// +// The object universal unique identifier (UUID) was not found. +// +#define RPC_S_OBJECT_NOT_FOUND 1710L + +// +// MessageId: RPC_S_ALREADY_REGISTERED +// +// MessageText: +// +// The object universal unique identifier (UUID) has already been registered. +// +#define RPC_S_ALREADY_REGISTERED 1711L + +// +// MessageId: RPC_S_TYPE_ALREADY_REGISTERED +// +// MessageText: +// +// The type universal unique identifier (UUID) has already been registered. +// +#define RPC_S_TYPE_ALREADY_REGISTERED 1712L + +// +// MessageId: RPC_S_ALREADY_LISTENING +// +// MessageText: +// +// The RPC server is already listening. +// +#define RPC_S_ALREADY_LISTENING 1713L + +// +// MessageId: RPC_S_NO_PROTSEQS_REGISTERED +// +// MessageText: +// +// No protocol sequences have been registered. +// +#define RPC_S_NO_PROTSEQS_REGISTERED 1714L + +// +// MessageId: RPC_S_NOT_LISTENING +// +// MessageText: +// +// The RPC server is not listening. +// +#define RPC_S_NOT_LISTENING 1715L + +// +// MessageId: RPC_S_UNKNOWN_MGR_TYPE +// +// MessageText: +// +// The manager type is unknown. +// +#define RPC_S_UNKNOWN_MGR_TYPE 1716L + +// +// MessageId: RPC_S_UNKNOWN_IF +// +// MessageText: +// +// The interface is unknown. +// +#define RPC_S_UNKNOWN_IF 1717L + +// +// MessageId: RPC_S_NO_BINDINGS +// +// MessageText: +// +// There are no bindings. +// +#define RPC_S_NO_BINDINGS 1718L + +// +// MessageId: RPC_S_NO_PROTSEQS +// +// MessageText: +// +// There are no protocol sequences. +// +#define RPC_S_NO_PROTSEQS 1719L + +// +// MessageId: RPC_S_CANT_CREATE_ENDPOINT +// +// MessageText: +// +// The endpoint cannot be created. +// +#define RPC_S_CANT_CREATE_ENDPOINT 1720L + +// +// MessageId: RPC_S_OUT_OF_RESOURCES +// +// MessageText: +// +// Not enough resources are available to complete this operation. +// +#define RPC_S_OUT_OF_RESOURCES 1721L + +// +// MessageId: RPC_S_SERVER_UNAVAILABLE +// +// MessageText: +// +// The RPC server is unavailable. +// +#define RPC_S_SERVER_UNAVAILABLE 1722L + +// +// MessageId: RPC_S_SERVER_TOO_BUSY +// +// MessageText: +// +// The RPC server is too busy to complete this operation. +// +#define RPC_S_SERVER_TOO_BUSY 1723L + +// +// MessageId: RPC_S_INVALID_NETWORK_OPTIONS +// +// MessageText: +// +// The network options are invalid. +// +#define RPC_S_INVALID_NETWORK_OPTIONS 1724L + +// +// MessageId: RPC_S_NO_CALL_ACTIVE +// +// MessageText: +// +// There are no remote procedure calls active on this thread. +// +#define RPC_S_NO_CALL_ACTIVE 1725L + +// +// MessageId: RPC_S_CALL_FAILED +// +// MessageText: +// +// The remote procedure call failed. +// +#define RPC_S_CALL_FAILED 1726L + +// +// MessageId: RPC_S_CALL_FAILED_DNE +// +// MessageText: +// +// The remote procedure call failed and did not execute. +// +#define RPC_S_CALL_FAILED_DNE 1727L + +// +// MessageId: RPC_S_PROTOCOL_ERROR +// +// MessageText: +// +// A remote procedure call (RPC) protocol error occurred. +// +#define RPC_S_PROTOCOL_ERROR 1728L + +// +// MessageId: RPC_S_UNSUPPORTED_TRANS_SYN +// +// MessageText: +// +// The transfer syntax is not supported by the RPC server. +// +#define RPC_S_UNSUPPORTED_TRANS_SYN 1730L + +// +// MessageId: RPC_S_UNSUPPORTED_TYPE +// +// MessageText: +// +// The universal unique identifier (UUID) type is not supported. +// +#define RPC_S_UNSUPPORTED_TYPE 1732L + +// +// MessageId: RPC_S_INVALID_TAG +// +// MessageText: +// +// The tag is invalid. +// +#define RPC_S_INVALID_TAG 1733L + +// +// MessageId: RPC_S_INVALID_BOUND +// +// MessageText: +// +// The array bounds are invalid. +// +#define RPC_S_INVALID_BOUND 1734L + +// +// MessageId: RPC_S_NO_ENTRY_NAME +// +// MessageText: +// +// The binding does not contain an entry name. +// +#define RPC_S_NO_ENTRY_NAME 1735L + +// +// MessageId: RPC_S_INVALID_NAME_SYNTAX +// +// MessageText: +// +// The name syntax is invalid. +// +#define RPC_S_INVALID_NAME_SYNTAX 1736L + +// +// MessageId: RPC_S_UNSUPPORTED_NAME_SYNTAX +// +// MessageText: +// +// The name syntax is not supported. +// +#define RPC_S_UNSUPPORTED_NAME_SYNTAX 1737L + +// +// MessageId: RPC_S_UUID_NO_ADDRESS +// +// MessageText: +// +// No network address is available to use to construct a universal unique identifier (UUID). +// +#define RPC_S_UUID_NO_ADDRESS 1739L + +// +// MessageId: RPC_S_DUPLICATE_ENDPOINT +// +// MessageText: +// +// The endpoint is a duplicate. +// +#define RPC_S_DUPLICATE_ENDPOINT 1740L + +// +// MessageId: RPC_S_UNKNOWN_AUTHN_TYPE +// +// MessageText: +// +// The authentication type is unknown. +// +#define RPC_S_UNKNOWN_AUTHN_TYPE 1741L + +// +// MessageId: RPC_S_MAX_CALLS_TOO_SMALL +// +// MessageText: +// +// The maximum number of calls is too small. +// +#define RPC_S_MAX_CALLS_TOO_SMALL 1742L + +// +// MessageId: RPC_S_STRING_TOO_LONG +// +// MessageText: +// +// The string is too long. +// +#define RPC_S_STRING_TOO_LONG 1743L + +// +// MessageId: RPC_S_PROTSEQ_NOT_FOUND +// +// MessageText: +// +// The RPC protocol sequence was not found. +// +#define RPC_S_PROTSEQ_NOT_FOUND 1744L + +// +// MessageId: RPC_S_PROCNUM_OUT_OF_RANGE +// +// MessageText: +// +// The procedure number is out of range. +// +#define RPC_S_PROCNUM_OUT_OF_RANGE 1745L + +// +// MessageId: RPC_S_BINDING_HAS_NO_AUTH +// +// MessageText: +// +// The binding does not contain any authentication information. +// +#define RPC_S_BINDING_HAS_NO_AUTH 1746L + +// +// MessageId: RPC_S_UNKNOWN_AUTHN_SERVICE +// +// MessageText: +// +// The authentication service is unknown. +// +#define RPC_S_UNKNOWN_AUTHN_SERVICE 1747L + +// +// MessageId: RPC_S_UNKNOWN_AUTHN_LEVEL +// +// MessageText: +// +// The authentication level is unknown. +// +#define RPC_S_UNKNOWN_AUTHN_LEVEL 1748L + +// +// MessageId: RPC_S_INVALID_AUTH_IDENTITY +// +// MessageText: +// +// The security context is invalid. +// +#define RPC_S_INVALID_AUTH_IDENTITY 1749L + +// +// MessageId: RPC_S_UNKNOWN_AUTHZ_SERVICE +// +// MessageText: +// +// The authorization service is unknown. +// +#define RPC_S_UNKNOWN_AUTHZ_SERVICE 1750L + +// +// MessageId: EPT_S_INVALID_ENTRY +// +// MessageText: +// +// The entry is invalid. +// +#define EPT_S_INVALID_ENTRY 1751L + +// +// MessageId: EPT_S_CANT_PERFORM_OP +// +// MessageText: +// +// The server endpoint cannot perform the operation. +// +#define EPT_S_CANT_PERFORM_OP 1752L + +// +// MessageId: EPT_S_NOT_REGISTERED +// +// MessageText: +// +// There are no more endpoints available from the endpoint mapper. +// +#define EPT_S_NOT_REGISTERED 1753L + +// +// MessageId: RPC_S_NOTHING_TO_EXPORT +// +// MessageText: +// +// No interfaces have been exported. +// +#define RPC_S_NOTHING_TO_EXPORT 1754L + +// +// MessageId: RPC_S_INCOMPLETE_NAME +// +// MessageText: +// +// The entry name is incomplete. +// +#define RPC_S_INCOMPLETE_NAME 1755L + +// +// MessageId: RPC_S_INVALID_VERS_OPTION +// +// MessageText: +// +// The version option is invalid. +// +#define RPC_S_INVALID_VERS_OPTION 1756L + +// +// MessageId: RPC_S_NO_MORE_MEMBERS +// +// MessageText: +// +// There are no more members. +// +#define RPC_S_NO_MORE_MEMBERS 1757L + +// +// MessageId: RPC_S_NOT_ALL_OBJS_UNEXPORTED +// +// MessageText: +// +// There is nothing to unexport. +// +#define RPC_S_NOT_ALL_OBJS_UNEXPORTED 1758L + +// +// MessageId: RPC_S_INTERFACE_NOT_FOUND +// +// MessageText: +// +// The interface was not found. +// +#define RPC_S_INTERFACE_NOT_FOUND 1759L + +// +// MessageId: RPC_S_ENTRY_ALREADY_EXISTS +// +// MessageText: +// +// The entry already exists. +// +#define RPC_S_ENTRY_ALREADY_EXISTS 1760L + +// +// MessageId: RPC_S_ENTRY_NOT_FOUND +// +// MessageText: +// +// The entry is not found. +// +#define RPC_S_ENTRY_NOT_FOUND 1761L + +// +// MessageId: RPC_S_NAME_SERVICE_UNAVAILABLE +// +// MessageText: +// +// The name service is unavailable. +// +#define RPC_S_NAME_SERVICE_UNAVAILABLE 1762L + +// +// MessageId: RPC_S_INVALID_NAF_ID +// +// MessageText: +// +// The network address family is invalid. +// +#define RPC_S_INVALID_NAF_ID 1763L + +// +// MessageId: RPC_S_CANNOT_SUPPORT +// +// MessageText: +// +// The requested operation is not supported. +// +#define RPC_S_CANNOT_SUPPORT 1764L + +// +// MessageId: RPC_S_NO_CONTEXT_AVAILABLE +// +// MessageText: +// +// No security context is available to allow impersonation. +// +#define RPC_S_NO_CONTEXT_AVAILABLE 1765L + +// +// MessageId: RPC_S_INTERNAL_ERROR +// +// MessageText: +// +// An internal error occurred in a remote procedure call (RPC). +// +#define RPC_S_INTERNAL_ERROR 1766L + +// +// MessageId: RPC_S_ZERO_DIVIDE +// +// MessageText: +// +// The RPC server attempted an integer division by zero. +// +#define RPC_S_ZERO_DIVIDE 1767L + +// +// MessageId: RPC_S_ADDRESS_ERROR +// +// MessageText: +// +// An addressing error occurred in the RPC server. +// +#define RPC_S_ADDRESS_ERROR 1768L + +// +// MessageId: RPC_S_FP_DIV_ZERO +// +// MessageText: +// +// A floating-point operation at the RPC server caused a division by zero. +// +#define RPC_S_FP_DIV_ZERO 1769L + +// +// MessageId: RPC_S_FP_UNDERFLOW +// +// MessageText: +// +// A floating-point underflow occurred at the RPC server. +// +#define RPC_S_FP_UNDERFLOW 1770L + +// +// MessageId: RPC_S_FP_OVERFLOW +// +// MessageText: +// +// A floating-point overflow occurred at the RPC server. +// +#define RPC_S_FP_OVERFLOW 1771L + +// +// MessageId: RPC_X_NO_MORE_ENTRIES +// +// MessageText: +// +// The list of RPC servers available for the binding of auto handles has been exhausted. +// +#define RPC_X_NO_MORE_ENTRIES 1772L + +// +// MessageId: RPC_X_SS_CHAR_TRANS_OPEN_FAIL +// +// MessageText: +// +// Unable to open the character translation table file. +// +#define RPC_X_SS_CHAR_TRANS_OPEN_FAIL 1773L + +// +// MessageId: RPC_X_SS_CHAR_TRANS_SHORT_FILE +// +// MessageText: +// +// The file containing the character translation table has fewer than 512 bytes. +// +#define RPC_X_SS_CHAR_TRANS_SHORT_FILE 1774L + +// +// MessageId: RPC_X_SS_IN_NULL_CONTEXT +// +// MessageText: +// +// A null context handle was passed from the client to the host during a remote procedure call. +// +#define RPC_X_SS_IN_NULL_CONTEXT 1775L + +// +// MessageId: RPC_X_SS_CONTEXT_DAMAGED +// +// MessageText: +// +// The context handle changed during a remote procedure call. +// +#define RPC_X_SS_CONTEXT_DAMAGED 1777L + +// +// MessageId: RPC_X_SS_HANDLES_MISMATCH +// +// MessageText: +// +// The binding handles passed to a remote procedure call do not match. +// +#define RPC_X_SS_HANDLES_MISMATCH 1778L + +// +// MessageId: RPC_X_SS_CANNOT_GET_CALL_HANDLE +// +// MessageText: +// +// The stub is unable to get the remote procedure call handle. +// +#define RPC_X_SS_CANNOT_GET_CALL_HANDLE 1779L + +// +// MessageId: RPC_X_NULL_REF_POINTER +// +// MessageText: +// +// A null reference pointer was passed to the stub. +// +#define RPC_X_NULL_REF_POINTER 1780L + +// +// MessageId: RPC_X_ENUM_VALUE_OUT_OF_RANGE +// +// MessageText: +// +// The enumeration value is out of range. +// +#define RPC_X_ENUM_VALUE_OUT_OF_RANGE 1781L + +// +// MessageId: RPC_X_BYTE_COUNT_TOO_SMALL +// +// MessageText: +// +// The byte count is too small. +// +#define RPC_X_BYTE_COUNT_TOO_SMALL 1782L + +// +// MessageId: RPC_X_BAD_STUB_DATA +// +// MessageText: +// +// The stub received bad data. +// +#define RPC_X_BAD_STUB_DATA 1783L + +// +// MessageId: ERROR_INVALID_USER_BUFFER +// +// MessageText: +// +// The supplied user buffer is not valid for the requested operation. +// +#define ERROR_INVALID_USER_BUFFER 1784L + +// +// MessageId: ERROR_UNRECOGNIZED_MEDIA +// +// MessageText: +// +// The disk media is not recognized. It may not be formatted. +// +#define ERROR_UNRECOGNIZED_MEDIA 1785L + +// +// MessageId: ERROR_NO_TRUST_LSA_SECRET +// +// MessageText: +// +// The workstation does not have a trust secret. +// +#define ERROR_NO_TRUST_LSA_SECRET 1786L + +// +// MessageId: ERROR_NO_TRUST_SAM_ACCOUNT +// +// MessageText: +// +// The security database on the server does not have a computer account for this workstation trust relationship. +// +#define ERROR_NO_TRUST_SAM_ACCOUNT 1787L + +// +// MessageId: ERROR_TRUSTED_DOMAIN_FAILURE +// +// MessageText: +// +// The trust relationship between the primary domain and the trusted domain failed. +// +#define ERROR_TRUSTED_DOMAIN_FAILURE 1788L + +// +// MessageId: ERROR_TRUSTED_RELATIONSHIP_FAILURE +// +// MessageText: +// +// The trust relationship between this workstation and the primary domain failed. +// +#define ERROR_TRUSTED_RELATIONSHIP_FAILURE 1789L + +// +// MessageId: ERROR_TRUST_FAILURE +// +// MessageText: +// +// The network logon failed. +// +#define ERROR_TRUST_FAILURE 1790L + +// +// MessageId: RPC_S_CALL_IN_PROGRESS +// +// MessageText: +// +// A remote procedure call is already in progress for this thread. +// +#define RPC_S_CALL_IN_PROGRESS 1791L + +// +// MessageId: ERROR_NETLOGON_NOT_STARTED +// +// MessageText: +// +// An attempt was made to logon, but the network logon service was not started. +// +#define ERROR_NETLOGON_NOT_STARTED 1792L + +// +// MessageId: ERROR_ACCOUNT_EXPIRED +// +// MessageText: +// +// The user's account has expired. +// +#define ERROR_ACCOUNT_EXPIRED 1793L + +// +// MessageId: ERROR_REDIRECTOR_HAS_OPEN_HANDLES +// +// MessageText: +// +// The redirector is in use and cannot be unloaded. +// +#define ERROR_REDIRECTOR_HAS_OPEN_HANDLES 1794L + +// +// MessageId: ERROR_PRINTER_DRIVER_ALREADY_INSTALLED +// +// MessageText: +// +// The specified printer driver is already installed. +// +#define ERROR_PRINTER_DRIVER_ALREADY_INSTALLED 1795L + +// +// MessageId: ERROR_UNKNOWN_PORT +// +// MessageText: +// +// The specified port is unknown. +// +#define ERROR_UNKNOWN_PORT 1796L + +// +// MessageId: ERROR_UNKNOWN_PRINTER_DRIVER +// +// MessageText: +// +// The printer driver is unknown. +// +#define ERROR_UNKNOWN_PRINTER_DRIVER 1797L + +// +// MessageId: ERROR_UNKNOWN_PRINTPROCESSOR +// +// MessageText: +// +// The print processor is unknown. +// +#define ERROR_UNKNOWN_PRINTPROCESSOR 1798L + +// +// MessageId: ERROR_INVALID_SEPARATOR_FILE +// +// MessageText: +// +// The specified separator file is invalid. +// +#define ERROR_INVALID_SEPARATOR_FILE 1799L + +// +// MessageId: ERROR_INVALID_PRIORITY +// +// MessageText: +// +// The specified priority is invalid. +// +#define ERROR_INVALID_PRIORITY 1800L + +// +// MessageId: ERROR_INVALID_PRINTER_NAME +// +// MessageText: +// +// The printer name is invalid. +// +#define ERROR_INVALID_PRINTER_NAME 1801L + +// +// MessageId: ERROR_PRINTER_ALREADY_EXISTS +// +// MessageText: +// +// The printer already exists. +// +#define ERROR_PRINTER_ALREADY_EXISTS 1802L + +// +// MessageId: ERROR_INVALID_PRINTER_COMMAND +// +// MessageText: +// +// The printer command is invalid. +// +#define ERROR_INVALID_PRINTER_COMMAND 1803L + +// +// MessageId: ERROR_INVALID_DATATYPE +// +// MessageText: +// +// The specified datatype is invalid. +// +#define ERROR_INVALID_DATATYPE 1804L + +// +// MessageId: ERROR_INVALID_ENVIRONMENT +// +// MessageText: +// +// The environment specified is invalid. +// +#define ERROR_INVALID_ENVIRONMENT 1805L + +// +// MessageId: RPC_S_NO_MORE_BINDINGS +// +// MessageText: +// +// There are no more bindings. +// +#define RPC_S_NO_MORE_BINDINGS 1806L + +// +// MessageId: ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT +// +// MessageText: +// +// The account used is an interdomain trust account. Use your global user account or local user account to access this server. +// +#define ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT 1807L + +// +// MessageId: ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT +// +// MessageText: +// +// The account used is a computer account. Use your global user account or local user account to access this server. +// +#define ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT 1808L + +// +// MessageId: ERROR_NOLOGON_SERVER_TRUST_ACCOUNT +// +// MessageText: +// +// The account used is a server trust account. Use your global user account or local user account to access this server. +// +#define ERROR_NOLOGON_SERVER_TRUST_ACCOUNT 1809L + +// +// MessageId: ERROR_DOMAIN_TRUST_INCONSISTENT +// +// MessageText: +// +// The name or security ID (SID) of the domain specified is inconsistent with the trust information for that domain. +// +#define ERROR_DOMAIN_TRUST_INCONSISTENT 1810L + +// +// MessageId: ERROR_SERVER_HAS_OPEN_HANDLES +// +// MessageText: +// +// The server is in use and cannot be unloaded. +// +#define ERROR_SERVER_HAS_OPEN_HANDLES 1811L + +// +// MessageId: ERROR_RESOURCE_DATA_NOT_FOUND +// +// MessageText: +// +// The specified image file did not contain a resource section. +// +#define ERROR_RESOURCE_DATA_NOT_FOUND 1812L + +// +// MessageId: ERROR_RESOURCE_TYPE_NOT_FOUND +// +// MessageText: +// +// The specified resource type cannot be found in the image file. +// +#define ERROR_RESOURCE_TYPE_NOT_FOUND 1813L + +// +// MessageId: ERROR_RESOURCE_NAME_NOT_FOUND +// +// MessageText: +// +// The specified resource name cannot be found in the image file. +// +#define ERROR_RESOURCE_NAME_NOT_FOUND 1814L + +// +// MessageId: ERROR_RESOURCE_LANG_NOT_FOUND +// +// MessageText: +// +// The specified resource language ID cannot be found in the image file. +// +#define ERROR_RESOURCE_LANG_NOT_FOUND 1815L + +// +// MessageId: ERROR_NOT_ENOUGH_QUOTA +// +// MessageText: +// +// Not enough quota is available to process this command. +// +#define ERROR_NOT_ENOUGH_QUOTA 1816L + +// +// MessageId: RPC_S_NO_INTERFACES +// +// MessageText: +// +// No interfaces have been registered. +// +#define RPC_S_NO_INTERFACES 1817L + +// +// MessageId: RPC_S_CALL_CANCELLED +// +// MessageText: +// +// The remote procedure call was cancelled. +// +#define RPC_S_CALL_CANCELLED 1818L + +// +// MessageId: RPC_S_BINDING_INCOMPLETE +// +// MessageText: +// +// The binding handle does not contain all required information. +// +#define RPC_S_BINDING_INCOMPLETE 1819L + +// +// MessageId: RPC_S_COMM_FAILURE +// +// MessageText: +// +// A communications failure occurred during a remote procedure call. +// +#define RPC_S_COMM_FAILURE 1820L + +// +// MessageId: RPC_S_UNSUPPORTED_AUTHN_LEVEL +// +// MessageText: +// +// The requested authentication level is not supported. +// +#define RPC_S_UNSUPPORTED_AUTHN_LEVEL 1821L + +// +// MessageId: RPC_S_NO_PRINC_NAME +// +// MessageText: +// +// No principal name registered. +// +#define RPC_S_NO_PRINC_NAME 1822L + +// +// MessageId: RPC_S_NOT_RPC_ERROR +// +// MessageText: +// +// The error specified is not a valid Windows RPC error code. +// +#define RPC_S_NOT_RPC_ERROR 1823L + +// +// MessageId: RPC_S_UUID_LOCAL_ONLY +// +// MessageText: +// +// A UUID that is valid only on this computer has been allocated. +// +#define RPC_S_UUID_LOCAL_ONLY 1824L + +// +// MessageId: RPC_S_SEC_PKG_ERROR +// +// MessageText: +// +// A security package specific error occurred. +// +#define RPC_S_SEC_PKG_ERROR 1825L + +// +// MessageId: RPC_S_NOT_CANCELLED +// +// MessageText: +// +// Thread is not canceled. +// +#define RPC_S_NOT_CANCELLED 1826L + +// +// MessageId: RPC_X_INVALID_ES_ACTION +// +// MessageText: +// +// Invalid operation on the encoding/decoding handle. +// +#define RPC_X_INVALID_ES_ACTION 1827L + +// +// MessageId: RPC_X_WRONG_ES_VERSION +// +// MessageText: +// +// Incompatible version of the serializing package. +// +#define RPC_X_WRONG_ES_VERSION 1828L + +// +// MessageId: RPC_X_WRONG_STUB_VERSION +// +// MessageText: +// +// Incompatible version of the RPC stub. +// +#define RPC_X_WRONG_STUB_VERSION 1829L + +// +// MessageId: RPC_X_INVALID_PIPE_OBJECT +// +// MessageText: +// +// The RPC pipe object is invalid or corrupted. +// +#define RPC_X_INVALID_PIPE_OBJECT 1830L + +// +// MessageId: RPC_X_WRONG_PIPE_ORDER +// +// MessageText: +// +// An invalid operation was attempted on an RPC pipe object. +// +#define RPC_X_WRONG_PIPE_ORDER 1831L + +// +// MessageId: RPC_X_WRONG_PIPE_VERSION +// +// MessageText: +// +// Unsupported RPC pipe version. +// +#define RPC_X_WRONG_PIPE_VERSION 1832L + +// +// MessageId: RPC_S_GROUP_MEMBER_NOT_FOUND +// +// MessageText: +// +// The group member was not found. +// +#define RPC_S_GROUP_MEMBER_NOT_FOUND 1898L + +// +// MessageId: EPT_S_CANT_CREATE +// +// MessageText: +// +// The endpoint mapper database entry could not be created. +// +#define EPT_S_CANT_CREATE 1899L + +// +// MessageId: RPC_S_INVALID_OBJECT +// +// MessageText: +// +// The object universal unique identifier (UUID) is the nil UUID. +// +#define RPC_S_INVALID_OBJECT 1900L + +// +// MessageId: ERROR_INVALID_TIME +// +// MessageText: +// +// The specified time is invalid. +// +#define ERROR_INVALID_TIME 1901L + +// +// MessageId: ERROR_INVALID_FORM_NAME +// +// MessageText: +// +// The specified form name is invalid. +// +#define ERROR_INVALID_FORM_NAME 1902L + +// +// MessageId: ERROR_INVALID_FORM_SIZE +// +// MessageText: +// +// The specified form size is invalid. +// +#define ERROR_INVALID_FORM_SIZE 1903L + +// +// MessageId: ERROR_ALREADY_WAITING +// +// MessageText: +// +// The specified printer handle is already being waited on +// +#define ERROR_ALREADY_WAITING 1904L + +// +// MessageId: ERROR_PRINTER_DELETED +// +// MessageText: +// +// The specified printer has been deleted. +// +#define ERROR_PRINTER_DELETED 1905L + +// +// MessageId: ERROR_INVALID_PRINTER_STATE +// +// MessageText: +// +// The state of the printer is invalid. +// +#define ERROR_INVALID_PRINTER_STATE 1906L + +// +// MessageId: ERROR_PASSWORD_MUST_CHANGE +// +// MessageText: +// +// The user's password must be changed before logging on the first time. +// +#define ERROR_PASSWORD_MUST_CHANGE 1907L + +// +// MessageId: ERROR_DOMAIN_CONTROLLER_NOT_FOUND +// +// MessageText: +// +// Could not find the domain controller for this domain. +// +#define ERROR_DOMAIN_CONTROLLER_NOT_FOUND 1908L + +// +// MessageId: ERROR_ACCOUNT_LOCKED_OUT +// +// MessageText: +// +// The referenced account is currently locked out and may not be logged on to. +// +#define ERROR_ACCOUNT_LOCKED_OUT 1909L + +// +// MessageId: OR_INVALID_OXID +// +// MessageText: +// +// The object exporter specified was not found. +// +#define OR_INVALID_OXID 1910L + +// +// MessageId: OR_INVALID_OID +// +// MessageText: +// +// The object specified was not found. +// +#define OR_INVALID_OID 1911L + +// +// MessageId: OR_INVALID_SET +// +// MessageText: +// +// The object resolver set specified was not found. +// +#define OR_INVALID_SET 1912L + +// +// MessageId: RPC_S_SEND_INCOMPLETE +// +// MessageText: +// +// Some data remains to be sent in the request buffer. +// +#define RPC_S_SEND_INCOMPLETE 1913L + +// +// MessageId: RPC_S_INVALID_ASYNC_HANDLE +// +// MessageText: +// +// Invalid asynchronous remote procedure call handle. +// +#define RPC_S_INVALID_ASYNC_HANDLE 1914L + +// +// MessageId: RPC_S_INVALID_ASYNC_CALL +// +// MessageText: +// +// Invalid asynchronous RPC call handle for this operation. +// +#define RPC_S_INVALID_ASYNC_CALL 1915L + +// +// MessageId: RPC_X_PIPE_CLOSED +// +// MessageText: +// +// The RPC pipe object has already been closed. +// +#define RPC_X_PIPE_CLOSED 1916L + +// +// MessageId: RPC_X_PIPE_DISCIPLINE_ERROR +// +// MessageText: +// +// The RPC call completed before all pipes were processed. +// +#define RPC_X_PIPE_DISCIPLINE_ERROR 1917L + +// +// MessageId: RPC_X_PIPE_EMPTY +// +// MessageText: +// +// No more data is available from the RPC pipe. +// +#define RPC_X_PIPE_EMPTY 1918L + +// +// MessageId: ERROR_NO_SITENAME +// +// MessageText: +// +// No site name is available for this machine. +// +#define ERROR_NO_SITENAME 1919L + +// +// MessageId: ERROR_CANT_ACCESS_FILE +// +// MessageText: +// +// The file can not be accessed by the system. +// +#define ERROR_CANT_ACCESS_FILE 1920L + +// +// MessageId: ERROR_CANT_RESOLVE_FILENAME +// +// MessageText: +// +// The name of the file cannot be resolved by the system. +// +#define ERROR_CANT_RESOLVE_FILENAME 1921L + +// +// MessageId: RPC_S_ENTRY_TYPE_MISMATCH +// +// MessageText: +// +// The entry is not of the expected type. +// +#define RPC_S_ENTRY_TYPE_MISMATCH 1922L + +// +// MessageId: RPC_S_NOT_ALL_OBJS_EXPORTED +// +// MessageText: +// +// Not all object UUIDs could be exported to the specified entry. +// +#define RPC_S_NOT_ALL_OBJS_EXPORTED 1923L + +// +// MessageId: RPC_S_INTERFACE_NOT_EXPORTED +// +// MessageText: +// +// Interface could not be exported to the specified entry. +// +#define RPC_S_INTERFACE_NOT_EXPORTED 1924L + +// +// MessageId: RPC_S_PROFILE_NOT_ADDED +// +// MessageText: +// +// The specified profile entry could not be added. +// +#define RPC_S_PROFILE_NOT_ADDED 1925L + +// +// MessageId: RPC_S_PRF_ELT_NOT_ADDED +// +// MessageText: +// +// The specified profile element could not be added. +// +#define RPC_S_PRF_ELT_NOT_ADDED 1926L + +// +// MessageId: RPC_S_PRF_ELT_NOT_REMOVED +// +// MessageText: +// +// The specified profile element could not be removed. +// +#define RPC_S_PRF_ELT_NOT_REMOVED 1927L + +// +// MessageId: RPC_S_GRP_ELT_NOT_ADDED +// +// MessageText: +// +// The group element could not be added. +// +#define RPC_S_GRP_ELT_NOT_ADDED 1928L + +// +// MessageId: RPC_S_GRP_ELT_NOT_REMOVED +// +// MessageText: +// +// The group element could not be removed. +// +#define RPC_S_GRP_ELT_NOT_REMOVED 1929L + +// +// MessageId: ERROR_KM_DRIVER_BLOCKED +// +// MessageText: +// +// The printer driver is not compatible with a policy enabled on your computer that blocks NT 4.0 drivers. +// +#define ERROR_KM_DRIVER_BLOCKED 1930L + +// +// MessageId: ERROR_CONTEXT_EXPIRED +// +// MessageText: +// +// The context has expired and can no longer be used. +// +#define ERROR_CONTEXT_EXPIRED 1931L + +// +// MessageId: ERROR_PER_USER_TRUST_QUOTA_EXCEEDED +// +// MessageText: +// +// The current user's delegated trust creation quota has been exceeded. +// +#define ERROR_PER_USER_TRUST_QUOTA_EXCEEDED 1932L + +// +// MessageId: ERROR_ALL_USER_TRUST_QUOTA_EXCEEDED +// +// MessageText: +// +// The total delegated trust creation quota has been exceeded. +// +#define ERROR_ALL_USER_TRUST_QUOTA_EXCEEDED 1933L + +// +// MessageId: ERROR_USER_DELETE_TRUST_QUOTA_EXCEEDED +// +// MessageText: +// +// The current user's delegated trust deletion quota has been exceeded. +// +#define ERROR_USER_DELETE_TRUST_QUOTA_EXCEEDED 1934L + +// +// MessageId: ERROR_AUTHENTICATION_FIREWALL_FAILED +// +// MessageText: +// +// Logon Failure: The machine you are logging onto is protected by an authentication firewall. The specified account is not allowed to authenticate to the machine. +// +#define ERROR_AUTHENTICATION_FIREWALL_FAILED 1935L + +// +// MessageId: ERROR_REMOTE_PRINT_CONNECTIONS_BLOCKED +// +// MessageText: +// +// Remote connections to the Print Spooler are blocked by a policy set on your machine. +// +#define ERROR_REMOTE_PRINT_CONNECTIONS_BLOCKED 1936L + + + + +/////////////////////////// +// // +// OpenGL Error Code // +// // +/////////////////////////// + + +// +// MessageId: ERROR_INVALID_PIXEL_FORMAT +// +// MessageText: +// +// The pixel format is invalid. +// +#define ERROR_INVALID_PIXEL_FORMAT 2000L + +// +// MessageId: ERROR_BAD_DRIVER +// +// MessageText: +// +// The specified driver is invalid. +// +#define ERROR_BAD_DRIVER 2001L + +// +// MessageId: ERROR_INVALID_WINDOW_STYLE +// +// MessageText: +// +// The window style or class attribute is invalid for this operation. +// +#define ERROR_INVALID_WINDOW_STYLE 2002L + +// +// MessageId: ERROR_METAFILE_NOT_SUPPORTED +// +// MessageText: +// +// The requested metafile operation is not supported. +// +#define ERROR_METAFILE_NOT_SUPPORTED 2003L + +// +// MessageId: ERROR_TRANSFORM_NOT_SUPPORTED +// +// MessageText: +// +// The requested transformation operation is not supported. +// +#define ERROR_TRANSFORM_NOT_SUPPORTED 2004L + +// +// MessageId: ERROR_CLIPPING_NOT_SUPPORTED +// +// MessageText: +// +// The requested clipping operation is not supported. +// +#define ERROR_CLIPPING_NOT_SUPPORTED 2005L + +// End of OpenGL error codes + + + +/////////////////////////////////////////// +// // +// Image Color Management Error Code // +// // +/////////////////////////////////////////// + + +// +// MessageId: ERROR_INVALID_CMM +// +// MessageText: +// +// The specified color management module is invalid. +// +#define ERROR_INVALID_CMM 2010L + +// +// MessageId: ERROR_INVALID_PROFILE +// +// MessageText: +// +// The specified color profile is invalid. +// +#define ERROR_INVALID_PROFILE 2011L + +// +// MessageId: ERROR_TAG_NOT_FOUND +// +// MessageText: +// +// The specified tag was not found. +// +#define ERROR_TAG_NOT_FOUND 2012L + +// +// MessageId: ERROR_TAG_NOT_PRESENT +// +// MessageText: +// +// A required tag is not present. +// +#define ERROR_TAG_NOT_PRESENT 2013L + +// +// MessageId: ERROR_DUPLICATE_TAG +// +// MessageText: +// +// The specified tag is already present. +// +#define ERROR_DUPLICATE_TAG 2014L + +// +// MessageId: ERROR_PROFILE_NOT_ASSOCIATED_WITH_DEVICE +// +// MessageText: +// +// The specified color profile is not associated with any device. +// +#define ERROR_PROFILE_NOT_ASSOCIATED_WITH_DEVICE 2015L + +// +// MessageId: ERROR_PROFILE_NOT_FOUND +// +// MessageText: +// +// The specified color profile was not found. +// +#define ERROR_PROFILE_NOT_FOUND 2016L + +// +// MessageId: ERROR_INVALID_COLORSPACE +// +// MessageText: +// +// The specified color space is invalid. +// +#define ERROR_INVALID_COLORSPACE 2017L + +// +// MessageId: ERROR_ICM_NOT_ENABLED +// +// MessageText: +// +// Image Color Management is not enabled. +// +#define ERROR_ICM_NOT_ENABLED 2018L + +// +// MessageId: ERROR_DELETING_ICM_XFORM +// +// MessageText: +// +// There was an error while deleting the color transform. +// +#define ERROR_DELETING_ICM_XFORM 2019L + +// +// MessageId: ERROR_INVALID_TRANSFORM +// +// MessageText: +// +// The specified color transform is invalid. +// +#define ERROR_INVALID_TRANSFORM 2020L + +// +// MessageId: ERROR_COLORSPACE_MISMATCH +// +// MessageText: +// +// The specified transform does not match the bitmap's color space. +// +#define ERROR_COLORSPACE_MISMATCH 2021L + +// +// MessageId: ERROR_INVALID_COLORINDEX +// +// MessageText: +// +// The specified named color index is not present in the profile. +// +#define ERROR_INVALID_COLORINDEX 2022L + + + + +/////////////////////////// +// // +// Winnet32 Status Codes // +// // +// The range 2100 through 2999 is reserved for network status codes. +// See lmerr.h for a complete listing +/////////////////////////// + + +// +// MessageId: ERROR_CONNECTED_OTHER_PASSWORD +// +// MessageText: +// +// The network connection was made successfully, but the user had to be prompted for a password other than the one originally specified. +// +#define ERROR_CONNECTED_OTHER_PASSWORD 2108L + +// +// MessageId: ERROR_CONNECTED_OTHER_PASSWORD_DEFAULT +// +// MessageText: +// +// The network connection was made successfully using default credentials. +// +#define ERROR_CONNECTED_OTHER_PASSWORD_DEFAULT 2109L + +// +// MessageId: ERROR_BAD_USERNAME +// +// MessageText: +// +// The specified username is invalid. +// +#define ERROR_BAD_USERNAME 2202L + +// +// MessageId: ERROR_NOT_CONNECTED +// +// MessageText: +// +// This network connection does not exist. +// +#define ERROR_NOT_CONNECTED 2250L + +// +// MessageId: ERROR_OPEN_FILES +// +// MessageText: +// +// This network connection has files open or requests pending. +// +#define ERROR_OPEN_FILES 2401L + +// +// MessageId: ERROR_ACTIVE_CONNECTIONS +// +// MessageText: +// +// Active connections still exist. +// +#define ERROR_ACTIVE_CONNECTIONS 2402L + +// +// MessageId: ERROR_DEVICE_IN_USE +// +// MessageText: +// +// The device is in use by an active process and cannot be disconnected. +// +#define ERROR_DEVICE_IN_USE 2404L + + +//////////////////////////////////// +// // +// Win32 Spooler Error Codes // +// // +//////////////////////////////////// +// +// MessageId: ERROR_UNKNOWN_PRINT_MONITOR +// +// MessageText: +// +// The specified print monitor is unknown. +// +#define ERROR_UNKNOWN_PRINT_MONITOR 3000L + +// +// MessageId: ERROR_PRINTER_DRIVER_IN_USE +// +// MessageText: +// +// The specified printer driver is currently in use. +// +#define ERROR_PRINTER_DRIVER_IN_USE 3001L + +// +// MessageId: ERROR_SPOOL_FILE_NOT_FOUND +// +// MessageText: +// +// The spool file was not found. +// +#define ERROR_SPOOL_FILE_NOT_FOUND 3002L + +// +// MessageId: ERROR_SPL_NO_STARTDOC +// +// MessageText: +// +// A StartDocPrinter call was not issued. +// +#define ERROR_SPL_NO_STARTDOC 3003L + +// +// MessageId: ERROR_SPL_NO_ADDJOB +// +// MessageText: +// +// An AddJob call was not issued. +// +#define ERROR_SPL_NO_ADDJOB 3004L + +// +// MessageId: ERROR_PRINT_PROCESSOR_ALREADY_INSTALLED +// +// MessageText: +// +// The specified print processor has already been installed. +// +#define ERROR_PRINT_PROCESSOR_ALREADY_INSTALLED 3005L + +// +// MessageId: ERROR_PRINT_MONITOR_ALREADY_INSTALLED +// +// MessageText: +// +// The specified print monitor has already been installed. +// +#define ERROR_PRINT_MONITOR_ALREADY_INSTALLED 3006L + +// +// MessageId: ERROR_INVALID_PRINT_MONITOR +// +// MessageText: +// +// The specified print monitor does not have the required functions. +// +#define ERROR_INVALID_PRINT_MONITOR 3007L + +// +// MessageId: ERROR_PRINT_MONITOR_IN_USE +// +// MessageText: +// +// The specified print monitor is currently in use. +// +#define ERROR_PRINT_MONITOR_IN_USE 3008L + +// +// MessageId: ERROR_PRINTER_HAS_JOBS_QUEUED +// +// MessageText: +// +// The requested operation is not allowed when there are jobs queued to the printer. +// +#define ERROR_PRINTER_HAS_JOBS_QUEUED 3009L + +// +// MessageId: ERROR_SUCCESS_REBOOT_REQUIRED +// +// MessageText: +// +// The requested operation is successful. Changes will not be effective until the system is rebooted. +// +#define ERROR_SUCCESS_REBOOT_REQUIRED 3010L + +// +// MessageId: ERROR_SUCCESS_RESTART_REQUIRED +// +// MessageText: +// +// The requested operation is successful. Changes will not be effective until the service is restarted. +// +#define ERROR_SUCCESS_RESTART_REQUIRED 3011L + +// +// MessageId: ERROR_PRINTER_NOT_FOUND +// +// MessageText: +// +// No printers were found. +// +#define ERROR_PRINTER_NOT_FOUND 3012L + +// +// MessageId: ERROR_PRINTER_DRIVER_WARNED +// +// MessageText: +// +// The printer driver is known to be unreliable. +// +#define ERROR_PRINTER_DRIVER_WARNED 3013L + +// +// MessageId: ERROR_PRINTER_DRIVER_BLOCKED +// +// MessageText: +// +// The printer driver is known to harm the system. +// +#define ERROR_PRINTER_DRIVER_BLOCKED 3014L + +//////////////////////////////////// +// // +// Wins Error Codes // +// // +//////////////////////////////////// +// +// MessageId: ERROR_WINS_INTERNAL +// +// MessageText: +// +// WINS encountered an error while processing the command. +// +#define ERROR_WINS_INTERNAL 4000L + +// +// MessageId: ERROR_CAN_NOT_DEL_LOCAL_WINS +// +// MessageText: +// +// The local WINS can not be deleted. +// +#define ERROR_CAN_NOT_DEL_LOCAL_WINS 4001L + +// +// MessageId: ERROR_STATIC_INIT +// +// MessageText: +// +// The importation from the file failed. +// +#define ERROR_STATIC_INIT 4002L + +// +// MessageId: ERROR_INC_BACKUP +// +// MessageText: +// +// The backup failed. Was a full backup done before? +// +#define ERROR_INC_BACKUP 4003L + +// +// MessageId: ERROR_FULL_BACKUP +// +// MessageText: +// +// The backup failed. Check the directory to which you are backing the database. +// +#define ERROR_FULL_BACKUP 4004L + +// +// MessageId: ERROR_REC_NON_EXISTENT +// +// MessageText: +// +// The name does not exist in the WINS database. +// +#define ERROR_REC_NON_EXISTENT 4005L + +// +// MessageId: ERROR_RPL_NOT_ALLOWED +// +// MessageText: +// +// Replication with a nonconfigured partner is not allowed. +// +#define ERROR_RPL_NOT_ALLOWED 4006L + +//////////////////////////////////// +// // +// DHCP Error Codes // +// // +//////////////////////////////////// +// +// MessageId: ERROR_DHCP_ADDRESS_CONFLICT +// +// MessageText: +// +// The DHCP client has obtained an IP address that is already in use on the network. The local interface will be disabled until the DHCP client can obtain a new address. +// +#define ERROR_DHCP_ADDRESS_CONFLICT 4100L + +//////////////////////////////////// +// // +// WMI Error Codes // +// // +//////////////////////////////////// +// +// MessageId: ERROR_WMI_GUID_NOT_FOUND +// +// MessageText: +// +// The GUID passed was not recognized as valid by a WMI data provider. +// +#define ERROR_WMI_GUID_NOT_FOUND 4200L + +// +// MessageId: ERROR_WMI_INSTANCE_NOT_FOUND +// +// MessageText: +// +// The instance name passed was not recognized as valid by a WMI data provider. +// +#define ERROR_WMI_INSTANCE_NOT_FOUND 4201L + +// +// MessageId: ERROR_WMI_ITEMID_NOT_FOUND +// +// MessageText: +// +// The data item ID passed was not recognized as valid by a WMI data provider. +// +#define ERROR_WMI_ITEMID_NOT_FOUND 4202L + +// +// MessageId: ERROR_WMI_TRY_AGAIN +// +// MessageText: +// +// The WMI request could not be completed and should be retried. +// +#define ERROR_WMI_TRY_AGAIN 4203L + +// +// MessageId: ERROR_WMI_DP_NOT_FOUND +// +// MessageText: +// +// The WMI data provider could not be located. +// +#define ERROR_WMI_DP_NOT_FOUND 4204L + +// +// MessageId: ERROR_WMI_UNRESOLVED_INSTANCE_REF +// +// MessageText: +// +// The WMI data provider references an instance set that has not been registered. +// +#define ERROR_WMI_UNRESOLVED_INSTANCE_REF 4205L + +// +// MessageId: ERROR_WMI_ALREADY_ENABLED +// +// MessageText: +// +// The WMI data block or event notification has already been enabled. +// +#define ERROR_WMI_ALREADY_ENABLED 4206L + +// +// MessageId: ERROR_WMI_GUID_DISCONNECTED +// +// MessageText: +// +// The WMI data block is no longer available. +// +#define ERROR_WMI_GUID_DISCONNECTED 4207L + +// +// MessageId: ERROR_WMI_SERVER_UNAVAILABLE +// +// MessageText: +// +// The WMI data service is not available. +// +#define ERROR_WMI_SERVER_UNAVAILABLE 4208L + +// +// MessageId: ERROR_WMI_DP_FAILED +// +// MessageText: +// +// The WMI data provider failed to carry out the request. +// +#define ERROR_WMI_DP_FAILED 4209L + +// +// MessageId: ERROR_WMI_INVALID_MOF +// +// MessageText: +// +// The WMI MOF information is not valid. +// +#define ERROR_WMI_INVALID_MOF 4210L + +// +// MessageId: ERROR_WMI_INVALID_REGINFO +// +// MessageText: +// +// The WMI registration information is not valid. +// +#define ERROR_WMI_INVALID_REGINFO 4211L + +// +// MessageId: ERROR_WMI_ALREADY_DISABLED +// +// MessageText: +// +// The WMI data block or event notification has already been disabled. +// +#define ERROR_WMI_ALREADY_DISABLED 4212L + +// +// MessageId: ERROR_WMI_READ_ONLY +// +// MessageText: +// +// The WMI data item or data block is read only. +// +#define ERROR_WMI_READ_ONLY 4213L + +// +// MessageId: ERROR_WMI_SET_FAILURE +// +// MessageText: +// +// The WMI data item or data block could not be changed. +// +#define ERROR_WMI_SET_FAILURE 4214L + +////////////////////////////////////////// +// // +// NT Media Services (RSM) Error Codes // +// // +////////////////////////////////////////// +// +// MessageId: ERROR_INVALID_MEDIA +// +// MessageText: +// +// The media identifier does not represent a valid medium. +// +#define ERROR_INVALID_MEDIA 4300L + +// +// MessageId: ERROR_INVALID_LIBRARY +// +// MessageText: +// +// The library identifier does not represent a valid library. +// +#define ERROR_INVALID_LIBRARY 4301L + +// +// MessageId: ERROR_INVALID_MEDIA_POOL +// +// MessageText: +// +// The media pool identifier does not represent a valid media pool. +// +#define ERROR_INVALID_MEDIA_POOL 4302L + +// +// MessageId: ERROR_DRIVE_MEDIA_MISMATCH +// +// MessageText: +// +// The drive and medium are not compatible or exist in different libraries. +// +#define ERROR_DRIVE_MEDIA_MISMATCH 4303L + +// +// MessageId: ERROR_MEDIA_OFFLINE +// +// MessageText: +// +// The medium currently exists in an offline library and must be online to perform this operation. +// +#define ERROR_MEDIA_OFFLINE 4304L + +// +// MessageId: ERROR_LIBRARY_OFFLINE +// +// MessageText: +// +// The operation cannot be performed on an offline library. +// +#define ERROR_LIBRARY_OFFLINE 4305L + +// +// MessageId: ERROR_EMPTY +// +// MessageText: +// +// The library, drive, or media pool is empty. +// +#define ERROR_EMPTY 4306L + +// +// MessageId: ERROR_NOT_EMPTY +// +// MessageText: +// +// The library, drive, or media pool must be empty to perform this operation. +// +#define ERROR_NOT_EMPTY 4307L + +// +// MessageId: ERROR_MEDIA_UNAVAILABLE +// +// MessageText: +// +// No media is currently available in this media pool or library. +// +#define ERROR_MEDIA_UNAVAILABLE 4308L + +// +// MessageId: ERROR_RESOURCE_DISABLED +// +// MessageText: +// +// A resource required for this operation is disabled. +// +#define ERROR_RESOURCE_DISABLED 4309L + +// +// MessageId: ERROR_INVALID_CLEANER +// +// MessageText: +// +// The media identifier does not represent a valid cleaner. +// +#define ERROR_INVALID_CLEANER 4310L + +// +// MessageId: ERROR_UNABLE_TO_CLEAN +// +// MessageText: +// +// The drive cannot be cleaned or does not support cleaning. +// +#define ERROR_UNABLE_TO_CLEAN 4311L + +// +// MessageId: ERROR_OBJECT_NOT_FOUND +// +// MessageText: +// +// The object identifier does not represent a valid object. +// +#define ERROR_OBJECT_NOT_FOUND 4312L + +// +// MessageId: ERROR_DATABASE_FAILURE +// +// MessageText: +// +// Unable to read from or write to the database. +// +#define ERROR_DATABASE_FAILURE 4313L + +// +// MessageId: ERROR_DATABASE_FULL +// +// MessageText: +// +// The database is full. +// +#define ERROR_DATABASE_FULL 4314L + +// +// MessageId: ERROR_MEDIA_INCOMPATIBLE +// +// MessageText: +// +// The medium is not compatible with the device or media pool. +// +#define ERROR_MEDIA_INCOMPATIBLE 4315L + +// +// MessageId: ERROR_RESOURCE_NOT_PRESENT +// +// MessageText: +// +// The resource required for this operation does not exist. +// +#define ERROR_RESOURCE_NOT_PRESENT 4316L + +// +// MessageId: ERROR_INVALID_OPERATION +// +// MessageText: +// +// The operation identifier is not valid. +// +#define ERROR_INVALID_OPERATION 4317L + +// +// MessageId: ERROR_MEDIA_NOT_AVAILABLE +// +// MessageText: +// +// The media is not mounted or ready for use. +// +#define ERROR_MEDIA_NOT_AVAILABLE 4318L + +// +// MessageId: ERROR_DEVICE_NOT_AVAILABLE +// +// MessageText: +// +// The device is not ready for use. +// +#define ERROR_DEVICE_NOT_AVAILABLE 4319L + +// +// MessageId: ERROR_REQUEST_REFUSED +// +// MessageText: +// +// The operator or administrator has refused the request. +// +#define ERROR_REQUEST_REFUSED 4320L + +// +// MessageId: ERROR_INVALID_DRIVE_OBJECT +// +// MessageText: +// +// The drive identifier does not represent a valid drive. +// +#define ERROR_INVALID_DRIVE_OBJECT 4321L + +// +// MessageId: ERROR_LIBRARY_FULL +// +// MessageText: +// +// Library is full. No slot is available for use. +// +#define ERROR_LIBRARY_FULL 4322L + +// +// MessageId: ERROR_MEDIUM_NOT_ACCESSIBLE +// +// MessageText: +// +// The transport cannot access the medium. +// +#define ERROR_MEDIUM_NOT_ACCESSIBLE 4323L + +// +// MessageId: ERROR_UNABLE_TO_LOAD_MEDIUM +// +// MessageText: +// +// Unable to load the medium into the drive. +// +#define ERROR_UNABLE_TO_LOAD_MEDIUM 4324L + +// +// MessageId: ERROR_UNABLE_TO_INVENTORY_DRIVE +// +// MessageText: +// +// Unable to retrieve the drive status. +// +#define ERROR_UNABLE_TO_INVENTORY_DRIVE 4325L + +// +// MessageId: ERROR_UNABLE_TO_INVENTORY_SLOT +// +// MessageText: +// +// Unable to retrieve the slot status. +// +#define ERROR_UNABLE_TO_INVENTORY_SLOT 4326L + +// +// MessageId: ERROR_UNABLE_TO_INVENTORY_TRANSPORT +// +// MessageText: +// +// Unable to retrieve status about the transport. +// +#define ERROR_UNABLE_TO_INVENTORY_TRANSPORT 4327L + +// +// MessageId: ERROR_TRANSPORT_FULL +// +// MessageText: +// +// Cannot use the transport because it is already in use. +// +#define ERROR_TRANSPORT_FULL 4328L + +// +// MessageId: ERROR_CONTROLLING_IEPORT +// +// MessageText: +// +// Unable to open or close the inject/eject port. +// +#define ERROR_CONTROLLING_IEPORT 4329L + +// +// MessageId: ERROR_UNABLE_TO_EJECT_MOUNTED_MEDIA +// +// MessageText: +// +// Unable to eject the medium because it is in a drive. +// +#define ERROR_UNABLE_TO_EJECT_MOUNTED_MEDIA 4330L + +// +// MessageId: ERROR_CLEANER_SLOT_SET +// +// MessageText: +// +// A cleaner slot is already reserved. +// +#define ERROR_CLEANER_SLOT_SET 4331L + +// +// MessageId: ERROR_CLEANER_SLOT_NOT_SET +// +// MessageText: +// +// A cleaner slot is not reserved. +// +#define ERROR_CLEANER_SLOT_NOT_SET 4332L + +// +// MessageId: ERROR_CLEANER_CARTRIDGE_SPENT +// +// MessageText: +// +// The cleaner cartridge has performed the maximum number of drive cleanings. +// +#define ERROR_CLEANER_CARTRIDGE_SPENT 4333L + +// +// MessageId: ERROR_UNEXPECTED_OMID +// +// MessageText: +// +// Unexpected on-medium identifier. +// +#define ERROR_UNEXPECTED_OMID 4334L + +// +// MessageId: ERROR_CANT_DELETE_LAST_ITEM +// +// MessageText: +// +// The last remaining item in this group or resource cannot be deleted. +// +#define ERROR_CANT_DELETE_LAST_ITEM 4335L + +// +// MessageId: ERROR_MESSAGE_EXCEEDS_MAX_SIZE +// +// MessageText: +// +// The message provided exceeds the maximum size allowed for this parameter. +// +#define ERROR_MESSAGE_EXCEEDS_MAX_SIZE 4336L + +// +// MessageId: ERROR_VOLUME_CONTAINS_SYS_FILES +// +// MessageText: +// +// The volume contains system or paging files. +// +#define ERROR_VOLUME_CONTAINS_SYS_FILES 4337L + +// +// MessageId: ERROR_INDIGENOUS_TYPE +// +// MessageText: +// +// The media type cannot be removed from this library since at least one drive in the library reports it can support this media type. +// +#define ERROR_INDIGENOUS_TYPE 4338L + +// +// MessageId: ERROR_NO_SUPPORTING_DRIVES +// +// MessageText: +// +// This offline media cannot be mounted on this system since no enabled drives are present which can be used. +// +#define ERROR_NO_SUPPORTING_DRIVES 4339L + +// +// MessageId: ERROR_CLEANER_CARTRIDGE_INSTALLED +// +// MessageText: +// +// A cleaner cartridge is present in the tape library. +// +#define ERROR_CLEANER_CARTRIDGE_INSTALLED 4340L + +// +// MessageId: ERROR_IEPORT_FULL +// +// MessageText: +// +// Cannot use the ieport because it is not empty. +// +#define ERROR_IEPORT_FULL 4341L + +//////////////////////////////////////////// +// // +// NT Remote Storage Service Error Codes // +// // +//////////////////////////////////////////// +// +// MessageId: ERROR_FILE_OFFLINE +// +// MessageText: +// +// The remote storage service was not able to recall the file. +// +#define ERROR_FILE_OFFLINE 4350L + +// +// MessageId: ERROR_REMOTE_STORAGE_NOT_ACTIVE +// +// MessageText: +// +// The remote storage service is not operational at this time. +// +#define ERROR_REMOTE_STORAGE_NOT_ACTIVE 4351L + +// +// MessageId: ERROR_REMOTE_STORAGE_MEDIA_ERROR +// +// MessageText: +// +// The remote storage service encountered a media error. +// +#define ERROR_REMOTE_STORAGE_MEDIA_ERROR 4352L + +//////////////////////////////////////////// +// // +// NT Reparse Points Error Codes // +// // +//////////////////////////////////////////// +// +// MessageId: ERROR_NOT_A_REPARSE_POINT +// +// MessageText: +// +// The file or directory is not a reparse point. +// +#define ERROR_NOT_A_REPARSE_POINT 4390L + +// +// MessageId: ERROR_REPARSE_ATTRIBUTE_CONFLICT +// +// MessageText: +// +// The reparse point attribute cannot be set because it conflicts with an existing attribute. +// +#define ERROR_REPARSE_ATTRIBUTE_CONFLICT 4391L + +// +// MessageId: ERROR_INVALID_REPARSE_DATA +// +// MessageText: +// +// The data present in the reparse point buffer is invalid. +// +#define ERROR_INVALID_REPARSE_DATA 4392L + +// +// MessageId: ERROR_REPARSE_TAG_INVALID +// +// MessageText: +// +// The tag present in the reparse point buffer is invalid. +// +#define ERROR_REPARSE_TAG_INVALID 4393L + +// +// MessageId: ERROR_REPARSE_TAG_MISMATCH +// +// MessageText: +// +// There is a mismatch between the tag specified in the request and the tag present in the reparse point. +// +// +#define ERROR_REPARSE_TAG_MISMATCH 4394L + +//////////////////////////////////////////// +// // +// NT Single Instance Store Error Codes // +// // +//////////////////////////////////////////// +// +// MessageId: ERROR_VOLUME_NOT_SIS_ENABLED +// +// MessageText: +// +// Single Instance Storage is not available on this volume. +// +#define ERROR_VOLUME_NOT_SIS_ENABLED 4500L + +//////////////////////////////////// +// // +// Cluster Error Codes // +// // +//////////////////////////////////// +// +// MessageId: ERROR_DEPENDENT_RESOURCE_EXISTS +// +// MessageText: +// +// The cluster resource cannot be moved to another group because other resources are dependent on it. +// +#define ERROR_DEPENDENT_RESOURCE_EXISTS 5001L + +// +// MessageId: ERROR_DEPENDENCY_NOT_FOUND +// +// MessageText: +// +// The cluster resource dependency cannot be found. +// +#define ERROR_DEPENDENCY_NOT_FOUND 5002L + +// +// MessageId: ERROR_DEPENDENCY_ALREADY_EXISTS +// +// MessageText: +// +// The cluster resource cannot be made dependent on the specified resource because it is already dependent. +// +#define ERROR_DEPENDENCY_ALREADY_EXISTS 5003L + +// +// MessageId: ERROR_RESOURCE_NOT_ONLINE +// +// MessageText: +// +// The cluster resource is not online. +// +#define ERROR_RESOURCE_NOT_ONLINE 5004L + +// +// MessageId: ERROR_HOST_NODE_NOT_AVAILABLE +// +// MessageText: +// +// A cluster node is not available for this operation. +// +#define ERROR_HOST_NODE_NOT_AVAILABLE 5005L + +// +// MessageId: ERROR_RESOURCE_NOT_AVAILABLE +// +// MessageText: +// +// The cluster resource is not available. +// +#define ERROR_RESOURCE_NOT_AVAILABLE 5006L + +// +// MessageId: ERROR_RESOURCE_NOT_FOUND +// +// MessageText: +// +// The cluster resource could not be found. +// +#define ERROR_RESOURCE_NOT_FOUND 5007L + +// +// MessageId: ERROR_SHUTDOWN_CLUSTER +// +// MessageText: +// +// The cluster is being shut down. +// +#define ERROR_SHUTDOWN_CLUSTER 5008L + +// +// MessageId: ERROR_CANT_EVICT_ACTIVE_NODE +// +// MessageText: +// +// A cluster node cannot be evicted from the cluster unless the node is down or it is the last node. +// +#define ERROR_CANT_EVICT_ACTIVE_NODE 5009L + +// +// MessageId: ERROR_OBJECT_ALREADY_EXISTS +// +// MessageText: +// +// The object already exists. +// +#define ERROR_OBJECT_ALREADY_EXISTS 5010L + +// +// MessageId: ERROR_OBJECT_IN_LIST +// +// MessageText: +// +// The object is already in the list. +// +#define ERROR_OBJECT_IN_LIST 5011L + +// +// MessageId: ERROR_GROUP_NOT_AVAILABLE +// +// MessageText: +// +// The cluster group is not available for any new requests. +// +#define ERROR_GROUP_NOT_AVAILABLE 5012L + +// +// MessageId: ERROR_GROUP_NOT_FOUND +// +// MessageText: +// +// The cluster group could not be found. +// +#define ERROR_GROUP_NOT_FOUND 5013L + +// +// MessageId: ERROR_GROUP_NOT_ONLINE +// +// MessageText: +// +// The operation could not be completed because the cluster group is not online. +// +#define ERROR_GROUP_NOT_ONLINE 5014L + +// +// MessageId: ERROR_HOST_NODE_NOT_RESOURCE_OWNER +// +// MessageText: +// +// The cluster node is not the owner of the resource. +// +#define ERROR_HOST_NODE_NOT_RESOURCE_OWNER 5015L + +// +// MessageId: ERROR_HOST_NODE_NOT_GROUP_OWNER +// +// MessageText: +// +// The cluster node is not the owner of the group. +// +#define ERROR_HOST_NODE_NOT_GROUP_OWNER 5016L + +// +// MessageId: ERROR_RESMON_CREATE_FAILED +// +// MessageText: +// +// The cluster resource could not be created in the specified resource monitor. +// +#define ERROR_RESMON_CREATE_FAILED 5017L + +// +// MessageId: ERROR_RESMON_ONLINE_FAILED +// +// MessageText: +// +// The cluster resource could not be brought online by the resource monitor. +// +#define ERROR_RESMON_ONLINE_FAILED 5018L + +// +// MessageId: ERROR_RESOURCE_ONLINE +// +// MessageText: +// +// The operation could not be completed because the cluster resource is online. +// +#define ERROR_RESOURCE_ONLINE 5019L + +// +// MessageId: ERROR_QUORUM_RESOURCE +// +// MessageText: +// +// The cluster resource could not be deleted or brought offline because it is the quorum resource. +// +#define ERROR_QUORUM_RESOURCE 5020L + +// +// MessageId: ERROR_NOT_QUORUM_CAPABLE +// +// MessageText: +// +// The cluster could not make the specified resource a quorum resource because it is not capable of being a quorum resource. +// +#define ERROR_NOT_QUORUM_CAPABLE 5021L + +// +// MessageId: ERROR_CLUSTER_SHUTTING_DOWN +// +// MessageText: +// +// The cluster software is shutting down. +// +#define ERROR_CLUSTER_SHUTTING_DOWN 5022L + +// +// MessageId: ERROR_INVALID_STATE +// +// MessageText: +// +// The group or resource is not in the correct state to perform the requested operation. +// +#define ERROR_INVALID_STATE 5023L + +// +// MessageId: ERROR_RESOURCE_PROPERTIES_STORED +// +// MessageText: +// +// The properties were stored but not all changes will take effect until the next time the resource is brought online. +// +#define ERROR_RESOURCE_PROPERTIES_STORED 5024L + +// +// MessageId: ERROR_NOT_QUORUM_CLASS +// +// MessageText: +// +// The cluster could not make the specified resource a quorum resource because it does not belong to a shared storage class. +// +#define ERROR_NOT_QUORUM_CLASS 5025L + +// +// MessageId: ERROR_CORE_RESOURCE +// +// MessageText: +// +// The cluster resource could not be deleted since it is a core resource. +// +#define ERROR_CORE_RESOURCE 5026L + +// +// MessageId: ERROR_QUORUM_RESOURCE_ONLINE_FAILED +// +// MessageText: +// +// The quorum resource failed to come online. +// +#define ERROR_QUORUM_RESOURCE_ONLINE_FAILED 5027L + +// +// MessageId: ERROR_QUORUMLOG_OPEN_FAILED +// +// MessageText: +// +// The quorum log could not be created or mounted successfully. +// +#define ERROR_QUORUMLOG_OPEN_FAILED 5028L + +// +// MessageId: ERROR_CLUSTERLOG_CORRUPT +// +// MessageText: +// +// The cluster log is corrupt. +// +#define ERROR_CLUSTERLOG_CORRUPT 5029L + +// +// MessageId: ERROR_CLUSTERLOG_RECORD_EXCEEDS_MAXSIZE +// +// MessageText: +// +// The record could not be written to the cluster log since it exceeds the maximum size. +// +#define ERROR_CLUSTERLOG_RECORD_EXCEEDS_MAXSIZE 5030L + +// +// MessageId: ERROR_CLUSTERLOG_EXCEEDS_MAXSIZE +// +// MessageText: +// +// The cluster log exceeds its maximum size. +// +#define ERROR_CLUSTERLOG_EXCEEDS_MAXSIZE 5031L + +// +// MessageId: ERROR_CLUSTERLOG_CHKPOINT_NOT_FOUND +// +// MessageText: +// +// No checkpoint record was found in the cluster log. +// +#define ERROR_CLUSTERLOG_CHKPOINT_NOT_FOUND 5032L + +// +// MessageId: ERROR_CLUSTERLOG_NOT_ENOUGH_SPACE +// +// MessageText: +// +// The minimum required disk space needed for logging is not available. +// +#define ERROR_CLUSTERLOG_NOT_ENOUGH_SPACE 5033L + +// +// MessageId: ERROR_QUORUM_OWNER_ALIVE +// +// MessageText: +// +// The cluster node failed to take control of the quorum resource because the resource is owned by another active node. +// +#define ERROR_QUORUM_OWNER_ALIVE 5034L + +// +// MessageId: ERROR_NETWORK_NOT_AVAILABLE +// +// MessageText: +// +// A cluster network is not available for this operation. +// +#define ERROR_NETWORK_NOT_AVAILABLE 5035L + +// +// MessageId: ERROR_NODE_NOT_AVAILABLE +// +// MessageText: +// +// A cluster node is not available for this operation. +// +#define ERROR_NODE_NOT_AVAILABLE 5036L + +// +// MessageId: ERROR_ALL_NODES_NOT_AVAILABLE +// +// MessageText: +// +// All cluster nodes must be running to perform this operation. +// +#define ERROR_ALL_NODES_NOT_AVAILABLE 5037L + +// +// MessageId: ERROR_RESOURCE_FAILED +// +// MessageText: +// +// A cluster resource failed. +// +#define ERROR_RESOURCE_FAILED 5038L + +// +// MessageId: ERROR_CLUSTER_INVALID_NODE +// +// MessageText: +// +// The cluster node is not valid. +// +#define ERROR_CLUSTER_INVALID_NODE 5039L + +// +// MessageId: ERROR_CLUSTER_NODE_EXISTS +// +// MessageText: +// +// The cluster node already exists. +// +#define ERROR_CLUSTER_NODE_EXISTS 5040L + +// +// MessageId: ERROR_CLUSTER_JOIN_IN_PROGRESS +// +// MessageText: +// +// A node is in the process of joining the cluster. +// +#define ERROR_CLUSTER_JOIN_IN_PROGRESS 5041L + +// +// MessageId: ERROR_CLUSTER_NODE_NOT_FOUND +// +// MessageText: +// +// The cluster node was not found. +// +#define ERROR_CLUSTER_NODE_NOT_FOUND 5042L + +// +// MessageId: ERROR_CLUSTER_LOCAL_NODE_NOT_FOUND +// +// MessageText: +// +// The cluster local node information was not found. +// +#define ERROR_CLUSTER_LOCAL_NODE_NOT_FOUND 5043L + +// +// MessageId: ERROR_CLUSTER_NETWORK_EXISTS +// +// MessageText: +// +// The cluster network already exists. +// +#define ERROR_CLUSTER_NETWORK_EXISTS 5044L + +// +// MessageId: ERROR_CLUSTER_NETWORK_NOT_FOUND +// +// MessageText: +// +// The cluster network was not found. +// +#define ERROR_CLUSTER_NETWORK_NOT_FOUND 5045L + +// +// MessageId: ERROR_CLUSTER_NETINTERFACE_EXISTS +// +// MessageText: +// +// The cluster network interface already exists. +// +#define ERROR_CLUSTER_NETINTERFACE_EXISTS 5046L + +// +// MessageId: ERROR_CLUSTER_NETINTERFACE_NOT_FOUND +// +// MessageText: +// +// The cluster network interface was not found. +// +#define ERROR_CLUSTER_NETINTERFACE_NOT_FOUND 5047L + +// +// MessageId: ERROR_CLUSTER_INVALID_REQUEST +// +// MessageText: +// +// The cluster request is not valid for this object. +// +#define ERROR_CLUSTER_INVALID_REQUEST 5048L + +// +// MessageId: ERROR_CLUSTER_INVALID_NETWORK_PROVIDER +// +// MessageText: +// +// The cluster network provider is not valid. +// +#define ERROR_CLUSTER_INVALID_NETWORK_PROVIDER 5049L + +// +// MessageId: ERROR_CLUSTER_NODE_DOWN +// +// MessageText: +// +// The cluster node is down. +// +#define ERROR_CLUSTER_NODE_DOWN 5050L + +// +// MessageId: ERROR_CLUSTER_NODE_UNREACHABLE +// +// MessageText: +// +// The cluster node is not reachable. +// +#define ERROR_CLUSTER_NODE_UNREACHABLE 5051L + +// +// MessageId: ERROR_CLUSTER_NODE_NOT_MEMBER +// +// MessageText: +// +// The cluster node is not a member of the cluster. +// +#define ERROR_CLUSTER_NODE_NOT_MEMBER 5052L + +// +// MessageId: ERROR_CLUSTER_JOIN_NOT_IN_PROGRESS +// +// MessageText: +// +// A cluster join operation is not in progress. +// +#define ERROR_CLUSTER_JOIN_NOT_IN_PROGRESS 5053L + +// +// MessageId: ERROR_CLUSTER_INVALID_NETWORK +// +// MessageText: +// +// The cluster network is not valid. +// +#define ERROR_CLUSTER_INVALID_NETWORK 5054L + +// +// MessageId: ERROR_CLUSTER_NODE_UP +// +// MessageText: +// +// The cluster node is up. +// +#define ERROR_CLUSTER_NODE_UP 5056L + +// +// MessageId: ERROR_CLUSTER_IPADDR_IN_USE +// +// MessageText: +// +// The cluster IP address is already in use. +// +#define ERROR_CLUSTER_IPADDR_IN_USE 5057L + +// +// MessageId: ERROR_CLUSTER_NODE_NOT_PAUSED +// +// MessageText: +// +// The cluster node is not paused. +// +#define ERROR_CLUSTER_NODE_NOT_PAUSED 5058L + +// +// MessageId: ERROR_CLUSTER_NO_SECURITY_CONTEXT +// +// MessageText: +// +// No cluster security context is available. +// +#define ERROR_CLUSTER_NO_SECURITY_CONTEXT 5059L + +// +// MessageId: ERROR_CLUSTER_NETWORK_NOT_INTERNAL +// +// MessageText: +// +// The cluster network is not configured for internal cluster communication. +// +#define ERROR_CLUSTER_NETWORK_NOT_INTERNAL 5060L + +// +// MessageId: ERROR_CLUSTER_NODE_ALREADY_UP +// +// MessageText: +// +// The cluster node is already up. +// +#define ERROR_CLUSTER_NODE_ALREADY_UP 5061L + +// +// MessageId: ERROR_CLUSTER_NODE_ALREADY_DOWN +// +// MessageText: +// +// The cluster node is already down. +// +#define ERROR_CLUSTER_NODE_ALREADY_DOWN 5062L + +// +// MessageId: ERROR_CLUSTER_NETWORK_ALREADY_ONLINE +// +// MessageText: +// +// The cluster network is already online. +// +#define ERROR_CLUSTER_NETWORK_ALREADY_ONLINE 5063L + +// +// MessageId: ERROR_CLUSTER_NETWORK_ALREADY_OFFLINE +// +// MessageText: +// +// The cluster network is already offline. +// +#define ERROR_CLUSTER_NETWORK_ALREADY_OFFLINE 5064L + +// +// MessageId: ERROR_CLUSTER_NODE_ALREADY_MEMBER +// +// MessageText: +// +// The cluster node is already a member of the cluster. +// +#define ERROR_CLUSTER_NODE_ALREADY_MEMBER 5065L + +// +// MessageId: ERROR_CLUSTER_LAST_INTERNAL_NETWORK +// +// MessageText: +// +// The cluster network is the only one configured for internal cluster communication between two or more active cluster nodes. The internal communication capability cannot be removed from the network. +// +#define ERROR_CLUSTER_LAST_INTERNAL_NETWORK 5066L + +// +// MessageId: ERROR_CLUSTER_NETWORK_HAS_DEPENDENTS +// +// MessageText: +// +// One or more cluster resources depend on the network to provide service to clients. The client access capability cannot be removed from the network. +// +#define ERROR_CLUSTER_NETWORK_HAS_DEPENDENTS 5067L + +// +// MessageId: ERROR_INVALID_OPERATION_ON_QUORUM +// +// MessageText: +// +// This operation cannot be performed on the cluster resource as it the quorum resource. You may not bring the quorum resource offline or modify its possible owners list. +// +#define ERROR_INVALID_OPERATION_ON_QUORUM 5068L + +// +// MessageId: ERROR_DEPENDENCY_NOT_ALLOWED +// +// MessageText: +// +// The cluster quorum resource is not allowed to have any dependencies. +// +#define ERROR_DEPENDENCY_NOT_ALLOWED 5069L + +// +// MessageId: ERROR_CLUSTER_NODE_PAUSED +// +// MessageText: +// +// The cluster node is paused. +// +#define ERROR_CLUSTER_NODE_PAUSED 5070L + +// +// MessageId: ERROR_NODE_CANT_HOST_RESOURCE +// +// MessageText: +// +// The cluster resource cannot be brought online. The owner node cannot run this resource. +// +#define ERROR_NODE_CANT_HOST_RESOURCE 5071L + +// +// MessageId: ERROR_CLUSTER_NODE_NOT_READY +// +// MessageText: +// +// The cluster node is not ready to perform the requested operation. +// +#define ERROR_CLUSTER_NODE_NOT_READY 5072L + +// +// MessageId: ERROR_CLUSTER_NODE_SHUTTING_DOWN +// +// MessageText: +// +// The cluster node is shutting down. +// +#define ERROR_CLUSTER_NODE_SHUTTING_DOWN 5073L + +// +// MessageId: ERROR_CLUSTER_JOIN_ABORTED +// +// MessageText: +// +// The cluster join operation was aborted. +// +#define ERROR_CLUSTER_JOIN_ABORTED 5074L + +// +// MessageId: ERROR_CLUSTER_INCOMPATIBLE_VERSIONS +// +// MessageText: +// +// The cluster join operation failed due to incompatible software versions between the joining node and its sponsor. +// +#define ERROR_CLUSTER_INCOMPATIBLE_VERSIONS 5075L + +// +// MessageId: ERROR_CLUSTER_MAXNUM_OF_RESOURCES_EXCEEDED +// +// MessageText: +// +// This resource cannot be created because the cluster has reached the limit on the number of resources it can monitor. +// +#define ERROR_CLUSTER_MAXNUM_OF_RESOURCES_EXCEEDED 5076L + +// +// MessageId: ERROR_CLUSTER_SYSTEM_CONFIG_CHANGED +// +// MessageText: +// +// The system configuration changed during the cluster join or form operation. The join or form operation was aborted. +// +#define ERROR_CLUSTER_SYSTEM_CONFIG_CHANGED 5077L + +// +// MessageId: ERROR_CLUSTER_RESOURCE_TYPE_NOT_FOUND +// +// MessageText: +// +// The specified resource type was not found. +// +#define ERROR_CLUSTER_RESOURCE_TYPE_NOT_FOUND 5078L + +// +// MessageId: ERROR_CLUSTER_RESTYPE_NOT_SUPPORTED +// +// MessageText: +// +// The specified node does not support a resource of this type. This may be due to version inconsistencies or due to the absence of the resource DLL on this node. +// +#define ERROR_CLUSTER_RESTYPE_NOT_SUPPORTED 5079L + +// +// MessageId: ERROR_CLUSTER_RESNAME_NOT_FOUND +// +// MessageText: +// +// The specified resource name is not supported by this resource DLL. This may be due to a bad (or changed) name supplied to the resource DLL. +// +#define ERROR_CLUSTER_RESNAME_NOT_FOUND 5080L + +// +// MessageId: ERROR_CLUSTER_NO_RPC_PACKAGES_REGISTERED +// +// MessageText: +// +// No authentication package could be registered with the RPC server. +// +#define ERROR_CLUSTER_NO_RPC_PACKAGES_REGISTERED 5081L + +// +// MessageId: ERROR_CLUSTER_OWNER_NOT_IN_PREFLIST +// +// MessageText: +// +// You cannot bring the group online because the owner of the group is not in the preferred list for the group. To change the owner node for the group, move the group. +// +#define ERROR_CLUSTER_OWNER_NOT_IN_PREFLIST 5082L + +// +// MessageId: ERROR_CLUSTER_DATABASE_SEQMISMATCH +// +// MessageText: +// +// The join operation failed because the cluster database sequence number has changed or is incompatible with the locker node. This may happen during a join operation if the cluster database was changing during the join. +// +#define ERROR_CLUSTER_DATABASE_SEQMISMATCH 5083L + +// +// MessageId: ERROR_RESMON_INVALID_STATE +// +// MessageText: +// +// The resource monitor will not allow the fail operation to be performed while the resource is in its current state. This may happen if the resource is in a pending state. +// +#define ERROR_RESMON_INVALID_STATE 5084L + +// +// MessageId: ERROR_CLUSTER_GUM_NOT_LOCKER +// +// MessageText: +// +// A non locker code got a request to reserve the lock for making global updates. +// +#define ERROR_CLUSTER_GUM_NOT_LOCKER 5085L + +// +// MessageId: ERROR_QUORUM_DISK_NOT_FOUND +// +// MessageText: +// +// The quorum disk could not be located by the cluster service. +// +#define ERROR_QUORUM_DISK_NOT_FOUND 5086L + +// +// MessageId: ERROR_DATABASE_BACKUP_CORRUPT +// +// MessageText: +// +// The backed up cluster database is possibly corrupt. +// +#define ERROR_DATABASE_BACKUP_CORRUPT 5087L + +// +// MessageId: ERROR_CLUSTER_NODE_ALREADY_HAS_DFS_ROOT +// +// MessageText: +// +// A DFS root already exists in this cluster node. +// +#define ERROR_CLUSTER_NODE_ALREADY_HAS_DFS_ROOT 5088L + +// +// MessageId: ERROR_RESOURCE_PROPERTY_UNCHANGEABLE +// +// MessageText: +// +// An attempt to modify a resource property failed because it conflicts with another existing property. +// +#define ERROR_RESOURCE_PROPERTY_UNCHANGEABLE 5089L + +/* + Codes from 4300 through 5889 overlap with codes in ds\published\inc\apperr2.w. + Do not add any more error codes in that range. +*/ +// +// MessageId: ERROR_CLUSTER_MEMBERSHIP_INVALID_STATE +// +// MessageText: +// +// An operation was attempted that is incompatible with the current membership state of the node. +// +#define ERROR_CLUSTER_MEMBERSHIP_INVALID_STATE 5890L + +// +// MessageId: ERROR_CLUSTER_QUORUMLOG_NOT_FOUND +// +// MessageText: +// +// The quorum resource does not contain the quorum log. +// +#define ERROR_CLUSTER_QUORUMLOG_NOT_FOUND 5891L + +// +// MessageId: ERROR_CLUSTER_MEMBERSHIP_HALT +// +// MessageText: +// +// The membership engine requested shutdown of the cluster service on this node. +// +#define ERROR_CLUSTER_MEMBERSHIP_HALT 5892L + +// +// MessageId: ERROR_CLUSTER_INSTANCE_ID_MISMATCH +// +// MessageText: +// +// The join operation failed because the cluster instance ID of the joining node does not match the cluster instance ID of the sponsor node. +// +#define ERROR_CLUSTER_INSTANCE_ID_MISMATCH 5893L + +// +// MessageId: ERROR_CLUSTER_NETWORK_NOT_FOUND_FOR_IP +// +// MessageText: +// +// A matching network for the specified IP address could not be found. Please also specify a subnet mask and a cluster network. +// +#define ERROR_CLUSTER_NETWORK_NOT_FOUND_FOR_IP 5894L + +// +// MessageId: ERROR_CLUSTER_PROPERTY_DATA_TYPE_MISMATCH +// +// MessageText: +// +// The actual data type of the property did not match the expected data type of the property. +// +#define ERROR_CLUSTER_PROPERTY_DATA_TYPE_MISMATCH 5895L + +// +// MessageId: ERROR_CLUSTER_EVICT_WITHOUT_CLEANUP +// +// MessageText: +// +// The cluster node was evicted from the cluster successfully, but the node was not cleaned up. Extended status information explaining why the node was not cleaned up is available. +// +#define ERROR_CLUSTER_EVICT_WITHOUT_CLEANUP 5896L + +// +// MessageId: ERROR_CLUSTER_PARAMETER_MISMATCH +// +// MessageText: +// +// Two or more parameter values specified for a resource's properties are in conflict. +// +#define ERROR_CLUSTER_PARAMETER_MISMATCH 5897L + +// +// MessageId: ERROR_NODE_CANNOT_BE_CLUSTERED +// +// MessageText: +// +// This computer cannot be made a member of a cluster. +// +#define ERROR_NODE_CANNOT_BE_CLUSTERED 5898L + +// +// MessageId: ERROR_CLUSTER_WRONG_OS_VERSION +// +// MessageText: +// +// This computer cannot be made a member of a cluster because it does not have the correct version of Windows installed. +// +#define ERROR_CLUSTER_WRONG_OS_VERSION 5899L + +// +// MessageId: ERROR_CLUSTER_CANT_CREATE_DUP_CLUSTER_NAME +// +// MessageText: +// +// A cluster cannot be created with the specified cluster name because that cluster name is already in use. Specify a different name for the cluster. +// +#define ERROR_CLUSTER_CANT_CREATE_DUP_CLUSTER_NAME 5900L + +// +// MessageId: ERROR_CLUSCFG_ALREADY_COMMITTED +// +// MessageText: +// +// The cluster configuration action has already been committed. +// +#define ERROR_CLUSCFG_ALREADY_COMMITTED 5901L + +// +// MessageId: ERROR_CLUSCFG_ROLLBACK_FAILED +// +// MessageText: +// +// The cluster configuration action could not be rolled back. +// +#define ERROR_CLUSCFG_ROLLBACK_FAILED 5902L + +// +// MessageId: ERROR_CLUSCFG_SYSTEM_DISK_DRIVE_LETTER_CONFLICT +// +// MessageText: +// +// The drive letter assigned to a system disk on one node conflicted with the drive letter assigned to a disk on another node. +// +#define ERROR_CLUSCFG_SYSTEM_DISK_DRIVE_LETTER_CONFLICT 5903L + +// +// MessageId: ERROR_CLUSTER_OLD_VERSION +// +// MessageText: +// +// One or more nodes in the cluster are running a version of Windows that does not support this operation. +// +#define ERROR_CLUSTER_OLD_VERSION 5904L + +// +// MessageId: ERROR_CLUSTER_MISMATCHED_COMPUTER_ACCT_NAME +// +// MessageText: +// +// The name of the corresponding computer account doesn't match the Network Name for this resource. +// +#define ERROR_CLUSTER_MISMATCHED_COMPUTER_ACCT_NAME 5905L + +//////////////////////////////////// +// // +// EFS Error Codes // +// // +//////////////////////////////////// +// +// MessageId: ERROR_ENCRYPTION_FAILED +// +// MessageText: +// +// The specified file could not be encrypted. +// +#define ERROR_ENCRYPTION_FAILED 6000L + +// +// MessageId: ERROR_DECRYPTION_FAILED +// +// MessageText: +// +// The specified file could not be decrypted. +// +#define ERROR_DECRYPTION_FAILED 6001L + +// +// MessageId: ERROR_FILE_ENCRYPTED +// +// MessageText: +// +// The specified file is encrypted and the user does not have the ability to decrypt it. +// +#define ERROR_FILE_ENCRYPTED 6002L + +// +// MessageId: ERROR_NO_RECOVERY_POLICY +// +// MessageText: +// +// There is no valid encryption recovery policy configured for this system. +// +#define ERROR_NO_RECOVERY_POLICY 6003L + +// +// MessageId: ERROR_NO_EFS +// +// MessageText: +// +// The required encryption driver is not loaded for this system. +// +#define ERROR_NO_EFS 6004L + +// +// MessageId: ERROR_WRONG_EFS +// +// MessageText: +// +// The file was encrypted with a different encryption driver than is currently loaded. +// +#define ERROR_WRONG_EFS 6005L + +// +// MessageId: ERROR_NO_USER_KEYS +// +// MessageText: +// +// There are no EFS keys defined for the user. +// +#define ERROR_NO_USER_KEYS 6006L + +// +// MessageId: ERROR_FILE_NOT_ENCRYPTED +// +// MessageText: +// +// The specified file is not encrypted. +// +#define ERROR_FILE_NOT_ENCRYPTED 6007L + +// +// MessageId: ERROR_NOT_EXPORT_FORMAT +// +// MessageText: +// +// The specified file is not in the defined EFS export format. +// +#define ERROR_NOT_EXPORT_FORMAT 6008L + +// +// MessageId: ERROR_FILE_READ_ONLY +// +// MessageText: +// +// The specified file is read only. +// +#define ERROR_FILE_READ_ONLY 6009L + +// +// MessageId: ERROR_DIR_EFS_DISALLOWED +// +// MessageText: +// +// The directory has been disabled for encryption. +// +#define ERROR_DIR_EFS_DISALLOWED 6010L + +// +// MessageId: ERROR_EFS_SERVER_NOT_TRUSTED +// +// MessageText: +// +// The server is not trusted for remote encryption operation. +// +#define ERROR_EFS_SERVER_NOT_TRUSTED 6011L + +// +// MessageId: ERROR_BAD_RECOVERY_POLICY +// +// MessageText: +// +// Recovery policy configured for this system contains invalid recovery certificate. +// +#define ERROR_BAD_RECOVERY_POLICY 6012L + +// +// MessageId: ERROR_EFS_ALG_BLOB_TOO_BIG +// +// MessageText: +// +// The encryption algorithm used on the source file needs a bigger key buffer than the one on the destination file. +// +#define ERROR_EFS_ALG_BLOB_TOO_BIG 6013L + +// +// MessageId: ERROR_VOLUME_NOT_SUPPORT_EFS +// +// MessageText: +// +// The disk partition does not support file encryption. +// +#define ERROR_VOLUME_NOT_SUPPORT_EFS 6014L + +// +// MessageId: ERROR_EFS_DISABLED +// +// MessageText: +// +// This machine is disabled for file encryption. +// +#define ERROR_EFS_DISABLED 6015L + +// +// MessageId: ERROR_EFS_VERSION_NOT_SUPPORT +// +// MessageText: +// +// A newer system is required to decrypt this encrypted file. +// +#define ERROR_EFS_VERSION_NOT_SUPPORT 6016L + +// This message number is for historical purposes and cannot be changed or re-used. +// +// MessageId: ERROR_NO_BROWSER_SERVERS_FOUND +// +// MessageText: +// +// The list of servers for this workgroup is not currently available +// +#define ERROR_NO_BROWSER_SERVERS_FOUND 6118L + +////////////////////////////////////////////////////////////////// +// // +// Task Scheduler Error Codes that NET START must understand // +// // +////////////////////////////////////////////////////////////////// +// +// MessageId: SCHED_E_SERVICE_NOT_LOCALSYSTEM +// +// MessageText: +// +// The Task Scheduler service must be configured to run in the System account to function properly. Individual tasks may be configured to run in other accounts. +// +#define SCHED_E_SERVICE_NOT_LOCALSYSTEM 6200L + +//////////////////////////////////// +// // +// Terminal Server Error Codes // +// // +//////////////////////////////////// +// +// MessageId: ERROR_CTX_WINSTATION_NAME_INVALID +// +// MessageText: +// +// The specified session name is invalid. +// +#define ERROR_CTX_WINSTATION_NAME_INVALID 7001L + +// +// MessageId: ERROR_CTX_INVALID_PD +// +// MessageText: +// +// The specified protocol driver is invalid. +// +#define ERROR_CTX_INVALID_PD 7002L + +// +// MessageId: ERROR_CTX_PD_NOT_FOUND +// +// MessageText: +// +// The specified protocol driver was not found in the system path. +// +#define ERROR_CTX_PD_NOT_FOUND 7003L + +// +// MessageId: ERROR_CTX_WD_NOT_FOUND +// +// MessageText: +// +// The specified terminal connection driver was not found in the system path. +// +#define ERROR_CTX_WD_NOT_FOUND 7004L + +// +// MessageId: ERROR_CTX_CANNOT_MAKE_EVENTLOG_ENTRY +// +// MessageText: +// +// A registry key for event logging could not be created for this session. +// +#define ERROR_CTX_CANNOT_MAKE_EVENTLOG_ENTRY 7005L + +// +// MessageId: ERROR_CTX_SERVICE_NAME_COLLISION +// +// MessageText: +// +// A service with the same name already exists on the system. +// +#define ERROR_CTX_SERVICE_NAME_COLLISION 7006L + +// +// MessageId: ERROR_CTX_CLOSE_PENDING +// +// MessageText: +// +// A close operation is pending on the session. +// +#define ERROR_CTX_CLOSE_PENDING 7007L + +// +// MessageId: ERROR_CTX_NO_OUTBUF +// +// MessageText: +// +// There are no free output buffers available. +// +#define ERROR_CTX_NO_OUTBUF 7008L + +// +// MessageId: ERROR_CTX_MODEM_INF_NOT_FOUND +// +// MessageText: +// +// The MODEM.INF file was not found. +// +#define ERROR_CTX_MODEM_INF_NOT_FOUND 7009L + +// +// MessageId: ERROR_CTX_INVALID_MODEMNAME +// +// MessageText: +// +// The modem name was not found in MODEM.INF. +// +#define ERROR_CTX_INVALID_MODEMNAME 7010L + +// +// MessageId: ERROR_CTX_MODEM_RESPONSE_ERROR +// +// MessageText: +// +// The modem did not accept the command sent to it. Verify that the configured modem name matches the attached modem. +// +#define ERROR_CTX_MODEM_RESPONSE_ERROR 7011L + +// +// MessageId: ERROR_CTX_MODEM_RESPONSE_TIMEOUT +// +// MessageText: +// +// The modem did not respond to the command sent to it. Verify that the modem is properly cabled and powered on. +// +#define ERROR_CTX_MODEM_RESPONSE_TIMEOUT 7012L + +// +// MessageId: ERROR_CTX_MODEM_RESPONSE_NO_CARRIER +// +// MessageText: +// +// Carrier detect has failed or carrier has been dropped due to disconnect. +// +#define ERROR_CTX_MODEM_RESPONSE_NO_CARRIER 7013L + +// +// MessageId: ERROR_CTX_MODEM_RESPONSE_NO_DIALTONE +// +// MessageText: +// +// Dial tone not detected within the required time. Verify that the phone cable is properly attached and functional. +// +#define ERROR_CTX_MODEM_RESPONSE_NO_DIALTONE 7014L + +// +// MessageId: ERROR_CTX_MODEM_RESPONSE_BUSY +// +// MessageText: +// +// Busy signal detected at remote site on callback. +// +#define ERROR_CTX_MODEM_RESPONSE_BUSY 7015L + +// +// MessageId: ERROR_CTX_MODEM_RESPONSE_VOICE +// +// MessageText: +// +// Voice detected at remote site on callback. +// +#define ERROR_CTX_MODEM_RESPONSE_VOICE 7016L + +// +// MessageId: ERROR_CTX_TD_ERROR +// +// MessageText: +// +// Transport driver error +// +#define ERROR_CTX_TD_ERROR 7017L + +// +// MessageId: ERROR_CTX_WINSTATION_NOT_FOUND +// +// MessageText: +// +// The specified session cannot be found. +// +#define ERROR_CTX_WINSTATION_NOT_FOUND 7022L + +// +// MessageId: ERROR_CTX_WINSTATION_ALREADY_EXISTS +// +// MessageText: +// +// The specified session name is already in use. +// +#define ERROR_CTX_WINSTATION_ALREADY_EXISTS 7023L + +// +// MessageId: ERROR_CTX_WINSTATION_BUSY +// +// MessageText: +// +// The requested operation cannot be completed because the terminal connection is currently busy processing a connect, disconnect, reset, or delete operation. +// +#define ERROR_CTX_WINSTATION_BUSY 7024L + +// +// MessageId: ERROR_CTX_BAD_VIDEO_MODE +// +// MessageText: +// +// An attempt has been made to connect to a session whose video mode is not supported by the current client. +// +#define ERROR_CTX_BAD_VIDEO_MODE 7025L + +// +// MessageId: ERROR_CTX_GRAPHICS_INVALID +// +// MessageText: +// +// The application attempted to enable DOS graphics mode. +// DOS graphics mode is not supported. +// +#define ERROR_CTX_GRAPHICS_INVALID 7035L + +// +// MessageId: ERROR_CTX_LOGON_DISABLED +// +// MessageText: +// +// Your interactive logon privilege has been disabled. +// Please contact your administrator. +// +#define ERROR_CTX_LOGON_DISABLED 7037L + +// +// MessageId: ERROR_CTX_NOT_CONSOLE +// +// MessageText: +// +// The requested operation can be performed only on the system console. +// This is most often the result of a driver or system DLL requiring direct console access. +// +#define ERROR_CTX_NOT_CONSOLE 7038L + +// +// MessageId: ERROR_CTX_CLIENT_QUERY_TIMEOUT +// +// MessageText: +// +// The client failed to respond to the server connect message. +// +#define ERROR_CTX_CLIENT_QUERY_TIMEOUT 7040L + +// +// MessageId: ERROR_CTX_CONSOLE_DISCONNECT +// +// MessageText: +// +// Disconnecting the console session is not supported. +// +#define ERROR_CTX_CONSOLE_DISCONNECT 7041L + +// +// MessageId: ERROR_CTX_CONSOLE_CONNECT +// +// MessageText: +// +// Reconnecting a disconnected session to the console is not supported. +// +#define ERROR_CTX_CONSOLE_CONNECT 7042L + +// +// MessageId: ERROR_CTX_SHADOW_DENIED +// +// MessageText: +// +// The request to control another session remotely was denied. +// +#define ERROR_CTX_SHADOW_DENIED 7044L + +// +// MessageId: ERROR_CTX_WINSTATION_ACCESS_DENIED +// +// MessageText: +// +// The requested session access is denied. +// +#define ERROR_CTX_WINSTATION_ACCESS_DENIED 7045L + +// +// MessageId: ERROR_CTX_INVALID_WD +// +// MessageText: +// +// The specified terminal connection driver is invalid. +// +#define ERROR_CTX_INVALID_WD 7049L + +// +// MessageId: ERROR_CTX_SHADOW_INVALID +// +// MessageText: +// +// The requested session cannot be controlled remotely. +// This may be because the session is disconnected or does not currently have a user logged on. +// +#define ERROR_CTX_SHADOW_INVALID 7050L + +// +// MessageId: ERROR_CTX_SHADOW_DISABLED +// +// MessageText: +// +// The requested session is not configured to allow remote control. +// +#define ERROR_CTX_SHADOW_DISABLED 7051L + +// +// MessageId: ERROR_CTX_CLIENT_LICENSE_IN_USE +// +// MessageText: +// +// Your request to connect to this Terminal Server has been rejected. Your Terminal Server client license number is currently being used by another user. +// Please call your system administrator to obtain a unique license number. +// +#define ERROR_CTX_CLIENT_LICENSE_IN_USE 7052L + +// +// MessageId: ERROR_CTX_CLIENT_LICENSE_NOT_SET +// +// MessageText: +// +// Your request to connect to this Terminal Server has been rejected. Your Terminal Server client license number has not been entered for this copy of the Terminal Server client. +// Please contact your system administrator. +// +#define ERROR_CTX_CLIENT_LICENSE_NOT_SET 7053L + +// +// MessageId: ERROR_CTX_LICENSE_NOT_AVAILABLE +// +// MessageText: +// +// The system has reached its licensed logon limit. +// Please try again later. +// +#define ERROR_CTX_LICENSE_NOT_AVAILABLE 7054L + +// +// MessageId: ERROR_CTX_LICENSE_CLIENT_INVALID +// +// MessageText: +// +// The client you are using is not licensed to use this system. Your logon request is denied. +// +#define ERROR_CTX_LICENSE_CLIENT_INVALID 7055L + +// +// MessageId: ERROR_CTX_LICENSE_EXPIRED +// +// MessageText: +// +// The system license has expired. Your logon request is denied. +// +#define ERROR_CTX_LICENSE_EXPIRED 7056L + +// +// MessageId: ERROR_CTX_SHADOW_NOT_RUNNING +// +// MessageText: +// +// Remote control could not be terminated because the specified session is not currently being remotely controlled. +// +#define ERROR_CTX_SHADOW_NOT_RUNNING 7057L + +// +// MessageId: ERROR_CTX_SHADOW_ENDED_BY_MODE_CHANGE +// +// MessageText: +// +// The remote control of the console was terminated because the display mode was changed. Changing the display mode in a remote control session is not supported. +// +#define ERROR_CTX_SHADOW_ENDED_BY_MODE_CHANGE 7058L + +// +// MessageId: ERROR_ACTIVATION_COUNT_EXCEEDED +// +// MessageText: +// +// Activation has already been reset the maximum number of times for this installation. Your activation timer will not be cleared. +// +#define ERROR_ACTIVATION_COUNT_EXCEEDED 7059L + +/////////////////////////////////////////////////// +// / +// Traffic Control Error Codes / +// / +// 7500 to 7999 / +// / +// defined in: tcerror.h / +/////////////////////////////////////////////////// +/////////////////////////////////////////////////// +// / +// Active Directory Error Codes / +// / +// 8000 to 8999 / +/////////////////////////////////////////////////// +// ***************** +// FACILITY_FILE_REPLICATION_SERVICE +// ***************** +// +// MessageId: FRS_ERR_INVALID_API_SEQUENCE +// +// MessageText: +// +// The file replication service API was called incorrectly. +// +#define FRS_ERR_INVALID_API_SEQUENCE 8001L + +// +// MessageId: FRS_ERR_STARTING_SERVICE +// +// MessageText: +// +// The file replication service cannot be started. +// +#define FRS_ERR_STARTING_SERVICE 8002L + +// +// MessageId: FRS_ERR_STOPPING_SERVICE +// +// MessageText: +// +// The file replication service cannot be stopped. +// +#define FRS_ERR_STOPPING_SERVICE 8003L + +// +// MessageId: FRS_ERR_INTERNAL_API +// +// MessageText: +// +// The file replication service API terminated the request. +// The event log may have more information. +// +#define FRS_ERR_INTERNAL_API 8004L + +// +// MessageId: FRS_ERR_INTERNAL +// +// MessageText: +// +// The file replication service terminated the request. +// The event log may have more information. +// +#define FRS_ERR_INTERNAL 8005L + +// +// MessageId: FRS_ERR_SERVICE_COMM +// +// MessageText: +// +// The file replication service cannot be contacted. +// The event log may have more information. +// +#define FRS_ERR_SERVICE_COMM 8006L + +// +// MessageId: FRS_ERR_INSUFFICIENT_PRIV +// +// MessageText: +// +// The file replication service cannot satisfy the request because the user has insufficient privileges. +// The event log may have more information. +// +#define FRS_ERR_INSUFFICIENT_PRIV 8007L + +// +// MessageId: FRS_ERR_AUTHENTICATION +// +// MessageText: +// +// The file replication service cannot satisfy the request because authenticated RPC is not available. +// The event log may have more information. +// +#define FRS_ERR_AUTHENTICATION 8008L + +// +// MessageId: FRS_ERR_PARENT_INSUFFICIENT_PRIV +// +// MessageText: +// +// The file replication service cannot satisfy the request because the user has insufficient privileges on the domain controller. +// The event log may have more information. +// +#define FRS_ERR_PARENT_INSUFFICIENT_PRIV 8009L + +// +// MessageId: FRS_ERR_PARENT_AUTHENTICATION +// +// MessageText: +// +// The file replication service cannot satisfy the request because authenticated RPC is not available on the domain controller. +// The event log may have more information. +// +#define FRS_ERR_PARENT_AUTHENTICATION 8010L + +// +// MessageId: FRS_ERR_CHILD_TO_PARENT_COMM +// +// MessageText: +// +// The file replication service cannot communicate with the file replication service on the domain controller. +// The event log may have more information. +// +#define FRS_ERR_CHILD_TO_PARENT_COMM 8011L + +// +// MessageId: FRS_ERR_PARENT_TO_CHILD_COMM +// +// MessageText: +// +// The file replication service on the domain controller cannot communicate with the file replication service on this computer. +// The event log may have more information. +// +#define FRS_ERR_PARENT_TO_CHILD_COMM 8012L + +// +// MessageId: FRS_ERR_SYSVOL_POPULATE +// +// MessageText: +// +// The file replication service cannot populate the system volume because of an internal error. +// The event log may have more information. +// +#define FRS_ERR_SYSVOL_POPULATE 8013L + +// +// MessageId: FRS_ERR_SYSVOL_POPULATE_TIMEOUT +// +// MessageText: +// +// The file replication service cannot populate the system volume because of an internal timeout. +// The event log may have more information. +// +#define FRS_ERR_SYSVOL_POPULATE_TIMEOUT 8014L + +// +// MessageId: FRS_ERR_SYSVOL_IS_BUSY +// +// MessageText: +// +// The file replication service cannot process the request. The system volume is busy with a previous request. +// +#define FRS_ERR_SYSVOL_IS_BUSY 8015L + +// +// MessageId: FRS_ERR_SYSVOL_DEMOTE +// +// MessageText: +// +// The file replication service cannot stop replicating the system volume because of an internal error. +// The event log may have more information. +// +#define FRS_ERR_SYSVOL_DEMOTE 8016L + +// +// MessageId: FRS_ERR_INVALID_SERVICE_PARAMETER +// +// MessageText: +// +// The file replication service detected an invalid parameter. +// +#define FRS_ERR_INVALID_SERVICE_PARAMETER 8017L + +// ***************** +// FACILITY DIRECTORY SERVICE +// ***************** +#define DS_S_SUCCESS NO_ERROR +// +// MessageId: ERROR_DS_NOT_INSTALLED +// +// MessageText: +// +// An error occurred while installing the directory service. For more information, see the event log. +// +#define ERROR_DS_NOT_INSTALLED 8200L + +// +// MessageId: ERROR_DS_MEMBERSHIP_EVALUATED_LOCALLY +// +// MessageText: +// +// The directory service evaluated group memberships locally. +// +#define ERROR_DS_MEMBERSHIP_EVALUATED_LOCALLY 8201L + +// +// MessageId: ERROR_DS_NO_ATTRIBUTE_OR_VALUE +// +// MessageText: +// +// The specified directory service attribute or value does not exist. +// +#define ERROR_DS_NO_ATTRIBUTE_OR_VALUE 8202L + +// +// MessageId: ERROR_DS_INVALID_ATTRIBUTE_SYNTAX +// +// MessageText: +// +// The attribute syntax specified to the directory service is invalid. +// +#define ERROR_DS_INVALID_ATTRIBUTE_SYNTAX 8203L + +// +// MessageId: ERROR_DS_ATTRIBUTE_TYPE_UNDEFINED +// +// MessageText: +// +// The attribute type specified to the directory service is not defined. +// +#define ERROR_DS_ATTRIBUTE_TYPE_UNDEFINED 8204L + +// +// MessageId: ERROR_DS_ATTRIBUTE_OR_VALUE_EXISTS +// +// MessageText: +// +// The specified directory service attribute or value already exists. +// +#define ERROR_DS_ATTRIBUTE_OR_VALUE_EXISTS 8205L + +// +// MessageId: ERROR_DS_BUSY +// +// MessageText: +// +// The directory service is busy. +// +#define ERROR_DS_BUSY 8206L + +// +// MessageId: ERROR_DS_UNAVAILABLE +// +// MessageText: +// +// The directory service is unavailable. +// +#define ERROR_DS_UNAVAILABLE 8207L + +// +// MessageId: ERROR_DS_NO_RIDS_ALLOCATED +// +// MessageText: +// +// The directory service was unable to allocate a relative identifier. +// +#define ERROR_DS_NO_RIDS_ALLOCATED 8208L + +// +// MessageId: ERROR_DS_NO_MORE_RIDS +// +// MessageText: +// +// The directory service has exhausted the pool of relative identifiers. +// +#define ERROR_DS_NO_MORE_RIDS 8209L + +// +// MessageId: ERROR_DS_INCORRECT_ROLE_OWNER +// +// MessageText: +// +// The requested operation could not be performed because the directory service is not the master for that type of operation. +// +#define ERROR_DS_INCORRECT_ROLE_OWNER 8210L + +// +// MessageId: ERROR_DS_RIDMGR_INIT_ERROR +// +// MessageText: +// +// The directory service was unable to initialize the subsystem that allocates relative identifiers. +// +#define ERROR_DS_RIDMGR_INIT_ERROR 8211L + +// +// MessageId: ERROR_DS_OBJ_CLASS_VIOLATION +// +// MessageText: +// +// The requested operation did not satisfy one or more constraints associated with the class of the object. +// +#define ERROR_DS_OBJ_CLASS_VIOLATION 8212L + +// +// MessageId: ERROR_DS_CANT_ON_NON_LEAF +// +// MessageText: +// +// The directory service can perform the requested operation only on a leaf object. +// +#define ERROR_DS_CANT_ON_NON_LEAF 8213L + +// +// MessageId: ERROR_DS_CANT_ON_RDN +// +// MessageText: +// +// The directory service cannot perform the requested operation on the RDN attribute of an object. +// +#define ERROR_DS_CANT_ON_RDN 8214L + +// +// MessageId: ERROR_DS_CANT_MOD_OBJ_CLASS +// +// MessageText: +// +// The directory service detected an attempt to modify the object class of an object. +// +#define ERROR_DS_CANT_MOD_OBJ_CLASS 8215L + +// +// MessageId: ERROR_DS_CROSS_DOM_MOVE_ERROR +// +// MessageText: +// +// The requested cross-domain move operation could not be performed. +// +#define ERROR_DS_CROSS_DOM_MOVE_ERROR 8216L + +// +// MessageId: ERROR_DS_GC_NOT_AVAILABLE +// +// MessageText: +// +// Unable to contact the global catalog server. +// +#define ERROR_DS_GC_NOT_AVAILABLE 8217L + +// +// MessageId: ERROR_SHARED_POLICY +// +// MessageText: +// +// The policy object is shared and can only be modified at the root. +// +#define ERROR_SHARED_POLICY 8218L + +// +// MessageId: ERROR_POLICY_OBJECT_NOT_FOUND +// +// MessageText: +// +// The policy object does not exist. +// +#define ERROR_POLICY_OBJECT_NOT_FOUND 8219L + +// +// MessageId: ERROR_POLICY_ONLY_IN_DS +// +// MessageText: +// +// The requested policy information is only in the directory service. +// +#define ERROR_POLICY_ONLY_IN_DS 8220L + +// +// MessageId: ERROR_PROMOTION_ACTIVE +// +// MessageText: +// +// A domain controller promotion is currently active. +// +#define ERROR_PROMOTION_ACTIVE 8221L + +// +// MessageId: ERROR_NO_PROMOTION_ACTIVE +// +// MessageText: +// +// A domain controller promotion is not currently active +// +#define ERROR_NO_PROMOTION_ACTIVE 8222L + +// 8223 unused +// +// MessageId: ERROR_DS_OPERATIONS_ERROR +// +// MessageText: +// +// An operations error occurred. +// +#define ERROR_DS_OPERATIONS_ERROR 8224L + +// +// MessageId: ERROR_DS_PROTOCOL_ERROR +// +// MessageText: +// +// A protocol error occurred. +// +#define ERROR_DS_PROTOCOL_ERROR 8225L + +// +// MessageId: ERROR_DS_TIMELIMIT_EXCEEDED +// +// MessageText: +// +// The time limit for this request was exceeded. +// +#define ERROR_DS_TIMELIMIT_EXCEEDED 8226L + +// +// MessageId: ERROR_DS_SIZELIMIT_EXCEEDED +// +// MessageText: +// +// The size limit for this request was exceeded. +// +#define ERROR_DS_SIZELIMIT_EXCEEDED 8227L + +// +// MessageId: ERROR_DS_ADMIN_LIMIT_EXCEEDED +// +// MessageText: +// +// The administrative limit for this request was exceeded. +// +#define ERROR_DS_ADMIN_LIMIT_EXCEEDED 8228L + +// +// MessageId: ERROR_DS_COMPARE_FALSE +// +// MessageText: +// +// The compare response was false. +// +#define ERROR_DS_COMPARE_FALSE 8229L + +// +// MessageId: ERROR_DS_COMPARE_TRUE +// +// MessageText: +// +// The compare response was true. +// +#define ERROR_DS_COMPARE_TRUE 8230L + +// +// MessageId: ERROR_DS_AUTH_METHOD_NOT_SUPPORTED +// +// MessageText: +// +// The requested authentication method is not supported by the server. +// +#define ERROR_DS_AUTH_METHOD_NOT_SUPPORTED 8231L + +// +// MessageId: ERROR_DS_STRONG_AUTH_REQUIRED +// +// MessageText: +// +// A more secure authentication method is required for this server. +// +#define ERROR_DS_STRONG_AUTH_REQUIRED 8232L + +// +// MessageId: ERROR_DS_INAPPROPRIATE_AUTH +// +// MessageText: +// +// Inappropriate authentication. +// +#define ERROR_DS_INAPPROPRIATE_AUTH 8233L + +// +// MessageId: ERROR_DS_AUTH_UNKNOWN +// +// MessageText: +// +// The authentication mechanism is unknown. +// +#define ERROR_DS_AUTH_UNKNOWN 8234L + +// +// MessageId: ERROR_DS_REFERRAL +// +// MessageText: +// +// A referral was returned from the server. +// +#define ERROR_DS_REFERRAL 8235L + +// +// MessageId: ERROR_DS_UNAVAILABLE_CRIT_EXTENSION +// +// MessageText: +// +// The server does not support the requested critical extension. +// +#define ERROR_DS_UNAVAILABLE_CRIT_EXTENSION 8236L + +// +// MessageId: ERROR_DS_CONFIDENTIALITY_REQUIRED +// +// MessageText: +// +// This request requires a secure connection. +// +#define ERROR_DS_CONFIDENTIALITY_REQUIRED 8237L + +// +// MessageId: ERROR_DS_INAPPROPRIATE_MATCHING +// +// MessageText: +// +// Inappropriate matching. +// +#define ERROR_DS_INAPPROPRIATE_MATCHING 8238L + +// +// MessageId: ERROR_DS_CONSTRAINT_VIOLATION +// +// MessageText: +// +// A constraint violation occurred. +// +#define ERROR_DS_CONSTRAINT_VIOLATION 8239L + +// +// MessageId: ERROR_DS_NO_SUCH_OBJECT +// +// MessageText: +// +// There is no such object on the server. +// +#define ERROR_DS_NO_SUCH_OBJECT 8240L + +// +// MessageId: ERROR_DS_ALIAS_PROBLEM +// +// MessageText: +// +// There is an alias problem. +// +#define ERROR_DS_ALIAS_PROBLEM 8241L + +// +// MessageId: ERROR_DS_INVALID_DN_SYNTAX +// +// MessageText: +// +// An invalid dn syntax has been specified. +// +#define ERROR_DS_INVALID_DN_SYNTAX 8242L + +// +// MessageId: ERROR_DS_IS_LEAF +// +// MessageText: +// +// The object is a leaf object. +// +#define ERROR_DS_IS_LEAF 8243L + +// +// MessageId: ERROR_DS_ALIAS_DEREF_PROBLEM +// +// MessageText: +// +// There is an alias dereferencing problem. +// +#define ERROR_DS_ALIAS_DEREF_PROBLEM 8244L + +// +// MessageId: ERROR_DS_UNWILLING_TO_PERFORM +// +// MessageText: +// +// The server is unwilling to process the request. +// +#define ERROR_DS_UNWILLING_TO_PERFORM 8245L + +// +// MessageId: ERROR_DS_LOOP_DETECT +// +// MessageText: +// +// A loop has been detected. +// +#define ERROR_DS_LOOP_DETECT 8246L + +// +// MessageId: ERROR_DS_NAMING_VIOLATION +// +// MessageText: +// +// There is a naming violation. +// +#define ERROR_DS_NAMING_VIOLATION 8247L + +// +// MessageId: ERROR_DS_OBJECT_RESULTS_TOO_LARGE +// +// MessageText: +// +// The result set is too large. +// +#define ERROR_DS_OBJECT_RESULTS_TOO_LARGE 8248L + +// +// MessageId: ERROR_DS_AFFECTS_MULTIPLE_DSAS +// +// MessageText: +// +// The operation affects multiple DSAs +// +#define ERROR_DS_AFFECTS_MULTIPLE_DSAS 8249L + +// +// MessageId: ERROR_DS_SERVER_DOWN +// +// MessageText: +// +// The server is not operational. +// +#define ERROR_DS_SERVER_DOWN 8250L + +// +// MessageId: ERROR_DS_LOCAL_ERROR +// +// MessageText: +// +// A local error has occurred. +// +#define ERROR_DS_LOCAL_ERROR 8251L + +// +// MessageId: ERROR_DS_ENCODING_ERROR +// +// MessageText: +// +// An encoding error has occurred. +// +#define ERROR_DS_ENCODING_ERROR 8252L + +// +// MessageId: ERROR_DS_DECODING_ERROR +// +// MessageText: +// +// A decoding error has occurred. +// +#define ERROR_DS_DECODING_ERROR 8253L + +// +// MessageId: ERROR_DS_FILTER_UNKNOWN +// +// MessageText: +// +// The search filter cannot be recognized. +// +#define ERROR_DS_FILTER_UNKNOWN 8254L + +// +// MessageId: ERROR_DS_PARAM_ERROR +// +// MessageText: +// +// One or more parameters are illegal. +// +#define ERROR_DS_PARAM_ERROR 8255L + +// +// MessageId: ERROR_DS_NOT_SUPPORTED +// +// MessageText: +// +// The specified method is not supported. +// +#define ERROR_DS_NOT_SUPPORTED 8256L + +// +// MessageId: ERROR_DS_NO_RESULTS_RETURNED +// +// MessageText: +// +// No results were returned. +// +#define ERROR_DS_NO_RESULTS_RETURNED 8257L + +// +// MessageId: ERROR_DS_CONTROL_NOT_FOUND +// +// MessageText: +// +// The specified control is not supported by the server. +// +#define ERROR_DS_CONTROL_NOT_FOUND 8258L + +// +// MessageId: ERROR_DS_CLIENT_LOOP +// +// MessageText: +// +// A referral loop was detected by the client. +// +#define ERROR_DS_CLIENT_LOOP 8259L + +// +// MessageId: ERROR_DS_REFERRAL_LIMIT_EXCEEDED +// +// MessageText: +// +// The preset referral limit was exceeded. +// +#define ERROR_DS_REFERRAL_LIMIT_EXCEEDED 8260L + +// +// MessageId: ERROR_DS_SORT_CONTROL_MISSING +// +// MessageText: +// +// The search requires a SORT control. +// +#define ERROR_DS_SORT_CONTROL_MISSING 8261L + +// +// MessageId: ERROR_DS_OFFSET_RANGE_ERROR +// +// MessageText: +// +// The search results exceed the offset range specified. +// +#define ERROR_DS_OFFSET_RANGE_ERROR 8262L + +// +// MessageId: ERROR_DS_ROOT_MUST_BE_NC +// +// MessageText: +// +// The root object must be the head of a naming context. The root object cannot have an instantiated parent. +// +#define ERROR_DS_ROOT_MUST_BE_NC 8301L + +// +// MessageId: ERROR_DS_ADD_REPLICA_INHIBITED +// +// MessageText: +// +// The add replica operation cannot be performed. The naming context must be writeable in order to create the replica. +// +#define ERROR_DS_ADD_REPLICA_INHIBITED 8302L + +// +// MessageId: ERROR_DS_ATT_NOT_DEF_IN_SCHEMA +// +// MessageText: +// +// A reference to an attribute that is not defined in the schema occurred. +// +#define ERROR_DS_ATT_NOT_DEF_IN_SCHEMA 8303L + +// +// MessageId: ERROR_DS_MAX_OBJ_SIZE_EXCEEDED +// +// MessageText: +// +// The maximum size of an object has been exceeded. +// +#define ERROR_DS_MAX_OBJ_SIZE_EXCEEDED 8304L + +// +// MessageId: ERROR_DS_OBJ_STRING_NAME_EXISTS +// +// MessageText: +// +// An attempt was made to add an object to the directory with a name that is already in use. +// +#define ERROR_DS_OBJ_STRING_NAME_EXISTS 8305L + +// +// MessageId: ERROR_DS_NO_RDN_DEFINED_IN_SCHEMA +// +// MessageText: +// +// An attempt was made to add an object of a class that does not have an RDN defined in the schema. +// +#define ERROR_DS_NO_RDN_DEFINED_IN_SCHEMA 8306L + +// +// MessageId: ERROR_DS_RDN_DOESNT_MATCH_SCHEMA +// +// MessageText: +// +// An attempt was made to add an object using an RDN that is not the RDN defined in the schema. +// +#define ERROR_DS_RDN_DOESNT_MATCH_SCHEMA 8307L + +// +// MessageId: ERROR_DS_NO_REQUESTED_ATTS_FOUND +// +// MessageText: +// +// None of the requested attributes were found on the objects. +// +#define ERROR_DS_NO_REQUESTED_ATTS_FOUND 8308L + +// +// MessageId: ERROR_DS_USER_BUFFER_TO_SMALL +// +// MessageText: +// +// The user buffer is too small. +// +#define ERROR_DS_USER_BUFFER_TO_SMALL 8309L + +// +// MessageId: ERROR_DS_ATT_IS_NOT_ON_OBJ +// +// MessageText: +// +// The attribute specified in the operation is not present on the object. +// +#define ERROR_DS_ATT_IS_NOT_ON_OBJ 8310L + +// +// MessageId: ERROR_DS_ILLEGAL_MOD_OPERATION +// +// MessageText: +// +// Illegal modify operation. Some aspect of the modification is not permitted. +// +#define ERROR_DS_ILLEGAL_MOD_OPERATION 8311L + +// +// MessageId: ERROR_DS_OBJ_TOO_LARGE +// +// MessageText: +// +// The specified object is too large. +// +#define ERROR_DS_OBJ_TOO_LARGE 8312L + +// +// MessageId: ERROR_DS_BAD_INSTANCE_TYPE +// +// MessageText: +// +// The specified instance type is not valid. +// +#define ERROR_DS_BAD_INSTANCE_TYPE 8313L + +// +// MessageId: ERROR_DS_MASTERDSA_REQUIRED +// +// MessageText: +// +// The operation must be performed at a master DSA. +// +#define ERROR_DS_MASTERDSA_REQUIRED 8314L + +// +// MessageId: ERROR_DS_OBJECT_CLASS_REQUIRED +// +// MessageText: +// +// The object class attribute must be specified. +// +#define ERROR_DS_OBJECT_CLASS_REQUIRED 8315L + +// +// MessageId: ERROR_DS_MISSING_REQUIRED_ATT +// +// MessageText: +// +// A required attribute is missing. +// +#define ERROR_DS_MISSING_REQUIRED_ATT 8316L + +// +// MessageId: ERROR_DS_ATT_NOT_DEF_FOR_CLASS +// +// MessageText: +// +// An attempt was made to modify an object to include an attribute that is not legal for its class. +// +#define ERROR_DS_ATT_NOT_DEF_FOR_CLASS 8317L + +// +// MessageId: ERROR_DS_ATT_ALREADY_EXISTS +// +// MessageText: +// +// The specified attribute is already present on the object. +// +#define ERROR_DS_ATT_ALREADY_EXISTS 8318L + +// 8319 unused +// +// MessageId: ERROR_DS_CANT_ADD_ATT_VALUES +// +// MessageText: +// +// The specified attribute is not present, or has no values. +// +#define ERROR_DS_CANT_ADD_ATT_VALUES 8320L + +// +// MessageId: ERROR_DS_SINGLE_VALUE_CONSTRAINT +// +// MessageText: +// +// Multiple values were specified for an attribute that can have only one value. +// +#define ERROR_DS_SINGLE_VALUE_CONSTRAINT 8321L + +// +// MessageId: ERROR_DS_RANGE_CONSTRAINT +// +// MessageText: +// +// A value for the attribute was not in the acceptable range of values. +// +#define ERROR_DS_RANGE_CONSTRAINT 8322L + +// +// MessageId: ERROR_DS_ATT_VAL_ALREADY_EXISTS +// +// MessageText: +// +// The specified value already exists. +// +#define ERROR_DS_ATT_VAL_ALREADY_EXISTS 8323L + +// +// MessageId: ERROR_DS_CANT_REM_MISSING_ATT +// +// MessageText: +// +// The attribute cannot be removed because it is not present on the object. +// +#define ERROR_DS_CANT_REM_MISSING_ATT 8324L + +// +// MessageId: ERROR_DS_CANT_REM_MISSING_ATT_VAL +// +// MessageText: +// +// The attribute value cannot be removed because it is not present on the object. +// +#define ERROR_DS_CANT_REM_MISSING_ATT_VAL 8325L + +// +// MessageId: ERROR_DS_ROOT_CANT_BE_SUBREF +// +// MessageText: +// +// The specified root object cannot be a subref. +// +#define ERROR_DS_ROOT_CANT_BE_SUBREF 8326L + +// +// MessageId: ERROR_DS_NO_CHAINING +// +// MessageText: +// +// Chaining is not permitted. +// +#define ERROR_DS_NO_CHAINING 8327L + +// +// MessageId: ERROR_DS_NO_CHAINED_EVAL +// +// MessageText: +// +// Chained evaluation is not permitted. +// +#define ERROR_DS_NO_CHAINED_EVAL 8328L + +// +// MessageId: ERROR_DS_NO_PARENT_OBJECT +// +// MessageText: +// +// The operation could not be performed because the object's parent is either uninstantiated or deleted. +// +#define ERROR_DS_NO_PARENT_OBJECT 8329L + +// +// MessageId: ERROR_DS_PARENT_IS_AN_ALIAS +// +// MessageText: +// +// Having a parent that is an alias is not permitted. Aliases are leaf objects. +// +#define ERROR_DS_PARENT_IS_AN_ALIAS 8330L + +// +// MessageId: ERROR_DS_CANT_MIX_MASTER_AND_REPS +// +// MessageText: +// +// The object and parent must be of the same type, either both masters or both replicas. +// +#define ERROR_DS_CANT_MIX_MASTER_AND_REPS 8331L + +// +// MessageId: ERROR_DS_CHILDREN_EXIST +// +// MessageText: +// +// The operation cannot be performed because child objects exist. This operation can only be performed on a leaf object. +// +#define ERROR_DS_CHILDREN_EXIST 8332L + +// +// MessageId: ERROR_DS_OBJ_NOT_FOUND +// +// MessageText: +// +// Directory object not found. +// +#define ERROR_DS_OBJ_NOT_FOUND 8333L + +// +// MessageId: ERROR_DS_ALIASED_OBJ_MISSING +// +// MessageText: +// +// The aliased object is missing. +// +#define ERROR_DS_ALIASED_OBJ_MISSING 8334L + +// +// MessageId: ERROR_DS_BAD_NAME_SYNTAX +// +// MessageText: +// +// The object name has bad syntax. +// +#define ERROR_DS_BAD_NAME_SYNTAX 8335L + +// +// MessageId: ERROR_DS_ALIAS_POINTS_TO_ALIAS +// +// MessageText: +// +// It is not permitted for an alias to refer to another alias. +// +#define ERROR_DS_ALIAS_POINTS_TO_ALIAS 8336L + +// +// MessageId: ERROR_DS_CANT_DEREF_ALIAS +// +// MessageText: +// +// The alias cannot be dereferenced. +// +#define ERROR_DS_CANT_DEREF_ALIAS 8337L + +// +// MessageId: ERROR_DS_OUT_OF_SCOPE +// +// MessageText: +// +// The operation is out of scope. +// +#define ERROR_DS_OUT_OF_SCOPE 8338L + +// +// MessageId: ERROR_DS_OBJECT_BEING_REMOVED +// +// MessageText: +// +// The operation cannot continue because the object is in the process of being removed. +// +#define ERROR_DS_OBJECT_BEING_REMOVED 8339L + +// +// MessageId: ERROR_DS_CANT_DELETE_DSA_OBJ +// +// MessageText: +// +// The DSA object cannot be deleted. +// +#define ERROR_DS_CANT_DELETE_DSA_OBJ 8340L + +// +// MessageId: ERROR_DS_GENERIC_ERROR +// +// MessageText: +// +// A directory service error has occurred. +// +#define ERROR_DS_GENERIC_ERROR 8341L + +// +// MessageId: ERROR_DS_DSA_MUST_BE_INT_MASTER +// +// MessageText: +// +// The operation can only be performed on an internal master DSA object. +// +#define ERROR_DS_DSA_MUST_BE_INT_MASTER 8342L + +// +// MessageId: ERROR_DS_CLASS_NOT_DSA +// +// MessageText: +// +// The object must be of class DSA. +// +#define ERROR_DS_CLASS_NOT_DSA 8343L + +// +// MessageId: ERROR_DS_INSUFF_ACCESS_RIGHTS +// +// MessageText: +// +// Insufficient access rights to perform the operation. +// +#define ERROR_DS_INSUFF_ACCESS_RIGHTS 8344L + +// +// MessageId: ERROR_DS_ILLEGAL_SUPERIOR +// +// MessageText: +// +// The object cannot be added because the parent is not on the list of possible superiors. +// +#define ERROR_DS_ILLEGAL_SUPERIOR 8345L + +// +// MessageId: ERROR_DS_ATTRIBUTE_OWNED_BY_SAM +// +// MessageText: +// +// Access to the attribute is not permitted because the attribute is owned by the Security Accounts Manager (SAM). +// +#define ERROR_DS_ATTRIBUTE_OWNED_BY_SAM 8346L + +// +// MessageId: ERROR_DS_NAME_TOO_MANY_PARTS +// +// MessageText: +// +// The name has too many parts. +// +#define ERROR_DS_NAME_TOO_MANY_PARTS 8347L + +// +// MessageId: ERROR_DS_NAME_TOO_LONG +// +// MessageText: +// +// The name is too long. +// +#define ERROR_DS_NAME_TOO_LONG 8348L + +// +// MessageId: ERROR_DS_NAME_VALUE_TOO_LONG +// +// MessageText: +// +// The name value is too long. +// +#define ERROR_DS_NAME_VALUE_TOO_LONG 8349L + +// +// MessageId: ERROR_DS_NAME_UNPARSEABLE +// +// MessageText: +// +// The directory service encountered an error parsing a name. +// +#define ERROR_DS_NAME_UNPARSEABLE 8350L + +// +// MessageId: ERROR_DS_NAME_TYPE_UNKNOWN +// +// MessageText: +// +// The directory service cannot get the attribute type for a name. +// +#define ERROR_DS_NAME_TYPE_UNKNOWN 8351L + +// +// MessageId: ERROR_DS_NOT_AN_OBJECT +// +// MessageText: +// +// The name does not identify an object; the name identifies a phantom. +// +#define ERROR_DS_NOT_AN_OBJECT 8352L + +// +// MessageId: ERROR_DS_SEC_DESC_TOO_SHORT +// +// MessageText: +// +// The security descriptor is too short. +// +#define ERROR_DS_SEC_DESC_TOO_SHORT 8353L + +// +// MessageId: ERROR_DS_SEC_DESC_INVALID +// +// MessageText: +// +// The security descriptor is invalid. +// +#define ERROR_DS_SEC_DESC_INVALID 8354L + +// +// MessageId: ERROR_DS_NO_DELETED_NAME +// +// MessageText: +// +// Failed to create name for deleted object. +// +#define ERROR_DS_NO_DELETED_NAME 8355L + +// +// MessageId: ERROR_DS_SUBREF_MUST_HAVE_PARENT +// +// MessageText: +// +// The parent of a new subref must exist. +// +#define ERROR_DS_SUBREF_MUST_HAVE_PARENT 8356L + +// +// MessageId: ERROR_DS_NCNAME_MUST_BE_NC +// +// MessageText: +// +// The object must be a naming context. +// +#define ERROR_DS_NCNAME_MUST_BE_NC 8357L + +// +// MessageId: ERROR_DS_CANT_ADD_SYSTEM_ONLY +// +// MessageText: +// +// It is not permitted to add an attribute which is owned by the system. +// +#define ERROR_DS_CANT_ADD_SYSTEM_ONLY 8358L + +// +// MessageId: ERROR_DS_CLASS_MUST_BE_CONCRETE +// +// MessageText: +// +// The class of the object must be structural; you cannot instantiate an abstract class. +// +#define ERROR_DS_CLASS_MUST_BE_CONCRETE 8359L + +// +// MessageId: ERROR_DS_INVALID_DMD +// +// MessageText: +// +// The schema object could not be found. +// +#define ERROR_DS_INVALID_DMD 8360L + +// +// MessageId: ERROR_DS_OBJ_GUID_EXISTS +// +// MessageText: +// +// A local object with this GUID (dead or alive) already exists. +// +#define ERROR_DS_OBJ_GUID_EXISTS 8361L + +// +// MessageId: ERROR_DS_NOT_ON_BACKLINK +// +// MessageText: +// +// The operation cannot be performed on a back link. +// +#define ERROR_DS_NOT_ON_BACKLINK 8362L + +// +// MessageId: ERROR_DS_NO_CROSSREF_FOR_NC +// +// MessageText: +// +// The cross reference for the specified naming context could not be found. +// +#define ERROR_DS_NO_CROSSREF_FOR_NC 8363L + +// +// MessageId: ERROR_DS_SHUTTING_DOWN +// +// MessageText: +// +// The operation could not be performed because the directory service is shutting down. +// +#define ERROR_DS_SHUTTING_DOWN 8364L + +// +// MessageId: ERROR_DS_UNKNOWN_OPERATION +// +// MessageText: +// +// The directory service request is invalid. +// +#define ERROR_DS_UNKNOWN_OPERATION 8365L + +// +// MessageId: ERROR_DS_INVALID_ROLE_OWNER +// +// MessageText: +// +// The role owner attribute could not be read. +// +#define ERROR_DS_INVALID_ROLE_OWNER 8366L + +// +// MessageId: ERROR_DS_COULDNT_CONTACT_FSMO +// +// MessageText: +// +// The requested FSMO operation failed. The current FSMO holder could not be contacted. +// +#define ERROR_DS_COULDNT_CONTACT_FSMO 8367L + +// +// MessageId: ERROR_DS_CROSS_NC_DN_RENAME +// +// MessageText: +// +// Modification of a DN across a naming context is not permitted. +// +#define ERROR_DS_CROSS_NC_DN_RENAME 8368L + +// +// MessageId: ERROR_DS_CANT_MOD_SYSTEM_ONLY +// +// MessageText: +// +// The attribute cannot be modified because it is owned by the system. +// +#define ERROR_DS_CANT_MOD_SYSTEM_ONLY 8369L + +// +// MessageId: ERROR_DS_REPLICATOR_ONLY +// +// MessageText: +// +// Only the replicator can perform this function. +// +#define ERROR_DS_REPLICATOR_ONLY 8370L + +// +// MessageId: ERROR_DS_OBJ_CLASS_NOT_DEFINED +// +// MessageText: +// +// The specified class is not defined. +// +#define ERROR_DS_OBJ_CLASS_NOT_DEFINED 8371L + +// +// MessageId: ERROR_DS_OBJ_CLASS_NOT_SUBCLASS +// +// MessageText: +// +// The specified class is not a subclass. +// +#define ERROR_DS_OBJ_CLASS_NOT_SUBCLASS 8372L + +// +// MessageId: ERROR_DS_NAME_REFERENCE_INVALID +// +// MessageText: +// +// The name reference is invalid. +// +#define ERROR_DS_NAME_REFERENCE_INVALID 8373L + +// +// MessageId: ERROR_DS_CROSS_REF_EXISTS +// +// MessageText: +// +// A cross reference already exists. +// +#define ERROR_DS_CROSS_REF_EXISTS 8374L + +// +// MessageId: ERROR_DS_CANT_DEL_MASTER_CROSSREF +// +// MessageText: +// +// It is not permitted to delete a master cross reference. +// +#define ERROR_DS_CANT_DEL_MASTER_CROSSREF 8375L + +// +// MessageId: ERROR_DS_SUBTREE_NOTIFY_NOT_NC_HEAD +// +// MessageText: +// +// Subtree notifications are only supported on NC heads. +// +#define ERROR_DS_SUBTREE_NOTIFY_NOT_NC_HEAD 8376L + +// +// MessageId: ERROR_DS_NOTIFY_FILTER_TOO_COMPLEX +// +// MessageText: +// +// Notification filter is too complex. +// +#define ERROR_DS_NOTIFY_FILTER_TOO_COMPLEX 8377L + +// +// MessageId: ERROR_DS_DUP_RDN +// +// MessageText: +// +// Schema update failed: duplicate RDN. +// +#define ERROR_DS_DUP_RDN 8378L + +// +// MessageId: ERROR_DS_DUP_OID +// +// MessageText: +// +// Schema update failed: duplicate OID. +// +#define ERROR_DS_DUP_OID 8379L + +// +// MessageId: ERROR_DS_DUP_MAPI_ID +// +// MessageText: +// +// Schema update failed: duplicate MAPI identifier. +// +#define ERROR_DS_DUP_MAPI_ID 8380L + +// +// MessageId: ERROR_DS_DUP_SCHEMA_ID_GUID +// +// MessageText: +// +// Schema update failed: duplicate schema-id GUID. +// +#define ERROR_DS_DUP_SCHEMA_ID_GUID 8381L + +// +// MessageId: ERROR_DS_DUP_LDAP_DISPLAY_NAME +// +// MessageText: +// +// Schema update failed: duplicate LDAP display name. +// +#define ERROR_DS_DUP_LDAP_DISPLAY_NAME 8382L + +// +// MessageId: ERROR_DS_SEMANTIC_ATT_TEST +// +// MessageText: +// +// Schema update failed: range-lower less than range upper. +// +#define ERROR_DS_SEMANTIC_ATT_TEST 8383L + +// +// MessageId: ERROR_DS_SYNTAX_MISMATCH +// +// MessageText: +// +// Schema update failed: syntax mismatch. +// +#define ERROR_DS_SYNTAX_MISMATCH 8384L + +// +// MessageId: ERROR_DS_EXISTS_IN_MUST_HAVE +// +// MessageText: +// +// Schema deletion failed: attribute is used in must-contain. +// +#define ERROR_DS_EXISTS_IN_MUST_HAVE 8385L + +// +// MessageId: ERROR_DS_EXISTS_IN_MAY_HAVE +// +// MessageText: +// +// Schema deletion failed: attribute is used in may-contain. +// +#define ERROR_DS_EXISTS_IN_MAY_HAVE 8386L + +// +// MessageId: ERROR_DS_NONEXISTENT_MAY_HAVE +// +// MessageText: +// +// Schema update failed: attribute in may-contain does not exist. +// +#define ERROR_DS_NONEXISTENT_MAY_HAVE 8387L + +// +// MessageId: ERROR_DS_NONEXISTENT_MUST_HAVE +// +// MessageText: +// +// Schema update failed: attribute in must-contain does not exist. +// +#define ERROR_DS_NONEXISTENT_MUST_HAVE 8388L + +// +// MessageId: ERROR_DS_AUX_CLS_TEST_FAIL +// +// MessageText: +// +// Schema update failed: class in aux-class list does not exist or is not an auxiliary class. +// +#define ERROR_DS_AUX_CLS_TEST_FAIL 8389L + +// +// MessageId: ERROR_DS_NONEXISTENT_POSS_SUP +// +// MessageText: +// +// Schema update failed: class in poss-superiors does not exist. +// +#define ERROR_DS_NONEXISTENT_POSS_SUP 8390L + +// +// MessageId: ERROR_DS_SUB_CLS_TEST_FAIL +// +// MessageText: +// +// Schema update failed: class in subclassof list does not exist or does not satisfy hierarchy rules. +// +#define ERROR_DS_SUB_CLS_TEST_FAIL 8391L + +// +// MessageId: ERROR_DS_BAD_RDN_ATT_ID_SYNTAX +// +// MessageText: +// +// Schema update failed: Rdn-Att-Id has wrong syntax. +// +#define ERROR_DS_BAD_RDN_ATT_ID_SYNTAX 8392L + +// +// MessageId: ERROR_DS_EXISTS_IN_AUX_CLS +// +// MessageText: +// +// Schema deletion failed: class is used as auxiliary class. +// +#define ERROR_DS_EXISTS_IN_AUX_CLS 8393L + +// +// MessageId: ERROR_DS_EXISTS_IN_SUB_CLS +// +// MessageText: +// +// Schema deletion failed: class is used as sub class. +// +#define ERROR_DS_EXISTS_IN_SUB_CLS 8394L + +// +// MessageId: ERROR_DS_EXISTS_IN_POSS_SUP +// +// MessageText: +// +// Schema deletion failed: class is used as poss superior. +// +#define ERROR_DS_EXISTS_IN_POSS_SUP 8395L + +// +// MessageId: ERROR_DS_RECALCSCHEMA_FAILED +// +// MessageText: +// +// Schema update failed in recalculating validation cache. +// +#define ERROR_DS_RECALCSCHEMA_FAILED 8396L + +// +// MessageId: ERROR_DS_TREE_DELETE_NOT_FINISHED +// +// MessageText: +// +// The tree deletion is not finished. The request must be made again to continue deleting the tree. +// +#define ERROR_DS_TREE_DELETE_NOT_FINISHED 8397L + +// +// MessageId: ERROR_DS_CANT_DELETE +// +// MessageText: +// +// The requested delete operation could not be performed. +// +#define ERROR_DS_CANT_DELETE 8398L + +// +// MessageId: ERROR_DS_ATT_SCHEMA_REQ_ID +// +// MessageText: +// +// Cannot read the governs class identifier for the schema record. +// +#define ERROR_DS_ATT_SCHEMA_REQ_ID 8399L + +// +// MessageId: ERROR_DS_BAD_ATT_SCHEMA_SYNTAX +// +// MessageText: +// +// The attribute schema has bad syntax. +// +#define ERROR_DS_BAD_ATT_SCHEMA_SYNTAX 8400L + +// +// MessageId: ERROR_DS_CANT_CACHE_ATT +// +// MessageText: +// +// The attribute could not be cached. +// +#define ERROR_DS_CANT_CACHE_ATT 8401L + +// +// MessageId: ERROR_DS_CANT_CACHE_CLASS +// +// MessageText: +// +// The class could not be cached. +// +#define ERROR_DS_CANT_CACHE_CLASS 8402L + +// +// MessageId: ERROR_DS_CANT_REMOVE_ATT_CACHE +// +// MessageText: +// +// The attribute could not be removed from the cache. +// +#define ERROR_DS_CANT_REMOVE_ATT_CACHE 8403L + +// +// MessageId: ERROR_DS_CANT_REMOVE_CLASS_CACHE +// +// MessageText: +// +// The class could not be removed from the cache. +// +#define ERROR_DS_CANT_REMOVE_CLASS_CACHE 8404L + +// +// MessageId: ERROR_DS_CANT_RETRIEVE_DN +// +// MessageText: +// +// The distinguished name attribute could not be read. +// +#define ERROR_DS_CANT_RETRIEVE_DN 8405L + +// +// MessageId: ERROR_DS_MISSING_SUPREF +// +// MessageText: +// +// No superior reference has been configured for the directory service. The directory service is therefore unable to issue referrals to objects outside this forest. +// +#define ERROR_DS_MISSING_SUPREF 8406L + +// +// MessageId: ERROR_DS_CANT_RETRIEVE_INSTANCE +// +// MessageText: +// +// The instance type attribute could not be retrieved. +// +#define ERROR_DS_CANT_RETRIEVE_INSTANCE 8407L + +// +// MessageId: ERROR_DS_CODE_INCONSISTENCY +// +// MessageText: +// +// An internal error has occurred. +// +#define ERROR_DS_CODE_INCONSISTENCY 8408L + +// +// MessageId: ERROR_DS_DATABASE_ERROR +// +// MessageText: +// +// A database error has occurred. +// +#define ERROR_DS_DATABASE_ERROR 8409L + +// +// MessageId: ERROR_DS_GOVERNSID_MISSING +// +// MessageText: +// +// The attribute GOVERNSID is missing. +// +#define ERROR_DS_GOVERNSID_MISSING 8410L + +// +// MessageId: ERROR_DS_MISSING_EXPECTED_ATT +// +// MessageText: +// +// An expected attribute is missing. +// +#define ERROR_DS_MISSING_EXPECTED_ATT 8411L + +// +// MessageId: ERROR_DS_NCNAME_MISSING_CR_REF +// +// MessageText: +// +// The specified naming context is missing a cross reference. +// +#define ERROR_DS_NCNAME_MISSING_CR_REF 8412L + +// +// MessageId: ERROR_DS_SECURITY_CHECKING_ERROR +// +// MessageText: +// +// A security checking error has occurred. +// +#define ERROR_DS_SECURITY_CHECKING_ERROR 8413L + +// +// MessageId: ERROR_DS_SCHEMA_NOT_LOADED +// +// MessageText: +// +// The schema is not loaded. +// +#define ERROR_DS_SCHEMA_NOT_LOADED 8414L + +// +// MessageId: ERROR_DS_SCHEMA_ALLOC_FAILED +// +// MessageText: +// +// Schema allocation failed. Please check if the machine is running low on memory. +// +#define ERROR_DS_SCHEMA_ALLOC_FAILED 8415L + +// +// MessageId: ERROR_DS_ATT_SCHEMA_REQ_SYNTAX +// +// MessageText: +// +// Failed to obtain the required syntax for the attribute schema. +// +#define ERROR_DS_ATT_SCHEMA_REQ_SYNTAX 8416L + +// +// MessageId: ERROR_DS_GCVERIFY_ERROR +// +// MessageText: +// +// The global catalog verification failed. The global catalog is not available or does not support the operation. Some part of the directory is currently not available. +// +#define ERROR_DS_GCVERIFY_ERROR 8417L + +// +// MessageId: ERROR_DS_DRA_SCHEMA_MISMATCH +// +// MessageText: +// +// The replication operation failed because of a schema mismatch between the servers involved. +// +#define ERROR_DS_DRA_SCHEMA_MISMATCH 8418L + +// +// MessageId: ERROR_DS_CANT_FIND_DSA_OBJ +// +// MessageText: +// +// The DSA object could not be found. +// +#define ERROR_DS_CANT_FIND_DSA_OBJ 8419L + +// +// MessageId: ERROR_DS_CANT_FIND_EXPECTED_NC +// +// MessageText: +// +// The naming context could not be found. +// +#define ERROR_DS_CANT_FIND_EXPECTED_NC 8420L + +// +// MessageId: ERROR_DS_CANT_FIND_NC_IN_CACHE +// +// MessageText: +// +// The naming context could not be found in the cache. +// +#define ERROR_DS_CANT_FIND_NC_IN_CACHE 8421L + +// +// MessageId: ERROR_DS_CANT_RETRIEVE_CHILD +// +// MessageText: +// +// The child object could not be retrieved. +// +#define ERROR_DS_CANT_RETRIEVE_CHILD 8422L + +// +// MessageId: ERROR_DS_SECURITY_ILLEGAL_MODIFY +// +// MessageText: +// +// The modification was not permitted for security reasons. +// +#define ERROR_DS_SECURITY_ILLEGAL_MODIFY 8423L + +// +// MessageId: ERROR_DS_CANT_REPLACE_HIDDEN_REC +// +// MessageText: +// +// The operation cannot replace the hidden record. +// +#define ERROR_DS_CANT_REPLACE_HIDDEN_REC 8424L + +// +// MessageId: ERROR_DS_BAD_HIERARCHY_FILE +// +// MessageText: +// +// The hierarchy file is invalid. +// +#define ERROR_DS_BAD_HIERARCHY_FILE 8425L + +// +// MessageId: ERROR_DS_BUILD_HIERARCHY_TABLE_FAILED +// +// MessageText: +// +// The attempt to build the hierarchy table failed. +// +#define ERROR_DS_BUILD_HIERARCHY_TABLE_FAILED 8426L + +// +// MessageId: ERROR_DS_CONFIG_PARAM_MISSING +// +// MessageText: +// +// The directory configuration parameter is missing from the registry. +// +#define ERROR_DS_CONFIG_PARAM_MISSING 8427L + +// +// MessageId: ERROR_DS_COUNTING_AB_INDICES_FAILED +// +// MessageText: +// +// The attempt to count the address book indices failed. +// +#define ERROR_DS_COUNTING_AB_INDICES_FAILED 8428L + +// +// MessageId: ERROR_DS_HIERARCHY_TABLE_MALLOC_FAILED +// +// MessageText: +// +// The allocation of the hierarchy table failed. +// +#define ERROR_DS_HIERARCHY_TABLE_MALLOC_FAILED 8429L + +// +// MessageId: ERROR_DS_INTERNAL_FAILURE +// +// MessageText: +// +// The directory service encountered an internal failure. +// +#define ERROR_DS_INTERNAL_FAILURE 8430L + +// +// MessageId: ERROR_DS_UNKNOWN_ERROR +// +// MessageText: +// +// The directory service encountered an unknown failure. +// +#define ERROR_DS_UNKNOWN_ERROR 8431L + +// +// MessageId: ERROR_DS_ROOT_REQUIRES_CLASS_TOP +// +// MessageText: +// +// A root object requires a class of 'top'. +// +#define ERROR_DS_ROOT_REQUIRES_CLASS_TOP 8432L + +// +// MessageId: ERROR_DS_REFUSING_FSMO_ROLES +// +// MessageText: +// +// This directory server is shutting down, and cannot take ownership of new floating single-master operation roles. +// +#define ERROR_DS_REFUSING_FSMO_ROLES 8433L + +// +// MessageId: ERROR_DS_MISSING_FSMO_SETTINGS +// +// MessageText: +// +// The directory service is missing mandatory configuration information, and is unable to determine the ownership of floating single-master operation roles. +// +#define ERROR_DS_MISSING_FSMO_SETTINGS 8434L + +// +// MessageId: ERROR_DS_UNABLE_TO_SURRENDER_ROLES +// +// MessageText: +// +// The directory service was unable to transfer ownership of one or more floating single-master operation roles to other servers. +// +#define ERROR_DS_UNABLE_TO_SURRENDER_ROLES 8435L + +// +// MessageId: ERROR_DS_DRA_GENERIC +// +// MessageText: +// +// The replication operation failed. +// +#define ERROR_DS_DRA_GENERIC 8436L + +// +// MessageId: ERROR_DS_DRA_INVALID_PARAMETER +// +// MessageText: +// +// An invalid parameter was specified for this replication operation. +// +#define ERROR_DS_DRA_INVALID_PARAMETER 8437L + +// +// MessageId: ERROR_DS_DRA_BUSY +// +// MessageText: +// +// The directory service is too busy to complete the replication operation at this time. +// +#define ERROR_DS_DRA_BUSY 8438L + +// +// MessageId: ERROR_DS_DRA_BAD_DN +// +// MessageText: +// +// The distinguished name specified for this replication operation is invalid. +// +#define ERROR_DS_DRA_BAD_DN 8439L + +// +// MessageId: ERROR_DS_DRA_BAD_NC +// +// MessageText: +// +// The naming context specified for this replication operation is invalid. +// +#define ERROR_DS_DRA_BAD_NC 8440L + +// +// MessageId: ERROR_DS_DRA_DN_EXISTS +// +// MessageText: +// +// The distinguished name specified for this replication operation already exists. +// +#define ERROR_DS_DRA_DN_EXISTS 8441L + +// +// MessageId: ERROR_DS_DRA_INTERNAL_ERROR +// +// MessageText: +// +// The replication system encountered an internal error. +// +#define ERROR_DS_DRA_INTERNAL_ERROR 8442L + +// +// MessageId: ERROR_DS_DRA_INCONSISTENT_DIT +// +// MessageText: +// +// The replication operation encountered a database inconsistency. +// +#define ERROR_DS_DRA_INCONSISTENT_DIT 8443L + +// +// MessageId: ERROR_DS_DRA_CONNECTION_FAILED +// +// MessageText: +// +// The server specified for this replication operation could not be contacted. +// +#define ERROR_DS_DRA_CONNECTION_FAILED 8444L + +// +// MessageId: ERROR_DS_DRA_BAD_INSTANCE_TYPE +// +// MessageText: +// +// The replication operation encountered an object with an invalid instance type. +// +#define ERROR_DS_DRA_BAD_INSTANCE_TYPE 8445L + +// +// MessageId: ERROR_DS_DRA_OUT_OF_MEM +// +// MessageText: +// +// The replication operation failed to allocate memory. +// +#define ERROR_DS_DRA_OUT_OF_MEM 8446L + +// +// MessageId: ERROR_DS_DRA_MAIL_PROBLEM +// +// MessageText: +// +// The replication operation encountered an error with the mail system. +// +#define ERROR_DS_DRA_MAIL_PROBLEM 8447L + +// +// MessageId: ERROR_DS_DRA_REF_ALREADY_EXISTS +// +// MessageText: +// +// The replication reference information for the target server already exists. +// +#define ERROR_DS_DRA_REF_ALREADY_EXISTS 8448L + +// +// MessageId: ERROR_DS_DRA_REF_NOT_FOUND +// +// MessageText: +// +// The replication reference information for the target server does not exist. +// +#define ERROR_DS_DRA_REF_NOT_FOUND 8449L + +// +// MessageId: ERROR_DS_DRA_OBJ_IS_REP_SOURCE +// +// MessageText: +// +// The naming context cannot be removed because it is replicated to another server. +// +#define ERROR_DS_DRA_OBJ_IS_REP_SOURCE 8450L + +// +// MessageId: ERROR_DS_DRA_DB_ERROR +// +// MessageText: +// +// The replication operation encountered a database error. +// +#define ERROR_DS_DRA_DB_ERROR 8451L + +// +// MessageId: ERROR_DS_DRA_NO_REPLICA +// +// MessageText: +// +// The naming context is in the process of being removed or is not replicated from the specified server. +// +#define ERROR_DS_DRA_NO_REPLICA 8452L + +// +// MessageId: ERROR_DS_DRA_ACCESS_DENIED +// +// MessageText: +// +// Replication access was denied. +// +#define ERROR_DS_DRA_ACCESS_DENIED 8453L + +// +// MessageId: ERROR_DS_DRA_NOT_SUPPORTED +// +// MessageText: +// +// The requested operation is not supported by this version of the directory service. +// +#define ERROR_DS_DRA_NOT_SUPPORTED 8454L + +// +// MessageId: ERROR_DS_DRA_RPC_CANCELLED +// +// MessageText: +// +// The replication remote procedure call was cancelled. +// +#define ERROR_DS_DRA_RPC_CANCELLED 8455L + +// +// MessageId: ERROR_DS_DRA_SOURCE_DISABLED +// +// MessageText: +// +// The source server is currently rejecting replication requests. +// +#define ERROR_DS_DRA_SOURCE_DISABLED 8456L + +// +// MessageId: ERROR_DS_DRA_SINK_DISABLED +// +// MessageText: +// +// The destination server is currently rejecting replication requests. +// +#define ERROR_DS_DRA_SINK_DISABLED 8457L + +// +// MessageId: ERROR_DS_DRA_NAME_COLLISION +// +// MessageText: +// +// The replication operation failed due to a collision of object names. +// +#define ERROR_DS_DRA_NAME_COLLISION 8458L + +// +// MessageId: ERROR_DS_DRA_SOURCE_REINSTALLED +// +// MessageText: +// +// The replication source has been reinstalled. +// +#define ERROR_DS_DRA_SOURCE_REINSTALLED 8459L + +// +// MessageId: ERROR_DS_DRA_MISSING_PARENT +// +// MessageText: +// +// The replication operation failed because a required parent object is missing. +// +#define ERROR_DS_DRA_MISSING_PARENT 8460L + +// +// MessageId: ERROR_DS_DRA_PREEMPTED +// +// MessageText: +// +// The replication operation was preempted. +// +#define ERROR_DS_DRA_PREEMPTED 8461L + +// +// MessageId: ERROR_DS_DRA_ABANDON_SYNC +// +// MessageText: +// +// The replication synchronization attempt was abandoned because of a lack of updates. +// +#define ERROR_DS_DRA_ABANDON_SYNC 8462L + +// +// MessageId: ERROR_DS_DRA_SHUTDOWN +// +// MessageText: +// +// The replication operation was terminated because the system is shutting down. +// +#define ERROR_DS_DRA_SHUTDOWN 8463L + +// +// MessageId: ERROR_DS_DRA_INCOMPATIBLE_PARTIAL_SET +// +// MessageText: +// +// Synchronization attempt failed because the destination DC is currently waiting to synchronize new partial attributes from source. This condition is normal if a recent schema change modified the partial attribute set. The destination partial attribute set is not a subset of source partial attribute set. +// +#define ERROR_DS_DRA_INCOMPATIBLE_PARTIAL_SET 8464L + +// +// MessageId: ERROR_DS_DRA_SOURCE_IS_PARTIAL_REPLICA +// +// MessageText: +// +// The replication synchronization attempt failed because a master replica attempted to sync from a partial replica. +// +#define ERROR_DS_DRA_SOURCE_IS_PARTIAL_REPLICA 8465L + +// +// MessageId: ERROR_DS_DRA_EXTN_CONNECTION_FAILED +// +// MessageText: +// +// The server specified for this replication operation was contacted, but that server was unable to contact an additional server needed to complete the operation. +// +#define ERROR_DS_DRA_EXTN_CONNECTION_FAILED 8466L + +// +// MessageId: ERROR_DS_INSTALL_SCHEMA_MISMATCH +// +// MessageText: +// +// The version of the Active Directory schema of the source forest is not compatible with the version of Active Directory on this computer. +// +#define ERROR_DS_INSTALL_SCHEMA_MISMATCH 8467L + +// +// MessageId: ERROR_DS_DUP_LINK_ID +// +// MessageText: +// +// Schema update failed: An attribute with the same link identifier already exists. +// +#define ERROR_DS_DUP_LINK_ID 8468L + +// +// MessageId: ERROR_DS_NAME_ERROR_RESOLVING +// +// MessageText: +// +// Name translation: Generic processing error. +// +#define ERROR_DS_NAME_ERROR_RESOLVING 8469L + +// +// MessageId: ERROR_DS_NAME_ERROR_NOT_FOUND +// +// MessageText: +// +// Name translation: Could not find the name or insufficient right to see name. +// +#define ERROR_DS_NAME_ERROR_NOT_FOUND 8470L + +// +// MessageId: ERROR_DS_NAME_ERROR_NOT_UNIQUE +// +// MessageText: +// +// Name translation: Input name mapped to more than one output name. +// +#define ERROR_DS_NAME_ERROR_NOT_UNIQUE 8471L + +// +// MessageId: ERROR_DS_NAME_ERROR_NO_MAPPING +// +// MessageText: +// +// Name translation: Input name found, but not the associated output format. +// +#define ERROR_DS_NAME_ERROR_NO_MAPPING 8472L + +// +// MessageId: ERROR_DS_NAME_ERROR_DOMAIN_ONLY +// +// MessageText: +// +// Name translation: Unable to resolve completely, only the domain was found. +// +#define ERROR_DS_NAME_ERROR_DOMAIN_ONLY 8473L + +// +// MessageId: ERROR_DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING +// +// MessageText: +// +// Name translation: Unable to perform purely syntactical mapping at the client without going out to the wire. +// +#define ERROR_DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING 8474L + +// +// MessageId: ERROR_DS_CONSTRUCTED_ATT_MOD +// +// MessageText: +// +// Modification of a constructed attribute is not allowed. +// +#define ERROR_DS_CONSTRUCTED_ATT_MOD 8475L + +// +// MessageId: ERROR_DS_WRONG_OM_OBJ_CLASS +// +// MessageText: +// +// The OM-Object-Class specified is incorrect for an attribute with the specified syntax. +// +#define ERROR_DS_WRONG_OM_OBJ_CLASS 8476L + +// +// MessageId: ERROR_DS_DRA_REPL_PENDING +// +// MessageText: +// +// The replication request has been posted; waiting for reply. +// +#define ERROR_DS_DRA_REPL_PENDING 8477L + +// +// MessageId: ERROR_DS_DS_REQUIRED +// +// MessageText: +// +// The requested operation requires a directory service, and none was available. +// +#define ERROR_DS_DS_REQUIRED 8478L + +// +// MessageId: ERROR_DS_INVALID_LDAP_DISPLAY_NAME +// +// MessageText: +// +// The LDAP display name of the class or attribute contains non-ASCII characters. +// +#define ERROR_DS_INVALID_LDAP_DISPLAY_NAME 8479L + +// +// MessageId: ERROR_DS_NON_BASE_SEARCH +// +// MessageText: +// +// The requested search operation is only supported for base searches. +// +#define ERROR_DS_NON_BASE_SEARCH 8480L + +// +// MessageId: ERROR_DS_CANT_RETRIEVE_ATTS +// +// MessageText: +// +// The search failed to retrieve attributes from the database. +// +#define ERROR_DS_CANT_RETRIEVE_ATTS 8481L + +// +// MessageId: ERROR_DS_BACKLINK_WITHOUT_LINK +// +// MessageText: +// +// The schema update operation tried to add a backward link attribute that has no corresponding forward link. +// +#define ERROR_DS_BACKLINK_WITHOUT_LINK 8482L + +// +// MessageId: ERROR_DS_EPOCH_MISMATCH +// +// MessageText: +// +// Source and destination of a cross-domain move do not agree on the object's epoch number. Either source or destination does not have the latest version of the object. +// +#define ERROR_DS_EPOCH_MISMATCH 8483L + +// +// MessageId: ERROR_DS_SRC_NAME_MISMATCH +// +// MessageText: +// +// Source and destination of a cross-domain move do not agree on the object's current name. Either source or destination does not have the latest version of the object. +// +#define ERROR_DS_SRC_NAME_MISMATCH 8484L + +// +// MessageId: ERROR_DS_SRC_AND_DST_NC_IDENTICAL +// +// MessageText: +// +// Source and destination for the cross-domain move operation are identical. Caller should use local move operation instead of cross-domain move operation. +// +#define ERROR_DS_SRC_AND_DST_NC_IDENTICAL 8485L + +// +// MessageId: ERROR_DS_DST_NC_MISMATCH +// +// MessageText: +// +// Source and destination for a cross-domain move are not in agreement on the naming contexts in the forest. Either source or destination does not have the latest version of the Partitions container. +// +#define ERROR_DS_DST_NC_MISMATCH 8486L + +// +// MessageId: ERROR_DS_NOT_AUTHORITIVE_FOR_DST_NC +// +// MessageText: +// +// Destination of a cross-domain move is not authoritative for the destination naming context. +// +#define ERROR_DS_NOT_AUTHORITIVE_FOR_DST_NC 8487L + +// +// MessageId: ERROR_DS_SRC_GUID_MISMATCH +// +// MessageText: +// +// Source and destination of a cross-domain move do not agree on the identity of the source object. Either source or destination does not have the latest version of the source object. +// +#define ERROR_DS_SRC_GUID_MISMATCH 8488L + +// +// MessageId: ERROR_DS_CANT_MOVE_DELETED_OBJECT +// +// MessageText: +// +// Object being moved across-domains is already known to be deleted by the destination server. The source server does not have the latest version of the source object. +// +#define ERROR_DS_CANT_MOVE_DELETED_OBJECT 8489L + +// +// MessageId: ERROR_DS_PDC_OPERATION_IN_PROGRESS +// +// MessageText: +// +// Another operation which requires exclusive access to the PDC FSMO is already in progress. +// +#define ERROR_DS_PDC_OPERATION_IN_PROGRESS 8490L + +// +// MessageId: ERROR_DS_CROSS_DOMAIN_CLEANUP_REQD +// +// MessageText: +// +// A cross-domain move operation failed such that two versions of the moved object exist - one each in the source and destination domains. The destination object needs to be removed to restore the system to a consistent state. +// +#define ERROR_DS_CROSS_DOMAIN_CLEANUP_REQD 8491L + +// +// MessageId: ERROR_DS_ILLEGAL_XDOM_MOVE_OPERATION +// +// MessageText: +// +// This object may not be moved across domain boundaries either because cross-domain moves for this class are disallowed, or the object has some special characteristics, e.g.: trust account or restricted RID, which prevent its move. +// +#define ERROR_DS_ILLEGAL_XDOM_MOVE_OPERATION 8492L + +// +// MessageId: ERROR_DS_CANT_WITH_ACCT_GROUP_MEMBERSHPS +// +// MessageText: +// +// Can't move objects with memberships across domain boundaries as once moved, this would violate the membership conditions of the account group. Remove the object from any account group memberships and retry. +// +#define ERROR_DS_CANT_WITH_ACCT_GROUP_MEMBERSHPS 8493L + +// +// MessageId: ERROR_DS_NC_MUST_HAVE_NC_PARENT +// +// MessageText: +// +// A naming context head must be the immediate child of another naming context head, not of an interior node. +// +#define ERROR_DS_NC_MUST_HAVE_NC_PARENT 8494L + +// +// MessageId: ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE +// +// MessageText: +// +// The directory cannot validate the proposed naming context name because it does not hold a replica of the naming context above the proposed naming context. Please ensure that the domain naming master role is held by a server that is configured as a global catalog server, and that the server is up to date with its replication partners. (Applies only to Windows 2000 Domain Naming masters) +// +#define ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE 8495L + +// +// MessageId: ERROR_DS_DST_DOMAIN_NOT_NATIVE +// +// MessageText: +// +// Destination domain must be in native mode. +// +#define ERROR_DS_DST_DOMAIN_NOT_NATIVE 8496L + +// +// MessageId: ERROR_DS_MISSING_INFRASTRUCTURE_CONTAINER +// +// MessageText: +// +// The operation can not be performed because the server does not have an infrastructure container in the domain of interest. +// +#define ERROR_DS_MISSING_INFRASTRUCTURE_CONTAINER 8497L + +// +// MessageId: ERROR_DS_CANT_MOVE_ACCOUNT_GROUP +// +// MessageText: +// +// Cross-domain move of non-empty account groups is not allowed. +// +#define ERROR_DS_CANT_MOVE_ACCOUNT_GROUP 8498L + +// +// MessageId: ERROR_DS_CANT_MOVE_RESOURCE_GROUP +// +// MessageText: +// +// Cross-domain move of non-empty resource groups is not allowed. +// +#define ERROR_DS_CANT_MOVE_RESOURCE_GROUP 8499L + +// +// MessageId: ERROR_DS_INVALID_SEARCH_FLAG +// +// MessageText: +// +// The search flags for the attribute are invalid. The ANR bit is valid only on attributes of Unicode or Teletex strings. +// +#define ERROR_DS_INVALID_SEARCH_FLAG 8500L + +// +// MessageId: ERROR_DS_NO_TREE_DELETE_ABOVE_NC +// +// MessageText: +// +// Tree deletions starting at an object which has an NC head as a descendant are not allowed. +// +#define ERROR_DS_NO_TREE_DELETE_ABOVE_NC 8501L + +// +// MessageId: ERROR_DS_COULDNT_LOCK_TREE_FOR_DELETE +// +// MessageText: +// +// The directory service failed to lock a tree in preparation for a tree deletion because the tree was in use. +// +#define ERROR_DS_COULDNT_LOCK_TREE_FOR_DELETE 8502L + +// +// MessageId: ERROR_DS_COULDNT_IDENTIFY_OBJECTS_FOR_TREE_DELETE +// +// MessageText: +// +// The directory service failed to identify the list of objects to delete while attempting a tree deletion. +// +#define ERROR_DS_COULDNT_IDENTIFY_OBJECTS_FOR_TREE_DELETE 8503L + +// +// MessageId: ERROR_DS_SAM_INIT_FAILURE +// +// MessageText: +// +// Security Accounts Manager initialization failed because of the following error: %1. +// Error Status: 0x%2. Click OK to shut down the system and reboot into Directory Services Restore Mode. Check the event log for detailed information. +// +#define ERROR_DS_SAM_INIT_FAILURE 8504L + +// +// MessageId: ERROR_DS_SENSITIVE_GROUP_VIOLATION +// +// MessageText: +// +// Only an administrator can modify the membership list of an administrative group. +// +#define ERROR_DS_SENSITIVE_GROUP_VIOLATION 8505L + +// +// MessageId: ERROR_DS_CANT_MOD_PRIMARYGROUPID +// +// MessageText: +// +// Cannot change the primary group ID of a domain controller account. +// +#define ERROR_DS_CANT_MOD_PRIMARYGROUPID 8506L + +// +// MessageId: ERROR_DS_ILLEGAL_BASE_SCHEMA_MOD +// +// MessageText: +// +// An attempt is made to modify the base schema. +// +#define ERROR_DS_ILLEGAL_BASE_SCHEMA_MOD 8507L + +// +// MessageId: ERROR_DS_NONSAFE_SCHEMA_CHANGE +// +// MessageText: +// +// Adding a new mandatory attribute to an existing class, deleting a mandatory attribute from an existing class, or adding an optional attribute to the special class Top that is not a backlink attribute (directly or through inheritance, for example, by adding or deleting an auxiliary class) is not allowed. +// +#define ERROR_DS_NONSAFE_SCHEMA_CHANGE 8508L + +// +// MessageId: ERROR_DS_SCHEMA_UPDATE_DISALLOWED +// +// MessageText: +// +// Schema update is not allowed on this DC because the DC is not the schema FSMO Role Owner. +// +#define ERROR_DS_SCHEMA_UPDATE_DISALLOWED 8509L + +// +// MessageId: ERROR_DS_CANT_CREATE_UNDER_SCHEMA +// +// MessageText: +// +// An object of this class cannot be created under the schema container. You can only create attribute-schema and class-schema objects under the schema container. +// +#define ERROR_DS_CANT_CREATE_UNDER_SCHEMA 8510L + +// +// MessageId: ERROR_DS_INSTALL_NO_SRC_SCH_VERSION +// +// MessageText: +// +// The replica/child install failed to get the objectVersion attribute on the schema container on the source DC. Either the attribute is missing on the schema container or the credentials supplied do not have permission to read it. +// +#define ERROR_DS_INSTALL_NO_SRC_SCH_VERSION 8511L + +// +// MessageId: ERROR_DS_INSTALL_NO_SCH_VERSION_IN_INIFILE +// +// MessageText: +// +// The replica/child install failed to read the objectVersion attribute in the SCHEMA section of the file schema.ini in the system32 directory. +// +#define ERROR_DS_INSTALL_NO_SCH_VERSION_IN_INIFILE 8512L + +// +// MessageId: ERROR_DS_INVALID_GROUP_TYPE +// +// MessageText: +// +// The specified group type is invalid. +// +#define ERROR_DS_INVALID_GROUP_TYPE 8513L + +// +// MessageId: ERROR_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN +// +// MessageText: +// +// You cannot nest global groups in a mixed domain if the group is security-enabled. +// +#define ERROR_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN 8514L + +// +// MessageId: ERROR_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN +// +// MessageText: +// +// You cannot nest local groups in a mixed domain if the group is security-enabled. +// +#define ERROR_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN 8515L + +// +// MessageId: ERROR_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER +// +// MessageText: +// +// A global group cannot have a local group as a member. +// +#define ERROR_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER 8516L + +// +// MessageId: ERROR_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER +// +// MessageText: +// +// A global group cannot have a universal group as a member. +// +#define ERROR_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER 8517L + +// +// MessageId: ERROR_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER +// +// MessageText: +// +// A universal group cannot have a local group as a member. +// +#define ERROR_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER 8518L + +// +// MessageId: ERROR_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER +// +// MessageText: +// +// A global group cannot have a cross-domain member. +// +#define ERROR_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER 8519L + +// +// MessageId: ERROR_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER +// +// MessageText: +// +// A local group cannot have another cross domain local group as a member. +// +#define ERROR_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER 8520L + +// +// MessageId: ERROR_DS_HAVE_PRIMARY_MEMBERS +// +// MessageText: +// +// A group with primary members cannot change to a security-disabled group. +// +#define ERROR_DS_HAVE_PRIMARY_MEMBERS 8521L + +// +// MessageId: ERROR_DS_STRING_SD_CONVERSION_FAILED +// +// MessageText: +// +// The schema cache load failed to convert the string default SD on a class-schema object. +// +#define ERROR_DS_STRING_SD_CONVERSION_FAILED 8522L + +// +// MessageId: ERROR_DS_NAMING_MASTER_GC +// +// MessageText: +// +// Only DSAs configured to be Global Catalog servers should be allowed to hold the Domain Naming Master FSMO role. (Applies only to Windows 2000 servers) +// +#define ERROR_DS_NAMING_MASTER_GC 8523L + +// +// MessageId: ERROR_DS_DNS_LOOKUP_FAILURE +// +// MessageText: +// +// The DSA operation is unable to proceed because of a DNS lookup failure. +// +#define ERROR_DS_DNS_LOOKUP_FAILURE 8524L + +// +// MessageId: ERROR_DS_COULDNT_UPDATE_SPNS +// +// MessageText: +// +// While processing a change to the DNS Host Name for an object, the Service Principal Name values could not be kept in sync. +// +#define ERROR_DS_COULDNT_UPDATE_SPNS 8525L + +// +// MessageId: ERROR_DS_CANT_RETRIEVE_SD +// +// MessageText: +// +// The Security Descriptor attribute could not be read. +// +#define ERROR_DS_CANT_RETRIEVE_SD 8526L + +// +// MessageId: ERROR_DS_KEY_NOT_UNIQUE +// +// MessageText: +// +// The object requested was not found, but an object with that key was found. +// +#define ERROR_DS_KEY_NOT_UNIQUE 8527L + +// +// MessageId: ERROR_DS_WRONG_LINKED_ATT_SYNTAX +// +// MessageText: +// +// The syntax of the linked attribute being added is incorrect. Forward links can only have syntax 2.5.5.1, 2.5.5.7, and 2.5.5.14, and backlinks can only have syntax 2.5.5.1 +// +#define ERROR_DS_WRONG_LINKED_ATT_SYNTAX 8528L + +// +// MessageId: ERROR_DS_SAM_NEED_BOOTKEY_PASSWORD +// +// MessageText: +// +// Security Account Manager needs to get the boot password. +// +#define ERROR_DS_SAM_NEED_BOOTKEY_PASSWORD 8529L + +// +// MessageId: ERROR_DS_SAM_NEED_BOOTKEY_FLOPPY +// +// MessageText: +// +// Security Account Manager needs to get the boot key from floppy disk. +// +#define ERROR_DS_SAM_NEED_BOOTKEY_FLOPPY 8530L + +// +// MessageId: ERROR_DS_CANT_START +// +// MessageText: +// +// Directory Service cannot start. +// +#define ERROR_DS_CANT_START 8531L + +// +// MessageId: ERROR_DS_INIT_FAILURE +// +// MessageText: +// +// Directory Services could not start. +// +#define ERROR_DS_INIT_FAILURE 8532L + +// +// MessageId: ERROR_DS_NO_PKT_PRIVACY_ON_CONNECTION +// +// MessageText: +// +// The connection between client and server requires packet privacy or better. +// +#define ERROR_DS_NO_PKT_PRIVACY_ON_CONNECTION 8533L + +// +// MessageId: ERROR_DS_SOURCE_DOMAIN_IN_FOREST +// +// MessageText: +// +// The source domain may not be in the same forest as destination. +// +#define ERROR_DS_SOURCE_DOMAIN_IN_FOREST 8534L + +// +// MessageId: ERROR_DS_DESTINATION_DOMAIN_NOT_IN_FOREST +// +// MessageText: +// +// The destination domain must be in the forest. +// +#define ERROR_DS_DESTINATION_DOMAIN_NOT_IN_FOREST 8535L + +// +// MessageId: ERROR_DS_DESTINATION_AUDITING_NOT_ENABLED +// +// MessageText: +// +// The operation requires that destination domain auditing be enabled. +// +#define ERROR_DS_DESTINATION_AUDITING_NOT_ENABLED 8536L + +// +// MessageId: ERROR_DS_CANT_FIND_DC_FOR_SRC_DOMAIN +// +// MessageText: +// +// The operation couldn't locate a DC for the source domain. +// +#define ERROR_DS_CANT_FIND_DC_FOR_SRC_DOMAIN 8537L + +// +// MessageId: ERROR_DS_SRC_OBJ_NOT_GROUP_OR_USER +// +// MessageText: +// +// The source object must be a group or user. +// +#define ERROR_DS_SRC_OBJ_NOT_GROUP_OR_USER 8538L + +// +// MessageId: ERROR_DS_SRC_SID_EXISTS_IN_FOREST +// +// MessageText: +// +// The source object's SID already exists in destination forest. +// +#define ERROR_DS_SRC_SID_EXISTS_IN_FOREST 8539L + +// +// MessageId: ERROR_DS_SRC_AND_DST_OBJECT_CLASS_MISMATCH +// +// MessageText: +// +// The source and destination object must be of the same type. +// +#define ERROR_DS_SRC_AND_DST_OBJECT_CLASS_MISMATCH 8540L + +// +// MessageId: ERROR_SAM_INIT_FAILURE +// +// MessageText: +// +// Security Accounts Manager initialization failed because of the following error: %1. +// Error Status: 0x%2. Click OK to shut down the system and reboot into Safe Mode. Check the event log for detailed information. +// +#define ERROR_SAM_INIT_FAILURE 8541L + +// +// MessageId: ERROR_DS_DRA_SCHEMA_INFO_SHIP +// +// MessageText: +// +// Schema information could not be included in the replication request. +// +#define ERROR_DS_DRA_SCHEMA_INFO_SHIP 8542L + +// +// MessageId: ERROR_DS_DRA_SCHEMA_CONFLICT +// +// MessageText: +// +// The replication operation could not be completed due to a schema incompatibility. +// +#define ERROR_DS_DRA_SCHEMA_CONFLICT 8543L + +// +// MessageId: ERROR_DS_DRA_EARLIER_SCHEMA_CONFLICT +// +// MessageText: +// +// The replication operation could not be completed due to a previous schema incompatibility. +// +#define ERROR_DS_DRA_EARLIER_SCHEMA_CONFLICT 8544L + +// +// MessageId: ERROR_DS_DRA_OBJ_NC_MISMATCH +// +// MessageText: +// +// The replication update could not be applied because either the source or the destination has not yet received information regarding a recent cross-domain move operation. +// +#define ERROR_DS_DRA_OBJ_NC_MISMATCH 8545L + +// +// MessageId: ERROR_DS_NC_STILL_HAS_DSAS +// +// MessageText: +// +// The requested domain could not be deleted because there exist domain controllers that still host this domain. +// +#define ERROR_DS_NC_STILL_HAS_DSAS 8546L + +// +// MessageId: ERROR_DS_GC_REQUIRED +// +// MessageText: +// +// The requested operation can be performed only on a global catalog server. +// +#define ERROR_DS_GC_REQUIRED 8547L + +// +// MessageId: ERROR_DS_LOCAL_MEMBER_OF_LOCAL_ONLY +// +// MessageText: +// +// A local group can only be a member of other local groups in the same domain. +// +#define ERROR_DS_LOCAL_MEMBER_OF_LOCAL_ONLY 8548L + +// +// MessageId: ERROR_DS_NO_FPO_IN_UNIVERSAL_GROUPS +// +// MessageText: +// +// Foreign security principals cannot be members of universal groups. +// +#define ERROR_DS_NO_FPO_IN_UNIVERSAL_GROUPS 8549L + +// +// MessageId: ERROR_DS_CANT_ADD_TO_GC +// +// MessageText: +// +// The attribute is not allowed to be replicated to the GC because of security reasons. +// +#define ERROR_DS_CANT_ADD_TO_GC 8550L + +// +// MessageId: ERROR_DS_NO_CHECKPOINT_WITH_PDC +// +// MessageText: +// +// The checkpoint with the PDC could not be taken because there too many modifications being processed currently. +// +#define ERROR_DS_NO_CHECKPOINT_WITH_PDC 8551L + +// +// MessageId: ERROR_DS_SOURCE_AUDITING_NOT_ENABLED +// +// MessageText: +// +// The operation requires that source domain auditing be enabled. +// +#define ERROR_DS_SOURCE_AUDITING_NOT_ENABLED 8552L + +// +// MessageId: ERROR_DS_CANT_CREATE_IN_NONDOMAIN_NC +// +// MessageText: +// +// Security principal objects can only be created inside domain naming contexts. +// +#define ERROR_DS_CANT_CREATE_IN_NONDOMAIN_NC 8553L + +// +// MessageId: ERROR_DS_INVALID_NAME_FOR_SPN +// +// MessageText: +// +// A Service Principal Name (SPN) could not be constructed because the provided hostname is not in the necessary format. +// +#define ERROR_DS_INVALID_NAME_FOR_SPN 8554L + +// +// MessageId: ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS +// +// MessageText: +// +// A Filter was passed that uses constructed attributes. +// +#define ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS 8555L + +// +// MessageId: ERROR_DS_UNICODEPWD_NOT_IN_QUOTES +// +// MessageText: +// +// The unicodePwd attribute value must be enclosed in double quotes. +// +#define ERROR_DS_UNICODEPWD_NOT_IN_QUOTES 8556L + +// +// MessageId: ERROR_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED +// +// MessageText: +// +// Your computer could not be joined to the domain. You have exceeded the maximum number of computer accounts you are allowed to create in this domain. Contact your system administrator to have this limit reset or increased. +// +#define ERROR_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED 8557L + +// +// MessageId: ERROR_DS_MUST_BE_RUN_ON_DST_DC +// +// MessageText: +// +// For security reasons, the operation must be run on the destination DC. +// +#define ERROR_DS_MUST_BE_RUN_ON_DST_DC 8558L + +// +// MessageId: ERROR_DS_SRC_DC_MUST_BE_SP4_OR_GREATER +// +// MessageText: +// +// For security reasons, the source DC must be NT4SP4 or greater. +// +#define ERROR_DS_SRC_DC_MUST_BE_SP4_OR_GREATER 8559L + +// +// MessageId: ERROR_DS_CANT_TREE_DELETE_CRITICAL_OBJ +// +// MessageText: +// +// Critical Directory Service System objects cannot be deleted during tree delete operations. The tree delete may have been partially performed. +// +#define ERROR_DS_CANT_TREE_DELETE_CRITICAL_OBJ 8560L + +// +// MessageId: ERROR_DS_INIT_FAILURE_CONSOLE +// +// MessageText: +// +// Directory Services could not start because of the following error: %1. +// Error Status: 0x%2. Please click OK to shutdown the system. You can use the recovery console to diagnose the system further. +// +#define ERROR_DS_INIT_FAILURE_CONSOLE 8561L + +// +// MessageId: ERROR_DS_SAM_INIT_FAILURE_CONSOLE +// +// MessageText: +// +// Security Accounts Manager initialization failed because of the following error: %1. +// Error Status: 0x%2. Please click OK to shutdown the system. You can use the recovery console to diagnose the system further. +// +#define ERROR_DS_SAM_INIT_FAILURE_CONSOLE 8562L + +// +// MessageId: ERROR_DS_FOREST_VERSION_TOO_HIGH +// +// MessageText: +// +// The version of the operating system installed is incompatible with the current forest functional level. You must upgrade to a new version of the operating system before this server can become a domain controller in this forest. +// +#define ERROR_DS_FOREST_VERSION_TOO_HIGH 8563L + +// +// MessageId: ERROR_DS_DOMAIN_VERSION_TOO_HIGH +// +// MessageText: +// +// The version of the operating system installed is incompatible with the current domain functional level. You must upgrade to a new version of the operating system before this server can become a domain controller in this domain. +// +#define ERROR_DS_DOMAIN_VERSION_TOO_HIGH 8564L + +// +// MessageId: ERROR_DS_FOREST_VERSION_TOO_LOW +// +// MessageText: +// +// The version of the operating system installed on this server no longer supports the current forest functional level. You must raise the forest functional level before this server can become a domain controller in this forest. +// +#define ERROR_DS_FOREST_VERSION_TOO_LOW 8565L + +// +// MessageId: ERROR_DS_DOMAIN_VERSION_TOO_LOW +// +// MessageText: +// +// The version of the operating system installed on this server no longer supports the current domain functional level. You must raise the domain functional level before this server can become a domain controller in this domain. +// +#define ERROR_DS_DOMAIN_VERSION_TOO_LOW 8566L + +// +// MessageId: ERROR_DS_INCOMPATIBLE_VERSION +// +// MessageText: +// +// The version of the operating system installed on this server is incompatible with the functional level of the domain or forest. +// +#define ERROR_DS_INCOMPATIBLE_VERSION 8567L + +// +// MessageId: ERROR_DS_LOW_DSA_VERSION +// +// MessageText: +// +// The functional level of the domain (or forest) cannot be raised to the requested value, because there exist one or more domain controllers in the domain (or forest) that are at a lower incompatible functional level. +// +#define ERROR_DS_LOW_DSA_VERSION 8568L + +// +// MessageId: ERROR_DS_NO_BEHAVIOR_VERSION_IN_MIXEDDOMAIN +// +// MessageText: +// +// The forest functional level cannot be raised to the requested value since one or more domains are still in mixed domain mode. All domains in the forest must be in native mode, for you to raise the forest functional level. +// +#define ERROR_DS_NO_BEHAVIOR_VERSION_IN_MIXEDDOMAIN 8569L + +// +// MessageId: ERROR_DS_NOT_SUPPORTED_SORT_ORDER +// +// MessageText: +// +// The sort order requested is not supported. +// +#define ERROR_DS_NOT_SUPPORTED_SORT_ORDER 8570L + +// +// MessageId: ERROR_DS_NAME_NOT_UNIQUE +// +// MessageText: +// +// The requested name already exists as a unique identifier. +// +#define ERROR_DS_NAME_NOT_UNIQUE 8571L + +// +// MessageId: ERROR_DS_MACHINE_ACCOUNT_CREATED_PRENT4 +// +// MessageText: +// +// The machine account was created pre-NT4. The account needs to be recreated. +// +#define ERROR_DS_MACHINE_ACCOUNT_CREATED_PRENT4 8572L + +// +// MessageId: ERROR_DS_OUT_OF_VERSION_STORE +// +// MessageText: +// +// The database is out of version store. +// +#define ERROR_DS_OUT_OF_VERSION_STORE 8573L + +// +// MessageId: ERROR_DS_INCOMPATIBLE_CONTROLS_USED +// +// MessageText: +// +// Unable to continue operation because multiple conflicting controls were used. +// +#define ERROR_DS_INCOMPATIBLE_CONTROLS_USED 8574L + +// +// MessageId: ERROR_DS_NO_REF_DOMAIN +// +// MessageText: +// +// Unable to find a valid security descriptor reference domain for this partition. +// +#define ERROR_DS_NO_REF_DOMAIN 8575L + +// +// MessageId: ERROR_DS_RESERVED_LINK_ID +// +// MessageText: +// +// Schema update failed: The link identifier is reserved. +// +#define ERROR_DS_RESERVED_LINK_ID 8576L + +// +// MessageId: ERROR_DS_LINK_ID_NOT_AVAILABLE +// +// MessageText: +// +// Schema update failed: There are no link identifiers available. +// +#define ERROR_DS_LINK_ID_NOT_AVAILABLE 8577L + +// +// MessageId: ERROR_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER +// +// MessageText: +// +// An account group can not have a universal group as a member. +// +#define ERROR_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER 8578L + +// +// MessageId: ERROR_DS_MODIFYDN_DISALLOWED_BY_INSTANCE_TYPE +// +// MessageText: +// +// Rename or move operations on naming context heads or read-only objects are not allowed. +// +#define ERROR_DS_MODIFYDN_DISALLOWED_BY_INSTANCE_TYPE 8579L + +// +// MessageId: ERROR_DS_NO_OBJECT_MOVE_IN_SCHEMA_NC +// +// MessageText: +// +// Move operations on objects in the schema naming context are not allowed. +// +#define ERROR_DS_NO_OBJECT_MOVE_IN_SCHEMA_NC 8580L + +// +// MessageId: ERROR_DS_MODIFYDN_DISALLOWED_BY_FLAG +// +// MessageText: +// +// A system flag has been set on the object and does not allow the object to be moved or renamed. +// +#define ERROR_DS_MODIFYDN_DISALLOWED_BY_FLAG 8581L + +// +// MessageId: ERROR_DS_MODIFYDN_WRONG_GRANDPARENT +// +// MessageText: +// +// This object is not allowed to change its grandparent container. Moves are not forbidden on this object, but are restricted to sibling containers. +// +#define ERROR_DS_MODIFYDN_WRONG_GRANDPARENT 8582L + +// +// MessageId: ERROR_DS_NAME_ERROR_TRUST_REFERRAL +// +// MessageText: +// +// Unable to resolve completely, a referral to another forest is generated. +// +#define ERROR_DS_NAME_ERROR_TRUST_REFERRAL 8583L + +// +// MessageId: ERROR_NOT_SUPPORTED_ON_STANDARD_SERVER +// +// MessageText: +// +// The requested action is not supported on standard server. +// +#define ERROR_NOT_SUPPORTED_ON_STANDARD_SERVER 8584L + +// +// MessageId: ERROR_DS_CANT_ACCESS_REMOTE_PART_OF_AD +// +// MessageText: +// +// Could not access a partition of the Active Directory located on a remote server. Make sure at least one server is running for the partition in question. +// +#define ERROR_DS_CANT_ACCESS_REMOTE_PART_OF_AD 8585L + +// +// MessageId: ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE_V2 +// +// MessageText: +// +// The directory cannot validate the proposed naming context (or partition) name because it does not hold a replica nor can it contact a replica of the naming context above the proposed naming context. Please ensure that the parent naming context is properly registered in DNS, and at least one replica of this naming context is reachable by the Domain Naming master. +// +#define ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE_V2 8586L + +// +// MessageId: ERROR_DS_THREAD_LIMIT_EXCEEDED +// +// MessageText: +// +// The thread limit for this request was exceeded. +// +#define ERROR_DS_THREAD_LIMIT_EXCEEDED 8587L + +// +// MessageId: ERROR_DS_NOT_CLOSEST +// +// MessageText: +// +// The Global catalog server is not in the closest site. +// +#define ERROR_DS_NOT_CLOSEST 8588L + +// +// MessageId: ERROR_DS_CANT_DERIVE_SPN_WITHOUT_SERVER_REF +// +// MessageText: +// +// The DS cannot derive a service principal name (SPN) with which to mutually authenticate the target server because the corresponding server object in the local DS database has no serverReference attribute. +// +#define ERROR_DS_CANT_DERIVE_SPN_WITHOUT_SERVER_REF 8589L + +// +// MessageId: ERROR_DS_SINGLE_USER_MODE_FAILED +// +// MessageText: +// +// The Directory Service failed to enter single user mode. +// +#define ERROR_DS_SINGLE_USER_MODE_FAILED 8590L + +// +// MessageId: ERROR_DS_NTDSCRIPT_SYNTAX_ERROR +// +// MessageText: +// +// The Directory Service cannot parse the script because of a syntax error. +// +#define ERROR_DS_NTDSCRIPT_SYNTAX_ERROR 8591L + +// +// MessageId: ERROR_DS_NTDSCRIPT_PROCESS_ERROR +// +// MessageText: +// +// The Directory Service cannot process the script because of an error. +// +#define ERROR_DS_NTDSCRIPT_PROCESS_ERROR 8592L + +// +// MessageId: ERROR_DS_DIFFERENT_REPL_EPOCHS +// +// MessageText: +// +// The directory service cannot perform the requested operation because the servers +// involved are of different replication epochs (which is usually related to a +// domain rename that is in progress). +// +#define ERROR_DS_DIFFERENT_REPL_EPOCHS 8593L + +// +// MessageId: ERROR_DS_DRS_EXTENSIONS_CHANGED +// +// MessageText: +// +// The directory service binding must be renegotiated due to a change in the server +// extensions information. +// +#define ERROR_DS_DRS_EXTENSIONS_CHANGED 8594L + +// +// MessageId: ERROR_DS_REPLICA_SET_CHANGE_NOT_ALLOWED_ON_DISABLED_CR +// +// MessageText: +// +// Operation not allowed on a disabled cross ref. +// +#define ERROR_DS_REPLICA_SET_CHANGE_NOT_ALLOWED_ON_DISABLED_CR 8595L + +// +// MessageId: ERROR_DS_NO_MSDS_INTID +// +// MessageText: +// +// Schema update failed: No values for msDS-IntId are available. +// +#define ERROR_DS_NO_MSDS_INTID 8596L + +// +// MessageId: ERROR_DS_DUP_MSDS_INTID +// +// MessageText: +// +// Schema update failed: Duplicate msDS-INtId. Retry the operation. +// +#define ERROR_DS_DUP_MSDS_INTID 8597L + +// +// MessageId: ERROR_DS_EXISTS_IN_RDNATTID +// +// MessageText: +// +// Schema deletion failed: attribute is used in rDNAttID. +// +#define ERROR_DS_EXISTS_IN_RDNATTID 8598L + +// +// MessageId: ERROR_DS_AUTHORIZATION_FAILED +// +// MessageText: +// +// The directory service failed to authorize the request. +// +#define ERROR_DS_AUTHORIZATION_FAILED 8599L + +// +// MessageId: ERROR_DS_INVALID_SCRIPT +// +// MessageText: +// +// The Directory Service cannot process the script because it is invalid. +// +#define ERROR_DS_INVALID_SCRIPT 8600L + +// +// MessageId: ERROR_DS_REMOTE_CROSSREF_OP_FAILED +// +// MessageText: +// +// The remote create cross reference operation failed on the Domain Naming Master FSMO. The operation's error is in the extended data. +// +#define ERROR_DS_REMOTE_CROSSREF_OP_FAILED 8601L + +// +// MessageId: ERROR_DS_CROSS_REF_BUSY +// +// MessageText: +// +// A cross reference is in use locally with the same name. +// +#define ERROR_DS_CROSS_REF_BUSY 8602L + +// +// MessageId: ERROR_DS_CANT_DERIVE_SPN_FOR_DELETED_DOMAIN +// +// MessageText: +// +// The DS cannot derive a service principal name (SPN) with which to mutually authenticate the target server because the server's domain has been deleted from the forest. +// +#define ERROR_DS_CANT_DERIVE_SPN_FOR_DELETED_DOMAIN 8603L + +// +// MessageId: ERROR_DS_CANT_DEMOTE_WITH_WRITEABLE_NC +// +// MessageText: +// +// Writeable NCs prevent this DC from demoting. +// +#define ERROR_DS_CANT_DEMOTE_WITH_WRITEABLE_NC 8604L + +// +// MessageId: ERROR_DS_DUPLICATE_ID_FOUND +// +// MessageText: +// +// The requested object has a non-unique identifier and cannot be retrieved. +// +#define ERROR_DS_DUPLICATE_ID_FOUND 8605L + +// +// MessageId: ERROR_DS_INSUFFICIENT_ATTR_TO_CREATE_OBJECT +// +// MessageText: +// +// Insufficient attributes were given to create an object. This object may not exist because it may have been deleted and already garbage collected. +// +#define ERROR_DS_INSUFFICIENT_ATTR_TO_CREATE_OBJECT 8606L + +// +// MessageId: ERROR_DS_GROUP_CONVERSION_ERROR +// +// MessageText: +// +// The group cannot be converted due to attribute restrictions on the requested group type. +// +#define ERROR_DS_GROUP_CONVERSION_ERROR 8607L + +// +// MessageId: ERROR_DS_CANT_MOVE_APP_BASIC_GROUP +// +// MessageText: +// +// Cross-domain move of non-empty basic application groups is not allowed. +// +#define ERROR_DS_CANT_MOVE_APP_BASIC_GROUP 8608L + +// +// MessageId: ERROR_DS_CANT_MOVE_APP_QUERY_GROUP +// +// MessageText: +// +// Cross-domain move of non-empty query based application groups is not allowed. +// +#define ERROR_DS_CANT_MOVE_APP_QUERY_GROUP 8609L + +// +// MessageId: ERROR_DS_ROLE_NOT_VERIFIED +// +// MessageText: +// +// The FSMO role ownership could not be verified because its directory partition has not replicated successfully with atleast one replication partner. +// +#define ERROR_DS_ROLE_NOT_VERIFIED 8610L + +// +// MessageId: ERROR_DS_WKO_CONTAINER_CANNOT_BE_SPECIAL +// +// MessageText: +// +// The target container for a redirection of a well known object container cannot already be a special container. +// +#define ERROR_DS_WKO_CONTAINER_CANNOT_BE_SPECIAL 8611L + +// +// MessageId: ERROR_DS_DOMAIN_RENAME_IN_PROGRESS +// +// MessageText: +// +// The Directory Service cannot perform the requested operation because a domain rename operation is in progress. +// +#define ERROR_DS_DOMAIN_RENAME_IN_PROGRESS 8612L + +// +// MessageId: ERROR_DS_EXISTING_AD_CHILD_NC +// +// MessageText: +// +// The Active Directory detected an Active Directory child partition below the +// requested new partition name. The Active Directory's partition heiarchy must +// be created in a top down method. +// +#define ERROR_DS_EXISTING_AD_CHILD_NC 8613L + +// +// MessageId: ERROR_DS_REPL_LIFETIME_EXCEEDED +// +// MessageText: +// +// The Active Directory cannot replicate with this server because the time since the last replication with this server has exceeded the tombstone lifetime. +// +#define ERROR_DS_REPL_LIFETIME_EXCEEDED 8614L + +// +// MessageId: ERROR_DS_DISALLOWED_IN_SYSTEM_CONTAINER +// +// MessageText: +// +// The requested operation is not allowed on an object under the system container. +// +#define ERROR_DS_DISALLOWED_IN_SYSTEM_CONTAINER 8615L + +// +// MessageId: ERROR_DS_LDAP_SEND_QUEUE_FULL +// +// MessageText: +// +// The LDAP servers network send queue has filled up because the client is not +// processing the results of it's requests fast enough. No more requests will +// be processed until the client catches up. If the client does not catch up +// then it will be disconnected. +// +#define ERROR_DS_LDAP_SEND_QUEUE_FULL 8616L + +// +// MessageId: ERROR_DS_DRA_OUT_SCHEDULE_WINDOW +// +// MessageText: +// +// The scheduled replication did not take place because the system was too busy to execute the request within the schedule window. The replication queue is overloaded. Consider reducing the number of partners or decreasing the scheduled replication frequency. +// +#define ERROR_DS_DRA_OUT_SCHEDULE_WINDOW 8617L + +/////////////////////////////////////////////////// +// / +// End of Active Directory Error Codes / +// / +// 8000 to 8999 / +/////////////////////////////////////////////////// + + +/////////////////////////////////////////////////// +// // +// DNS Error Codes // +// // +// 9000 to 9999 // +/////////////////////////////////////////////////// + +// ============================= +// Facility DNS Error Messages +// ============================= + +// +// DNS response codes. +// + +#define DNS_ERROR_RESPONSE_CODES_BASE 9000 + +#define DNS_ERROR_RCODE_NO_ERROR NO_ERROR + +#define DNS_ERROR_MASK 0x00002328 // 9000 or DNS_ERROR_RESPONSE_CODES_BASE + +// DNS_ERROR_RCODE_FORMAT_ERROR 0x00002329 +// +// MessageId: DNS_ERROR_RCODE_FORMAT_ERROR +// +// MessageText: +// +// DNS server unable to interpret format. +// +#define DNS_ERROR_RCODE_FORMAT_ERROR 9001L + +// DNS_ERROR_RCODE_SERVER_FAILURE 0x0000232a +// +// MessageId: DNS_ERROR_RCODE_SERVER_FAILURE +// +// MessageText: +// +// DNS server failure. +// +#define DNS_ERROR_RCODE_SERVER_FAILURE 9002L + +// DNS_ERROR_RCODE_NAME_ERROR 0x0000232b +// +// MessageId: DNS_ERROR_RCODE_NAME_ERROR +// +// MessageText: +// +// DNS name does not exist. +// +#define DNS_ERROR_RCODE_NAME_ERROR 9003L + +// DNS_ERROR_RCODE_NOT_IMPLEMENTED 0x0000232c +// +// MessageId: DNS_ERROR_RCODE_NOT_IMPLEMENTED +// +// MessageText: +// +// DNS request not supported by name server. +// +#define DNS_ERROR_RCODE_NOT_IMPLEMENTED 9004L + +// DNS_ERROR_RCODE_REFUSED 0x0000232d +// +// MessageId: DNS_ERROR_RCODE_REFUSED +// +// MessageText: +// +// DNS operation refused. +// +#define DNS_ERROR_RCODE_REFUSED 9005L + +// DNS_ERROR_RCODE_YXDOMAIN 0x0000232e +// +// MessageId: DNS_ERROR_RCODE_YXDOMAIN +// +// MessageText: +// +// DNS name that ought not exist, does exist. +// +#define DNS_ERROR_RCODE_YXDOMAIN 9006L + +// DNS_ERROR_RCODE_YXRRSET 0x0000232f +// +// MessageId: DNS_ERROR_RCODE_YXRRSET +// +// MessageText: +// +// DNS RR set that ought not exist, does exist. +// +#define DNS_ERROR_RCODE_YXRRSET 9007L + +// DNS_ERROR_RCODE_NXRRSET 0x00002330 +// +// MessageId: DNS_ERROR_RCODE_NXRRSET +// +// MessageText: +// +// DNS RR set that ought to exist, does not exist. +// +#define DNS_ERROR_RCODE_NXRRSET 9008L + +// DNS_ERROR_RCODE_NOTAUTH 0x00002331 +// +// MessageId: DNS_ERROR_RCODE_NOTAUTH +// +// MessageText: +// +// DNS server not authoritative for zone. +// +#define DNS_ERROR_RCODE_NOTAUTH 9009L + +// DNS_ERROR_RCODE_NOTZONE 0x00002332 +// +// MessageId: DNS_ERROR_RCODE_NOTZONE +// +// MessageText: +// +// DNS name in update or prereq is not in zone. +// +#define DNS_ERROR_RCODE_NOTZONE 9010L + +// DNS_ERROR_RCODE_BADSIG 0x00002338 +// +// MessageId: DNS_ERROR_RCODE_BADSIG +// +// MessageText: +// +// DNS signature failed to verify. +// +#define DNS_ERROR_RCODE_BADSIG 9016L + +// DNS_ERROR_RCODE_BADKEY 0x00002339 +// +// MessageId: DNS_ERROR_RCODE_BADKEY +// +// MessageText: +// +// DNS bad key. +// +#define DNS_ERROR_RCODE_BADKEY 9017L + +// DNS_ERROR_RCODE_BADTIME 0x0000233a +// +// MessageId: DNS_ERROR_RCODE_BADTIME +// +// MessageText: +// +// DNS signature validity expired. +// +#define DNS_ERROR_RCODE_BADTIME 9018L + +#define DNS_ERROR_RCODE_LAST DNS_ERROR_RCODE_BADTIME + + +// +// Packet format +// + +#define DNS_ERROR_PACKET_FMT_BASE 9500 + +// DNS_INFO_NO_RECORDS 0x0000251d +// +// MessageId: DNS_INFO_NO_RECORDS +// +// MessageText: +// +// No records found for given DNS query. +// +#define DNS_INFO_NO_RECORDS 9501L + +// DNS_ERROR_BAD_PACKET 0x0000251e +// +// MessageId: DNS_ERROR_BAD_PACKET +// +// MessageText: +// +// Bad DNS packet. +// +#define DNS_ERROR_BAD_PACKET 9502L + +// DNS_ERROR_NO_PACKET 0x0000251f +// +// MessageId: DNS_ERROR_NO_PACKET +// +// MessageText: +// +// No DNS packet. +// +#define DNS_ERROR_NO_PACKET 9503L + +// DNS_ERROR_RCODE 0x00002520 +// +// MessageId: DNS_ERROR_RCODE +// +// MessageText: +// +// DNS error, check rcode. +// +#define DNS_ERROR_RCODE 9504L + +// DNS_ERROR_UNSECURE_PACKET 0x00002521 +// +// MessageId: DNS_ERROR_UNSECURE_PACKET +// +// MessageText: +// +// Unsecured DNS packet. +// +#define DNS_ERROR_UNSECURE_PACKET 9505L + +#define DNS_STATUS_PACKET_UNSECURE DNS_ERROR_UNSECURE_PACKET + + +// +// General API errors +// + +#define DNS_ERROR_NO_MEMORY ERROR_OUTOFMEMORY +#define DNS_ERROR_INVALID_NAME ERROR_INVALID_NAME +#define DNS_ERROR_INVALID_DATA ERROR_INVALID_DATA + +#define DNS_ERROR_GENERAL_API_BASE 9550 + +// DNS_ERROR_INVALID_TYPE 0x0000254f +// +// MessageId: DNS_ERROR_INVALID_TYPE +// +// MessageText: +// +// Invalid DNS type. +// +#define DNS_ERROR_INVALID_TYPE 9551L + +// DNS_ERROR_INVALID_IP_ADDRESS 0x00002550 +// +// MessageId: DNS_ERROR_INVALID_IP_ADDRESS +// +// MessageText: +// +// Invalid IP address. +// +#define DNS_ERROR_INVALID_IP_ADDRESS 9552L + +// DNS_ERROR_INVALID_PROPERTY 0x00002551 +// +// MessageId: DNS_ERROR_INVALID_PROPERTY +// +// MessageText: +// +// Invalid property. +// +#define DNS_ERROR_INVALID_PROPERTY 9553L + +// DNS_ERROR_TRY_AGAIN_LATER 0x00002552 +// +// MessageId: DNS_ERROR_TRY_AGAIN_LATER +// +// MessageText: +// +// Try DNS operation again later. +// +#define DNS_ERROR_TRY_AGAIN_LATER 9554L + +// DNS_ERROR_NOT_UNIQUE 0x00002553 +// +// MessageId: DNS_ERROR_NOT_UNIQUE +// +// MessageText: +// +// Record for given name and type is not unique. +// +#define DNS_ERROR_NOT_UNIQUE 9555L + +// DNS_ERROR_NON_RFC_NAME 0x00002554 +// +// MessageId: DNS_ERROR_NON_RFC_NAME +// +// MessageText: +// +// DNS name does not comply with RFC specifications. +// +#define DNS_ERROR_NON_RFC_NAME 9556L + +// DNS_STATUS_FQDN 0x00002555 +// +// MessageId: DNS_STATUS_FQDN +// +// MessageText: +// +// DNS name is a fully-qualified DNS name. +// +#define DNS_STATUS_FQDN 9557L + +// DNS_STATUS_DOTTED_NAME 0x00002556 +// +// MessageId: DNS_STATUS_DOTTED_NAME +// +// MessageText: +// +// DNS name is dotted (multi-label). +// +#define DNS_STATUS_DOTTED_NAME 9558L + +// DNS_STATUS_SINGLE_PART_NAME 0x00002557 +// +// MessageId: DNS_STATUS_SINGLE_PART_NAME +// +// MessageText: +// +// DNS name is a single-part name. +// +#define DNS_STATUS_SINGLE_PART_NAME 9559L + +// DNS_ERROR_INVALID_NAME_CHAR 0x00002558 +// +// MessageId: DNS_ERROR_INVALID_NAME_CHAR +// +// MessageText: +// +// DNS name contains an invalid character. +// +#define DNS_ERROR_INVALID_NAME_CHAR 9560L + +// DNS_ERROR_NUMERIC_NAME 0x00002559 +// +// MessageId: DNS_ERROR_NUMERIC_NAME +// +// MessageText: +// +// DNS name is entirely numeric. +// +#define DNS_ERROR_NUMERIC_NAME 9561L + +// DNS_ERROR_NOT_ALLOWED_ON_ROOT_SERVER 0x0000255A +// +// MessageId: DNS_ERROR_NOT_ALLOWED_ON_ROOT_SERVER +// +// MessageText: +// +// The operation requested is not permitted on a DNS root server. +// +#define DNS_ERROR_NOT_ALLOWED_ON_ROOT_SERVER 9562L + +// DNS_ERROR_NOT_ALLOWED_UNDER_DELEGATION 0x0000255B +// +// MessageId: DNS_ERROR_NOT_ALLOWED_UNDER_DELEGATION +// +// MessageText: +// +// The record could not be created because this part of the DNS namespace has +// been delegated to another server. +// +#define DNS_ERROR_NOT_ALLOWED_UNDER_DELEGATION 9563L + +// DNS_ERROR_CANNOT_FIND_ROOT_HINTS 0x0000255C +// +// MessageId: DNS_ERROR_CANNOT_FIND_ROOT_HINTS +// +// MessageText: +// +// The DNS server could not find a set of root hints. +// +#define DNS_ERROR_CANNOT_FIND_ROOT_HINTS 9564L + +// DNS_ERROR_INCONSISTENT_ROOT_HINTS 0x0000255D +// +// MessageId: DNS_ERROR_INCONSISTENT_ROOT_HINTS +// +// MessageText: +// +// The DNS server found root hints but they were not consistent across +// all adapters. +// +#define DNS_ERROR_INCONSISTENT_ROOT_HINTS 9565L + + +// +// Zone errors +// + +#define DNS_ERROR_ZONE_BASE 9600 + +// DNS_ERROR_ZONE_DOES_NOT_EXIST 0x00002581 +// +// MessageId: DNS_ERROR_ZONE_DOES_NOT_EXIST +// +// MessageText: +// +// DNS zone does not exist. +// +#define DNS_ERROR_ZONE_DOES_NOT_EXIST 9601L + +// DNS_ERROR_NO_ZONE_INFO 0x00002582 +// +// MessageId: DNS_ERROR_NO_ZONE_INFO +// +// MessageText: +// +// DNS zone information not available. +// +#define DNS_ERROR_NO_ZONE_INFO 9602L + +// DNS_ERROR_INVALID_ZONE_OPERATION 0x00002583 +// +// MessageId: DNS_ERROR_INVALID_ZONE_OPERATION +// +// MessageText: +// +// Invalid operation for DNS zone. +// +#define DNS_ERROR_INVALID_ZONE_OPERATION 9603L + +// DNS_ERROR_ZONE_CONFIGURATION_ERROR 0x00002584 +// +// MessageId: DNS_ERROR_ZONE_CONFIGURATION_ERROR +// +// MessageText: +// +// Invalid DNS zone configuration. +// +#define DNS_ERROR_ZONE_CONFIGURATION_ERROR 9604L + +// DNS_ERROR_ZONE_HAS_NO_SOA_RECORD 0x00002585 +// +// MessageId: DNS_ERROR_ZONE_HAS_NO_SOA_RECORD +// +// MessageText: +// +// DNS zone has no start of authority (SOA) record. +// +#define DNS_ERROR_ZONE_HAS_NO_SOA_RECORD 9605L + +// DNS_ERROR_ZONE_HAS_NO_NS_RECORDS 0x00002586 +// +// MessageId: DNS_ERROR_ZONE_HAS_NO_NS_RECORDS +// +// MessageText: +// +// DNS zone has no Name Server (NS) record. +// +#define DNS_ERROR_ZONE_HAS_NO_NS_RECORDS 9606L + +// DNS_ERROR_ZONE_LOCKED 0x00002587 +// +// MessageId: DNS_ERROR_ZONE_LOCKED +// +// MessageText: +// +// DNS zone is locked. +// +#define DNS_ERROR_ZONE_LOCKED 9607L + +// DNS_ERROR_ZONE_CREATION_FAILED 0x00002588 +// +// MessageId: DNS_ERROR_ZONE_CREATION_FAILED +// +// MessageText: +// +// DNS zone creation failed. +// +#define DNS_ERROR_ZONE_CREATION_FAILED 9608L + +// DNS_ERROR_ZONE_ALREADY_EXISTS 0x00002589 +// +// MessageId: DNS_ERROR_ZONE_ALREADY_EXISTS +// +// MessageText: +// +// DNS zone already exists. +// +#define DNS_ERROR_ZONE_ALREADY_EXISTS 9609L + +// DNS_ERROR_AUTOZONE_ALREADY_EXISTS 0x0000258a +// +// MessageId: DNS_ERROR_AUTOZONE_ALREADY_EXISTS +// +// MessageText: +// +// DNS automatic zone already exists. +// +#define DNS_ERROR_AUTOZONE_ALREADY_EXISTS 9610L + +// DNS_ERROR_INVALID_ZONE_TYPE 0x0000258b +// +// MessageId: DNS_ERROR_INVALID_ZONE_TYPE +// +// MessageText: +// +// Invalid DNS zone type. +// +#define DNS_ERROR_INVALID_ZONE_TYPE 9611L + +// DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP 0x0000258c +// +// MessageId: DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP +// +// MessageText: +// +// Secondary DNS zone requires master IP address. +// +#define DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP 9612L + +// DNS_ERROR_ZONE_NOT_SECONDARY 0x0000258d +// +// MessageId: DNS_ERROR_ZONE_NOT_SECONDARY +// +// MessageText: +// +// DNS zone not secondary. +// +#define DNS_ERROR_ZONE_NOT_SECONDARY 9613L + +// DNS_ERROR_NEED_SECONDARY_ADDRESSES 0x0000258e +// +// MessageId: DNS_ERROR_NEED_SECONDARY_ADDRESSES +// +// MessageText: +// +// Need secondary IP address. +// +#define DNS_ERROR_NEED_SECONDARY_ADDRESSES 9614L + +// DNS_ERROR_WINS_INIT_FAILED 0x0000258f +// +// MessageId: DNS_ERROR_WINS_INIT_FAILED +// +// MessageText: +// +// WINS initialization failed. +// +#define DNS_ERROR_WINS_INIT_FAILED 9615L + +// DNS_ERROR_NEED_WINS_SERVERS 0x00002590 +// +// MessageId: DNS_ERROR_NEED_WINS_SERVERS +// +// MessageText: +// +// Need WINS servers. +// +#define DNS_ERROR_NEED_WINS_SERVERS 9616L + +// DNS_ERROR_NBSTAT_INIT_FAILED 0x00002591 +// +// MessageId: DNS_ERROR_NBSTAT_INIT_FAILED +// +// MessageText: +// +// NBTSTAT initialization call failed. +// +#define DNS_ERROR_NBSTAT_INIT_FAILED 9617L + +// DNS_ERROR_SOA_DELETE_INVALID 0x00002592 +// +// MessageId: DNS_ERROR_SOA_DELETE_INVALID +// +// MessageText: +// +// Invalid delete of start of authority (SOA) +// +#define DNS_ERROR_SOA_DELETE_INVALID 9618L + +// DNS_ERROR_FORWARDER_ALREADY_EXISTS 0x00002593 +// +// MessageId: DNS_ERROR_FORWARDER_ALREADY_EXISTS +// +// MessageText: +// +// A conditional forwarding zone already exists for that name. +// +#define DNS_ERROR_FORWARDER_ALREADY_EXISTS 9619L + +// DNS_ERROR_ZONE_REQUIRES_MASTER_IP 0x00002594 +// +// MessageId: DNS_ERROR_ZONE_REQUIRES_MASTER_IP +// +// MessageText: +// +// This zone must be configured with one or more master DNS server IP addresses. +// +#define DNS_ERROR_ZONE_REQUIRES_MASTER_IP 9620L + +// DNS_ERROR_ZONE_IS_SHUTDOWN 0x00002595 +// +// MessageId: DNS_ERROR_ZONE_IS_SHUTDOWN +// +// MessageText: +// +// The operation cannot be performed because this zone is shutdown. +// +#define DNS_ERROR_ZONE_IS_SHUTDOWN 9621L + + +// +// Datafile errors +// + +#define DNS_ERROR_DATAFILE_BASE 9650 + +// DNS 0x000025b3 +// +// MessageId: DNS_ERROR_PRIMARY_REQUIRES_DATAFILE +// +// MessageText: +// +// Primary DNS zone requires datafile. +// +#define DNS_ERROR_PRIMARY_REQUIRES_DATAFILE 9651L + +// DNS 0x000025b4 +// +// MessageId: DNS_ERROR_INVALID_DATAFILE_NAME +// +// MessageText: +// +// Invalid datafile name for DNS zone. +// +#define DNS_ERROR_INVALID_DATAFILE_NAME 9652L + +// DNS 0x000025b5 +// +// MessageId: DNS_ERROR_DATAFILE_OPEN_FAILURE +// +// MessageText: +// +// Failed to open datafile for DNS zone. +// +#define DNS_ERROR_DATAFILE_OPEN_FAILURE 9653L + +// DNS 0x000025b6 +// +// MessageId: DNS_ERROR_FILE_WRITEBACK_FAILED +// +// MessageText: +// +// Failed to write datafile for DNS zone. +// +#define DNS_ERROR_FILE_WRITEBACK_FAILED 9654L + +// DNS 0x000025b7 +// +// MessageId: DNS_ERROR_DATAFILE_PARSING +// +// MessageText: +// +// Failure while reading datafile for DNS zone. +// +#define DNS_ERROR_DATAFILE_PARSING 9655L + + +// +// Database errors +// + +#define DNS_ERROR_DATABASE_BASE 9700 + +// DNS_ERROR_RECORD_DOES_NOT_EXIST 0x000025e5 +// +// MessageId: DNS_ERROR_RECORD_DOES_NOT_EXIST +// +// MessageText: +// +// DNS record does not exist. +// +#define DNS_ERROR_RECORD_DOES_NOT_EXIST 9701L + +// DNS_ERROR_RECORD_FORMAT 0x000025e6 +// +// MessageId: DNS_ERROR_RECORD_FORMAT +// +// MessageText: +// +// DNS record format error. +// +#define DNS_ERROR_RECORD_FORMAT 9702L + +// DNS_ERROR_NODE_CREATION_FAILED 0x000025e7 +// +// MessageId: DNS_ERROR_NODE_CREATION_FAILED +// +// MessageText: +// +// Node creation failure in DNS. +// +#define DNS_ERROR_NODE_CREATION_FAILED 9703L + +// DNS_ERROR_UNKNOWN_RECORD_TYPE 0x000025e8 +// +// MessageId: DNS_ERROR_UNKNOWN_RECORD_TYPE +// +// MessageText: +// +// Unknown DNS record type. +// +#define DNS_ERROR_UNKNOWN_RECORD_TYPE 9704L + +// DNS_ERROR_RECORD_TIMED_OUT 0x000025e9 +// +// MessageId: DNS_ERROR_RECORD_TIMED_OUT +// +// MessageText: +// +// DNS record timed out. +// +#define DNS_ERROR_RECORD_TIMED_OUT 9705L + +// DNS_ERROR_NAME_NOT_IN_ZONE 0x000025ea +// +// MessageId: DNS_ERROR_NAME_NOT_IN_ZONE +// +// MessageText: +// +// Name not in DNS zone. +// +#define DNS_ERROR_NAME_NOT_IN_ZONE 9706L + +// DNS_ERROR_CNAME_LOOP 0x000025eb +// +// MessageId: DNS_ERROR_CNAME_LOOP +// +// MessageText: +// +// CNAME loop detected. +// +#define DNS_ERROR_CNAME_LOOP 9707L + +// DNS_ERROR_NODE_IS_CNAME 0x000025ec +// +// MessageId: DNS_ERROR_NODE_IS_CNAME +// +// MessageText: +// +// Node is a CNAME DNS record. +// +#define DNS_ERROR_NODE_IS_CNAME 9708L + +// DNS_ERROR_CNAME_COLLISION 0x000025ed +// +// MessageId: DNS_ERROR_CNAME_COLLISION +// +// MessageText: +// +// A CNAME record already exists for given name. +// +#define DNS_ERROR_CNAME_COLLISION 9709L + +// DNS_ERROR_RECORD_ONLY_AT_ZONE_ROOT 0x000025ee +// +// MessageId: DNS_ERROR_RECORD_ONLY_AT_ZONE_ROOT +// +// MessageText: +// +// Record only at DNS zone root. +// +#define DNS_ERROR_RECORD_ONLY_AT_ZONE_ROOT 9710L + +// DNS_ERROR_RECORD_ALREADY_EXISTS 0x000025ef +// +// MessageId: DNS_ERROR_RECORD_ALREADY_EXISTS +// +// MessageText: +// +// DNS record already exists. +// +#define DNS_ERROR_RECORD_ALREADY_EXISTS 9711L + +// DNS_ERROR_SECONDARY_DATA 0x000025f0 +// +// MessageId: DNS_ERROR_SECONDARY_DATA +// +// MessageText: +// +// Secondary DNS zone data error. +// +#define DNS_ERROR_SECONDARY_DATA 9712L + +// DNS_ERROR_NO_CREATE_CACHE_DATA 0x000025f1 +// +// MessageId: DNS_ERROR_NO_CREATE_CACHE_DATA +// +// MessageText: +// +// Could not create DNS cache data. +// +#define DNS_ERROR_NO_CREATE_CACHE_DATA 9713L + +// DNS_ERROR_NAME_DOES_NOT_EXIST 0x000025f2 +// +// MessageId: DNS_ERROR_NAME_DOES_NOT_EXIST +// +// MessageText: +// +// DNS name does not exist. +// +#define DNS_ERROR_NAME_DOES_NOT_EXIST 9714L + +// DNS_WARNING_PTR_CREATE_FAILED 0x000025f3 +// +// MessageId: DNS_WARNING_PTR_CREATE_FAILED +// +// MessageText: +// +// Could not create pointer (PTR) record. +// +#define DNS_WARNING_PTR_CREATE_FAILED 9715L + +// DNS_WARNING_DOMAIN_UNDELETED 0x000025f4 +// +// MessageId: DNS_WARNING_DOMAIN_UNDELETED +// +// MessageText: +// +// DNS domain was undeleted. +// +#define DNS_WARNING_DOMAIN_UNDELETED 9716L + +// DNS_ERROR_DS_UNAVAILABLE 0x000025f5 +// +// MessageId: DNS_ERROR_DS_UNAVAILABLE +// +// MessageText: +// +// The directory service is unavailable. +// +#define DNS_ERROR_DS_UNAVAILABLE 9717L + +// DNS_ERROR_DS_ZONE_ALREADY_EXISTS 0x000025f6 +// +// MessageId: DNS_ERROR_DS_ZONE_ALREADY_EXISTS +// +// MessageText: +// +// DNS zone already exists in the directory service. +// +#define DNS_ERROR_DS_ZONE_ALREADY_EXISTS 9718L + +// DNS_ERROR_NO_BOOTFILE_IF_DS_ZONE 0x000025f7 +// +// MessageId: DNS_ERROR_NO_BOOTFILE_IF_DS_ZONE +// +// MessageText: +// +// DNS server not creating or reading the boot file for the directory service integrated DNS zone. +// +#define DNS_ERROR_NO_BOOTFILE_IF_DS_ZONE 9719L + + +// +// Operation errors +// + +#define DNS_ERROR_OPERATION_BASE 9750 + +// DNS_INFO_AXFR_COMPLETE 0x00002617 +// +// MessageId: DNS_INFO_AXFR_COMPLETE +// +// MessageText: +// +// DNS AXFR (zone transfer) complete. +// +#define DNS_INFO_AXFR_COMPLETE 9751L + +// DNS_ERROR_AXFR 0x00002618 +// +// MessageId: DNS_ERROR_AXFR +// +// MessageText: +// +// DNS zone transfer failed. +// +#define DNS_ERROR_AXFR 9752L + +// DNS_INFO_ADDED_LOCAL_WINS 0x00002619 +// +// MessageId: DNS_INFO_ADDED_LOCAL_WINS +// +// MessageText: +// +// Added local WINS server. +// +#define DNS_INFO_ADDED_LOCAL_WINS 9753L + + +// +// Secure update +// + +#define DNS_ERROR_SECURE_BASE 9800 + +// DNS_STATUS_CONTINUE_NEEDED 0x00002649 +// +// MessageId: DNS_STATUS_CONTINUE_NEEDED +// +// MessageText: +// +// Secure update call needs to continue update request. +// +#define DNS_STATUS_CONTINUE_NEEDED 9801L + + +// +// Setup errors +// + +#define DNS_ERROR_SETUP_BASE 9850 + +// DNS_ERROR_NO_TCPIP 0x0000267b +// +// MessageId: DNS_ERROR_NO_TCPIP +// +// MessageText: +// +// TCP/IP network protocol not installed. +// +#define DNS_ERROR_NO_TCPIP 9851L + +// DNS_ERROR_NO_DNS_SERVERS 0x0000267c +// +// MessageId: DNS_ERROR_NO_DNS_SERVERS +// +// MessageText: +// +// No DNS servers configured for local system. +// +#define DNS_ERROR_NO_DNS_SERVERS 9852L + + +// +// Directory partition (DP) errors +// + +#define DNS_ERROR_DP_BASE 9900 + +// DNS_ERROR_DP_DOES_NOT_EXIST 0x000026ad +// +// MessageId: DNS_ERROR_DP_DOES_NOT_EXIST +// +// MessageText: +// +// The specified directory partition does not exist. +// +#define DNS_ERROR_DP_DOES_NOT_EXIST 9901L + +// DNS_ERROR_DP_ALREADY_EXISTS 0x000026ae +// +// MessageId: DNS_ERROR_DP_ALREADY_EXISTS +// +// MessageText: +// +// The specified directory partition already exists. +// +#define DNS_ERROR_DP_ALREADY_EXISTS 9902L + +// DNS_ERROR_DP_NOT_ENLISTED 0x000026af +// +// MessageId: DNS_ERROR_DP_NOT_ENLISTED +// +// MessageText: +// +// This DNS server is not enlisted in the specified directory partition. +// +#define DNS_ERROR_DP_NOT_ENLISTED 9903L + +// DNS_ERROR_DP_ALREADY_ENLISTED 0x000026b0 +// +// MessageId: DNS_ERROR_DP_ALREADY_ENLISTED +// +// MessageText: +// +// This DNS server is already enlisted in the specified directory partition. +// +#define DNS_ERROR_DP_ALREADY_ENLISTED 9904L + +// DNS_ERROR_DP_NOT_AVAILABLE 0x000026b1 +// +// MessageId: DNS_ERROR_DP_NOT_AVAILABLE +// +// MessageText: +// +// The directory partition is not available at this time. Please wait +// a few minutes and try again. +// +#define DNS_ERROR_DP_NOT_AVAILABLE 9905L + +// DNS_ERROR_DP_FSMO_ERROR 0x000026b2 +// +// MessageId: DNS_ERROR_DP_FSMO_ERROR +// +// MessageText: +// +// The application directory partition operation failed. The domain controller +// holding the domain naming master role is down or unable to service the +// request or is not running Windows Server 2003. +// +#define DNS_ERROR_DP_FSMO_ERROR 9906L + +/////////////////////////////////////////////////// +// // +// End of DNS Error Codes // +// // +// 9000 to 9999 // +/////////////////////////////////////////////////// + + +/////////////////////////////////////////////////// +// // +// WinSock Error Codes // +// // +// 10000 to 11999 // +/////////////////////////////////////////////////// + +// +// WinSock error codes are also defined in WinSock.h +// and WinSock2.h, hence the IFDEF +// +#ifndef WSABASEERR +#define WSABASEERR 10000 +// +// MessageId: WSAEINTR +// +// MessageText: +// +// A blocking operation was interrupted by a call to WSACancelBlockingCall. +// +#define WSAEINTR 10004L + +// +// MessageId: WSAEBADF +// +// MessageText: +// +// The file handle supplied is not valid. +// +#define WSAEBADF 10009L + +// +// MessageId: WSAEACCES +// +// MessageText: +// +// An attempt was made to access a socket in a way forbidden by its access permissions. +// +#define WSAEACCES 10013L + +// +// MessageId: WSAEFAULT +// +// MessageText: +// +// The system detected an invalid pointer address in attempting to use a pointer argument in a call. +// +#define WSAEFAULT 10014L + +// +// MessageId: WSAEINVAL +// +// MessageText: +// +// An invalid argument was supplied. +// +#define WSAEINVAL 10022L + +// +// MessageId: WSAEMFILE +// +// MessageText: +// +// Too many open sockets. +// +#define WSAEMFILE 10024L + +// +// MessageId: WSAEWOULDBLOCK +// +// MessageText: +// +// A non-blocking socket operation could not be completed immediately. +// +#define WSAEWOULDBLOCK 10035L + +// +// MessageId: WSAEINPROGRESS +// +// MessageText: +// +// A blocking operation is currently executing. +// +#define WSAEINPROGRESS 10036L + +// +// MessageId: WSAEALREADY +// +// MessageText: +// +// An operation was attempted on a non-blocking socket that already had an operation in progress. +// +#define WSAEALREADY 10037L + +// +// MessageId: WSAENOTSOCK +// +// MessageText: +// +// An operation was attempted on something that is not a socket. +// +#define WSAENOTSOCK 10038L + +// +// MessageId: WSAEDESTADDRREQ +// +// MessageText: +// +// A required address was omitted from an operation on a socket. +// +#define WSAEDESTADDRREQ 10039L + +// +// MessageId: WSAEMSGSIZE +// +// MessageText: +// +// A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was smaller than the datagram itself. +// +#define WSAEMSGSIZE 10040L + +// +// MessageId: WSAEPROTOTYPE +// +// MessageText: +// +// A protocol was specified in the socket function call that does not support the semantics of the socket type requested. +// +#define WSAEPROTOTYPE 10041L + +// +// MessageId: WSAENOPROTOOPT +// +// MessageText: +// +// An unknown, invalid, or unsupported option or level was specified in a getsockopt or setsockopt call. +// +#define WSAENOPROTOOPT 10042L + +// +// MessageId: WSAEPROTONOSUPPORT +// +// MessageText: +// +// The requested protocol has not been configured into the system, or no implementation for it exists. +// +#define WSAEPROTONOSUPPORT 10043L + +// +// MessageId: WSAESOCKTNOSUPPORT +// +// MessageText: +// +// The support for the specified socket type does not exist in this address family. +// +#define WSAESOCKTNOSUPPORT 10044L + +// +// MessageId: WSAEOPNOTSUPP +// +// MessageText: +// +// The attempted operation is not supported for the type of object referenced. +// +#define WSAEOPNOTSUPP 10045L + +// +// MessageId: WSAEPFNOSUPPORT +// +// MessageText: +// +// The protocol family has not been configured into the system or no implementation for it exists. +// +#define WSAEPFNOSUPPORT 10046L + +// +// MessageId: WSAEAFNOSUPPORT +// +// MessageText: +// +// An address incompatible with the requested protocol was used. +// +#define WSAEAFNOSUPPORT 10047L + +// +// MessageId: WSAEADDRINUSE +// +// MessageText: +// +// Only one usage of each socket address (protocol/network address/port) is normally permitted. +// +#define WSAEADDRINUSE 10048L + +// +// MessageId: WSAEADDRNOTAVAIL +// +// MessageText: +// +// The requested address is not valid in its context. +// +#define WSAEADDRNOTAVAIL 10049L + +// +// MessageId: WSAENETDOWN +// +// MessageText: +// +// A socket operation encountered a dead network. +// +#define WSAENETDOWN 10050L + +// +// MessageId: WSAENETUNREACH +// +// MessageText: +// +// A socket operation was attempted to an unreachable network. +// +#define WSAENETUNREACH 10051L + +// +// MessageId: WSAENETRESET +// +// MessageText: +// +// The connection has been broken due to keep-alive activity detecting a failure while the operation was in progress. +// +#define WSAENETRESET 10052L + +// +// MessageId: WSAECONNABORTED +// +// MessageText: +// +// An established connection was aborted by the software in your host machine. +// +#define WSAECONNABORTED 10053L + +// +// MessageId: WSAECONNRESET +// +// MessageText: +// +// An existing connection was forcibly closed by the remote host. +// +#define WSAECONNRESET 10054L + +// +// MessageId: WSAENOBUFS +// +// MessageText: +// +// An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full. +// +#define WSAENOBUFS 10055L + +// +// MessageId: WSAEISCONN +// +// MessageText: +// +// A connect request was made on an already connected socket. +// +#define WSAEISCONN 10056L + +// +// MessageId: WSAENOTCONN +// +// MessageText: +// +// A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied. +// +#define WSAENOTCONN 10057L + +// +// MessageId: WSAESHUTDOWN +// +// MessageText: +// +// A request to send or receive data was disallowed because the socket had already been shut down in that direction with a previous shutdown call. +// +#define WSAESHUTDOWN 10058L + +// +// MessageId: WSAETOOMANYREFS +// +// MessageText: +// +// Too many references to some kernel object. +// +#define WSAETOOMANYREFS 10059L + +// +// MessageId: WSAETIMEDOUT +// +// MessageText: +// +// A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. +// +#define WSAETIMEDOUT 10060L + +// +// MessageId: WSAECONNREFUSED +// +// MessageText: +// +// No connection could be made because the target machine actively refused it. +// +#define WSAECONNREFUSED 10061L + +// +// MessageId: WSAELOOP +// +// MessageText: +// +// Cannot translate name. +// +#define WSAELOOP 10062L + +// +// MessageId: WSAENAMETOOLONG +// +// MessageText: +// +// Name component or name was too long. +// +#define WSAENAMETOOLONG 10063L + +// +// MessageId: WSAEHOSTDOWN +// +// MessageText: +// +// A socket operation failed because the destination host was down. +// +#define WSAEHOSTDOWN 10064L + +// +// MessageId: WSAEHOSTUNREACH +// +// MessageText: +// +// A socket operation was attempted to an unreachable host. +// +#define WSAEHOSTUNREACH 10065L + +// +// MessageId: WSAENOTEMPTY +// +// MessageText: +// +// Cannot remove a directory that is not empty. +// +#define WSAENOTEMPTY 10066L + +// +// MessageId: WSAEPROCLIM +// +// MessageText: +// +// A Windows Sockets implementation may have a limit on the number of applications that may use it simultaneously. +// +#define WSAEPROCLIM 10067L + +// +// MessageId: WSAEUSERS +// +// MessageText: +// +// Ran out of quota. +// +#define WSAEUSERS 10068L + +// +// MessageId: WSAEDQUOT +// +// MessageText: +// +// Ran out of disk quota. +// +#define WSAEDQUOT 10069L + +// +// MessageId: WSAESTALE +// +// MessageText: +// +// File handle reference is no longer available. +// +#define WSAESTALE 10070L + +// +// MessageId: WSAEREMOTE +// +// MessageText: +// +// Item is not available locally. +// +#define WSAEREMOTE 10071L + +// +// MessageId: WSASYSNOTREADY +// +// MessageText: +// +// WSAStartup cannot function at this time because the underlying system it uses to provide network services is currently unavailable. +// +#define WSASYSNOTREADY 10091L + +// +// MessageId: WSAVERNOTSUPPORTED +// +// MessageText: +// +// The Windows Sockets version requested is not supported. +// +#define WSAVERNOTSUPPORTED 10092L + +// +// MessageId: WSANOTINITIALISED +// +// MessageText: +// +// Either the application has not called WSAStartup, or WSAStartup failed. +// +#define WSANOTINITIALISED 10093L + +// +// MessageId: WSAEDISCON +// +// MessageText: +// +// Returned by WSARecv or WSARecvFrom to indicate the remote party has initiated a graceful shutdown sequence. +// +#define WSAEDISCON 10101L + +// +// MessageId: WSAENOMORE +// +// MessageText: +// +// No more results can be returned by WSALookupServiceNext. +// +#define WSAENOMORE 10102L + +// +// MessageId: WSAECANCELLED +// +// MessageText: +// +// A call to WSALookupServiceEnd was made while this call was still processing. The call has been canceled. +// +#define WSAECANCELLED 10103L + +// +// MessageId: WSAEINVALIDPROCTABLE +// +// MessageText: +// +// The procedure call table is invalid. +// +#define WSAEINVALIDPROCTABLE 10104L + +// +// MessageId: WSAEINVALIDPROVIDER +// +// MessageText: +// +// The requested service provider is invalid. +// +#define WSAEINVALIDPROVIDER 10105L + +// +// MessageId: WSAEPROVIDERFAILEDINIT +// +// MessageText: +// +// The requested service provider could not be loaded or initialized. +// +#define WSAEPROVIDERFAILEDINIT 10106L + +// +// MessageId: WSASYSCALLFAILURE +// +// MessageText: +// +// A system call that should never fail has failed. +// +#define WSASYSCALLFAILURE 10107L + +// +// MessageId: WSASERVICE_NOT_FOUND +// +// MessageText: +// +// No such service is known. The service cannot be found in the specified name space. +// +#define WSASERVICE_NOT_FOUND 10108L + +// +// MessageId: WSATYPE_NOT_FOUND +// +// MessageText: +// +// The specified class was not found. +// +#define WSATYPE_NOT_FOUND 10109L + +// +// MessageId: WSA_E_NO_MORE +// +// MessageText: +// +// No more results can be returned by WSALookupServiceNext. +// +#define WSA_E_NO_MORE 10110L + +// +// MessageId: WSA_E_CANCELLED +// +// MessageText: +// +// A call to WSALookupServiceEnd was made while this call was still processing. The call has been canceled. +// +#define WSA_E_CANCELLED 10111L + +// +// MessageId: WSAEREFUSED +// +// MessageText: +// +// A database query failed because it was actively refused. +// +#define WSAEREFUSED 10112L + +// +// MessageId: WSAHOST_NOT_FOUND +// +// MessageText: +// +// No such host is known. +// +#define WSAHOST_NOT_FOUND 11001L + +// +// MessageId: WSATRY_AGAIN +// +// MessageText: +// +// This is usually a temporary error during hostname resolution and means that the local server did not receive a response from an authoritative server. +// +#define WSATRY_AGAIN 11002L + +// +// MessageId: WSANO_RECOVERY +// +// MessageText: +// +// A non-recoverable error occurred during a database lookup. +// +#define WSANO_RECOVERY 11003L + +// +// MessageId: WSANO_DATA +// +// MessageText: +// +// The requested name is valid, but no data of the requested type was found. +// +#define WSANO_DATA 11004L + +// +// MessageId: WSA_QOS_RECEIVERS +// +// MessageText: +// +// At least one reserve has arrived. +// +#define WSA_QOS_RECEIVERS 11005L + +// +// MessageId: WSA_QOS_SENDERS +// +// MessageText: +// +// At least one path has arrived. +// +#define WSA_QOS_SENDERS 11006L + +// +// MessageId: WSA_QOS_NO_SENDERS +// +// MessageText: +// +// There are no senders. +// +#define WSA_QOS_NO_SENDERS 11007L + +// +// MessageId: WSA_QOS_NO_RECEIVERS +// +// MessageText: +// +// There are no receivers. +// +#define WSA_QOS_NO_RECEIVERS 11008L + +// +// MessageId: WSA_QOS_REQUEST_CONFIRMED +// +// MessageText: +// +// Reserve has been confirmed. +// +#define WSA_QOS_REQUEST_CONFIRMED 11009L + +// +// MessageId: WSA_QOS_ADMISSION_FAILURE +// +// MessageText: +// +// Error due to lack of resources. +// +#define WSA_QOS_ADMISSION_FAILURE 11010L + +// +// MessageId: WSA_QOS_POLICY_FAILURE +// +// MessageText: +// +// Rejected for administrative reasons - bad credentials. +// +#define WSA_QOS_POLICY_FAILURE 11011L + +// +// MessageId: WSA_QOS_BAD_STYLE +// +// MessageText: +// +// Unknown or conflicting style. +// +#define WSA_QOS_BAD_STYLE 11012L + +// +// MessageId: WSA_QOS_BAD_OBJECT +// +// MessageText: +// +// Problem with some part of the filterspec or providerspecific buffer in general. +// +#define WSA_QOS_BAD_OBJECT 11013L + +// +// MessageId: WSA_QOS_TRAFFIC_CTRL_ERROR +// +// MessageText: +// +// Problem with some part of the flowspec. +// +#define WSA_QOS_TRAFFIC_CTRL_ERROR 11014L + +// +// MessageId: WSA_QOS_GENERIC_ERROR +// +// MessageText: +// +// General QOS error. +// +#define WSA_QOS_GENERIC_ERROR 11015L + +// +// MessageId: WSA_QOS_ESERVICETYPE +// +// MessageText: +// +// An invalid or unrecognized service type was found in the flowspec. +// +#define WSA_QOS_ESERVICETYPE 11016L + +// +// MessageId: WSA_QOS_EFLOWSPEC +// +// MessageText: +// +// An invalid or inconsistent flowspec was found in the QOS structure. +// +#define WSA_QOS_EFLOWSPEC 11017L + +// +// MessageId: WSA_QOS_EPROVSPECBUF +// +// MessageText: +// +// Invalid QOS provider-specific buffer. +// +#define WSA_QOS_EPROVSPECBUF 11018L + +// +// MessageId: WSA_QOS_EFILTERSTYLE +// +// MessageText: +// +// An invalid QOS filter style was used. +// +#define WSA_QOS_EFILTERSTYLE 11019L + +// +// MessageId: WSA_QOS_EFILTERTYPE +// +// MessageText: +// +// An invalid QOS filter type was used. +// +#define WSA_QOS_EFILTERTYPE 11020L + +// +// MessageId: WSA_QOS_EFILTERCOUNT +// +// MessageText: +// +// An incorrect number of QOS FILTERSPECs were specified in the FLOWDESCRIPTOR. +// +#define WSA_QOS_EFILTERCOUNT 11021L + +// +// MessageId: WSA_QOS_EOBJLENGTH +// +// MessageText: +// +// An object with an invalid ObjectLength field was specified in the QOS provider-specific buffer. +// +#define WSA_QOS_EOBJLENGTH 11022L + +// +// MessageId: WSA_QOS_EFLOWCOUNT +// +// MessageText: +// +// An incorrect number of flow descriptors was specified in the QOS structure. +// +#define WSA_QOS_EFLOWCOUNT 11023L + +// +// MessageId: WSA_QOS_EUNKOWNPSOBJ +// +// MessageText: +// +// An unrecognized object was found in the QOS provider-specific buffer. +// +#define WSA_QOS_EUNKOWNPSOBJ 11024L + +// +// MessageId: WSA_QOS_EPOLICYOBJ +// +// MessageText: +// +// An invalid policy object was found in the QOS provider-specific buffer. +// +#define WSA_QOS_EPOLICYOBJ 11025L + +// +// MessageId: WSA_QOS_EFLOWDESC +// +// MessageText: +// +// An invalid QOS flow descriptor was found in the flow descriptor list. +// +#define WSA_QOS_EFLOWDESC 11026L + +// +// MessageId: WSA_QOS_EPSFLOWSPEC +// +// MessageText: +// +// An invalid or inconsistent flowspec was found in the QOS provider specific buffer. +// +#define WSA_QOS_EPSFLOWSPEC 11027L + +// +// MessageId: WSA_QOS_EPSFILTERSPEC +// +// MessageText: +// +// An invalid FILTERSPEC was found in the QOS provider-specific buffer. +// +#define WSA_QOS_EPSFILTERSPEC 11028L + +// +// MessageId: WSA_QOS_ESDMODEOBJ +// +// MessageText: +// +// An invalid shape discard mode object was found in the QOS provider specific buffer. +// +#define WSA_QOS_ESDMODEOBJ 11029L + +// +// MessageId: WSA_QOS_ESHAPERATEOBJ +// +// MessageText: +// +// An invalid shaping rate object was found in the QOS provider-specific buffer. +// +#define WSA_QOS_ESHAPERATEOBJ 11030L + +// +// MessageId: WSA_QOS_RESERVED_PETYPE +// +// MessageText: +// +// A reserved policy element was found in the QOS provider-specific buffer. +// +#define WSA_QOS_RESERVED_PETYPE 11031L + +#endif // defined(WSABASEERR) + +/////////////////////////////////////////////////// +// // +// End of WinSock Error Codes // +// // +// 10000 to 11999 // +/////////////////////////////////////////////////// + + + +/////////////////////////////////////////////////// +// // +// Side By Side Error Codes // +// // +// 14000 to 14999 // +/////////////////////////////////////////////////// + +// +// MessageId: ERROR_SXS_SECTION_NOT_FOUND +// +// MessageText: +// +// The requested section was not present in the activation context. +// +#define ERROR_SXS_SECTION_NOT_FOUND 14000L + +// +// MessageId: ERROR_SXS_CANT_GEN_ACTCTX +// +// MessageText: +// +// This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem. +// +#define ERROR_SXS_CANT_GEN_ACTCTX 14001L + +// +// MessageId: ERROR_SXS_INVALID_ACTCTXDATA_FORMAT +// +// MessageText: +// +// The application binding data format is invalid. +// +#define ERROR_SXS_INVALID_ACTCTXDATA_FORMAT 14002L + +// +// MessageId: ERROR_SXS_ASSEMBLY_NOT_FOUND +// +// MessageText: +// +// The referenced assembly is not installed on your system. +// +#define ERROR_SXS_ASSEMBLY_NOT_FOUND 14003L + +// +// MessageId: ERROR_SXS_MANIFEST_FORMAT_ERROR +// +// MessageText: +// +// The manifest file does not begin with the required tag and format information. +// +#define ERROR_SXS_MANIFEST_FORMAT_ERROR 14004L + +// +// MessageId: ERROR_SXS_MANIFEST_PARSE_ERROR +// +// MessageText: +// +// The manifest file contains one or more syntax errors. +// +#define ERROR_SXS_MANIFEST_PARSE_ERROR 14005L + +// +// MessageId: ERROR_SXS_ACTIVATION_CONTEXT_DISABLED +// +// MessageText: +// +// The application attempted to activate a disabled activation context. +// +#define ERROR_SXS_ACTIVATION_CONTEXT_DISABLED 14006L + +// +// MessageId: ERROR_SXS_KEY_NOT_FOUND +// +// MessageText: +// +// The requested lookup key was not found in any active activation context. +// +#define ERROR_SXS_KEY_NOT_FOUND 14007L + +// +// MessageId: ERROR_SXS_VERSION_CONFLICT +// +// MessageText: +// +// A component version required by the application conflicts with another component version already active. +// +#define ERROR_SXS_VERSION_CONFLICT 14008L + +// +// MessageId: ERROR_SXS_WRONG_SECTION_TYPE +// +// MessageText: +// +// The type requested activation context section does not match the query API used. +// +#define ERROR_SXS_WRONG_SECTION_TYPE 14009L + +// +// MessageId: ERROR_SXS_THREAD_QUERIES_DISABLED +// +// MessageText: +// +// Lack of system resources has required isolated activation to be disabled for the current thread of execution. +// +#define ERROR_SXS_THREAD_QUERIES_DISABLED 14010L + +// +// MessageId: ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET +// +// MessageText: +// +// An attempt to set the process default activation context failed because the process default activation context was already set. +// +#define ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET 14011L + +// +// MessageId: ERROR_SXS_UNKNOWN_ENCODING_GROUP +// +// MessageText: +// +// The encoding group identifier specified is not recognized. +// +#define ERROR_SXS_UNKNOWN_ENCODING_GROUP 14012L + +// +// MessageId: ERROR_SXS_UNKNOWN_ENCODING +// +// MessageText: +// +// The encoding requested is not recognized. +// +#define ERROR_SXS_UNKNOWN_ENCODING 14013L + +// +// MessageId: ERROR_SXS_INVALID_XML_NAMESPACE_URI +// +// MessageText: +// +// The manifest contains a reference to an invalid URI. +// +#define ERROR_SXS_INVALID_XML_NAMESPACE_URI 14014L + +// +// MessageId: ERROR_SXS_ROOT_MANIFEST_DEPENDENCY_NOT_INSTALLED +// +// MessageText: +// +// The application manifest contains a reference to a dependent assembly which is not installed +// +#define ERROR_SXS_ROOT_MANIFEST_DEPENDENCY_NOT_INSTALLED 14015L + +// +// MessageId: ERROR_SXS_LEAF_MANIFEST_DEPENDENCY_NOT_INSTALLED +// +// MessageText: +// +// The manifest for an assembly used by the application has a reference to a dependent assembly which is not installed +// +#define ERROR_SXS_LEAF_MANIFEST_DEPENDENCY_NOT_INSTALLED 14016L + +// +// MessageId: ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE +// +// MessageText: +// +// The manifest contains an attribute for the assembly identity which is not valid. +// +#define ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE 14017L + +// +// MessageId: ERROR_SXS_MANIFEST_MISSING_REQUIRED_DEFAULT_NAMESPACE +// +// MessageText: +// +// The manifest is missing the required default namespace specification on the assembly element. +// +#define ERROR_SXS_MANIFEST_MISSING_REQUIRED_DEFAULT_NAMESPACE 14018L + +// +// MessageId: ERROR_SXS_MANIFEST_INVALID_REQUIRED_DEFAULT_NAMESPACE +// +// MessageText: +// +// The manifest has a default namespace specified on the assembly element but its value is not "urn:schemas-microsoft-com:asm.v1". +// +#define ERROR_SXS_MANIFEST_INVALID_REQUIRED_DEFAULT_NAMESPACE 14019L + +// +// MessageId: ERROR_SXS_PRIVATE_MANIFEST_CROSS_PATH_WITH_REPARSE_POINT +// +// MessageText: +// +// The private manifest probed has crossed reparse-point-associated path +// +#define ERROR_SXS_PRIVATE_MANIFEST_CROSS_PATH_WITH_REPARSE_POINT 14020L + +// +// MessageId: ERROR_SXS_DUPLICATE_DLL_NAME +// +// MessageText: +// +// Two or more components referenced directly or indirectly by the application manifest have files by the same name. +// +#define ERROR_SXS_DUPLICATE_DLL_NAME 14021L + +// +// MessageId: ERROR_SXS_DUPLICATE_WINDOWCLASS_NAME +// +// MessageText: +// +// Two or more components referenced directly or indirectly by the application manifest have window classes with the same name. +// +#define ERROR_SXS_DUPLICATE_WINDOWCLASS_NAME 14022L + +// +// MessageId: ERROR_SXS_DUPLICATE_CLSID +// +// MessageText: +// +// Two or more components referenced directly or indirectly by the application manifest have the same COM server CLSIDs. +// +#define ERROR_SXS_DUPLICATE_CLSID 14023L + +// +// MessageId: ERROR_SXS_DUPLICATE_IID +// +// MessageText: +// +// Two or more components referenced directly or indirectly by the application manifest have proxies for the same COM interface IIDs. +// +#define ERROR_SXS_DUPLICATE_IID 14024L + +// +// MessageId: ERROR_SXS_DUPLICATE_TLBID +// +// MessageText: +// +// Two or more components referenced directly or indirectly by the application manifest have the same COM type library TLBIDs. +// +#define ERROR_SXS_DUPLICATE_TLBID 14025L + +// +// MessageId: ERROR_SXS_DUPLICATE_PROGID +// +// MessageText: +// +// Two or more components referenced directly or indirectly by the application manifest have the same COM ProgIDs. +// +#define ERROR_SXS_DUPLICATE_PROGID 14026L + +// +// MessageId: ERROR_SXS_DUPLICATE_ASSEMBLY_NAME +// +// MessageText: +// +// Two or more components referenced directly or indirectly by the application manifest are different versions of the same component which is not permitted. +// +#define ERROR_SXS_DUPLICATE_ASSEMBLY_NAME 14027L + +// +// MessageId: ERROR_SXS_FILE_HASH_MISMATCH +// +// MessageText: +// +// A component's file does not match the verification information present in the +// component manifest. +// +#define ERROR_SXS_FILE_HASH_MISMATCH 14028L + +// +// MessageId: ERROR_SXS_POLICY_PARSE_ERROR +// +// MessageText: +// +// The policy manifest contains one or more syntax errors. +// +#define ERROR_SXS_POLICY_PARSE_ERROR 14029L + +// +// MessageId: ERROR_SXS_XML_E_MISSINGQUOTE +// +// MessageText: +// +// Manifest Parse Error : A string literal was expected, but no opening quote character was found. +// +#define ERROR_SXS_XML_E_MISSINGQUOTE 14030L + +// +// MessageId: ERROR_SXS_XML_E_COMMENTSYNTAX +// +// MessageText: +// +// Manifest Parse Error : Incorrect syntax was used in a comment. +// +#define ERROR_SXS_XML_E_COMMENTSYNTAX 14031L + +// +// MessageId: ERROR_SXS_XML_E_BADSTARTNAMECHAR +// +// MessageText: +// +// Manifest Parse Error : A name was started with an invalid character. +// +#define ERROR_SXS_XML_E_BADSTARTNAMECHAR 14032L + +// +// MessageId: ERROR_SXS_XML_E_BADNAMECHAR +// +// MessageText: +// +// Manifest Parse Error : A name contained an invalid character. +// +#define ERROR_SXS_XML_E_BADNAMECHAR 14033L + +// +// MessageId: ERROR_SXS_XML_E_BADCHARINSTRING +// +// MessageText: +// +// Manifest Parse Error : A string literal contained an invalid character. +// +#define ERROR_SXS_XML_E_BADCHARINSTRING 14034L + +// +// MessageId: ERROR_SXS_XML_E_XMLDECLSYNTAX +// +// MessageText: +// +// Manifest Parse Error : Invalid syntax for an xml declaration. +// +#define ERROR_SXS_XML_E_XMLDECLSYNTAX 14035L + +// +// MessageId: ERROR_SXS_XML_E_BADCHARDATA +// +// MessageText: +// +// Manifest Parse Error : An Invalid character was found in text content. +// +#define ERROR_SXS_XML_E_BADCHARDATA 14036L + +// +// MessageId: ERROR_SXS_XML_E_MISSINGWHITESPACE +// +// MessageText: +// +// Manifest Parse Error : Required white space was missing. +// +#define ERROR_SXS_XML_E_MISSINGWHITESPACE 14037L + +// +// MessageId: ERROR_SXS_XML_E_EXPECTINGTAGEND +// +// MessageText: +// +// Manifest Parse Error : The character '>' was expected. +// +#define ERROR_SXS_XML_E_EXPECTINGTAGEND 14038L + +// +// MessageId: ERROR_SXS_XML_E_MISSINGSEMICOLON +// +// MessageText: +// +// Manifest Parse Error : A semi colon character was expected. +// +#define ERROR_SXS_XML_E_MISSINGSEMICOLON 14039L + +// +// MessageId: ERROR_SXS_XML_E_UNBALANCEDPAREN +// +// MessageText: +// +// Manifest Parse Error : Unbalanced parentheses. +// +#define ERROR_SXS_XML_E_UNBALANCEDPAREN 14040L + +// +// MessageId: ERROR_SXS_XML_E_INTERNALERROR +// +// MessageText: +// +// Manifest Parse Error : Internal error. +// +#define ERROR_SXS_XML_E_INTERNALERROR 14041L + +// +// MessageId: ERROR_SXS_XML_E_UNEXPECTED_WHITESPACE +// +// MessageText: +// +// Manifest Parse Error : Whitespace is not allowed at this location. +// +#define ERROR_SXS_XML_E_UNEXPECTED_WHITESPACE 14042L + +// +// MessageId: ERROR_SXS_XML_E_INCOMPLETE_ENCODING +// +// MessageText: +// +// Manifest Parse Error : End of file reached in invalid state for current encoding. +// +#define ERROR_SXS_XML_E_INCOMPLETE_ENCODING 14043L + +// +// MessageId: ERROR_SXS_XML_E_MISSING_PAREN +// +// MessageText: +// +// Manifest Parse Error : Missing parenthesis. +// +#define ERROR_SXS_XML_E_MISSING_PAREN 14044L + +// +// MessageId: ERROR_SXS_XML_E_EXPECTINGCLOSEQUOTE +// +// MessageText: +// +// Manifest Parse Error : A single or double closing quote character (\' or \") is missing. +// +#define ERROR_SXS_XML_E_EXPECTINGCLOSEQUOTE 14045L + +// +// MessageId: ERROR_SXS_XML_E_MULTIPLE_COLONS +// +// MessageText: +// +// Manifest Parse Error : Multiple colons are not allowed in a name. +// +#define ERROR_SXS_XML_E_MULTIPLE_COLONS 14046L + +// +// MessageId: ERROR_SXS_XML_E_INVALID_DECIMAL +// +// MessageText: +// +// Manifest Parse Error : Invalid character for decimal digit. +// +#define ERROR_SXS_XML_E_INVALID_DECIMAL 14047L + +// +// MessageId: ERROR_SXS_XML_E_INVALID_HEXIDECIMAL +// +// MessageText: +// +// Manifest Parse Error : Invalid character for hexidecimal digit. +// +#define ERROR_SXS_XML_E_INVALID_HEXIDECIMAL 14048L + +// +// MessageId: ERROR_SXS_XML_E_INVALID_UNICODE +// +// MessageText: +// +// Manifest Parse Error : Invalid unicode character value for this platform. +// +#define ERROR_SXS_XML_E_INVALID_UNICODE 14049L + +// +// MessageId: ERROR_SXS_XML_E_WHITESPACEORQUESTIONMARK +// +// MessageText: +// +// Manifest Parse Error : Expecting whitespace or '?'. +// +#define ERROR_SXS_XML_E_WHITESPACEORQUESTIONMARK 14050L + +// +// MessageId: ERROR_SXS_XML_E_UNEXPECTEDENDTAG +// +// MessageText: +// +// Manifest Parse Error : End tag was not expected at this location. +// +#define ERROR_SXS_XML_E_UNEXPECTEDENDTAG 14051L + +// +// MessageId: ERROR_SXS_XML_E_UNCLOSEDTAG +// +// MessageText: +// +// Manifest Parse Error : The following tags were not closed: %1. +// +#define ERROR_SXS_XML_E_UNCLOSEDTAG 14052L + +// +// MessageId: ERROR_SXS_XML_E_DUPLICATEATTRIBUTE +// +// MessageText: +// +// Manifest Parse Error : Duplicate attribute. +// +#define ERROR_SXS_XML_E_DUPLICATEATTRIBUTE 14053L + +// +// MessageId: ERROR_SXS_XML_E_MULTIPLEROOTS +// +// MessageText: +// +// Manifest Parse Error : Only one top level element is allowed in an XML document. +// +#define ERROR_SXS_XML_E_MULTIPLEROOTS 14054L + +// +// MessageId: ERROR_SXS_XML_E_INVALIDATROOTLEVEL +// +// MessageText: +// +// Manifest Parse Error : Invalid at the top level of the document. +// +#define ERROR_SXS_XML_E_INVALIDATROOTLEVEL 14055L + +// +// MessageId: ERROR_SXS_XML_E_BADXMLDECL +// +// MessageText: +// +// Manifest Parse Error : Invalid xml declaration. +// +#define ERROR_SXS_XML_E_BADXMLDECL 14056L + +// +// MessageId: ERROR_SXS_XML_E_MISSINGROOT +// +// MessageText: +// +// Manifest Parse Error : XML document must have a top level element. +// +#define ERROR_SXS_XML_E_MISSINGROOT 14057L + +// +// MessageId: ERROR_SXS_XML_E_UNEXPECTEDEOF +// +// MessageText: +// +// Manifest Parse Error : Unexpected end of file. +// +#define ERROR_SXS_XML_E_UNEXPECTEDEOF 14058L + +// +// MessageId: ERROR_SXS_XML_E_BADPEREFINSUBSET +// +// MessageText: +// +// Manifest Parse Error : Parameter entities cannot be used inside markup declarations in an internal subset. +// +#define ERROR_SXS_XML_E_BADPEREFINSUBSET 14059L + +// +// MessageId: ERROR_SXS_XML_E_UNCLOSEDSTARTTAG +// +// MessageText: +// +// Manifest Parse Error : Element was not closed. +// +#define ERROR_SXS_XML_E_UNCLOSEDSTARTTAG 14060L + +// +// MessageId: ERROR_SXS_XML_E_UNCLOSEDENDTAG +// +// MessageText: +// +// Manifest Parse Error : End element was missing the character '>'. +// +#define ERROR_SXS_XML_E_UNCLOSEDENDTAG 14061L + +// +// MessageId: ERROR_SXS_XML_E_UNCLOSEDSTRING +// +// MessageText: +// +// Manifest Parse Error : A string literal was not closed. +// +#define ERROR_SXS_XML_E_UNCLOSEDSTRING 14062L + +// +// MessageId: ERROR_SXS_XML_E_UNCLOSEDCOMMENT +// +// MessageText: +// +// Manifest Parse Error : A comment was not closed. +// +#define ERROR_SXS_XML_E_UNCLOSEDCOMMENT 14063L + +// +// MessageId: ERROR_SXS_XML_E_UNCLOSEDDECL +// +// MessageText: +// +// Manifest Parse Error : A declaration was not closed. +// +#define ERROR_SXS_XML_E_UNCLOSEDDECL 14064L + +// +// MessageId: ERROR_SXS_XML_E_UNCLOSEDCDATA +// +// MessageText: +// +// Manifest Parse Error : A CDATA section was not closed. +// +#define ERROR_SXS_XML_E_UNCLOSEDCDATA 14065L + +// +// MessageId: ERROR_SXS_XML_E_RESERVEDNAMESPACE +// +// MessageText: +// +// Manifest Parse Error : The namespace prefix is not allowed to start with the reserved string "xml". +// +#define ERROR_SXS_XML_E_RESERVEDNAMESPACE 14066L + +// +// MessageId: ERROR_SXS_XML_E_INVALIDENCODING +// +// MessageText: +// +// Manifest Parse Error : System does not support the specified encoding. +// +#define ERROR_SXS_XML_E_INVALIDENCODING 14067L + +// +// MessageId: ERROR_SXS_XML_E_INVALIDSWITCH +// +// MessageText: +// +// Manifest Parse Error : Switch from current encoding to specified encoding not supported. +// +#define ERROR_SXS_XML_E_INVALIDSWITCH 14068L + +// +// MessageId: ERROR_SXS_XML_E_BADXMLCASE +// +// MessageText: +// +// Manifest Parse Error : The name 'xml' is reserved and must be lower case. +// +#define ERROR_SXS_XML_E_BADXMLCASE 14069L + +// +// MessageId: ERROR_SXS_XML_E_INVALID_STANDALONE +// +// MessageText: +// +// Manifest Parse Error : The standalone attribute must have the value 'yes' or 'no'. +// +#define ERROR_SXS_XML_E_INVALID_STANDALONE 14070L + +// +// MessageId: ERROR_SXS_XML_E_UNEXPECTED_STANDALONE +// +// MessageText: +// +// Manifest Parse Error : The standalone attribute cannot be used in external entities. +// +#define ERROR_SXS_XML_E_UNEXPECTED_STANDALONE 14071L + +// +// MessageId: ERROR_SXS_XML_E_INVALID_VERSION +// +// MessageText: +// +// Manifest Parse Error : Invalid version number. +// +#define ERROR_SXS_XML_E_INVALID_VERSION 14072L + +// +// MessageId: ERROR_SXS_XML_E_MISSINGEQUALS +// +// MessageText: +// +// Manifest Parse Error : Missing equals sign between attribute and attribute value. +// +#define ERROR_SXS_XML_E_MISSINGEQUALS 14073L + +// +// MessageId: ERROR_SXS_PROTECTION_RECOVERY_FAILED +// +// MessageText: +// +// Assembly Protection Error : Unable to recover the specified assembly. +// +#define ERROR_SXS_PROTECTION_RECOVERY_FAILED 14074L + +// +// MessageId: ERROR_SXS_PROTECTION_PUBLIC_KEY_TOO_SHORT +// +// MessageText: +// +// Assembly Protection Error : The public key for an assembly was too short to be allowed. +// +#define ERROR_SXS_PROTECTION_PUBLIC_KEY_TOO_SHORT 14075L + +// +// MessageId: ERROR_SXS_PROTECTION_CATALOG_NOT_VALID +// +// MessageText: +// +// Assembly Protection Error : The catalog for an assembly is not valid, or does not match the assembly's manifest. +// +#define ERROR_SXS_PROTECTION_CATALOG_NOT_VALID 14076L + +// +// MessageId: ERROR_SXS_UNTRANSLATABLE_HRESULT +// +// MessageText: +// +// An HRESULT could not be translated to a corresponding Win32 error code. +// +#define ERROR_SXS_UNTRANSLATABLE_HRESULT 14077L + +// +// MessageId: ERROR_SXS_PROTECTION_CATALOG_FILE_MISSING +// +// MessageText: +// +// Assembly Protection Error : The catalog for an assembly is missing. +// +#define ERROR_SXS_PROTECTION_CATALOG_FILE_MISSING 14078L + +// +// MessageId: ERROR_SXS_MISSING_ASSEMBLY_IDENTITY_ATTRIBUTE +// +// MessageText: +// +// The supplied assembly identity is missing one or more attributes which must be present in this context. +// +#define ERROR_SXS_MISSING_ASSEMBLY_IDENTITY_ATTRIBUTE 14079L + +// +// MessageId: ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE_NAME +// +// MessageText: +// +// The supplied assembly identity has one or more attribute names that contain characters not permitted in XML names. +// +#define ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE_NAME 14080L + + +/////////////////////////////////////////////////// +// // +// End of Side By Side Error Codes // +// // +// 14000 to 14999 // +/////////////////////////////////////////////////// + + + +/////////////////////////////////////////////////// +// // +// Start of IPSec Error codes // +// // +// 13000 to 13999 // +/////////////////////////////////////////////////// + + +// +// MessageId: ERROR_IPSEC_QM_POLICY_EXISTS +// +// MessageText: +// +// The specified quick mode policy already exists. +// +#define ERROR_IPSEC_QM_POLICY_EXISTS 13000L + +// +// MessageId: ERROR_IPSEC_QM_POLICY_NOT_FOUND +// +// MessageText: +// +// The specified quick mode policy was not found. +// +#define ERROR_IPSEC_QM_POLICY_NOT_FOUND 13001L + +// +// MessageId: ERROR_IPSEC_QM_POLICY_IN_USE +// +// MessageText: +// +// The specified quick mode policy is being used. +// +#define ERROR_IPSEC_QM_POLICY_IN_USE 13002L + +// +// MessageId: ERROR_IPSEC_MM_POLICY_EXISTS +// +// MessageText: +// +// The specified main mode policy already exists. +// +#define ERROR_IPSEC_MM_POLICY_EXISTS 13003L + +// +// MessageId: ERROR_IPSEC_MM_POLICY_NOT_FOUND +// +// MessageText: +// +// The specified main mode policy was not found +// +#define ERROR_IPSEC_MM_POLICY_NOT_FOUND 13004L + +// +// MessageId: ERROR_IPSEC_MM_POLICY_IN_USE +// +// MessageText: +// +// The specified main mode policy is being used. +// +#define ERROR_IPSEC_MM_POLICY_IN_USE 13005L + +// +// MessageId: ERROR_IPSEC_MM_FILTER_EXISTS +// +// MessageText: +// +// The specified main mode filter already exists. +// +#define ERROR_IPSEC_MM_FILTER_EXISTS 13006L + +// +// MessageId: ERROR_IPSEC_MM_FILTER_NOT_FOUND +// +// MessageText: +// +// The specified main mode filter was not found. +// +#define ERROR_IPSEC_MM_FILTER_NOT_FOUND 13007L + +// +// MessageId: ERROR_IPSEC_TRANSPORT_FILTER_EXISTS +// +// MessageText: +// +// The specified transport mode filter already exists. +// +#define ERROR_IPSEC_TRANSPORT_FILTER_EXISTS 13008L + +// +// MessageId: ERROR_IPSEC_TRANSPORT_FILTER_NOT_FOUND +// +// MessageText: +// +// The specified transport mode filter does not exist. +// +#define ERROR_IPSEC_TRANSPORT_FILTER_NOT_FOUND 13009L + +// +// MessageId: ERROR_IPSEC_MM_AUTH_EXISTS +// +// MessageText: +// +// The specified main mode authentication list exists. +// +#define ERROR_IPSEC_MM_AUTH_EXISTS 13010L + +// +// MessageId: ERROR_IPSEC_MM_AUTH_NOT_FOUND +// +// MessageText: +// +// The specified main mode authentication list was not found. +// +#define ERROR_IPSEC_MM_AUTH_NOT_FOUND 13011L + +// +// MessageId: ERROR_IPSEC_MM_AUTH_IN_USE +// +// MessageText: +// +// The specified quick mode policy is being used. +// +#define ERROR_IPSEC_MM_AUTH_IN_USE 13012L + +// +// MessageId: ERROR_IPSEC_DEFAULT_MM_POLICY_NOT_FOUND +// +// MessageText: +// +// The specified main mode policy was not found. +// +#define ERROR_IPSEC_DEFAULT_MM_POLICY_NOT_FOUND 13013L + +// +// MessageId: ERROR_IPSEC_DEFAULT_MM_AUTH_NOT_FOUND +// +// MessageText: +// +// The specified quick mode policy was not found +// +#define ERROR_IPSEC_DEFAULT_MM_AUTH_NOT_FOUND 13014L + +// +// MessageId: ERROR_IPSEC_DEFAULT_QM_POLICY_NOT_FOUND +// +// MessageText: +// +// The manifest file contains one or more syntax errors. +// +#define ERROR_IPSEC_DEFAULT_QM_POLICY_NOT_FOUND 13015L + +// +// MessageId: ERROR_IPSEC_TUNNEL_FILTER_EXISTS +// +// MessageText: +// +// The application attempted to activate a disabled activation context. +// +#define ERROR_IPSEC_TUNNEL_FILTER_EXISTS 13016L + +// +// MessageId: ERROR_IPSEC_TUNNEL_FILTER_NOT_FOUND +// +// MessageText: +// +// The requested lookup key was not found in any active activation context. +// +#define ERROR_IPSEC_TUNNEL_FILTER_NOT_FOUND 13017L + +// +// MessageId: ERROR_IPSEC_MM_FILTER_PENDING_DELETION +// +// MessageText: +// +// The Main Mode filter is pending deletion. +// +#define ERROR_IPSEC_MM_FILTER_PENDING_DELETION 13018L + +// +// MessageId: ERROR_IPSEC_TRANSPORT_FILTER_PENDING_DELETION +// +// MessageText: +// +// The transport filter is pending deletion. +// +#define ERROR_IPSEC_TRANSPORT_FILTER_PENDING_DELETION 13019L + +// +// MessageId: ERROR_IPSEC_TUNNEL_FILTER_PENDING_DELETION +// +// MessageText: +// +// The tunnel filter is pending deletion. +// +#define ERROR_IPSEC_TUNNEL_FILTER_PENDING_DELETION 13020L + +// +// MessageId: ERROR_IPSEC_MM_POLICY_PENDING_DELETION +// +// MessageText: +// +// The Main Mode policy is pending deletion. +// +#define ERROR_IPSEC_MM_POLICY_PENDING_DELETION 13021L + +// +// MessageId: ERROR_IPSEC_MM_AUTH_PENDING_DELETION +// +// MessageText: +// +// The Main Mode authentication bundle is pending deletion. +// +#define ERROR_IPSEC_MM_AUTH_PENDING_DELETION 13022L + +// +// MessageId: ERROR_IPSEC_QM_POLICY_PENDING_DELETION +// +// MessageText: +// +// The Quick Mode policy is pending deletion. +// +#define ERROR_IPSEC_QM_POLICY_PENDING_DELETION 13023L + +// +// MessageId: WARNING_IPSEC_MM_POLICY_PRUNED +// +// MessageText: +// +// The Main Mode policy was successfully added, but some of the requested offers are not supported. +// +#define WARNING_IPSEC_MM_POLICY_PRUNED 13024L + +// +// MessageId: WARNING_IPSEC_QM_POLICY_PRUNED +// +// MessageText: +// +// The Quick Mode policy was successfully added, but some of the requested offers are not supported. +// +#define WARNING_IPSEC_QM_POLICY_PRUNED 13025L + +// +// MessageId: ERROR_IPSEC_IKE_NEG_STATUS_BEGIN +// +// MessageText: +// +// ERROR_IPSEC_IKE_NEG_STATUS_BEGIN +// +#define ERROR_IPSEC_IKE_NEG_STATUS_BEGIN 13800L + +// +// MessageId: ERROR_IPSEC_IKE_AUTH_FAIL +// +// MessageText: +// +// IKE authentication credentials are unacceptable +// +#define ERROR_IPSEC_IKE_AUTH_FAIL 13801L + +// +// MessageId: ERROR_IPSEC_IKE_ATTRIB_FAIL +// +// MessageText: +// +// IKE security attributes are unacceptable +// +#define ERROR_IPSEC_IKE_ATTRIB_FAIL 13802L + +// +// MessageId: ERROR_IPSEC_IKE_NEGOTIATION_PENDING +// +// MessageText: +// +// IKE Negotiation in progress +// +#define ERROR_IPSEC_IKE_NEGOTIATION_PENDING 13803L + +// +// MessageId: ERROR_IPSEC_IKE_GENERAL_PROCESSING_ERROR +// +// MessageText: +// +// General processing error +// +#define ERROR_IPSEC_IKE_GENERAL_PROCESSING_ERROR 13804L + +// +// MessageId: ERROR_IPSEC_IKE_TIMED_OUT +// +// MessageText: +// +// Negotiation timed out +// +#define ERROR_IPSEC_IKE_TIMED_OUT 13805L + +// +// MessageId: ERROR_IPSEC_IKE_NO_CERT +// +// MessageText: +// +// IKE failed to find valid machine certificate +// +#define ERROR_IPSEC_IKE_NO_CERT 13806L + +// +// MessageId: ERROR_IPSEC_IKE_SA_DELETED +// +// MessageText: +// +// IKE SA deleted by peer before establishment completed +// +#define ERROR_IPSEC_IKE_SA_DELETED 13807L + +// +// MessageId: ERROR_IPSEC_IKE_SA_REAPED +// +// MessageText: +// +// IKE SA deleted before establishment completed +// +#define ERROR_IPSEC_IKE_SA_REAPED 13808L + +// +// MessageId: ERROR_IPSEC_IKE_MM_ACQUIRE_DROP +// +// MessageText: +// +// Negotiation request sat in Queue too long +// +#define ERROR_IPSEC_IKE_MM_ACQUIRE_DROP 13809L + +// +// MessageId: ERROR_IPSEC_IKE_QM_ACQUIRE_DROP +// +// MessageText: +// +// Negotiation request sat in Queue too long +// +#define ERROR_IPSEC_IKE_QM_ACQUIRE_DROP 13810L + +// +// MessageId: ERROR_IPSEC_IKE_QUEUE_DROP_MM +// +// MessageText: +// +// Negotiation request sat in Queue too long +// +#define ERROR_IPSEC_IKE_QUEUE_DROP_MM 13811L + +// +// MessageId: ERROR_IPSEC_IKE_QUEUE_DROP_NO_MM +// +// MessageText: +// +// Negotiation request sat in Queue too long +// +#define ERROR_IPSEC_IKE_QUEUE_DROP_NO_MM 13812L + +// +// MessageId: ERROR_IPSEC_IKE_DROP_NO_RESPONSE +// +// MessageText: +// +// No response from peer +// +#define ERROR_IPSEC_IKE_DROP_NO_RESPONSE 13813L + +// +// MessageId: ERROR_IPSEC_IKE_MM_DELAY_DROP +// +// MessageText: +// +// Negotiation took too long +// +#define ERROR_IPSEC_IKE_MM_DELAY_DROP 13814L + +// +// MessageId: ERROR_IPSEC_IKE_QM_DELAY_DROP +// +// MessageText: +// +// Negotiation took too long +// +#define ERROR_IPSEC_IKE_QM_DELAY_DROP 13815L + +// +// MessageId: ERROR_IPSEC_IKE_ERROR +// +// MessageText: +// +// Unknown error occurred +// +#define ERROR_IPSEC_IKE_ERROR 13816L + +// +// MessageId: ERROR_IPSEC_IKE_CRL_FAILED +// +// MessageText: +// +// Certificate Revocation Check failed +// +#define ERROR_IPSEC_IKE_CRL_FAILED 13817L + +// +// MessageId: ERROR_IPSEC_IKE_INVALID_KEY_USAGE +// +// MessageText: +// +// Invalid certificate key usage +// +#define ERROR_IPSEC_IKE_INVALID_KEY_USAGE 13818L + +// +// MessageId: ERROR_IPSEC_IKE_INVALID_CERT_TYPE +// +// MessageText: +// +// Invalid certificate type +// +#define ERROR_IPSEC_IKE_INVALID_CERT_TYPE 13819L + +// +// MessageId: ERROR_IPSEC_IKE_NO_PRIVATE_KEY +// +// MessageText: +// +// No private key associated with machine certificate +// +#define ERROR_IPSEC_IKE_NO_PRIVATE_KEY 13820L + +// +// MessageId: ERROR_IPSEC_IKE_DH_FAIL +// +// MessageText: +// +// Failure in Diffie-Helman computation +// +#define ERROR_IPSEC_IKE_DH_FAIL 13822L + +// +// MessageId: ERROR_IPSEC_IKE_INVALID_HEADER +// +// MessageText: +// +// Invalid header +// +#define ERROR_IPSEC_IKE_INVALID_HEADER 13824L + +// +// MessageId: ERROR_IPSEC_IKE_NO_POLICY +// +// MessageText: +// +// No policy configured +// +#define ERROR_IPSEC_IKE_NO_POLICY 13825L + +// +// MessageId: ERROR_IPSEC_IKE_INVALID_SIGNATURE +// +// MessageText: +// +// Failed to verify signature +// +#define ERROR_IPSEC_IKE_INVALID_SIGNATURE 13826L + +// +// MessageId: ERROR_IPSEC_IKE_KERBEROS_ERROR +// +// MessageText: +// +// Failed to authenticate using kerberos +// +#define ERROR_IPSEC_IKE_KERBEROS_ERROR 13827L + +// +// MessageId: ERROR_IPSEC_IKE_NO_PUBLIC_KEY +// +// MessageText: +// +// Peer's certificate did not have a public key +// +#define ERROR_IPSEC_IKE_NO_PUBLIC_KEY 13828L + +// These must stay as a unit. +// +// MessageId: ERROR_IPSEC_IKE_PROCESS_ERR +// +// MessageText: +// +// Error processing error payload +// +#define ERROR_IPSEC_IKE_PROCESS_ERR 13829L + +// +// MessageId: ERROR_IPSEC_IKE_PROCESS_ERR_SA +// +// MessageText: +// +// Error processing SA payload +// +#define ERROR_IPSEC_IKE_PROCESS_ERR_SA 13830L + +// +// MessageId: ERROR_IPSEC_IKE_PROCESS_ERR_PROP +// +// MessageText: +// +// Error processing Proposal payload +// +#define ERROR_IPSEC_IKE_PROCESS_ERR_PROP 13831L + +// +// MessageId: ERROR_IPSEC_IKE_PROCESS_ERR_TRANS +// +// MessageText: +// +// Error processing Transform payload +// +#define ERROR_IPSEC_IKE_PROCESS_ERR_TRANS 13832L + +// +// MessageId: ERROR_IPSEC_IKE_PROCESS_ERR_KE +// +// MessageText: +// +// Error processing KE payload +// +#define ERROR_IPSEC_IKE_PROCESS_ERR_KE 13833L + +// +// MessageId: ERROR_IPSEC_IKE_PROCESS_ERR_ID +// +// MessageText: +// +// Error processing ID payload +// +#define ERROR_IPSEC_IKE_PROCESS_ERR_ID 13834L + +// +// MessageId: ERROR_IPSEC_IKE_PROCESS_ERR_CERT +// +// MessageText: +// +// Error processing Cert payload +// +#define ERROR_IPSEC_IKE_PROCESS_ERR_CERT 13835L + +// +// MessageId: ERROR_IPSEC_IKE_PROCESS_ERR_CERT_REQ +// +// MessageText: +// +// Error processing Certificate Request payload +// +#define ERROR_IPSEC_IKE_PROCESS_ERR_CERT_REQ 13836L + +// +// MessageId: ERROR_IPSEC_IKE_PROCESS_ERR_HASH +// +// MessageText: +// +// Error processing Hash payload +// +#define ERROR_IPSEC_IKE_PROCESS_ERR_HASH 13837L + +// +// MessageId: ERROR_IPSEC_IKE_PROCESS_ERR_SIG +// +// MessageText: +// +// Error processing Signature payload +// +#define ERROR_IPSEC_IKE_PROCESS_ERR_SIG 13838L + +// +// MessageId: ERROR_IPSEC_IKE_PROCESS_ERR_NONCE +// +// MessageText: +// +// Error processing Nonce payload +// +#define ERROR_IPSEC_IKE_PROCESS_ERR_NONCE 13839L + +// +// MessageId: ERROR_IPSEC_IKE_PROCESS_ERR_NOTIFY +// +// MessageText: +// +// Error processing Notify payload +// +#define ERROR_IPSEC_IKE_PROCESS_ERR_NOTIFY 13840L + +// +// MessageId: ERROR_IPSEC_IKE_PROCESS_ERR_DELETE +// +// MessageText: +// +// Error processing Delete Payload +// +#define ERROR_IPSEC_IKE_PROCESS_ERR_DELETE 13841L + +// +// MessageId: ERROR_IPSEC_IKE_PROCESS_ERR_VENDOR +// +// MessageText: +// +// Error processing VendorId payload +// +#define ERROR_IPSEC_IKE_PROCESS_ERR_VENDOR 13842L + +// +// MessageId: ERROR_IPSEC_IKE_INVALID_PAYLOAD +// +// MessageText: +// +// Invalid payload received +// +#define ERROR_IPSEC_IKE_INVALID_PAYLOAD 13843L + +// +// MessageId: ERROR_IPSEC_IKE_LOAD_SOFT_SA +// +// MessageText: +// +// Soft SA loaded +// +#define ERROR_IPSEC_IKE_LOAD_SOFT_SA 13844L + +// +// MessageId: ERROR_IPSEC_IKE_SOFT_SA_TORN_DOWN +// +// MessageText: +// +// Soft SA torn down +// +#define ERROR_IPSEC_IKE_SOFT_SA_TORN_DOWN 13845L + +// +// MessageId: ERROR_IPSEC_IKE_INVALID_COOKIE +// +// MessageText: +// +// Invalid cookie received. +// +#define ERROR_IPSEC_IKE_INVALID_COOKIE 13846L + +// +// MessageId: ERROR_IPSEC_IKE_NO_PEER_CERT +// +// MessageText: +// +// Peer failed to send valid machine certificate +// +#define ERROR_IPSEC_IKE_NO_PEER_CERT 13847L + +// +// MessageId: ERROR_IPSEC_IKE_PEER_CRL_FAILED +// +// MessageText: +// +// Certification Revocation check of peer's certificate failed +// +#define ERROR_IPSEC_IKE_PEER_CRL_FAILED 13848L + +// +// MessageId: ERROR_IPSEC_IKE_POLICY_CHANGE +// +// MessageText: +// +// New policy invalidated SAs formed with old policy +// +#define ERROR_IPSEC_IKE_POLICY_CHANGE 13849L + +// +// MessageId: ERROR_IPSEC_IKE_NO_MM_POLICY +// +// MessageText: +// +// There is no available Main Mode IKE policy. +// +#define ERROR_IPSEC_IKE_NO_MM_POLICY 13850L + +// +// MessageId: ERROR_IPSEC_IKE_NOTCBPRIV +// +// MessageText: +// +// Failed to enabled TCB privilege. +// +#define ERROR_IPSEC_IKE_NOTCBPRIV 13851L + +// +// MessageId: ERROR_IPSEC_IKE_SECLOADFAIL +// +// MessageText: +// +// Failed to load SECURITY.DLL. +// +#define ERROR_IPSEC_IKE_SECLOADFAIL 13852L + +// +// MessageId: ERROR_IPSEC_IKE_FAILSSPINIT +// +// MessageText: +// +// Failed to obtain security function table dispatch address from SSPI. +// +#define ERROR_IPSEC_IKE_FAILSSPINIT 13853L + +// +// MessageId: ERROR_IPSEC_IKE_FAILQUERYSSP +// +// MessageText: +// +// Failed to query Kerberos package to obtain max token size. +// +#define ERROR_IPSEC_IKE_FAILQUERYSSP 13854L + +// +// MessageId: ERROR_IPSEC_IKE_SRVACQFAIL +// +// MessageText: +// +// Failed to obtain Kerberos server credentials for ISAKMP/ERROR_IPSEC_IKE service. Kerberos authentication will not function. The most likely reason for this is lack of domain membership. This is normal if your computer is a member of a workgroup. +// +#define ERROR_IPSEC_IKE_SRVACQFAIL 13855L + +// +// MessageId: ERROR_IPSEC_IKE_SRVQUERYCRED +// +// MessageText: +// +// Failed to determine SSPI principal name for ISAKMP/ERROR_IPSEC_IKE service (QueryCredentialsAttributes). +// +#define ERROR_IPSEC_IKE_SRVQUERYCRED 13856L + +// +// MessageId: ERROR_IPSEC_IKE_GETSPIFAIL +// +// MessageText: +// +// Failed to obtain new SPI for the inbound SA from Ipsec driver. The most common cause for this is that the driver does not have the correct filter. Check your policy to verify the filters. +// +#define ERROR_IPSEC_IKE_GETSPIFAIL 13857L + +// +// MessageId: ERROR_IPSEC_IKE_INVALID_FILTER +// +// MessageText: +// +// Given filter is invalid +// +#define ERROR_IPSEC_IKE_INVALID_FILTER 13858L + +// +// MessageId: ERROR_IPSEC_IKE_OUT_OF_MEMORY +// +// MessageText: +// +// Memory allocation failed. +// +#define ERROR_IPSEC_IKE_OUT_OF_MEMORY 13859L + +// +// MessageId: ERROR_IPSEC_IKE_ADD_UPDATE_KEY_FAILED +// +// MessageText: +// +// Failed to add Security Association to IPSec Driver. The most common cause for this is if the IKE negotiation took too long to complete. If the problem persists, reduce the load on the faulting machine. +// +#define ERROR_IPSEC_IKE_ADD_UPDATE_KEY_FAILED 13860L + +// +// MessageId: ERROR_IPSEC_IKE_INVALID_POLICY +// +// MessageText: +// +// Invalid policy +// +#define ERROR_IPSEC_IKE_INVALID_POLICY 13861L + +// +// MessageId: ERROR_IPSEC_IKE_UNKNOWN_DOI +// +// MessageText: +// +// Invalid DOI +// +#define ERROR_IPSEC_IKE_UNKNOWN_DOI 13862L + +// +// MessageId: ERROR_IPSEC_IKE_INVALID_SITUATION +// +// MessageText: +// +// Invalid situation +// +#define ERROR_IPSEC_IKE_INVALID_SITUATION 13863L + +// +// MessageId: ERROR_IPSEC_IKE_DH_FAILURE +// +// MessageText: +// +// Diffie-Hellman failure +// +#define ERROR_IPSEC_IKE_DH_FAILURE 13864L + +// +// MessageId: ERROR_IPSEC_IKE_INVALID_GROUP +// +// MessageText: +// +// Invalid Diffie-Hellman group +// +#define ERROR_IPSEC_IKE_INVALID_GROUP 13865L + +// +// MessageId: ERROR_IPSEC_IKE_ENCRYPT +// +// MessageText: +// +// Error encrypting payload +// +#define ERROR_IPSEC_IKE_ENCRYPT 13866L + +// +// MessageId: ERROR_IPSEC_IKE_DECRYPT +// +// MessageText: +// +// Error decrypting payload +// +#define ERROR_IPSEC_IKE_DECRYPT 13867L + +// +// MessageId: ERROR_IPSEC_IKE_POLICY_MATCH +// +// MessageText: +// +// Policy match error +// +#define ERROR_IPSEC_IKE_POLICY_MATCH 13868L + +// +// MessageId: ERROR_IPSEC_IKE_UNSUPPORTED_ID +// +// MessageText: +// +// Unsupported ID +// +#define ERROR_IPSEC_IKE_UNSUPPORTED_ID 13869L + +// +// MessageId: ERROR_IPSEC_IKE_INVALID_HASH +// +// MessageText: +// +// Hash verification failed +// +#define ERROR_IPSEC_IKE_INVALID_HASH 13870L + +// +// MessageId: ERROR_IPSEC_IKE_INVALID_HASH_ALG +// +// MessageText: +// +// Invalid hash algorithm +// +#define ERROR_IPSEC_IKE_INVALID_HASH_ALG 13871L + +// +// MessageId: ERROR_IPSEC_IKE_INVALID_HASH_SIZE +// +// MessageText: +// +// Invalid hash size +// +#define ERROR_IPSEC_IKE_INVALID_HASH_SIZE 13872L + +// +// MessageId: ERROR_IPSEC_IKE_INVALID_ENCRYPT_ALG +// +// MessageText: +// +// Invalid encryption algorithm +// +#define ERROR_IPSEC_IKE_INVALID_ENCRYPT_ALG 13873L + +// +// MessageId: ERROR_IPSEC_IKE_INVALID_AUTH_ALG +// +// MessageText: +// +// Invalid authentication algorithm +// +#define ERROR_IPSEC_IKE_INVALID_AUTH_ALG 13874L + +// +// MessageId: ERROR_IPSEC_IKE_INVALID_SIG +// +// MessageText: +// +// Invalid certificate signature +// +#define ERROR_IPSEC_IKE_INVALID_SIG 13875L + +// +// MessageId: ERROR_IPSEC_IKE_LOAD_FAILED +// +// MessageText: +// +// Load failed +// +#define ERROR_IPSEC_IKE_LOAD_FAILED 13876L + +// +// MessageId: ERROR_IPSEC_IKE_RPC_DELETE +// +// MessageText: +// +// Deleted via RPC call +// +#define ERROR_IPSEC_IKE_RPC_DELETE 13877L + +// +// MessageId: ERROR_IPSEC_IKE_BENIGN_REINIT +// +// MessageText: +// +// Temporary state created to perform reinit. This is not a real failure. +// +#define ERROR_IPSEC_IKE_BENIGN_REINIT 13878L + +// +// MessageId: ERROR_IPSEC_IKE_INVALID_RESPONDER_LIFETIME_NOTIFY +// +// MessageText: +// +// The lifetime value received in the Responder Lifetime Notify is below the Windows 2000 configured minimum value. Please fix the policy on the peer machine. +// +#define ERROR_IPSEC_IKE_INVALID_RESPONDER_LIFETIME_NOTIFY 13879L + +// +// MessageId: ERROR_IPSEC_IKE_INVALID_CERT_KEYLEN +// +// MessageText: +// +// Key length in certificate is too small for configured security requirements. +// +#define ERROR_IPSEC_IKE_INVALID_CERT_KEYLEN 13881L + +// +// MessageId: ERROR_IPSEC_IKE_MM_LIMIT +// +// MessageText: +// +// Max number of established MM SAs to peer exceeded. +// +#define ERROR_IPSEC_IKE_MM_LIMIT 13882L + +// +// MessageId: ERROR_IPSEC_IKE_NEGOTIATION_DISABLED +// +// MessageText: +// +// IKE received a policy that disables negotiation. +// +#define ERROR_IPSEC_IKE_NEGOTIATION_DISABLED 13883L + +// +// MessageId: ERROR_IPSEC_IKE_NEG_STATUS_END +// +// MessageText: +// +// ERROR_IPSEC_IKE_NEG_STATUS_END +// +#define ERROR_IPSEC_IKE_NEG_STATUS_END 13884L + +//////////////////////////////////// +// // +// COM Error Codes // +// // +//////////////////////////////////// + +// +// The return value of COM functions and methods is an HRESULT. +// This is not a handle to anything, but is merely a 32-bit value +// with several fields encoded in the value. The parts of an +// HRESULT are shown below. +// +// Many of the macros and functions below were orginally defined to +// operate on SCODEs. SCODEs are no longer used. The macros are +// still present for compatibility and easy porting of Win16 code. +// Newly written code should use the HRESULT macros and functions. +// + +// +// HRESULTs are 32 bit values layed out as follows: +// +// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 +// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 +// +-+-+-+-+-+---------------------+-------------------------------+ +// |S|R|C|N|r| Facility | Code | +// +-+-+-+-+-+---------------------+-------------------------------+ +// +// where +// +// S - Severity - indicates success/fail +// +// 0 - Success +// 1 - Fail (COERROR) +// +// R - reserved portion of the facility code, corresponds to NT's +// second severity bit. +// +// C - reserved portion of the facility code, corresponds to NT's +// C field. +// +// N - reserved portion of the facility code. Used to indicate a +// mapped NT status value. +// +// r - reserved portion of the facility code. Reserved for internal +// use. Used to indicate HRESULT values that are not status +// values, but are instead message ids for display strings. +// +// Facility - is the facility code +// +// Code - is the facility's status code +// + +// +// Severity values +// + +#define SEVERITY_SUCCESS 0 +#define SEVERITY_ERROR 1 + + +// +// Generic test for success on any status value (non-negative numbers +// indicate success). +// + +#define SUCCEEDED(hr) ((HRESULT)(hr) >= 0) + +// +// and the inverse +// + +#define FAILED(hr) ((HRESULT)(hr) < 0) + + +// +// Generic test for error on any status value. +// + +#define IS_ERROR(Status) ((unsigned long)(Status) >> 31 == SEVERITY_ERROR) + +// +// Return the code +// + +#define HRESULT_CODE(hr) ((hr) & 0xFFFF) +#define SCODE_CODE(sc) ((sc) & 0xFFFF) + +// +// Return the facility +// + +#define HRESULT_FACILITY(hr) (((hr) >> 16) & 0x1fff) +#define SCODE_FACILITY(sc) (((sc) >> 16) & 0x1fff) + +// +// Return the severity +// + +#define HRESULT_SEVERITY(hr) (((hr) >> 31) & 0x1) +#define SCODE_SEVERITY(sc) (((sc) >> 31) & 0x1) + +// +// Create an HRESULT value from component pieces +// + +#define MAKE_HRESULT(sev,fac,code) \ + ((HRESULT) (((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))) ) +#define MAKE_SCODE(sev,fac,code) \ + ((SCODE) (((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))) ) + + +// +// Map a WIN32 error value into a HRESULT +// Note: This assumes that WIN32 errors fall in the range -32k to 32k. +// +// Define bits here so macros are guaranteed to work + +#define FACILITY_NT_BIT 0x10000000 + +// __HRESULT_FROM_WIN32 will always be a macro. +// The goal will be to enable INLINE_HRESULT_FROM_WIN32 all the time, +// but there's too much code to change to do that at this time. + +#define __HRESULT_FROM_WIN32(x) ((HRESULT)(x) <= 0 ? ((HRESULT)(x)) : ((HRESULT) (((x) & 0x0000FFFF) | (FACILITY_WIN32 << 16) | 0x80000000))) + +#ifdef INLINE_HRESULT_FROM_WIN32 +#ifndef _HRESULT_DEFINED +#define _HRESULT_DEFINED +typedef long HRESULT; +#endif +#ifndef __midl +__inline HRESULT HRESULT_FROM_WIN32(long x) { return x <= 0 ? (HRESULT)x : (HRESULT) (((x) & 0x0000FFFF) | (FACILITY_WIN32 << 16) | 0x80000000);} +#else +#define HRESULT_FROM_WIN32(x) __HRESULT_FROM_WIN32(x) +#endif +#else +#define HRESULT_FROM_WIN32(x) __HRESULT_FROM_WIN32(x) +#endif + +// +// Map an NT status value into a HRESULT +// + +#define HRESULT_FROM_NT(x) ((HRESULT) ((x) | FACILITY_NT_BIT)) + + +// ****** OBSOLETE functions + +// HRESULT functions +// As noted above, these functions are obsolete and should not be used. + + +// Extract the SCODE from a HRESULT + +#define GetScode(hr) ((SCODE) (hr)) + +// Convert an SCODE into an HRESULT. + +#define ResultFromScode(sc) ((HRESULT) (sc)) + + +// PropagateResult is a noop +#define PropagateResult(hrPrevious, scBase) ((HRESULT) scBase) + + +// ****** End of OBSOLETE functions. + + +// ---------------------- HRESULT value definitions ----------------- +// +// HRESULT definitions +// + +#ifdef RC_INVOKED +#define _HRESULT_TYPEDEF_(_sc) _sc +#else // RC_INVOKED +#define _HRESULT_TYPEDEF_(_sc) ((HRESULT)_sc) +#endif // RC_INVOKED + +#define NOERROR 0 + +// +// Error definitions follow +// + +// +// Codes 0x4000-0x40ff are reserved for OLE +// +// +// Error codes +// +// +// MessageId: E_UNEXPECTED +// +// MessageText: +// +// Catastrophic failure +// +#define E_UNEXPECTED _HRESULT_TYPEDEF_(0x8000FFFFL) + +#if defined(_WIN32) && !defined(_MAC) +// +// MessageId: E_NOTIMPL +// +// MessageText: +// +// Not implemented +// +#define E_NOTIMPL _HRESULT_TYPEDEF_(0x80004001L) + +// +// MessageId: E_OUTOFMEMORY +// +// MessageText: +// +// Ran out of memory +// +#define E_OUTOFMEMORY _HRESULT_TYPEDEF_(0x8007000EL) + +// +// MessageId: E_INVALIDARG +// +// MessageText: +// +// One or more arguments are invalid +// +#define E_INVALIDARG _HRESULT_TYPEDEF_(0x80070057L) + +// +// MessageId: E_NOINTERFACE +// +// MessageText: +// +// No such interface supported +// +#define E_NOINTERFACE _HRESULT_TYPEDEF_(0x80004002L) + +// +// MessageId: E_POINTER +// +// MessageText: +// +// Invalid pointer +// +#define E_POINTER _HRESULT_TYPEDEF_(0x80004003L) + +// +// MessageId: E_HANDLE +// +// MessageText: +// +// Invalid handle +// +#define E_HANDLE _HRESULT_TYPEDEF_(0x80070006L) + +// +// MessageId: E_ABORT +// +// MessageText: +// +// Operation aborted +// +#define E_ABORT _HRESULT_TYPEDEF_(0x80004004L) + +// +// MessageId: E_FAIL +// +// MessageText: +// +// Unspecified error +// +#define E_FAIL _HRESULT_TYPEDEF_(0x80004005L) + +// +// MessageId: E_ACCESSDENIED +// +// MessageText: +// +// General access denied error +// +#define E_ACCESSDENIED _HRESULT_TYPEDEF_(0x80070005L) + +#else +// +// MessageId: E_NOTIMPL +// +// MessageText: +// +// Not implemented +// +#define E_NOTIMPL _HRESULT_TYPEDEF_(0x80000001L) + +// +// MessageId: E_OUTOFMEMORY +// +// MessageText: +// +// Ran out of memory +// +#define E_OUTOFMEMORY _HRESULT_TYPEDEF_(0x80000002L) + +// +// MessageId: E_INVALIDARG +// +// MessageText: +// +// One or more arguments are invalid +// +#define E_INVALIDARG _HRESULT_TYPEDEF_(0x80000003L) + +// +// MessageId: E_NOINTERFACE +// +// MessageText: +// +// No such interface supported +// +#define E_NOINTERFACE _HRESULT_TYPEDEF_(0x80000004L) + +// +// MessageId: E_POINTER +// +// MessageText: +// +// Invalid pointer +// +#define E_POINTER _HRESULT_TYPEDEF_(0x80000005L) + +// +// MessageId: E_HANDLE +// +// MessageText: +// +// Invalid handle +// +#define E_HANDLE _HRESULT_TYPEDEF_(0x80000006L) + +// +// MessageId: E_ABORT +// +// MessageText: +// +// Operation aborted +// +#define E_ABORT _HRESULT_TYPEDEF_(0x80000007L) + +// +// MessageId: E_FAIL +// +// MessageText: +// +// Unspecified error +// +#define E_FAIL _HRESULT_TYPEDEF_(0x80000008L) + +// +// MessageId: E_ACCESSDENIED +// +// MessageText: +// +// General access denied error +// +#define E_ACCESSDENIED _HRESULT_TYPEDEF_(0x80000009L) + +#endif //WIN32 +// +// MessageId: E_PENDING +// +// MessageText: +// +// The data necessary to complete this operation is not yet available. +// +#define E_PENDING _HRESULT_TYPEDEF_(0x8000000AL) + +// +// MessageId: CO_E_INIT_TLS +// +// MessageText: +// +// Thread local storage failure +// +#define CO_E_INIT_TLS _HRESULT_TYPEDEF_(0x80004006L) + +// +// MessageId: CO_E_INIT_SHARED_ALLOCATOR +// +// MessageText: +// +// Get shared memory allocator failure +// +#define CO_E_INIT_SHARED_ALLOCATOR _HRESULT_TYPEDEF_(0x80004007L) + +// +// MessageId: CO_E_INIT_MEMORY_ALLOCATOR +// +// MessageText: +// +// Get memory allocator failure +// +#define CO_E_INIT_MEMORY_ALLOCATOR _HRESULT_TYPEDEF_(0x80004008L) + +// +// MessageId: CO_E_INIT_CLASS_CACHE +// +// MessageText: +// +// Unable to initialize class cache +// +#define CO_E_INIT_CLASS_CACHE _HRESULT_TYPEDEF_(0x80004009L) + +// +// MessageId: CO_E_INIT_RPC_CHANNEL +// +// MessageText: +// +// Unable to initialize RPC services +// +#define CO_E_INIT_RPC_CHANNEL _HRESULT_TYPEDEF_(0x8000400AL) + +// +// MessageId: CO_E_INIT_TLS_SET_CHANNEL_CONTROL +// +// MessageText: +// +// Cannot set thread local storage channel control +// +#define CO_E_INIT_TLS_SET_CHANNEL_CONTROL _HRESULT_TYPEDEF_(0x8000400BL) + +// +// MessageId: CO_E_INIT_TLS_CHANNEL_CONTROL +// +// MessageText: +// +// Could not allocate thread local storage channel control +// +#define CO_E_INIT_TLS_CHANNEL_CONTROL _HRESULT_TYPEDEF_(0x8000400CL) + +// +// MessageId: CO_E_INIT_UNACCEPTED_USER_ALLOCATOR +// +// MessageText: +// +// The user supplied memory allocator is unacceptable +// +#define CO_E_INIT_UNACCEPTED_USER_ALLOCATOR _HRESULT_TYPEDEF_(0x8000400DL) + +// +// MessageId: CO_E_INIT_SCM_MUTEX_EXISTS +// +// MessageText: +// +// The OLE service mutex already exists +// +#define CO_E_INIT_SCM_MUTEX_EXISTS _HRESULT_TYPEDEF_(0x8000400EL) + +// +// MessageId: CO_E_INIT_SCM_FILE_MAPPING_EXISTS +// +// MessageText: +// +// The OLE service file mapping already exists +// +#define CO_E_INIT_SCM_FILE_MAPPING_EXISTS _HRESULT_TYPEDEF_(0x8000400FL) + +// +// MessageId: CO_E_INIT_SCM_MAP_VIEW_OF_FILE +// +// MessageText: +// +// Unable to map view of file for OLE service +// +#define CO_E_INIT_SCM_MAP_VIEW_OF_FILE _HRESULT_TYPEDEF_(0x80004010L) + +// +// MessageId: CO_E_INIT_SCM_EXEC_FAILURE +// +// MessageText: +// +// Failure attempting to launch OLE service +// +#define CO_E_INIT_SCM_EXEC_FAILURE _HRESULT_TYPEDEF_(0x80004011L) + +// +// MessageId: CO_E_INIT_ONLY_SINGLE_THREADED +// +// MessageText: +// +// There was an attempt to call CoInitialize a second time while single threaded +// +#define CO_E_INIT_ONLY_SINGLE_THREADED _HRESULT_TYPEDEF_(0x80004012L) + +// +// MessageId: CO_E_CANT_REMOTE +// +// MessageText: +// +// A Remote activation was necessary but was not allowed +// +#define CO_E_CANT_REMOTE _HRESULT_TYPEDEF_(0x80004013L) + +// +// MessageId: CO_E_BAD_SERVER_NAME +// +// MessageText: +// +// A Remote activation was necessary but the server name provided was invalid +// +#define CO_E_BAD_SERVER_NAME _HRESULT_TYPEDEF_(0x80004014L) + +// +// MessageId: CO_E_WRONG_SERVER_IDENTITY +// +// MessageText: +// +// The class is configured to run as a security id different from the caller +// +#define CO_E_WRONG_SERVER_IDENTITY _HRESULT_TYPEDEF_(0x80004015L) + +// +// MessageId: CO_E_OLE1DDE_DISABLED +// +// MessageText: +// +// Use of Ole1 services requiring DDE windows is disabled +// +#define CO_E_OLE1DDE_DISABLED _HRESULT_TYPEDEF_(0x80004016L) + +// +// MessageId: CO_E_RUNAS_SYNTAX +// +// MessageText: +// +// A RunAs specification must be \ or simply +// +#define CO_E_RUNAS_SYNTAX _HRESULT_TYPEDEF_(0x80004017L) + +// +// MessageId: CO_E_CREATEPROCESS_FAILURE +// +// MessageText: +// +// The server process could not be started. The pathname may be incorrect. +// +#define CO_E_CREATEPROCESS_FAILURE _HRESULT_TYPEDEF_(0x80004018L) + +// +// MessageId: CO_E_RUNAS_CREATEPROCESS_FAILURE +// +// MessageText: +// +// The server process could not be started as the configured identity. The pathname may be incorrect or unavailable. +// +#define CO_E_RUNAS_CREATEPROCESS_FAILURE _HRESULT_TYPEDEF_(0x80004019L) + +// +// MessageId: CO_E_RUNAS_LOGON_FAILURE +// +// MessageText: +// +// The server process could not be started because the configured identity is incorrect. Check the username and password. +// +#define CO_E_RUNAS_LOGON_FAILURE _HRESULT_TYPEDEF_(0x8000401AL) + +// +// MessageId: CO_E_LAUNCH_PERMSSION_DENIED +// +// MessageText: +// +// The client is not allowed to launch this server. +// +#define CO_E_LAUNCH_PERMSSION_DENIED _HRESULT_TYPEDEF_(0x8000401BL) + +// +// MessageId: CO_E_START_SERVICE_FAILURE +// +// MessageText: +// +// The service providing this server could not be started. +// +#define CO_E_START_SERVICE_FAILURE _HRESULT_TYPEDEF_(0x8000401CL) + +// +// MessageId: CO_E_REMOTE_COMMUNICATION_FAILURE +// +// MessageText: +// +// This computer was unable to communicate with the computer providing the server. +// +#define CO_E_REMOTE_COMMUNICATION_FAILURE _HRESULT_TYPEDEF_(0x8000401DL) + +// +// MessageId: CO_E_SERVER_START_TIMEOUT +// +// MessageText: +// +// The server did not respond after being launched. +// +#define CO_E_SERVER_START_TIMEOUT _HRESULT_TYPEDEF_(0x8000401EL) + +// +// MessageId: CO_E_CLSREG_INCONSISTENT +// +// MessageText: +// +// The registration information for this server is inconsistent or incomplete. +// +#define CO_E_CLSREG_INCONSISTENT _HRESULT_TYPEDEF_(0x8000401FL) + +// +// MessageId: CO_E_IIDREG_INCONSISTENT +// +// MessageText: +// +// The registration information for this interface is inconsistent or incomplete. +// +#define CO_E_IIDREG_INCONSISTENT _HRESULT_TYPEDEF_(0x80004020L) + +// +// MessageId: CO_E_NOT_SUPPORTED +// +// MessageText: +// +// The operation attempted is not supported. +// +#define CO_E_NOT_SUPPORTED _HRESULT_TYPEDEF_(0x80004021L) + +// +// MessageId: CO_E_RELOAD_DLL +// +// MessageText: +// +// A dll must be loaded. +// +#define CO_E_RELOAD_DLL _HRESULT_TYPEDEF_(0x80004022L) + +// +// MessageId: CO_E_MSI_ERROR +// +// MessageText: +// +// A Microsoft Software Installer error was encountered. +// +#define CO_E_MSI_ERROR _HRESULT_TYPEDEF_(0x80004023L) + +// +// MessageId: CO_E_ATTEMPT_TO_CREATE_OUTSIDE_CLIENT_CONTEXT +// +// MessageText: +// +// The specified activation could not occur in the client context as specified. +// +#define CO_E_ATTEMPT_TO_CREATE_OUTSIDE_CLIENT_CONTEXT _HRESULT_TYPEDEF_(0x80004024L) + +// +// MessageId: CO_E_SERVER_PAUSED +// +// MessageText: +// +// Activations on the server are paused. +// +#define CO_E_SERVER_PAUSED _HRESULT_TYPEDEF_(0x80004025L) + +// +// MessageId: CO_E_SERVER_NOT_PAUSED +// +// MessageText: +// +// Activations on the server are not paused. +// +#define CO_E_SERVER_NOT_PAUSED _HRESULT_TYPEDEF_(0x80004026L) + +// +// MessageId: CO_E_CLASS_DISABLED +// +// MessageText: +// +// The component or application containing the component has been disabled. +// +#define CO_E_CLASS_DISABLED _HRESULT_TYPEDEF_(0x80004027L) + +// +// MessageId: CO_E_CLRNOTAVAILABLE +// +// MessageText: +// +// The common language runtime is not available +// +#define CO_E_CLRNOTAVAILABLE _HRESULT_TYPEDEF_(0x80004028L) + +// +// MessageId: CO_E_ASYNC_WORK_REJECTED +// +// MessageText: +// +// The thread-pool rejected the submitted asynchronous work. +// +#define CO_E_ASYNC_WORK_REJECTED _HRESULT_TYPEDEF_(0x80004029L) + +// +// MessageId: CO_E_SERVER_INIT_TIMEOUT +// +// MessageText: +// +// The server started, but did not finish initializing in a timely fashion. +// +#define CO_E_SERVER_INIT_TIMEOUT _HRESULT_TYPEDEF_(0x8000402AL) + +// +// MessageId: CO_E_NO_SECCTX_IN_ACTIVATE +// +// MessageText: +// +// Unable to complete the call since there is no COM+ security context inside IObjectControl.Activate. +// +#define CO_E_NO_SECCTX_IN_ACTIVATE _HRESULT_TYPEDEF_(0x8000402BL) + +// +// MessageId: CO_E_TRACKER_CONFIG +// +// MessageText: +// +// The provided tracker configuration is invalid +// +#define CO_E_TRACKER_CONFIG _HRESULT_TYPEDEF_(0x80004030L) + +// +// MessageId: CO_E_THREADPOOL_CONFIG +// +// MessageText: +// +// The provided thread pool configuration is invalid +// +#define CO_E_THREADPOOL_CONFIG _HRESULT_TYPEDEF_(0x80004031L) + +// +// MessageId: CO_E_SXS_CONFIG +// +// MessageText: +// +// The provided side-by-side configuration is invalid +// +#define CO_E_SXS_CONFIG _HRESULT_TYPEDEF_(0x80004032L) + +// +// MessageId: CO_E_MALFORMED_SPN +// +// MessageText: +// +// The server principal name (SPN) obtained during security negotiation is malformed. +// +#define CO_E_MALFORMED_SPN _HRESULT_TYPEDEF_(0x80004033L) + + +// +// Success codes +// +#define S_OK ((HRESULT)0x00000000L) +#define S_FALSE ((HRESULT)0x00000001L) + +// ****************** +// FACILITY_ITF +// ****************** + +// +// Codes 0x0-0x01ff are reserved for the OLE group of +// interfaces. +// + + +// +// Generic OLE errors that may be returned by many inerfaces +// + +#define OLE_E_FIRST ((HRESULT)0x80040000L) +#define OLE_E_LAST ((HRESULT)0x800400FFL) +#define OLE_S_FIRST ((HRESULT)0x00040000L) +#define OLE_S_LAST ((HRESULT)0x000400FFL) + +// +// Old OLE errors +// +// +// MessageId: OLE_E_OLEVERB +// +// MessageText: +// +// Invalid OLEVERB structure +// +#define OLE_E_OLEVERB _HRESULT_TYPEDEF_(0x80040000L) + +// +// MessageId: OLE_E_ADVF +// +// MessageText: +// +// Invalid advise flags +// +#define OLE_E_ADVF _HRESULT_TYPEDEF_(0x80040001L) + +// +// MessageId: OLE_E_ENUM_NOMORE +// +// MessageText: +// +// Can't enumerate any more, because the associated data is missing +// +#define OLE_E_ENUM_NOMORE _HRESULT_TYPEDEF_(0x80040002L) + +// +// MessageId: OLE_E_ADVISENOTSUPPORTED +// +// MessageText: +// +// This implementation doesn't take advises +// +#define OLE_E_ADVISENOTSUPPORTED _HRESULT_TYPEDEF_(0x80040003L) + +// +// MessageId: OLE_E_NOCONNECTION +// +// MessageText: +// +// There is no connection for this connection ID +// +#define OLE_E_NOCONNECTION _HRESULT_TYPEDEF_(0x80040004L) + +// +// MessageId: OLE_E_NOTRUNNING +// +// MessageText: +// +// Need to run the object to perform this operation +// +#define OLE_E_NOTRUNNING _HRESULT_TYPEDEF_(0x80040005L) + +// +// MessageId: OLE_E_NOCACHE +// +// MessageText: +// +// There is no cache to operate on +// +#define OLE_E_NOCACHE _HRESULT_TYPEDEF_(0x80040006L) + +// +// MessageId: OLE_E_BLANK +// +// MessageText: +// +// Uninitialized object +// +#define OLE_E_BLANK _HRESULT_TYPEDEF_(0x80040007L) + +// +// MessageId: OLE_E_CLASSDIFF +// +// MessageText: +// +// Linked object's source class has changed +// +#define OLE_E_CLASSDIFF _HRESULT_TYPEDEF_(0x80040008L) + +// +// MessageId: OLE_E_CANT_GETMONIKER +// +// MessageText: +// +// Not able to get the moniker of the object +// +#define OLE_E_CANT_GETMONIKER _HRESULT_TYPEDEF_(0x80040009L) + +// +// MessageId: OLE_E_CANT_BINDTOSOURCE +// +// MessageText: +// +// Not able to bind to the source +// +#define OLE_E_CANT_BINDTOSOURCE _HRESULT_TYPEDEF_(0x8004000AL) + +// +// MessageId: OLE_E_STATIC +// +// MessageText: +// +// Object is static; operation not allowed +// +#define OLE_E_STATIC _HRESULT_TYPEDEF_(0x8004000BL) + +// +// MessageId: OLE_E_PROMPTSAVECANCELLED +// +// MessageText: +// +// User canceled out of save dialog +// +#define OLE_E_PROMPTSAVECANCELLED _HRESULT_TYPEDEF_(0x8004000CL) + +// +// MessageId: OLE_E_INVALIDRECT +// +// MessageText: +// +// Invalid rectangle +// +#define OLE_E_INVALIDRECT _HRESULT_TYPEDEF_(0x8004000DL) + +// +// MessageId: OLE_E_WRONGCOMPOBJ +// +// MessageText: +// +// compobj.dll is too old for the ole2.dll initialized +// +#define OLE_E_WRONGCOMPOBJ _HRESULT_TYPEDEF_(0x8004000EL) + +// +// MessageId: OLE_E_INVALIDHWND +// +// MessageText: +// +// Invalid window handle +// +#define OLE_E_INVALIDHWND _HRESULT_TYPEDEF_(0x8004000FL) + +// +// MessageId: OLE_E_NOT_INPLACEACTIVE +// +// MessageText: +// +// Object is not in any of the inplace active states +// +#define OLE_E_NOT_INPLACEACTIVE _HRESULT_TYPEDEF_(0x80040010L) + +// +// MessageId: OLE_E_CANTCONVERT +// +// MessageText: +// +// Not able to convert object +// +#define OLE_E_CANTCONVERT _HRESULT_TYPEDEF_(0x80040011L) + +// +// MessageId: OLE_E_NOSTORAGE +// +// MessageText: +// +// Not able to perform the operation because object is not given storage yet +// +#define OLE_E_NOSTORAGE _HRESULT_TYPEDEF_(0x80040012L) + +// +// MessageId: DV_E_FORMATETC +// +// MessageText: +// +// Invalid FORMATETC structure +// +#define DV_E_FORMATETC _HRESULT_TYPEDEF_(0x80040064L) + +// +// MessageId: DV_E_DVTARGETDEVICE +// +// MessageText: +// +// Invalid DVTARGETDEVICE structure +// +#define DV_E_DVTARGETDEVICE _HRESULT_TYPEDEF_(0x80040065L) + +// +// MessageId: DV_E_STGMEDIUM +// +// MessageText: +// +// Invalid STDGMEDIUM structure +// +#define DV_E_STGMEDIUM _HRESULT_TYPEDEF_(0x80040066L) + +// +// MessageId: DV_E_STATDATA +// +// MessageText: +// +// Invalid STATDATA structure +// +#define DV_E_STATDATA _HRESULT_TYPEDEF_(0x80040067L) + +// +// MessageId: DV_E_LINDEX +// +// MessageText: +// +// Invalid lindex +// +#define DV_E_LINDEX _HRESULT_TYPEDEF_(0x80040068L) + +// +// MessageId: DV_E_TYMED +// +// MessageText: +// +// Invalid tymed +// +#define DV_E_TYMED _HRESULT_TYPEDEF_(0x80040069L) + +// +// MessageId: DV_E_CLIPFORMAT +// +// MessageText: +// +// Invalid clipboard format +// +#define DV_E_CLIPFORMAT _HRESULT_TYPEDEF_(0x8004006AL) + +// +// MessageId: DV_E_DVASPECT +// +// MessageText: +// +// Invalid aspect(s) +// +#define DV_E_DVASPECT _HRESULT_TYPEDEF_(0x8004006BL) + +// +// MessageId: DV_E_DVTARGETDEVICE_SIZE +// +// MessageText: +// +// tdSize parameter of the DVTARGETDEVICE structure is invalid +// +#define DV_E_DVTARGETDEVICE_SIZE _HRESULT_TYPEDEF_(0x8004006CL) + +// +// MessageId: DV_E_NOIVIEWOBJECT +// +// MessageText: +// +// Object doesn't support IViewObject interface +// +#define DV_E_NOIVIEWOBJECT _HRESULT_TYPEDEF_(0x8004006DL) + +#define DRAGDROP_E_FIRST 0x80040100L +#define DRAGDROP_E_LAST 0x8004010FL +#define DRAGDROP_S_FIRST 0x00040100L +#define DRAGDROP_S_LAST 0x0004010FL +// +// MessageId: DRAGDROP_E_NOTREGISTERED +// +// MessageText: +// +// Trying to revoke a drop target that has not been registered +// +#define DRAGDROP_E_NOTREGISTERED _HRESULT_TYPEDEF_(0x80040100L) + +// +// MessageId: DRAGDROP_E_ALREADYREGISTERED +// +// MessageText: +// +// This window has already been registered as a drop target +// +#define DRAGDROP_E_ALREADYREGISTERED _HRESULT_TYPEDEF_(0x80040101L) + +// +// MessageId: DRAGDROP_E_INVALIDHWND +// +// MessageText: +// +// Invalid window handle +// +#define DRAGDROP_E_INVALIDHWND _HRESULT_TYPEDEF_(0x80040102L) + +#define CLASSFACTORY_E_FIRST 0x80040110L +#define CLASSFACTORY_E_LAST 0x8004011FL +#define CLASSFACTORY_S_FIRST 0x00040110L +#define CLASSFACTORY_S_LAST 0x0004011FL +// +// MessageId: CLASS_E_NOAGGREGATION +// +// MessageText: +// +// Class does not support aggregation (or class object is remote) +// +#define CLASS_E_NOAGGREGATION _HRESULT_TYPEDEF_(0x80040110L) + +// +// MessageId: CLASS_E_CLASSNOTAVAILABLE +// +// MessageText: +// +// ClassFactory cannot supply requested class +// +#define CLASS_E_CLASSNOTAVAILABLE _HRESULT_TYPEDEF_(0x80040111L) + +// +// MessageId: CLASS_E_NOTLICENSED +// +// MessageText: +// +// Class is not licensed for use +// +#define CLASS_E_NOTLICENSED _HRESULT_TYPEDEF_(0x80040112L) + +#define MARSHAL_E_FIRST 0x80040120L +#define MARSHAL_E_LAST 0x8004012FL +#define MARSHAL_S_FIRST 0x00040120L +#define MARSHAL_S_LAST 0x0004012FL +#define DATA_E_FIRST 0x80040130L +#define DATA_E_LAST 0x8004013FL +#define DATA_S_FIRST 0x00040130L +#define DATA_S_LAST 0x0004013FL +#define VIEW_E_FIRST 0x80040140L +#define VIEW_E_LAST 0x8004014FL +#define VIEW_S_FIRST 0x00040140L +#define VIEW_S_LAST 0x0004014FL +// +// MessageId: VIEW_E_DRAW +// +// MessageText: +// +// Error drawing view +// +#define VIEW_E_DRAW _HRESULT_TYPEDEF_(0x80040140L) + +#define REGDB_E_FIRST 0x80040150L +#define REGDB_E_LAST 0x8004015FL +#define REGDB_S_FIRST 0x00040150L +#define REGDB_S_LAST 0x0004015FL +// +// MessageId: REGDB_E_READREGDB +// +// MessageText: +// +// Could not read key from registry +// +#define REGDB_E_READREGDB _HRESULT_TYPEDEF_(0x80040150L) + +// +// MessageId: REGDB_E_WRITEREGDB +// +// MessageText: +// +// Could not write key to registry +// +#define REGDB_E_WRITEREGDB _HRESULT_TYPEDEF_(0x80040151L) + +// +// MessageId: REGDB_E_KEYMISSING +// +// MessageText: +// +// Could not find the key in the registry +// +#define REGDB_E_KEYMISSING _HRESULT_TYPEDEF_(0x80040152L) + +// +// MessageId: REGDB_E_INVALIDVALUE +// +// MessageText: +// +// Invalid value for registry +// +#define REGDB_E_INVALIDVALUE _HRESULT_TYPEDEF_(0x80040153L) + +// +// MessageId: REGDB_E_CLASSNOTREG +// +// MessageText: +// +// Class not registered +// +#define REGDB_E_CLASSNOTREG _HRESULT_TYPEDEF_(0x80040154L) + +// +// MessageId: REGDB_E_IIDNOTREG +// +// MessageText: +// +// Interface not registered +// +#define REGDB_E_IIDNOTREG _HRESULT_TYPEDEF_(0x80040155L) + +// +// MessageId: REGDB_E_BADTHREADINGMODEL +// +// MessageText: +// +// Threading model entry is not valid +// +#define REGDB_E_BADTHREADINGMODEL _HRESULT_TYPEDEF_(0x80040156L) + +#define CAT_E_FIRST 0x80040160L +#define CAT_E_LAST 0x80040161L +// +// MessageId: CAT_E_CATIDNOEXIST +// +// MessageText: +// +// CATID does not exist +// +#define CAT_E_CATIDNOEXIST _HRESULT_TYPEDEF_(0x80040160L) + +// +// MessageId: CAT_E_NODESCRIPTION +// +// MessageText: +// +// Description not found +// +#define CAT_E_NODESCRIPTION _HRESULT_TYPEDEF_(0x80040161L) + +//////////////////////////////////// +// // +// Class Store Error Codes // +// // +//////////////////////////////////// +#define CS_E_FIRST 0x80040164L +#define CS_E_LAST 0x8004016FL +// +// MessageId: CS_E_PACKAGE_NOTFOUND +// +// MessageText: +// +// No package in the software installation data in the Active Directory meets this criteria. +// +#define CS_E_PACKAGE_NOTFOUND _HRESULT_TYPEDEF_(0x80040164L) + +// +// MessageId: CS_E_NOT_DELETABLE +// +// MessageText: +// +// Deleting this will break the referential integrity of the software installation data in the Active Directory. +// +#define CS_E_NOT_DELETABLE _HRESULT_TYPEDEF_(0x80040165L) + +// +// MessageId: CS_E_CLASS_NOTFOUND +// +// MessageText: +// +// The CLSID was not found in the software installation data in the Active Directory. +// +#define CS_E_CLASS_NOTFOUND _HRESULT_TYPEDEF_(0x80040166L) + +// +// MessageId: CS_E_INVALID_VERSION +// +// MessageText: +// +// The software installation data in the Active Directory is corrupt. +// +#define CS_E_INVALID_VERSION _HRESULT_TYPEDEF_(0x80040167L) + +// +// MessageId: CS_E_NO_CLASSSTORE +// +// MessageText: +// +// There is no software installation data in the Active Directory. +// +#define CS_E_NO_CLASSSTORE _HRESULT_TYPEDEF_(0x80040168L) + +// +// MessageId: CS_E_OBJECT_NOTFOUND +// +// MessageText: +// +// There is no software installation data object in the Active Directory. +// +#define CS_E_OBJECT_NOTFOUND _HRESULT_TYPEDEF_(0x80040169L) + +// +// MessageId: CS_E_OBJECT_ALREADY_EXISTS +// +// MessageText: +// +// The software installation data object in the Active Directory already exists. +// +#define CS_E_OBJECT_ALREADY_EXISTS _HRESULT_TYPEDEF_(0x8004016AL) + +// +// MessageId: CS_E_INVALID_PATH +// +// MessageText: +// +// The path to the software installation data in the Active Directory is not correct. +// +#define CS_E_INVALID_PATH _HRESULT_TYPEDEF_(0x8004016BL) + +// +// MessageId: CS_E_NETWORK_ERROR +// +// MessageText: +// +// A network error interrupted the operation. +// +#define CS_E_NETWORK_ERROR _HRESULT_TYPEDEF_(0x8004016CL) + +// +// MessageId: CS_E_ADMIN_LIMIT_EXCEEDED +// +// MessageText: +// +// The size of this object exceeds the maximum size set by the Administrator. +// +#define CS_E_ADMIN_LIMIT_EXCEEDED _HRESULT_TYPEDEF_(0x8004016DL) + +// +// MessageId: CS_E_SCHEMA_MISMATCH +// +// MessageText: +// +// The schema for the software installation data in the Active Directory does not match the required schema. +// +#define CS_E_SCHEMA_MISMATCH _HRESULT_TYPEDEF_(0x8004016EL) + +// +// MessageId: CS_E_INTERNAL_ERROR +// +// MessageText: +// +// An error occurred in the software installation data in the Active Directory. +// +#define CS_E_INTERNAL_ERROR _HRESULT_TYPEDEF_(0x8004016FL) + +#define CACHE_E_FIRST 0x80040170L +#define CACHE_E_LAST 0x8004017FL +#define CACHE_S_FIRST 0x00040170L +#define CACHE_S_LAST 0x0004017FL +// +// MessageId: CACHE_E_NOCACHE_UPDATED +// +// MessageText: +// +// Cache not updated +// +#define CACHE_E_NOCACHE_UPDATED _HRESULT_TYPEDEF_(0x80040170L) + +#define OLEOBJ_E_FIRST 0x80040180L +#define OLEOBJ_E_LAST 0x8004018FL +#define OLEOBJ_S_FIRST 0x00040180L +#define OLEOBJ_S_LAST 0x0004018FL +// +// MessageId: OLEOBJ_E_NOVERBS +// +// MessageText: +// +// No verbs for OLE object +// +#define OLEOBJ_E_NOVERBS _HRESULT_TYPEDEF_(0x80040180L) + +// +// MessageId: OLEOBJ_E_INVALIDVERB +// +// MessageText: +// +// Invalid verb for OLE object +// +#define OLEOBJ_E_INVALIDVERB _HRESULT_TYPEDEF_(0x80040181L) + +#define CLIENTSITE_E_FIRST 0x80040190L +#define CLIENTSITE_E_LAST 0x8004019FL +#define CLIENTSITE_S_FIRST 0x00040190L +#define CLIENTSITE_S_LAST 0x0004019FL +// +// MessageId: INPLACE_E_NOTUNDOABLE +// +// MessageText: +// +// Undo is not available +// +#define INPLACE_E_NOTUNDOABLE _HRESULT_TYPEDEF_(0x800401A0L) + +// +// MessageId: INPLACE_E_NOTOOLSPACE +// +// MessageText: +// +// Space for tools is not available +// +#define INPLACE_E_NOTOOLSPACE _HRESULT_TYPEDEF_(0x800401A1L) + +#define INPLACE_E_FIRST 0x800401A0L +#define INPLACE_E_LAST 0x800401AFL +#define INPLACE_S_FIRST 0x000401A0L +#define INPLACE_S_LAST 0x000401AFL +#define ENUM_E_FIRST 0x800401B0L +#define ENUM_E_LAST 0x800401BFL +#define ENUM_S_FIRST 0x000401B0L +#define ENUM_S_LAST 0x000401BFL +#define CONVERT10_E_FIRST 0x800401C0L +#define CONVERT10_E_LAST 0x800401CFL +#define CONVERT10_S_FIRST 0x000401C0L +#define CONVERT10_S_LAST 0x000401CFL +// +// MessageId: CONVERT10_E_OLESTREAM_GET +// +// MessageText: +// +// OLESTREAM Get method failed +// +#define CONVERT10_E_OLESTREAM_GET _HRESULT_TYPEDEF_(0x800401C0L) + +// +// MessageId: CONVERT10_E_OLESTREAM_PUT +// +// MessageText: +// +// OLESTREAM Put method failed +// +#define CONVERT10_E_OLESTREAM_PUT _HRESULT_TYPEDEF_(0x800401C1L) + +// +// MessageId: CONVERT10_E_OLESTREAM_FMT +// +// MessageText: +// +// Contents of the OLESTREAM not in correct format +// +#define CONVERT10_E_OLESTREAM_FMT _HRESULT_TYPEDEF_(0x800401C2L) + +// +// MessageId: CONVERT10_E_OLESTREAM_BITMAP_TO_DIB +// +// MessageText: +// +// There was an error in a Windows GDI call while converting the bitmap to a DIB +// +#define CONVERT10_E_OLESTREAM_BITMAP_TO_DIB _HRESULT_TYPEDEF_(0x800401C3L) + +// +// MessageId: CONVERT10_E_STG_FMT +// +// MessageText: +// +// Contents of the IStorage not in correct format +// +#define CONVERT10_E_STG_FMT _HRESULT_TYPEDEF_(0x800401C4L) + +// +// MessageId: CONVERT10_E_STG_NO_STD_STREAM +// +// MessageText: +// +// Contents of IStorage is missing one of the standard streams +// +#define CONVERT10_E_STG_NO_STD_STREAM _HRESULT_TYPEDEF_(0x800401C5L) + +// +// MessageId: CONVERT10_E_STG_DIB_TO_BITMAP +// +// MessageText: +// +// There was an error in a Windows GDI call while converting the DIB to a bitmap. +// +// +#define CONVERT10_E_STG_DIB_TO_BITMAP _HRESULT_TYPEDEF_(0x800401C6L) + +#define CLIPBRD_E_FIRST 0x800401D0L +#define CLIPBRD_E_LAST 0x800401DFL +#define CLIPBRD_S_FIRST 0x000401D0L +#define CLIPBRD_S_LAST 0x000401DFL +// +// MessageId: CLIPBRD_E_CANT_OPEN +// +// MessageText: +// +// OpenClipboard Failed +// +#define CLIPBRD_E_CANT_OPEN _HRESULT_TYPEDEF_(0x800401D0L) + +// +// MessageId: CLIPBRD_E_CANT_EMPTY +// +// MessageText: +// +// EmptyClipboard Failed +// +#define CLIPBRD_E_CANT_EMPTY _HRESULT_TYPEDEF_(0x800401D1L) + +// +// MessageId: CLIPBRD_E_CANT_SET +// +// MessageText: +// +// SetClipboard Failed +// +#define CLIPBRD_E_CANT_SET _HRESULT_TYPEDEF_(0x800401D2L) + +// +// MessageId: CLIPBRD_E_BAD_DATA +// +// MessageText: +// +// Data on clipboard is invalid +// +#define CLIPBRD_E_BAD_DATA _HRESULT_TYPEDEF_(0x800401D3L) + +// +// MessageId: CLIPBRD_E_CANT_CLOSE +// +// MessageText: +// +// CloseClipboard Failed +// +#define CLIPBRD_E_CANT_CLOSE _HRESULT_TYPEDEF_(0x800401D4L) + +#define MK_E_FIRST 0x800401E0L +#define MK_E_LAST 0x800401EFL +#define MK_S_FIRST 0x000401E0L +#define MK_S_LAST 0x000401EFL +// +// MessageId: MK_E_CONNECTMANUALLY +// +// MessageText: +// +// Moniker needs to be connected manually +// +#define MK_E_CONNECTMANUALLY _HRESULT_TYPEDEF_(0x800401E0L) + +// +// MessageId: MK_E_EXCEEDEDDEADLINE +// +// MessageText: +// +// Operation exceeded deadline +// +#define MK_E_EXCEEDEDDEADLINE _HRESULT_TYPEDEF_(0x800401E1L) + +// +// MessageId: MK_E_NEEDGENERIC +// +// MessageText: +// +// Moniker needs to be generic +// +#define MK_E_NEEDGENERIC _HRESULT_TYPEDEF_(0x800401E2L) + +// +// MessageId: MK_E_UNAVAILABLE +// +// MessageText: +// +// Operation unavailable +// +#define MK_E_UNAVAILABLE _HRESULT_TYPEDEF_(0x800401E3L) + +// +// MessageId: MK_E_SYNTAX +// +// MessageText: +// +// Invalid syntax +// +#define MK_E_SYNTAX _HRESULT_TYPEDEF_(0x800401E4L) + +// +// MessageId: MK_E_NOOBJECT +// +// MessageText: +// +// No object for moniker +// +#define MK_E_NOOBJECT _HRESULT_TYPEDEF_(0x800401E5L) + +// +// MessageId: MK_E_INVALIDEXTENSION +// +// MessageText: +// +// Bad extension for file +// +#define MK_E_INVALIDEXTENSION _HRESULT_TYPEDEF_(0x800401E6L) + +// +// MessageId: MK_E_INTERMEDIATEINTERFACENOTSUPPORTED +// +// MessageText: +// +// Intermediate operation failed +// +#define MK_E_INTERMEDIATEINTERFACENOTSUPPORTED _HRESULT_TYPEDEF_(0x800401E7L) + +// +// MessageId: MK_E_NOTBINDABLE +// +// MessageText: +// +// Moniker is not bindable +// +#define MK_E_NOTBINDABLE _HRESULT_TYPEDEF_(0x800401E8L) + +// +// MessageId: MK_E_NOTBOUND +// +// MessageText: +// +// Moniker is not bound +// +#define MK_E_NOTBOUND _HRESULT_TYPEDEF_(0x800401E9L) + +// +// MessageId: MK_E_CANTOPENFILE +// +// MessageText: +// +// Moniker cannot open file +// +#define MK_E_CANTOPENFILE _HRESULT_TYPEDEF_(0x800401EAL) + +// +// MessageId: MK_E_MUSTBOTHERUSER +// +// MessageText: +// +// User input required for operation to succeed +// +#define MK_E_MUSTBOTHERUSER _HRESULT_TYPEDEF_(0x800401EBL) + +// +// MessageId: MK_E_NOINVERSE +// +// MessageText: +// +// Moniker class has no inverse +// +#define MK_E_NOINVERSE _HRESULT_TYPEDEF_(0x800401ECL) + +// +// MessageId: MK_E_NOSTORAGE +// +// MessageText: +// +// Moniker does not refer to storage +// +#define MK_E_NOSTORAGE _HRESULT_TYPEDEF_(0x800401EDL) + +// +// MessageId: MK_E_NOPREFIX +// +// MessageText: +// +// No common prefix +// +#define MK_E_NOPREFIX _HRESULT_TYPEDEF_(0x800401EEL) + +// +// MessageId: MK_E_ENUMERATION_FAILED +// +// MessageText: +// +// Moniker could not be enumerated +// +#define MK_E_ENUMERATION_FAILED _HRESULT_TYPEDEF_(0x800401EFL) + +#define CO_E_FIRST 0x800401F0L +#define CO_E_LAST 0x800401FFL +#define CO_S_FIRST 0x000401F0L +#define CO_S_LAST 0x000401FFL +// +// MessageId: CO_E_NOTINITIALIZED +// +// MessageText: +// +// CoInitialize has not been called. +// +#define CO_E_NOTINITIALIZED _HRESULT_TYPEDEF_(0x800401F0L) + +// +// MessageId: CO_E_ALREADYINITIALIZED +// +// MessageText: +// +// CoInitialize has already been called. +// +#define CO_E_ALREADYINITIALIZED _HRESULT_TYPEDEF_(0x800401F1L) + +// +// MessageId: CO_E_CANTDETERMINECLASS +// +// MessageText: +// +// Class of object cannot be determined +// +#define CO_E_CANTDETERMINECLASS _HRESULT_TYPEDEF_(0x800401F2L) + +// +// MessageId: CO_E_CLASSSTRING +// +// MessageText: +// +// Invalid class string +// +#define CO_E_CLASSSTRING _HRESULT_TYPEDEF_(0x800401F3L) + +// +// MessageId: CO_E_IIDSTRING +// +// MessageText: +// +// Invalid interface string +// +#define CO_E_IIDSTRING _HRESULT_TYPEDEF_(0x800401F4L) + +// +// MessageId: CO_E_APPNOTFOUND +// +// MessageText: +// +// Application not found +// +#define CO_E_APPNOTFOUND _HRESULT_TYPEDEF_(0x800401F5L) + +// +// MessageId: CO_E_APPSINGLEUSE +// +// MessageText: +// +// Application cannot be run more than once +// +#define CO_E_APPSINGLEUSE _HRESULT_TYPEDEF_(0x800401F6L) + +// +// MessageId: CO_E_ERRORINAPP +// +// MessageText: +// +// Some error in application program +// +#define CO_E_ERRORINAPP _HRESULT_TYPEDEF_(0x800401F7L) + +// +// MessageId: CO_E_DLLNOTFOUND +// +// MessageText: +// +// DLL for class not found +// +#define CO_E_DLLNOTFOUND _HRESULT_TYPEDEF_(0x800401F8L) + +// +// MessageId: CO_E_ERRORINDLL +// +// MessageText: +// +// Error in the DLL +// +#define CO_E_ERRORINDLL _HRESULT_TYPEDEF_(0x800401F9L) + +// +// MessageId: CO_E_WRONGOSFORAPP +// +// MessageText: +// +// Wrong OS or OS version for application +// +#define CO_E_WRONGOSFORAPP _HRESULT_TYPEDEF_(0x800401FAL) + +// +// MessageId: CO_E_OBJNOTREG +// +// MessageText: +// +// Object is not registered +// +#define CO_E_OBJNOTREG _HRESULT_TYPEDEF_(0x800401FBL) + +// +// MessageId: CO_E_OBJISREG +// +// MessageText: +// +// Object is already registered +// +#define CO_E_OBJISREG _HRESULT_TYPEDEF_(0x800401FCL) + +// +// MessageId: CO_E_OBJNOTCONNECTED +// +// MessageText: +// +// Object is not connected to server +// +#define CO_E_OBJNOTCONNECTED _HRESULT_TYPEDEF_(0x800401FDL) + +// +// MessageId: CO_E_APPDIDNTREG +// +// MessageText: +// +// Application was launched but it didn't register a class factory +// +#define CO_E_APPDIDNTREG _HRESULT_TYPEDEF_(0x800401FEL) + +// +// MessageId: CO_E_RELEASED +// +// MessageText: +// +// Object has been released +// +#define CO_E_RELEASED _HRESULT_TYPEDEF_(0x800401FFL) + +#define EVENT_E_FIRST 0x80040200L +#define EVENT_E_LAST 0x8004021FL +#define EVENT_S_FIRST 0x00040200L +#define EVENT_S_LAST 0x0004021FL +// +// MessageId: EVENT_S_SOME_SUBSCRIBERS_FAILED +// +// MessageText: +// +// An event was able to invoke some but not all of the subscribers +// +#define EVENT_S_SOME_SUBSCRIBERS_FAILED _HRESULT_TYPEDEF_(0x00040200L) + +// +// MessageId: EVENT_E_ALL_SUBSCRIBERS_FAILED +// +// MessageText: +// +// An event was unable to invoke any of the subscribers +// +#define EVENT_E_ALL_SUBSCRIBERS_FAILED _HRESULT_TYPEDEF_(0x80040201L) + +// +// MessageId: EVENT_S_NOSUBSCRIBERS +// +// MessageText: +// +// An event was delivered but there were no subscribers +// +#define EVENT_S_NOSUBSCRIBERS _HRESULT_TYPEDEF_(0x00040202L) + +// +// MessageId: EVENT_E_QUERYSYNTAX +// +// MessageText: +// +// A syntax error occurred trying to evaluate a query string +// +#define EVENT_E_QUERYSYNTAX _HRESULT_TYPEDEF_(0x80040203L) + +// +// MessageId: EVENT_E_QUERYFIELD +// +// MessageText: +// +// An invalid field name was used in a query string +// +#define EVENT_E_QUERYFIELD _HRESULT_TYPEDEF_(0x80040204L) + +// +// MessageId: EVENT_E_INTERNALEXCEPTION +// +// MessageText: +// +// An unexpected exception was raised +// +#define EVENT_E_INTERNALEXCEPTION _HRESULT_TYPEDEF_(0x80040205L) + +// +// MessageId: EVENT_E_INTERNALERROR +// +// MessageText: +// +// An unexpected internal error was detected +// +#define EVENT_E_INTERNALERROR _HRESULT_TYPEDEF_(0x80040206L) + +// +// MessageId: EVENT_E_INVALID_PER_USER_SID +// +// MessageText: +// +// The owner SID on a per-user subscription doesn't exist +// +#define EVENT_E_INVALID_PER_USER_SID _HRESULT_TYPEDEF_(0x80040207L) + +// +// MessageId: EVENT_E_USER_EXCEPTION +// +// MessageText: +// +// A user-supplied component or subscriber raised an exception +// +#define EVENT_E_USER_EXCEPTION _HRESULT_TYPEDEF_(0x80040208L) + +// +// MessageId: EVENT_E_TOO_MANY_METHODS +// +// MessageText: +// +// An interface has too many methods to fire events from +// +#define EVENT_E_TOO_MANY_METHODS _HRESULT_TYPEDEF_(0x80040209L) + +// +// MessageId: EVENT_E_MISSING_EVENTCLASS +// +// MessageText: +// +// A subscription cannot be stored unless its event class already exists +// +#define EVENT_E_MISSING_EVENTCLASS _HRESULT_TYPEDEF_(0x8004020AL) + +// +// MessageId: EVENT_E_NOT_ALL_REMOVED +// +// MessageText: +// +// Not all the objects requested could be removed +// +#define EVENT_E_NOT_ALL_REMOVED _HRESULT_TYPEDEF_(0x8004020BL) + +// +// MessageId: EVENT_E_COMPLUS_NOT_INSTALLED +// +// MessageText: +// +// COM+ is required for this operation, but is not installed +// +#define EVENT_E_COMPLUS_NOT_INSTALLED _HRESULT_TYPEDEF_(0x8004020CL) + +// +// MessageId: EVENT_E_CANT_MODIFY_OR_DELETE_UNCONFIGURED_OBJECT +// +// MessageText: +// +// Cannot modify or delete an object that was not added using the COM+ Admin SDK +// +#define EVENT_E_CANT_MODIFY_OR_DELETE_UNCONFIGURED_OBJECT _HRESULT_TYPEDEF_(0x8004020DL) + +// +// MessageId: EVENT_E_CANT_MODIFY_OR_DELETE_CONFIGURED_OBJECT +// +// MessageText: +// +// Cannot modify or delete an object that was added using the COM+ Admin SDK +// +#define EVENT_E_CANT_MODIFY_OR_DELETE_CONFIGURED_OBJECT _HRESULT_TYPEDEF_(0x8004020EL) + +// +// MessageId: EVENT_E_INVALID_EVENT_CLASS_PARTITION +// +// MessageText: +// +// The event class for this subscription is in an invalid partition +// +#define EVENT_E_INVALID_EVENT_CLASS_PARTITION _HRESULT_TYPEDEF_(0x8004020FL) + +// +// MessageId: EVENT_E_PER_USER_SID_NOT_LOGGED_ON +// +// MessageText: +// +// The owner of the PerUser subscription is not logged on to the system specified +// +#define EVENT_E_PER_USER_SID_NOT_LOGGED_ON _HRESULT_TYPEDEF_(0x80040210L) + +#define XACT_E_FIRST 0x8004D000 +#define XACT_E_LAST 0x8004D029 +#define XACT_S_FIRST 0x0004D000 +#define XACT_S_LAST 0x0004D010 +// +// MessageId: XACT_E_ALREADYOTHERSINGLEPHASE +// +// MessageText: +// +// Another single phase resource manager has already been enlisted in this transaction. +// +#define XACT_E_ALREADYOTHERSINGLEPHASE _HRESULT_TYPEDEF_(0x8004D000L) + +// +// MessageId: XACT_E_CANTRETAIN +// +// MessageText: +// +// A retaining commit or abort is not supported +// +#define XACT_E_CANTRETAIN _HRESULT_TYPEDEF_(0x8004D001L) + +// +// MessageId: XACT_E_COMMITFAILED +// +// MessageText: +// +// The transaction failed to commit for an unknown reason. The transaction was aborted. +// +#define XACT_E_COMMITFAILED _HRESULT_TYPEDEF_(0x8004D002L) + +// +// MessageId: XACT_E_COMMITPREVENTED +// +// MessageText: +// +// Cannot call commit on this transaction object because the calling application did not initiate the transaction. +// +#define XACT_E_COMMITPREVENTED _HRESULT_TYPEDEF_(0x8004D003L) + +// +// MessageId: XACT_E_HEURISTICABORT +// +// MessageText: +// +// Instead of committing, the resource heuristically aborted. +// +#define XACT_E_HEURISTICABORT _HRESULT_TYPEDEF_(0x8004D004L) + +// +// MessageId: XACT_E_HEURISTICCOMMIT +// +// MessageText: +// +// Instead of aborting, the resource heuristically committed. +// +#define XACT_E_HEURISTICCOMMIT _HRESULT_TYPEDEF_(0x8004D005L) + +// +// MessageId: XACT_E_HEURISTICDAMAGE +// +// MessageText: +// +// Some of the states of the resource were committed while others were aborted, likely because of heuristic decisions. +// +#define XACT_E_HEURISTICDAMAGE _HRESULT_TYPEDEF_(0x8004D006L) + +// +// MessageId: XACT_E_HEURISTICDANGER +// +// MessageText: +// +// Some of the states of the resource may have been committed while others may have been aborted, likely because of heuristic decisions. +// +#define XACT_E_HEURISTICDANGER _HRESULT_TYPEDEF_(0x8004D007L) + +// +// MessageId: XACT_E_ISOLATIONLEVEL +// +// MessageText: +// +// The requested isolation level is not valid or supported. +// +#define XACT_E_ISOLATIONLEVEL _HRESULT_TYPEDEF_(0x8004D008L) + +// +// MessageId: XACT_E_NOASYNC +// +// MessageText: +// +// The transaction manager doesn't support an asynchronous operation for this method. +// +#define XACT_E_NOASYNC _HRESULT_TYPEDEF_(0x8004D009L) + +// +// MessageId: XACT_E_NOENLIST +// +// MessageText: +// +// Unable to enlist in the transaction. +// +#define XACT_E_NOENLIST _HRESULT_TYPEDEF_(0x8004D00AL) + +// +// MessageId: XACT_E_NOISORETAIN +// +// MessageText: +// +// The requested semantics of retention of isolation across retaining commit and abort boundaries cannot be supported by this transaction implementation, or isoFlags was not equal to zero. +// +#define XACT_E_NOISORETAIN _HRESULT_TYPEDEF_(0x8004D00BL) + +// +// MessageId: XACT_E_NORESOURCE +// +// MessageText: +// +// There is no resource presently associated with this enlistment +// +#define XACT_E_NORESOURCE _HRESULT_TYPEDEF_(0x8004D00CL) + +// +// MessageId: XACT_E_NOTCURRENT +// +// MessageText: +// +// The transaction failed to commit due to the failure of optimistic concurrency control in at least one of the resource managers. +// +#define XACT_E_NOTCURRENT _HRESULT_TYPEDEF_(0x8004D00DL) + +// +// MessageId: XACT_E_NOTRANSACTION +// +// MessageText: +// +// The transaction has already been implicitly or explicitly committed or aborted +// +#define XACT_E_NOTRANSACTION _HRESULT_TYPEDEF_(0x8004D00EL) + +// +// MessageId: XACT_E_NOTSUPPORTED +// +// MessageText: +// +// An invalid combination of flags was specified +// +#define XACT_E_NOTSUPPORTED _HRESULT_TYPEDEF_(0x8004D00FL) + +// +// MessageId: XACT_E_UNKNOWNRMGRID +// +// MessageText: +// +// The resource manager id is not associated with this transaction or the transaction manager. +// +#define XACT_E_UNKNOWNRMGRID _HRESULT_TYPEDEF_(0x8004D010L) + +// +// MessageId: XACT_E_WRONGSTATE +// +// MessageText: +// +// This method was called in the wrong state +// +#define XACT_E_WRONGSTATE _HRESULT_TYPEDEF_(0x8004D011L) + +// +// MessageId: XACT_E_WRONGUOW +// +// MessageText: +// +// The indicated unit of work does not match the unit of work expected by the resource manager. +// +#define XACT_E_WRONGUOW _HRESULT_TYPEDEF_(0x8004D012L) + +// +// MessageId: XACT_E_XTIONEXISTS +// +// MessageText: +// +// An enlistment in a transaction already exists. +// +#define XACT_E_XTIONEXISTS _HRESULT_TYPEDEF_(0x8004D013L) + +// +// MessageId: XACT_E_NOIMPORTOBJECT +// +// MessageText: +// +// An import object for the transaction could not be found. +// +#define XACT_E_NOIMPORTOBJECT _HRESULT_TYPEDEF_(0x8004D014L) + +// +// MessageId: XACT_E_INVALIDCOOKIE +// +// MessageText: +// +// The transaction cookie is invalid. +// +#define XACT_E_INVALIDCOOKIE _HRESULT_TYPEDEF_(0x8004D015L) + +// +// MessageId: XACT_E_INDOUBT +// +// MessageText: +// +// The transaction status is in doubt. A communication failure occurred, or a transaction manager or resource manager has failed +// +#define XACT_E_INDOUBT _HRESULT_TYPEDEF_(0x8004D016L) + +// +// MessageId: XACT_E_NOTIMEOUT +// +// MessageText: +// +// A time-out was specified, but time-outs are not supported. +// +#define XACT_E_NOTIMEOUT _HRESULT_TYPEDEF_(0x8004D017L) + +// +// MessageId: XACT_E_ALREADYINPROGRESS +// +// MessageText: +// +// The requested operation is already in progress for the transaction. +// +#define XACT_E_ALREADYINPROGRESS _HRESULT_TYPEDEF_(0x8004D018L) + +// +// MessageId: XACT_E_ABORTED +// +// MessageText: +// +// The transaction has already been aborted. +// +#define XACT_E_ABORTED _HRESULT_TYPEDEF_(0x8004D019L) + +// +// MessageId: XACT_E_LOGFULL +// +// MessageText: +// +// The Transaction Manager returned a log full error. +// +#define XACT_E_LOGFULL _HRESULT_TYPEDEF_(0x8004D01AL) + +// +// MessageId: XACT_E_TMNOTAVAILABLE +// +// MessageText: +// +// The Transaction Manager is not available. +// +#define XACT_E_TMNOTAVAILABLE _HRESULT_TYPEDEF_(0x8004D01BL) + +// +// MessageId: XACT_E_CONNECTION_DOWN +// +// MessageText: +// +// A connection with the transaction manager was lost. +// +#define XACT_E_CONNECTION_DOWN _HRESULT_TYPEDEF_(0x8004D01CL) + +// +// MessageId: XACT_E_CONNECTION_DENIED +// +// MessageText: +// +// A request to establish a connection with the transaction manager was denied. +// +#define XACT_E_CONNECTION_DENIED _HRESULT_TYPEDEF_(0x8004D01DL) + +// +// MessageId: XACT_E_REENLISTTIMEOUT +// +// MessageText: +// +// Resource manager reenlistment to determine transaction status timed out. +// +#define XACT_E_REENLISTTIMEOUT _HRESULT_TYPEDEF_(0x8004D01EL) + +// +// MessageId: XACT_E_TIP_CONNECT_FAILED +// +// MessageText: +// +// This transaction manager failed to establish a connection with another TIP transaction manager. +// +#define XACT_E_TIP_CONNECT_FAILED _HRESULT_TYPEDEF_(0x8004D01FL) + +// +// MessageId: XACT_E_TIP_PROTOCOL_ERROR +// +// MessageText: +// +// This transaction manager encountered a protocol error with another TIP transaction manager. +// +#define XACT_E_TIP_PROTOCOL_ERROR _HRESULT_TYPEDEF_(0x8004D020L) + +// +// MessageId: XACT_E_TIP_PULL_FAILED +// +// MessageText: +// +// This transaction manager could not propagate a transaction from another TIP transaction manager. +// +#define XACT_E_TIP_PULL_FAILED _HRESULT_TYPEDEF_(0x8004D021L) + +// +// MessageId: XACT_E_DEST_TMNOTAVAILABLE +// +// MessageText: +// +// The Transaction Manager on the destination machine is not available. +// +#define XACT_E_DEST_TMNOTAVAILABLE _HRESULT_TYPEDEF_(0x8004D022L) + +// +// MessageId: XACT_E_TIP_DISABLED +// +// MessageText: +// +// The Transaction Manager has disabled its support for TIP. +// +#define XACT_E_TIP_DISABLED _HRESULT_TYPEDEF_(0x8004D023L) + +// +// MessageId: XACT_E_NETWORK_TX_DISABLED +// +// MessageText: +// +// The transaction manager has disabled its support for remote/network transactions. +// +#define XACT_E_NETWORK_TX_DISABLED _HRESULT_TYPEDEF_(0x8004D024L) + +// +// MessageId: XACT_E_PARTNER_NETWORK_TX_DISABLED +// +// MessageText: +// +// The partner transaction manager has disabled its support for remote/network transactions. +// +#define XACT_E_PARTNER_NETWORK_TX_DISABLED _HRESULT_TYPEDEF_(0x8004D025L) + +// +// MessageId: XACT_E_XA_TX_DISABLED +// +// MessageText: +// +// The transaction manager has disabled its support for XA transactions. +// +#define XACT_E_XA_TX_DISABLED _HRESULT_TYPEDEF_(0x8004D026L) + +// +// MessageId: XACT_E_UNABLE_TO_READ_DTC_CONFIG +// +// MessageText: +// +// MSDTC was unable to read its configuration information. +// +#define XACT_E_UNABLE_TO_READ_DTC_CONFIG _HRESULT_TYPEDEF_(0x8004D027L) + +// +// MessageId: XACT_E_UNABLE_TO_LOAD_DTC_PROXY +// +// MessageText: +// +// MSDTC was unable to load the dtc proxy dll. +// +#define XACT_E_UNABLE_TO_LOAD_DTC_PROXY _HRESULT_TYPEDEF_(0x8004D028L) + +// +// MessageId: XACT_E_ABORTING +// +// MessageText: +// +// The local transaction has aborted. +// +#define XACT_E_ABORTING _HRESULT_TYPEDEF_(0x8004D029L) + +// +// TXF & CRM errors start 4d080. +// +// MessageId: XACT_E_CLERKNOTFOUND +// +// MessageText: +// +// XACT_E_CLERKNOTFOUND +// +#define XACT_E_CLERKNOTFOUND _HRESULT_TYPEDEF_(0x8004D080L) + +// +// MessageId: XACT_E_CLERKEXISTS +// +// MessageText: +// +// XACT_E_CLERKEXISTS +// +#define XACT_E_CLERKEXISTS _HRESULT_TYPEDEF_(0x8004D081L) + +// +// MessageId: XACT_E_RECOVERYINPROGRESS +// +// MessageText: +// +// XACT_E_RECOVERYINPROGRESS +// +#define XACT_E_RECOVERYINPROGRESS _HRESULT_TYPEDEF_(0x8004D082L) + +// +// MessageId: XACT_E_TRANSACTIONCLOSED +// +// MessageText: +// +// XACT_E_TRANSACTIONCLOSED +// +#define XACT_E_TRANSACTIONCLOSED _HRESULT_TYPEDEF_(0x8004D083L) + +// +// MessageId: XACT_E_INVALIDLSN +// +// MessageText: +// +// XACT_E_INVALIDLSN +// +#define XACT_E_INVALIDLSN _HRESULT_TYPEDEF_(0x8004D084L) + +// +// MessageId: XACT_E_REPLAYREQUEST +// +// MessageText: +// +// XACT_E_REPLAYREQUEST +// +#define XACT_E_REPLAYREQUEST _HRESULT_TYPEDEF_(0x8004D085L) + +// +// OleTx Success codes. +// +// +// MessageId: XACT_S_ASYNC +// +// MessageText: +// +// An asynchronous operation was specified. The operation has begun, but its outcome is not known yet. +// +#define XACT_S_ASYNC _HRESULT_TYPEDEF_(0x0004D000L) + +// +// MessageId: XACT_S_DEFECT +// +// MessageText: +// +// XACT_S_DEFECT +// +#define XACT_S_DEFECT _HRESULT_TYPEDEF_(0x0004D001L) + +// +// MessageId: XACT_S_READONLY +// +// MessageText: +// +// The method call succeeded because the transaction was read-only. +// +#define XACT_S_READONLY _HRESULT_TYPEDEF_(0x0004D002L) + +// +// MessageId: XACT_S_SOMENORETAIN +// +// MessageText: +// +// The transaction was successfully aborted. However, this is a coordinated transaction, and some number of enlisted resources were aborted outright because they could not support abort-retaining semantics +// +#define XACT_S_SOMENORETAIN _HRESULT_TYPEDEF_(0x0004D003L) + +// +// MessageId: XACT_S_OKINFORM +// +// MessageText: +// +// No changes were made during this call, but the sink wants another chance to look if any other sinks make further changes. +// +#define XACT_S_OKINFORM _HRESULT_TYPEDEF_(0x0004D004L) + +// +// MessageId: XACT_S_MADECHANGESCONTENT +// +// MessageText: +// +// The sink is content and wishes the transaction to proceed. Changes were made to one or more resources during this call. +// +#define XACT_S_MADECHANGESCONTENT _HRESULT_TYPEDEF_(0x0004D005L) + +// +// MessageId: XACT_S_MADECHANGESINFORM +// +// MessageText: +// +// The sink is for the moment and wishes the transaction to proceed, but if other changes are made following this return by other event sinks then this sink wants another chance to look +// +#define XACT_S_MADECHANGESINFORM _HRESULT_TYPEDEF_(0x0004D006L) + +// +// MessageId: XACT_S_ALLNORETAIN +// +// MessageText: +// +// The transaction was successfully aborted. However, the abort was non-retaining. +// +#define XACT_S_ALLNORETAIN _HRESULT_TYPEDEF_(0x0004D007L) + +// +// MessageId: XACT_S_ABORTING +// +// MessageText: +// +// An abort operation was already in progress. +// +#define XACT_S_ABORTING _HRESULT_TYPEDEF_(0x0004D008L) + +// +// MessageId: XACT_S_SINGLEPHASE +// +// MessageText: +// +// The resource manager has performed a single-phase commit of the transaction. +// +#define XACT_S_SINGLEPHASE _HRESULT_TYPEDEF_(0x0004D009L) + +// +// MessageId: XACT_S_LOCALLY_OK +// +// MessageText: +// +// The local transaction has not aborted. +// +#define XACT_S_LOCALLY_OK _HRESULT_TYPEDEF_(0x0004D00AL) + +// +// MessageId: XACT_S_LASTRESOURCEMANAGER +// +// MessageText: +// +// The resource manager has requested to be the coordinator (last resource manager) for the transaction. +// +#define XACT_S_LASTRESOURCEMANAGER _HRESULT_TYPEDEF_(0x0004D010L) + +#define CONTEXT_E_FIRST 0x8004E000L +#define CONTEXT_E_LAST 0x8004E02FL +#define CONTEXT_S_FIRST 0x0004E000L +#define CONTEXT_S_LAST 0x0004E02FL +// +// MessageId: CONTEXT_E_ABORTED +// +// MessageText: +// +// The root transaction wanted to commit, but transaction aborted +// +#define CONTEXT_E_ABORTED _HRESULT_TYPEDEF_(0x8004E002L) + +// +// MessageId: CONTEXT_E_ABORTING +// +// MessageText: +// +// You made a method call on a COM+ component that has a transaction that has already aborted or in the process of aborting. +// +#define CONTEXT_E_ABORTING _HRESULT_TYPEDEF_(0x8004E003L) + +// +// MessageId: CONTEXT_E_NOCONTEXT +// +// MessageText: +// +// There is no MTS object context +// +#define CONTEXT_E_NOCONTEXT _HRESULT_TYPEDEF_(0x8004E004L) + +// +// MessageId: CONTEXT_E_WOULD_DEADLOCK +// +// MessageText: +// +// The component is configured to use synchronization and this method call would cause a deadlock to occur. +// +#define CONTEXT_E_WOULD_DEADLOCK _HRESULT_TYPEDEF_(0x8004E005L) + +// +// MessageId: CONTEXT_E_SYNCH_TIMEOUT +// +// MessageText: +// +// The component is configured to use synchronization and a thread has timed out waiting to enter the context. +// +#define CONTEXT_E_SYNCH_TIMEOUT _HRESULT_TYPEDEF_(0x8004E006L) + +// +// MessageId: CONTEXT_E_OLDREF +// +// MessageText: +// +// You made a method call on a COM+ component that has a transaction that has already committed or aborted. +// +#define CONTEXT_E_OLDREF _HRESULT_TYPEDEF_(0x8004E007L) + +// +// MessageId: CONTEXT_E_ROLENOTFOUND +// +// MessageText: +// +// The specified role was not configured for the application +// +#define CONTEXT_E_ROLENOTFOUND _HRESULT_TYPEDEF_(0x8004E00CL) + +// +// MessageId: CONTEXT_E_TMNOTAVAILABLE +// +// MessageText: +// +// COM+ was unable to talk to the Microsoft Distributed Transaction Coordinator +// +#define CONTEXT_E_TMNOTAVAILABLE _HRESULT_TYPEDEF_(0x8004E00FL) + +// +// MessageId: CO_E_ACTIVATIONFAILED +// +// MessageText: +// +// An unexpected error occurred during COM+ Activation. +// +#define CO_E_ACTIVATIONFAILED _HRESULT_TYPEDEF_(0x8004E021L) + +// +// MessageId: CO_E_ACTIVATIONFAILED_EVENTLOGGED +// +// MessageText: +// +// COM+ Activation failed. Check the event log for more information +// +#define CO_E_ACTIVATIONFAILED_EVENTLOGGED _HRESULT_TYPEDEF_(0x8004E022L) + +// +// MessageId: CO_E_ACTIVATIONFAILED_CATALOGERROR +// +// MessageText: +// +// COM+ Activation failed due to a catalog or configuration error. +// +#define CO_E_ACTIVATIONFAILED_CATALOGERROR _HRESULT_TYPEDEF_(0x8004E023L) + +// +// MessageId: CO_E_ACTIVATIONFAILED_TIMEOUT +// +// MessageText: +// +// COM+ activation failed because the activation could not be completed in the specified amount of time. +// +#define CO_E_ACTIVATIONFAILED_TIMEOUT _HRESULT_TYPEDEF_(0x8004E024L) + +// +// MessageId: CO_E_INITIALIZATIONFAILED +// +// MessageText: +// +// COM+ Activation failed because an initialization function failed. Check the event log for more information. +// +#define CO_E_INITIALIZATIONFAILED _HRESULT_TYPEDEF_(0x8004E025L) + +// +// MessageId: CONTEXT_E_NOJIT +// +// MessageText: +// +// The requested operation requires that JIT be in the current context and it is not +// +#define CONTEXT_E_NOJIT _HRESULT_TYPEDEF_(0x8004E026L) + +// +// MessageId: CONTEXT_E_NOTRANSACTION +// +// MessageText: +// +// The requested operation requires that the current context have a Transaction, and it does not +// +#define CONTEXT_E_NOTRANSACTION _HRESULT_TYPEDEF_(0x8004E027L) + +// +// MessageId: CO_E_THREADINGMODEL_CHANGED +// +// MessageText: +// +// The components threading model has changed after install into a COM+ Application. Please re-install component. +// +#define CO_E_THREADINGMODEL_CHANGED _HRESULT_TYPEDEF_(0x8004E028L) + +// +// MessageId: CO_E_NOIISINTRINSICS +// +// MessageText: +// +// IIS intrinsics not available. Start your work with IIS. +// +#define CO_E_NOIISINTRINSICS _HRESULT_TYPEDEF_(0x8004E029L) + +// +// MessageId: CO_E_NOCOOKIES +// +// MessageText: +// +// An attempt to write a cookie failed. +// +#define CO_E_NOCOOKIES _HRESULT_TYPEDEF_(0x8004E02AL) + +// +// MessageId: CO_E_DBERROR +// +// MessageText: +// +// An attempt to use a database generated a database specific error. +// +#define CO_E_DBERROR _HRESULT_TYPEDEF_(0x8004E02BL) + +// +// MessageId: CO_E_NOTPOOLED +// +// MessageText: +// +// The COM+ component you created must use object pooling to work. +// +#define CO_E_NOTPOOLED _HRESULT_TYPEDEF_(0x8004E02CL) + +// +// MessageId: CO_E_NOTCONSTRUCTED +// +// MessageText: +// +// The COM+ component you created must use object construction to work correctly. +// +#define CO_E_NOTCONSTRUCTED _HRESULT_TYPEDEF_(0x8004E02DL) + +// +// MessageId: CO_E_NOSYNCHRONIZATION +// +// MessageText: +// +// The COM+ component requires synchronization, and it is not configured for it. +// +#define CO_E_NOSYNCHRONIZATION _HRESULT_TYPEDEF_(0x8004E02EL) + +// +// MessageId: CO_E_ISOLEVELMISMATCH +// +// MessageText: +// +// The TxIsolation Level property for the COM+ component being created is stronger than the TxIsolationLevel for the "root" component for the transaction. The creation failed. +// +#define CO_E_ISOLEVELMISMATCH _HRESULT_TYPEDEF_(0x8004E02FL) + +// +// Old OLE Success Codes +// +// +// MessageId: OLE_S_USEREG +// +// MessageText: +// +// Use the registry database to provide the requested information +// +#define OLE_S_USEREG _HRESULT_TYPEDEF_(0x00040000L) + +// +// MessageId: OLE_S_STATIC +// +// MessageText: +// +// Success, but static +// +#define OLE_S_STATIC _HRESULT_TYPEDEF_(0x00040001L) + +// +// MessageId: OLE_S_MAC_CLIPFORMAT +// +// MessageText: +// +// Macintosh clipboard format +// +#define OLE_S_MAC_CLIPFORMAT _HRESULT_TYPEDEF_(0x00040002L) + +// +// MessageId: DRAGDROP_S_DROP +// +// MessageText: +// +// Successful drop took place +// +#define DRAGDROP_S_DROP _HRESULT_TYPEDEF_(0x00040100L) + +// +// MessageId: DRAGDROP_S_CANCEL +// +// MessageText: +// +// Drag-drop operation canceled +// +#define DRAGDROP_S_CANCEL _HRESULT_TYPEDEF_(0x00040101L) + +// +// MessageId: DRAGDROP_S_USEDEFAULTCURSORS +// +// MessageText: +// +// Use the default cursor +// +#define DRAGDROP_S_USEDEFAULTCURSORS _HRESULT_TYPEDEF_(0x00040102L) + +// +// MessageId: DATA_S_SAMEFORMATETC +// +// MessageText: +// +// Data has same FORMATETC +// +#define DATA_S_SAMEFORMATETC _HRESULT_TYPEDEF_(0x00040130L) + +// +// MessageId: VIEW_S_ALREADY_FROZEN +// +// MessageText: +// +// View is already frozen +// +#define VIEW_S_ALREADY_FROZEN _HRESULT_TYPEDEF_(0x00040140L) + +// +// MessageId: CACHE_S_FORMATETC_NOTSUPPORTED +// +// MessageText: +// +// FORMATETC not supported +// +#define CACHE_S_FORMATETC_NOTSUPPORTED _HRESULT_TYPEDEF_(0x00040170L) + +// +// MessageId: CACHE_S_SAMECACHE +// +// MessageText: +// +// Same cache +// +#define CACHE_S_SAMECACHE _HRESULT_TYPEDEF_(0x00040171L) + +// +// MessageId: CACHE_S_SOMECACHES_NOTUPDATED +// +// MessageText: +// +// Some cache(s) not updated +// +#define CACHE_S_SOMECACHES_NOTUPDATED _HRESULT_TYPEDEF_(0x00040172L) + +// +// MessageId: OLEOBJ_S_INVALIDVERB +// +// MessageText: +// +// Invalid verb for OLE object +// +#define OLEOBJ_S_INVALIDVERB _HRESULT_TYPEDEF_(0x00040180L) + +// +// MessageId: OLEOBJ_S_CANNOT_DOVERB_NOW +// +// MessageText: +// +// Verb number is valid but verb cannot be done now +// +#define OLEOBJ_S_CANNOT_DOVERB_NOW _HRESULT_TYPEDEF_(0x00040181L) + +// +// MessageId: OLEOBJ_S_INVALIDHWND +// +// MessageText: +// +// Invalid window handle passed +// +#define OLEOBJ_S_INVALIDHWND _HRESULT_TYPEDEF_(0x00040182L) + +// +// MessageId: INPLACE_S_TRUNCATED +// +// MessageText: +// +// Message is too long; some of it had to be truncated before displaying +// +#define INPLACE_S_TRUNCATED _HRESULT_TYPEDEF_(0x000401A0L) + +// +// MessageId: CONVERT10_S_NO_PRESENTATION +// +// MessageText: +// +// Unable to convert OLESTREAM to IStorage +// +#define CONVERT10_S_NO_PRESENTATION _HRESULT_TYPEDEF_(0x000401C0L) + +// +// MessageId: MK_S_REDUCED_TO_SELF +// +// MessageText: +// +// Moniker reduced to itself +// +#define MK_S_REDUCED_TO_SELF _HRESULT_TYPEDEF_(0x000401E2L) + +// +// MessageId: MK_S_ME +// +// MessageText: +// +// Common prefix is this moniker +// +#define MK_S_ME _HRESULT_TYPEDEF_(0x000401E4L) + +// +// MessageId: MK_S_HIM +// +// MessageText: +// +// Common prefix is input moniker +// +#define MK_S_HIM _HRESULT_TYPEDEF_(0x000401E5L) + +// +// MessageId: MK_S_US +// +// MessageText: +// +// Common prefix is both monikers +// +#define MK_S_US _HRESULT_TYPEDEF_(0x000401E6L) + +// +// MessageId: MK_S_MONIKERALREADYREGISTERED +// +// MessageText: +// +// Moniker is already registered in running object table +// +#define MK_S_MONIKERALREADYREGISTERED _HRESULT_TYPEDEF_(0x000401E7L) + +// +// Task Scheduler errors +// +// +// MessageId: SCHED_S_TASK_READY +// +// MessageText: +// +// The task is ready to run at its next scheduled time. +// +#define SCHED_S_TASK_READY _HRESULT_TYPEDEF_(0x00041300L) + +// +// MessageId: SCHED_S_TASK_RUNNING +// +// MessageText: +// +// The task is currently running. +// +#define SCHED_S_TASK_RUNNING _HRESULT_TYPEDEF_(0x00041301L) + +// +// MessageId: SCHED_S_TASK_DISABLED +// +// MessageText: +// +// The task will not run at the scheduled times because it has been disabled. +// +#define SCHED_S_TASK_DISABLED _HRESULT_TYPEDEF_(0x00041302L) + +// +// MessageId: SCHED_S_TASK_HAS_NOT_RUN +// +// MessageText: +// +// The task has not yet run. +// +#define SCHED_S_TASK_HAS_NOT_RUN _HRESULT_TYPEDEF_(0x00041303L) + +// +// MessageId: SCHED_S_TASK_NO_MORE_RUNS +// +// MessageText: +// +// There are no more runs scheduled for this task. +// +#define SCHED_S_TASK_NO_MORE_RUNS _HRESULT_TYPEDEF_(0x00041304L) + +// +// MessageId: SCHED_S_TASK_NOT_SCHEDULED +// +// MessageText: +// +// One or more of the properties that are needed to run this task on a schedule have not been set. +// +#define SCHED_S_TASK_NOT_SCHEDULED _HRESULT_TYPEDEF_(0x00041305L) + +// +// MessageId: SCHED_S_TASK_TERMINATED +// +// MessageText: +// +// The last run of the task was terminated by the user. +// +#define SCHED_S_TASK_TERMINATED _HRESULT_TYPEDEF_(0x00041306L) + +// +// MessageId: SCHED_S_TASK_NO_VALID_TRIGGERS +// +// MessageText: +// +// Either the task has no triggers or the existing triggers are disabled or not set. +// +#define SCHED_S_TASK_NO_VALID_TRIGGERS _HRESULT_TYPEDEF_(0x00041307L) + +// +// MessageId: SCHED_S_EVENT_TRIGGER +// +// MessageText: +// +// Event triggers don't have set run times. +// +#define SCHED_S_EVENT_TRIGGER _HRESULT_TYPEDEF_(0x00041308L) + +// +// MessageId: SCHED_E_TRIGGER_NOT_FOUND +// +// MessageText: +// +// Trigger not found. +// +#define SCHED_E_TRIGGER_NOT_FOUND _HRESULT_TYPEDEF_(0x80041309L) + +// +// MessageId: SCHED_E_TASK_NOT_READY +// +// MessageText: +// +// One or more of the properties that are needed to run this task have not been set. +// +#define SCHED_E_TASK_NOT_READY _HRESULT_TYPEDEF_(0x8004130AL) + +// +// MessageId: SCHED_E_TASK_NOT_RUNNING +// +// MessageText: +// +// There is no running instance of the task to terminate. +// +#define SCHED_E_TASK_NOT_RUNNING _HRESULT_TYPEDEF_(0x8004130BL) + +// +// MessageId: SCHED_E_SERVICE_NOT_INSTALLED +// +// MessageText: +// +// The Task Scheduler Service is not installed on this computer. +// +#define SCHED_E_SERVICE_NOT_INSTALLED _HRESULT_TYPEDEF_(0x8004130CL) + +// +// MessageId: SCHED_E_CANNOT_OPEN_TASK +// +// MessageText: +// +// The task object could not be opened. +// +#define SCHED_E_CANNOT_OPEN_TASK _HRESULT_TYPEDEF_(0x8004130DL) + +// +// MessageId: SCHED_E_INVALID_TASK +// +// MessageText: +// +// The object is either an invalid task object or is not a task object. +// +#define SCHED_E_INVALID_TASK _HRESULT_TYPEDEF_(0x8004130EL) + +// +// MessageId: SCHED_E_ACCOUNT_INFORMATION_NOT_SET +// +// MessageText: +// +// No account information could be found in the Task Scheduler security database for the task indicated. +// +#define SCHED_E_ACCOUNT_INFORMATION_NOT_SET _HRESULT_TYPEDEF_(0x8004130FL) + +// +// MessageId: SCHED_E_ACCOUNT_NAME_NOT_FOUND +// +// MessageText: +// +// Unable to establish existence of the account specified. +// +#define SCHED_E_ACCOUNT_NAME_NOT_FOUND _HRESULT_TYPEDEF_(0x80041310L) + +// +// MessageId: SCHED_E_ACCOUNT_DBASE_CORRUPT +// +// MessageText: +// +// Corruption was detected in the Task Scheduler security database; the database has been reset. +// +#define SCHED_E_ACCOUNT_DBASE_CORRUPT _HRESULT_TYPEDEF_(0x80041311L) + +// +// MessageId: SCHED_E_NO_SECURITY_SERVICES +// +// MessageText: +// +// Task Scheduler security services are available only on Windows NT. +// +#define SCHED_E_NO_SECURITY_SERVICES _HRESULT_TYPEDEF_(0x80041312L) + +// +// MessageId: SCHED_E_UNKNOWN_OBJECT_VERSION +// +// MessageText: +// +// The task object version is either unsupported or invalid. +// +#define SCHED_E_UNKNOWN_OBJECT_VERSION _HRESULT_TYPEDEF_(0x80041313L) + +// +// MessageId: SCHED_E_UNSUPPORTED_ACCOUNT_OPTION +// +// MessageText: +// +// The task has been configured with an unsupported combination of account settings and run time options. +// +#define SCHED_E_UNSUPPORTED_ACCOUNT_OPTION _HRESULT_TYPEDEF_(0x80041314L) + +// +// MessageId: SCHED_E_SERVICE_NOT_RUNNING +// +// MessageText: +// +// The Task Scheduler Service is not running. +// +#define SCHED_E_SERVICE_NOT_RUNNING _HRESULT_TYPEDEF_(0x80041315L) + +// ****************** +// FACILITY_WINDOWS +// ****************** +// +// Codes 0x0-0x01ff are reserved for the OLE group of +// interfaces. +// +// +// MessageId: CO_E_CLASS_CREATE_FAILED +// +// MessageText: +// +// Attempt to create a class object failed +// +#define CO_E_CLASS_CREATE_FAILED _HRESULT_TYPEDEF_(0x80080001L) + +// +// MessageId: CO_E_SCM_ERROR +// +// MessageText: +// +// OLE service could not bind object +// +#define CO_E_SCM_ERROR _HRESULT_TYPEDEF_(0x80080002L) + +// +// MessageId: CO_E_SCM_RPC_FAILURE +// +// MessageText: +// +// RPC communication failed with OLE service +// +#define CO_E_SCM_RPC_FAILURE _HRESULT_TYPEDEF_(0x80080003L) + +// +// MessageId: CO_E_BAD_PATH +// +// MessageText: +// +// Bad path to object +// +#define CO_E_BAD_PATH _HRESULT_TYPEDEF_(0x80080004L) + +// +// MessageId: CO_E_SERVER_EXEC_FAILURE +// +// MessageText: +// +// Server execution failed +// +#define CO_E_SERVER_EXEC_FAILURE _HRESULT_TYPEDEF_(0x80080005L) + +// +// MessageId: CO_E_OBJSRV_RPC_FAILURE +// +// MessageText: +// +// OLE service could not communicate with the object server +// +#define CO_E_OBJSRV_RPC_FAILURE _HRESULT_TYPEDEF_(0x80080006L) + +// +// MessageId: MK_E_NO_NORMALIZED +// +// MessageText: +// +// Moniker path could not be normalized +// +#define MK_E_NO_NORMALIZED _HRESULT_TYPEDEF_(0x80080007L) + +// +// MessageId: CO_E_SERVER_STOPPING +// +// MessageText: +// +// Object server is stopping when OLE service contacts it +// +#define CO_E_SERVER_STOPPING _HRESULT_TYPEDEF_(0x80080008L) + +// +// MessageId: MEM_E_INVALID_ROOT +// +// MessageText: +// +// An invalid root block pointer was specified +// +#define MEM_E_INVALID_ROOT _HRESULT_TYPEDEF_(0x80080009L) + +// +// MessageId: MEM_E_INVALID_LINK +// +// MessageText: +// +// An allocation chain contained an invalid link pointer +// +#define MEM_E_INVALID_LINK _HRESULT_TYPEDEF_(0x80080010L) + +// +// MessageId: MEM_E_INVALID_SIZE +// +// MessageText: +// +// The requested allocation size was too large +// +#define MEM_E_INVALID_SIZE _HRESULT_TYPEDEF_(0x80080011L) + +// +// MessageId: CO_S_NOTALLINTERFACES +// +// MessageText: +// +// Not all the requested interfaces were available +// +#define CO_S_NOTALLINTERFACES _HRESULT_TYPEDEF_(0x00080012L) + +// +// MessageId: CO_S_MACHINENAMENOTFOUND +// +// MessageText: +// +// The specified machine name was not found in the cache. +// +#define CO_S_MACHINENAMENOTFOUND _HRESULT_TYPEDEF_(0x00080013L) + +// ****************** +// FACILITY_DISPATCH +// ****************** +// +// MessageId: DISP_E_UNKNOWNINTERFACE +// +// MessageText: +// +// Unknown interface. +// +#define DISP_E_UNKNOWNINTERFACE _HRESULT_TYPEDEF_(0x80020001L) + +// +// MessageId: DISP_E_MEMBERNOTFOUND +// +// MessageText: +// +// Member not found. +// +#define DISP_E_MEMBERNOTFOUND _HRESULT_TYPEDEF_(0x80020003L) + +// +// MessageId: DISP_E_PARAMNOTFOUND +// +// MessageText: +// +// Parameter not found. +// +#define DISP_E_PARAMNOTFOUND _HRESULT_TYPEDEF_(0x80020004L) + +// +// MessageId: DISP_E_TYPEMISMATCH +// +// MessageText: +// +// Type mismatch. +// +#define DISP_E_TYPEMISMATCH _HRESULT_TYPEDEF_(0x80020005L) + +// +// MessageId: DISP_E_UNKNOWNNAME +// +// MessageText: +// +// Unknown name. +// +#define DISP_E_UNKNOWNNAME _HRESULT_TYPEDEF_(0x80020006L) + +// +// MessageId: DISP_E_NONAMEDARGS +// +// MessageText: +// +// No named arguments. +// +#define DISP_E_NONAMEDARGS _HRESULT_TYPEDEF_(0x80020007L) + +// +// MessageId: DISP_E_BADVARTYPE +// +// MessageText: +// +// Bad variable type. +// +#define DISP_E_BADVARTYPE _HRESULT_TYPEDEF_(0x80020008L) + +// +// MessageId: DISP_E_EXCEPTION +// +// MessageText: +// +// Exception occurred. +// +#define DISP_E_EXCEPTION _HRESULT_TYPEDEF_(0x80020009L) + +// +// MessageId: DISP_E_OVERFLOW +// +// MessageText: +// +// Out of present range. +// +#define DISP_E_OVERFLOW _HRESULT_TYPEDEF_(0x8002000AL) + +// +// MessageId: DISP_E_BADINDEX +// +// MessageText: +// +// Invalid index. +// +#define DISP_E_BADINDEX _HRESULT_TYPEDEF_(0x8002000BL) + +// +// MessageId: DISP_E_UNKNOWNLCID +// +// MessageText: +// +// Unknown language. +// +#define DISP_E_UNKNOWNLCID _HRESULT_TYPEDEF_(0x8002000CL) + +// +// MessageId: DISP_E_ARRAYISLOCKED +// +// MessageText: +// +// Memory is locked. +// +#define DISP_E_ARRAYISLOCKED _HRESULT_TYPEDEF_(0x8002000DL) + +// +// MessageId: DISP_E_BADPARAMCOUNT +// +// MessageText: +// +// Invalid number of parameters. +// +#define DISP_E_BADPARAMCOUNT _HRESULT_TYPEDEF_(0x8002000EL) + +// +// MessageId: DISP_E_PARAMNOTOPTIONAL +// +// MessageText: +// +// Parameter not optional. +// +#define DISP_E_PARAMNOTOPTIONAL _HRESULT_TYPEDEF_(0x8002000FL) + +// +// MessageId: DISP_E_BADCALLEE +// +// MessageText: +// +// Invalid callee. +// +#define DISP_E_BADCALLEE _HRESULT_TYPEDEF_(0x80020010L) + +// +// MessageId: DISP_E_NOTACOLLECTION +// +// MessageText: +// +// Does not support a collection. +// +#define DISP_E_NOTACOLLECTION _HRESULT_TYPEDEF_(0x80020011L) + +// +// MessageId: DISP_E_DIVBYZERO +// +// MessageText: +// +// Division by zero. +// +#define DISP_E_DIVBYZERO _HRESULT_TYPEDEF_(0x80020012L) + +// +// MessageId: DISP_E_BUFFERTOOSMALL +// +// MessageText: +// +// Buffer too small +// +#define DISP_E_BUFFERTOOSMALL _HRESULT_TYPEDEF_(0x80020013L) + +// +// MessageId: TYPE_E_BUFFERTOOSMALL +// +// MessageText: +// +// Buffer too small. +// +#define TYPE_E_BUFFERTOOSMALL _HRESULT_TYPEDEF_(0x80028016L) + +// +// MessageId: TYPE_E_FIELDNOTFOUND +// +// MessageText: +// +// Field name not defined in the record. +// +#define TYPE_E_FIELDNOTFOUND _HRESULT_TYPEDEF_(0x80028017L) + +// +// MessageId: TYPE_E_INVDATAREAD +// +// MessageText: +// +// Old format or invalid type library. +// +#define TYPE_E_INVDATAREAD _HRESULT_TYPEDEF_(0x80028018L) + +// +// MessageId: TYPE_E_UNSUPFORMAT +// +// MessageText: +// +// Old format or invalid type library. +// +#define TYPE_E_UNSUPFORMAT _HRESULT_TYPEDEF_(0x80028019L) + +// +// MessageId: TYPE_E_REGISTRYACCESS +// +// MessageText: +// +// Error accessing the OLE registry. +// +#define TYPE_E_REGISTRYACCESS _HRESULT_TYPEDEF_(0x8002801CL) + +// +// MessageId: TYPE_E_LIBNOTREGISTERED +// +// MessageText: +// +// Library not registered. +// +#define TYPE_E_LIBNOTREGISTERED _HRESULT_TYPEDEF_(0x8002801DL) + +// +// MessageId: TYPE_E_UNDEFINEDTYPE +// +// MessageText: +// +// Bound to unknown type. +// +#define TYPE_E_UNDEFINEDTYPE _HRESULT_TYPEDEF_(0x80028027L) + +// +// MessageId: TYPE_E_QUALIFIEDNAMEDISALLOWED +// +// MessageText: +// +// Qualified name disallowed. +// +#define TYPE_E_QUALIFIEDNAMEDISALLOWED _HRESULT_TYPEDEF_(0x80028028L) + +// +// MessageId: TYPE_E_INVALIDSTATE +// +// MessageText: +// +// Invalid forward reference, or reference to uncompiled type. +// +#define TYPE_E_INVALIDSTATE _HRESULT_TYPEDEF_(0x80028029L) + +// +// MessageId: TYPE_E_WRONGTYPEKIND +// +// MessageText: +// +// Type mismatch. +// +#define TYPE_E_WRONGTYPEKIND _HRESULT_TYPEDEF_(0x8002802AL) + +// +// MessageId: TYPE_E_ELEMENTNOTFOUND +// +// MessageText: +// +// Element not found. +// +#define TYPE_E_ELEMENTNOTFOUND _HRESULT_TYPEDEF_(0x8002802BL) + +// +// MessageId: TYPE_E_AMBIGUOUSNAME +// +// MessageText: +// +// Ambiguous name. +// +#define TYPE_E_AMBIGUOUSNAME _HRESULT_TYPEDEF_(0x8002802CL) + +// +// MessageId: TYPE_E_NAMECONFLICT +// +// MessageText: +// +// Name already exists in the library. +// +#define TYPE_E_NAMECONFLICT _HRESULT_TYPEDEF_(0x8002802DL) + +// +// MessageId: TYPE_E_UNKNOWNLCID +// +// MessageText: +// +// Unknown LCID. +// +#define TYPE_E_UNKNOWNLCID _HRESULT_TYPEDEF_(0x8002802EL) + +// +// MessageId: TYPE_E_DLLFUNCTIONNOTFOUND +// +// MessageText: +// +// Function not defined in specified DLL. +// +#define TYPE_E_DLLFUNCTIONNOTFOUND _HRESULT_TYPEDEF_(0x8002802FL) + +// +// MessageId: TYPE_E_BADMODULEKIND +// +// MessageText: +// +// Wrong module kind for the operation. +// +#define TYPE_E_BADMODULEKIND _HRESULT_TYPEDEF_(0x800288BDL) + +// +// MessageId: TYPE_E_SIZETOOBIG +// +// MessageText: +// +// Size may not exceed 64K. +// +#define TYPE_E_SIZETOOBIG _HRESULT_TYPEDEF_(0x800288C5L) + +// +// MessageId: TYPE_E_DUPLICATEID +// +// MessageText: +// +// Duplicate ID in inheritance hierarchy. +// +#define TYPE_E_DUPLICATEID _HRESULT_TYPEDEF_(0x800288C6L) + +// +// MessageId: TYPE_E_INVALIDID +// +// MessageText: +// +// Incorrect inheritance depth in standard OLE hmember. +// +#define TYPE_E_INVALIDID _HRESULT_TYPEDEF_(0x800288CFL) + +// +// MessageId: TYPE_E_TYPEMISMATCH +// +// MessageText: +// +// Type mismatch. +// +#define TYPE_E_TYPEMISMATCH _HRESULT_TYPEDEF_(0x80028CA0L) + +// +// MessageId: TYPE_E_OUTOFBOUNDS +// +// MessageText: +// +// Invalid number of arguments. +// +#define TYPE_E_OUTOFBOUNDS _HRESULT_TYPEDEF_(0x80028CA1L) + +// +// MessageId: TYPE_E_IOERROR +// +// MessageText: +// +// I/O Error. +// +#define TYPE_E_IOERROR _HRESULT_TYPEDEF_(0x80028CA2L) + +// +// MessageId: TYPE_E_CANTCREATETMPFILE +// +// MessageText: +// +// Error creating unique tmp file. +// +#define TYPE_E_CANTCREATETMPFILE _HRESULT_TYPEDEF_(0x80028CA3L) + +// +// MessageId: TYPE_E_CANTLOADLIBRARY +// +// MessageText: +// +// Error loading type library/DLL. +// +#define TYPE_E_CANTLOADLIBRARY _HRESULT_TYPEDEF_(0x80029C4AL) + +// +// MessageId: TYPE_E_INCONSISTENTPROPFUNCS +// +// MessageText: +// +// Inconsistent property functions. +// +#define TYPE_E_INCONSISTENTPROPFUNCS _HRESULT_TYPEDEF_(0x80029C83L) + +// +// MessageId: TYPE_E_CIRCULARTYPE +// +// MessageText: +// +// Circular dependency between types/modules. +// +#define TYPE_E_CIRCULARTYPE _HRESULT_TYPEDEF_(0x80029C84L) + +// ****************** +// FACILITY_STORAGE +// ****************** +// +// MessageId: STG_E_INVALIDFUNCTION +// +// MessageText: +// +// Unable to perform requested operation. +// +#define STG_E_INVALIDFUNCTION _HRESULT_TYPEDEF_(0x80030001L) + +// +// MessageId: STG_E_FILENOTFOUND +// +// MessageText: +// +// %1 could not be found. +// +#define STG_E_FILENOTFOUND _HRESULT_TYPEDEF_(0x80030002L) + +// +// MessageId: STG_E_PATHNOTFOUND +// +// MessageText: +// +// The path %1 could not be found. +// +#define STG_E_PATHNOTFOUND _HRESULT_TYPEDEF_(0x80030003L) + +// +// MessageId: STG_E_TOOMANYOPENFILES +// +// MessageText: +// +// There are insufficient resources to open another file. +// +#define STG_E_TOOMANYOPENFILES _HRESULT_TYPEDEF_(0x80030004L) + +// +// MessageId: STG_E_ACCESSDENIED +// +// MessageText: +// +// Access Denied. +// +#define STG_E_ACCESSDENIED _HRESULT_TYPEDEF_(0x80030005L) + +// +// MessageId: STG_E_INVALIDHANDLE +// +// MessageText: +// +// Attempted an operation on an invalid object. +// +#define STG_E_INVALIDHANDLE _HRESULT_TYPEDEF_(0x80030006L) + +// +// MessageId: STG_E_INSUFFICIENTMEMORY +// +// MessageText: +// +// There is insufficient memory available to complete operation. +// +#define STG_E_INSUFFICIENTMEMORY _HRESULT_TYPEDEF_(0x80030008L) + +// +// MessageId: STG_E_INVALIDPOINTER +// +// MessageText: +// +// Invalid pointer error. +// +#define STG_E_INVALIDPOINTER _HRESULT_TYPEDEF_(0x80030009L) + +// +// MessageId: STG_E_NOMOREFILES +// +// MessageText: +// +// There are no more entries to return. +// +#define STG_E_NOMOREFILES _HRESULT_TYPEDEF_(0x80030012L) + +// +// MessageId: STG_E_DISKISWRITEPROTECTED +// +// MessageText: +// +// Disk is write-protected. +// +#define STG_E_DISKISWRITEPROTECTED _HRESULT_TYPEDEF_(0x80030013L) + +// +// MessageId: STG_E_SEEKERROR +// +// MessageText: +// +// An error occurred during a seek operation. +// +#define STG_E_SEEKERROR _HRESULT_TYPEDEF_(0x80030019L) + +// +// MessageId: STG_E_WRITEFAULT +// +// MessageText: +// +// A disk error occurred during a write operation. +// +#define STG_E_WRITEFAULT _HRESULT_TYPEDEF_(0x8003001DL) + +// +// MessageId: STG_E_READFAULT +// +// MessageText: +// +// A disk error occurred during a read operation. +// +#define STG_E_READFAULT _HRESULT_TYPEDEF_(0x8003001EL) + +// +// MessageId: STG_E_SHAREVIOLATION +// +// MessageText: +// +// A share violation has occurred. +// +#define STG_E_SHAREVIOLATION _HRESULT_TYPEDEF_(0x80030020L) + +// +// MessageId: STG_E_LOCKVIOLATION +// +// MessageText: +// +// A lock violation has occurred. +// +#define STG_E_LOCKVIOLATION _HRESULT_TYPEDEF_(0x80030021L) + +// +// MessageId: STG_E_FILEALREADYEXISTS +// +// MessageText: +// +// %1 already exists. +// +#define STG_E_FILEALREADYEXISTS _HRESULT_TYPEDEF_(0x80030050L) + +// +// MessageId: STG_E_INVALIDPARAMETER +// +// MessageText: +// +// Invalid parameter error. +// +#define STG_E_INVALIDPARAMETER _HRESULT_TYPEDEF_(0x80030057L) + +// +// MessageId: STG_E_MEDIUMFULL +// +// MessageText: +// +// There is insufficient disk space to complete operation. +// +#define STG_E_MEDIUMFULL _HRESULT_TYPEDEF_(0x80030070L) + +// +// MessageId: STG_E_PROPSETMISMATCHED +// +// MessageText: +// +// Illegal write of non-simple property to simple property set. +// +#define STG_E_PROPSETMISMATCHED _HRESULT_TYPEDEF_(0x800300F0L) + +// +// MessageId: STG_E_ABNORMALAPIEXIT +// +// MessageText: +// +// An API call exited abnormally. +// +#define STG_E_ABNORMALAPIEXIT _HRESULT_TYPEDEF_(0x800300FAL) + +// +// MessageId: STG_E_INVALIDHEADER +// +// MessageText: +// +// The file %1 is not a valid compound file. +// +#define STG_E_INVALIDHEADER _HRESULT_TYPEDEF_(0x800300FBL) + +// +// MessageId: STG_E_INVALIDNAME +// +// MessageText: +// +// The name %1 is not valid. +// +#define STG_E_INVALIDNAME _HRESULT_TYPEDEF_(0x800300FCL) + +// +// MessageId: STG_E_UNKNOWN +// +// MessageText: +// +// An unexpected error occurred. +// +#define STG_E_UNKNOWN _HRESULT_TYPEDEF_(0x800300FDL) + +// +// MessageId: STG_E_UNIMPLEMENTEDFUNCTION +// +// MessageText: +// +// That function is not implemented. +// +#define STG_E_UNIMPLEMENTEDFUNCTION _HRESULT_TYPEDEF_(0x800300FEL) + +// +// MessageId: STG_E_INVALIDFLAG +// +// MessageText: +// +// Invalid flag error. +// +#define STG_E_INVALIDFLAG _HRESULT_TYPEDEF_(0x800300FFL) + +// +// MessageId: STG_E_INUSE +// +// MessageText: +// +// Attempted to use an object that is busy. +// +#define STG_E_INUSE _HRESULT_TYPEDEF_(0x80030100L) + +// +// MessageId: STG_E_NOTCURRENT +// +// MessageText: +// +// The storage has been changed since the last commit. +// +#define STG_E_NOTCURRENT _HRESULT_TYPEDEF_(0x80030101L) + +// +// MessageId: STG_E_REVERTED +// +// MessageText: +// +// Attempted to use an object that has ceased to exist. +// +#define STG_E_REVERTED _HRESULT_TYPEDEF_(0x80030102L) + +// +// MessageId: STG_E_CANTSAVE +// +// MessageText: +// +// Can't save. +// +#define STG_E_CANTSAVE _HRESULT_TYPEDEF_(0x80030103L) + +// +// MessageId: STG_E_OLDFORMAT +// +// MessageText: +// +// The compound file %1 was produced with an incompatible version of storage. +// +#define STG_E_OLDFORMAT _HRESULT_TYPEDEF_(0x80030104L) + +// +// MessageId: STG_E_OLDDLL +// +// MessageText: +// +// The compound file %1 was produced with a newer version of storage. +// +#define STG_E_OLDDLL _HRESULT_TYPEDEF_(0x80030105L) + +// +// MessageId: STG_E_SHAREREQUIRED +// +// MessageText: +// +// Share.exe or equivalent is required for operation. +// +#define STG_E_SHAREREQUIRED _HRESULT_TYPEDEF_(0x80030106L) + +// +// MessageId: STG_E_NOTFILEBASEDSTORAGE +// +// MessageText: +// +// Illegal operation called on non-file based storage. +// +#define STG_E_NOTFILEBASEDSTORAGE _HRESULT_TYPEDEF_(0x80030107L) + +// +// MessageId: STG_E_EXTANTMARSHALLINGS +// +// MessageText: +// +// Illegal operation called on object with extant marshallings. +// +#define STG_E_EXTANTMARSHALLINGS _HRESULT_TYPEDEF_(0x80030108L) + +// +// MessageId: STG_E_DOCFILECORRUPT +// +// MessageText: +// +// The docfile has been corrupted. +// +#define STG_E_DOCFILECORRUPT _HRESULT_TYPEDEF_(0x80030109L) + +// +// MessageId: STG_E_BADBASEADDRESS +// +// MessageText: +// +// OLE32.DLL has been loaded at the wrong address. +// +#define STG_E_BADBASEADDRESS _HRESULT_TYPEDEF_(0x80030110L) + +// +// MessageId: STG_E_DOCFILETOOLARGE +// +// MessageText: +// +// The compound file is too large for the current implementation +// +#define STG_E_DOCFILETOOLARGE _HRESULT_TYPEDEF_(0x80030111L) + +// +// MessageId: STG_E_NOTSIMPLEFORMAT +// +// MessageText: +// +// The compound file was not created with the STGM_SIMPLE flag +// +#define STG_E_NOTSIMPLEFORMAT _HRESULT_TYPEDEF_(0x80030112L) + +// +// MessageId: STG_E_INCOMPLETE +// +// MessageText: +// +// The file download was aborted abnormally. The file is incomplete. +// +#define STG_E_INCOMPLETE _HRESULT_TYPEDEF_(0x80030201L) + +// +// MessageId: STG_E_TERMINATED +// +// MessageText: +// +// The file download has been terminated. +// +#define STG_E_TERMINATED _HRESULT_TYPEDEF_(0x80030202L) + +// +// MessageId: STG_S_CONVERTED +// +// MessageText: +// +// The underlying file was converted to compound file format. +// +#define STG_S_CONVERTED _HRESULT_TYPEDEF_(0x00030200L) + +// +// MessageId: STG_S_BLOCK +// +// MessageText: +// +// The storage operation should block until more data is available. +// +#define STG_S_BLOCK _HRESULT_TYPEDEF_(0x00030201L) + +// +// MessageId: STG_S_RETRYNOW +// +// MessageText: +// +// The storage operation should retry immediately. +// +#define STG_S_RETRYNOW _HRESULT_TYPEDEF_(0x00030202L) + +// +// MessageId: STG_S_MONITORING +// +// MessageText: +// +// The notified event sink will not influence the storage operation. +// +#define STG_S_MONITORING _HRESULT_TYPEDEF_(0x00030203L) + +// +// MessageId: STG_S_MULTIPLEOPENS +// +// MessageText: +// +// Multiple opens prevent consolidated. (commit succeeded). +// +#define STG_S_MULTIPLEOPENS _HRESULT_TYPEDEF_(0x00030204L) + +// +// MessageId: STG_S_CONSOLIDATIONFAILED +// +// MessageText: +// +// Consolidation of the storage file failed. (commit succeeded). +// +#define STG_S_CONSOLIDATIONFAILED _HRESULT_TYPEDEF_(0x00030205L) + +// +// MessageId: STG_S_CANNOTCONSOLIDATE +// +// MessageText: +// +// Consolidation of the storage file is inappropriate. (commit succeeded). +// +#define STG_S_CANNOTCONSOLIDATE _HRESULT_TYPEDEF_(0x00030206L) + +/*++ + + MessageId's 0x0305 - 0x031f (inclusive) are reserved for **STORAGE** + copy protection errors. + +--*/ +// +// MessageId: STG_E_STATUS_COPY_PROTECTION_FAILURE +// +// MessageText: +// +// Generic Copy Protection Error. +// +#define STG_E_STATUS_COPY_PROTECTION_FAILURE _HRESULT_TYPEDEF_(0x80030305L) + +// +// MessageId: STG_E_CSS_AUTHENTICATION_FAILURE +// +// MessageText: +// +// Copy Protection Error - DVD CSS Authentication failed. +// +#define STG_E_CSS_AUTHENTICATION_FAILURE _HRESULT_TYPEDEF_(0x80030306L) + +// +// MessageId: STG_E_CSS_KEY_NOT_PRESENT +// +// MessageText: +// +// Copy Protection Error - The given sector does not have a valid CSS key. +// +#define STG_E_CSS_KEY_NOT_PRESENT _HRESULT_TYPEDEF_(0x80030307L) + +// +// MessageId: STG_E_CSS_KEY_NOT_ESTABLISHED +// +// MessageText: +// +// Copy Protection Error - DVD session key not established. +// +#define STG_E_CSS_KEY_NOT_ESTABLISHED _HRESULT_TYPEDEF_(0x80030308L) + +// +// MessageId: STG_E_CSS_SCRAMBLED_SECTOR +// +// MessageText: +// +// Copy Protection Error - The read failed because the sector is encrypted. +// +#define STG_E_CSS_SCRAMBLED_SECTOR _HRESULT_TYPEDEF_(0x80030309L) + +// +// MessageId: STG_E_CSS_REGION_MISMATCH +// +// MessageText: +// +// Copy Protection Error - The current DVD's region does not correspond to the region setting of the drive. +// +#define STG_E_CSS_REGION_MISMATCH _HRESULT_TYPEDEF_(0x8003030AL) + +// +// MessageId: STG_E_RESETS_EXHAUSTED +// +// MessageText: +// +// Copy Protection Error - The drive's region setting may be permanent or the number of user resets has been exhausted. +// +#define STG_E_RESETS_EXHAUSTED _HRESULT_TYPEDEF_(0x8003030BL) + +/*++ + + MessageId's 0x0305 - 0x031f (inclusive) are reserved for **STORAGE** + copy protection errors. + +--*/ +// ****************** +// FACILITY_RPC +// ****************** +// +// Codes 0x0-0x11 are propagated from 16 bit OLE. +// +// +// MessageId: RPC_E_CALL_REJECTED +// +// MessageText: +// +// Call was rejected by callee. +// +#define RPC_E_CALL_REJECTED _HRESULT_TYPEDEF_(0x80010001L) + +// +// MessageId: RPC_E_CALL_CANCELED +// +// MessageText: +// +// Call was canceled by the message filter. +// +#define RPC_E_CALL_CANCELED _HRESULT_TYPEDEF_(0x80010002L) + +// +// MessageId: RPC_E_CANTPOST_INSENDCALL +// +// MessageText: +// +// The caller is dispatching an intertask SendMessage call and cannot call out via PostMessage. +// +#define RPC_E_CANTPOST_INSENDCALL _HRESULT_TYPEDEF_(0x80010003L) + +// +// MessageId: RPC_E_CANTCALLOUT_INASYNCCALL +// +// MessageText: +// +// The caller is dispatching an asynchronous call and cannot make an outgoing call on behalf of this call. +// +#define RPC_E_CANTCALLOUT_INASYNCCALL _HRESULT_TYPEDEF_(0x80010004L) + +// +// MessageId: RPC_E_CANTCALLOUT_INEXTERNALCALL +// +// MessageText: +// +// It is illegal to call out while inside message filter. +// +#define RPC_E_CANTCALLOUT_INEXTERNALCALL _HRESULT_TYPEDEF_(0x80010005L) + +// +// MessageId: RPC_E_CONNECTION_TERMINATED +// +// MessageText: +// +// The connection terminated or is in a bogus state and cannot be used any more. Other connections are still valid. +// +#define RPC_E_CONNECTION_TERMINATED _HRESULT_TYPEDEF_(0x80010006L) + +// +// MessageId: RPC_E_SERVER_DIED +// +// MessageText: +// +// The callee (server [not server application]) is not available and disappeared; all connections are invalid. The call may have executed. +// +#define RPC_E_SERVER_DIED _HRESULT_TYPEDEF_(0x80010007L) + +// +// MessageId: RPC_E_CLIENT_DIED +// +// MessageText: +// +// The caller (client) disappeared while the callee (server) was processing a call. +// +#define RPC_E_CLIENT_DIED _HRESULT_TYPEDEF_(0x80010008L) + +// +// MessageId: RPC_E_INVALID_DATAPACKET +// +// MessageText: +// +// The data packet with the marshalled parameter data is incorrect. +// +#define RPC_E_INVALID_DATAPACKET _HRESULT_TYPEDEF_(0x80010009L) + +// +// MessageId: RPC_E_CANTTRANSMIT_CALL +// +// MessageText: +// +// The call was not transmitted properly; the message queue was full and was not emptied after yielding. +// +#define RPC_E_CANTTRANSMIT_CALL _HRESULT_TYPEDEF_(0x8001000AL) + +// +// MessageId: RPC_E_CLIENT_CANTMARSHAL_DATA +// +// MessageText: +// +// The client (caller) cannot marshall the parameter data - low memory, etc. +// +#define RPC_E_CLIENT_CANTMARSHAL_DATA _HRESULT_TYPEDEF_(0x8001000BL) + +// +// MessageId: RPC_E_CLIENT_CANTUNMARSHAL_DATA +// +// MessageText: +// +// The client (caller) cannot unmarshall the return data - low memory, etc. +// +#define RPC_E_CLIENT_CANTUNMARSHAL_DATA _HRESULT_TYPEDEF_(0x8001000CL) + +// +// MessageId: RPC_E_SERVER_CANTMARSHAL_DATA +// +// MessageText: +// +// The server (callee) cannot marshall the return data - low memory, etc. +// +#define RPC_E_SERVER_CANTMARSHAL_DATA _HRESULT_TYPEDEF_(0x8001000DL) + +// +// MessageId: RPC_E_SERVER_CANTUNMARSHAL_DATA +// +// MessageText: +// +// The server (callee) cannot unmarshall the parameter data - low memory, etc. +// +#define RPC_E_SERVER_CANTUNMARSHAL_DATA _HRESULT_TYPEDEF_(0x8001000EL) + +// +// MessageId: RPC_E_INVALID_DATA +// +// MessageText: +// +// Received data is invalid; could be server or client data. +// +#define RPC_E_INVALID_DATA _HRESULT_TYPEDEF_(0x8001000FL) + +// +// MessageId: RPC_E_INVALID_PARAMETER +// +// MessageText: +// +// A particular parameter is invalid and cannot be (un)marshalled. +// +#define RPC_E_INVALID_PARAMETER _HRESULT_TYPEDEF_(0x80010010L) + +// +// MessageId: RPC_E_CANTCALLOUT_AGAIN +// +// MessageText: +// +// There is no second outgoing call on same channel in DDE conversation. +// +#define RPC_E_CANTCALLOUT_AGAIN _HRESULT_TYPEDEF_(0x80010011L) + +// +// MessageId: RPC_E_SERVER_DIED_DNE +// +// MessageText: +// +// The callee (server [not server application]) is not available and disappeared; all connections are invalid. The call did not execute. +// +#define RPC_E_SERVER_DIED_DNE _HRESULT_TYPEDEF_(0x80010012L) + +// +// MessageId: RPC_E_SYS_CALL_FAILED +// +// MessageText: +// +// System call failed. +// +#define RPC_E_SYS_CALL_FAILED _HRESULT_TYPEDEF_(0x80010100L) + +// +// MessageId: RPC_E_OUT_OF_RESOURCES +// +// MessageText: +// +// Could not allocate some required resource (memory, events, ...) +// +#define RPC_E_OUT_OF_RESOURCES _HRESULT_TYPEDEF_(0x80010101L) + +// +// MessageId: RPC_E_ATTEMPTED_MULTITHREAD +// +// MessageText: +// +// Attempted to make calls on more than one thread in single threaded mode. +// +#define RPC_E_ATTEMPTED_MULTITHREAD _HRESULT_TYPEDEF_(0x80010102L) + +// +// MessageId: RPC_E_NOT_REGISTERED +// +// MessageText: +// +// The requested interface is not registered on the server object. +// +#define RPC_E_NOT_REGISTERED _HRESULT_TYPEDEF_(0x80010103L) + +// +// MessageId: RPC_E_FAULT +// +// MessageText: +// +// RPC could not call the server or could not return the results of calling the server. +// +#define RPC_E_FAULT _HRESULT_TYPEDEF_(0x80010104L) + +// +// MessageId: RPC_E_SERVERFAULT +// +// MessageText: +// +// The server threw an exception. +// +#define RPC_E_SERVERFAULT _HRESULT_TYPEDEF_(0x80010105L) + +// +// MessageId: RPC_E_CHANGED_MODE +// +// MessageText: +// +// Cannot change thread mode after it is set. +// +#define RPC_E_CHANGED_MODE _HRESULT_TYPEDEF_(0x80010106L) + +// +// MessageId: RPC_E_INVALIDMETHOD +// +// MessageText: +// +// The method called does not exist on the server. +// +#define RPC_E_INVALIDMETHOD _HRESULT_TYPEDEF_(0x80010107L) + +// +// MessageId: RPC_E_DISCONNECTED +// +// MessageText: +// +// The object invoked has disconnected from its clients. +// +#define RPC_E_DISCONNECTED _HRESULT_TYPEDEF_(0x80010108L) + +// +// MessageId: RPC_E_RETRY +// +// MessageText: +// +// The object invoked chose not to process the call now. Try again later. +// +#define RPC_E_RETRY _HRESULT_TYPEDEF_(0x80010109L) + +// +// MessageId: RPC_E_SERVERCALL_RETRYLATER +// +// MessageText: +// +// The message filter indicated that the application is busy. +// +#define RPC_E_SERVERCALL_RETRYLATER _HRESULT_TYPEDEF_(0x8001010AL) + +// +// MessageId: RPC_E_SERVERCALL_REJECTED +// +// MessageText: +// +// The message filter rejected the call. +// +#define RPC_E_SERVERCALL_REJECTED _HRESULT_TYPEDEF_(0x8001010BL) + +// +// MessageId: RPC_E_INVALID_CALLDATA +// +// MessageText: +// +// A call control interfaces was called with invalid data. +// +#define RPC_E_INVALID_CALLDATA _HRESULT_TYPEDEF_(0x8001010CL) + +// +// MessageId: RPC_E_CANTCALLOUT_ININPUTSYNCCALL +// +// MessageText: +// +// An outgoing call cannot be made since the application is dispatching an input-synchronous call. +// +#define RPC_E_CANTCALLOUT_ININPUTSYNCCALL _HRESULT_TYPEDEF_(0x8001010DL) + +// +// MessageId: RPC_E_WRONG_THREAD +// +// MessageText: +// +// The application called an interface that was marshalled for a different thread. +// +#define RPC_E_WRONG_THREAD _HRESULT_TYPEDEF_(0x8001010EL) + +// +// MessageId: RPC_E_THREAD_NOT_INIT +// +// MessageText: +// +// CoInitialize has not been called on the current thread. +// +#define RPC_E_THREAD_NOT_INIT _HRESULT_TYPEDEF_(0x8001010FL) + +// +// MessageId: RPC_E_VERSION_MISMATCH +// +// MessageText: +// +// The version of OLE on the client and server machines does not match. +// +#define RPC_E_VERSION_MISMATCH _HRESULT_TYPEDEF_(0x80010110L) + +// +// MessageId: RPC_E_INVALID_HEADER +// +// MessageText: +// +// OLE received a packet with an invalid header. +// +#define RPC_E_INVALID_HEADER _HRESULT_TYPEDEF_(0x80010111L) + +// +// MessageId: RPC_E_INVALID_EXTENSION +// +// MessageText: +// +// OLE received a packet with an invalid extension. +// +#define RPC_E_INVALID_EXTENSION _HRESULT_TYPEDEF_(0x80010112L) + +// +// MessageId: RPC_E_INVALID_IPID +// +// MessageText: +// +// The requested object or interface does not exist. +// +#define RPC_E_INVALID_IPID _HRESULT_TYPEDEF_(0x80010113L) + +// +// MessageId: RPC_E_INVALID_OBJECT +// +// MessageText: +// +// The requested object does not exist. +// +#define RPC_E_INVALID_OBJECT _HRESULT_TYPEDEF_(0x80010114L) + +// +// MessageId: RPC_S_CALLPENDING +// +// MessageText: +// +// OLE has sent a request and is waiting for a reply. +// +#define RPC_S_CALLPENDING _HRESULT_TYPEDEF_(0x80010115L) + +// +// MessageId: RPC_S_WAITONTIMER +// +// MessageText: +// +// OLE is waiting before retrying a request. +// +#define RPC_S_WAITONTIMER _HRESULT_TYPEDEF_(0x80010116L) + +// +// MessageId: RPC_E_CALL_COMPLETE +// +// MessageText: +// +// Call context cannot be accessed after call completed. +// +#define RPC_E_CALL_COMPLETE _HRESULT_TYPEDEF_(0x80010117L) + +// +// MessageId: RPC_E_UNSECURE_CALL +// +// MessageText: +// +// Impersonate on unsecure calls is not supported. +// +#define RPC_E_UNSECURE_CALL _HRESULT_TYPEDEF_(0x80010118L) + +// +// MessageId: RPC_E_TOO_LATE +// +// MessageText: +// +// Security must be initialized before any interfaces are marshalled or unmarshalled. It cannot be changed once initialized. +// +#define RPC_E_TOO_LATE _HRESULT_TYPEDEF_(0x80010119L) + +// +// MessageId: RPC_E_NO_GOOD_SECURITY_PACKAGES +// +// MessageText: +// +// No security packages are installed on this machine or the user is not logged on or there are no compatible security packages between the client and server. +// +#define RPC_E_NO_GOOD_SECURITY_PACKAGES _HRESULT_TYPEDEF_(0x8001011AL) + +// +// MessageId: RPC_E_ACCESS_DENIED +// +// MessageText: +// +// Access is denied. +// +#define RPC_E_ACCESS_DENIED _HRESULT_TYPEDEF_(0x8001011BL) + +// +// MessageId: RPC_E_REMOTE_DISABLED +// +// MessageText: +// +// Remote calls are not allowed for this process. +// +#define RPC_E_REMOTE_DISABLED _HRESULT_TYPEDEF_(0x8001011CL) + +// +// MessageId: RPC_E_INVALID_OBJREF +// +// MessageText: +// +// The marshaled interface data packet (OBJREF) has an invalid or unknown format. +// +#define RPC_E_INVALID_OBJREF _HRESULT_TYPEDEF_(0x8001011DL) + +// +// MessageId: RPC_E_NO_CONTEXT +// +// MessageText: +// +// No context is associated with this call. This happens for some custom marshalled calls and on the client side of the call. +// +#define RPC_E_NO_CONTEXT _HRESULT_TYPEDEF_(0x8001011EL) + +// +// MessageId: RPC_E_TIMEOUT +// +// MessageText: +// +// This operation returned because the timeout period expired. +// +#define RPC_E_TIMEOUT _HRESULT_TYPEDEF_(0x8001011FL) + +// +// MessageId: RPC_E_NO_SYNC +// +// MessageText: +// +// There are no synchronize objects to wait on. +// +#define RPC_E_NO_SYNC _HRESULT_TYPEDEF_(0x80010120L) + +// +// MessageId: RPC_E_FULLSIC_REQUIRED +// +// MessageText: +// +// Full subject issuer chain SSL principal name expected from the server. +// +#define RPC_E_FULLSIC_REQUIRED _HRESULT_TYPEDEF_(0x80010121L) + +// +// MessageId: RPC_E_INVALID_STD_NAME +// +// MessageText: +// +// Principal name is not a valid MSSTD name. +// +#define RPC_E_INVALID_STD_NAME _HRESULT_TYPEDEF_(0x80010122L) + +// +// MessageId: CO_E_FAILEDTOIMPERSONATE +// +// MessageText: +// +// Unable to impersonate DCOM client +// +#define CO_E_FAILEDTOIMPERSONATE _HRESULT_TYPEDEF_(0x80010123L) + +// +// MessageId: CO_E_FAILEDTOGETSECCTX +// +// MessageText: +// +// Unable to obtain server's security context +// +#define CO_E_FAILEDTOGETSECCTX _HRESULT_TYPEDEF_(0x80010124L) + +// +// MessageId: CO_E_FAILEDTOOPENTHREADTOKEN +// +// MessageText: +// +// Unable to open the access token of the current thread +// +#define CO_E_FAILEDTOOPENTHREADTOKEN _HRESULT_TYPEDEF_(0x80010125L) + +// +// MessageId: CO_E_FAILEDTOGETTOKENINFO +// +// MessageText: +// +// Unable to obtain user info from an access token +// +#define CO_E_FAILEDTOGETTOKENINFO _HRESULT_TYPEDEF_(0x80010126L) + +// +// MessageId: CO_E_TRUSTEEDOESNTMATCHCLIENT +// +// MessageText: +// +// The client who called IAccessControl::IsAccessPermitted was not the trustee provided to the method +// +#define CO_E_TRUSTEEDOESNTMATCHCLIENT _HRESULT_TYPEDEF_(0x80010127L) + +// +// MessageId: CO_E_FAILEDTOQUERYCLIENTBLANKET +// +// MessageText: +// +// Unable to obtain the client's security blanket +// +#define CO_E_FAILEDTOQUERYCLIENTBLANKET _HRESULT_TYPEDEF_(0x80010128L) + +// +// MessageId: CO_E_FAILEDTOSETDACL +// +// MessageText: +// +// Unable to set a discretionary ACL into a security descriptor +// +#define CO_E_FAILEDTOSETDACL _HRESULT_TYPEDEF_(0x80010129L) + +// +// MessageId: CO_E_ACCESSCHECKFAILED +// +// MessageText: +// +// The system function, AccessCheck, returned false +// +#define CO_E_ACCESSCHECKFAILED _HRESULT_TYPEDEF_(0x8001012AL) + +// +// MessageId: CO_E_NETACCESSAPIFAILED +// +// MessageText: +// +// Either NetAccessDel or NetAccessAdd returned an error code. +// +#define CO_E_NETACCESSAPIFAILED _HRESULT_TYPEDEF_(0x8001012BL) + +// +// MessageId: CO_E_WRONGTRUSTEENAMESYNTAX +// +// MessageText: +// +// One of the trustee strings provided by the user did not conform to the \ syntax and it was not the "*" string +// +#define CO_E_WRONGTRUSTEENAMESYNTAX _HRESULT_TYPEDEF_(0x8001012CL) + +// +// MessageId: CO_E_INVALIDSID +// +// MessageText: +// +// One of the security identifiers provided by the user was invalid +// +#define CO_E_INVALIDSID _HRESULT_TYPEDEF_(0x8001012DL) + +// +// MessageId: CO_E_CONVERSIONFAILED +// +// MessageText: +// +// Unable to convert a wide character trustee string to a multibyte trustee string +// +#define CO_E_CONVERSIONFAILED _HRESULT_TYPEDEF_(0x8001012EL) + +// +// MessageId: CO_E_NOMATCHINGSIDFOUND +// +// MessageText: +// +// Unable to find a security identifier that corresponds to a trustee string provided by the user +// +#define CO_E_NOMATCHINGSIDFOUND _HRESULT_TYPEDEF_(0x8001012FL) + +// +// MessageId: CO_E_LOOKUPACCSIDFAILED +// +// MessageText: +// +// The system function, LookupAccountSID, failed +// +#define CO_E_LOOKUPACCSIDFAILED _HRESULT_TYPEDEF_(0x80010130L) + +// +// MessageId: CO_E_NOMATCHINGNAMEFOUND +// +// MessageText: +// +// Unable to find a trustee name that corresponds to a security identifier provided by the user +// +#define CO_E_NOMATCHINGNAMEFOUND _HRESULT_TYPEDEF_(0x80010131L) + +// +// MessageId: CO_E_LOOKUPACCNAMEFAILED +// +// MessageText: +// +// The system function, LookupAccountName, failed +// +#define CO_E_LOOKUPACCNAMEFAILED _HRESULT_TYPEDEF_(0x80010132L) + +// +// MessageId: CO_E_SETSERLHNDLFAILED +// +// MessageText: +// +// Unable to set or reset a serialization handle +// +#define CO_E_SETSERLHNDLFAILED _HRESULT_TYPEDEF_(0x80010133L) + +// +// MessageId: CO_E_FAILEDTOGETWINDIR +// +// MessageText: +// +// Unable to obtain the Windows directory +// +#define CO_E_FAILEDTOGETWINDIR _HRESULT_TYPEDEF_(0x80010134L) + +// +// MessageId: CO_E_PATHTOOLONG +// +// MessageText: +// +// Path too long +// +#define CO_E_PATHTOOLONG _HRESULT_TYPEDEF_(0x80010135L) + +// +// MessageId: CO_E_FAILEDTOGENUUID +// +// MessageText: +// +// Unable to generate a uuid. +// +#define CO_E_FAILEDTOGENUUID _HRESULT_TYPEDEF_(0x80010136L) + +// +// MessageId: CO_E_FAILEDTOCREATEFILE +// +// MessageText: +// +// Unable to create file +// +#define CO_E_FAILEDTOCREATEFILE _HRESULT_TYPEDEF_(0x80010137L) + +// +// MessageId: CO_E_FAILEDTOCLOSEHANDLE +// +// MessageText: +// +// Unable to close a serialization handle or a file handle. +// +#define CO_E_FAILEDTOCLOSEHANDLE _HRESULT_TYPEDEF_(0x80010138L) + +// +// MessageId: CO_E_EXCEEDSYSACLLIMIT +// +// MessageText: +// +// The number of ACEs in an ACL exceeds the system limit. +// +#define CO_E_EXCEEDSYSACLLIMIT _HRESULT_TYPEDEF_(0x80010139L) + +// +// MessageId: CO_E_ACESINWRONGORDER +// +// MessageText: +// +// Not all the DENY_ACCESS ACEs are arranged in front of the GRANT_ACCESS ACEs in the stream. +// +#define CO_E_ACESINWRONGORDER _HRESULT_TYPEDEF_(0x8001013AL) + +// +// MessageId: CO_E_INCOMPATIBLESTREAMVERSION +// +// MessageText: +// +// The version of ACL format in the stream is not supported by this implementation of IAccessControl +// +#define CO_E_INCOMPATIBLESTREAMVERSION _HRESULT_TYPEDEF_(0x8001013BL) + +// +// MessageId: CO_E_FAILEDTOOPENPROCESSTOKEN +// +// MessageText: +// +// Unable to open the access token of the server process +// +#define CO_E_FAILEDTOOPENPROCESSTOKEN _HRESULT_TYPEDEF_(0x8001013CL) + +// +// MessageId: CO_E_DECODEFAILED +// +// MessageText: +// +// Unable to decode the ACL in the stream provided by the user +// +#define CO_E_DECODEFAILED _HRESULT_TYPEDEF_(0x8001013DL) + +// +// MessageId: CO_E_ACNOTINITIALIZED +// +// MessageText: +// +// The COM IAccessControl object is not initialized +// +#define CO_E_ACNOTINITIALIZED _HRESULT_TYPEDEF_(0x8001013FL) + +// +// MessageId: CO_E_CANCEL_DISABLED +// +// MessageText: +// +// Call Cancellation is disabled +// +#define CO_E_CANCEL_DISABLED _HRESULT_TYPEDEF_(0x80010140L) + +// +// MessageId: RPC_E_UNEXPECTED +// +// MessageText: +// +// An internal error occurred. +// +#define RPC_E_UNEXPECTED _HRESULT_TYPEDEF_(0x8001FFFFL) + + + +////////////////////////////////////// +// // +// Additional Security Status Codes // +// // +// Facility=Security // +// // +////////////////////////////////////// + + +// +// MessageId: ERROR_AUDITING_DISABLED +// +// MessageText: +// +// The specified event is currently not being audited. +// +#define ERROR_AUDITING_DISABLED _HRESULT_TYPEDEF_(0xC0090001L) + +// +// MessageId: ERROR_ALL_SIDS_FILTERED +// +// MessageText: +// +// The SID filtering operation removed all SIDs. +// +#define ERROR_ALL_SIDS_FILTERED _HRESULT_TYPEDEF_(0xC0090002L) + + + +///////////////////////////////////////////// +// // +// end of Additional Security Status Codes // +// // +///////////////////////////////////////////// + + + + ///////////////// + // + // FACILITY_SSPI + // + ///////////////// + +// +// MessageId: NTE_BAD_UID +// +// MessageText: +// +// Bad UID. +// +#define NTE_BAD_UID _HRESULT_TYPEDEF_(0x80090001L) + +// +// MessageId: NTE_BAD_HASH +// +// MessageText: +// +// Bad Hash. +// +#define NTE_BAD_HASH _HRESULT_TYPEDEF_(0x80090002L) + +// +// MessageId: NTE_BAD_KEY +// +// MessageText: +// +// Bad Key. +// +#define NTE_BAD_KEY _HRESULT_TYPEDEF_(0x80090003L) + +// +// MessageId: NTE_BAD_LEN +// +// MessageText: +// +// Bad Length. +// +#define NTE_BAD_LEN _HRESULT_TYPEDEF_(0x80090004L) + +// +// MessageId: NTE_BAD_DATA +// +// MessageText: +// +// Bad Data. +// +#define NTE_BAD_DATA _HRESULT_TYPEDEF_(0x80090005L) + +// +// MessageId: NTE_BAD_SIGNATURE +// +// MessageText: +// +// Invalid Signature. +// +#define NTE_BAD_SIGNATURE _HRESULT_TYPEDEF_(0x80090006L) + +// +// MessageId: NTE_BAD_VER +// +// MessageText: +// +// Bad Version of provider. +// +#define NTE_BAD_VER _HRESULT_TYPEDEF_(0x80090007L) + +// +// MessageId: NTE_BAD_ALGID +// +// MessageText: +// +// Invalid algorithm specified. +// +#define NTE_BAD_ALGID _HRESULT_TYPEDEF_(0x80090008L) + +// +// MessageId: NTE_BAD_FLAGS +// +// MessageText: +// +// Invalid flags specified. +// +#define NTE_BAD_FLAGS _HRESULT_TYPEDEF_(0x80090009L) + +// +// MessageId: NTE_BAD_TYPE +// +// MessageText: +// +// Invalid type specified. +// +#define NTE_BAD_TYPE _HRESULT_TYPEDEF_(0x8009000AL) + +// +// MessageId: NTE_BAD_KEY_STATE +// +// MessageText: +// +// Key not valid for use in specified state. +// +#define NTE_BAD_KEY_STATE _HRESULT_TYPEDEF_(0x8009000BL) + +// +// MessageId: NTE_BAD_HASH_STATE +// +// MessageText: +// +// Hash not valid for use in specified state. +// +#define NTE_BAD_HASH_STATE _HRESULT_TYPEDEF_(0x8009000CL) + +// +// MessageId: NTE_NO_KEY +// +// MessageText: +// +// Key does not exist. +// +#define NTE_NO_KEY _HRESULT_TYPEDEF_(0x8009000DL) + +// +// MessageId: NTE_NO_MEMORY +// +// MessageText: +// +// Insufficient memory available for the operation. +// +#define NTE_NO_MEMORY _HRESULT_TYPEDEF_(0x8009000EL) + +// +// MessageId: NTE_EXISTS +// +// MessageText: +// +// Object already exists. +// +#define NTE_EXISTS _HRESULT_TYPEDEF_(0x8009000FL) + +// +// MessageId: NTE_PERM +// +// MessageText: +// +// Access denied. +// +#define NTE_PERM _HRESULT_TYPEDEF_(0x80090010L) + +// +// MessageId: NTE_NOT_FOUND +// +// MessageText: +// +// Object was not found. +// +#define NTE_NOT_FOUND _HRESULT_TYPEDEF_(0x80090011L) + +// +// MessageId: NTE_DOUBLE_ENCRYPT +// +// MessageText: +// +// Data already encrypted. +// +#define NTE_DOUBLE_ENCRYPT _HRESULT_TYPEDEF_(0x80090012L) + +// +// MessageId: NTE_BAD_PROVIDER +// +// MessageText: +// +// Invalid provider specified. +// +#define NTE_BAD_PROVIDER _HRESULT_TYPEDEF_(0x80090013L) + +// +// MessageId: NTE_BAD_PROV_TYPE +// +// MessageText: +// +// Invalid provider type specified. +// +#define NTE_BAD_PROV_TYPE _HRESULT_TYPEDEF_(0x80090014L) + +// +// MessageId: NTE_BAD_PUBLIC_KEY +// +// MessageText: +// +// Provider's public key is invalid. +// +#define NTE_BAD_PUBLIC_KEY _HRESULT_TYPEDEF_(0x80090015L) + +// +// MessageId: NTE_BAD_KEYSET +// +// MessageText: +// +// Keyset does not exist +// +#define NTE_BAD_KEYSET _HRESULT_TYPEDEF_(0x80090016L) + +// +// MessageId: NTE_PROV_TYPE_NOT_DEF +// +// MessageText: +// +// Provider type not defined. +// +#define NTE_PROV_TYPE_NOT_DEF _HRESULT_TYPEDEF_(0x80090017L) + +// +// MessageId: NTE_PROV_TYPE_ENTRY_BAD +// +// MessageText: +// +// Provider type as registered is invalid. +// +#define NTE_PROV_TYPE_ENTRY_BAD _HRESULT_TYPEDEF_(0x80090018L) + +// +// MessageId: NTE_KEYSET_NOT_DEF +// +// MessageText: +// +// The keyset is not defined. +// +#define NTE_KEYSET_NOT_DEF _HRESULT_TYPEDEF_(0x80090019L) + +// +// MessageId: NTE_KEYSET_ENTRY_BAD +// +// MessageText: +// +// Keyset as registered is invalid. +// +#define NTE_KEYSET_ENTRY_BAD _HRESULT_TYPEDEF_(0x8009001AL) + +// +// MessageId: NTE_PROV_TYPE_NO_MATCH +// +// MessageText: +// +// Provider type does not match registered value. +// +#define NTE_PROV_TYPE_NO_MATCH _HRESULT_TYPEDEF_(0x8009001BL) + +// +// MessageId: NTE_SIGNATURE_FILE_BAD +// +// MessageText: +// +// The digital signature file is corrupt. +// +#define NTE_SIGNATURE_FILE_BAD _HRESULT_TYPEDEF_(0x8009001CL) + +// +// MessageId: NTE_PROVIDER_DLL_FAIL +// +// MessageText: +// +// Provider DLL failed to initialize correctly. +// +#define NTE_PROVIDER_DLL_FAIL _HRESULT_TYPEDEF_(0x8009001DL) + +// +// MessageId: NTE_PROV_DLL_NOT_FOUND +// +// MessageText: +// +// Provider DLL could not be found. +// +#define NTE_PROV_DLL_NOT_FOUND _HRESULT_TYPEDEF_(0x8009001EL) + +// +// MessageId: NTE_BAD_KEYSET_PARAM +// +// MessageText: +// +// The Keyset parameter is invalid. +// +#define NTE_BAD_KEYSET_PARAM _HRESULT_TYPEDEF_(0x8009001FL) + +// +// MessageId: NTE_FAIL +// +// MessageText: +// +// An internal error occurred. +// +#define NTE_FAIL _HRESULT_TYPEDEF_(0x80090020L) + +// +// MessageId: NTE_SYS_ERR +// +// MessageText: +// +// A base error occurred. +// +#define NTE_SYS_ERR _HRESULT_TYPEDEF_(0x80090021L) + +// +// MessageId: NTE_SILENT_CONTEXT +// +// MessageText: +// +// Provider could not perform the action since the context was acquired as silent. +// +#define NTE_SILENT_CONTEXT _HRESULT_TYPEDEF_(0x80090022L) + +// +// MessageId: NTE_TOKEN_KEYSET_STORAGE_FULL +// +// MessageText: +// +// The security token does not have storage space available for an additional container. +// +#define NTE_TOKEN_KEYSET_STORAGE_FULL _HRESULT_TYPEDEF_(0x80090023L) + +// +// MessageId: NTE_TEMPORARY_PROFILE +// +// MessageText: +// +// The profile for the user is a temporary profile. +// +#define NTE_TEMPORARY_PROFILE _HRESULT_TYPEDEF_(0x80090024L) + +// +// MessageId: NTE_FIXEDPARAMETER +// +// MessageText: +// +// The key parameters could not be set because the CSP uses fixed parameters. +// +#define NTE_FIXEDPARAMETER _HRESULT_TYPEDEF_(0x80090025L) + +// +// MessageId: SEC_E_INSUFFICIENT_MEMORY +// +// MessageText: +// +// Not enough memory is available to complete this request +// +#define SEC_E_INSUFFICIENT_MEMORY _HRESULT_TYPEDEF_(0x80090300L) + +// +// MessageId: SEC_E_INVALID_HANDLE +// +// MessageText: +// +// The handle specified is invalid +// +#define SEC_E_INVALID_HANDLE _HRESULT_TYPEDEF_(0x80090301L) + +// +// MessageId: SEC_E_UNSUPPORTED_FUNCTION +// +// MessageText: +// +// The function requested is not supported +// +#define SEC_E_UNSUPPORTED_FUNCTION _HRESULT_TYPEDEF_(0x80090302L) + +// +// MessageId: SEC_E_TARGET_UNKNOWN +// +// MessageText: +// +// The specified target is unknown or unreachable +// +#define SEC_E_TARGET_UNKNOWN _HRESULT_TYPEDEF_(0x80090303L) + +// +// MessageId: SEC_E_INTERNAL_ERROR +// +// MessageText: +// +// The Local Security Authority cannot be contacted +// +#define SEC_E_INTERNAL_ERROR _HRESULT_TYPEDEF_(0x80090304L) + +// +// MessageId: SEC_E_SECPKG_NOT_FOUND +// +// MessageText: +// +// The requested security package does not exist +// +#define SEC_E_SECPKG_NOT_FOUND _HRESULT_TYPEDEF_(0x80090305L) + +// +// MessageId: SEC_E_NOT_OWNER +// +// MessageText: +// +// The caller is not the owner of the desired credentials +// +#define SEC_E_NOT_OWNER _HRESULT_TYPEDEF_(0x80090306L) + +// +// MessageId: SEC_E_CANNOT_INSTALL +// +// MessageText: +// +// The security package failed to initialize, and cannot be installed +// +#define SEC_E_CANNOT_INSTALL _HRESULT_TYPEDEF_(0x80090307L) + +// +// MessageId: SEC_E_INVALID_TOKEN +// +// MessageText: +// +// The token supplied to the function is invalid +// +#define SEC_E_INVALID_TOKEN _HRESULT_TYPEDEF_(0x80090308L) + +// +// MessageId: SEC_E_CANNOT_PACK +// +// MessageText: +// +// The security package is not able to marshall the logon buffer, so the logon attempt has failed +// +#define SEC_E_CANNOT_PACK _HRESULT_TYPEDEF_(0x80090309L) + +// +// MessageId: SEC_E_QOP_NOT_SUPPORTED +// +// MessageText: +// +// The per-message Quality of Protection is not supported by the security package +// +#define SEC_E_QOP_NOT_SUPPORTED _HRESULT_TYPEDEF_(0x8009030AL) + +// +// MessageId: SEC_E_NO_IMPERSONATION +// +// MessageText: +// +// The security context does not allow impersonation of the client +// +#define SEC_E_NO_IMPERSONATION _HRESULT_TYPEDEF_(0x8009030BL) + +// +// MessageId: SEC_E_LOGON_DENIED +// +// MessageText: +// +// The logon attempt failed +// +#define SEC_E_LOGON_DENIED _HRESULT_TYPEDEF_(0x8009030CL) + +// +// MessageId: SEC_E_UNKNOWN_CREDENTIALS +// +// MessageText: +// +// The credentials supplied to the package were not recognized +// +#define SEC_E_UNKNOWN_CREDENTIALS _HRESULT_TYPEDEF_(0x8009030DL) + +// +// MessageId: SEC_E_NO_CREDENTIALS +// +// MessageText: +// +// No credentials are available in the security package +// +#define SEC_E_NO_CREDENTIALS _HRESULT_TYPEDEF_(0x8009030EL) + +// +// MessageId: SEC_E_MESSAGE_ALTERED +// +// MessageText: +// +// The message or signature supplied for verification has been altered +// +#define SEC_E_MESSAGE_ALTERED _HRESULT_TYPEDEF_(0x8009030FL) + +// +// MessageId: SEC_E_OUT_OF_SEQUENCE +// +// MessageText: +// +// The message supplied for verification is out of sequence +// +#define SEC_E_OUT_OF_SEQUENCE _HRESULT_TYPEDEF_(0x80090310L) + +// +// MessageId: SEC_E_NO_AUTHENTICATING_AUTHORITY +// +// MessageText: +// +// No authority could be contacted for authentication. +// +#define SEC_E_NO_AUTHENTICATING_AUTHORITY _HRESULT_TYPEDEF_(0x80090311L) + +// +// MessageId: SEC_I_CONTINUE_NEEDED +// +// MessageText: +// +// The function completed successfully, but must be called again to complete the context +// +#define SEC_I_CONTINUE_NEEDED _HRESULT_TYPEDEF_(0x00090312L) + +// +// MessageId: SEC_I_COMPLETE_NEEDED +// +// MessageText: +// +// The function completed successfully, but CompleteToken must be called +// +#define SEC_I_COMPLETE_NEEDED _HRESULT_TYPEDEF_(0x00090313L) + +// +// MessageId: SEC_I_COMPLETE_AND_CONTINUE +// +// MessageText: +// +// The function completed successfully, but both CompleteToken and this function must be called to complete the context +// +#define SEC_I_COMPLETE_AND_CONTINUE _HRESULT_TYPEDEF_(0x00090314L) + +// +// MessageId: SEC_I_LOCAL_LOGON +// +// MessageText: +// +// The logon was completed, but no network authority was available. The logon was made using locally known information +// +#define SEC_I_LOCAL_LOGON _HRESULT_TYPEDEF_(0x00090315L) + +// +// MessageId: SEC_E_BAD_PKGID +// +// MessageText: +// +// The requested security package does not exist +// +#define SEC_E_BAD_PKGID _HRESULT_TYPEDEF_(0x80090316L) + +// +// MessageId: SEC_E_CONTEXT_EXPIRED +// +// MessageText: +// +// The context has expired and can no longer be used. +// +#define SEC_E_CONTEXT_EXPIRED _HRESULT_TYPEDEF_(0x80090317L) + +// +// MessageId: SEC_I_CONTEXT_EXPIRED +// +// MessageText: +// +// The context has expired and can no longer be used. +// +#define SEC_I_CONTEXT_EXPIRED _HRESULT_TYPEDEF_(0x00090317L) + +// +// MessageId: SEC_E_INCOMPLETE_MESSAGE +// +// MessageText: +// +// The supplied message is incomplete. The signature was not verified. +// +#define SEC_E_INCOMPLETE_MESSAGE _HRESULT_TYPEDEF_(0x80090318L) + +// +// MessageId: SEC_E_INCOMPLETE_CREDENTIALS +// +// MessageText: +// +// The credentials supplied were not complete, and could not be verified. The context could not be initialized. +// +#define SEC_E_INCOMPLETE_CREDENTIALS _HRESULT_TYPEDEF_(0x80090320L) + +// +// MessageId: SEC_E_BUFFER_TOO_SMALL +// +// MessageText: +// +// The buffers supplied to a function was too small. +// +#define SEC_E_BUFFER_TOO_SMALL _HRESULT_TYPEDEF_(0x80090321L) + +// +// MessageId: SEC_I_INCOMPLETE_CREDENTIALS +// +// MessageText: +// +// The credentials supplied were not complete, and could not be verified. Additional information can be returned from the context. +// +#define SEC_I_INCOMPLETE_CREDENTIALS _HRESULT_TYPEDEF_(0x00090320L) + +// +// MessageId: SEC_I_RENEGOTIATE +// +// MessageText: +// +// The context data must be renegotiated with the peer. +// +#define SEC_I_RENEGOTIATE _HRESULT_TYPEDEF_(0x00090321L) + +// +// MessageId: SEC_E_WRONG_PRINCIPAL +// +// MessageText: +// +// The target principal name is incorrect. +// +#define SEC_E_WRONG_PRINCIPAL _HRESULT_TYPEDEF_(0x80090322L) + +// +// MessageId: SEC_I_NO_LSA_CONTEXT +// +// MessageText: +// +// There is no LSA mode context associated with this context. +// +#define SEC_I_NO_LSA_CONTEXT _HRESULT_TYPEDEF_(0x00090323L) + +// +// MessageId: SEC_E_TIME_SKEW +// +// MessageText: +// +// The clocks on the client and server machines are skewed. +// +#define SEC_E_TIME_SKEW _HRESULT_TYPEDEF_(0x80090324L) + +// +// MessageId: SEC_E_UNTRUSTED_ROOT +// +// MessageText: +// +// The certificate chain was issued by an authority that is not trusted. +// +#define SEC_E_UNTRUSTED_ROOT _HRESULT_TYPEDEF_(0x80090325L) + +// +// MessageId: SEC_E_ILLEGAL_MESSAGE +// +// MessageText: +// +// The message received was unexpected or badly formatted. +// +#define SEC_E_ILLEGAL_MESSAGE _HRESULT_TYPEDEF_(0x80090326L) + +// +// MessageId: SEC_E_CERT_UNKNOWN +// +// MessageText: +// +// An unknown error occurred while processing the certificate. +// +#define SEC_E_CERT_UNKNOWN _HRESULT_TYPEDEF_(0x80090327L) + +// +// MessageId: SEC_E_CERT_EXPIRED +// +// MessageText: +// +// The received certificate has expired. +// +#define SEC_E_CERT_EXPIRED _HRESULT_TYPEDEF_(0x80090328L) + +// +// MessageId: SEC_E_ENCRYPT_FAILURE +// +// MessageText: +// +// The specified data could not be encrypted. +// +#define SEC_E_ENCRYPT_FAILURE _HRESULT_TYPEDEF_(0x80090329L) + +// +// MessageId: SEC_E_DECRYPT_FAILURE +// +// MessageText: +// +// The specified data could not be decrypted. +// +// +#define SEC_E_DECRYPT_FAILURE _HRESULT_TYPEDEF_(0x80090330L) + +// +// MessageId: SEC_E_ALGORITHM_MISMATCH +// +// MessageText: +// +// The client and server cannot communicate, because they do not possess a common algorithm. +// +#define SEC_E_ALGORITHM_MISMATCH _HRESULT_TYPEDEF_(0x80090331L) + +// +// MessageId: SEC_E_SECURITY_QOS_FAILED +// +// MessageText: +// +// The security context could not be established due to a failure in the requested quality of service (e.g. mutual authentication or delegation). +// +#define SEC_E_SECURITY_QOS_FAILED _HRESULT_TYPEDEF_(0x80090332L) + +// +// MessageId: SEC_E_UNFINISHED_CONTEXT_DELETED +// +// MessageText: +// +// A security context was deleted before the context was completed. This is considered a logon failure. +// +#define SEC_E_UNFINISHED_CONTEXT_DELETED _HRESULT_TYPEDEF_(0x80090333L) + +// +// MessageId: SEC_E_NO_TGT_REPLY +// +// MessageText: +// +// The client is trying to negotiate a context and the server requires user-to-user but didn't send a TGT reply. +// +#define SEC_E_NO_TGT_REPLY _HRESULT_TYPEDEF_(0x80090334L) + +// +// MessageId: SEC_E_NO_IP_ADDRESSES +// +// MessageText: +// +// Unable to accomplish the requested task because the local machine does not have any IP addresses. +// +#define SEC_E_NO_IP_ADDRESSES _HRESULT_TYPEDEF_(0x80090335L) + +// +// MessageId: SEC_E_WRONG_CREDENTIAL_HANDLE +// +// MessageText: +// +// The supplied credential handle does not match the credential associated with the security context. +// +#define SEC_E_WRONG_CREDENTIAL_HANDLE _HRESULT_TYPEDEF_(0x80090336L) + +// +// MessageId: SEC_E_CRYPTO_SYSTEM_INVALID +// +// MessageText: +// +// The crypto system or checksum function is invalid because a required function is unavailable. +// +#define SEC_E_CRYPTO_SYSTEM_INVALID _HRESULT_TYPEDEF_(0x80090337L) + +// +// MessageId: SEC_E_MAX_REFERRALS_EXCEEDED +// +// MessageText: +// +// The number of maximum ticket referrals has been exceeded. +// +#define SEC_E_MAX_REFERRALS_EXCEEDED _HRESULT_TYPEDEF_(0x80090338L) + +// +// MessageId: SEC_E_MUST_BE_KDC +// +// MessageText: +// +// The local machine must be a Kerberos KDC (domain controller) and it is not. +// +#define SEC_E_MUST_BE_KDC _HRESULT_TYPEDEF_(0x80090339L) + +// +// MessageId: SEC_E_STRONG_CRYPTO_NOT_SUPPORTED +// +// MessageText: +// +// The other end of the security negotiation is requires strong crypto but it is not supported on the local machine. +// +#define SEC_E_STRONG_CRYPTO_NOT_SUPPORTED _HRESULT_TYPEDEF_(0x8009033AL) + +// +// MessageId: SEC_E_TOO_MANY_PRINCIPALS +// +// MessageText: +// +// The KDC reply contained more than one principal name. +// +#define SEC_E_TOO_MANY_PRINCIPALS _HRESULT_TYPEDEF_(0x8009033BL) + +// +// MessageId: SEC_E_NO_PA_DATA +// +// MessageText: +// +// Expected to find PA data for a hint of what etype to use, but it was not found. +// +#define SEC_E_NO_PA_DATA _HRESULT_TYPEDEF_(0x8009033CL) + +// +// MessageId: SEC_E_PKINIT_NAME_MISMATCH +// +// MessageText: +// +// The client certificate does not contain a valid UPN, or does not match the client name +// in the logon request. Please contact your administrator. +// +#define SEC_E_PKINIT_NAME_MISMATCH _HRESULT_TYPEDEF_(0x8009033DL) + +// +// MessageId: SEC_E_SMARTCARD_LOGON_REQUIRED +// +// MessageText: +// +// Smartcard logon is required and was not used. +// +#define SEC_E_SMARTCARD_LOGON_REQUIRED _HRESULT_TYPEDEF_(0x8009033EL) + +// +// MessageId: SEC_E_SHUTDOWN_IN_PROGRESS +// +// MessageText: +// +// A system shutdown is in progress. +// +#define SEC_E_SHUTDOWN_IN_PROGRESS _HRESULT_TYPEDEF_(0x8009033FL) + +// +// MessageId: SEC_E_KDC_INVALID_REQUEST +// +// MessageText: +// +// An invalid request was sent to the KDC. +// +#define SEC_E_KDC_INVALID_REQUEST _HRESULT_TYPEDEF_(0x80090340L) + +// +// MessageId: SEC_E_KDC_UNABLE_TO_REFER +// +// MessageText: +// +// The KDC was unable to generate a referral for the service requested. +// +#define SEC_E_KDC_UNABLE_TO_REFER _HRESULT_TYPEDEF_(0x80090341L) + +// +// MessageId: SEC_E_KDC_UNKNOWN_ETYPE +// +// MessageText: +// +// The encryption type requested is not supported by the KDC. +// +#define SEC_E_KDC_UNKNOWN_ETYPE _HRESULT_TYPEDEF_(0x80090342L) + +// +// MessageId: SEC_E_UNSUPPORTED_PREAUTH +// +// MessageText: +// +// An unsupported preauthentication mechanism was presented to the kerberos package. +// +#define SEC_E_UNSUPPORTED_PREAUTH _HRESULT_TYPEDEF_(0x80090343L) + +// +// MessageId: SEC_E_DELEGATION_REQUIRED +// +// MessageText: +// +// The requested operation cannot be completed. The computer must be trusted for delegation and the current user account must be configured to allow delegation. +// +#define SEC_E_DELEGATION_REQUIRED _HRESULT_TYPEDEF_(0x80090345L) + +// +// MessageId: SEC_E_BAD_BINDINGS +// +// MessageText: +// +// Client's supplied SSPI channel bindings were incorrect. +// +#define SEC_E_BAD_BINDINGS _HRESULT_TYPEDEF_(0x80090346L) + +// +// MessageId: SEC_E_MULTIPLE_ACCOUNTS +// +// MessageText: +// +// The received certificate was mapped to multiple accounts. +// +#define SEC_E_MULTIPLE_ACCOUNTS _HRESULT_TYPEDEF_(0x80090347L) + +// +// MessageId: SEC_E_NO_KERB_KEY +// +// MessageText: +// +// SEC_E_NO_KERB_KEY +// +#define SEC_E_NO_KERB_KEY _HRESULT_TYPEDEF_(0x80090348L) + +// +// MessageId: SEC_E_CERT_WRONG_USAGE +// +// MessageText: +// +// The certificate is not valid for the requested usage. +// +#define SEC_E_CERT_WRONG_USAGE _HRESULT_TYPEDEF_(0x80090349L) + +// +// MessageId: SEC_E_DOWNGRADE_DETECTED +// +// MessageText: +// +// The system detected a possible attempt to compromise security. Please ensure that you can contact the server that authenticated you. +// +#define SEC_E_DOWNGRADE_DETECTED _HRESULT_TYPEDEF_(0x80090350L) + +// +// MessageId: SEC_E_SMARTCARD_CERT_REVOKED +// +// MessageText: +// +// The smartcard certificate used for authentication has been revoked. +// Please contact your system administrator. There may be additional information in the +// event log. +// +#define SEC_E_SMARTCARD_CERT_REVOKED _HRESULT_TYPEDEF_(0x80090351L) + +// +// MessageId: SEC_E_ISSUING_CA_UNTRUSTED +// +// MessageText: +// +// An untrusted certificate authority was detected While processing the +// smartcard certificate used for authentication. Please contact your system +// administrator. +// +#define SEC_E_ISSUING_CA_UNTRUSTED _HRESULT_TYPEDEF_(0x80090352L) + +// +// MessageId: SEC_E_REVOCATION_OFFLINE_C +// +// MessageText: +// +// The revocation status of the smartcard certificate used for +// authentication could not be determined. Please contact your system administrator. +// +#define SEC_E_REVOCATION_OFFLINE_C _HRESULT_TYPEDEF_(0x80090353L) + +// +// MessageId: SEC_E_PKINIT_CLIENT_FAILURE +// +// MessageText: +// +// The smartcard certificate used for authentication was not trusted. Please +// contact your system administrator. +// +#define SEC_E_PKINIT_CLIENT_FAILURE _HRESULT_TYPEDEF_(0x80090354L) + +// +// MessageId: SEC_E_SMARTCARD_CERT_EXPIRED +// +// MessageText: +// +// The smartcard certificate used for authentication has expired. Please +// contact your system administrator. +// +#define SEC_E_SMARTCARD_CERT_EXPIRED _HRESULT_TYPEDEF_(0x80090355L) + +// +// MessageId: SEC_E_NO_S4U_PROT_SUPPORT +// +// MessageText: +// +// The Kerberos subsystem encountered an error. A service for user protocol request was made +// against a domain controller which does not support service for user. +// +#define SEC_E_NO_S4U_PROT_SUPPORT _HRESULT_TYPEDEF_(0x80090356L) + +// +// MessageId: SEC_E_CROSSREALM_DELEGATION_FAILURE +// +// MessageText: +// +// An attempt was made by this server to make a Kerberos constrained delegation request for a target +// outside of the server's realm. This is not supported, and indicates a misconfiguration on this +// server's allowed to delegate to list. Please contact your administrator. +// +#define SEC_E_CROSSREALM_DELEGATION_FAILURE _HRESULT_TYPEDEF_(0x80090357L) + +// +// MessageId: SEC_E_REVOCATION_OFFLINE_KDC +// +// MessageText: +// +// The revocation status of the domain controller certificate used for smartcard +// authentication could not be determined. There is additional information in the system event +// log. Please contact your system administrator. +// +#define SEC_E_REVOCATION_OFFLINE_KDC _HRESULT_TYPEDEF_(0x80090358L) + +// +// MessageId: SEC_E_ISSUING_CA_UNTRUSTED_KDC +// +// MessageText: +// +// An untrusted certificate authority was detected while processing the +// domain controller certificate used for authentication. There is additional information in +// the system event log. Please contact your system administrator. +// +#define SEC_E_ISSUING_CA_UNTRUSTED_KDC _HRESULT_TYPEDEF_(0x80090359L) + +// +// MessageId: SEC_E_KDC_CERT_EXPIRED +// +// MessageText: +// +// The domain controller certificate used for smartcard logon has expired. +// Please contact your system administrator with the contents of your system event log. +// +#define SEC_E_KDC_CERT_EXPIRED _HRESULT_TYPEDEF_(0x8009035AL) + +// +// MessageId: SEC_E_KDC_CERT_REVOKED +// +// MessageText: +// +// The domain controller certificate used for smartcard logon has been revoked. +// Please contact your system administrator with the contents of your system event log. +// +#define SEC_E_KDC_CERT_REVOKED _HRESULT_TYPEDEF_(0x8009035BL) + +// +// Provided for backwards compatibility +// + +#define SEC_E_NO_SPM SEC_E_INTERNAL_ERROR +#define SEC_E_NOT_SUPPORTED SEC_E_UNSUPPORTED_FUNCTION + +// +// MessageId: CRYPT_E_MSG_ERROR +// +// MessageText: +// +// An error occurred while performing an operation on a cryptographic message. +// +#define CRYPT_E_MSG_ERROR _HRESULT_TYPEDEF_(0x80091001L) + +// +// MessageId: CRYPT_E_UNKNOWN_ALGO +// +// MessageText: +// +// Unknown cryptographic algorithm. +// +#define CRYPT_E_UNKNOWN_ALGO _HRESULT_TYPEDEF_(0x80091002L) + +// +// MessageId: CRYPT_E_OID_FORMAT +// +// MessageText: +// +// The object identifier is poorly formatted. +// +#define CRYPT_E_OID_FORMAT _HRESULT_TYPEDEF_(0x80091003L) + +// +// MessageId: CRYPT_E_INVALID_MSG_TYPE +// +// MessageText: +// +// Invalid cryptographic message type. +// +#define CRYPT_E_INVALID_MSG_TYPE _HRESULT_TYPEDEF_(0x80091004L) + +// +// MessageId: CRYPT_E_UNEXPECTED_ENCODING +// +// MessageText: +// +// Unexpected cryptographic message encoding. +// +#define CRYPT_E_UNEXPECTED_ENCODING _HRESULT_TYPEDEF_(0x80091005L) + +// +// MessageId: CRYPT_E_AUTH_ATTR_MISSING +// +// MessageText: +// +// The cryptographic message does not contain an expected authenticated attribute. +// +#define CRYPT_E_AUTH_ATTR_MISSING _HRESULT_TYPEDEF_(0x80091006L) + +// +// MessageId: CRYPT_E_HASH_VALUE +// +// MessageText: +// +// The hash value is not correct. +// +#define CRYPT_E_HASH_VALUE _HRESULT_TYPEDEF_(0x80091007L) + +// +// MessageId: CRYPT_E_INVALID_INDEX +// +// MessageText: +// +// The index value is not valid. +// +#define CRYPT_E_INVALID_INDEX _HRESULT_TYPEDEF_(0x80091008L) + +// +// MessageId: CRYPT_E_ALREADY_DECRYPTED +// +// MessageText: +// +// The content of the cryptographic message has already been decrypted. +// +#define CRYPT_E_ALREADY_DECRYPTED _HRESULT_TYPEDEF_(0x80091009L) + +// +// MessageId: CRYPT_E_NOT_DECRYPTED +// +// MessageText: +// +// The content of the cryptographic message has not been decrypted yet. +// +#define CRYPT_E_NOT_DECRYPTED _HRESULT_TYPEDEF_(0x8009100AL) + +// +// MessageId: CRYPT_E_RECIPIENT_NOT_FOUND +// +// MessageText: +// +// The enveloped-data message does not contain the specified recipient. +// +#define CRYPT_E_RECIPIENT_NOT_FOUND _HRESULT_TYPEDEF_(0x8009100BL) + +// +// MessageId: CRYPT_E_CONTROL_TYPE +// +// MessageText: +// +// Invalid control type. +// +#define CRYPT_E_CONTROL_TYPE _HRESULT_TYPEDEF_(0x8009100CL) + +// +// MessageId: CRYPT_E_ISSUER_SERIALNUMBER +// +// MessageText: +// +// Invalid issuer and/or serial number. +// +#define CRYPT_E_ISSUER_SERIALNUMBER _HRESULT_TYPEDEF_(0x8009100DL) + +// +// MessageId: CRYPT_E_SIGNER_NOT_FOUND +// +// MessageText: +// +// Cannot find the original signer. +// +#define CRYPT_E_SIGNER_NOT_FOUND _HRESULT_TYPEDEF_(0x8009100EL) + +// +// MessageId: CRYPT_E_ATTRIBUTES_MISSING +// +// MessageText: +// +// The cryptographic message does not contain all of the requested attributes. +// +#define CRYPT_E_ATTRIBUTES_MISSING _HRESULT_TYPEDEF_(0x8009100FL) + +// +// MessageId: CRYPT_E_STREAM_MSG_NOT_READY +// +// MessageText: +// +// The streamed cryptographic message is not ready to return data. +// +#define CRYPT_E_STREAM_MSG_NOT_READY _HRESULT_TYPEDEF_(0x80091010L) + +// +// MessageId: CRYPT_E_STREAM_INSUFFICIENT_DATA +// +// MessageText: +// +// The streamed cryptographic message requires more data to complete the decode operation. +// +#define CRYPT_E_STREAM_INSUFFICIENT_DATA _HRESULT_TYPEDEF_(0x80091011L) + +// +// MessageId: CRYPT_I_NEW_PROTECTION_REQUIRED +// +// MessageText: +// +// The protected data needs to be re-protected. +// +#define CRYPT_I_NEW_PROTECTION_REQUIRED _HRESULT_TYPEDEF_(0x00091012L) + +// +// MessageId: CRYPT_E_BAD_LEN +// +// MessageText: +// +// The length specified for the output data was insufficient. +// +#define CRYPT_E_BAD_LEN _HRESULT_TYPEDEF_(0x80092001L) + +// +// MessageId: CRYPT_E_BAD_ENCODE +// +// MessageText: +// +// An error occurred during encode or decode operation. +// +#define CRYPT_E_BAD_ENCODE _HRESULT_TYPEDEF_(0x80092002L) + +// +// MessageId: CRYPT_E_FILE_ERROR +// +// MessageText: +// +// An error occurred while reading or writing to a file. +// +#define CRYPT_E_FILE_ERROR _HRESULT_TYPEDEF_(0x80092003L) + +// +// MessageId: CRYPT_E_NOT_FOUND +// +// MessageText: +// +// Cannot find object or property. +// +#define CRYPT_E_NOT_FOUND _HRESULT_TYPEDEF_(0x80092004L) + +// +// MessageId: CRYPT_E_EXISTS +// +// MessageText: +// +// The object or property already exists. +// +#define CRYPT_E_EXISTS _HRESULT_TYPEDEF_(0x80092005L) + +// +// MessageId: CRYPT_E_NO_PROVIDER +// +// MessageText: +// +// No provider was specified for the store or object. +// +#define CRYPT_E_NO_PROVIDER _HRESULT_TYPEDEF_(0x80092006L) + +// +// MessageId: CRYPT_E_SELF_SIGNED +// +// MessageText: +// +// The specified certificate is self signed. +// +#define CRYPT_E_SELF_SIGNED _HRESULT_TYPEDEF_(0x80092007L) + +// +// MessageId: CRYPT_E_DELETED_PREV +// +// MessageText: +// +// The previous certificate or CRL context was deleted. +// +#define CRYPT_E_DELETED_PREV _HRESULT_TYPEDEF_(0x80092008L) + +// +// MessageId: CRYPT_E_NO_MATCH +// +// MessageText: +// +// Cannot find the requested object. +// +#define CRYPT_E_NO_MATCH _HRESULT_TYPEDEF_(0x80092009L) + +// +// MessageId: CRYPT_E_UNEXPECTED_MSG_TYPE +// +// MessageText: +// +// The certificate does not have a property that references a private key. +// +#define CRYPT_E_UNEXPECTED_MSG_TYPE _HRESULT_TYPEDEF_(0x8009200AL) + +// +// MessageId: CRYPT_E_NO_KEY_PROPERTY +// +// MessageText: +// +// Cannot find the certificate and private key for decryption. +// +#define CRYPT_E_NO_KEY_PROPERTY _HRESULT_TYPEDEF_(0x8009200BL) + +// +// MessageId: CRYPT_E_NO_DECRYPT_CERT +// +// MessageText: +// +// Cannot find the certificate and private key to use for decryption. +// +#define CRYPT_E_NO_DECRYPT_CERT _HRESULT_TYPEDEF_(0x8009200CL) + +// +// MessageId: CRYPT_E_BAD_MSG +// +// MessageText: +// +// Not a cryptographic message or the cryptographic message is not formatted correctly. +// +#define CRYPT_E_BAD_MSG _HRESULT_TYPEDEF_(0x8009200DL) + +// +// MessageId: CRYPT_E_NO_SIGNER +// +// MessageText: +// +// The signed cryptographic message does not have a signer for the specified signer index. +// +#define CRYPT_E_NO_SIGNER _HRESULT_TYPEDEF_(0x8009200EL) + +// +// MessageId: CRYPT_E_PENDING_CLOSE +// +// MessageText: +// +// Final closure is pending until additional frees or closes. +// +#define CRYPT_E_PENDING_CLOSE _HRESULT_TYPEDEF_(0x8009200FL) + +// +// MessageId: CRYPT_E_REVOKED +// +// MessageText: +// +// The certificate is revoked. +// +#define CRYPT_E_REVOKED _HRESULT_TYPEDEF_(0x80092010L) + +// +// MessageId: CRYPT_E_NO_REVOCATION_DLL +// +// MessageText: +// +// No Dll or exported function was found to verify revocation. +// +#define CRYPT_E_NO_REVOCATION_DLL _HRESULT_TYPEDEF_(0x80092011L) + +// +// MessageId: CRYPT_E_NO_REVOCATION_CHECK +// +// MessageText: +// +// The revocation function was unable to check revocation for the certificate. +// +#define CRYPT_E_NO_REVOCATION_CHECK _HRESULT_TYPEDEF_(0x80092012L) + +// +// MessageId: CRYPT_E_REVOCATION_OFFLINE +// +// MessageText: +// +// The revocation function was unable to check revocation because the revocation server was offline. +// +#define CRYPT_E_REVOCATION_OFFLINE _HRESULT_TYPEDEF_(0x80092013L) + +// +// MessageId: CRYPT_E_NOT_IN_REVOCATION_DATABASE +// +// MessageText: +// +// The certificate is not in the revocation server's database. +// +#define CRYPT_E_NOT_IN_REVOCATION_DATABASE _HRESULT_TYPEDEF_(0x80092014L) + +// +// MessageId: CRYPT_E_INVALID_NUMERIC_STRING +// +// MessageText: +// +// The string contains a non-numeric character. +// +#define CRYPT_E_INVALID_NUMERIC_STRING _HRESULT_TYPEDEF_(0x80092020L) + +// +// MessageId: CRYPT_E_INVALID_PRINTABLE_STRING +// +// MessageText: +// +// The string contains a non-printable character. +// +#define CRYPT_E_INVALID_PRINTABLE_STRING _HRESULT_TYPEDEF_(0x80092021L) + +// +// MessageId: CRYPT_E_INVALID_IA5_STRING +// +// MessageText: +// +// The string contains a character not in the 7 bit ASCII character set. +// +#define CRYPT_E_INVALID_IA5_STRING _HRESULT_TYPEDEF_(0x80092022L) + +// +// MessageId: CRYPT_E_INVALID_X500_STRING +// +// MessageText: +// +// The string contains an invalid X500 name attribute key, oid, value or delimiter. +// +#define CRYPT_E_INVALID_X500_STRING _HRESULT_TYPEDEF_(0x80092023L) + +// +// MessageId: CRYPT_E_NOT_CHAR_STRING +// +// MessageText: +// +// The dwValueType for the CERT_NAME_VALUE is not one of the character strings. Most likely it is either a CERT_RDN_ENCODED_BLOB or CERT_TDN_OCTED_STRING. +// +#define CRYPT_E_NOT_CHAR_STRING _HRESULT_TYPEDEF_(0x80092024L) + +// +// MessageId: CRYPT_E_FILERESIZED +// +// MessageText: +// +// The Put operation can not continue. The file needs to be resized. However, there is already a signature present. A complete signing operation must be done. +// +#define CRYPT_E_FILERESIZED _HRESULT_TYPEDEF_(0x80092025L) + +// +// MessageId: CRYPT_E_SECURITY_SETTINGS +// +// MessageText: +// +// The cryptographic operation failed due to a local security option setting. +// +#define CRYPT_E_SECURITY_SETTINGS _HRESULT_TYPEDEF_(0x80092026L) + +// +// MessageId: CRYPT_E_NO_VERIFY_USAGE_DLL +// +// MessageText: +// +// No DLL or exported function was found to verify subject usage. +// +#define CRYPT_E_NO_VERIFY_USAGE_DLL _HRESULT_TYPEDEF_(0x80092027L) + +// +// MessageId: CRYPT_E_NO_VERIFY_USAGE_CHECK +// +// MessageText: +// +// The called function was unable to do a usage check on the subject. +// +#define CRYPT_E_NO_VERIFY_USAGE_CHECK _HRESULT_TYPEDEF_(0x80092028L) + +// +// MessageId: CRYPT_E_VERIFY_USAGE_OFFLINE +// +// MessageText: +// +// Since the server was offline, the called function was unable to complete the usage check. +// +#define CRYPT_E_VERIFY_USAGE_OFFLINE _HRESULT_TYPEDEF_(0x80092029L) + +// +// MessageId: CRYPT_E_NOT_IN_CTL +// +// MessageText: +// +// The subject was not found in a Certificate Trust List (CTL). +// +#define CRYPT_E_NOT_IN_CTL _HRESULT_TYPEDEF_(0x8009202AL) + +// +// MessageId: CRYPT_E_NO_TRUSTED_SIGNER +// +// MessageText: +// +// None of the signers of the cryptographic message or certificate trust list is trusted. +// +#define CRYPT_E_NO_TRUSTED_SIGNER _HRESULT_TYPEDEF_(0x8009202BL) + +// +// MessageId: CRYPT_E_MISSING_PUBKEY_PARA +// +// MessageText: +// +// The public key's algorithm parameters are missing. +// +#define CRYPT_E_MISSING_PUBKEY_PARA _HRESULT_TYPEDEF_(0x8009202CL) + +// +// MessageId: CRYPT_E_OSS_ERROR +// +// MessageText: +// +// OSS Certificate encode/decode error code base +// +// See asn1code.h for a definition of the OSS runtime errors. The OSS +// error values are offset by CRYPT_E_OSS_ERROR. +// +#define CRYPT_E_OSS_ERROR _HRESULT_TYPEDEF_(0x80093000L) + +// +// MessageId: OSS_MORE_BUF +// +// MessageText: +// +// OSS ASN.1 Error: Output Buffer is too small. +// +#define OSS_MORE_BUF _HRESULT_TYPEDEF_(0x80093001L) + +// +// MessageId: OSS_NEGATIVE_UINTEGER +// +// MessageText: +// +// OSS ASN.1 Error: Signed integer is encoded as a unsigned integer. +// +#define OSS_NEGATIVE_UINTEGER _HRESULT_TYPEDEF_(0x80093002L) + +// +// MessageId: OSS_PDU_RANGE +// +// MessageText: +// +// OSS ASN.1 Error: Unknown ASN.1 data type. +// +#define OSS_PDU_RANGE _HRESULT_TYPEDEF_(0x80093003L) + +// +// MessageId: OSS_MORE_INPUT +// +// MessageText: +// +// OSS ASN.1 Error: Output buffer is too small, the decoded data has been truncated. +// +#define OSS_MORE_INPUT _HRESULT_TYPEDEF_(0x80093004L) + +// +// MessageId: OSS_DATA_ERROR +// +// MessageText: +// +// OSS ASN.1 Error: Invalid data. +// +#define OSS_DATA_ERROR _HRESULT_TYPEDEF_(0x80093005L) + +// +// MessageId: OSS_BAD_ARG +// +// MessageText: +// +// OSS ASN.1 Error: Invalid argument. +// +#define OSS_BAD_ARG _HRESULT_TYPEDEF_(0x80093006L) + +// +// MessageId: OSS_BAD_VERSION +// +// MessageText: +// +// OSS ASN.1 Error: Encode/Decode version mismatch. +// +#define OSS_BAD_VERSION _HRESULT_TYPEDEF_(0x80093007L) + +// +// MessageId: OSS_OUT_MEMORY +// +// MessageText: +// +// OSS ASN.1 Error: Out of memory. +// +#define OSS_OUT_MEMORY _HRESULT_TYPEDEF_(0x80093008L) + +// +// MessageId: OSS_PDU_MISMATCH +// +// MessageText: +// +// OSS ASN.1 Error: Encode/Decode Error. +// +#define OSS_PDU_MISMATCH _HRESULT_TYPEDEF_(0x80093009L) + +// +// MessageId: OSS_LIMITED +// +// MessageText: +// +// OSS ASN.1 Error: Internal Error. +// +#define OSS_LIMITED _HRESULT_TYPEDEF_(0x8009300AL) + +// +// MessageId: OSS_BAD_PTR +// +// MessageText: +// +// OSS ASN.1 Error: Invalid data. +// +#define OSS_BAD_PTR _HRESULT_TYPEDEF_(0x8009300BL) + +// +// MessageId: OSS_BAD_TIME +// +// MessageText: +// +// OSS ASN.1 Error: Invalid data. +// +#define OSS_BAD_TIME _HRESULT_TYPEDEF_(0x8009300CL) + +// +// MessageId: OSS_INDEFINITE_NOT_SUPPORTED +// +// MessageText: +// +// OSS ASN.1 Error: Unsupported BER indefinite-length encoding. +// +#define OSS_INDEFINITE_NOT_SUPPORTED _HRESULT_TYPEDEF_(0x8009300DL) + +// +// MessageId: OSS_MEM_ERROR +// +// MessageText: +// +// OSS ASN.1 Error: Access violation. +// +#define OSS_MEM_ERROR _HRESULT_TYPEDEF_(0x8009300EL) + +// +// MessageId: OSS_BAD_TABLE +// +// MessageText: +// +// OSS ASN.1 Error: Invalid data. +// +#define OSS_BAD_TABLE _HRESULT_TYPEDEF_(0x8009300FL) + +// +// MessageId: OSS_TOO_LONG +// +// MessageText: +// +// OSS ASN.1 Error: Invalid data. +// +#define OSS_TOO_LONG _HRESULT_TYPEDEF_(0x80093010L) + +// +// MessageId: OSS_CONSTRAINT_VIOLATED +// +// MessageText: +// +// OSS ASN.1 Error: Invalid data. +// +#define OSS_CONSTRAINT_VIOLATED _HRESULT_TYPEDEF_(0x80093011L) + +// +// MessageId: OSS_FATAL_ERROR +// +// MessageText: +// +// OSS ASN.1 Error: Internal Error. +// +#define OSS_FATAL_ERROR _HRESULT_TYPEDEF_(0x80093012L) + +// +// MessageId: OSS_ACCESS_SERIALIZATION_ERROR +// +// MessageText: +// +// OSS ASN.1 Error: Multi-threading conflict. +// +#define OSS_ACCESS_SERIALIZATION_ERROR _HRESULT_TYPEDEF_(0x80093013L) + +// +// MessageId: OSS_NULL_TBL +// +// MessageText: +// +// OSS ASN.1 Error: Invalid data. +// +#define OSS_NULL_TBL _HRESULT_TYPEDEF_(0x80093014L) + +// +// MessageId: OSS_NULL_FCN +// +// MessageText: +// +// OSS ASN.1 Error: Invalid data. +// +#define OSS_NULL_FCN _HRESULT_TYPEDEF_(0x80093015L) + +// +// MessageId: OSS_BAD_ENCRULES +// +// MessageText: +// +// OSS ASN.1 Error: Invalid data. +// +#define OSS_BAD_ENCRULES _HRESULT_TYPEDEF_(0x80093016L) + +// +// MessageId: OSS_UNAVAIL_ENCRULES +// +// MessageText: +// +// OSS ASN.1 Error: Encode/Decode function not implemented. +// +#define OSS_UNAVAIL_ENCRULES _HRESULT_TYPEDEF_(0x80093017L) + +// +// MessageId: OSS_CANT_OPEN_TRACE_WINDOW +// +// MessageText: +// +// OSS ASN.1 Error: Trace file error. +// +#define OSS_CANT_OPEN_TRACE_WINDOW _HRESULT_TYPEDEF_(0x80093018L) + +// +// MessageId: OSS_UNIMPLEMENTED +// +// MessageText: +// +// OSS ASN.1 Error: Function not implemented. +// +#define OSS_UNIMPLEMENTED _HRESULT_TYPEDEF_(0x80093019L) + +// +// MessageId: OSS_OID_DLL_NOT_LINKED +// +// MessageText: +// +// OSS ASN.1 Error: Program link error. +// +#define OSS_OID_DLL_NOT_LINKED _HRESULT_TYPEDEF_(0x8009301AL) + +// +// MessageId: OSS_CANT_OPEN_TRACE_FILE +// +// MessageText: +// +// OSS ASN.1 Error: Trace file error. +// +#define OSS_CANT_OPEN_TRACE_FILE _HRESULT_TYPEDEF_(0x8009301BL) + +// +// MessageId: OSS_TRACE_FILE_ALREADY_OPEN +// +// MessageText: +// +// OSS ASN.1 Error: Trace file error. +// +#define OSS_TRACE_FILE_ALREADY_OPEN _HRESULT_TYPEDEF_(0x8009301CL) + +// +// MessageId: OSS_TABLE_MISMATCH +// +// MessageText: +// +// OSS ASN.1 Error: Invalid data. +// +#define OSS_TABLE_MISMATCH _HRESULT_TYPEDEF_(0x8009301DL) + +// +// MessageId: OSS_TYPE_NOT_SUPPORTED +// +// MessageText: +// +// OSS ASN.1 Error: Invalid data. +// +#define OSS_TYPE_NOT_SUPPORTED _HRESULT_TYPEDEF_(0x8009301EL) + +// +// MessageId: OSS_REAL_DLL_NOT_LINKED +// +// MessageText: +// +// OSS ASN.1 Error: Program link error. +// +#define OSS_REAL_DLL_NOT_LINKED _HRESULT_TYPEDEF_(0x8009301FL) + +// +// MessageId: OSS_REAL_CODE_NOT_LINKED +// +// MessageText: +// +// OSS ASN.1 Error: Program link error. +// +#define OSS_REAL_CODE_NOT_LINKED _HRESULT_TYPEDEF_(0x80093020L) + +// +// MessageId: OSS_OUT_OF_RANGE +// +// MessageText: +// +// OSS ASN.1 Error: Program link error. +// +#define OSS_OUT_OF_RANGE _HRESULT_TYPEDEF_(0x80093021L) + +// +// MessageId: OSS_COPIER_DLL_NOT_LINKED +// +// MessageText: +// +// OSS ASN.1 Error: Program link error. +// +#define OSS_COPIER_DLL_NOT_LINKED _HRESULT_TYPEDEF_(0x80093022L) + +// +// MessageId: OSS_CONSTRAINT_DLL_NOT_LINKED +// +// MessageText: +// +// OSS ASN.1 Error: Program link error. +// +#define OSS_CONSTRAINT_DLL_NOT_LINKED _HRESULT_TYPEDEF_(0x80093023L) + +// +// MessageId: OSS_COMPARATOR_DLL_NOT_LINKED +// +// MessageText: +// +// OSS ASN.1 Error: Program link error. +// +#define OSS_COMPARATOR_DLL_NOT_LINKED _HRESULT_TYPEDEF_(0x80093024L) + +// +// MessageId: OSS_COMPARATOR_CODE_NOT_LINKED +// +// MessageText: +// +// OSS ASN.1 Error: Program link error. +// +#define OSS_COMPARATOR_CODE_NOT_LINKED _HRESULT_TYPEDEF_(0x80093025L) + +// +// MessageId: OSS_MEM_MGR_DLL_NOT_LINKED +// +// MessageText: +// +// OSS ASN.1 Error: Program link error. +// +#define OSS_MEM_MGR_DLL_NOT_LINKED _HRESULT_TYPEDEF_(0x80093026L) + +// +// MessageId: OSS_PDV_DLL_NOT_LINKED +// +// MessageText: +// +// OSS ASN.1 Error: Program link error. +// +#define OSS_PDV_DLL_NOT_LINKED _HRESULT_TYPEDEF_(0x80093027L) + +// +// MessageId: OSS_PDV_CODE_NOT_LINKED +// +// MessageText: +// +// OSS ASN.1 Error: Program link error. +// +#define OSS_PDV_CODE_NOT_LINKED _HRESULT_TYPEDEF_(0x80093028L) + +// +// MessageId: OSS_API_DLL_NOT_LINKED +// +// MessageText: +// +// OSS ASN.1 Error: Program link error. +// +#define OSS_API_DLL_NOT_LINKED _HRESULT_TYPEDEF_(0x80093029L) + +// +// MessageId: OSS_BERDER_DLL_NOT_LINKED +// +// MessageText: +// +// OSS ASN.1 Error: Program link error. +// +#define OSS_BERDER_DLL_NOT_LINKED _HRESULT_TYPEDEF_(0x8009302AL) + +// +// MessageId: OSS_PER_DLL_NOT_LINKED +// +// MessageText: +// +// OSS ASN.1 Error: Program link error. +// +#define OSS_PER_DLL_NOT_LINKED _HRESULT_TYPEDEF_(0x8009302BL) + +// +// MessageId: OSS_OPEN_TYPE_ERROR +// +// MessageText: +// +// OSS ASN.1 Error: Program link error. +// +#define OSS_OPEN_TYPE_ERROR _HRESULT_TYPEDEF_(0x8009302CL) + +// +// MessageId: OSS_MUTEX_NOT_CREATED +// +// MessageText: +// +// OSS ASN.1 Error: System resource error. +// +#define OSS_MUTEX_NOT_CREATED _HRESULT_TYPEDEF_(0x8009302DL) + +// +// MessageId: OSS_CANT_CLOSE_TRACE_FILE +// +// MessageText: +// +// OSS ASN.1 Error: Trace file error. +// +#define OSS_CANT_CLOSE_TRACE_FILE _HRESULT_TYPEDEF_(0x8009302EL) + +// +// MessageId: CRYPT_E_ASN1_ERROR +// +// MessageText: +// +// ASN1 Certificate encode/decode error code base. +// +// The ASN1 error values are offset by CRYPT_E_ASN1_ERROR. +// +#define CRYPT_E_ASN1_ERROR _HRESULT_TYPEDEF_(0x80093100L) + +// +// MessageId: CRYPT_E_ASN1_INTERNAL +// +// MessageText: +// +// ASN1 internal encode or decode error. +// +#define CRYPT_E_ASN1_INTERNAL _HRESULT_TYPEDEF_(0x80093101L) + +// +// MessageId: CRYPT_E_ASN1_EOD +// +// MessageText: +// +// ASN1 unexpected end of data. +// +#define CRYPT_E_ASN1_EOD _HRESULT_TYPEDEF_(0x80093102L) + +// +// MessageId: CRYPT_E_ASN1_CORRUPT +// +// MessageText: +// +// ASN1 corrupted data. +// +#define CRYPT_E_ASN1_CORRUPT _HRESULT_TYPEDEF_(0x80093103L) + +// +// MessageId: CRYPT_E_ASN1_LARGE +// +// MessageText: +// +// ASN1 value too large. +// +#define CRYPT_E_ASN1_LARGE _HRESULT_TYPEDEF_(0x80093104L) + +// +// MessageId: CRYPT_E_ASN1_CONSTRAINT +// +// MessageText: +// +// ASN1 constraint violated. +// +#define CRYPT_E_ASN1_CONSTRAINT _HRESULT_TYPEDEF_(0x80093105L) + +// +// MessageId: CRYPT_E_ASN1_MEMORY +// +// MessageText: +// +// ASN1 out of memory. +// +#define CRYPT_E_ASN1_MEMORY _HRESULT_TYPEDEF_(0x80093106L) + +// +// MessageId: CRYPT_E_ASN1_OVERFLOW +// +// MessageText: +// +// ASN1 buffer overflow. +// +#define CRYPT_E_ASN1_OVERFLOW _HRESULT_TYPEDEF_(0x80093107L) + +// +// MessageId: CRYPT_E_ASN1_BADPDU +// +// MessageText: +// +// ASN1 function not supported for this PDU. +// +#define CRYPT_E_ASN1_BADPDU _HRESULT_TYPEDEF_(0x80093108L) + +// +// MessageId: CRYPT_E_ASN1_BADARGS +// +// MessageText: +// +// ASN1 bad arguments to function call. +// +#define CRYPT_E_ASN1_BADARGS _HRESULT_TYPEDEF_(0x80093109L) + +// +// MessageId: CRYPT_E_ASN1_BADREAL +// +// MessageText: +// +// ASN1 bad real value. +// +#define CRYPT_E_ASN1_BADREAL _HRESULT_TYPEDEF_(0x8009310AL) + +// +// MessageId: CRYPT_E_ASN1_BADTAG +// +// MessageText: +// +// ASN1 bad tag value met. +// +#define CRYPT_E_ASN1_BADTAG _HRESULT_TYPEDEF_(0x8009310BL) + +// +// MessageId: CRYPT_E_ASN1_CHOICE +// +// MessageText: +// +// ASN1 bad choice value. +// +#define CRYPT_E_ASN1_CHOICE _HRESULT_TYPEDEF_(0x8009310CL) + +// +// MessageId: CRYPT_E_ASN1_RULE +// +// MessageText: +// +// ASN1 bad encoding rule. +// +#define CRYPT_E_ASN1_RULE _HRESULT_TYPEDEF_(0x8009310DL) + +// +// MessageId: CRYPT_E_ASN1_UTF8 +// +// MessageText: +// +// ASN1 bad unicode (UTF8). +// +#define CRYPT_E_ASN1_UTF8 _HRESULT_TYPEDEF_(0x8009310EL) + +// +// MessageId: CRYPT_E_ASN1_PDU_TYPE +// +// MessageText: +// +// ASN1 bad PDU type. +// +#define CRYPT_E_ASN1_PDU_TYPE _HRESULT_TYPEDEF_(0x80093133L) + +// +// MessageId: CRYPT_E_ASN1_NYI +// +// MessageText: +// +// ASN1 not yet implemented. +// +#define CRYPT_E_ASN1_NYI _HRESULT_TYPEDEF_(0x80093134L) + +// +// MessageId: CRYPT_E_ASN1_EXTENDED +// +// MessageText: +// +// ASN1 skipped unknown extension(s). +// +#define CRYPT_E_ASN1_EXTENDED _HRESULT_TYPEDEF_(0x80093201L) + +// +// MessageId: CRYPT_E_ASN1_NOEOD +// +// MessageText: +// +// ASN1 end of data expected +// +#define CRYPT_E_ASN1_NOEOD _HRESULT_TYPEDEF_(0x80093202L) + +// +// MessageId: CERTSRV_E_BAD_REQUESTSUBJECT +// +// MessageText: +// +// The request subject name is invalid or too long. +// +#define CERTSRV_E_BAD_REQUESTSUBJECT _HRESULT_TYPEDEF_(0x80094001L) + +// +// MessageId: CERTSRV_E_NO_REQUEST +// +// MessageText: +// +// The request does not exist. +// +#define CERTSRV_E_NO_REQUEST _HRESULT_TYPEDEF_(0x80094002L) + +// +// MessageId: CERTSRV_E_BAD_REQUESTSTATUS +// +// MessageText: +// +// The request's current status does not allow this operation. +// +#define CERTSRV_E_BAD_REQUESTSTATUS _HRESULT_TYPEDEF_(0x80094003L) + +// +// MessageId: CERTSRV_E_PROPERTY_EMPTY +// +// MessageText: +// +// The requested property value is empty. +// +#define CERTSRV_E_PROPERTY_EMPTY _HRESULT_TYPEDEF_(0x80094004L) + +// +// MessageId: CERTSRV_E_INVALID_CA_CERTIFICATE +// +// MessageText: +// +// The certification authority's certificate contains invalid data. +// +#define CERTSRV_E_INVALID_CA_CERTIFICATE _HRESULT_TYPEDEF_(0x80094005L) + +// +// MessageId: CERTSRV_E_SERVER_SUSPENDED +// +// MessageText: +// +// Certificate service has been suspended for a database restore operation. +// +#define CERTSRV_E_SERVER_SUSPENDED _HRESULT_TYPEDEF_(0x80094006L) + +// +// MessageId: CERTSRV_E_ENCODING_LENGTH +// +// MessageText: +// +// The certificate contains an encoded length that is potentially incompatible with older enrollment software. +// +#define CERTSRV_E_ENCODING_LENGTH _HRESULT_TYPEDEF_(0x80094007L) + +// +// MessageId: CERTSRV_E_ROLECONFLICT +// +// MessageText: +// +// The operation is denied. The user has multiple roles assigned and the certification authority is configured to enforce role separation. +// +#define CERTSRV_E_ROLECONFLICT _HRESULT_TYPEDEF_(0x80094008L) + +// +// MessageId: CERTSRV_E_RESTRICTEDOFFICER +// +// MessageText: +// +// The operation is denied. It can only be performed by a certificate manager that is allowed to manage certificates for the current requester. +// +#define CERTSRV_E_RESTRICTEDOFFICER _HRESULT_TYPEDEF_(0x80094009L) + +// +// MessageId: CERTSRV_E_KEY_ARCHIVAL_NOT_CONFIGURED +// +// MessageText: +// +// Cannot archive private key. The certification authority is not configured for key archival. +// +#define CERTSRV_E_KEY_ARCHIVAL_NOT_CONFIGURED _HRESULT_TYPEDEF_(0x8009400AL) + +// +// MessageId: CERTSRV_E_NO_VALID_KRA +// +// MessageText: +// +// Cannot archive private key. The certification authority could not verify one or more key recovery certificates. +// +#define CERTSRV_E_NO_VALID_KRA _HRESULT_TYPEDEF_(0x8009400BL) + +// +// MessageId: CERTSRV_E_BAD_REQUEST_KEY_ARCHIVAL +// +// MessageText: +// +// The request is incorrectly formatted. The encrypted private key must be in an unauthenticated attribute in an outermost signature. +// +#define CERTSRV_E_BAD_REQUEST_KEY_ARCHIVAL _HRESULT_TYPEDEF_(0x8009400CL) + +// +// MessageId: CERTSRV_E_NO_CAADMIN_DEFINED +// +// MessageText: +// +// At least one security principal must have the permission to manage this CA. +// +#define CERTSRV_E_NO_CAADMIN_DEFINED _HRESULT_TYPEDEF_(0x8009400DL) + +// +// MessageId: CERTSRV_E_BAD_RENEWAL_CERT_ATTRIBUTE +// +// MessageText: +// +// The request contains an invalid renewal certificate attribute. +// +#define CERTSRV_E_BAD_RENEWAL_CERT_ATTRIBUTE _HRESULT_TYPEDEF_(0x8009400EL) + +// +// MessageId: CERTSRV_E_NO_DB_SESSIONS +// +// MessageText: +// +// An attempt was made to open a Certification Authority database session, but there are already too many active sessions. The server may need to be configured to allow additional sessions. +// +#define CERTSRV_E_NO_DB_SESSIONS _HRESULT_TYPEDEF_(0x8009400FL) + +// +// MessageId: CERTSRV_E_ALIGNMENT_FAULT +// +// MessageText: +// +// A memory reference caused a data alignment fault. +// +#define CERTSRV_E_ALIGNMENT_FAULT _HRESULT_TYPEDEF_(0x80094010L) + +// +// MessageId: CERTSRV_E_ENROLL_DENIED +// +// MessageText: +// +// The permissions on this certification authority do not allow the current user to enroll for certificates. +// +#define CERTSRV_E_ENROLL_DENIED _HRESULT_TYPEDEF_(0x80094011L) + +// +// MessageId: CERTSRV_E_TEMPLATE_DENIED +// +// MessageText: +// +// The permissions on the certificate template do not allow the current user to enroll for this type of certificate. +// +#define CERTSRV_E_TEMPLATE_DENIED _HRESULT_TYPEDEF_(0x80094012L) + +// +// MessageId: CERTSRV_E_DOWNLEVEL_DC_SSL_OR_UPGRADE +// +// MessageText: +// +// The contacted domain controller cannot support signed LDAP traffic. Update the domain controller or configure Certificate Services to use SSL for Active Directory access. +// +#define CERTSRV_E_DOWNLEVEL_DC_SSL_OR_UPGRADE _HRESULT_TYPEDEF_(0x80094013L) + +// +// MessageId: CERTSRV_E_UNSUPPORTED_CERT_TYPE +// +// MessageText: +// +// The requested certificate template is not supported by this CA. +// +#define CERTSRV_E_UNSUPPORTED_CERT_TYPE _HRESULT_TYPEDEF_(0x80094800L) + +// +// MessageId: CERTSRV_E_NO_CERT_TYPE +// +// MessageText: +// +// The request contains no certificate template information. +// +#define CERTSRV_E_NO_CERT_TYPE _HRESULT_TYPEDEF_(0x80094801L) + +// +// MessageId: CERTSRV_E_TEMPLATE_CONFLICT +// +// MessageText: +// +// The request contains conflicting template information. +// +#define CERTSRV_E_TEMPLATE_CONFLICT _HRESULT_TYPEDEF_(0x80094802L) + +// +// MessageId: CERTSRV_E_SUBJECT_ALT_NAME_REQUIRED +// +// MessageText: +// +// The request is missing a required Subject Alternate name extension. +// +#define CERTSRV_E_SUBJECT_ALT_NAME_REQUIRED _HRESULT_TYPEDEF_(0x80094803L) + +// +// MessageId: CERTSRV_E_ARCHIVED_KEY_REQUIRED +// +// MessageText: +// +// The request is missing a required private key for archival by the server. +// +#define CERTSRV_E_ARCHIVED_KEY_REQUIRED _HRESULT_TYPEDEF_(0x80094804L) + +// +// MessageId: CERTSRV_E_SMIME_REQUIRED +// +// MessageText: +// +// The request is missing a required SMIME capabilities extension. +// +#define CERTSRV_E_SMIME_REQUIRED _HRESULT_TYPEDEF_(0x80094805L) + +// +// MessageId: CERTSRV_E_BAD_RENEWAL_SUBJECT +// +// MessageText: +// +// The request was made on behalf of a subject other than the caller. The certificate template must be configured to require at least one signature to authorize the request. +// +#define CERTSRV_E_BAD_RENEWAL_SUBJECT _HRESULT_TYPEDEF_(0x80094806L) + +// +// MessageId: CERTSRV_E_BAD_TEMPLATE_VERSION +// +// MessageText: +// +// The request template version is newer than the supported template version. +// +#define CERTSRV_E_BAD_TEMPLATE_VERSION _HRESULT_TYPEDEF_(0x80094807L) + +// +// MessageId: CERTSRV_E_TEMPLATE_POLICY_REQUIRED +// +// MessageText: +// +// The template is missing a required signature policy attribute. +// +#define CERTSRV_E_TEMPLATE_POLICY_REQUIRED _HRESULT_TYPEDEF_(0x80094808L) + +// +// MessageId: CERTSRV_E_SIGNATURE_POLICY_REQUIRED +// +// MessageText: +// +// The request is missing required signature policy information. +// +#define CERTSRV_E_SIGNATURE_POLICY_REQUIRED _HRESULT_TYPEDEF_(0x80094809L) + +// +// MessageId: CERTSRV_E_SIGNATURE_COUNT +// +// MessageText: +// +// The request is missing one or more required signatures. +// +#define CERTSRV_E_SIGNATURE_COUNT _HRESULT_TYPEDEF_(0x8009480AL) + +// +// MessageId: CERTSRV_E_SIGNATURE_REJECTED +// +// MessageText: +// +// One or more signatures did not include the required application or issuance policies. The request is missing one or more required valid signatures. +// +#define CERTSRV_E_SIGNATURE_REJECTED _HRESULT_TYPEDEF_(0x8009480BL) + +// +// MessageId: CERTSRV_E_ISSUANCE_POLICY_REQUIRED +// +// MessageText: +// +// The request is missing one or more required signature issuance policies. +// +#define CERTSRV_E_ISSUANCE_POLICY_REQUIRED _HRESULT_TYPEDEF_(0x8009480CL) + +// +// MessageId: CERTSRV_E_SUBJECT_UPN_REQUIRED +// +// MessageText: +// +// The UPN is unavailable and cannot be added to the Subject Alternate name. +// +#define CERTSRV_E_SUBJECT_UPN_REQUIRED _HRESULT_TYPEDEF_(0x8009480DL) + +// +// MessageId: CERTSRV_E_SUBJECT_DIRECTORY_GUID_REQUIRED +// +// MessageText: +// +// The Active Directory GUID is unavailable and cannot be added to the Subject Alternate name. +// +#define CERTSRV_E_SUBJECT_DIRECTORY_GUID_REQUIRED _HRESULT_TYPEDEF_(0x8009480EL) + +// +// MessageId: CERTSRV_E_SUBJECT_DNS_REQUIRED +// +// MessageText: +// +// The DNS name is unavailable and cannot be added to the Subject Alternate name. +// +#define CERTSRV_E_SUBJECT_DNS_REQUIRED _HRESULT_TYPEDEF_(0x8009480FL) + +// +// MessageId: CERTSRV_E_ARCHIVED_KEY_UNEXPECTED +// +// MessageText: +// +// The request includes a private key for archival by the server, but key archival is not enabled for the specified certificate template. +// +#define CERTSRV_E_ARCHIVED_KEY_UNEXPECTED _HRESULT_TYPEDEF_(0x80094810L) + +// +// MessageId: CERTSRV_E_KEY_LENGTH +// +// MessageText: +// +// The public key does not meet the minimum size required by the specified certificate template. +// +#define CERTSRV_E_KEY_LENGTH _HRESULT_TYPEDEF_(0x80094811L) + +// +// MessageId: CERTSRV_E_SUBJECT_EMAIL_REQUIRED +// +// MessageText: +// +// The EMail name is unavailable and cannot be added to the Subject or Subject Alternate name. +// +#define CERTSRV_E_SUBJECT_EMAIL_REQUIRED _HRESULT_TYPEDEF_(0x80094812L) + +// +// MessageId: CERTSRV_E_UNKNOWN_CERT_TYPE +// +// MessageText: +// +// One or more certificate templates to be enabled on this certification authority could not be found. +// +#define CERTSRV_E_UNKNOWN_CERT_TYPE _HRESULT_TYPEDEF_(0x80094813L) + +// +// MessageId: CERTSRV_E_CERT_TYPE_OVERLAP +// +// MessageText: +// +// The certificate template renewal period is longer than the certificate validity period. The template should be reconfigured or the CA certificate renewed. +// +#define CERTSRV_E_CERT_TYPE_OVERLAP _HRESULT_TYPEDEF_(0x80094814L) + +// +// The range 0x5000-0x51ff is reserved for XENROLL errors. +// +// +// MessageId: XENROLL_E_KEY_NOT_EXPORTABLE +// +// MessageText: +// +// The key is not exportable. +// +#define XENROLL_E_KEY_NOT_EXPORTABLE _HRESULT_TYPEDEF_(0x80095000L) + +// +// MessageId: XENROLL_E_CANNOT_ADD_ROOT_CERT +// +// MessageText: +// +// You cannot add the root CA certificate into your local store. +// +#define XENROLL_E_CANNOT_ADD_ROOT_CERT _HRESULT_TYPEDEF_(0x80095001L) + +// +// MessageId: XENROLL_E_RESPONSE_KA_HASH_NOT_FOUND +// +// MessageText: +// +// The key archival hash attribute was not found in the response. +// +#define XENROLL_E_RESPONSE_KA_HASH_NOT_FOUND _HRESULT_TYPEDEF_(0x80095002L) + +// +// MessageId: XENROLL_E_RESPONSE_UNEXPECTED_KA_HASH +// +// MessageText: +// +// An unexpected key archival hash attribute was found in the response. +// +#define XENROLL_E_RESPONSE_UNEXPECTED_KA_HASH _HRESULT_TYPEDEF_(0x80095003L) + +// +// MessageId: XENROLL_E_RESPONSE_KA_HASH_MISMATCH +// +// MessageText: +// +// There is a key archival hash mismatch between the request and the response. +// +#define XENROLL_E_RESPONSE_KA_HASH_MISMATCH _HRESULT_TYPEDEF_(0x80095004L) + +// +// MessageId: XENROLL_E_KEYSPEC_SMIME_MISMATCH +// +// MessageText: +// +// Signing certificate cannot include SMIME extension. +// +#define XENROLL_E_KEYSPEC_SMIME_MISMATCH _HRESULT_TYPEDEF_(0x80095005L) + +// +// MessageId: TRUST_E_SYSTEM_ERROR +// +// MessageText: +// +// A system-level error occurred while verifying trust. +// +#define TRUST_E_SYSTEM_ERROR _HRESULT_TYPEDEF_(0x80096001L) + +// +// MessageId: TRUST_E_NO_SIGNER_CERT +// +// MessageText: +// +// The certificate for the signer of the message is invalid or not found. +// +#define TRUST_E_NO_SIGNER_CERT _HRESULT_TYPEDEF_(0x80096002L) + +// +// MessageId: TRUST_E_COUNTER_SIGNER +// +// MessageText: +// +// One of the counter signatures was invalid. +// +#define TRUST_E_COUNTER_SIGNER _HRESULT_TYPEDEF_(0x80096003L) + +// +// MessageId: TRUST_E_CERT_SIGNATURE +// +// MessageText: +// +// The signature of the certificate can not be verified. +// +#define TRUST_E_CERT_SIGNATURE _HRESULT_TYPEDEF_(0x80096004L) + +// +// MessageId: TRUST_E_TIME_STAMP +// +// MessageText: +// +// The timestamp signature and/or certificate could not be verified or is malformed. +// +#define TRUST_E_TIME_STAMP _HRESULT_TYPEDEF_(0x80096005L) + +// +// MessageId: TRUST_E_BAD_DIGEST +// +// MessageText: +// +// The digital signature of the object did not verify. +// +#define TRUST_E_BAD_DIGEST _HRESULT_TYPEDEF_(0x80096010L) + +// +// MessageId: TRUST_E_BASIC_CONSTRAINTS +// +// MessageText: +// +// A certificate's basic constraint extension has not been observed. +// +#define TRUST_E_BASIC_CONSTRAINTS _HRESULT_TYPEDEF_(0x80096019L) + +// +// MessageId: TRUST_E_FINANCIAL_CRITERIA +// +// MessageText: +// +// The certificate does not meet or contain the Authenticode(tm) financial extensions. +// +#define TRUST_E_FINANCIAL_CRITERIA _HRESULT_TYPEDEF_(0x8009601EL) + +// +// Error codes for mssipotf.dll +// Most of the error codes can only occur when an error occurs +// during font file signing +// +// +// +// MessageId: MSSIPOTF_E_OUTOFMEMRANGE +// +// MessageText: +// +// Tried to reference a part of the file outside the proper range. +// +#define MSSIPOTF_E_OUTOFMEMRANGE _HRESULT_TYPEDEF_(0x80097001L) + +// +// MessageId: MSSIPOTF_E_CANTGETOBJECT +// +// MessageText: +// +// Could not retrieve an object from the file. +// +#define MSSIPOTF_E_CANTGETOBJECT _HRESULT_TYPEDEF_(0x80097002L) + +// +// MessageId: MSSIPOTF_E_NOHEADTABLE +// +// MessageText: +// +// Could not find the head table in the file. +// +#define MSSIPOTF_E_NOHEADTABLE _HRESULT_TYPEDEF_(0x80097003L) + +// +// MessageId: MSSIPOTF_E_BAD_MAGICNUMBER +// +// MessageText: +// +// The magic number in the head table is incorrect. +// +#define MSSIPOTF_E_BAD_MAGICNUMBER _HRESULT_TYPEDEF_(0x80097004L) + +// +// MessageId: MSSIPOTF_E_BAD_OFFSET_TABLE +// +// MessageText: +// +// The offset table has incorrect values. +// +#define MSSIPOTF_E_BAD_OFFSET_TABLE _HRESULT_TYPEDEF_(0x80097005L) + +// +// MessageId: MSSIPOTF_E_TABLE_TAGORDER +// +// MessageText: +// +// Duplicate table tags or tags out of alphabetical order. +// +#define MSSIPOTF_E_TABLE_TAGORDER _HRESULT_TYPEDEF_(0x80097006L) + +// +// MessageId: MSSIPOTF_E_TABLE_LONGWORD +// +// MessageText: +// +// A table does not start on a long word boundary. +// +#define MSSIPOTF_E_TABLE_LONGWORD _HRESULT_TYPEDEF_(0x80097007L) + +// +// MessageId: MSSIPOTF_E_BAD_FIRST_TABLE_PLACEMENT +// +// MessageText: +// +// First table does not appear after header information. +// +#define MSSIPOTF_E_BAD_FIRST_TABLE_PLACEMENT _HRESULT_TYPEDEF_(0x80097008L) + +// +// MessageId: MSSIPOTF_E_TABLES_OVERLAP +// +// MessageText: +// +// Two or more tables overlap. +// +#define MSSIPOTF_E_TABLES_OVERLAP _HRESULT_TYPEDEF_(0x80097009L) + +// +// MessageId: MSSIPOTF_E_TABLE_PADBYTES +// +// MessageText: +// +// Too many pad bytes between tables or pad bytes are not 0. +// +#define MSSIPOTF_E_TABLE_PADBYTES _HRESULT_TYPEDEF_(0x8009700AL) + +// +// MessageId: MSSIPOTF_E_FILETOOSMALL +// +// MessageText: +// +// File is too small to contain the last table. +// +#define MSSIPOTF_E_FILETOOSMALL _HRESULT_TYPEDEF_(0x8009700BL) + +// +// MessageId: MSSIPOTF_E_TABLE_CHECKSUM +// +// MessageText: +// +// A table checksum is incorrect. +// +#define MSSIPOTF_E_TABLE_CHECKSUM _HRESULT_TYPEDEF_(0x8009700CL) + +// +// MessageId: MSSIPOTF_E_FILE_CHECKSUM +// +// MessageText: +// +// The file checksum is incorrect. +// +#define MSSIPOTF_E_FILE_CHECKSUM _HRESULT_TYPEDEF_(0x8009700DL) + +// +// MessageId: MSSIPOTF_E_FAILED_POLICY +// +// MessageText: +// +// The signature does not have the correct attributes for the policy. +// +#define MSSIPOTF_E_FAILED_POLICY _HRESULT_TYPEDEF_(0x80097010L) + +// +// MessageId: MSSIPOTF_E_FAILED_HINTS_CHECK +// +// MessageText: +// +// The file did not pass the hints check. +// +#define MSSIPOTF_E_FAILED_HINTS_CHECK _HRESULT_TYPEDEF_(0x80097011L) + +// +// MessageId: MSSIPOTF_E_NOT_OPENTYPE +// +// MessageText: +// +// The file is not an OpenType file. +// +#define MSSIPOTF_E_NOT_OPENTYPE _HRESULT_TYPEDEF_(0x80097012L) + +// +// MessageId: MSSIPOTF_E_FILE +// +// MessageText: +// +// Failed on a file operation (open, map, read, write). +// +#define MSSIPOTF_E_FILE _HRESULT_TYPEDEF_(0x80097013L) + +// +// MessageId: MSSIPOTF_E_CRYPT +// +// MessageText: +// +// A call to a CryptoAPI function failed. +// +#define MSSIPOTF_E_CRYPT _HRESULT_TYPEDEF_(0x80097014L) + +// +// MessageId: MSSIPOTF_E_BADVERSION +// +// MessageText: +// +// There is a bad version number in the file. +// +#define MSSIPOTF_E_BADVERSION _HRESULT_TYPEDEF_(0x80097015L) + +// +// MessageId: MSSIPOTF_E_DSIG_STRUCTURE +// +// MessageText: +// +// The structure of the DSIG table is incorrect. +// +#define MSSIPOTF_E_DSIG_STRUCTURE _HRESULT_TYPEDEF_(0x80097016L) + +// +// MessageId: MSSIPOTF_E_PCONST_CHECK +// +// MessageText: +// +// A check failed in a partially constant table. +// +#define MSSIPOTF_E_PCONST_CHECK _HRESULT_TYPEDEF_(0x80097017L) + +// +// MessageId: MSSIPOTF_E_STRUCTURE +// +// MessageText: +// +// Some kind of structural error. +// +#define MSSIPOTF_E_STRUCTURE _HRESULT_TYPEDEF_(0x80097018L) + +#define NTE_OP_OK 0 + +// +// Note that additional FACILITY_SSPI errors are in issperr.h +// +// ****************** +// FACILITY_CERT +// ****************** +// +// MessageId: TRUST_E_PROVIDER_UNKNOWN +// +// MessageText: +// +// Unknown trust provider. +// +#define TRUST_E_PROVIDER_UNKNOWN _HRESULT_TYPEDEF_(0x800B0001L) + +// +// MessageId: TRUST_E_ACTION_UNKNOWN +// +// MessageText: +// +// The trust verification action specified is not supported by the specified trust provider. +// +#define TRUST_E_ACTION_UNKNOWN _HRESULT_TYPEDEF_(0x800B0002L) + +// +// MessageId: TRUST_E_SUBJECT_FORM_UNKNOWN +// +// MessageText: +// +// The form specified for the subject is not one supported or known by the specified trust provider. +// +#define TRUST_E_SUBJECT_FORM_UNKNOWN _HRESULT_TYPEDEF_(0x800B0003L) + +// +// MessageId: TRUST_E_SUBJECT_NOT_TRUSTED +// +// MessageText: +// +// The subject is not trusted for the specified action. +// +#define TRUST_E_SUBJECT_NOT_TRUSTED _HRESULT_TYPEDEF_(0x800B0004L) + +// +// MessageId: DIGSIG_E_ENCODE +// +// MessageText: +// +// Error due to problem in ASN.1 encoding process. +// +#define DIGSIG_E_ENCODE _HRESULT_TYPEDEF_(0x800B0005L) + +// +// MessageId: DIGSIG_E_DECODE +// +// MessageText: +// +// Error due to problem in ASN.1 decoding process. +// +#define DIGSIG_E_DECODE _HRESULT_TYPEDEF_(0x800B0006L) + +// +// MessageId: DIGSIG_E_EXTENSIBILITY +// +// MessageText: +// +// Reading / writing Extensions where Attributes are appropriate, and visa versa. +// +#define DIGSIG_E_EXTENSIBILITY _HRESULT_TYPEDEF_(0x800B0007L) + +// +// MessageId: DIGSIG_E_CRYPTO +// +// MessageText: +// +// Unspecified cryptographic failure. +// +#define DIGSIG_E_CRYPTO _HRESULT_TYPEDEF_(0x800B0008L) + +// +// MessageId: PERSIST_E_SIZEDEFINITE +// +// MessageText: +// +// The size of the data could not be determined. +// +#define PERSIST_E_SIZEDEFINITE _HRESULT_TYPEDEF_(0x800B0009L) + +// +// MessageId: PERSIST_E_SIZEINDEFINITE +// +// MessageText: +// +// The size of the indefinite-sized data could not be determined. +// +#define PERSIST_E_SIZEINDEFINITE _HRESULT_TYPEDEF_(0x800B000AL) + +// +// MessageId: PERSIST_E_NOTSELFSIZING +// +// MessageText: +// +// This object does not read and write self-sizing data. +// +#define PERSIST_E_NOTSELFSIZING _HRESULT_TYPEDEF_(0x800B000BL) + +// +// MessageId: TRUST_E_NOSIGNATURE +// +// MessageText: +// +// No signature was present in the subject. +// +#define TRUST_E_NOSIGNATURE _HRESULT_TYPEDEF_(0x800B0100L) + +// +// MessageId: CERT_E_EXPIRED +// +// MessageText: +// +// A required certificate is not within its validity period when verifying against the current system clock or the timestamp in the signed file. +// +#define CERT_E_EXPIRED _HRESULT_TYPEDEF_(0x800B0101L) + +// +// MessageId: CERT_E_VALIDITYPERIODNESTING +// +// MessageText: +// +// The validity periods of the certification chain do not nest correctly. +// +#define CERT_E_VALIDITYPERIODNESTING _HRESULT_TYPEDEF_(0x800B0102L) + +// +// MessageId: CERT_E_ROLE +// +// MessageText: +// +// A certificate that can only be used as an end-entity is being used as a CA or visa versa. +// +#define CERT_E_ROLE _HRESULT_TYPEDEF_(0x800B0103L) + +// +// MessageId: CERT_E_PATHLENCONST +// +// MessageText: +// +// A path length constraint in the certification chain has been violated. +// +#define CERT_E_PATHLENCONST _HRESULT_TYPEDEF_(0x800B0104L) + +// +// MessageId: CERT_E_CRITICAL +// +// MessageText: +// +// A certificate contains an unknown extension that is marked 'critical'. +// +#define CERT_E_CRITICAL _HRESULT_TYPEDEF_(0x800B0105L) + +// +// MessageId: CERT_E_PURPOSE +// +// MessageText: +// +// A certificate being used for a purpose other than the ones specified by its CA. +// +#define CERT_E_PURPOSE _HRESULT_TYPEDEF_(0x800B0106L) + +// +// MessageId: CERT_E_ISSUERCHAINING +// +// MessageText: +// +// A parent of a given certificate in fact did not issue that child certificate. +// +#define CERT_E_ISSUERCHAINING _HRESULT_TYPEDEF_(0x800B0107L) + +// +// MessageId: CERT_E_MALFORMED +// +// MessageText: +// +// A certificate is missing or has an empty value for an important field, such as a subject or issuer name. +// +#define CERT_E_MALFORMED _HRESULT_TYPEDEF_(0x800B0108L) + +// +// MessageId: CERT_E_UNTRUSTEDROOT +// +// MessageText: +// +// A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider. +// +#define CERT_E_UNTRUSTEDROOT _HRESULT_TYPEDEF_(0x800B0109L) + +// +// MessageId: CERT_E_CHAINING +// +// MessageText: +// +// A certificate chain could not be built to a trusted root authority. +// +#define CERT_E_CHAINING _HRESULT_TYPEDEF_(0x800B010AL) + +// +// MessageId: TRUST_E_FAIL +// +// MessageText: +// +// Generic trust failure. +// +#define TRUST_E_FAIL _HRESULT_TYPEDEF_(0x800B010BL) + +// +// MessageId: CERT_E_REVOKED +// +// MessageText: +// +// A certificate was explicitly revoked by its issuer. +// +#define CERT_E_REVOKED _HRESULT_TYPEDEF_(0x800B010CL) + +// +// MessageId: CERT_E_UNTRUSTEDTESTROOT +// +// MessageText: +// +// The certification path terminates with the test root which is not trusted with the current policy settings. +// +#define CERT_E_UNTRUSTEDTESTROOT _HRESULT_TYPEDEF_(0x800B010DL) + +// +// MessageId: CERT_E_REVOCATION_FAILURE +// +// MessageText: +// +// The revocation process could not continue - the certificate(s) could not be checked. +// +#define CERT_E_REVOCATION_FAILURE _HRESULT_TYPEDEF_(0x800B010EL) + +// +// MessageId: CERT_E_CN_NO_MATCH +// +// MessageText: +// +// The certificate's CN name does not match the passed value. +// +#define CERT_E_CN_NO_MATCH _HRESULT_TYPEDEF_(0x800B010FL) + +// +// MessageId: CERT_E_WRONG_USAGE +// +// MessageText: +// +// The certificate is not valid for the requested usage. +// +#define CERT_E_WRONG_USAGE _HRESULT_TYPEDEF_(0x800B0110L) + +// +// MessageId: TRUST_E_EXPLICIT_DISTRUST +// +// MessageText: +// +// The certificate was explicitly marked as untrusted by the user. +// +#define TRUST_E_EXPLICIT_DISTRUST _HRESULT_TYPEDEF_(0x800B0111L) + +// +// MessageId: CERT_E_UNTRUSTEDCA +// +// MessageText: +// +// A certification chain processed correctly, but one of the CA certificates is not trusted by the policy provider. +// +#define CERT_E_UNTRUSTEDCA _HRESULT_TYPEDEF_(0x800B0112L) + +// +// MessageId: CERT_E_INVALID_POLICY +// +// MessageText: +// +// The certificate has invalid policy. +// +#define CERT_E_INVALID_POLICY _HRESULT_TYPEDEF_(0x800B0113L) + +// +// MessageId: CERT_E_INVALID_NAME +// +// MessageText: +// +// The certificate has an invalid name. The name is not included in the permitted list or is explicitly excluded. +// +#define CERT_E_INVALID_NAME _HRESULT_TYPEDEF_(0x800B0114L) + +// ***************** +// FACILITY_SETUPAPI +// ***************** +// +// Since these error codes aren't in the standard Win32 range (i.e., 0-64K), define a +// macro to map either Win32 or SetupAPI error codes into an HRESULT. +// +#define HRESULT_FROM_SETUPAPI(x) ((((x) & (APPLICATION_ERROR_MASK|ERROR_SEVERITY_ERROR)) == (APPLICATION_ERROR_MASK|ERROR_SEVERITY_ERROR)) \ + ? ((HRESULT) (((x) & 0x0000FFFF) | (FACILITY_SETUPAPI << 16) | 0x80000000)) \ + : HRESULT_FROM_WIN32(x)) +// +// MessageId: SPAPI_E_EXPECTED_SECTION_NAME +// +// MessageText: +// +// A non-empty line was encountered in the INF before the start of a section. +// +#define SPAPI_E_EXPECTED_SECTION_NAME _HRESULT_TYPEDEF_(0x800F0000L) + +// +// MessageId: SPAPI_E_BAD_SECTION_NAME_LINE +// +// MessageText: +// +// A section name marker in the INF is not complete, or does not exist on a line by itself. +// +#define SPAPI_E_BAD_SECTION_NAME_LINE _HRESULT_TYPEDEF_(0x800F0001L) + +// +// MessageId: SPAPI_E_SECTION_NAME_TOO_LONG +// +// MessageText: +// +// An INF section was encountered whose name exceeds the maximum section name length. +// +#define SPAPI_E_SECTION_NAME_TOO_LONG _HRESULT_TYPEDEF_(0x800F0002L) + +// +// MessageId: SPAPI_E_GENERAL_SYNTAX +// +// MessageText: +// +// The syntax of the INF is invalid. +// +#define SPAPI_E_GENERAL_SYNTAX _HRESULT_TYPEDEF_(0x800F0003L) + +// +// MessageId: SPAPI_E_WRONG_INF_STYLE +// +// MessageText: +// +// The style of the INF is different than what was requested. +// +#define SPAPI_E_WRONG_INF_STYLE _HRESULT_TYPEDEF_(0x800F0100L) + +// +// MessageId: SPAPI_E_SECTION_NOT_FOUND +// +// MessageText: +// +// The required section was not found in the INF. +// +#define SPAPI_E_SECTION_NOT_FOUND _HRESULT_TYPEDEF_(0x800F0101L) + +// +// MessageId: SPAPI_E_LINE_NOT_FOUND +// +// MessageText: +// +// The required line was not found in the INF. +// +#define SPAPI_E_LINE_NOT_FOUND _HRESULT_TYPEDEF_(0x800F0102L) + +// +// MessageId: SPAPI_E_NO_BACKUP +// +// MessageText: +// +// The files affected by the installation of this file queue have not been backed up for uninstall. +// +#define SPAPI_E_NO_BACKUP _HRESULT_TYPEDEF_(0x800F0103L) + +// +// MessageId: SPAPI_E_NO_ASSOCIATED_CLASS +// +// MessageText: +// +// The INF or the device information set or element does not have an associated install class. +// +#define SPAPI_E_NO_ASSOCIATED_CLASS _HRESULT_TYPEDEF_(0x800F0200L) + +// +// MessageId: SPAPI_E_CLASS_MISMATCH +// +// MessageText: +// +// The INF or the device information set or element does not match the specified install class. +// +#define SPAPI_E_CLASS_MISMATCH _HRESULT_TYPEDEF_(0x800F0201L) + +// +// MessageId: SPAPI_E_DUPLICATE_FOUND +// +// MessageText: +// +// An existing device was found that is a duplicate of the device being manually installed. +// +#define SPAPI_E_DUPLICATE_FOUND _HRESULT_TYPEDEF_(0x800F0202L) + +// +// MessageId: SPAPI_E_NO_DRIVER_SELECTED +// +// MessageText: +// +// There is no driver selected for the device information set or element. +// +#define SPAPI_E_NO_DRIVER_SELECTED _HRESULT_TYPEDEF_(0x800F0203L) + +// +// MessageId: SPAPI_E_KEY_DOES_NOT_EXIST +// +// MessageText: +// +// The requested device registry key does not exist. +// +#define SPAPI_E_KEY_DOES_NOT_EXIST _HRESULT_TYPEDEF_(0x800F0204L) + +// +// MessageId: SPAPI_E_INVALID_DEVINST_NAME +// +// MessageText: +// +// The device instance name is invalid. +// +#define SPAPI_E_INVALID_DEVINST_NAME _HRESULT_TYPEDEF_(0x800F0205L) + +// +// MessageId: SPAPI_E_INVALID_CLASS +// +// MessageText: +// +// The install class is not present or is invalid. +// +#define SPAPI_E_INVALID_CLASS _HRESULT_TYPEDEF_(0x800F0206L) + +// +// MessageId: SPAPI_E_DEVINST_ALREADY_EXISTS +// +// MessageText: +// +// The device instance cannot be created because it already exists. +// +#define SPAPI_E_DEVINST_ALREADY_EXISTS _HRESULT_TYPEDEF_(0x800F0207L) + +// +// MessageId: SPAPI_E_DEVINFO_NOT_REGISTERED +// +// MessageText: +// +// The operation cannot be performed on a device information element that has not been registered. +// +#define SPAPI_E_DEVINFO_NOT_REGISTERED _HRESULT_TYPEDEF_(0x800F0208L) + +// +// MessageId: SPAPI_E_INVALID_REG_PROPERTY +// +// MessageText: +// +// The device property code is invalid. +// +#define SPAPI_E_INVALID_REG_PROPERTY _HRESULT_TYPEDEF_(0x800F0209L) + +// +// MessageId: SPAPI_E_NO_INF +// +// MessageText: +// +// The INF from which a driver list is to be built does not exist. +// +#define SPAPI_E_NO_INF _HRESULT_TYPEDEF_(0x800F020AL) + +// +// MessageId: SPAPI_E_NO_SUCH_DEVINST +// +// MessageText: +// +// The device instance does not exist in the hardware tree. +// +#define SPAPI_E_NO_SUCH_DEVINST _HRESULT_TYPEDEF_(0x800F020BL) + +// +// MessageId: SPAPI_E_CANT_LOAD_CLASS_ICON +// +// MessageText: +// +// The icon representing this install class cannot be loaded. +// +#define SPAPI_E_CANT_LOAD_CLASS_ICON _HRESULT_TYPEDEF_(0x800F020CL) + +// +// MessageId: SPAPI_E_INVALID_CLASS_INSTALLER +// +// MessageText: +// +// The class installer registry entry is invalid. +// +#define SPAPI_E_INVALID_CLASS_INSTALLER _HRESULT_TYPEDEF_(0x800F020DL) + +// +// MessageId: SPAPI_E_DI_DO_DEFAULT +// +// MessageText: +// +// The class installer has indicated that the default action should be performed for this installation request. +// +#define SPAPI_E_DI_DO_DEFAULT _HRESULT_TYPEDEF_(0x800F020EL) + +// +// MessageId: SPAPI_E_DI_NOFILECOPY +// +// MessageText: +// +// The operation does not require any files to be copied. +// +#define SPAPI_E_DI_NOFILECOPY _HRESULT_TYPEDEF_(0x800F020FL) + +// +// MessageId: SPAPI_E_INVALID_HWPROFILE +// +// MessageText: +// +// The specified hardware profile does not exist. +// +#define SPAPI_E_INVALID_HWPROFILE _HRESULT_TYPEDEF_(0x800F0210L) + +// +// MessageId: SPAPI_E_NO_DEVICE_SELECTED +// +// MessageText: +// +// There is no device information element currently selected for this device information set. +// +#define SPAPI_E_NO_DEVICE_SELECTED _HRESULT_TYPEDEF_(0x800F0211L) + +// +// MessageId: SPAPI_E_DEVINFO_LIST_LOCKED +// +// MessageText: +// +// The operation cannot be performed because the device information set is locked. +// +#define SPAPI_E_DEVINFO_LIST_LOCKED _HRESULT_TYPEDEF_(0x800F0212L) + +// +// MessageId: SPAPI_E_DEVINFO_DATA_LOCKED +// +// MessageText: +// +// The operation cannot be performed because the device information element is locked. +// +#define SPAPI_E_DEVINFO_DATA_LOCKED _HRESULT_TYPEDEF_(0x800F0213L) + +// +// MessageId: SPAPI_E_DI_BAD_PATH +// +// MessageText: +// +// The specified path does not contain any applicable device INFs. +// +#define SPAPI_E_DI_BAD_PATH _HRESULT_TYPEDEF_(0x800F0214L) + +// +// MessageId: SPAPI_E_NO_CLASSINSTALL_PARAMS +// +// MessageText: +// +// No class installer parameters have been set for the device information set or element. +// +#define SPAPI_E_NO_CLASSINSTALL_PARAMS _HRESULT_TYPEDEF_(0x800F0215L) + +// +// MessageId: SPAPI_E_FILEQUEUE_LOCKED +// +// MessageText: +// +// The operation cannot be performed because the file queue is locked. +// +#define SPAPI_E_FILEQUEUE_LOCKED _HRESULT_TYPEDEF_(0x800F0216L) + +// +// MessageId: SPAPI_E_BAD_SERVICE_INSTALLSECT +// +// MessageText: +// +// A service installation section in this INF is invalid. +// +#define SPAPI_E_BAD_SERVICE_INSTALLSECT _HRESULT_TYPEDEF_(0x800F0217L) + +// +// MessageId: SPAPI_E_NO_CLASS_DRIVER_LIST +// +// MessageText: +// +// There is no class driver list for the device information element. +// +#define SPAPI_E_NO_CLASS_DRIVER_LIST _HRESULT_TYPEDEF_(0x800F0218L) + +// +// MessageId: SPAPI_E_NO_ASSOCIATED_SERVICE +// +// MessageText: +// +// The installation failed because a function driver was not specified for this device instance. +// +#define SPAPI_E_NO_ASSOCIATED_SERVICE _HRESULT_TYPEDEF_(0x800F0219L) + +// +// MessageId: SPAPI_E_NO_DEFAULT_DEVICE_INTERFACE +// +// MessageText: +// +// There is presently no default device interface designated for this interface class. +// +#define SPAPI_E_NO_DEFAULT_DEVICE_INTERFACE _HRESULT_TYPEDEF_(0x800F021AL) + +// +// MessageId: SPAPI_E_DEVICE_INTERFACE_ACTIVE +// +// MessageText: +// +// The operation cannot be performed because the device interface is currently active. +// +#define SPAPI_E_DEVICE_INTERFACE_ACTIVE _HRESULT_TYPEDEF_(0x800F021BL) + +// +// MessageId: SPAPI_E_DEVICE_INTERFACE_REMOVED +// +// MessageText: +// +// The operation cannot be performed because the device interface has been removed from the system. +// +#define SPAPI_E_DEVICE_INTERFACE_REMOVED _HRESULT_TYPEDEF_(0x800F021CL) + +// +// MessageId: SPAPI_E_BAD_INTERFACE_INSTALLSECT +// +// MessageText: +// +// An interface installation section in this INF is invalid. +// +#define SPAPI_E_BAD_INTERFACE_INSTALLSECT _HRESULT_TYPEDEF_(0x800F021DL) + +// +// MessageId: SPAPI_E_NO_SUCH_INTERFACE_CLASS +// +// MessageText: +// +// This interface class does not exist in the system. +// +#define SPAPI_E_NO_SUCH_INTERFACE_CLASS _HRESULT_TYPEDEF_(0x800F021EL) + +// +// MessageId: SPAPI_E_INVALID_REFERENCE_STRING +// +// MessageText: +// +// The reference string supplied for this interface device is invalid. +// +#define SPAPI_E_INVALID_REFERENCE_STRING _HRESULT_TYPEDEF_(0x800F021FL) + +// +// MessageId: SPAPI_E_INVALID_MACHINENAME +// +// MessageText: +// +// The specified machine name does not conform to UNC naming conventions. +// +#define SPAPI_E_INVALID_MACHINENAME _HRESULT_TYPEDEF_(0x800F0220L) + +// +// MessageId: SPAPI_E_REMOTE_COMM_FAILURE +// +// MessageText: +// +// A general remote communication error occurred. +// +#define SPAPI_E_REMOTE_COMM_FAILURE _HRESULT_TYPEDEF_(0x800F0221L) + +// +// MessageId: SPAPI_E_MACHINE_UNAVAILABLE +// +// MessageText: +// +// The machine selected for remote communication is not available at this time. +// +#define SPAPI_E_MACHINE_UNAVAILABLE _HRESULT_TYPEDEF_(0x800F0222L) + +// +// MessageId: SPAPI_E_NO_CONFIGMGR_SERVICES +// +// MessageText: +// +// The Plug and Play service is not available on the remote machine. +// +#define SPAPI_E_NO_CONFIGMGR_SERVICES _HRESULT_TYPEDEF_(0x800F0223L) + +// +// MessageId: SPAPI_E_INVALID_PROPPAGE_PROVIDER +// +// MessageText: +// +// The property page provider registry entry is invalid. +// +#define SPAPI_E_INVALID_PROPPAGE_PROVIDER _HRESULT_TYPEDEF_(0x800F0224L) + +// +// MessageId: SPAPI_E_NO_SUCH_DEVICE_INTERFACE +// +// MessageText: +// +// The requested device interface is not present in the system. +// +#define SPAPI_E_NO_SUCH_DEVICE_INTERFACE _HRESULT_TYPEDEF_(0x800F0225L) + +// +// MessageId: SPAPI_E_DI_POSTPROCESSING_REQUIRED +// +// MessageText: +// +// The device's co-installer has additional work to perform after installation is complete. +// +#define SPAPI_E_DI_POSTPROCESSING_REQUIRED _HRESULT_TYPEDEF_(0x800F0226L) + +// +// MessageId: SPAPI_E_INVALID_COINSTALLER +// +// MessageText: +// +// The device's co-installer is invalid. +// +#define SPAPI_E_INVALID_COINSTALLER _HRESULT_TYPEDEF_(0x800F0227L) + +// +// MessageId: SPAPI_E_NO_COMPAT_DRIVERS +// +// MessageText: +// +// There are no compatible drivers for this device. +// +#define SPAPI_E_NO_COMPAT_DRIVERS _HRESULT_TYPEDEF_(0x800F0228L) + +// +// MessageId: SPAPI_E_NO_DEVICE_ICON +// +// MessageText: +// +// There is no icon that represents this device or device type. +// +#define SPAPI_E_NO_DEVICE_ICON _HRESULT_TYPEDEF_(0x800F0229L) + +// +// MessageId: SPAPI_E_INVALID_INF_LOGCONFIG +// +// MessageText: +// +// A logical configuration specified in this INF is invalid. +// +#define SPAPI_E_INVALID_INF_LOGCONFIG _HRESULT_TYPEDEF_(0x800F022AL) + +// +// MessageId: SPAPI_E_DI_DONT_INSTALL +// +// MessageText: +// +// The class installer has denied the request to install or upgrade this device. +// +#define SPAPI_E_DI_DONT_INSTALL _HRESULT_TYPEDEF_(0x800F022BL) + +// +// MessageId: SPAPI_E_INVALID_FILTER_DRIVER +// +// MessageText: +// +// One of the filter drivers installed for this device is invalid. +// +#define SPAPI_E_INVALID_FILTER_DRIVER _HRESULT_TYPEDEF_(0x800F022CL) + +// +// MessageId: SPAPI_E_NON_WINDOWS_NT_DRIVER +// +// MessageText: +// +// The driver selected for this device does not support Windows XP. +// +#define SPAPI_E_NON_WINDOWS_NT_DRIVER _HRESULT_TYPEDEF_(0x800F022DL) + +// +// MessageId: SPAPI_E_NON_WINDOWS_DRIVER +// +// MessageText: +// +// The driver selected for this device does not support Windows. +// +#define SPAPI_E_NON_WINDOWS_DRIVER _HRESULT_TYPEDEF_(0x800F022EL) + +// +// MessageId: SPAPI_E_NO_CATALOG_FOR_OEM_INF +// +// MessageText: +// +// The third-party INF does not contain digital signature information. +// +#define SPAPI_E_NO_CATALOG_FOR_OEM_INF _HRESULT_TYPEDEF_(0x800F022FL) + +// +// MessageId: SPAPI_E_DEVINSTALL_QUEUE_NONNATIVE +// +// MessageText: +// +// An invalid attempt was made to use a device installation file queue for verification of digital signatures relative to other platforms. +// +#define SPAPI_E_DEVINSTALL_QUEUE_NONNATIVE _HRESULT_TYPEDEF_(0x800F0230L) + +// +// MessageId: SPAPI_E_NOT_DISABLEABLE +// +// MessageText: +// +// The device cannot be disabled. +// +#define SPAPI_E_NOT_DISABLEABLE _HRESULT_TYPEDEF_(0x800F0231L) + +// +// MessageId: SPAPI_E_CANT_REMOVE_DEVINST +// +// MessageText: +// +// The device could not be dynamically removed. +// +#define SPAPI_E_CANT_REMOVE_DEVINST _HRESULT_TYPEDEF_(0x800F0232L) + +// +// MessageId: SPAPI_E_INVALID_TARGET +// +// MessageText: +// +// Cannot copy to specified target. +// +#define SPAPI_E_INVALID_TARGET _HRESULT_TYPEDEF_(0x800F0233L) + +// +// MessageId: SPAPI_E_DRIVER_NONNATIVE +// +// MessageText: +// +// Driver is not intended for this platform. +// +#define SPAPI_E_DRIVER_NONNATIVE _HRESULT_TYPEDEF_(0x800F0234L) + +// +// MessageId: SPAPI_E_IN_WOW64 +// +// MessageText: +// +// Operation not allowed in WOW64. +// +#define SPAPI_E_IN_WOW64 _HRESULT_TYPEDEF_(0x800F0235L) + +// +// MessageId: SPAPI_E_SET_SYSTEM_RESTORE_POINT +// +// MessageText: +// +// The operation involving unsigned file copying was rolled back, so that a system restore point could be set. +// +#define SPAPI_E_SET_SYSTEM_RESTORE_POINT _HRESULT_TYPEDEF_(0x800F0236L) + +// +// MessageId: SPAPI_E_INCORRECTLY_COPIED_INF +// +// MessageText: +// +// An INF was copied into the Windows INF directory in an improper manner. +// +#define SPAPI_E_INCORRECTLY_COPIED_INF _HRESULT_TYPEDEF_(0x800F0237L) + +// +// MessageId: SPAPI_E_SCE_DISABLED +// +// MessageText: +// +// The Security Configuration Editor (SCE) APIs have been disabled on this Embedded product. +// +#define SPAPI_E_SCE_DISABLED _HRESULT_TYPEDEF_(0x800F0238L) + +// +// MessageId: SPAPI_E_UNKNOWN_EXCEPTION +// +// MessageText: +// +// An unknown exception was encountered. +// +#define SPAPI_E_UNKNOWN_EXCEPTION _HRESULT_TYPEDEF_(0x800F0239L) + +// +// MessageId: SPAPI_E_PNP_REGISTRY_ERROR +// +// MessageText: +// +// A problem was encountered when accessing the Plug and Play registry database. +// +#define SPAPI_E_PNP_REGISTRY_ERROR _HRESULT_TYPEDEF_(0x800F023AL) + +// +// MessageId: SPAPI_E_REMOTE_REQUEST_UNSUPPORTED +// +// MessageText: +// +// The requested operation is not supported for a remote machine. +// +#define SPAPI_E_REMOTE_REQUEST_UNSUPPORTED _HRESULT_TYPEDEF_(0x800F023BL) + +// +// MessageId: SPAPI_E_NOT_AN_INSTALLED_OEM_INF +// +// MessageText: +// +// The specified file is not an installed OEM INF. +// +#define SPAPI_E_NOT_AN_INSTALLED_OEM_INF _HRESULT_TYPEDEF_(0x800F023CL) + +// +// MessageId: SPAPI_E_INF_IN_USE_BY_DEVICES +// +// MessageText: +// +// One or more devices are presently installed using the specified INF. +// +#define SPAPI_E_INF_IN_USE_BY_DEVICES _HRESULT_TYPEDEF_(0x800F023DL) + +// +// MessageId: SPAPI_E_DI_FUNCTION_OBSOLETE +// +// MessageText: +// +// The requested device install operation is obsolete. +// +#define SPAPI_E_DI_FUNCTION_OBSOLETE _HRESULT_TYPEDEF_(0x800F023EL) + +// +// MessageId: SPAPI_E_NO_AUTHENTICODE_CATALOG +// +// MessageText: +// +// A file could not be verified because it does not have an associated catalog signed via Authenticode(tm). +// +#define SPAPI_E_NO_AUTHENTICODE_CATALOG _HRESULT_TYPEDEF_(0x800F023FL) + +// +// MessageId: SPAPI_E_AUTHENTICODE_DISALLOWED +// +// MessageText: +// +// Authenticode(tm) signature verification is not supported for the specified INF. +// +#define SPAPI_E_AUTHENTICODE_DISALLOWED _HRESULT_TYPEDEF_(0x800F0240L) + +// +// MessageId: SPAPI_E_AUTHENTICODE_TRUSTED_PUBLISHER +// +// MessageText: +// +// The INF was signed with an Authenticode(tm) catalog from a trusted publisher. +// +#define SPAPI_E_AUTHENTICODE_TRUSTED_PUBLISHER _HRESULT_TYPEDEF_(0x800F0241L) + +// +// MessageId: SPAPI_E_AUTHENTICODE_TRUST_NOT_ESTABLISHED +// +// MessageText: +// +// The publisher of an Authenticode(tm) signed catalog has not yet been established as trusted. +// +#define SPAPI_E_AUTHENTICODE_TRUST_NOT_ESTABLISHED _HRESULT_TYPEDEF_(0x800F0242L) + +// +// MessageId: SPAPI_E_AUTHENTICODE_PUBLISHER_NOT_TRUSTED +// +// MessageText: +// +// The publisher of an Authenticode(tm) signed catalog was not established as trusted. +// +#define SPAPI_E_AUTHENTICODE_PUBLISHER_NOT_TRUSTED _HRESULT_TYPEDEF_(0x800F0243L) + +// +// MessageId: SPAPI_E_SIGNATURE_OSATTRIBUTE_MISMATCH +// +// MessageText: +// +// The software was tested for compliance with Windows Logo requirements on a different version of Windows, and may not be compatible with this version. +// +#define SPAPI_E_SIGNATURE_OSATTRIBUTE_MISMATCH _HRESULT_TYPEDEF_(0x800F0244L) + +// +// MessageId: SPAPI_E_ONLY_VALIDATE_VIA_AUTHENTICODE +// +// MessageText: +// +// The file may only be validated by a catalog signed via Authenticode(tm). +// +#define SPAPI_E_ONLY_VALIDATE_VIA_AUTHENTICODE _HRESULT_TYPEDEF_(0x800F0245L) + +// +// MessageId: SPAPI_E_UNRECOVERABLE_STACK_OVERFLOW +// +// MessageText: +// +// An unrecoverable stack overflow was encountered. +// +#define SPAPI_E_UNRECOVERABLE_STACK_OVERFLOW _HRESULT_TYPEDEF_(0x800F0300L) + +// +// MessageId: SPAPI_E_ERROR_NOT_INSTALLED +// +// MessageText: +// +// No installed components were detected. +// +#define SPAPI_E_ERROR_NOT_INSTALLED _HRESULT_TYPEDEF_(0x800F1000L) + +// ***************** +// FACILITY_SCARD +// ***************** +// +// ============================= +// Facility SCARD Error Messages +// ============================= +// +#define SCARD_S_SUCCESS NO_ERROR +// +// MessageId: SCARD_F_INTERNAL_ERROR +// +// MessageText: +// +// An internal consistency check failed. +// +#define SCARD_F_INTERNAL_ERROR _HRESULT_TYPEDEF_(0x80100001L) + +// +// MessageId: SCARD_E_CANCELLED +// +// MessageText: +// +// The action was cancelled by an SCardCancel request. +// +#define SCARD_E_CANCELLED _HRESULT_TYPEDEF_(0x80100002L) + +// +// MessageId: SCARD_E_INVALID_HANDLE +// +// MessageText: +// +// The supplied handle was invalid. +// +#define SCARD_E_INVALID_HANDLE _HRESULT_TYPEDEF_(0x80100003L) + +// +// MessageId: SCARD_E_INVALID_PARAMETER +// +// MessageText: +// +// One or more of the supplied parameters could not be properly interpreted. +// +#define SCARD_E_INVALID_PARAMETER _HRESULT_TYPEDEF_(0x80100004L) + +// +// MessageId: SCARD_E_INVALID_TARGET +// +// MessageText: +// +// Registry startup information is missing or invalid. +// +#define SCARD_E_INVALID_TARGET _HRESULT_TYPEDEF_(0x80100005L) + +// +// MessageId: SCARD_E_NO_MEMORY +// +// MessageText: +// +// Not enough memory available to complete this command. +// +#define SCARD_E_NO_MEMORY _HRESULT_TYPEDEF_(0x80100006L) + +// +// MessageId: SCARD_F_WAITED_TOO_LONG +// +// MessageText: +// +// An internal consistency timer has expired. +// +#define SCARD_F_WAITED_TOO_LONG _HRESULT_TYPEDEF_(0x80100007L) + +// +// MessageId: SCARD_E_INSUFFICIENT_BUFFER +// +// MessageText: +// +// The data buffer to receive returned data is too small for the returned data. +// +#define SCARD_E_INSUFFICIENT_BUFFER _HRESULT_TYPEDEF_(0x80100008L) + +// +// MessageId: SCARD_E_UNKNOWN_READER +// +// MessageText: +// +// The specified reader name is not recognized. +// +#define SCARD_E_UNKNOWN_READER _HRESULT_TYPEDEF_(0x80100009L) + +// +// MessageId: SCARD_E_TIMEOUT +// +// MessageText: +// +// The user-specified timeout value has expired. +// +#define SCARD_E_TIMEOUT _HRESULT_TYPEDEF_(0x8010000AL) + +// +// MessageId: SCARD_E_SHARING_VIOLATION +// +// MessageText: +// +// The smart card cannot be accessed because of other connections outstanding. +// +#define SCARD_E_SHARING_VIOLATION _HRESULT_TYPEDEF_(0x8010000BL) + +// +// MessageId: SCARD_E_NO_SMARTCARD +// +// MessageText: +// +// The operation requires a Smart Card, but no Smart Card is currently in the device. +// +#define SCARD_E_NO_SMARTCARD _HRESULT_TYPEDEF_(0x8010000CL) + +// +// MessageId: SCARD_E_UNKNOWN_CARD +// +// MessageText: +// +// The specified smart card name is not recognized. +// +#define SCARD_E_UNKNOWN_CARD _HRESULT_TYPEDEF_(0x8010000DL) + +// +// MessageId: SCARD_E_CANT_DISPOSE +// +// MessageText: +// +// The system could not dispose of the media in the requested manner. +// +#define SCARD_E_CANT_DISPOSE _HRESULT_TYPEDEF_(0x8010000EL) + +// +// MessageId: SCARD_E_PROTO_MISMATCH +// +// MessageText: +// +// The requested protocols are incompatible with the protocol currently in use with the smart card. +// +#define SCARD_E_PROTO_MISMATCH _HRESULT_TYPEDEF_(0x8010000FL) + +// +// MessageId: SCARD_E_NOT_READY +// +// MessageText: +// +// The reader or smart card is not ready to accept commands. +// +#define SCARD_E_NOT_READY _HRESULT_TYPEDEF_(0x80100010L) + +// +// MessageId: SCARD_E_INVALID_VALUE +// +// MessageText: +// +// One or more of the supplied parameters values could not be properly interpreted. +// +#define SCARD_E_INVALID_VALUE _HRESULT_TYPEDEF_(0x80100011L) + +// +// MessageId: SCARD_E_SYSTEM_CANCELLED +// +// MessageText: +// +// The action was cancelled by the system, presumably to log off or shut down. +// +#define SCARD_E_SYSTEM_CANCELLED _HRESULT_TYPEDEF_(0x80100012L) + +// +// MessageId: SCARD_F_COMM_ERROR +// +// MessageText: +// +// An internal communications error has been detected. +// +#define SCARD_F_COMM_ERROR _HRESULT_TYPEDEF_(0x80100013L) + +// +// MessageId: SCARD_F_UNKNOWN_ERROR +// +// MessageText: +// +// An internal error has been detected, but the source is unknown. +// +#define SCARD_F_UNKNOWN_ERROR _HRESULT_TYPEDEF_(0x80100014L) + +// +// MessageId: SCARD_E_INVALID_ATR +// +// MessageText: +// +// An ATR obtained from the registry is not a valid ATR string. +// +#define SCARD_E_INVALID_ATR _HRESULT_TYPEDEF_(0x80100015L) + +// +// MessageId: SCARD_E_NOT_TRANSACTED +// +// MessageText: +// +// An attempt was made to end a non-existent transaction. +// +#define SCARD_E_NOT_TRANSACTED _HRESULT_TYPEDEF_(0x80100016L) + +// +// MessageId: SCARD_E_READER_UNAVAILABLE +// +// MessageText: +// +// The specified reader is not currently available for use. +// +#define SCARD_E_READER_UNAVAILABLE _HRESULT_TYPEDEF_(0x80100017L) + +// +// MessageId: SCARD_P_SHUTDOWN +// +// MessageText: +// +// The operation has been aborted to allow the server application to exit. +// +#define SCARD_P_SHUTDOWN _HRESULT_TYPEDEF_(0x80100018L) + +// +// MessageId: SCARD_E_PCI_TOO_SMALL +// +// MessageText: +// +// The PCI Receive buffer was too small. +// +#define SCARD_E_PCI_TOO_SMALL _HRESULT_TYPEDEF_(0x80100019L) + +// +// MessageId: SCARD_E_READER_UNSUPPORTED +// +// MessageText: +// +// The reader driver does not meet minimal requirements for support. +// +#define SCARD_E_READER_UNSUPPORTED _HRESULT_TYPEDEF_(0x8010001AL) + +// +// MessageId: SCARD_E_DUPLICATE_READER +// +// MessageText: +// +// The reader driver did not produce a unique reader name. +// +#define SCARD_E_DUPLICATE_READER _HRESULT_TYPEDEF_(0x8010001BL) + +// +// MessageId: SCARD_E_CARD_UNSUPPORTED +// +// MessageText: +// +// The smart card does not meet minimal requirements for support. +// +#define SCARD_E_CARD_UNSUPPORTED _HRESULT_TYPEDEF_(0x8010001CL) + +// +// MessageId: SCARD_E_NO_SERVICE +// +// MessageText: +// +// The Smart card resource manager is not running. +// +#define SCARD_E_NO_SERVICE _HRESULT_TYPEDEF_(0x8010001DL) + +// +// MessageId: SCARD_E_SERVICE_STOPPED +// +// MessageText: +// +// The Smart card resource manager has shut down. +// +#define SCARD_E_SERVICE_STOPPED _HRESULT_TYPEDEF_(0x8010001EL) + +// +// MessageId: SCARD_E_UNEXPECTED +// +// MessageText: +// +// An unexpected card error has occurred. +// +#define SCARD_E_UNEXPECTED _HRESULT_TYPEDEF_(0x8010001FL) + +// +// MessageId: SCARD_E_ICC_INSTALLATION +// +// MessageText: +// +// No Primary Provider can be found for the smart card. +// +#define SCARD_E_ICC_INSTALLATION _HRESULT_TYPEDEF_(0x80100020L) + +// +// MessageId: SCARD_E_ICC_CREATEORDER +// +// MessageText: +// +// The requested order of object creation is not supported. +// +#define SCARD_E_ICC_CREATEORDER _HRESULT_TYPEDEF_(0x80100021L) + +// +// MessageId: SCARD_E_UNSUPPORTED_FEATURE +// +// MessageText: +// +// This smart card does not support the requested feature. +// +#define SCARD_E_UNSUPPORTED_FEATURE _HRESULT_TYPEDEF_(0x80100022L) + +// +// MessageId: SCARD_E_DIR_NOT_FOUND +// +// MessageText: +// +// The identified directory does not exist in the smart card. +// +#define SCARD_E_DIR_NOT_FOUND _HRESULT_TYPEDEF_(0x80100023L) + +// +// MessageId: SCARD_E_FILE_NOT_FOUND +// +// MessageText: +// +// The identified file does not exist in the smart card. +// +#define SCARD_E_FILE_NOT_FOUND _HRESULT_TYPEDEF_(0x80100024L) + +// +// MessageId: SCARD_E_NO_DIR +// +// MessageText: +// +// The supplied path does not represent a smart card directory. +// +#define SCARD_E_NO_DIR _HRESULT_TYPEDEF_(0x80100025L) + +// +// MessageId: SCARD_E_NO_FILE +// +// MessageText: +// +// The supplied path does not represent a smart card file. +// +#define SCARD_E_NO_FILE _HRESULT_TYPEDEF_(0x80100026L) + +// +// MessageId: SCARD_E_NO_ACCESS +// +// MessageText: +// +// Access is denied to this file. +// +#define SCARD_E_NO_ACCESS _HRESULT_TYPEDEF_(0x80100027L) + +// +// MessageId: SCARD_E_WRITE_TOO_MANY +// +// MessageText: +// +// The smartcard does not have enough memory to store the information. +// +#define SCARD_E_WRITE_TOO_MANY _HRESULT_TYPEDEF_(0x80100028L) + +// +// MessageId: SCARD_E_BAD_SEEK +// +// MessageText: +// +// There was an error trying to set the smart card file object pointer. +// +#define SCARD_E_BAD_SEEK _HRESULT_TYPEDEF_(0x80100029L) + +// +// MessageId: SCARD_E_INVALID_CHV +// +// MessageText: +// +// The supplied PIN is incorrect. +// +#define SCARD_E_INVALID_CHV _HRESULT_TYPEDEF_(0x8010002AL) + +// +// MessageId: SCARD_E_UNKNOWN_RES_MNG +// +// MessageText: +// +// An unrecognized error code was returned from a layered component. +// +#define SCARD_E_UNKNOWN_RES_MNG _HRESULT_TYPEDEF_(0x8010002BL) + +// +// MessageId: SCARD_E_NO_SUCH_CERTIFICATE +// +// MessageText: +// +// The requested certificate does not exist. +// +#define SCARD_E_NO_SUCH_CERTIFICATE _HRESULT_TYPEDEF_(0x8010002CL) + +// +// MessageId: SCARD_E_CERTIFICATE_UNAVAILABLE +// +// MessageText: +// +// The requested certificate could not be obtained. +// +#define SCARD_E_CERTIFICATE_UNAVAILABLE _HRESULT_TYPEDEF_(0x8010002DL) + +// +// MessageId: SCARD_E_NO_READERS_AVAILABLE +// +// MessageText: +// +// Cannot find a smart card reader. +// +#define SCARD_E_NO_READERS_AVAILABLE _HRESULT_TYPEDEF_(0x8010002EL) + +// +// MessageId: SCARD_E_COMM_DATA_LOST +// +// MessageText: +// +// A communications error with the smart card has been detected. Retry the operation. +// +#define SCARD_E_COMM_DATA_LOST _HRESULT_TYPEDEF_(0x8010002FL) + +// +// MessageId: SCARD_E_NO_KEY_CONTAINER +// +// MessageText: +// +// The requested key container does not exist on the smart card. +// +#define SCARD_E_NO_KEY_CONTAINER _HRESULT_TYPEDEF_(0x80100030L) + +// +// MessageId: SCARD_E_SERVER_TOO_BUSY +// +// MessageText: +// +// The Smart card resource manager is too busy to complete this operation. +// +#define SCARD_E_SERVER_TOO_BUSY _HRESULT_TYPEDEF_(0x80100031L) + +// +// These are warning codes. +// +// +// MessageId: SCARD_W_UNSUPPORTED_CARD +// +// MessageText: +// +// The reader cannot communicate with the smart card, due to ATR configuration conflicts. +// +#define SCARD_W_UNSUPPORTED_CARD _HRESULT_TYPEDEF_(0x80100065L) + +// +// MessageId: SCARD_W_UNRESPONSIVE_CARD +// +// MessageText: +// +// The smart card is not responding to a reset. +// +#define SCARD_W_UNRESPONSIVE_CARD _HRESULT_TYPEDEF_(0x80100066L) + +// +// MessageId: SCARD_W_UNPOWERED_CARD +// +// MessageText: +// +// Power has been removed from the smart card, so that further communication is not possible. +// +#define SCARD_W_UNPOWERED_CARD _HRESULT_TYPEDEF_(0x80100067L) + +// +// MessageId: SCARD_W_RESET_CARD +// +// MessageText: +// +// The smart card has been reset, so any shared state information is invalid. +// +#define SCARD_W_RESET_CARD _HRESULT_TYPEDEF_(0x80100068L) + +// +// MessageId: SCARD_W_REMOVED_CARD +// +// MessageText: +// +// The smart card has been removed, so that further communication is not possible. +// +#define SCARD_W_REMOVED_CARD _HRESULT_TYPEDEF_(0x80100069L) + +// +// MessageId: SCARD_W_SECURITY_VIOLATION +// +// MessageText: +// +// Access was denied because of a security violation. +// +#define SCARD_W_SECURITY_VIOLATION _HRESULT_TYPEDEF_(0x8010006AL) + +// +// MessageId: SCARD_W_WRONG_CHV +// +// MessageText: +// +// The card cannot be accessed because the wrong PIN was presented. +// +#define SCARD_W_WRONG_CHV _HRESULT_TYPEDEF_(0x8010006BL) + +// +// MessageId: SCARD_W_CHV_BLOCKED +// +// MessageText: +// +// The card cannot be accessed because the maximum number of PIN entry attempts has been reached. +// +#define SCARD_W_CHV_BLOCKED _HRESULT_TYPEDEF_(0x8010006CL) + +// +// MessageId: SCARD_W_EOF +// +// MessageText: +// +// The end of the smart card file has been reached. +// +#define SCARD_W_EOF _HRESULT_TYPEDEF_(0x8010006DL) + +// +// MessageId: SCARD_W_CANCELLED_BY_USER +// +// MessageText: +// +// The action was cancelled by the user. +// +#define SCARD_W_CANCELLED_BY_USER _HRESULT_TYPEDEF_(0x8010006EL) + +// +// MessageId: SCARD_W_CARD_NOT_AUTHENTICATED +// +// MessageText: +// +// No PIN was presented to the smart card. +// +#define SCARD_W_CARD_NOT_AUTHENTICATED _HRESULT_TYPEDEF_(0x8010006FL) + +// ***************** +// FACILITY_COMPLUS +// ***************** +// +// =============================== +// Facility COMPLUS Error Messages +// =============================== +// +// +// The following are the subranges within the COMPLUS facility +// 0x400 - 0x4ff COMADMIN_E_CAT +// 0x600 - 0x6ff COMQC errors +// 0x700 - 0x7ff MSDTC errors +// 0x800 - 0x8ff Other COMADMIN errors +// +// COMPLUS Admin errors +// +// +// MessageId: COMADMIN_E_OBJECTERRORS +// +// MessageText: +// +// Errors occurred accessing one or more objects - the ErrorInfo collection may have more detail +// +#define COMADMIN_E_OBJECTERRORS _HRESULT_TYPEDEF_(0x80110401L) + +// +// MessageId: COMADMIN_E_OBJECTINVALID +// +// MessageText: +// +// One or more of the object's properties are missing or invalid +// +#define COMADMIN_E_OBJECTINVALID _HRESULT_TYPEDEF_(0x80110402L) + +// +// MessageId: COMADMIN_E_KEYMISSING +// +// MessageText: +// +// The object was not found in the catalog +// +#define COMADMIN_E_KEYMISSING _HRESULT_TYPEDEF_(0x80110403L) + +// +// MessageId: COMADMIN_E_ALREADYINSTALLED +// +// MessageText: +// +// The object is already registered +// +#define COMADMIN_E_ALREADYINSTALLED _HRESULT_TYPEDEF_(0x80110404L) + +// +// MessageId: COMADMIN_E_APP_FILE_WRITEFAIL +// +// MessageText: +// +// Error occurred writing to the application file +// +#define COMADMIN_E_APP_FILE_WRITEFAIL _HRESULT_TYPEDEF_(0x80110407L) + +// +// MessageId: COMADMIN_E_APP_FILE_READFAIL +// +// MessageText: +// +// Error occurred reading the application file +// +#define COMADMIN_E_APP_FILE_READFAIL _HRESULT_TYPEDEF_(0x80110408L) + +// +// MessageId: COMADMIN_E_APP_FILE_VERSION +// +// MessageText: +// +// Invalid version number in application file +// +#define COMADMIN_E_APP_FILE_VERSION _HRESULT_TYPEDEF_(0x80110409L) + +// +// MessageId: COMADMIN_E_BADPATH +// +// MessageText: +// +// The file path is invalid +// +#define COMADMIN_E_BADPATH _HRESULT_TYPEDEF_(0x8011040AL) + +// +// MessageId: COMADMIN_E_APPLICATIONEXISTS +// +// MessageText: +// +// The application is already installed +// +#define COMADMIN_E_APPLICATIONEXISTS _HRESULT_TYPEDEF_(0x8011040BL) + +// +// MessageId: COMADMIN_E_ROLEEXISTS +// +// MessageText: +// +// The role already exists +// +#define COMADMIN_E_ROLEEXISTS _HRESULT_TYPEDEF_(0x8011040CL) + +// +// MessageId: COMADMIN_E_CANTCOPYFILE +// +// MessageText: +// +// An error occurred copying the file +// +#define COMADMIN_E_CANTCOPYFILE _HRESULT_TYPEDEF_(0x8011040DL) + +// +// MessageId: COMADMIN_E_NOUSER +// +// MessageText: +// +// One or more users are not valid +// +#define COMADMIN_E_NOUSER _HRESULT_TYPEDEF_(0x8011040FL) + +// +// MessageId: COMADMIN_E_INVALIDUSERIDS +// +// MessageText: +// +// One or more users in the application file are not valid +// +#define COMADMIN_E_INVALIDUSERIDS _HRESULT_TYPEDEF_(0x80110410L) + +// +// MessageId: COMADMIN_E_NOREGISTRYCLSID +// +// MessageText: +// +// The component's CLSID is missing or corrupt +// +#define COMADMIN_E_NOREGISTRYCLSID _HRESULT_TYPEDEF_(0x80110411L) + +// +// MessageId: COMADMIN_E_BADREGISTRYPROGID +// +// MessageText: +// +// The component's progID is missing or corrupt +// +#define COMADMIN_E_BADREGISTRYPROGID _HRESULT_TYPEDEF_(0x80110412L) + +// +// MessageId: COMADMIN_E_AUTHENTICATIONLEVEL +// +// MessageText: +// +// Unable to set required authentication level for update request +// +#define COMADMIN_E_AUTHENTICATIONLEVEL _HRESULT_TYPEDEF_(0x80110413L) + +// +// MessageId: COMADMIN_E_USERPASSWDNOTVALID +// +// MessageText: +// +// The identity or password set on the application is not valid +// +#define COMADMIN_E_USERPASSWDNOTVALID _HRESULT_TYPEDEF_(0x80110414L) + +// +// MessageId: COMADMIN_E_CLSIDORIIDMISMATCH +// +// MessageText: +// +// Application file CLSIDs or IIDs do not match corresponding DLLs +// +#define COMADMIN_E_CLSIDORIIDMISMATCH _HRESULT_TYPEDEF_(0x80110418L) + +// +// MessageId: COMADMIN_E_REMOTEINTERFACE +// +// MessageText: +// +// Interface information is either missing or changed +// +#define COMADMIN_E_REMOTEINTERFACE _HRESULT_TYPEDEF_(0x80110419L) + +// +// MessageId: COMADMIN_E_DLLREGISTERSERVER +// +// MessageText: +// +// DllRegisterServer failed on component install +// +#define COMADMIN_E_DLLREGISTERSERVER _HRESULT_TYPEDEF_(0x8011041AL) + +// +// MessageId: COMADMIN_E_NOSERVERSHARE +// +// MessageText: +// +// No server file share available +// +#define COMADMIN_E_NOSERVERSHARE _HRESULT_TYPEDEF_(0x8011041BL) + +// +// MessageId: COMADMIN_E_DLLLOADFAILED +// +// MessageText: +// +// DLL could not be loaded +// +#define COMADMIN_E_DLLLOADFAILED _HRESULT_TYPEDEF_(0x8011041DL) + +// +// MessageId: COMADMIN_E_BADREGISTRYLIBID +// +// MessageText: +// +// The registered TypeLib ID is not valid +// +#define COMADMIN_E_BADREGISTRYLIBID _HRESULT_TYPEDEF_(0x8011041EL) + +// +// MessageId: COMADMIN_E_APPDIRNOTFOUND +// +// MessageText: +// +// Application install directory not found +// +#define COMADMIN_E_APPDIRNOTFOUND _HRESULT_TYPEDEF_(0x8011041FL) + +// +// MessageId: COMADMIN_E_REGISTRARFAILED +// +// MessageText: +// +// Errors occurred while in the component registrar +// +#define COMADMIN_E_REGISTRARFAILED _HRESULT_TYPEDEF_(0x80110423L) + +// +// MessageId: COMADMIN_E_COMPFILE_DOESNOTEXIST +// +// MessageText: +// +// The file does not exist +// +#define COMADMIN_E_COMPFILE_DOESNOTEXIST _HRESULT_TYPEDEF_(0x80110424L) + +// +// MessageId: COMADMIN_E_COMPFILE_LOADDLLFAIL +// +// MessageText: +// +// The DLL could not be loaded +// +#define COMADMIN_E_COMPFILE_LOADDLLFAIL _HRESULT_TYPEDEF_(0x80110425L) + +// +// MessageId: COMADMIN_E_COMPFILE_GETCLASSOBJ +// +// MessageText: +// +// GetClassObject failed in the DLL +// +#define COMADMIN_E_COMPFILE_GETCLASSOBJ _HRESULT_TYPEDEF_(0x80110426L) + +// +// MessageId: COMADMIN_E_COMPFILE_CLASSNOTAVAIL +// +// MessageText: +// +// The DLL does not support the components listed in the TypeLib +// +#define COMADMIN_E_COMPFILE_CLASSNOTAVAIL _HRESULT_TYPEDEF_(0x80110427L) + +// +// MessageId: COMADMIN_E_COMPFILE_BADTLB +// +// MessageText: +// +// The TypeLib could not be loaded +// +#define COMADMIN_E_COMPFILE_BADTLB _HRESULT_TYPEDEF_(0x80110428L) + +// +// MessageId: COMADMIN_E_COMPFILE_NOTINSTALLABLE +// +// MessageText: +// +// The file does not contain components or component information +// +#define COMADMIN_E_COMPFILE_NOTINSTALLABLE _HRESULT_TYPEDEF_(0x80110429L) + +// +// MessageId: COMADMIN_E_NOTCHANGEABLE +// +// MessageText: +// +// Changes to this object and its sub-objects have been disabled +// +#define COMADMIN_E_NOTCHANGEABLE _HRESULT_TYPEDEF_(0x8011042AL) + +// +// MessageId: COMADMIN_E_NOTDELETEABLE +// +// MessageText: +// +// The delete function has been disabled for this object +// +#define COMADMIN_E_NOTDELETEABLE _HRESULT_TYPEDEF_(0x8011042BL) + +// +// MessageId: COMADMIN_E_SESSION +// +// MessageText: +// +// The server catalog version is not supported +// +#define COMADMIN_E_SESSION _HRESULT_TYPEDEF_(0x8011042CL) + +// +// MessageId: COMADMIN_E_COMP_MOVE_LOCKED +// +// MessageText: +// +// The component move was disallowed, because the source or destination application is either a system application or currently locked against changes +// +#define COMADMIN_E_COMP_MOVE_LOCKED _HRESULT_TYPEDEF_(0x8011042DL) + +// +// MessageId: COMADMIN_E_COMP_MOVE_BAD_DEST +// +// MessageText: +// +// The component move failed because the destination application no longer exists +// +#define COMADMIN_E_COMP_MOVE_BAD_DEST _HRESULT_TYPEDEF_(0x8011042EL) + +// +// MessageId: COMADMIN_E_REGISTERTLB +// +// MessageText: +// +// The system was unable to register the TypeLib +// +#define COMADMIN_E_REGISTERTLB _HRESULT_TYPEDEF_(0x80110430L) + +// +// MessageId: COMADMIN_E_SYSTEMAPP +// +// MessageText: +// +// This operation can not be performed on the system application +// +#define COMADMIN_E_SYSTEMAPP _HRESULT_TYPEDEF_(0x80110433L) + +// +// MessageId: COMADMIN_E_COMPFILE_NOREGISTRAR +// +// MessageText: +// +// The component registrar referenced in this file is not available +// +#define COMADMIN_E_COMPFILE_NOREGISTRAR _HRESULT_TYPEDEF_(0x80110434L) + +// +// MessageId: COMADMIN_E_COREQCOMPINSTALLED +// +// MessageText: +// +// A component in the same DLL is already installed +// +#define COMADMIN_E_COREQCOMPINSTALLED _HRESULT_TYPEDEF_(0x80110435L) + +// +// MessageId: COMADMIN_E_SERVICENOTINSTALLED +// +// MessageText: +// +// The service is not installed +// +#define COMADMIN_E_SERVICENOTINSTALLED _HRESULT_TYPEDEF_(0x80110436L) + +// +// MessageId: COMADMIN_E_PROPERTYSAVEFAILED +// +// MessageText: +// +// One or more property settings are either invalid or in conflict with each other +// +#define COMADMIN_E_PROPERTYSAVEFAILED _HRESULT_TYPEDEF_(0x80110437L) + +// +// MessageId: COMADMIN_E_OBJECTEXISTS +// +// MessageText: +// +// The object you are attempting to add or rename already exists +// +#define COMADMIN_E_OBJECTEXISTS _HRESULT_TYPEDEF_(0x80110438L) + +// +// MessageId: COMADMIN_E_COMPONENTEXISTS +// +// MessageText: +// +// The component already exists +// +#define COMADMIN_E_COMPONENTEXISTS _HRESULT_TYPEDEF_(0x80110439L) + +// +// MessageId: COMADMIN_E_REGFILE_CORRUPT +// +// MessageText: +// +// The registration file is corrupt +// +#define COMADMIN_E_REGFILE_CORRUPT _HRESULT_TYPEDEF_(0x8011043BL) + +// +// MessageId: COMADMIN_E_PROPERTY_OVERFLOW +// +// MessageText: +// +// The property value is too large +// +#define COMADMIN_E_PROPERTY_OVERFLOW _HRESULT_TYPEDEF_(0x8011043CL) + +// +// MessageId: COMADMIN_E_NOTINREGISTRY +// +// MessageText: +// +// Object was not found in registry +// +#define COMADMIN_E_NOTINREGISTRY _HRESULT_TYPEDEF_(0x8011043EL) + +// +// MessageId: COMADMIN_E_OBJECTNOTPOOLABLE +// +// MessageText: +// +// This object is not poolable +// +#define COMADMIN_E_OBJECTNOTPOOLABLE _HRESULT_TYPEDEF_(0x8011043FL) + +// +// MessageId: COMADMIN_E_APPLID_MATCHES_CLSID +// +// MessageText: +// +// A CLSID with the same GUID as the new application ID is already installed on this machine +// +#define COMADMIN_E_APPLID_MATCHES_CLSID _HRESULT_TYPEDEF_(0x80110446L) + +// +// MessageId: COMADMIN_E_ROLE_DOES_NOT_EXIST +// +// MessageText: +// +// A role assigned to a component, interface, or method did not exist in the application +// +#define COMADMIN_E_ROLE_DOES_NOT_EXIST _HRESULT_TYPEDEF_(0x80110447L) + +// +// MessageId: COMADMIN_E_START_APP_NEEDS_COMPONENTS +// +// MessageText: +// +// You must have components in an application in order to start the application +// +#define COMADMIN_E_START_APP_NEEDS_COMPONENTS _HRESULT_TYPEDEF_(0x80110448L) + +// +// MessageId: COMADMIN_E_REQUIRES_DIFFERENT_PLATFORM +// +// MessageText: +// +// This operation is not enabled on this platform +// +#define COMADMIN_E_REQUIRES_DIFFERENT_PLATFORM _HRESULT_TYPEDEF_(0x80110449L) + +// +// MessageId: COMADMIN_E_CAN_NOT_EXPORT_APP_PROXY +// +// MessageText: +// +// Application Proxy is not exportable +// +#define COMADMIN_E_CAN_NOT_EXPORT_APP_PROXY _HRESULT_TYPEDEF_(0x8011044AL) + +// +// MessageId: COMADMIN_E_CAN_NOT_START_APP +// +// MessageText: +// +// Failed to start application because it is either a library application or an application proxy +// +#define COMADMIN_E_CAN_NOT_START_APP _HRESULT_TYPEDEF_(0x8011044BL) + +// +// MessageId: COMADMIN_E_CAN_NOT_EXPORT_SYS_APP +// +// MessageText: +// +// System application is not exportable +// +#define COMADMIN_E_CAN_NOT_EXPORT_SYS_APP _HRESULT_TYPEDEF_(0x8011044CL) + +// +// MessageId: COMADMIN_E_CANT_SUBSCRIBE_TO_COMPONENT +// +// MessageText: +// +// Can not subscribe to this component (the component may have been imported) +// +#define COMADMIN_E_CANT_SUBSCRIBE_TO_COMPONENT _HRESULT_TYPEDEF_(0x8011044DL) + +// +// MessageId: COMADMIN_E_EVENTCLASS_CANT_BE_SUBSCRIBER +// +// MessageText: +// +// An event class cannot also be a subscriber component +// +#define COMADMIN_E_EVENTCLASS_CANT_BE_SUBSCRIBER _HRESULT_TYPEDEF_(0x8011044EL) + +// +// MessageId: COMADMIN_E_LIB_APP_PROXY_INCOMPATIBLE +// +// MessageText: +// +// Library applications and application proxies are incompatible +// +#define COMADMIN_E_LIB_APP_PROXY_INCOMPATIBLE _HRESULT_TYPEDEF_(0x8011044FL) + +// +// MessageId: COMADMIN_E_BASE_PARTITION_ONLY +// +// MessageText: +// +// This function is valid for the base partition only +// +#define COMADMIN_E_BASE_PARTITION_ONLY _HRESULT_TYPEDEF_(0x80110450L) + +// +// MessageId: COMADMIN_E_START_APP_DISABLED +// +// MessageText: +// +// You cannot start an application that has been disabled +// +#define COMADMIN_E_START_APP_DISABLED _HRESULT_TYPEDEF_(0x80110451L) + +// +// MessageId: COMADMIN_E_CAT_DUPLICATE_PARTITION_NAME +// +// MessageText: +// +// The specified partition name is already in use on this computer +// +#define COMADMIN_E_CAT_DUPLICATE_PARTITION_NAME _HRESULT_TYPEDEF_(0x80110457L) + +// +// MessageId: COMADMIN_E_CAT_INVALID_PARTITION_NAME +// +// MessageText: +// +// The specified partition name is invalid. Check that the name contains at least one visible character +// +#define COMADMIN_E_CAT_INVALID_PARTITION_NAME _HRESULT_TYPEDEF_(0x80110458L) + +// +// MessageId: COMADMIN_E_CAT_PARTITION_IN_USE +// +// MessageText: +// +// The partition cannot be deleted because it is the default partition for one or more users +// +#define COMADMIN_E_CAT_PARTITION_IN_USE _HRESULT_TYPEDEF_(0x80110459L) + +// +// MessageId: COMADMIN_E_FILE_PARTITION_DUPLICATE_FILES +// +// MessageText: +// +// The partition cannot be exported, because one or more components in the partition have the same file name +// +#define COMADMIN_E_FILE_PARTITION_DUPLICATE_FILES _HRESULT_TYPEDEF_(0x8011045AL) + +// +// MessageId: COMADMIN_E_CAT_IMPORTED_COMPONENTS_NOT_ALLOWED +// +// MessageText: +// +// Applications that contain one or more imported components cannot be installed into a non-base partition +// +#define COMADMIN_E_CAT_IMPORTED_COMPONENTS_NOT_ALLOWED _HRESULT_TYPEDEF_(0x8011045BL) + +// +// MessageId: COMADMIN_E_AMBIGUOUS_APPLICATION_NAME +// +// MessageText: +// +// The application name is not unique and cannot be resolved to an application id +// +#define COMADMIN_E_AMBIGUOUS_APPLICATION_NAME _HRESULT_TYPEDEF_(0x8011045CL) + +// +// MessageId: COMADMIN_E_AMBIGUOUS_PARTITION_NAME +// +// MessageText: +// +// The partition name is not unique and cannot be resolved to a partition id +// +#define COMADMIN_E_AMBIGUOUS_PARTITION_NAME _HRESULT_TYPEDEF_(0x8011045DL) + +// +// MessageId: COMADMIN_E_REGDB_NOTINITIALIZED +// +// MessageText: +// +// The COM+ registry database has not been initialized +// +#define COMADMIN_E_REGDB_NOTINITIALIZED _HRESULT_TYPEDEF_(0x80110472L) + +// +// MessageId: COMADMIN_E_REGDB_NOTOPEN +// +// MessageText: +// +// The COM+ registry database is not open +// +#define COMADMIN_E_REGDB_NOTOPEN _HRESULT_TYPEDEF_(0x80110473L) + +// +// MessageId: COMADMIN_E_REGDB_SYSTEMERR +// +// MessageText: +// +// The COM+ registry database detected a system error +// +#define COMADMIN_E_REGDB_SYSTEMERR _HRESULT_TYPEDEF_(0x80110474L) + +// +// MessageId: COMADMIN_E_REGDB_ALREADYRUNNING +// +// MessageText: +// +// The COM+ registry database is already running +// +#define COMADMIN_E_REGDB_ALREADYRUNNING _HRESULT_TYPEDEF_(0x80110475L) + +// +// MessageId: COMADMIN_E_MIG_VERSIONNOTSUPPORTED +// +// MessageText: +// +// This version of the COM+ registry database cannot be migrated +// +#define COMADMIN_E_MIG_VERSIONNOTSUPPORTED _HRESULT_TYPEDEF_(0x80110480L) + +// +// MessageId: COMADMIN_E_MIG_SCHEMANOTFOUND +// +// MessageText: +// +// The schema version to be migrated could not be found in the COM+ registry database +// +#define COMADMIN_E_MIG_SCHEMANOTFOUND _HRESULT_TYPEDEF_(0x80110481L) + +// +// MessageId: COMADMIN_E_CAT_BITNESSMISMATCH +// +// MessageText: +// +// There was a type mismatch between binaries +// +#define COMADMIN_E_CAT_BITNESSMISMATCH _HRESULT_TYPEDEF_(0x80110482L) + +// +// MessageId: COMADMIN_E_CAT_UNACCEPTABLEBITNESS +// +// MessageText: +// +// A binary of unknown or invalid type was provided +// +#define COMADMIN_E_CAT_UNACCEPTABLEBITNESS _HRESULT_TYPEDEF_(0x80110483L) + +// +// MessageId: COMADMIN_E_CAT_WRONGAPPBITNESS +// +// MessageText: +// +// There was a type mismatch between a binary and an application +// +#define COMADMIN_E_CAT_WRONGAPPBITNESS _HRESULT_TYPEDEF_(0x80110484L) + +// +// MessageId: COMADMIN_E_CAT_PAUSE_RESUME_NOT_SUPPORTED +// +// MessageText: +// +// The application cannot be paused or resumed +// +#define COMADMIN_E_CAT_PAUSE_RESUME_NOT_SUPPORTED _HRESULT_TYPEDEF_(0x80110485L) + +// +// MessageId: COMADMIN_E_CAT_SERVERFAULT +// +// MessageText: +// +// The COM+ Catalog Server threw an exception during execution +// +#define COMADMIN_E_CAT_SERVERFAULT _HRESULT_TYPEDEF_(0x80110486L) + +// +// COMPLUS Queued component errors +// +// +// MessageId: COMQC_E_APPLICATION_NOT_QUEUED +// +// MessageText: +// +// Only COM+ Applications marked "queued" can be invoked using the "queue" moniker +// +#define COMQC_E_APPLICATION_NOT_QUEUED _HRESULT_TYPEDEF_(0x80110600L) + +// +// MessageId: COMQC_E_NO_QUEUEABLE_INTERFACES +// +// MessageText: +// +// At least one interface must be marked "queued" in order to create a queued component instance with the "queue" moniker +// +#define COMQC_E_NO_QUEUEABLE_INTERFACES _HRESULT_TYPEDEF_(0x80110601L) + +// +// MessageId: COMQC_E_QUEUING_SERVICE_NOT_AVAILABLE +// +// MessageText: +// +// MSMQ is required for the requested operation and is not installed +// +#define COMQC_E_QUEUING_SERVICE_NOT_AVAILABLE _HRESULT_TYPEDEF_(0x80110602L) + +// +// MessageId: COMQC_E_NO_IPERSISTSTREAM +// +// MessageText: +// +// Unable to marshal an interface that does not support IPersistStream +// +#define COMQC_E_NO_IPERSISTSTREAM _HRESULT_TYPEDEF_(0x80110603L) + +// +// MessageId: COMQC_E_BAD_MESSAGE +// +// MessageText: +// +// The message is improperly formatted or was damaged in transit +// +#define COMQC_E_BAD_MESSAGE _HRESULT_TYPEDEF_(0x80110604L) + +// +// MessageId: COMQC_E_UNAUTHENTICATED +// +// MessageText: +// +// An unauthenticated message was received by an application that accepts only authenticated messages +// +#define COMQC_E_UNAUTHENTICATED _HRESULT_TYPEDEF_(0x80110605L) + +// +// MessageId: COMQC_E_UNTRUSTED_ENQUEUER +// +// MessageText: +// +// The message was requeued or moved by a user not in the "QC Trusted User" role +// +#define COMQC_E_UNTRUSTED_ENQUEUER _HRESULT_TYPEDEF_(0x80110606L) + +// +// The range 0x700-0x7ff is reserved for MSDTC errors. +// +// +// MessageId: MSDTC_E_DUPLICATE_RESOURCE +// +// MessageText: +// +// Cannot create a duplicate resource of type Distributed Transaction Coordinator +// +#define MSDTC_E_DUPLICATE_RESOURCE _HRESULT_TYPEDEF_(0x80110701L) + +// +// More COMADMIN errors from 0x8** +// +// +// MessageId: COMADMIN_E_OBJECT_PARENT_MISSING +// +// MessageText: +// +// One of the objects being inserted or updated does not belong to a valid parent collection +// +#define COMADMIN_E_OBJECT_PARENT_MISSING _HRESULT_TYPEDEF_(0x80110808L) + +// +// MessageId: COMADMIN_E_OBJECT_DOES_NOT_EXIST +// +// MessageText: +// +// One of the specified objects cannot be found +// +#define COMADMIN_E_OBJECT_DOES_NOT_EXIST _HRESULT_TYPEDEF_(0x80110809L) + +// +// MessageId: COMADMIN_E_APP_NOT_RUNNING +// +// MessageText: +// +// The specified application is not currently running +// +#define COMADMIN_E_APP_NOT_RUNNING _HRESULT_TYPEDEF_(0x8011080AL) + +// +// MessageId: COMADMIN_E_INVALID_PARTITION +// +// MessageText: +// +// The partition(s) specified are not valid. +// +#define COMADMIN_E_INVALID_PARTITION _HRESULT_TYPEDEF_(0x8011080BL) + +// +// MessageId: COMADMIN_E_SVCAPP_NOT_POOLABLE_OR_RECYCLABLE +// +// MessageText: +// +// COM+ applications that run as NT service may not be pooled or recycled +// +#define COMADMIN_E_SVCAPP_NOT_POOLABLE_OR_RECYCLABLE _HRESULT_TYPEDEF_(0x8011080DL) + +// +// MessageId: COMADMIN_E_USER_IN_SET +// +// MessageText: +// +// One or more users are already assigned to a local partition set. +// +#define COMADMIN_E_USER_IN_SET _HRESULT_TYPEDEF_(0x8011080EL) + +// +// MessageId: COMADMIN_E_CANTRECYCLELIBRARYAPPS +// +// MessageText: +// +// Library applications may not be recycled. +// +#define COMADMIN_E_CANTRECYCLELIBRARYAPPS _HRESULT_TYPEDEF_(0x8011080FL) + +// +// MessageId: COMADMIN_E_CANTRECYCLESERVICEAPPS +// +// MessageText: +// +// Applications running as NT services may not be recycled. +// +#define COMADMIN_E_CANTRECYCLESERVICEAPPS _HRESULT_TYPEDEF_(0x80110811L) + +// +// MessageId: COMADMIN_E_PROCESSALREADYRECYCLED +// +// MessageText: +// +// The process has already been recycled. +// +#define COMADMIN_E_PROCESSALREADYRECYCLED _HRESULT_TYPEDEF_(0x80110812L) + +// +// MessageId: COMADMIN_E_PAUSEDPROCESSMAYNOTBERECYCLED +// +// MessageText: +// +// A paused process may not be recycled. +// +#define COMADMIN_E_PAUSEDPROCESSMAYNOTBERECYCLED _HRESULT_TYPEDEF_(0x80110813L) + +// +// MessageId: COMADMIN_E_CANTMAKEINPROCSERVICE +// +// MessageText: +// +// Library applications may not be NT services. +// +#define COMADMIN_E_CANTMAKEINPROCSERVICE _HRESULT_TYPEDEF_(0x80110814L) + +// +// MessageId: COMADMIN_E_PROGIDINUSEBYCLSID +// +// MessageText: +// +// The ProgID provided to the copy operation is invalid. The ProgID is in use by another registered CLSID. +// +#define COMADMIN_E_PROGIDINUSEBYCLSID _HRESULT_TYPEDEF_(0x80110815L) + +// +// MessageId: COMADMIN_E_DEFAULT_PARTITION_NOT_IN_SET +// +// MessageText: +// +// The partition specified as default is not a member of the partition set. +// +#define COMADMIN_E_DEFAULT_PARTITION_NOT_IN_SET _HRESULT_TYPEDEF_(0x80110816L) + +// +// MessageId: COMADMIN_E_RECYCLEDPROCESSMAYNOTBEPAUSED +// +// MessageText: +// +// A recycled process may not be paused. +// +#define COMADMIN_E_RECYCLEDPROCESSMAYNOTBEPAUSED _HRESULT_TYPEDEF_(0x80110817L) + +// +// MessageId: COMADMIN_E_PARTITION_ACCESSDENIED +// +// MessageText: +// +// Access to the specified partition is denied. +// +#define COMADMIN_E_PARTITION_ACCESSDENIED _HRESULT_TYPEDEF_(0x80110818L) + +// +// MessageId: COMADMIN_E_PARTITION_MSI_ONLY +// +// MessageText: +// +// Only Application Files (*.MSI files) can be installed into partitions. +// +#define COMADMIN_E_PARTITION_MSI_ONLY _HRESULT_TYPEDEF_(0x80110819L) + +// +// MessageId: COMADMIN_E_LEGACYCOMPS_NOT_ALLOWED_IN_1_0_FORMAT +// +// MessageText: +// +// Applications containing one or more legacy components may not be exported to 1.0 format. +// +#define COMADMIN_E_LEGACYCOMPS_NOT_ALLOWED_IN_1_0_FORMAT _HRESULT_TYPEDEF_(0x8011081AL) + +// +// MessageId: COMADMIN_E_LEGACYCOMPS_NOT_ALLOWED_IN_NONBASE_PARTITIONS +// +// MessageText: +// +// Legacy components may not exist in non-base partitions. +// +#define COMADMIN_E_LEGACYCOMPS_NOT_ALLOWED_IN_NONBASE_PARTITIONS _HRESULT_TYPEDEF_(0x8011081BL) + +// +// MessageId: COMADMIN_E_COMP_MOVE_SOURCE +// +// MessageText: +// +// A component cannot be moved (or copied) from the System Application, an application proxy or a non-changeable application +// +#define COMADMIN_E_COMP_MOVE_SOURCE _HRESULT_TYPEDEF_(0x8011081CL) + +// +// MessageId: COMADMIN_E_COMP_MOVE_DEST +// +// MessageText: +// +// A component cannot be moved (or copied) to the System Application, an application proxy or a non-changeable application +// +#define COMADMIN_E_COMP_MOVE_DEST _HRESULT_TYPEDEF_(0x8011081DL) + +// +// MessageId: COMADMIN_E_COMP_MOVE_PRIVATE +// +// MessageText: +// +// A private component cannot be moved (or copied) to a library application or to the base partition +// +#define COMADMIN_E_COMP_MOVE_PRIVATE _HRESULT_TYPEDEF_(0x8011081EL) + +// +// MessageId: COMADMIN_E_BASEPARTITION_REQUIRED_IN_SET +// +// MessageText: +// +// The Base Application Partition exists in all partition sets and cannot be removed. +// +#define COMADMIN_E_BASEPARTITION_REQUIRED_IN_SET _HRESULT_TYPEDEF_(0x8011081FL) + +// +// MessageId: COMADMIN_E_CANNOT_ALIAS_EVENTCLASS +// +// MessageText: +// +// Alas, Event Class components cannot be aliased. +// +#define COMADMIN_E_CANNOT_ALIAS_EVENTCLASS _HRESULT_TYPEDEF_(0x80110820L) + +// +// MessageId: COMADMIN_E_PRIVATE_ACCESSDENIED +// +// MessageText: +// +// Access is denied because the component is private. +// +#define COMADMIN_E_PRIVATE_ACCESSDENIED _HRESULT_TYPEDEF_(0x80110821L) + +// +// MessageId: COMADMIN_E_SAFERINVALID +// +// MessageText: +// +// The specified SAFER level is invalid. +// +#define COMADMIN_E_SAFERINVALID _HRESULT_TYPEDEF_(0x80110822L) + +// +// MessageId: COMADMIN_E_REGISTRY_ACCESSDENIED +// +// MessageText: +// +// The specified user cannot write to the system registry +// +#define COMADMIN_E_REGISTRY_ACCESSDENIED _HRESULT_TYPEDEF_(0x80110823L) + +// +// MessageId: COMADMIN_E_PARTITIONS_DISABLED +// +// MessageText: +// +// COM+ partitions are currently disabled. +// +#define COMADMIN_E_PARTITIONS_DISABLED _HRESULT_TYPEDEF_(0x80110824L) + +#endif // GLDWINERRORDEF_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDWindowComboBox.h b/GCR/trunk/Glodon/include/GLD/GLDWindowComboBox.h new file mode 100644 index 00000000..5e689df2 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDWindowComboBox.h @@ -0,0 +1,197 @@ +#ifndef GLDWINDOWCOMBOBOX_H +#define GLDWINDOWCOMBOBOX_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "GLDWAbstractspinbox.h" + +class QStyleOptionSpinBox; +class GLDWindowComboBox; +class GLDComboBoxPopup; + +class GLDWIDGETSHARED_EXPORT GLDWindowComboBox : public GLDWAbstractSpinBox +{ + Q_OBJECT + Q_PROPERTY(bool hasSelectedText READ hasSelectedText) +public: + enum ButtonTypes { None, ComboBoxArrow, Ellipsis }; + + explicit GLDWindowComboBox(QWidget *parent = 0); + ~GLDWindowComboBox(); + + //设置下拉窗体对象 + QWidget *popupWidget() const; + virtual void setPopupWidget(QWidget *popup); + + //包含下拉窗体的外部控件 + inline GLDComboBoxPopup *comboBoxPopup() { return m_pComboxPopup; } + + bool isEditable() const; + void setEditable(bool editable); + + QString editText() const; + void setEditText(const QString &text); + + inline GLDPlainTextEdit *getLineEdit() { return lineEdit(); } + + //设置是否显示下拉窗体 + bool framePopup() const; + void setFramePopup(bool enable); + + inline bool hidePopupOnEdit() const { return m_hidePopupOnEdit; } + inline void setHidePopupOnEdit(const bool value) { m_hidePopupOnEdit = value; } + + inline bool showPopupOnEnter() const { return m_showPopupOnEnter; } + inline void setShowPopupOnEnter(const bool value) { m_showPopupOnEnter = value; } + + inline bool hideEditOnExit() const { return m_hideEditOnExit; } + inline void setHideEditOnExit(bool value) { m_hideEditOnExit = value;} + + /** + * @brief 下拉窗体显示的时间, 默认为150毫秒, 时间越小, 显示越快 + * 若要设置此时间, 请在setPopupWidget之后设置 + * @param time + */ + void setPopupScrollTime(int time); + int popupScrollTime(); + + void setResizeEnable(bool value); + void setPopupSize(QSize value); + void setPopupHeight(int value); + + void hidePopup(); //只隐藏,不关闭,焦点在editor上面 + + void setButtonTypes(ButtonTypes type); + ButtonTypes buttonType(); + + bool hasSelectedText(); + + inline void setAnimationPopup(bool animateEnabled = true) { m_animationPopup = animateEnabled; } + inline bool animationPopup() const { return m_animationPopup; } +public: + void showPopup(); + void closePopup(); + +Q_SIGNALS: + void onManualColsePopup(); + void keyPressType(Qt::Key key, bool &handled); + void onHide(); + void shouldShowPopup(bool &value); + + void selectionChanged(); + void cursorPositionChanged(); + +public slots: + void cut(); + void copy(); + void paste(); + void deleteSelectedText(); + +private Q_SLOTS: + void doPopupHide(); + void doSelectionChanged(); + void doCursorPositionChanged(); + +protected: + void init(); + QStyle::SubControl newHoverControl(const QPoint &pos); + virtual void updateEditFieldGeometry(); + void updateArrow(QStyle::StateFlag state); + void syncPopupWidget(); + void initComboBoxPopup(QWidget *cw = 0); + +protected: + void keyPressEvent(QKeyEvent *event); + void focusInEvent(QFocusEvent *event); + void mousePressEvent(QMouseEvent *event); + void paintEvent(QPaintEvent *event); + void contextMenuEvent(QContextMenuEvent *event); + void initStyleOption(QStyleOptionSpinBox *option) const; + + bool eventFilter(QObject *object, QEvent *event); + void resizeEvent(QResizeEvent *event); + void moveEvent(QMoveEvent *); + + void setPopupFixedWidth(int width); + +protected: + ButtonTypes m_buttonType; //edit中的按钮样式 + +private: + GLDComboBoxPopup *m_pComboxPopup; + bool m_hasHadFocus; + bool m_framePopuped; + bool m_hidePopupOnEdit; //弹出窗体后点击edit时隐藏下拉窗体 + bool m_showPopupOnEnter; //进入编辑框时直接弹出窗体 + bool m_hideEditOnExit; //失去焦点退出编辑 + QStyle::StateFlag m_arrowState; + bool m_editorNeedFocus;//进入编辑框并弹出窗体时设置焦点在editor上 + bool m_animationPopup; +#ifdef QT_KEYPAD_NAVIGATION + bool focusOnButton; +#endif + friend class GLDComboBoxPopup; +}; + +class GLDWIDGETSHARED_EXPORT GLDComboBoxPopup : public QDialog +{ + Q_OBJECT +public: + explicit GLDComboBoxPopup(QWidget *parent = 0, QWidget *cw = 0); + QWidget *popupWidget() const { return const_cast(this)->verifyPopupInstance(); } + + void setpopupWidget(QWidget *cw); + void setSizeGripEnabled(bool enabled); + void setPopupSize(QSize value); + void setPopupHeight(int value); + int popuHeight(); + inline void setAtBottom(bool value) { m_isAtBottom = value; } + QSize sizeHint() const; + inline void setScrollTime(int time) { m_scrollTime = time; } + inline int scrollTime() { return m_scrollTime; } + inline void setAnimationPopup(bool animateEnabled = true) { m_animationPopup = animateEnabled; } + inline bool animationPopup() const { return m_animationPopup; } + +Q_SIGNALS: + void onHide(); + void shouldShowPopup(bool &value); +public Q_SLOTS: + void setEditorFocus(); + void show(); + int exec(); +protected: + void showEvent(QShowEvent *e); + void hideEvent(QHideEvent *); + void mousePressEvent(QMouseEvent *e); + void mouseReleaseEvent(QMouseEvent *); + void resizeEvent(QResizeEvent *e); + bool event(QEvent *e); + bool eventFilter(QObject *object, QEvent *event); + void positionFramePopup(); +private: + QWidget *verifyPopupInstance(); + void setEdgeCursor(); + void alignResizer(const QRect &rect); + void initPopupSize(); +private: + QPointer m_popupWidget; + QPoint m_curPos; + QSizeGrip *m_resizer; + bool m_sizeGripEnabled; + //暂时不用,m_popupWidget没有设置eventFilter + bool m_cursorChanged; + bool m_canDrag; + bool m_isAtBottom; //resizer是否位于下面 + QSize m_popupSize; + int m_scrollTime; //ComboBoxPopup滚动出来所需要的时间,0为没有滚动效果 + bool m_animationPopup; + friend class GLDWindowComboBox; +}; + +#endif // GLDWINDOWCOMBOBOX_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDWindowComboBoxEx.h b/GCR/trunk/Glodon/include/GLD/GLDWindowComboBoxEx.h new file mode 100644 index 00000000..998b48e3 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDWindowComboBoxEx.h @@ -0,0 +1,219 @@ +#ifndef GLDWindowComboBoxEx_H +#define GLDWindowComboBoxEx_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "GLDWAbstractspinbox.h" + +class QStyleOptionSpinBox; +class GLDWindowComboBoxEx; +class GLDComboBoxPopupEx; + +class GLDWIDGETSHARED_EXPORT GLDWindowComboBoxEx : public GLDWAbstractSpinBox +{ + Q_OBJECT + Q_PROPERTY(bool hasSelectedText READ hasSelectedText) +public: + enum ButtonTypes { None, ComboBoxArrow, Ellipsis }; + + explicit GLDWindowComboBoxEx(QWidget *parent = 0); + ~GLDWindowComboBoxEx(); + + //设置下拉窗体对象 + QWidget *popupWidget() const; + virtual void setPopupWidget(QWidget *popup); + + //包含下拉窗体的外部控件 + inline GLDComboBoxPopupEx *comboBoxPopup() { return m_pComboxPopup; } + + //获取ComboBox右边Icon的QRect + inline QRect subIconRect() { return m_subIconRect; } + + bool isEditable() const; + void setEditable(bool editable); + + QString editText() const; + void setEditText(const QString &text); + + inline GLDPlainTextEdit *getLineEdit() { return lineEdit(); } + + //设置是否显示下拉窗体 + bool framePopup() const; + void setFramePopup(bool enable); + + inline bool hidePopupOnEdit() const { return m_hidePopupOnEdit; } + inline void setHidePopupOnEdit(const bool value) { m_hidePopupOnEdit = value; } + + inline bool showPopupOnEnter() const { return m_showPopupOnEnter; } + inline void setShowPopupOnEnter(const bool value) { m_showPopupOnEnter = value; } + + inline bool hideEditOnExit() const { return m_hideEditOnExit; } + inline void setHideEditOnExit(bool value) { m_hideEditOnExit = value;} + + /** + * @brief 下拉窗体显示的时间, 默认为150毫秒, 时间越小, 显示越快 + * 若要设置此时间, 请在setPopupWidget之后设置 + * @param time + */ + void setPopupScrollTime(int time); + int popupScrollTime(); + + void setResizeEnable(bool value); + void setPopupSize(QSize value); + + void hidePopup(); //只隐藏,不关闭,焦点在editor上面 + + void setButtonTypes(ButtonTypes type); + ButtonTypes buttonType(); + + bool hasSelectedText(); + + inline void setAnimationPopup(bool animateEnabled = true) { m_animationPopup = animateEnabled; } + inline bool animationPopup() const { return m_animationPopup; } + + void setComboBoxPopupOffset(const int xOffset = 0, const int yOffset = 0); + +public: + void showPopup(); + void closePopup(); + +public: + void setHasBorder(bool hasBorder = false); + void setEditProperty(bool bShow); + + bool isHidePopupOnEdit(); + void setIsHidePopupOnEdit(bool bIsHidePopupOnEdit); + void setFouseKeepInLineEdit(bool isKeepFouseInLineEdit); + +Q_SIGNALS: + void onManualColsePopup(); + void keyPressType(Qt::Key key, bool &handled); + void onHide(); + void shouldShowPopup(bool &value); + + void selectionChanged(); + void cursorPositionChanged(); + +public slots: + void cut(); + void copy(); + void paste(); + void deleteSelectedText(); + +private Q_SLOTS: + void doPopupHide(); + + void doSelectionChanged(); + void doCursorPositionChanged(); + +protected: + void init(); + QStyle::SubControl newHoverControl(const QPoint &pos); + virtual void updateEditFieldGeometry(); + void updateArrow(QStyle::StateFlag state); + void syncPopupWidget(); + void initComboBoxPopup(QWidget *cw = 0); + +protected: + void keyPressEvent(QKeyEvent *event); + void focusInEvent(QFocusEvent *event); + void mousePressEvent(QMouseEvent *event); + void paintEvent(QPaintEvent *event); + void contextMenuEvent(QContextMenuEvent *event); + void initStyleOption(QStyleOptionSpinBox *option) const; + + bool eventFilter(QObject *object, QEvent *event); + void resizeEvent(QResizeEvent *event); + void moveEvent(QMoveEvent *); + + void setPopupFixedWidth(int width); + +private: + bool m_hasHadFocus; + bool m_framePopuped; + bool m_hidePopupOnEdit; //弹出窗体后点击edit时隐藏下拉窗体 + bool m_showPopupOnEnter; //进入编辑框时直接弹出窗体 + bool m_hideEditOnExit; //失去焦点退出编辑 + QStyle::StateFlag m_arrowState; + GLDComboBoxPopupEx *m_pComboxPopup; + bool m_editorNeedFocus;//进入编辑框并弹出窗体时设置焦点在editor上 + ButtonTypes m_buttonType; //edit中的按钮样式 + bool m_animationPopup; + bool m_hasBorder; + QRect m_subIconRect; //右边图标的宽度 + bool m_isKeepFouseInLineEdit;//焦点位置是否一直位于lineedit内 + +#ifdef QT_KEYPAD_NAVIGATION + bool focusOnButton; +#endif + friend class GLDComboBoxPopupEx; +}; + +class GLDWIDGETSHARED_EXPORT GLDComboBoxPopupEx : public QDialog +{ + Q_OBJECT +public: + explicit GLDComboBoxPopupEx(QWidget *parent = 0, QWidget *cw = 0); + QWidget *popupWidget() const { return const_cast(this)->verifyPopupInstance(); } + + void setpopupWidget(QWidget *cw); + void setSizeGripEnabled(bool enabled); + void setPopupSize(QSize value); + inline void setAtBottom(bool value) { m_isAtBottom = value; } + QSize sizeHint() const; + inline void setScrollTime(int time) { m_scrollTime = time; } + inline int scrollTime() { return m_scrollTime; } + inline void setAnimationPopup(bool animateEnabled = true) { m_animationPopup = animateEnabled; } + inline bool animationPopup() const { return m_animationPopup; } + void setOffset(int xOffset = 0, int yOffset = 0); + +Q_SIGNALS: + void onHide(); + void shouldShowPopup(bool &value); + +public Q_SLOTS: + void setEditorFocus(); + void show(); + int exec(); + +protected: + void showEvent(QShowEvent *e); + void hideEvent(QHideEvent *); + void mousePressEvent(QMouseEvent *e); + void mouseReleaseEvent(QMouseEvent *); + void resizeEvent(QResizeEvent *e); + bool event(QEvent *e); + bool eventFilter(QObject *object, QEvent *event); + void positionFramePopup(); + +private: + QWidget *verifyPopupInstance(); + void setEdgeCursor(); + void alignResizer(const QRect &rect); + void initPopupSize(); + +private: + QPointer m_popupWidget; + QPoint m_curPos; + QSizeGrip *m_resizer; + bool m_sizeGripEnabled; + //暂时不用,m_popupWidget没有设置eventFilter + bool m_cursorChanged; + bool m_canDrag; + bool m_isAtBottom; //resizer是否位于下面 + QSize m_popupSize; + int m_scrollTime; //ComboBoxPopup滚动出来所需要的时间,0为没有滚动效果 + bool m_animationPopup; + int m_xOffset; // 下拉窗体x方向偏移量 + int m_yOffset; // 下拉窗体y方向偏移量 + friend class GLDWindowComboBoxEx; +}; + +#endif // GLDWindowComboBoxEx_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDXLS.h b/GCR/trunk/Glodon/include/GLD/GLDXLS.h new file mode 100644 index 00000000..3a30a1bb --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDXLS.h @@ -0,0 +1,16 @@ +#ifndef GLDXLS_H +#define GLDXLS_H + +#include "libxl.h" +#include +#include "GLDTableView_Global.h" + +GLDTABLEVIEWSHARED_EXPORT libxl::Book *createXLSBook(bool isXls); + +GLDTABLEVIEWSHARED_EXPORT Qt::Alignment XLSHorzAlignmentToQtAlignment(libxl::AlignH align); +GLDTABLEVIEWSHARED_EXPORT Qt::Alignment XLSVertAlignmentToQtAlignment(libxl::AlignV align); +GLDTABLEVIEWSHARED_EXPORT Qt::Alignment XLSAlignmentToQtAlignment(libxl::AlignH horzAlignment, libxl::AlignV vertAlignment); +GLDTABLEVIEWSHARED_EXPORT libxl::AlignV QtAlignmentToXLSVertAlignment(Qt::Alignment align); +GLDTABLEVIEWSHARED_EXPORT libxl::AlignH QtAlignmentToXLSHorzAlignment(Qt::Alignment align); + +#endif // GLDXLS_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDXLSModel.h b/GCR/trunk/Glodon/include/GLD/GLDXLSModel.h new file mode 100644 index 00000000..f9103f4e --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDXLSModel.h @@ -0,0 +1,81 @@ +#ifndef GLDXLSMODEL_H +#define GLDXLSMODEL_H + +#include "GLDString.h" +#include "GLDAbstractItemModel.h" +#include "GLDXLS.h" + +GLDTABLEVIEWSHARED_EXPORT libxl::Book *loadxlsFile(const GString &fileName); + +class GLDTABLEVIEWSHARED_EXPORT GlodonXLSModel : public GlodonAbstractItemModel +{ + Q_OBJECT +public: + explicit GlodonXLSModel(QObject *parent = 0); + virtual ~GlodonXLSModel(); + + bool load(const GString &fileName); + bool save(const GString &fileName); + bool setSheetIndex(int index); + + inline bool editable() const + { + return m_editable; + } + inline void setEditable(bool value) + { + m_editable = value; + } + inline libxl::Book *book() const + { + return m_book; + } + inline libxl::Book *bakBook() const + { + return m_bakBook; + } + void setXlsBook(libxl::Book *oBook); + void setXlsBakBook(libxl::Book *oBakBook); + inline libxl::Sheet *activeSheet() const + { + return m_sheet; + } + GString getSheetName() const; + +public: + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex &child) const; + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + bool hasChildren(const QModelIndex &parent = QModelIndex()) const; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, + int role = Qt::EditRole); + + Qt::ItemFlags flags(const QModelIndex &index) const; + +protected: + virtual QVariant displayData(int row, int col) const; + virtual QVariant editData(int row, int col) const; + bool doSetEditData(int row, int col, const QVariant &value); + +private: + libxl::Book *m_book; + libxl::Book *m_bakBook; //专门用来解析颜色 + libxl::Sheet *m_sheet; + + QList m_listBook; //统一存储生成的m_book和m_bakBook,在析构时统一释放 + + bool m_editable; + +private: + typedef GlodonAbstractItemModel inherited; +}; + +#endif // GLDXLSMODEL_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDXMLBuilder.h b/GCR/trunk/Glodon/include/GLD/GLDXMLBuilder.h new file mode 100644 index 00000000..73254168 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDXMLBuilder.h @@ -0,0 +1,43 @@ +#ifndef GXMLBUILDER_H +#define GXMLBUILDER_H + +#include "GLDString.h" +#include "GLDIODevice.h" +#include "GLDXML_Global.h" + +class CGLDXMLDocument; +class CGLDXMLNode; + +enum EnXMLEncode +{ + XE_ANSI, + XE_UTF8 +}; + +class GXMLBuilderPrivate; +class GLDXMLSHARED_EXPORT GXMLBuilder +{ +public: + explicit GXMLBuilder(GStream *stream); + ~GXMLBuilder(); + +public: + static GString saveDocText(CGLDXMLDocument *doc, bool replaceChars); + static void saveDoc(CGLDXMLDocument *doc, GStream *stream); + static void saveNode(CGLDXMLNode *node, GStream *stream); + void saveXMLDocument(CGLDXMLDocument *doc, bool replaceChars, bool ignoreEncode);// 需理清逻辑 + +private: + GString getNodeOpenTag(CGLDXMLNode *node, bool end = false); + GString getNodeCloseTag(CGLDXMLNode *node); + + void recursionWriteNode(CGLDXMLNode *node); + void writeIndentText(int level); + void writeText(const GString &text, bool addLineBreak = true); + +private: + GXMLBuilderPrivate * const d_ptr; + Q_DECLARE_PRIVATE(GXMLBuilder); +}; + +#endif // GXMLBUILDER_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDXMLCore.h b/GCR/trunk/Glodon/include/GLD/GLDXMLCore.h new file mode 100644 index 00000000..1f7fa458 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDXMLCore.h @@ -0,0 +1,249 @@ +#ifndef GLDXMLCORE_H +#define GLDXMLCORE_H + +#include "GLDComptr.h" +#include "GLDXMLInterface.h" + +class GLDXMLNode; +class GLDXMLNodeList; +class GLDXMLNodeAttribute; +class GLDXMLNodeAttributes; + +class GLDXMLSHARED_EXPORT GLDXMLDocument : public GComPtr // TXMLIntfObject未找到Qt中对应结构 +{ +public: + GLDXMLDocument(); + inline GLDXMLDocument(IGLDXMLDocument *lp) : GComPtr(lp) {} + inline GLDXMLDocument(IGLDXMLDocument *lp, bool /*dummy*/) : GComPtr(lp, false){} + template + inline GLDXMLDocument(const GComPtr &lp) : GComPtr(lp){} + +public: + GLDXMLNode createElement(const GString &name); + GLDXMLNode createNode(const GString &name, EnXMLNodeType type = ELEMENT); + bool isEmpty(); + void loadFromFile(const GString &fileName); + void saveToFile(const GString &fileName); + void loadFromStream(GStream *stream); + void loadFromStream(GStream *stream, bool aUseUtf8Optimize); + void saveToStream(GStream *stream); + + bool autoIndent(); + void setAutoIndent(bool value); + GString displayText(); + GLDXMLNode documentElement() const; + GString encoding(); + void setEncoding(const GString &value); + GString fileName(); + void setFileName(const GString &value); + bool includeHeader(); + void setIncludeHeader(bool value); + EnTXMLOptions options(); + void setOptions(EnTXMLOptions xmlOptionsSet); + GString version(); + void setVersion(const GString &value); + GString xml(); + void setXML(const GString &value); + GLDXMLNode root(); + void setRoot(const GLDXMLNode &root); + + /*Qt XML*/ + GLDXMLNode appendChild(GLDXMLNode newChild); + bool setContent(GStream* dev, GString *errorMsg=0, int *errorLine=0, int *errorColumn=0 ); + bool setContent(const GString& text, bool namespaceProcessing, GString *errorMsg=0, int *errorLine=0, int *errorColumn=0 ); + bool setContent(const GString& text, GString *errorMsg=0, int *errorLine=0, int *errorColumn=0 ); + bool setContent(const QByteArray& text, GString *errorMsg=0, int *errorLine=0, int *errorColumn=0 ); + GLDXMLNode firstChild() const; + void save(GStream* stream, int indent/*, EncodingPolicy=QDomNode::EncodingFromDocument*/); + GString toString(int indent = 1) const; + GLDXMLNode elementById(const GString &elementId); + GLDXMLNodeAttribute createAttribute(const GString& name); + GLDXMLNode firstChildElement(const GString &tagName = GString()) const; + GLDXMLNode createTextNode(const GString& data); + GLDXMLNodeList childNodes() const; + void clear(); + GLDXMLNode toElement() const; + bool isNull() const; + +private: + void innerCreateXMLDocument(); +}; + +class GLDXMLSHARED_EXPORT GLDXMLNode : public GComPtr +{ +public: + inline GLDXMLNode() : GComPtr () {} + inline GLDXMLNode(IGLDXMLNode *lp) : GComPtr(lp) {} + inline GLDXMLNode(IGLDXMLNode *lp, bool /*dummy*/) : GComPtr(lp, false){} + template + inline GLDXMLNode(const GComPtr &lp) : GComPtr(lp){} + +public: + GLDXMLNode addChild(const GString &strName); + GLDXMLNode cloneNode(bool deep = true); + bool hasAttribute(const GString &strName) const; + GLDXMLNode nextSibling(); + GLDXMLNode prevSibling(); + + bool asBoolean(); + double asFloat(); + gint64 asInt64(); + int asInteger(); + GString asString(); + GVariant asVariant(); + GLDXMLNodeAttributes attributes() const; + GLDXMLNodeList childNodes() const; + int level(); + GString name(); + EnXMLNodeType nodeType(); + GLDXMLNode parent() const; + GString text() const; + GString xml(); + + void setAsBoolean(bool value); + void setAsFloat(float value); + void setAsInt64(gint64 value); + void setAsInteger(int value); + void setAsString(const GString &value); + void setAsVariant(const GVariant value); + void setName(const GString &value); + void setNodeType(const EnXMLNodeType value); + void setParent(const GLDXMLNode &parent); + void setText(const GString &value); + void setXML(const GString &value); + void loadFromStream(GStream *pStream); + void saveToStream(GStream *pStream); + + /**Qt XML*/ + GLDXMLNode firstChildElement(const GString &tagName = GString()) const; + GString nodeName() const; + GLDXMLNode nextSiblingElement(const GString &taName = GString()) const; + GLDXMLDocument ownerDocument() const; + GLDXMLNode appendChild(const GLDXMLNode &newChild); + GString attribute(const GString& name, const GString& defValue = GString()) const; + void setAttribute(const GString& name, const GString& value); + void setAttribute(const GString& name, int value); + GLDXMLNode insertBefore(const GLDXMLNode &newChild, const GLDXMLNode &refChild); + GLDXMLNode removeChild(const GLDXMLNode &oldChild); + bool hasChildNodes() const; + GLDXMLNode parentNode() const; + void setNodeValue(const GString& value); + GLDXMLNodeAttribute attributeNode(const GString& name); + void clear(); + void setTagName(const GString& name); // Qt extension + GString tagName() const; + GLDXMLNode toElement() const; + GLDXMLNodeList elementsByTagName(const GString& tagname) const; + GLDXMLNode firstChild() const; + GString nodeValue() const; + GLDXMLNode lastChild() const; + GLDXMLNode toText() const; + GString data() const; + void removeAttribute(const GString& name); + GLDXMLNodeAttribute setAttributeNode(GLDXMLNodeAttribute& newAttr); + bool isNull() const; + bool isElement() const; + + GLDXMLNode replaceChild(const GLDXMLNode &newChild, const GLDXMLNode &oldChild); + GLDXMLNode insertAfter(const GLDXMLNode &newChild, const GLDXMLNode &refChild); + GLDXMLNode namedItem(const GString& name) const; +}; + +class GLDXMLSHARED_EXPORT GLDXMLNodeList : public GComPtr +{ +public: + inline GLDXMLNodeList() : GComPtr () {} + inline GLDXMLNodeList(IGLDXMLNodeList *lp) : GComPtr(lp) {} + inline GLDXMLNodeList(IGLDXMLNodeList *lp, bool /*dummy*/) : GComPtr(lp, false){} + template + inline GLDXMLNodeList(const GComPtr &lp) : GComPtr(lp){} + +public: + int add(const GLDXMLNode &node); + int deleteNode(const GString &name); + void deleteNode(int index); + int indexOf(const GLDXMLNode &node); + int indexOf(const GString &name); + int remove(const GLDXMLNode &node); + void clear(); + void exChange(int cureIndex, int newIndex); + void insert(int index, const GLDXMLNode &node); + void move(int cureIndex, int newIndex); + GLDXMLNode findNode(const GString &name); + + int count() const;// read m_count + GLDXMLNode node(int index);// read m_nodes + GLDXMLNode nodeByName(const GString &name);// read m_byNameB + + /*Qt XML*/ + GLDXMLNode at(int index) const; + int size() const { return count(); } + GLDXMLNode item(int index); +}; + +class GLDXMLSHARED_EXPORT GLDXMLNodeAttribute : public GComPtr +{ +public: + inline GLDXMLNodeAttribute() : GComPtr () {} + inline GLDXMLNodeAttribute(IGLDXMLNodeAttribute *lp) : GComPtr(lp) {} + inline GLDXMLNodeAttribute(IGLDXMLNodeAttribute *lp, bool /*dummy*/) : GComPtr(lp, false){} + template + inline GLDXMLNodeAttribute(const GComPtr &lp) : GComPtr(lp){} + +public: + bool asBoolean(); + double asFloat(); + gint64 asInt64(); + int asInteger(); + GString asString(); + GVariant asVariant(); + int hashData(); + GString name(); + GString text(); + GString xml(); + + void setAsBoolean(bool value); + void setAsFloat(double value); + void setAsInt64(gint64 value); + void setAsInteger(int value); + void setAsString(const GString &value); + void setAsVariant(const GVariant value); + void setName(const GString &strName); + void setText(const GString &strText); + void setXml(const GString &strXML); + + /*Qt XML*/ + void setNodeValue(const GString &value); + GString nodeValue() const; + GLDXMLNodeAttribute toAttr() const; + GString value() const; + GString nodeName() const; +}; + +class GLDXMLSHARED_EXPORT GLDXMLNodeAttributes : public GComPtr +{ +public: + inline GLDXMLNodeAttributes() : GComPtr () {} + inline GLDXMLNodeAttributes(IGLDXMLNodeAttributes *lp) : GComPtr(lp) {} + inline GLDXMLNodeAttributes(IGLDXMLNodeAttributes *lp, bool /*dummy*/) : GComPtr(lp, false){} + template + inline GLDXMLNodeAttributes(const GComPtr &lp) : GComPtr(lp){} + +public: + void clear(); + void remove(int nIndex); + void setXml(const GString &value); + + int count(); + int indexOf(const GString &strName); + + GString xml(); + GLDXMLNodeAttribute add(const GString &strName); + GLDXMLNodeAttribute item(int nIndex); + GLDXMLNodeAttribute itemsByName(const GString &strName); + + /*Qt XML*/ + GLDXMLNodeAttribute namedItem(const GString& name) const; + bool contains(const GString& name); +}; +#endif // GLDXMLCORE_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDXMLDoc.h b/GCR/trunk/Glodon/include/GLD/GLDXMLDoc.h new file mode 100644 index 00000000..dc73a2fc --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDXMLDoc.h @@ -0,0 +1,319 @@ +#ifndef GLDXMLDOC_H +#define GLDXMLDOC_H + +#include "GLDChar.h" +#include "GLDXMLInterface.h" +#include "GLDXML_Global.h" + +class CGLDXMLNode; +class CGLDXMLNodeAttribute; +class CGLDXMLDocument; +class CGLDXMLNodeAttributes; +class CGLDXMLNodeList; + +extern const GString c_uft8Encoding; +extern const GString c_gdefNodeName[4]; +extern const GString c_gconCDataPosx; +extern const GString c_gconCDataPrex; + +class CGLDXMLNodePrivate; +class GLDXMLSHARED_EXPORT CGLDXMLNode : public GInterfaceObject, public IGLDXMLNode, public IGLDXMLJSONPersistent +{ +public: + CGLDXMLNode(IGLDXMLNode *pParentNode, EnTXMLOptions enOptions, EnXMLNodeType enType, IGLDXMLDocument *ownerDocument = NULL); + virtual ~CGLDXMLNode(); + +public: + DECLARE_IUNKNOWN + IGLDXMLNode* GLDMETHODCALLTYPE addChild(GString strName); + IGLDXMLNode* GLDMETHODCALLTYPE cloneNode(bool deep); + bool GLDMETHODCALLTYPE hasAttribute(const GString &strName) const; + IGLDXMLNode* GLDMETHODCALLTYPE nextSibling(); + IGLDXMLNode* GLDMETHODCALLTYPE prevSibling(); + + bool GLDMETHODCALLTYPE asBoolean(); + double GLDMETHODCALLTYPE asFloat(); + gint64 GLDMETHODCALLTYPE asInt64(); + int GLDMETHODCALLTYPE asInteger(); + GString GLDMETHODCALLTYPE asString(); + GVariant GLDMETHODCALLTYPE asVariant(); + IGLDXMLNodeAttributes* GLDMETHODCALLTYPE attributes() const; + IGLDXMLNodeList* GLDMETHODCALLTYPE childNodes() const; + int GLDMETHODCALLTYPE level(); + QString GLDMETHODCALLTYPE name(); + EnXMLNodeType GLDMETHODCALLTYPE nodeType(); + IGLDXMLNode* GLDMETHODCALLTYPE parent() const; + QString GLDMETHODCALLTYPE text() const; + QString GLDMETHODCALLTYPE xml(); + void GLDMETHODCALLTYPE setAsBoolean(bool value); + void GLDMETHODCALLTYPE setAsFloat(double value); + void GLDMETHODCALLTYPE setAsInt64(gint64 value); + void GLDMETHODCALLTYPE setAsInteger(int value); + void GLDMETHODCALLTYPE setAsString(const GString &value); + void GLDMETHODCALLTYPE setAsVariant(const GVariant value); + void GLDMETHODCALLTYPE setName(const GString &value); + void GLDMETHODCALLTYPE setNodeType(const EnXMLNodeType value); + void GLDMETHODCALLTYPE setParent(IGLDXMLNode *value); + void GLDMETHODCALLTYPE setText(const GString &value); + void GLDMETHODCALLTYPE setXML(const GString &value); + + void GLDMETHODCALLTYPE loadFromStream(GStream *pStream); + void GLDMETHODCALLTYPE saveToStream(GStream *pStream); + + /*IGLDXMLJSONPersistent*/ + QString GLDMETHODCALLTYPE asJSON(); + void GLDMETHODCALLTYPE setAsJSON(const GString &strValue); + + /*Qt 兼容*/ + IGLDXMLNode* GLDMETHODCALLTYPE firstChildElement(const GString &tagName = GString()) const; + IGLDXMLNode* GLDMETHODCALLTYPE insertBefore(IGLDXMLNode *newChild, IGLDXMLNode *refChild); + + QString GLDMETHODCALLTYPE nodeValue() const; + IGLDXMLNodeAttribute* GLDMETHODCALLTYPE attributeNode(const QString &name); + IGLDXMLNode* GLDMETHODCALLTYPE replaceChild(IGLDXMLNode* newChild, IGLDXMLNode* oldChild); + IGLDXMLNode* GLDMETHODCALLTYPE insertAfter(IGLDXMLNode* newChild, IGLDXMLNode* refChild); + + void GLDMETHODCALLTYPE clear(); + void GLDMETHODCALLTYPE setAttribute(const GString &name, const GString &value); + void GLDMETHODCALLTYPE setAttribute(const GString &name, int value); + GString GLDMETHODCALLTYPE attribute(const GString &name, const GString &defValue = "attribute does not exist"); + IGLDXMLDocument* GLDMETHODCALLTYPE ownerDocument() const; + + IGLDXMLNode* GLDMETHODCALLTYPE toElement() const; + bool GLDMETHODCALLTYPE isElement() const; + bool GLDMETHODCALLTYPE isNull() const; + bool GLDMETHODCALLTYPE hasChildNodes() const; + IGLDXMLNode* GLDMETHODCALLTYPE parentNode() const; + void GLDMETHODCALLTYPE setNodeValue(const GString& value); + IGLDXMLNode* GLDMETHODCALLTYPE firstChild() const; + IGLDXMLNode* GLDMETHODCALLTYPE lastChild() const; + void GLDMETHODCALLTYPE removeAttribute(const GString& name); + IGLDXMLNodeAttribute* GLDMETHODCALLTYPE setAttributeNode(IGLDXMLNodeAttribute *newAttr); + + GString GLDMETHODCALLTYPE nodeName(); + IGLDXMLNode* GLDMETHODCALLTYPE nextSiblingElement(const GString &tagName); + IGLDXMLNode* GLDMETHODCALLTYPE appendChild(IGLDXMLNode *node); + IGLDXMLNode* GLDMETHODCALLTYPE removeChild(IGLDXMLNode *node); + void GLDMETHODCALLTYPE setTagName(const GString &name); + GString GLDMETHODCALLTYPE tagName(); + IGLDXMLNodeList* GLDMETHODCALLTYPE elementsByTagName(const GString &value); + IGLDXMLNode* GLDMETHODCALLTYPE toText(); + GString GLDMETHODCALLTYPE data(); + IGLDXMLNode* GLDMETHODCALLTYPE namedItem(const GString& name) const; + +public: + CGLDXMLNode* parentObj() const; + CGLDXMLNodeList* childNodesObj() const; + CGLDXMLNode* nextSiblingObj(); + CGLDXMLNode *prevSiblingObj(); + CGLDXMLNodeAttributes* attributesObj(); + CGLDXMLNode* cloneNodeObj(bool deep); + CGLDXMLNode* toElementObj() const; + +private: + int getFirstNonCharIdx(const GString str, const GChar ch, int nOffSet, bool isReverse = false); + int getFirstCharIdx(const GString str, const GChar ch, int nOffSet, bool isReverse = false); + void elementsByTagName(CGLDXMLNodeList *list, CGLDXMLNode *parent, const GString &value); + +private: + CGLDXMLNodePrivate * const d_ptr; + Q_DECLARE_PRIVATE(CGLDXMLNode); +}; + +class CGLDXMLNodeAttributePrivate; +class GLDXMLSHARED_EXPORT CGLDXMLNodeAttribute : public GInterfaceObject, public IGLDXMLNodeAttribute +{ +public: + CGLDXMLNodeAttribute(const GString &name, EnTXMLOptions options); + virtual ~CGLDXMLNodeAttribute(); + +public: + DECLARE_IUNKNOWN + bool GLDMETHODCALLTYPE asBoolean(); + double GLDMETHODCALLTYPE asFloat(); + gint64 GLDMETHODCALLTYPE asInt64(); + int GLDMETHODCALLTYPE asInteger(); + GString GLDMETHODCALLTYPE asString(); + GVariant GLDMETHODCALLTYPE asVariant(); + int GLDMETHODCALLTYPE hashData(); + GString GLDMETHODCALLTYPE name(); + GString GLDMETHODCALLTYPE text(); + GString GLDMETHODCALLTYPE xml(); + void GLDMETHODCALLTYPE setAsBoolean(bool value); + void GLDMETHODCALLTYPE setAsFloat(double value); + void GLDMETHODCALLTYPE setAsInt64(gint64 value); + void GLDMETHODCALLTYPE setAsInteger(int value); + void GLDMETHODCALLTYPE setAsString(const GString &value); + void GLDMETHODCALLTYPE setAsVariant(const GVariant value); + void GLDMETHODCALLTYPE setName(const GString &strName); + void GLDMETHODCALLTYPE setText(const GString &strText); + void GLDMETHODCALLTYPE setXml(const GString &strXML); + + /*QT 兼容*/ + GString GLDMETHODCALLTYPE nodeName() const; + CGLDXMLNodeAttribute* GLDMETHODCALLTYPE toAttr(); + GString GLDMETHODCALLTYPE value(); + GString GLDMETHODCALLTYPE nodeValue(); + void GLDMETHODCALLTYPE setNodeValue(const GString& value); + +private: + GString copyTrimSpaceAndQuotaionMark(const GString &str, int index); + +private: + CGLDXMLNodeAttributePrivate * const d_ptr; + Q_DECLARE_PRIVATE(CGLDXMLNodeAttribute); +}; + +class CGLDXMLDocumentPrivate; +class GLDXMLSHARED_EXPORT CGLDXMLDocument : public GInterfaceObject, public IGLDXMLDocument, public IGLDXMLJSONPersistent, public IGLDXMLJSONPersistentFile // TXMLIntfObject未找到Qt中对应结构 +{ +public: + explicit CGLDXMLDocument(); + ~CGLDXMLDocument(); + +public: + DECLARE_IUNKNOWN + IGLDXMLNode* GLDMETHODCALLTYPE createElement(const GString &name); + IGLDXMLNode* GLDMETHODCALLTYPE createNode(const GString &name, EnXMLNodeType type = ELEMENT); + bool GLDMETHODCALLTYPE isEmpty(); + void GLDMETHODCALLTYPE loadFromFile(const GString &fileName); + void GLDMETHODCALLTYPE saveToFile(const GString &fileName); + void GLDMETHODCALLTYPE loadFromStream(GStream *stream); + void GLDMETHODCALLTYPE loadFromStream(GStream *stream, bool aUseUtf8Optimize); + void GLDMETHODCALLTYPE saveToStream(GStream *stream); + GString GLDMETHODCALLTYPE getXMLHeader(); + IGLDXMLNode* GLDMETHODCALLTYPE appendChild(IGLDXMLNode *newChild); + IGLDXMLNode* GLDMETHODCALLTYPE firstChild() const; + void GLDMETHODCALLTYPE save(GStream* stream, int indent/*, EncodingPolicy=QDomNode::EncodingFromDocument*/) const; + bool GLDMETHODCALLTYPE setContent(GStream* dev, GString *errorMsg=0, int *errorLine=0, int *errorColumn=0 ); + bool GLDMETHODCALLTYPE setContent(const GString& text, bool namespaceProcessing, GString *errorMsg=0, int *errorLine=0, int *errorColumn=0 ); + bool GLDMETHODCALLTYPE setContent(const QString& text, QString *errorMsg=0, int *errorLine=0, int *errorColumn=0 ); + bool GLDMETHODCALLTYPE setContent(const QByteArray& text, QString *errorMsg=0, int *errorLine=0, int *errorColumn=0 ); + IGLDXMLNodeAttribute* GLDMETHODCALLTYPE createAttribute(const QString& name); + IGLDXMLNode* GLDMETHODCALLTYPE createTextNode(const GString& data); + IGLDXMLNodeList* GLDMETHODCALLTYPE childNodes() const; + void GLDMETHODCALLTYPE clear(); + + bool GLDMETHODCALLTYPE autoIndent(); + void GLDMETHODCALLTYPE setAutoIndent(bool value); + GString GLDMETHODCALLTYPE displayText(); + IGLDXMLNode* GLDMETHODCALLTYPE documentElement() const; + GString GLDMETHODCALLTYPE encoding(); + void GLDMETHODCALLTYPE setEncoding(const GString &value); + GString GLDMETHODCALLTYPE fileName(); + void GLDMETHODCALLTYPE setFileName(const GString &value); + bool GLDMETHODCALLTYPE includeHeader(); + void GLDMETHODCALLTYPE setIncludeHeader(bool value); + EnTXMLOptions GLDMETHODCALLTYPE options(); + void GLDMETHODCALLTYPE setOptions(EnTXMLOptions xmlOptionsSet); + GString GLDMETHODCALLTYPE version(); + void GLDMETHODCALLTYPE setVersion(const GString &value); + GString GLDMETHODCALLTYPE xml(); + void GLDMETHODCALLTYPE setXML(const GString &value); + IGLDXMLNode* GLDMETHODCALLTYPE root(); + void GLDMETHODCALLTYPE setRoot(IGLDXMLNode *root); + GString GLDMETHODCALLTYPE toString(int indent = 1) const; + IGLDXMLNode* GLDMETHODCALLTYPE elementById(const GString &elementID); + IGLDXMLNode* GLDMETHODCALLTYPE firstChildElement(const GString &tagName) const; + IGLDXMLNode* GLDMETHODCALLTYPE toElement() const; + bool GLDMETHODCALLTYPE isNull() const; + + //GIXMLJSONPsst + GString GLDMETHODCALLTYPE asJSON(); //读m_asJSON + void GLDMETHODCALLTYPE setAsJSON(const GString &value);//写m_asJSON + + //GIXMLJSONPsstFile + void GLDMETHODCALLTYPE loadFromJSONFile(const GString &fileName); + void GLDMETHODCALLTYPE loadFromJSONStream(GStream *stream); + void GLDMETHODCALLTYPE saveAsJSONToFile(const GString &fileName); + void GLDMETHODCALLTYPE saveAsJSONToStream(GStream *stream); + +public: + CGLDXMLNode* createNodeObj(const GString &name, EnXMLNodeType type = ELEMENT); + void setRootObj(CGLDXMLNode *root); + CGLDXMLNode *rootObj(); + bool findEncoding(const char *data, bool &bom, GString &encoding); + void parse(const GString &data, int pos); + +private: + CGLDXMLDocumentPrivate * const d_ptr; + Q_DECLARE_PRIVATE(CGLDXMLDocument); +}; + +class CGLDXMLNodeAttributesPrivate; +class GLDXMLSHARED_EXPORT CGLDXMLNodeAttributes : public GInterfaceObject, public IGLDXMLNodeAttributes +{ +public: + CGLDXMLNodeAttributes(EnTXMLOptions enOptions); + ~CGLDXMLNodeAttributes(); + +public: + DECLARE_IUNKNOWN + IGLDXMLNodeAttribute* GLDMETHODCALLTYPE add(const GString &strName); + int GLDMETHODCALLTYPE indexOf(const GString &strName); + void GLDMETHODCALLTYPE clear(); + void GLDMETHODCALLTYPE remove(int nIndex); + + int GLDMETHODCALLTYPE count(); + IGLDXMLNodeAttribute* GLDMETHODCALLTYPE item(int nIndex); + IGLDXMLNodeAttribute* GLDMETHODCALLTYPE itemsByName(const GString &strName); + GString GLDMETHODCALLTYPE xml(); + void GLDMETHODCALLTYPE setXml(const GString &value); + + /*Qt 兼容*/ + int hashOf(const GString &strName); + bool GLDMETHODCALLTYPE contains(const GString& name); + IGLDXMLNodeAttribute* GLDMETHODCALLTYPE namedItem(const GString &name); + +public: + CGLDXMLNodeAttribute* itemsByNameObj(const GString &strName); + CGLDXMLNodeAttribute* addObj(const GString &strName); + CGLDXMLNodeAttribute* itemObj(int nIndex); + +private: + void doAddAttribute(const GString &strName, const GString &strText); + bool findQuotationStr(const GString &str, int nstartPos, GString &squotedString, int &nendPos); + GString trimSpecialChar(const GString &value); + +private: + CGLDXMLNodeAttributesPrivate * const d_ptr; + Q_DECLARE_PRIVATE(CGLDXMLNodeAttributes); +}; + +class CGLDXMLNodeListPrivate; +class GLDXMLSHARED_EXPORT CGLDXMLNodeList : public GInterfaceObject, public IGLDXMLNodeList +{ +public: + explicit CGLDXMLNodeList(IGLDXMLNode *parent=0); + ~CGLDXMLNodeList(); + +public: + DECLARE_IUNKNOWN + int GLDMETHODCALLTYPE add(IGLDXMLNode *node); + int GLDMETHODCALLTYPE deleteNode(const GString &name); + void GLDMETHODCALLTYPE deleteNode(int index); + IGLDXMLNode* GLDMETHODCALLTYPE findNode(const GString &name); + int GLDMETHODCALLTYPE indexOf(IGLDXMLNode *node) const; + int GLDMETHODCALLTYPE indexOf(const GString &name) const; + int GLDMETHODCALLTYPE remove(IGLDXMLNode *node); + void GLDMETHODCALLTYPE clear(); + void GLDMETHODCALLTYPE exChange(int cureIndex, int newIndex); + void GLDMETHODCALLTYPE insert(int index, IGLDXMLNode *node); + void GLDMETHODCALLTYPE move(int cureIndex, int newIndex); + + int GLDMETHODCALLTYPE count()const; + IGLDXMLNode* GLDMETHODCALLTYPE item(int index); + IGLDXMLNode* GLDMETHODCALLTYPE node(int index); + IGLDXMLNode* GLDMETHODCALLTYPE nodeByName(const GString &name); + + /*Qt 兼容*/ + IGLDXMLNode* GLDMETHODCALLTYPE at(int index); +public: + CGLDXMLNode* nodeObj(int index); + CGLDXMLNode* findNodeObj(const GString &name) const; + +private: + CGLDXMLNodeListPrivate * const d_ptr; + Q_DECLARE_PRIVATE(CGLDXMLNodeList); +}; +#endif // GLDXMLDOC_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDXMLInterface.h b/GCR/trunk/Glodon/include/GLD/GLDXMLInterface.h new file mode 100644 index 00000000..47cdb361 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDXMLInterface.h @@ -0,0 +1,254 @@ +#ifndef GLDXMLINTERFACE_H +#define GLDXMLINTERFACE_H + +#include "GLDString.h" +#include "GLDVariant.h" +#include "GLDStream.h" +#include "GLDObject.h" +#include "GLDStrings.h" +#include "GLDXML_Global.h" + +interface IGLDXMLDocument; +interface IGLDXMLNodeList; +interface IGLDXMLNodeAttribute; +interface IGLDXMLNodeAttributes; + +typedef byte EnTXMLOptions; + +enum EnXMLNodeType +{ + ELEMENT, + TEXT, + CDATA, + COMMENT +}; + + +enum EnTXMLOption +{ + XO_DECODE_CRLF, + XO_ENCODE_CRLF, + XO_IGNORE_CDATA, + XO_IGNORE_COMMENT +}; + +DEFINE_IID(IGLDXMLNode, "06468216-F087-47CA-AD19-A47393AFFF56"); +DECLARE_INTERFACE_(IGLDXMLNode, IUnknown) +{ + GLDMETHOD(IGLDXMLNode *, addChild)(GString name) PURE; //返回自身类型需要返回指针类型 + GLDMETHOD(IGLDXMLNode *, cloneNode)(bool bDeep) PURE; + GLDMETHOD(bool, hasAttribute)(const GString &nme) const PURE; + GLDMETHOD(IGLDXMLNode *, nextSibling)() PURE; + GLDMETHOD(IGLDXMLNode *, prevSibling)() PURE; + + GLDMETHOD(bool, asBoolean)() PURE; + GLDMETHOD(double, asFloat)() PURE; + GLDMETHOD(int, asInteger)() PURE; + GLDMETHOD(GString, asString)() PURE; + GLDMETHOD(GVariant, asVariant)() PURE; + GLDMETHOD(IGLDXMLNodeAttributes *, attributes)() const PURE; + GLDMETHOD(IGLDXMLNodeList *, childNodes)() const PURE; + GLDMETHOD(bool, hasChildNodes)()const PURE; + GLDMETHOD(int, level)() PURE; + GLDMETHOD(GString, name)() PURE; + GLDMETHOD(EnXMLNodeType, nodeType)() PURE; + GLDMETHOD(IGLDXMLNode *, parent)() const PURE; + GLDMETHOD(GString, text)() const PURE; + GLDMETHOD(GString, xml)() PURE; + + GLDMETHOD(void, setAsBoolean)(bool value) PURE; + GLDMETHOD(void, setAsFloat)(double value) PURE; + GLDMETHOD(void, setAsInteger)(int value) PURE; + GLDMETHOD(void, setAsString)(const GString &value) PURE; + GLDMETHOD(void, setAsVariant)(const GVariant value) PURE; + GLDMETHOD(void, setName)(const GString &value) PURE; + GLDMETHOD(void, setNodeType)(const EnXMLNodeType value) PURE; + GLDMETHOD(void, setParent)(IGLDXMLNode *value) PURE; + GLDMETHOD(void, setText)(const GString &value) PURE; + GLDMETHOD(void, setXML)(const GString &value) PURE; + + GLDMETHOD(void, loadFromStream)(GStream *stream) PURE; + GLDMETHOD(void, saveToStream)(GStream *stream) PURE; + + GLDMETHOD(gint64, asInt64)() PURE; + GLDMETHOD(void, setAsInt64)(gint64) PURE; + + /*Qt 兼容*/ + GLDMETHOD(IGLDXMLNode*, replaceChild)(IGLDXMLNode* newChild, IGLDXMLNode* oldChild) PURE; + GLDMETHOD (IGLDXMLNode*, insertAfter)(IGLDXMLNode* newChild, IGLDXMLNode* refChild) PURE; + GLDMETHOD(IGLDXMLNode *, firstChildElement)(const GString &tagName = GString()) const PURE; + GLDMETHOD(IGLDXMLNode *, insertBefore)(IGLDXMLNode *newChild, IGLDXMLNode *refChild) PURE; + GLDMETHOD(IGLDXMLNodeAttribute *, attributeNode)(const QString &name) PURE; + GLDMETHOD(GString, nodeName)() PURE; + GLDMETHOD(IGLDXMLNode *, nextSiblingElement)(const GString &value) PURE; + GLDMETHOD(IGLDXMLNode *, appendChild)(IGLDXMLNode *value) PURE; + GLDMETHOD(IGLDXMLNode *, removeChild)(IGLDXMLNode *value) PURE; + GLDMETHOD(void, setTagName)(const GString &value) PURE; + GLDMETHOD(GString, tagName)() PURE; + GLDMETHOD(IGLDXMLNodeList *, elementsByTagName)(const GString &value) PURE; + GLDMETHOD(IGLDXMLNode *, toText)() PURE; + GLDMETHOD(GString, data)() PURE; + GLDMETHOD(void, setAttribute)(const GString &name, const GString &value) PURE; + GLDMETHOD(void, setAttribute)(const GString &name, int value) PURE; + GLDMETHOD(GString, attribute)(const GString &name, const GString &defValue) PURE; + GLDMETHOD(void, clear)() PURE; + GLDMETHOD(GString, nodeValue)() const PURE; + GLDMETHOD(IGLDXMLDocument*, ownerDocument)() const PURE; + GLDMETHOD(IGLDXMLNode*, toElement)() const PURE; + GLDMETHOD(bool, isElement)() const PURE; + GLDMETHOD(bool, isNull)() const PURE; + GLDMETHOD(IGLDXMLNode*, parentNode)() const PURE; + GLDMETHOD(void, setNodeValue)(const GString &value) PURE; + GLDMETHOD(IGLDXMLNode*, firstChild)()const PURE; + GLDMETHOD(IGLDXMLNode*, lastChild)()const PURE; + GLDMETHOD(void, removeAttribute)(const GString &name) PURE; + GLDMETHOD(IGLDXMLNodeAttribute*, setAttributeNode)(IGLDXMLNodeAttribute* newAttr) PURE; + GLDMETHOD(IGLDXMLNode *, namedItem)(const GString &name) const PURE; +}; + +DEFINE_IID(IGLDXMLNodeList, "9152F99B-EA65-480A-98F2-FCFF212E0F23"); +DECLARE_INTERFACE_(IGLDXMLNodeList, IUnknown) +{ + GLDMETHOD(int, add)(IGLDXMLNode *node) PURE; + GLDMETHOD(int, deleteNode)(const GString &name) PURE;// deleteNode -> Delete + GLDMETHOD(void, deleteNode)(int index) PURE; + GLDMETHOD(IGLDXMLNode *, findNode)(const GString &name) PURE;// strName -> AName + GLDMETHOD(int, indexOf)(IGLDXMLNode *node) const PURE; + GLDMETHOD(int, indexOf)(const GString &name) const PURE; + GLDMETHOD(int, remove)(IGLDXMLNode *node) PURE; + GLDMETHOD(void, clear)() PURE; + GLDMETHOD(void, insert)(int nIndex, IGLDXMLNode *node) PURE; + GLDMETHOD(void, move)(int currIndex, int newIndex) PURE; + GLDMETHOD(void, exChange)(int index1, int index2) PURE; + + GLDMETHOD(int, count)()const PURE;// read count; + GLDMETHOD(IGLDXMLNode *, node)(int index) PURE;// read nodes; + GLDMETHOD(IGLDXMLNode *, nodeByName)(const GString &name) PURE;// read byNameNode; + + /*Qt 兼容*/ + GLDMETHOD(IGLDXMLNode *, at)(int index) PURE; + GLDMETHOD(IGLDXMLNode *, item)(int index) PURE; +}; + +DEFINE_IID(IGLDXMLDocument, "A773026D-A728-46A8-A181-372D49FF00CE"); +DECLARE_INTERFACE_(IGLDXMLDocument, IUnknown) +{ + GLDMETHOD(IGLDXMLNode*, createElement)(const GString &name) PURE; + GLDMETHOD(IGLDXMLNode*, createNode)(const GString &name, EnXMLNodeType type = ELEMENT) PURE; + GLDMETHOD(bool, autoIndent)() PURE; + GLDMETHOD(GString, displayText)() PURE; + GLDMETHOD(IGLDXMLNode*, documentElement)() const PURE; + + GLDMETHOD(GString, encoding)() PURE; + GLDMETHOD(GString, fileName)() PURE; + GLDMETHOD(bool, includeHeader)() PURE; + GLDMETHOD(EnTXMLOptions, options)() PURE; + GLDMETHOD(GString, version)() PURE; + GLDMETHOD(GString, xml)() PURE; + + GLDMETHOD(bool, isEmpty)() PURE; + GLDMETHOD(void, loadFromFile)(const GString &fileName) PURE; + GLDMETHOD(void, loadFromStream)(GStream *stream) PURE; + GLDMETHOD(void, saveToFile)(const GString &fileName) PURE; + GLDMETHOD(void, saveToStream)(GStream *stream) PURE; + GLDMETHOD(void, setAutoIndent)(bool value) PURE; + GLDMETHOD(void, setEncoding)(const GString &value) PURE; + GLDMETHOD(void, setFileName)(const GString &value) PURE; + GLDMETHOD(void, setIncludeHeader)(bool value) PURE; + GLDMETHOD(void, setOptions)(EnTXMLOptions xmlOptionsSet) PURE; + GLDMETHOD(void, setVersion)(const GString &value) PURE; + GLDMETHOD(void, setXML)(const GString &value) PURE; + + /*Qt 兼容*/ + GLDMETHOD(IGLDXMLNode*, appendChild)(IGLDXMLNode *newChild) PURE; + GLDMETHOD(IGLDXMLNode*, firstChild)() const PURE; + GLDMETHOD(void, save)(GStream *stream, int indent) const PURE; + GLDMETHOD(bool, setContent)(GStream* dev, GString *errorMsg=0, int *errorLine=0, int *errorColumn=0 ) PURE; + GLDMETHOD(bool, setContent)(const GString& text, bool namespaceProcessing, + GString *errorMsg=0, int *errorLine=0, int *errorColumn=0 ) PURE; + GLDMETHOD(bool, setContent)(const QString& text, QString *errorMsg=0, int *errorLine=0, int *errorColumn=0 ) PURE; + GLDMETHOD(bool, setContent)(const QByteArray& text, QString *errorMsg=0, int *errorLine=0, int *errorColumn=0 ) PURE; + GLDMETHOD(IGLDXMLNodeAttribute*, createAttribute)(const QString& name) PURE; + GLDMETHOD(IGLDXMLNode*, createTextNode)(const GString& data) PURE; + GLDMETHOD(IGLDXMLNodeList*, childNodes)() const PURE; + GLDMETHOD(void, clear)() PURE; + + GLDMETHOD(IGLDXMLNode *, root)() PURE; + GLDMETHOD(void, setRoot)(IGLDXMLNode *root) PURE; + GLDMETHOD(GString, toString)(int indent = 1) const PURE; + GLDMETHOD(IGLDXMLNode*, toElement)()const PURE; + GLDMETHOD(IGLDXMLNode*, elementById)(const GString &elementID) PURE; + GLDMETHOD(IGLDXMLNode*, firstChildElement)(const GString &tagName) const PURE; + GLDMETHOD(bool, isNull)() const PURE; + +}; + +DEFINE_IID(IGLDXMLNodeAttribute, "59939529-966F-45C9-B581-19EEF1D1FEDE"); +DECLARE_INTERFACE_(IGLDXMLNodeAttribute, IUnknown) +{ + GLDMETHOD(bool, asBoolean)() PURE; + GLDMETHOD(double, asFloat)() PURE; + GLDMETHOD(int, asInteger)() PURE; + GLDMETHOD(GString, asString)() PURE; + GLDMETHOD(GVariant, asVariant)() PURE; + GLDMETHOD(int, hashData)() PURE; + GLDMETHOD(GString, name)() PURE; + GLDMETHOD(GString, text)() PURE; + GLDMETHOD(GString, xml)()PURE; + + GLDMETHOD(void, setAsBoolean)(bool value) PURE; + GLDMETHOD(void, setAsFloat)(double value) PURE; + GLDMETHOD(void, setAsInteger)(int value) PURE; + GLDMETHOD(void, setAsString)(const GString &value) PURE; + GLDMETHOD(void, setAsVariant)(const GVariant value) PURE; + GLDMETHOD(void, setName)(const GString &strName) PURE; + GLDMETHOD(void, setText)(const GString &strText) PURE; + GLDMETHOD(void, setXml)(const GString &strXML) PURE; + GLDMETHOD(gint64, asInt64)() PURE; + GLDMETHOD(void, setAsInt64)(gint64 value) PURE; + + /*Qt 兼容*/ + GLDMETHOD(GString, value)() PURE; + GLDMETHOD(IGLDXMLNodeAttribute*, toAttr)() PURE; + GLDMETHOD(GString, nodeName)() const PURE; + + GLDMETHOD(GString, nodeValue)()PURE; + GLDMETHOD(void, setNodeValue)(const GString &value) PURE; +}; + +DEFINE_IID(IGLDXMLNodeAttributes, "6874C84B-2E07-45CA-B463-B03CF031FD8D"); +DECLARE_INTERFACE_(IGLDXMLNodeAttributes, IUnknown) +{ + GLDMETHOD(IGLDXMLNodeAttribute*, add)(const GString &strName) PURE; + GLDMETHOD(int, indexOf)(const GString &strName) PURE; + GLDMETHOD(void, clear)() PURE; + GLDMETHOD(void, remove)(int nIndex) PURE; + + GLDMETHOD(int, count)() PURE; + GLDMETHOD(IGLDXMLNodeAttribute*, item)(int nIndex) PURE; + GLDMETHOD(IGLDXMLNodeAttribute*, itemsByName)(const GString &strName) PURE; + GLDMETHOD(void, setXml)(const GString &value) PURE; + GLDMETHOD(GString, xml)() PURE; + + /*Qt 兼容*/ + GLDMETHOD(bool, contains)(const GString &name) PURE; + GLDMETHOD(IGLDXMLNodeAttribute*, namedItem)(const GString &name) PURE; +}; + +DEFINE_IID(IGLDXMLJSONPersistent, "B790D662-8515-4FEB-BE01-B7ADFCB9B5AC"); +DECLARE_INTERFACE_(IGLDXMLJSONPersistent, IUnknown) +{ + GLDMETHOD(GString, asJSON)() PURE; //读m_asJSON + GLDMETHOD(void, setAsJSON)(const GString &value) PURE;//写m_asJSON +}; + +DEFINE_IID(IGLDXMLJSONPersistentFile, "30DC536F-72D5-4359-A09E-ED4A2E26EFD6"); +DECLARE_INTERFACE_(IGLDXMLJSONPersistentFile, IUnknown) +{ + GLDMETHOD(void, loadFromJSONFile)(const GString &fileName) PURE; + GLDMETHOD(void, loadFromJSONStream)(GStream *stream) PURE; + GLDMETHOD(void, saveAsJSONToFile)(const GString &fileName) PURE; + GLDMETHOD(void, saveAsJSONToStream)(GStream *stream) PURE; + +}; +#endif // GLDXMLINTERFACE_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDXMLParser.h b/GCR/trunk/Glodon/include/GLD/GLDXMLParser.h new file mode 100644 index 00000000..8902d28d --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDXMLParser.h @@ -0,0 +1,38 @@ +#ifndef GXMLPARSER_H +#define GXMLPARSER_H + +#include "GLDStrUtils.h" +#include "GLDXMLInterface.h" +#include "GLDXMLDoc.h" + +class CGLDXMLDocument; + +class GXMLParserPrivate; +class GLDXMLSHARED_EXPORT GXMLParser +{ +public: + explicit GXMLParser(const GString strData, IGLDXMLNode *pBase, EnTXMLOptions Options ); + ~GXMLParser(); + +public: + CGLDXMLNode *addOpenTag(const GString &text); + void addCloseTag(); + void addDataNode(const GString &data, EnXMLNodeType nodeType); + void addProcessingInstruction(const GString &data); + void doParse(); + void xmlDocErrorInParser(const GString &msg); + CGLDXMLNode *base(); + const CGLDXMLNode *current(); + GString encoding(); + GString version(); + void setPos(int pos); + void setDocument(CGLDXMLDocument *document); + static void execute(const GString &data, CGLDXMLDocument *pdoc, int iPos); + static void execute(const GString &data, CGLDXMLNode *pBase, EnTXMLOptions options); + +private: + GXMLParserPrivate * const d_ptr; + Q_DECLARE_PRIVATE(GXMLParser); +}; + +#endif // GXMLPARSER_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDXMLSAXUtils.h b/GCR/trunk/Glodon/include/GLD/GLDXMLSAXUtils.h new file mode 100644 index 00000000..3bfb8a07 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDXMLSAXUtils.h @@ -0,0 +1,56 @@ +#ifndef GLDSAXXMLUTILS_H +#define GLDSAXXMLUTILS_H + +#include +#include "GLDString.h" +#include "GLDFile.h" +#include "GLDXML_Global.h" + +class GLDXMLSAXReaderPrivate; +class GLDXMLSHARED_EXPORT GLDXMLSAXReader +{ +public: + explicit GLDXMLSAXReader(); + explicit GLDXMLSAXReader(const GString &fileName); + explicit GLDXMLSAXReader(QIODevice *device); + virtual ~GLDXMLSAXReader(); +public: + static GString tr(const char *sourceText, const char *disambiguation = 0, int n = -1); +public: + GString readNextNode(const GString &nodeName = ""); + GStringRef readNextNodeNameRef(const GLatin1String &nodeName); + GStringRef readNextNodeNameRef(); + GString readAttribute(const GString &attributeName) const; + bool hasAttribute(const GString &attribute) const; + QXmlStreamAttributes attributes() const; + GString readElementText(QXmlStreamReader::ReadElementTextBehaviour behaviour = QXmlStreamReader::ErrorOnUnexpectedElement); + + GStringRef text() const; + GString name() const; + GStringRef nameRef() const; + + bool atEnd() const; + bool isEndElement() const; + bool isEndDocument() const; + bool isStartElement() const; + bool isStartDocument() const; + bool isCharacters() const; + bool isWhitespace() const; + bool isCDATA() const; + bool isComment() const; + bool isDTD() const; + bool isEntityReference() const; + bool isProcessingInstruction() const; + void skipCurrentElement(); + void reset(); + + void setDevice(QIODevice *device); + void setFilename(const GString &fileName); + void closeFile(); + QXmlStreamReader& reader(); +private: + GLDXMLSAXReaderPrivate * const d_ptr; + Q_DECLARE_PRIVATE(GLDXMLSAXReader); +}; + +#endif // GLDSAXXMLUTILS_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDXMLTypes.h b/GCR/trunk/Glodon/include/GLD/GLDXMLTypes.h new file mode 100644 index 00000000..303085f2 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDXMLTypes.h @@ -0,0 +1,15 @@ +#ifndef GLDXMLTYPES_H +#define GLDXMLTYPES_H + +#include + +typedef QDomDocument GXMLDocument; +typedef QDomElement GXMLNode; +typedef QDomNodeList GDomNodeList; +typedef QDomNode GDomNode; +typedef QDomText GDomText; +typedef QDomAttr GDomAttr; +typedef QDomProcessingInstruction GDomProcessingInstruction; +typedef QDomNamedNodeMap GDomNamedNodeMap; + +#endif // GLDXMLTYPES_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDXMLUtils.h b/GCR/trunk/Glodon/include/GLD/GLDXMLUtils.h new file mode 100644 index 00000000..191c6d4b --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDXMLUtils.h @@ -0,0 +1,97 @@ +#ifndef GLDXMLUTILS_H +#define GLDXMLUTILS_H + +#include "GLDXML_Global.h" +#include "GLDString.h" +#include "GLDVariantList.h" +#include "GLDXMLTypes.h" +#include "GLDXMLCore.h" + +//namespace GlodonXMLUtils; +// 该单元所提供的方法,GXMLNode目前通过typedef定义,实际上位Qt的xml解析方法 +// GLDXMLNode为与delphi一致的解析方式,以此类推方法名和类名 + +GLDXMLSHARED_EXPORT GXMLNode firstChildNode(const GXMLNode &node, const QString &tagName = QString()); +GLDXMLSHARED_EXPORT GXMLNode findChildNode(const GXMLNode &node, const GString &nodeName); +GLDXMLSHARED_EXPORT GXMLNode addChild(GXMLNode &node, const GString &nodeName); + +GLDXMLSHARED_EXPORT GString readStrFromXML(const GXMLNode &node, const GString &nodeName, const GString &defVal = ""); +GLDXMLSHARED_EXPORT bool readBoolFromXML(const GXMLNode &node, const GString &nodeName, bool defVal = false); +GLDXMLSHARED_EXPORT int readIntFromXML(const GXMLNode &node, const GString &nodeName, int defVal = 0); +GLDXMLSHARED_EXPORT long long readInt64FromXML(const GXMLNode &node, const GString &nodeName, long long defVal = 0); +GLDXMLSHARED_EXPORT guint64 readUInt64FromXML(const GXMLNode &node, const GString &nodeName, guint64 defVal = 0); +GLDXMLSHARED_EXPORT double readFloatFromXML(const GXMLNode &node, const GString &nodeName, double defVal = 0); + +GLDXMLSHARED_EXPORT GString readStrFromXMLAttr(const GXMLNode &node, const GString &attrName, const GString &defVal = ""); +GLDXMLSHARED_EXPORT bool readBoolFromXMLAttr(const GXMLNode &node, const GString &attrName, bool defVal = false); +GLDXMLSHARED_EXPORT int readIntFromXMLAttr(const GXMLNode &node, const GString &attrName, int defVal = 0); +GLDXMLSHARED_EXPORT gint64 readInt64FromXMLAttr(const GXMLNode &node, const GString &attrName, gint64 defVal = 0); +GLDXMLSHARED_EXPORT guint64 readUInt64FromXMLAttr(const GXMLNode &node, const GString &attrName, guint64 defVal = 0); +GLDXMLSHARED_EXPORT double readFloatFromXMLAttr(const GXMLNode &node, const GString &attrName, double defVal = 0); + +GLDXMLSHARED_EXPORT void writeStrToXML(GXMLNode &node, const GString &nodeName, const GString &value, const GString &defVal = ""); +GLDXMLSHARED_EXPORT void writeBoolToXML(GXMLNode &node, const GString &nodeName, bool value, bool defVal = false); +GLDXMLSHARED_EXPORT void writeIntToXML(GXMLNode &node, const GString &nodeName, int value, int defVal = 0); +GLDXMLSHARED_EXPORT void writeInt64ToXML(GXMLNode &node, const GString &attrNodeName, long long value, long long defVal = 0); +GLDXMLSHARED_EXPORT void writeUInt64ToXML(GXMLNode &node, const GString &attrNodeName, guint64 value, guint64 defVal = 0); +GLDXMLSHARED_EXPORT void writeFloatToXML(GXMLNode &node, const GString &nodeName, double value, double defVal = 0); + +GLDXMLSHARED_EXPORT void writeStrToXMLAttr(GXMLNode &node, const GString &attrName, const GString &value, const GString &defVal = ""); +GLDXMLSHARED_EXPORT void writeBoolToXMLAttr(GXMLNode &node, const GString &attrName, bool value, bool defVal = false); +GLDXMLSHARED_EXPORT void writeIntToXMLAttr(GXMLNode &node, const GString &attrName, int value, int defVal = 0); +GLDXMLSHARED_EXPORT void writeUIntToXMLAttr(GXMLNode &node, const GString &attrName, uint value, uint defVal = 0); +GLDXMLSHARED_EXPORT void writeFloatToXMLAttr(GXMLNode &node, const GString &attrName, double value, double defVal = 0); + +GLDXMLSHARED_EXPORT GLDXMLNode firstChildNode(const GLDXMLNode &node, const QString &tagName = QString()); +GLDXMLSHARED_EXPORT GLDXMLNode findChildNode(const GLDXMLNode &node, const GString &nodeName); +GLDXMLSHARED_EXPORT GLDXMLNode addChild(GLDXMLNode &node, const GString &nodeName); + +GLDXMLSHARED_EXPORT GString readStrFromXML(const GLDXMLNode &node, const GString &nodeName, const GString &defVal = ""); +GLDXMLSHARED_EXPORT bool readBoolFromXML(const GLDXMLNode &node, const GString &nodeName, bool defVal = false); +GLDXMLSHARED_EXPORT int readIntFromXML(const GLDXMLNode &node, const GString &nodeName, int defVal = 0); +GLDXMLSHARED_EXPORT long long readInt64FromXML(const GLDXMLNode &node, const GString &nodeName, long long defVal = 0); +GLDXMLSHARED_EXPORT guint64 readUInt64FromXML(const GLDXMLNode &node, const GString &nodeName, guint64 defVal = 0); +GLDXMLSHARED_EXPORT double readFloatFromXML(const GLDXMLNode &node, const GString &nodeName, double defVal = 0); + +GLDXMLSHARED_EXPORT GString readStrFromXMLAttr(const GLDXMLNode &node, const GString &attrName, const GString &defVal = ""); +GLDXMLSHARED_EXPORT bool readBoolFromXMLAttr(const GLDXMLNode &node, const GString &attrName, bool defVal = false); +GLDXMLSHARED_EXPORT int readIntFromXMLAttr(const GLDXMLNode &node, const GString &attrName, int defVal = 0); +GLDXMLSHARED_EXPORT gint64 readInt64FromXMLAttr(const GLDXMLNode &node, const GString &attrName, gint64 defVal = 0); +GLDXMLSHARED_EXPORT guint64 readUInt64FromXMLAttr(const GLDXMLNode &node, const GString &attrName, guint64 defVal = 0); +GLDXMLSHARED_EXPORT double readFloatFromXMLAttr(const GLDXMLNode &node, const GString &attrName, double defVal = 0); + +GLDXMLSHARED_EXPORT void writeStrToXML(GLDXMLNode &node, const GString &nodeName, const GString &value, const GString &defVal = ""); +GLDXMLSHARED_EXPORT void writeBoolToXML(GLDXMLNode &node, const GString &nodeName, bool value, bool defVal = false); +GLDXMLSHARED_EXPORT void writeIntToXML(GLDXMLNode &node, const GString &nodeName, int value, int defVal = 0); +GLDXMLSHARED_EXPORT void writeInt64ToXML(GLDXMLNode &node, const GString &attrNodeName, long long value, long long defVal = 0); +GLDXMLSHARED_EXPORT void writeUInt64ToXML(GLDXMLNode &node, const GString &attrNodeName, guint64 value, guint64 defVal = 0); +GLDXMLSHARED_EXPORT void writeFloatToXML(GLDXMLNode &node, const GString &nodeName, double value, double defVal = 0); + +GLDXMLSHARED_EXPORT void writeStrToXMLAttr(GLDXMLNode &node, const GString &attrName, const GString &value, const GString &defVal = ""); +GLDXMLSHARED_EXPORT void writeBoolToXMLAttr(GLDXMLNode &node, const GString &attrName, bool value, bool defVal = false); +GLDXMLSHARED_EXPORT void writeIntToXMLAttr(GLDXMLNode &node, const GString &attrName, int value, int defVal = 0); +GLDXMLSHARED_EXPORT void writeUIntToXMLAttr(GLDXMLNode &node, const GString &attrName, uint value, uint defVal = 0); +GLDXMLSHARED_EXPORT void writeFloatToXMLAttr(GLDXMLNode &node, const GString &attrName, double value, double defVal = 0); + +GLDXMLSHARED_EXPORT GXMLDocument createXMLDocument(bool aIncludeHeader = true, bool autoIndent = true); +GLDXMLSHARED_EXPORT GXMLDocument loadXMLDocument(const GString &fileName); +GLDXMLSHARED_EXPORT GXMLDocument loadXMLDocument(GStream *stream); +GLDXMLSHARED_EXPORT void saveXMLDocument(GXMLDocument &doc, const GString &fileName); +GLDXMLSHARED_EXPORT void saveXMLDocument(GXMLDocument &doc, GStream *stream); + +GLDXMLSHARED_EXPORT bool isXMLStream(GStream *stream); + +GLDXMLSHARED_EXPORT void clearNodes(GXMLNode &node); + +GLDXMLSHARED_EXPORT int posXMLString(GString strSub,GString strValue,int nStart = 0); +GLDXMLSHARED_EXPORT void xmlDocError(const GString &msg); +GLDXMLSHARED_EXPORT void xmlDocError(const GString &msg, const GVariantList &variantList); + +GLDXMLSHARED_EXPORT GLDXMLDocument createGLDXMLDocument(bool aIncludeHeader = true, bool autoIndent = true); +GLDXMLSHARED_EXPORT GLDXMLDocument loadGLDXMLDocument(const GString &fileName); +GLDXMLSHARED_EXPORT GLDXMLDocument loadGLDXMLDocument(GStream *stream); +GLDXMLSHARED_EXPORT void saveGLDXMLDocument(GLDXMLDocument &doc, const GString &fileName); +GLDXMLSHARED_EXPORT void saveGLDXMLDocument(GLDXMLDocument &doc, GStream *stream); + +#endif // GLDXMLUTILS_H + diff --git a/GCR/trunk/Glodon/include/GLD/GLDXMLWriter.h b/GCR/trunk/Glodon/include/GLD/GLDXMLWriter.h new file mode 100644 index 00000000..442d48e2 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDXMLWriter.h @@ -0,0 +1,88 @@ +/*************************************************************************/ +/* */ +/* 广联达 XML 直接编写对象实现单元 */ +/* */ +/* 设计:Linc 2012.06.05 */ +/* 备注: */ +/* 审核: */ +/* */ +/* copyright(c) 1994-2012 GrandSoft Corporation */ +/* */ +/*************************************************************************/ +#ifndef GLDXMLWRITER_H +#define GLDXMLWRITER_H + +#include "GLDString.h" +#include "GLDVariant.h" +#include "GLDIODevice.h" +#include "GLDVector.h" +#include "GLDXML_Global.h" + +class CGrandXMLNodeStack; +class GLDXMLWriter; + +enum CXMLEncode +{ + xeUtf8 +}; + +class CGrandXMLNodeStackPrivate; +class GLDXMLSHARED_EXPORT CGrandXMLNodeStack +{ +public: + CGrandXMLNodeStack(); + virtual ~CGrandXMLNodeStack(); + int count(); + bool isEmptyElement() const; + void setIsEmptyElement(const bool value); + + GLatin1String push(const GLatin1String &s); + GLatin1String pop(); + GLatin1String peek(); +private: + CGrandXMLNodeStackPrivate * const d_ptr; + Q_DECLARE_PRIVATE(CGrandXMLNodeStack); +}; + +class GLDXMLWriterPrivate; +class GLDXMLSHARED_EXPORT GLDXMLWriter +{ +public: + GLDXMLWriter(GStream *stream, bool autoIndent = false); + virtual ~GLDXMLWriter(); + void createProcessingInstruction(const GString &version = "", const GString &Encoding = "", + const GString &standalone = ""); + void beginNode(const GLatin1String &name, GLDVector *attNames, GLDVector *attValues); + void beginNode(const GLatin1String &name); + void endNode(bool indent = true); + + void addAttr(const GString &name, bool value); + void addAttr(const GString &name, double value); + void addAttr(const GString &name, long long value); + void addAttr(const GString &name, unsigned long long value); + void addAttr(const GString &name, int value); + void addAttr(const GString &name, GVariant *value); + void addAttr(const GString &name, const GString &value); + + void createFullNode(const GLatin1String &name, const GString &text, GLDVector *attNames, + GLDVector *attValues); + void createFullNode(const GLatin1String &name, GLDVector *attNames, GLDVector *attValues); + void createFullNode(const GLatin1String &name, const GString &text = ""); + + GStream *stream(); + CXMLEncode encoding(); + void setIsEmptyElement(bool value); +private: + void addAttrVarRec(const GString &name, const GVariant &v); + void write(const GString &s); + void write(const GLatin1String &s); + void writeLn(const GString &s); + void writeLn(const GLatin1String &s); + void writeIndent(int offset); + CXMLEncode getEncoding(const GString &encode); +private: + GLDXMLWriterPrivate * const d_ptr; + Q_DECLARE_PRIVATE(GLDXMLWriter) +}; + +#endif // GLDXMLWRITER_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDXML_Global.h b/GCR/trunk/Glodon/include/GLD/GLDXML_Global.h new file mode 100644 index 00000000..8b2086ac --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDXML_Global.h @@ -0,0 +1,16 @@ +#ifndef GLDXML_GLOBAL_H +#define GLDXML_GLOBAL_H + +#include + +#ifndef GLD_FULLSOURCE + #if defined(GLDXML_LIBRARY) + # define GLDXMLSHARED_EXPORT Q_DECL_EXPORT + #else + # define GLDXMLSHARED_EXPORT Q_DECL_IMPORT + #endif +#else + #define GLDXMLSHARED_EXPORT +#endif + +#endif // GLDXML_GLOBAL_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDZipEnc.h b/GCR/trunk/Glodon/include/GLD/GLDZipEnc.h new file mode 100644 index 00000000..1047ad5d --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDZipEnc.h @@ -0,0 +1,91 @@ +#ifndef GLDZIPENC_H +#define GLDZIPENC_H + +#include "GLDTypes.h" +#include "GLDZip_Global.h" +#include "GLDStream.h" + +class GLDZIPSHARED_EXPORT GLDZipDecryptEngine +{ +public: + GLDZipDecryptEngine(); + virtual ~GLDZipDecryptEngine(); +public: + unsigned char decode(unsigned char ch); + void decodeBuffer(char *buffer, int count); + bool verifyHeader(const unsigned char header[12], const GString &passPhrase, long checkValue); +protected: + void zdeInitState(const GString &passPhras); +private: + bool m_ready; + long m_state[3]; +}; + +class GLDZIPSHARED_EXPORT GLDZipDecryptStream : public GStream +{ +public: + GLDZipDecryptStream(GStream *stream, long checkValue, const GString passPhrase); + virtual ~GLDZipDecryptStream(); +public: + bool isValid(); + long seek(long offset, GSeekOrigin origin); + + gint64 size() const; + gint64 pos() const; + bool seek(gint64 off); +protected: + gint64 readData(char *data, gint64 maxlen); + gint64 writeData(const char *data, gint64 len); +private: + long m_checkValue; + GLDZipDecryptEngine *m_Engine; + GString m_passPhrase; + bool m_Ready; + GStream *m_stream; +}; + +class GLDZIPSHARED_EXPORT GLDZipEncryptEngine +{ +public: + GLDZipEncryptEngine(); + virtual ~GLDZipEncryptEngine(); +public: + unsigned char encode(unsigned char ch); + void encodeBuffer(char *buffer, int count); + void createheader(unsigned char *header, const GString passphrase, long checkValue); +protected: + void zeeInitState(const GString passPhrase); +private: + bool m_ready; + long m_state[3]; +}; + +class GLDZIPSHARED_EXPORT GLDZipEncryptStream : public GStream +{ +public: + GLDZipEncryptStream(GStream *stream, long checkValue, const GString passPhrase); + virtual ~GLDZipEncryptStream(); +public: + long seek(long offset, GSeekOrigin origin); + + gint64 size() const; + gint64 pos() const; + bool seek(gint64 off); +protected: + gint64 readData(char *data, gint64 maxlen); + gint64 writeData(const char *data, gint64 len); +private: + char* m_buffer; + int m_bufSize; + GLDZipEncryptEngine *m_Engine; + GStream *m_stream; +}; + +GLDZIPSHARED_EXPORT unsigned long zipCRC32(GByteArray &data); +//重载接口 +GLDZIPSHARED_EXPORT unsigned long zipCRC32(GStream *stream); + +GLDZIPSHARED_EXPORT unsigned long zipUpdateCRC32(unsigned char curByte, unsigned long curCrc); +//void zipUpdateKeys(unsigned short c, unsigned long &keys[3]); + +#endif // GLDZIPENC_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDZipFile.h b/GCR/trunk/Glodon/include/GLD/GLDZipFile.h new file mode 100644 index 00000000..a9e6ceb0 --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDZipFile.h @@ -0,0 +1,242 @@ +#ifndef GLDZIPFILE_H +#define GLDZIPFILE_H + +#include "GLDTypes.h" +#include "GLDUnknwn.h" +#include "GLDComptr.h" +#include "GLDStream.h" +#include "GLDZip_Global.h" + +enum GLDZipCompressionLevel +{ + ctNone, + ctFastest, + ctDefault, + ctMax, + ctUnknown +}; + +interface IGLDZipFile; +interface IGLDZipFileEntry; +interface IGLDZipGetPassWordEvent; +class GLDZipFile; +class GLDZipFileEntry; +class GLDZipGetPassWordEvent; +class GStreamStrategy; + +DEFINE_IID(IGLDZipGetPassWordEvent, "{8E879058-AD61-44CE-92C6-2DCBAEB301D5}"); +DECLARE_INTERFACE_(IGLDZipGetPassWordEvent, IUnknown) +{ + GLDMETHOD(void, getPasswordEvent)(IGLDZipFileEntry *entry, GString *password); +}; + +DEFINE_IID(IGLDZipFileEntry, "{F96F15DA-C9CE-4466-B64F-06DE79642F30}"); +DECLARE_INTERFACE_(IGLDZipFileEntry, IUnknown) +{ + GLDMETHOD(int, attriButes)() PURE; + GLDMETHOD(unsigned long, compressedSize)() PURE; + GLDMETHOD(unsigned long, crc32)() PURE; + + //返回值存在内存开辟失败问题 +// GLDMETHOD(GByteArray, data)() PURE; + GLDMETHOD(GStream *, data)() PURE; + + GLDMETHOD(double, dateTime)() PURE; + GLDMETHOD(bool, isEncrypted)() PURE; + GLDMETHOD(GString, name)() PURE; + GLDMETHOD(IGLDZipFile *, owner)() PURE; + GLDMETHOD(unsigned long, uncompressedSize)() PURE; + GLDMETHOD(void, setAttriButes)(const int value) PURE; + + //GByteArray存在内存开辟失败问题,建议使用GStream + GLDMETHOD(void, setData)(GByteArray value) PURE; + GLDMETHOD(void, setData)(GStream *value) PURE; + + GLDMETHOD(void, setDateTime)(const double value) PURE; + + GLDMETHOD(void, loadFromFile)(const GString file) PURE; + GLDMETHOD(void, saveToFile)(const GString file) PURE; + + GLDMETHOD(void, loadFromStream)(GStream *stream) PURE; + GLDMETHOD(void, saveToStream)(GStream *stream) PURE; + + GLDMETHOD(void, compressFromFile)(const GString file) PURE; + GLDMETHOD(void, decompressToFile)(const GString file) PURE; +}; + +DEFINE_IID(IGLDZipFile, "{0C5D3108-B7B9-4FFE-A233-AA19E6A5FCD0}"); +DECLARE_INTERFACE_(IGLDZipFile, IUnknown) +{ + GLDMETHOD(int, count)() PURE; + GLDMETHOD(GByteArray, customFileHeader)() PURE; + GLDMETHOD(GString, fileComment)() PURE; + GLDMETHOD(IGLDZipFileEntry *, items)(int index) PURE; + GLDMETHOD(GLDZipCompressionLevel, level)() PURE; + GLDMETHOD(GString, password)() PURE; + + GLDMETHOD(void, setCustomFileHeader)(GByteArray value) PURE; + GLDMETHOD(void, setFileComment)(const GString value) PURE; + GLDMETHOD(void, setLevel)(const GLDZipCompressionLevel value) PURE; + GLDMETHOD(void, setPassword)(const GString value) PURE; + + GLDMETHOD(IGLDZipFileEntry *, add)(const GString name) PURE; + GLDMETHOD(int, addFiles)(const GString folder, const GString base = "", + bool recursion = true, const GString fileMask = "", int searchAttr = 0) PURE; + GLDMETHOD(IGLDZipFileEntry *, addFromBuffer)(const GString &name, void *buffer, int count) PURE; + GLDMETHOD(IGLDZipFileEntry *, addFromFile)(const GString &name, const GString &file) PURE; + GLDMETHOD(IGLDZipFileEntry *, addFromStream)(const GString &name, GStream *stream) PURE; + + GLDMETHOD(int, indexOf)(const GString name) PURE; + + GLDMETHOD(void, clear)() PURE; + GLDMETHOD(void, deleteItem)(int index) PURE; + + GLDMETHOD(void, extractFiles)(const GString folder, const GString nameMask = "") PURE; + GLDMETHOD(void, extractToBuffer)(const GString name, int *buffer, int count) PURE; + GLDMETHOD(void, extractToStream)(const GString &name, GStream *stream) PURE; + GLDMETHOD(void, extractToString)(const GString name, GByteArray *text) PURE; + + GLDMETHOD(void, loadFromFile)(const GString file) PURE; + GLDMETHOD(void, saveToFile)(const GString file) PURE; + + GLDMETHOD(void, loadFromStream)(GStream *stream) PURE; + GLDMETHOD(void, saveToStream)(GStream *stream) PURE; + + GLDMETHOD(IGLDZipGetPassWordEvent*, getOnGetPassword)() PURE; + GLDMETHOD(void, setOnGetPassword)(IGLDZipGetPassWordEvent *value) PURE; +}; + +class GLDZIPSHARED_EXPORT GLDZipGetPassWordEvent : public GComPtr +{ +public: + inline GLDZipGetPassWordEvent() : GComPtr () {} + inline GLDZipGetPassWordEvent(IGLDZipGetPassWordEvent *lp) : GComPtr(lp) {} + inline GLDZipGetPassWordEvent(IGLDZipGetPassWordEvent *lp, bool /*dummy*/) : GComPtr(lp, false){} + template + inline GLDZipGetPassWordEvent(const GComPtr &lp) : GComPtr(lp){} + void getPasswordEvent(GLDZipFileEntry entry, GString *password); +}; + +class GLDZIPSHARED_EXPORT GLDZipFileEntry : public GComPtr +{ +public: + inline GLDZipFileEntry() : GComPtr () {} + inline GLDZipFileEntry(IGLDZipFileEntry *lp) : GComPtr(lp) {} + inline GLDZipFileEntry(IGLDZipFileEntry *lp, bool /*dummy*/) : GComPtr(lp, false){} + + template + inline GLDZipFileEntry(const GComPtr &lp) : GComPtr(lp){} + + int attriButes(); + unsigned long compressedSize(); + unsigned long crc32(); + + //返回值存在内存开辟失败问题 + //GByteArray data(); + GStream *data(); + + double dateTime(); + bool isEncrypted(); + GString name(); + GLDZipFile owner(); + unsigned long uncompressedSize(); + void setAttriButes(const int value); + + //GByteArray存在内存开辟失败问题,建议使用GStream + void setData(GByteArray &value); + void setData(GStream *value); + + void setDateTime(const double value); + void loadFromFile(const GString &file); + void saveToFile(const GString &file); + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + void compressFromFile(const GString &file); + void decompressToFile(const GString &file); +}; + +class GLDZIPSHARED_EXPORT GLDZipFile : public GComPtr +{ +public: + inline GLDZipFile() : GComPtr () {} + inline GLDZipFile(IGLDZipFile *lp) : GComPtr(lp) {} + inline GLDZipFile(IGLDZipFile *lp, bool /*dummy*/) : GComPtr(lp, false){} + + template + inline GLDZipFile(const GComPtr &lp) : GComPtr(lp){} + + int count(); + GByteArray customFileHeader(); + GString fileComment(); + GLDZipFileEntry items(int index); + GLDZipCompressionLevel level(); + GString password(); + + void setCustomFileHeader(const GByteArray &value); + void setFileComment(const GString &value); + void setLevel(const GLDZipCompressionLevel &value); + void setPassword(const GString &value); + GLDZipFileEntry add(const GString &name); + + int addFiles(const GString &folder, const GString &base = "", + const bool recursion = true, const GString &fileMask = "", const int searchAttr = 0); + GLDZipFileEntry addFromBuffer(const GString &name, void *buffer, const int count); + GLDZipFileEntry addFromFile(const GString &name, const GString &file); + GLDZipFileEntry addFromStream(const GString &name, GStream *stream); + + int indexOf(const GString &name); + void clear(); + void deleteItem(const int index); + + void extractFiles(const GString &folder, const GString &nameMask = ""); + void extractToBuffer(const GString &name, int *buffer, const int count); + void extractToStream(const GString &name, GStream *stream); + void extractToString(const GString &name, GByteArray *text); + + void loadFromFile(const GString &file); + void saveToFile(const GString &file); + + void loadFromStream(GStream *stream); + void saveToStream(GStream *stream); + + GLDZipGetPassWordEvent getOnGetPassword(); + void setOnGetPassword(GLDZipGetPassWordEvent &value); +}; + +GLDZIPSHARED_EXPORT void zipFileError(const GString Msg); +GLDZIPSHARED_EXPORT IGLDZipFile *createZipFile(const GString &password = ""); +GLDZIPSHARED_EXPORT GLDZipFile createZipFileSPtr(const GString &password = ""); + +GLDZIPSHARED_EXPORT IGLDZipFile *loadZipFile(const GString &file, const GString &password = ""); +GLDZIPSHARED_EXPORT IGLDZipFile *loadZipFile(GStream *stream, const GString &password = ""); +GLDZIPSHARED_EXPORT GLDZipFile loadZipFileSPtr(const GString &file, const GString &password = ""); +GLDZIPSHARED_EXPORT GLDZipFile loadZipFileSPtr(GStream *stream, const GString &password = ""); + +GLDZIPSHARED_EXPORT GString fileNameToZipName(const GString &name); +GLDZIPSHARED_EXPORT GString zipNameToFileName(const GString &name); + +GLDZIPSHARED_EXPORT bool isZipFile(const GString &file); +GLDZIPSHARED_EXPORT bool isZipStream(GStream *stream); + +GLDZIPSHARED_EXPORT bool isEncryptedZipFile(const GString &file); +GLDZIPSHARED_EXPORT bool isEncryptedZipStream(GStream *stream); + +//返回值存在内存开辟失败问题 +//GByteArray zipText(const GByteArray &s); +//GByteArray unzipText(const GByteArray &s); + +GLDZIPSHARED_EXPORT GStream *zipText(const GByteArray &s); +GLDZIPSHARED_EXPORT GStream *unzipText(const GByteArray &s); + +GLDZIPSHARED_EXPORT bool zipStream(GStream *srcStream, GStream *desStream, const GString &password = ""); +GLDZIPSHARED_EXPORT bool zipStream(GStream *stream, const GString &password); + +GLDZIPSHARED_EXPORT bool unZipStream(GStream *srcStream, GStream *desStream, const GString &password = ""); +GLDZIPSHARED_EXPORT bool unZipStream(GStream *stream, const GString &password = ""); + +GLDZIPSHARED_EXPORT int compressZipFiles(const GString &file, const GString &folder, const GString &nameMask = ""); +GLDZIPSHARED_EXPORT int extractZipFiles(const GString &file, const GString &folder, const GString &nameMask = ""); +GLDZIPSHARED_EXPORT IGLDZipFileEntry* createZipFileEntry(IGLDZipFile *zipFile, const GString &zipFileName); +GLDZIPSHARED_EXPORT void zipFileError(const GString Msg); + +#endif // GLDZIPFILE_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDZip_Global.h b/GCR/trunk/Glodon/include/GLD/GLDZip_Global.h new file mode 100644 index 00000000..060b40bd --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDZip_Global.h @@ -0,0 +1,16 @@ +#ifndef GLDDZIP_GLOBAL_H +#define GLDDZIP_GLOBAL_H + +#include + +#ifndef GLD_FULLSOURCE + #if defined(GLDZIP_LIBRARY) + # define GLDZIPSHARED_EXPORT Q_DECL_EXPORT + #else + # define GLDZIPSHARED_EXPORT Q_DECL_IMPORT + #endif +#else + #define GLDZIPSHARED_EXPORT +#endif + +#endif // GLDDZIP_GLOBAL_H diff --git a/GCR/trunk/Glodon/include/GLD/GLDZlib.h b/GCR/trunk/Glodon/include/GLD/GLDZlib.h new file mode 100644 index 00000000..d59cebbe --- /dev/null +++ b/GCR/trunk/Glodon/include/GLD/GLDZlib.h @@ -0,0 +1,83 @@ +#ifndef GLDZLIB_H +#define GLDZLIB_H + +#include "GLDTypes.h" +#include "GLDStream.h" +#include "GLDZip_Global.h" + +#define FRAGMENT_LENGTH_ZIP 0x100000 //16M, 当文件大于16M时,创建文件流缓存,否则是内存流 +#define FRAGMENT_LENGTH_7Z 0x10000 //7z压缩解压缩的分片大小 +#define ZLIB_HEADER_LENGTH 2 //zlib头长度 + +//////////////////////////////////////////////////////////////////////////////// +//设计:创建一个策略类,根据用户传入参数,用工厂方法动态创建对象,屏蔽差异,用户不感知,方便扩展 +//功能:根据用户传入的参数(文件名/文件大小),创建文件流(当文件大小大于16M时)或者内存流 +//////////////////////////////////////////////////////////////////////////////// +class GStreamStrategy +{ +public: + void setStreamFragmentSize(gint64 nFragmentSize) + { + m_nFragMentSize = nFragmentSize; + } + gint64 streamFragmentSize() + { + return m_nFragMentSize; + } + GStream * stream() + { + return m_stream; + } + static void copyStreamByFragment(GStream *outStream, GStream *inStream, uint nFragmentLength, gint64 nCopySize); + void createFileInDir(const GString &strFileName); + +private: + GStreamStrategy(const GString &strFileName, const GString &strDirName, const GString &strSuffix = "", bool bUseFileStreamFlag = true, gint64 nFragSize = 0x1000000);//16M + GStreamStrategy(const GString &strFileName, gint64 streamSize, const GString &strSuffix = "", bool bUseFileStreamFlag = true, gint64 nFragSize = 0x1000000); + +private: + GStream *m_stream ; // 流指针 + gint64 m_nFragMentSize; //分片大小,用户可以指定,超过此大小的流需要创建文件流,否则创建块内存 + friend class CGLDZlib; + friend class CGLDZipFileEntry; +}; + +class GLDZIPSHARED_EXPORT CGLDZlib +{ +public: + CGLDZlib(); + virtual ~CGLDZlib(); + static bool compress(GStream *inStream, GStream *outStream); + static GStream* compress(GStream *inStream, bool bUseFileStreamFlag = true); + static bool unCompress(GStream *inStream, GStream *outStream, GByteArray zlibHeader = ""); + static GStream* unCompress(GStream *inStream, bool bUseFileStreamFlag = true); + static int newCompress(GStream *inStream, GStream *outStream, bool hasZlibHeaderFlag = true); +}; + +#ifdef WIN32 +class GLDZIPSHARED_EXPORT CGLD7Zip +{ +public: + CGLD7Zip() {} + virtual ~CGLD7Zip() {} + // 需外部创建outStream + static GStream* compress(GStream *inStream); + static GStream* unCompress(GStream *inStream, int unCompressedSize = 0); +private: + static bool compress(GStream *instream, GStream *outStream); + static bool unCompress(GStream *instream, GStream *outStream, int unCompressedSize = 0); + friend class CGLDAutoCompress; +}; +#endif + +class GLDZIPSHARED_EXPORT CGLDAutoCompress +{ +public: + CGLDAutoCompress() {} + virtual ~CGLDAutoCompress() {} + // 需外部创建outStream + static GStream* compress(GStream *inStream); + static GStream* unCompress(GStream *inStream); +}; + +#endif // GLDZLIB_H diff --git a/GCR/trunk/Glodon/lib/Debug/ReadMe.txt b/GCR/trunk/Glodon/lib/Debug/ReadMe.txt new file mode 100644 index 00000000..560651dd --- /dev/null +++ b/GCR/trunk/Glodon/lib/Debug/ReadMe.txt @@ -0,0 +1 @@ +本目录下存放的是Unicode编码方式的Debug版本Lib文件 \ No newline at end of file diff --git a/GCR/trunk/Glodon/lib/Debug/X64/MTd/ReadMe.txt b/GCR/trunk/Glodon/lib/Debug/X64/MTd/ReadMe.txt new file mode 100644 index 00000000..f8ebdefe --- /dev/null +++ b/GCR/trunk/Glodon/lib/Debug/X64/MTd/ReadMe.txt @@ -0,0 +1,3 @@ +本目录下存放的是Unicode编码方式的Debug版本Lib文件 +本目录默认存放运行库为:MTd(多线程调试) +64位 \ No newline at end of file diff --git a/GCR/trunk/Glodon/lib/Debug/X64/ReadMe.txt b/GCR/trunk/Glodon/lib/Debug/X64/ReadMe.txt new file mode 100644 index 00000000..6ea6e6b1 --- /dev/null +++ b/GCR/trunk/Glodon/lib/Debug/X64/ReadMe.txt @@ -0,0 +1,3 @@ +本目录下存放的是Unicode编码方式的Debug版本Lib文件 +本目录默认存放运行库为:MDd(多线程调试DLL) +64位 \ No newline at end of file diff --git a/GCR/trunk/Glodon/lib/Debug/X86/MTd/ReadMe.txt b/GCR/trunk/Glodon/lib/Debug/X86/MTd/ReadMe.txt new file mode 100644 index 00000000..cef1a6eb --- /dev/null +++ b/GCR/trunk/Glodon/lib/Debug/X86/MTd/ReadMe.txt @@ -0,0 +1,3 @@ +本目录下存放的是Unicode编码方式的Debug版本Lib文件 +本目录下存放运行库为:MTd(多线程调试) +32位 \ No newline at end of file diff --git a/GCR/trunk/Glodon/lib/Debug/X86/ReadMe.txt b/GCR/trunk/Glodon/lib/Debug/X86/ReadMe.txt new file mode 100644 index 00000000..e5188280 --- /dev/null +++ b/GCR/trunk/Glodon/lib/Debug/X86/ReadMe.txt @@ -0,0 +1,3 @@ +本目录下存放的是Unicode编码方式的Debug版本Lib文件 +本目录默认存放运行库为:MDd(多线程调试DLL) +32位 \ No newline at end of file diff --git a/GCR/trunk/Glodon/lib/Release/ReadMe.txt b/GCR/trunk/Glodon/lib/Release/ReadMe.txt new file mode 100644 index 00000000..c8feeabc --- /dev/null +++ b/GCR/trunk/Glodon/lib/Release/ReadMe.txt @@ -0,0 +1 @@ +本目录下存放的是Unicode编码方式的Release版本Lib文件 \ No newline at end of file diff --git a/GCR/trunk/Glodon/lib/Release/X64/MT/ReadMe.txt b/GCR/trunk/Glodon/lib/Release/X64/MT/ReadMe.txt new file mode 100644 index 00000000..ca9193dd --- /dev/null +++ b/GCR/trunk/Glodon/lib/Release/X64/MT/ReadMe.txt @@ -0,0 +1,3 @@ +本目录下存放的是Unicode编码方式的Release版本Lib文件 +本目录默认存放运行库为:MT(多线程) +64位 \ No newline at end of file diff --git a/GCR/trunk/Glodon/lib/Release/X64/ReadMe.txt b/GCR/trunk/Glodon/lib/Release/X64/ReadMe.txt new file mode 100644 index 00000000..d3661c8b --- /dev/null +++ b/GCR/trunk/Glodon/lib/Release/X64/ReadMe.txt @@ -0,0 +1,3 @@ +本目录下存放的是Unicode编码方式的Release版本Lib文件 +本目录默认存放运行库为:MD(多线程DLL) +64位 \ No newline at end of file diff --git a/GCR/trunk/Glodon/lib/Release/X86/MT/ReadMe.txt b/GCR/trunk/Glodon/lib/Release/X86/MT/ReadMe.txt new file mode 100644 index 00000000..c7a9a273 --- /dev/null +++ b/GCR/trunk/Glodon/lib/Release/X86/MT/ReadMe.txt @@ -0,0 +1,3 @@ +本目录下存放的是Unicode编码方式的Release版本Lib文件 +本目录下存放运行库为:MT(多线程) +32位 \ No newline at end of file diff --git a/GCR/trunk/Glodon/lib/Release/X86/ReadMe.txt b/GCR/trunk/Glodon/lib/Release/X86/ReadMe.txt new file mode 100644 index 00000000..1e86ac93 --- /dev/null +++ b/GCR/trunk/Glodon/lib/Release/X86/ReadMe.txt @@ -0,0 +1,3 @@ +本目录下存放的是Unicode编码方式的Release版本Lib文件 +本目录默认存放运行库为:MD(多线程DLL) +32位 \ No newline at end of file diff --git a/GCR/trunk/Glodon/shared/Cryptopp.pri b/GCR/trunk/Glodon/shared/Cryptopp.pri new file mode 100644 index 00000000..5512bc04 --- /dev/null +++ b/GCR/trunk/Glodon/shared/Cryptopp.pri @@ -0,0 +1,21 @@ + +GLDRS = $$quote($$(GLDRS)) + +INCLUDEPATH += $$GLDRS/ThirdPart/cryptopp/include \ + $$GLDRS/ThirdPart/cryptopp/Addin + +CONFIG(debug, debug|release){ + contains(QMAKE_HOST.arch, x86_64) { + LIBS += $$GLDRS/ThirdPart/cryptopp/lib/Debug/X64/cryptoppd.lib + } else { + LIBS += $$GLDRS/ThirdPart/cryptopp/lib/Debug/X86/cryptoppd.lib + } +} + +CONFIG(release, debug|release){ + contains(QMAKE_HOST.arch, x86_64) { + LIBS += $$GLDRS/ThirdPart/cryptopp/lib/Release/X64/cryptopp.lib + } else { + LIBS += $$GLDRS/ThirdPart/cryptopp/lib/Release/X86/cryptopp.lib + } +} diff --git a/GCR/trunk/Glodon/shared/GHS.pri b/GCR/trunk/Glodon/shared/GHS.pri new file mode 100644 index 00000000..4a9a4900 --- /dev/null +++ b/GCR/trunk/Glodon/shared/GHS.pri @@ -0,0 +1,27 @@ + +GLDRS = $$quote($$(GLDRS)) +Glodon= $$(Glodon) + +isEmpty(Glodon){ + Glodon = $$GLDRS/Glodon +} + +INCLUDEPATH += \ + $$Glodon/include/GHS + +CONFIG(debug, debug|release){ + LIBS += -L$$Glodon/lib/Debug/X86 \ + -lGLDd -lGHSd + LIBS += -L$(GLDRS)/ThirdPart/curl/build/lib/Debug \ + -llibcurl_imp +} + +CONFIG(release, debug|release){ + LIBS += -L$$Glodon/lib/Release/X86 \ + -lGLD -lGHS + LIBS += -L$(GLDRS)/ThirdPart/curl/build/lib/Release \ + -llibcurl_imp +} + +# vista and above only +LIBS += -lWs2_32 diff --git a/GCR/trunk/Glodon/shared/GLD.pri b/GCR/trunk/Glodon/shared/GLD.pri new file mode 100644 index 00000000..6cc72079 --- /dev/null +++ b/GCR/trunk/Glodon/shared/GLD.pri @@ -0,0 +1,53 @@ +#对于需要公共资源所有模块的大项目,可以直接使用引用GLD.pri +#如果是用到GLD部分功能,推荐直接引用单独的子模块即可,不必要include所有模块。 + +GLDRS = $$quote($$(GLDRS)) +Glodon= $$(Glodon) + +isEmpty(Glodon){ + Glodon = $$GLDRS/Glodon +} + +DEFINES += GDP_QT + +INCLUDEPATH += $$Glodon/include/GLD + +include($(GLDRS)/Glodon/shared/GLDCommon.pri) +include($(GLDRS)/Glodon/shared/GLDZip.pri) +include($(GLDRS)/Glodon/shared/GLDCrypt.pri) +include($(GLDRS)/Glodon/shared/GLDTableView.pri) +include($(GLDRS)/Glodon/shared/GLDWidget.pri) +include($(GLDRS)/Glodon/shared/GLDXML.pri) + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003 \ + |win32-msvc2005|win32-msvc2008|win32-msvc2010 \ + |win32-msvc2012|win32-msvc2013 { + + include($(GLDRS)/Glodon/shared/ZLIB.pri) + include($$Glodon/shared/RichText.pri) + include($$Glodon/shared/QuaZip.pri) + include($(GLDRS)/ThirdPart/lzma/C/lzma.pri) + include($(GLDRS)/Glodon/shared/Cryptopp.pri) + include($(GLDRS)/Glodon/shared/GLDXLS.pri) +} +else { + include($$Glodon/shared/RichText.pri) + include($(GLDRS)/ThirdPart/zlib/zlib.pri) +} + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003 \ + |win32-msvc2005|win32-msvc2008|win32-msvc2010 \ + |win32-msvc2012|win32-msvc2013 { + + LIBS += -loleaut32 -lole32 -lshell32 -lUser32 + + greaterThan(QT_MAJOR_VERSION, 4){ + greaterThan(QT_MINOR_VERSION, 1){ +# QT += winextras + } + } +} + +win32-g++ { + LIBS += -loleaut32 -lole32 -luuid -lnetapi32 +} diff --git a/GCR/trunk/Glodon/shared/GLDCommon.pri b/GCR/trunk/Glodon/shared/GLDCommon.pri new file mode 100644 index 00000000..d0de8a7e --- /dev/null +++ b/GCR/trunk/Glodon/shared/GLDCommon.pri @@ -0,0 +1,53 @@ + +GLDRS = $$quote($$(GLDRS)) +Glodon= $$(Glodon) + +isEmpty(Glodon){ + Glodon = $$GLDRS\Glodon +} + +DEFINES += GDP_QT + +INCLUDEPATH += $$Glodon/include/GLD + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003|win32-msvc2005|win32-msvc2008|win32-msvc2010|win32-msvc2012|win32-msvc2013 { +} + +CONFIG(debug, debug|release) { + + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$Glodon/bin/Debug/X64 + } else { + LIBS += -L$$Glodon/bin/Debug/X86 + } + + win32:LIBS += -lGLDCommond + unix:LIBS += -lGLDCommon_debug +} + +CONFIG(release, debug|release) { + + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$Glodon/bin/Release/X64 + } else { + LIBS += -L$$Glodon/bin/Release/X86 + } + + LIBS += -lGLDCommon + +} + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003|win32-msvc2005|win32-msvc2008|win32-msvc2010|win32-msvc2012|win32-msvc2013 { + + LIBS += -loleaut32 -lole32 -lshell32 + + greaterThan(QT_MAJOR_VERSION, 4){ + greaterThan(QT_MINOR_VERSION, 1){ +# QT += winextras + } + } +} + +win32-g++ { + LIBS += -loleaut32 -lole32 -luuid -lnetapi32 +} diff --git a/GCR/trunk/Glodon/shared/GLDCrypt.pri b/GCR/trunk/Glodon/shared/GLDCrypt.pri new file mode 100644 index 00000000..a2e2ae3a --- /dev/null +++ b/GCR/trunk/Glodon/shared/GLDCrypt.pri @@ -0,0 +1,54 @@ + +GLDRS = $$quote($$(GLDRS)) +Glodon= $$(Glodon) + +isEmpty(Glodon){ + Glodon = $$GLDRS\Glodon +} + +DEFINES += GDP_QT + +INCLUDEPATH += $$Glodon/include/GLD + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003|win32-msvc2005|win32-msvc2008|win32-msvc2010|win32-msvc2012|win32-msvc2013 { + +} + +CONFIG(debug, debug|release) { + + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$Glodon/bin/Debug/X64 + } else { + LIBS += -L$$Glodon/bin/Debug/X86 + } + + win32:LIBS += -lGLDCryptd + unix:LIBS += -lGLDCrypt_debug + +} + +CONFIG(release, debug|release) { + + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$Glodon/bin/Release/X64 + } else { + LIBS += -L$$Glodon/bin/Release/X86 + } + + LIBS += -lGLDCrypt +} + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003|win32-msvc2005|win32-msvc2008|win32-msvc2010|win32-msvc2012|win32-msvc2013 { + + LIBS += -loleaut32 -lole32 -lshell32 + + greaterThan(QT_MAJOR_VERSION, 4){ + greaterThan(QT_MINOR_VERSION, 1){ +# QT += winextras + } + } +} + +win32-g++ { + LIBS += -loleaut32 -lole32 -luuid -lnetapi32 +} diff --git a/GCR/trunk/Glodon/shared/GLDMask.pri b/GCR/trunk/Glodon/shared/GLDMask.pri new file mode 100644 index 00000000..1162116e --- /dev/null +++ b/GCR/trunk/Glodon/shared/GLDMask.pri @@ -0,0 +1,53 @@ + +GLDRS = $$quote($$(GLDRS)) +Glodon= $$(Glodon) + +isEmpty(Glodon){ + Glodon = $$GLDRS\Glodon +} + +DEFINES += GDP_QT + +INCLUDEPATH += $$Glodon/include/GLD + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003|win32-msvc2005|win32-msvc2008|win32-msvc2010|win32-msvc2012|win32-msvc2013 { +} + +CONFIG(debug, debug|release) { + + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$Glodon/bin/Debug/X64 + } else { + LIBS += -L$$Glodon/bin/Debug/X86 + } + + win32:LIBS += -lGLDMaskd + unix:LIBS += -lGLDMask_debug +} + +CONFIG(release, debug|release) { + + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$Glodon/bin/Release/X64 + } else { + LIBS += -L$$Glodon/bin/Release/X86 + } + + LIBS += -lGLDMask + +} + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003|win32-msvc2005|win32-msvc2008|win32-msvc2010|win32-msvc2012|win32-msvc2013 { + + LIBS += -loleaut32 -lole32 -lshell32 + + greaterThan(QT_MAJOR_VERSION, 4){ + greaterThan(QT_MINOR_VERSION, 1){ +# QT += winextras + } + } +} + +win32-g++ { + LIBS += -loleaut32 -lole32 -luuid -lnetapi32 +} diff --git a/GCR/trunk/Glodon/shared/GLDRS.pri b/GCR/trunk/Glodon/shared/GLDRS.pri new file mode 100644 index 00000000..da67addb --- /dev/null +++ b/GCR/trunk/Glodon/shared/GLDRS.pri @@ -0,0 +1,9 @@ + +include($(GLDRS)/Glodon/shared/GLD.pri) +include($(GLDRS)/Glodon/shared/GSP.pri) +include($(GLDRS)/Glodon/shared/GRP.pri) +include($(GLDRS)/Glodon/shared/GSC.pri) +include($(GLDRS)/Glodon/shared/ZLIB.pri) +include($(GLDRS)/Glodon/shared/VLD.pri) +include($(GLDRS)/Glodon/shared/QtitanRibbon.pri) +include($(GLDRS)/Glodon/shared/QtitanChart.pri) diff --git a/GCR/trunk/Glodon/shared/GLDStaticLib.pri b/GCR/trunk/Glodon/shared/GLDStaticLib.pri new file mode 100644 index 00000000..a21450b3 --- /dev/null +++ b/GCR/trunk/Glodon/shared/GLDStaticLib.pri @@ -0,0 +1,63 @@ + +GLDRS = $$quote($$(GLDRS)) +Glodon= $$(Glodon) + +isEmpty(Glodon){ + Glodon = $$GLDRS/Glodon +} + +DEFINES += GDP_QT GLD_FULLSOURCE + +INCLUDEPATH += $$Glodon/include/GLD + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003|win32-msvc2005|win32-msvc2008|win32-msvc2010|win32-msvc2012|win32-msvc2013 { + include($(GLDRS)/Glodon/shared/ZLIB.pri) + include($$Glodon/shared/RichText.pri) + include($$Glodon/shared/QuaZip.pri) + include($(GLDRS)/ThirdPart/lzma/C/lzma.pri) + include($(GLDRS)/Glodon/shared/Cryptopp.pri) +} +else { + include($$Glodon/shared/RichText.pri) + include($(GLDRS)/ThirdPart/zlib/zlib.pri) +} + +CONFIG(debug, debug|release) { + + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$Glodon/lib/Debug/X64 + } else { + LIBS += -L$$Glodon/lib/Debug/X86 + } + + win32:LIBS += -lGLDStaticLibd + unix:LIBS += -lGLDStaticLib_debug + +} + +CONFIG(release, debug|release) { + + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$Glodon/lib/Release/X64 + } else { + LIBS += -L$$Glodon/lib/Release/X86 + } + + LIBS += -lGLDStaticLib + +} + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003|win32-msvc2005|win32-msvc2008|win32-msvc2010|win32-msvc2012|win32-msvc2013 { + + LIBS += -loleaut32 -lole32 -lshell32 -lUser32 + + greaterThan(QT_MAJOR_VERSION, 4){ + greaterThan(QT_MINOR_VERSION, 1){ +# QT += winextras + } + } +} + +win32-g++ { + LIBS += -loleaut32 -lole32 -luuid -lnetapi32 +} diff --git a/GCR/trunk/Glodon/shared/GLDTableView.pri b/GCR/trunk/Glodon/shared/GLDTableView.pri new file mode 100644 index 00000000..830a6e5b --- /dev/null +++ b/GCR/trunk/Glodon/shared/GLDTableView.pri @@ -0,0 +1,53 @@ + +GLDRS = $$quote($$(GLDRS)) +Glodon= $$(Glodon) + +isEmpty(Glodon){ + Glodon = $$GLDRS\Glodon +} + +DEFINES += GDP_QT + +INCLUDEPATH += $$Glodon/include/GLD + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003|win32-msvc2005|win32-msvc2008|win32-msvc2010|win32-msvc2012|win32-msvc2013 { + +} + +CONFIG(debug, debug|release) { + + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$Glodon/bin/Debug/X64 + } else { + LIBS += -L$$Glodon/bin/Debug/X86 + } + + win32:LIBS += -lGLDTableViewd + unix:LIBS += -lGLDTableView_debug +} + +CONFIG(release, debug|release) { + + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$Glodon/bin/Release/X64 + } else { + LIBS += -L$$Glodon/bin/Release/X86 + } + + LIBS += -lGLDTableView +} + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003|win32-msvc2005|win32-msvc2008|win32-msvc2010|win32-msvc2012|win32-msvc2013 { + + LIBS += -loleaut32 -lole32 -lshell32 + + greaterThan(QT_MAJOR_VERSION, 4){ + greaterThan(QT_MINOR_VERSION, 1){ +# QT += winextras + } + } +} + +win32-g++ { + LIBS += -loleaut32 -lole32 -luuid -lnetapi32 +} diff --git a/GCR/trunk/Glodon/shared/GLDTechPlatform.pri b/GCR/trunk/Glodon/shared/GLDTechPlatform.pri new file mode 100644 index 00000000..5f846cd1 --- /dev/null +++ b/GCR/trunk/Glodon/shared/GLDTechPlatform.pri @@ -0,0 +1,25 @@ + +GLDRS = $$quote($$(GLDRS)) + +INCLUDEPATH += $$GLDRS/GLDTechPlatform/include \ + $$GLDRS/GLDTechPlatform/include/Intf \ + $$GLDRS/GLDTechPlatform/include/Impl + + +CONFIG(debug, debug|release){ + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$GLDRS/GLDTechPlatform/lib/Debug/X64 + } else { + LIBS += -L$$GLDRS/GLDTechPlatform/lib/Debug/X86 + } + LIBS += -lGLDTechPlatformd +} + +CONFIG(release, debug|release){ + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$GLDRS/GLDTechPlatform/lib/Release/X64 + } else { + LIBS += -L$$GLDRS/GLDTechPlatform/lib/Release/X86 + } + LIBS += -lGLDTechPlatform +} diff --git a/GCR/trunk/Glodon/shared/GLDTechPlatformWithGSP.pri b/GCR/trunk/Glodon/shared/GLDTechPlatformWithGSP.pri new file mode 100644 index 00000000..b98beef9 --- /dev/null +++ b/GCR/trunk/Glodon/shared/GLDTechPlatformWithGSP.pri @@ -0,0 +1,25 @@ + +GLDRS = $$quote($$(GLDRS)) + +INCLUDEPATH += $$GLDRS/GLDTechPlatform/include \ + $$GLDRS/GLDTechPlatform/include/Intf \ + $$GLDRS/GLDTechPlatform/include/Impl + + +CONFIG(debug, debug|release){ + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$GLDRS/GLDTechPlatform/lib/Debug/X64 + } else { + LIBS += -L$$GLDRS/GLDTechPlatform/lib/Debug/X86 + } + LIBS += -lGLDTechPlatformWithGSPd +} + +CONFIG(release, debug|release){ + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$GLDRS/GLDTechPlatform/lib/Release/X64 + } else { + LIBS += -L$$GLDRS/GLDTechPlatform/lib/Release/X86 + } + LIBS += -lGLDTechPlatformWithGSP +} diff --git a/GCR/trunk/Glodon/shared/GLDWidget.pri b/GCR/trunk/Glodon/shared/GLDWidget.pri new file mode 100644 index 00000000..6be53ba3 --- /dev/null +++ b/GCR/trunk/Glodon/shared/GLDWidget.pri @@ -0,0 +1,53 @@ + +GLDRS = $$quote($$(GLDRS)) +Glodon= $$(Glodon) + +isEmpty(Glodon){ + Glodon = $$GLDRS\Glodon +} + +DEFINES += GDP_QT + +INCLUDEPATH += $$Glodon/include/GLD + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003|win32-msvc2005|win32-msvc2008|win32-msvc2010|win32-msvc2012|win32-msvc2013 { + LIBS += -lUser32 +} + +CONFIG(debug, debug|release) { + + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$Glodon/bin/Debug/X64 + } else { + LIBS += -L$$Glodon/bin/Debug/X86 + } + + win32:LIBS += -lGLDWidgetd + unix:LIBS += -lGLDWidget_debug +} + +CONFIG(release, debug|release) { + + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$Glodon/bin/Release/X64 + } else { + LIBS += -L$$Glodon/bin/Release/X86 + } + + LIBS += -lGLDWidget +} + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003|win32-msvc2005|win32-msvc2008|win32-msvc2010|win32-msvc2012|win32-msvc2013 { + + LIBS += -loleaut32 -lole32 -lshell32 + + greaterThan(QT_MAJOR_VERSION, 4){ + greaterThan(QT_MINOR_VERSION, 1){ +# QT += winextras + } + } +} + +win32-g++ { + LIBS += -loleaut32 -lole32 -luuid -lnetapi32 +} diff --git a/GCR/trunk/Glodon/shared/GLDXLS.pri b/GCR/trunk/Glodon/shared/GLDXLS.pri new file mode 100644 index 00000000..c163e3c6 --- /dev/null +++ b/GCR/trunk/Glodon/shared/GLDXLS.pri @@ -0,0 +1,21 @@ +GLDRS = $$quote($$(GLDRS)) + +INCLUDEPATH += $$GLDRS/ThirdPart/libxl/include_cpp + +DEFINES += _UNICODE + +CONFIG(debug, debug|release){ + contains(QMAKE_HOST.arch, x86_64) { + LIBS += $$GLDRS/ThirdPart/libxl/lib64/libxl.lib + } else { + LIBS += $$GLDRS/ThirdPart/libxl/lib/libxl.lib + } +} + +CONFIG(release, debug|release){ + contains(QMAKE_HOST.arch, x86_64) { + LIBS += $$GLDRS/ThirdPart/libxl/lib64/libxl.lib + } else { + LIBS += $$GLDRS/ThirdPart/libxl/lib/libxl.lib + } +} diff --git a/GCR/trunk/Glodon/shared/GLDXML.pri b/GCR/trunk/Glodon/shared/GLDXML.pri new file mode 100644 index 00000000..f84d1a14 --- /dev/null +++ b/GCR/trunk/Glodon/shared/GLDXML.pri @@ -0,0 +1,55 @@ + +GLDRS = $$quote($$(GLDRS)) +Glodon= $$(Glodon) + +isEmpty(Glodon){ + Glodon = $$GLDRS\Glodon +} + +DEFINES += GDP_QT + +INCLUDEPATH += $$Glodon/include/GLD + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003|win32-msvc2005|win32-msvc2008|win32-msvc2010|win32-msvc2012|win32-msvc2013 { + +} + +CONFIG(debug, debug|release) { + + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$Glodon/bin/Debug/X64 + } else { + LIBS += -L$$Glodon/bin/Debug/X86 + } + + win32:LIBS += -lGLDXMLd + unix:LIBS += -lGLDXML_debug + +} + +CONFIG(release, debug|release) { + + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$Glodon/bin/Release/X64 + } else { + LIBS += -L$$Glodon/bin/Release/X86 + } + + LIBS += -lGLDXML + +} + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003|win32-msvc2005|win32-msvc2008|win32-msvc2010|win32-msvc2012|win32-msvc2013 { + + LIBS += -loleaut32 -lole32 -lshell32 + + greaterThan(QT_MAJOR_VERSION, 4){ + greaterThan(QT_MINOR_VERSION, 1){ +# QT += winextras + } + } +} + +win32-g++ { + LIBS += -loleaut32 -lole32 -luuid -lnetapi32 +} diff --git a/GCR/trunk/Glodon/shared/GLDZip.pri b/GCR/trunk/Glodon/shared/GLDZip.pri new file mode 100644 index 00000000..06f59fbd --- /dev/null +++ b/GCR/trunk/Glodon/shared/GLDZip.pri @@ -0,0 +1,57 @@ + +GLDRS = $$quote($$(GLDRS)) +Glodon= $$(Glodon) + +isEmpty(Glodon){ + Glodon = $$GLDRS\Glodon +} + +DEFINES += GDP_QT + +INCLUDEPATH += $$Glodon/include/GLD + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003|win32-msvc2005|win32-msvc2008|win32-msvc2010|win32-msvc2012|win32-msvc2013 { + +} + +include($(GLDRS)/Glodon/shared/ZLIB.pri) +include($(GLDRS)/Glodon/shared/GLDCommon.pri) + +CONFIG(debug, debug|release) { + + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$Glodon/bin/Debug/X64 + } else { + LIBS += -L$$Glodon/bin/Debug/X86 + } + + win32:LIBS += -lGLDZipd + unix:LIBS += -lGLDZip_debug +} + +CONFIG(release, debug|release) { + + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$Glodon/bin/Release/X64 + } else { + LIBS += -L$$Glodon/bin/Release/X86 + } + + LIBS += -lGLDZip + +} + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003|win32-msvc2005|win32-msvc2008|win32-msvc2010|win32-msvc2012|win32-msvc2013 { + + LIBS += -loleaut32 -lole32 -lshell32 + + greaterThan(QT_MAJOR_VERSION, 4){ + greaterThan(QT_MINOR_VERSION, 1){ +# QT += winextras + } + } +} + +win32-g++ { + LIBS += -loleaut32 -lole32 -luuid -lnetapi32 +} diff --git a/GCR/trunk/Glodon/shared/GRE.pri b/GCR/trunk/Glodon/shared/GRE.pri new file mode 100644 index 00000000..ad2e40a8 --- /dev/null +++ b/GCR/trunk/Glodon/shared/GRE.pri @@ -0,0 +1,34 @@ + +GLDRS = $$quote($$(GLDRS)) +Glodon= $$(Glodon) + +isEmpty(Glodon){ + Glodon = $$GLDRS/Glodon +} + +DEFINES += GDP_QT + +INCLUDEPATH += $$Glodon/include/GRE + +CONFIG(debug, debug|release) { + + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$Glodon/lib/Debug/X64 + } else { + LIBS += -L$$Glodon/lib/Debug/X86 + } + + win32:LIBS += -lGREd + unix:LIBS += -lGRE_debug +} + +CONFIG(release, debug|release) { + + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$Glodon/lib/Release/X64 + } else { + LIBS += -L$$Glodon/lib/Release/X86 + } + + LIBS += -lGRE +} diff --git a/GCR/trunk/Glodon/shared/GRP.pri b/GCR/trunk/Glodon/shared/GRP.pri new file mode 100644 index 00000000..0a1af1df --- /dev/null +++ b/GCR/trunk/Glodon/shared/GRP.pri @@ -0,0 +1,17 @@ +Glodon= $$(Glodon) + +isEmpty(Glodon){ + Glodon = $$GLDRS/Glodon +} + +include($$Glodon/shared/GSP.pri) + +INCLUDEPATH += $$Glodon/include/GRP + +CONFIG(debug, debug|release) { + LIBS += -lGRPd +} + +CONFIG(release, debug|release) { + LIBS += -lGRP +} diff --git a/GCR/trunk/Glodon/shared/GRPCommon.pri b/GCR/trunk/Glodon/shared/GRPCommon.pri new file mode 100644 index 00000000..164b6ecc --- /dev/null +++ b/GCR/trunk/Glodon/shared/GRPCommon.pri @@ -0,0 +1,37 @@ +GLDRS = $$quote($$(GLDRS)) +Glodon= $$(Glodon) + +isEmpty(Glodon){ + Glodon = $$GLDRS/Glodon +} + +DEFINES += GDP_QT +greaterThan(QT_MAJOR_VERSION, 4): DEFINES += NOMINMAX + +INCLUDEPATH += $$Glodon/include/GRP7 + +RESOURCES += $$Glodon/src/GRP/GRP7/resDesigner/resDesigner.qrc + + +include($$Glodon/shared/GSP.pri) + +CONFIG(debug, debug|release) { + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$Glodon/bin/Debug/X64 + } else { + LIBS += -L$$Glodon/bin/Debug/X86 + } + win32:LIBS += -lGRPCommond + unix:LIBS += -lGRPCommon_debug +} + +CONFIG(release, debug|release) { + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$Glodon/bin/Release/X64 + } else { + LIBS += -L$$Glodon/bin/Release/X86 + } + + LIBS += -lGRPCommon +} + diff --git a/GCR/trunk/Glodon/shared/GRPGGDB.pri b/GCR/trunk/Glodon/shared/GRPGGDB.pri new file mode 100644 index 00000000..463bd959 --- /dev/null +++ b/GCR/trunk/Glodon/shared/GRPGGDB.pri @@ -0,0 +1,44 @@ + +GLDRS = $$quote($$(GLDRS)) +Glodon= $$(Glodon) + +isEmpty(Glodon){ + Glodon = $$GLDRS/Glodon +} + +DEFINES += GDP_QT +greaterThan(QT_MAJOR_VERSION, 4): DEFINES += NOMINMAX + +INCLUDEPATH += $$Glodon/include/GRPGGDB + +include($$Glodon/shared/GRP7.pri) + +LIBS += -L$$Glodon/lib/Debug/X86 \ + GGDBd.lib \ + MDCommond.lib \ + Commond.lib \ + Geometryd.lib \ + MDCmdLogd.lib \ + MDCached.lib \ + MDScriptd.lib +CONFIG(debug, debug|release){ + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$Glodon/lib/Debug/X64 + } else { + LIBS += -L$$Glodon/lib/Debug/X86 + } + win32:LIBS += -lGRPGGDBd + unix:LIBS += -lGRPGGDBd_debug +} + + +CONFIG(release, debug|release) { + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$Glodon/lib/Release/X64 + } else { + LIBS += -L$$Glodon/lib/Release/X86 + } + + LIBS += -lGRPGGDB + +} diff --git a/GCR/trunk/Glodon/shared/GSC.pri b/GCR/trunk/Glodon/shared/GSC.pri new file mode 100644 index 00000000..d55b7cd6 --- /dev/null +++ b/GCR/trunk/Glodon/shared/GSC.pri @@ -0,0 +1,33 @@ +GLDRS = $$quote($$(GLDRS)) +Glodon = $$(Glodon) + +isEmpty(Glodon){ + Glodon = $$GLDRS/Glodon +} + +greaterThan(QT_MAJOR_VERSION, 4): DEFINES += NOMINMAX + +INCLUDEPATH += $$Glodon/include/GSC + +CONFIG(debug, debug|release) { + + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$Glodon/lib/Debug/X64 + } else { + LIBS += -L$$Glodon/lib/Debug/X86 + } + + win32:LIBS += -lGSCd -lGSCAppImpld -ladvapi32 + unix:LIBS += -lGSC_debug -lGSCAppImpld_debug +} + +CONFIG(release, debug|release) { + + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$Glodon/lib/Release/X64 + } else { + LIBS += -L$$Glodon/lib/Release/X86 + } + + LIBS += -lGSC -lGSCAppImpl -ladvapi32 +} diff --git a/GCR/trunk/Glodon/shared/GSCRSA.pri b/GCR/trunk/Glodon/shared/GSCRSA.pri new file mode 100644 index 00000000..804f038c --- /dev/null +++ b/GCR/trunk/Glodon/shared/GSCRSA.pri @@ -0,0 +1,49 @@ + +GLDRS = $$quote($$(GLDRS)) +Glodon= $$(Glodon) + +isEmpty(Glodon){ + Glodon = $$GLDRS/Glodon +} + +DEFINES += GDP_QT + +INCLUDEPATH += $$Glodon/include/GSC + +include($$Glodon/shared/GLD.pri) + +CONFIG(debug, debug|release) { + + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$Glodon/lib/Debug/X64 + } else { + LIBS += -L$$Glodon/lib/Debug/X86 + } + + win32:LIBS += -lGSCRSAd + unix:LIBS += -lGSCRSA_debug +} + +CONFIG(release, debug|release) { + + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$Glodon/lib/Release/X64 + } else { + LIBS += -L$$Glodon/lib/Release/X86 + } + + LIBS += -lGSCRSA +} + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003|win32-msvc2005|win32-msvc2008|win32-msvc2010|win32-msvc2012 { + LIBS += -loleaut32 -lole32 -lshell32 +greaterThan(QT_MAJOR_VERSION, 4){ + greaterThan(QT_MINOR_VERSION, 1){ +# QT += winextras + } +} +} + +win32-g++ { + LIBS += -loleaut32 -lole32 -luuid -lnetapi32 +} diff --git a/GCR/trunk/Glodon/shared/GSP.pri b/GCR/trunk/Glodon/shared/GSP.pri new file mode 100644 index 00000000..02f7f125 --- /dev/null +++ b/GCR/trunk/Glodon/shared/GSP.pri @@ -0,0 +1,36 @@ +GLDRS = $$quote($$(GLDRS)) +Glodon= $$(Glodon) + +isEmpty(Glodon){ + Glodon = $$GLDRS/Glodon +} + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003|win32-msvc2005|win32-msvc2008|win32-msvc2010|win32-msvc2012|win32-msvc2013 { +} + +DEFINES += GDP_QT + +greaterThan(QT_MAJOR_VERSION, 4): DEFINES += NOMINMAX + +INCLUDEPATH += $$Glodon/include/GSP + +CONFIG(debug, debug|release) { + + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$Glodon/bin/Debug/X64 + } else { + LIBS += -L$$Glodon/bin/Debug/X86 + } + win32:LIBS += -lGSPd + unix:LIBS += -lGSP_debug +} + +CONFIG(release, debug|release) { + + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$Glodon/bin/Release/X64 + } else { + LIBS += -L$$Glodon/bin/Release/X86 + } + LIBS += -lGSP +} diff --git a/GCR/trunk/Glodon/shared/GSPStaticLib.pri b/GCR/trunk/Glodon/shared/GSPStaticLib.pri new file mode 100644 index 00000000..bedb2347 --- /dev/null +++ b/GCR/trunk/Glodon/shared/GSPStaticLib.pri @@ -0,0 +1,37 @@ +GLDRS = $$quote($$(GLDRS)) +Glodon= $$(Glodon) + +isEmpty(Glodon){ + Glodon = $$GLDRS/Glodon +} + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003|win32-msvc2005|win32-msvc2008|win32-msvc2010|win32-msvc2012|win32-msvc2013 { + include($$Glodon/shared/GLDStaticLib.pri) +} + +DEFINES += GDP_QT GLD_FULLSOURCE + +greaterThan(QT_MAJOR_VERSION, 4): DEFINES += NOMINMAX + +INCLUDEPATH += $$Glodon/include/GSP + +CONFIG(debug, debug|release) { + + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$Glodon/bin/Debug/X64 + } else { + LIBS += -L$$Glodon/bin/Debug/X86 + } + win32:LIBS += -lGSPStaticLibd + unix:LIBS += -lGSPStaticLib_debug +} + +CONFIG(release, debug|release) { + + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$Glodon/bin/Release/X64 + } else { + LIBS += -L$$Glodon/bin/Release/X86 + } + LIBS += -lGSPStaticLib +} diff --git a/GCR/trunk/Glodon/shared/GUC.pri b/GCR/trunk/Glodon/shared/GUC.pri new file mode 100644 index 00000000..bee77a8c --- /dev/null +++ b/GCR/trunk/Glodon/shared/GUC.pri @@ -0,0 +1,49 @@ + +GLDRS = $$quote($$(GLDRS)) +Glodon= $$(Glodon) + +isEmpty(Glodon){ + Glodon = $$GLDRS/Glodon +} + +DEFINES += GDP_QT + +INCLUDEPATH += $$Glodon/include/GUC + +include($$Glodon/shared/GLD.pri) + +CONFIG(debug, debug|release) { + + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$Glodon/lib/Debug/X64 + } else { + LIBS += -L$$Glodon/lib/Debug/X86 + } + + win32:LIBS += -lGUCd + unix:LIBS += -lGUC_debug +} + +CONFIG(release, debug|release) { + + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$Glodon/lib/Release/X64 + } else { + LIBS += -L$$Glodon/lib/Release/X86 + } + + LIBS += -lGUC +} + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003|win32-msvc2005|win32-msvc2008|win32-msvc2010|win32-msvc2012 { + LIBS += -loleaut32 -lole32 -lshell32 +greaterThan(QT_MAJOR_VERSION, 4){ + greaterThan(QT_MINOR_VERSION, 1){ +# QT += winextras + } +} +} + +win32-g++ { + LIBS += -loleaut32 -lole32 -luuid -lnetapi32 +} diff --git a/GCR/trunk/Glodon/shared/QtitanChart.pri b/GCR/trunk/Glodon/shared/QtitanChart.pri new file mode 100644 index 00000000..e50f58e6 --- /dev/null +++ b/GCR/trunk/Glodon/shared/QtitanChart.pri @@ -0,0 +1,4 @@ + +QTITANDIR = $$quote($$(GLDRS)/ThirdPart/Qtitan) + +include($(QTITANDIR)/src/shared/qtitanchart.pri) diff --git a/GCR/trunk/Glodon/shared/QtitanRibbon.pri b/GCR/trunk/Glodon/shared/QtitanRibbon.pri new file mode 100644 index 00000000..cc21ba0d --- /dev/null +++ b/GCR/trunk/Glodon/shared/QtitanRibbon.pri @@ -0,0 +1,5 @@ + +QTITANDIR = $$quote($$(GLDRS)/ThirdPart/Qtitan) + +include($$QTITANDIR/src/shared/qtitanribbon.pri) +#include($(QTITANDIR)/src/shared/qtitanribbon_static.pri) diff --git a/GCR/trunk/Glodon/shared/QuaZip.pri b/GCR/trunk/Glodon/shared/QuaZip.pri new file mode 100644 index 00000000..fa7dc3f1 --- /dev/null +++ b/GCR/trunk/Glodon/shared/QuaZip.pri @@ -0,0 +1,36 @@ +GLDRS = $$quote($$(GLDRS)) + +DEFINES += QUAZIP_STATIC +INCLUDEPATH += $$GLDRS/ThirdPart/quazip + +CONFIG(debug, debug|release) { + + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$GLDRS/ThirdPart/quazip/lib/Debug/X64 + } else { + LIBS += -L$$GLDRS/ThirdPart/quazip/lib/Debug/X86 + } + + win32:LIBS += -lquazipd + unix:LIBS += -lquazip_debug +} + +CONFIG(release, debug|release) { + + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$GLDRS/ThirdPart/quazip/lib/Release/X64 + } else { + LIBS += -L$$GLDRS/ThirdPart/quazip/lib/Release/X86 + } + + LIBS += -lquazip +} + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003|win32-msvc2005|win32-msvc2008|win32-msvc2010|win32-msvc2012|win32-msvc2013 { + include($$GLDRS/Glodon/shared/ZLIB.pri) + include($(GLDRS)/ThirdPart/lzma/C/lzma.pri) +} +else { +# include($$GLDRS/ThirdPart/zlib/zlib.pri) +# include($(GLDRS)/ThirdPart/lzma/C/lzma.pri) +} diff --git a/GCR/trunk/Glodon/shared/RichText.pri b/GCR/trunk/Glodon/shared/RichText.pri new file mode 100644 index 00000000..d76e7b72 --- /dev/null +++ b/GCR/trunk/Glodon/shared/RichText.pri @@ -0,0 +1,33 @@ +GLDRS = $$quote($$(GLDRS)) + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003|win32-msvc2005|win32-msvc2008|win32-msvc2010|win32-msvc2012|win32-msvc2013 { +# include($$GLDRS/Glodon/shared/QuaZip.pri) +} +else { + include($$GLDRS/Glodon/shared/QuaZip.pri) +} + +INCLUDEPATH += $$GLDRS/ThirdPart/RichText/include + +CONFIG(debug, debug|release) { + + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$GLDRS/ThirdPart/RichText/lib/Debug/X64 + } else { + LIBS += -L$$GLDRS/ThirdPart/RichText/lib/Debug/X86 + } + + win32:LIBS += -lRichTextd + unix:LIBS += -lRichText_debug +} + +CONFIG(release, debug|release) { + + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$GLDRS/ThirdPart/RichText/lib/Release/X64 + } else { + LIBS += -L$$GLDRS/ThirdPart/RichText/lib/Release/X86 + } + + LIBS += -lRichText +} diff --git a/GCR/trunk/Glodon/shared/VLD.pri b/GCR/trunk/Glodon/shared/VLD.pri new file mode 100644 index 00000000..853d2e86 --- /dev/null +++ b/GCR/trunk/Glodon/shared/VLD.pri @@ -0,0 +1,14 @@ + +GLDRS = $$quote($$(GLDRS)) + +INCLUDEPATH += $$GLDRS/ThirdPart/VLD/include + +contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$GLDRS/ThirdPart/VLD/lib/Win64 +} else { + LIBS += -L$$GLDRS/ThirdPart/VLD/lib/Win32 +} + +CONFIG(debug, debug|release) { + win32:LIBS += -lvld +} diff --git a/GCR/trunk/Glodon/shared/ZLIB.pri b/GCR/trunk/Glodon/shared/ZLIB.pri new file mode 100644 index 00000000..4d04a2e9 --- /dev/null +++ b/GCR/trunk/Glodon/shared/ZLIB.pri @@ -0,0 +1,25 @@ + +GLDRS = $$quote($$(GLDRS)) + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003|win32-msvc2005|win32-msvc2008|win32-msvc2010|win32-msvc2012|win32-msvc2013 { + + DEFINES += ZLIB_WINAPI +} + +INCLUDEPATH += $$GLDRS/ThirdPart/zlib + +CONFIG(debug, debug|release){ + contains(QMAKE_HOST.arch, x86_64) { + LIBS += $$GLDRS/ThirdPart/zlib/lib/Debug/X64/zlibd.lib + } else { + LIBS += $$GLDRS/ThirdPart/zlib/lib/Debug/X86/zlibd.lib + } +} + +CONFIG(release, debug|release){ + contains(QMAKE_HOST.arch, x86_64) { + LIBS += $$GLDRS/ThirdPart/zlib/lib/Release/X64/zlib.lib + } else { + LIBS += $$GLDRS/ThirdPart/zlib/lib/Release/X86/zlib.lib + } +} diff --git a/GCR/trunk/Glodon/shared/lua.pri b/GCR/trunk/Glodon/shared/lua.pri new file mode 100644 index 00000000..a8625b8c --- /dev/null +++ b/GCR/trunk/Glodon/shared/lua.pri @@ -0,0 +1,24 @@ + +GLDRS = $$quote($$(GLDRS)) + +INCLUDEPATH += $$GLDRS/ThirdPart/lua/include + +CONFIG(debug, debug|release) { + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$GLDRS/ThirdPart/lua/bin/Debug/X64 + } else { + LIBS += -L$$GLDRS/ThirdPart/lua/bin/Debug/X86 + } + win32:LIBS += -lluad + #unix:LIBS += -llua +} + +CONFIG(release, debug|release) { + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$GLDRS/ThirdPart/lua/bin/Release/X64 + } else { + LIBS += -L$$GLDRS/ThirdPart/lua/bin/Release/X86 + } + win32:LIBS += -llua + #unix:LIBS += -llua +} diff --git a/GCR/trunk/Glodon/shared/lzma.pri b/GCR/trunk/Glodon/shared/lzma.pri new file mode 100644 index 00000000..b35d9a83 --- /dev/null +++ b/GCR/trunk/Glodon/shared/lzma.pri @@ -0,0 +1,28 @@ + +GLDRS = $$quote($$(GLDRS)) +INCLUDEPATH += \ + $(GLDRS)/ThirdPart/lzma/C/lzma \ + $(GLDRS)/ThirdPart/lzma/C + +CONFIG(debug, debug|release) { + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$GLDRS/ThirdPart/lzma/C/lzma/lib/Debug/X64 + } else { + LIBS += -L$$GLDRS/ThirdPart/lzma/C/lzma/lib/Debug/X86 + } + + win32:LIBS += -llzmad + unix:LIBS += -llzma_debug +} + +CONFIG(release, debug|release) { + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$GLDRS/ThirdPart/lzma/C/lzma/lib/Release/X64 + } else { + LIBS += -L$$GLDRS/ThirdPart/lzma/C/lzma/lib/Release/X86 + } + + LIBS += -llzma +} + + diff --git a/GCR/trunk/Glodon/shared/tcmalloc.pri b/GCR/trunk/Glodon/shared/tcmalloc.pri new file mode 100644 index 00000000..36d4aa73 --- /dev/null +++ b/GCR/trunk/Glodon/shared/tcmalloc.pri @@ -0,0 +1,26 @@ + +GLDRS = $$quote($$(GLDRS)) + +INCLUDEPATH += $$GLDRS/ThirdPart/gperftools/include + +CONFIG(debug, debug|release) { + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$GLDRS/ThirdPart/gperftools/Debug/X64 + } else { + LIBS += -L$$GLDRS/ThirdPart/gperftools/Debug/X86 + } + win32:LIBS += -llibtcmalloc_minimal-debug + #unix:LIBS += -libtcmalloc_minimal-debug +} + +CONFIG(release, debug|release) { + contains(QMAKE_HOST.arch, x86_64) { + LIBS += -L$$GLDRS/ThirdPart/gperftools/Release/X64 + } else { + LIBS += -L$$GLDRS/ThirdPart/gperftools/Release/X86 + } + win32:LIBS += -llibtcmalloc_minimal + #unix:LIBS += -llibtcmalloc_minimal +} + + diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDCrypt.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDCrypt.cpp new file mode 100644 index 00000000..cd5027a1 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDCrypt.cpp @@ -0,0 +1,924 @@ +/*! +* @加解密库类 +* @ 详细: 包括加解密类基类及子类AES和子类DES及方法; +* 加解密算法策略类及方法 +* @author lijb +* @date 2015.06.05 +* @remarks 备注 +* Copyright (c) 1998-2015 Glodon Corporation +*/ + +//cryptlib库宏定义,以静态lib方式引入cryptlib.lib +#define _CRT_SECURE_NO_DEPRECATE +#define CRYPTOPP_DEFAULT_NO_DLL +#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 + +#include "dll.h" + +using namespace CryptoPP; +using namespace std; + +#include "qglobal.h" +#include "GLDCrypt.h" +#include "GLDFile.h" + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: 加解密算法类私类 +//参数: +//////////////////////////////////////////////////////////////////////////////// +class GCryptAlgorithmPrivate +{ +public: + GCryptAlgorithmPrivate() + { + } + +protected: + GCryptAlgorithm * q_ptr; + byte * m_pbyKey; //密钥 + byte * m_pbyIv; //初始向量 + int m_nKeyLength; //密钥长度 + EnAlgorithmType m_EnAlgorithmType; //算法类型,如AES , DES等 + EnEncodeMode m_EnEncodeMode; //编码模式,如CBC, ECB等 + EnPaddingType m_EnPaddingType; //填充类型,如NoPadding,PKCS5Padding等 + +private: + Q_DECLARE_PUBLIC(GCryptAlgorithm); +}; + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: 加解密算法类构造函数,配置加密参数 +//参数:enAlgorithmType 加密算法类型,如AES, DES等 +// EnEncodeMode 加密模式类型,如CBC, ECB等 +// EnPaddingType 填充模式类型,如NoPadding,PKCS5Padding等 +//////////////////////////////////////////////////////////////////////////////// +GCryptAlgorithm::GCryptAlgorithm(EnAlgorithmType EnAlgorithmKind, EnEncodeMode EnEncodeKind + , EnPaddingType EnPaddingKind) + : d_ptr(new GCryptAlgorithmPrivate) +{ + Q_D(GCryptAlgorithm); + + d->q_ptr = this; + + d->m_EnAlgorithmType = EnAlgorithmKind; + d->m_EnEncodeMode = EnEncodeKind; + d->m_EnPaddingType = EnPaddingKind; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: 加解密算法类构造函数,配置加密参数 +//参数:enAlgorithmType 加密算法类型,如AES, DES等 +// EnEncodeMode 加密模式类型,如CBC, ECB等 +// EnPaddingType 填充模式类型,如NoPadding,PKCS5Padding等 +//////////////////////////////////////////////////////////////////////////////// +GCryptAlgorithm::GCryptAlgorithm(GCryptAlgorithmPrivate &dd, EnAlgorithmType EnAlgorithmKind + , EnEncodeMode EnEncodeType, EnPaddingType EnPadding) + : d_ptr(&dd) +{ + Q_D(GCryptAlgorithm); + + d->q_ptr = this; + + d->m_EnAlgorithmType = EnAlgorithmKind; + d->m_EnEncodeMode = EnEncodeType; + d->m_EnPaddingType = EnPadding; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: 加解密算法类析造函数 +//////////////////////////////////////////////////////////////////////////////// +GCryptAlgorithm::~GCryptAlgorithm() +{ + Q_D(GCryptAlgorithm); + + delete(d); +} +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: 用密钥加密明文字符串,返回加密后的密文字符串 +//参数: strPlainText 明文字符串 +//返回: 密文字符串 +//////////////////////////////////////////////////////////////////////////////// +const GString GCryptAlgorithm::encryptStr(const GString &strPlainText) +{ + Q_D(GCryptAlgorithm); + + string strCipher; + + // 生成加密器对象 + SymmetricCipher *penncryptor = encryptor(d->m_EnEncodeMode); + + StringSource(strPlainText.toLatin1().data(), true, new StreamTransformationFilter(*penncryptor, new StringSink(strCipher) + , (StreamTransformationFilter::BlockPaddingScheme)d->m_EnPaddingType)); + + //加密密文由string转换为GString + return QString(QLatin1String(strCipher.c_str())); +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: 用密钥解密密文字符串,返回解密后的明文字符串 +//参数: strPlainText 明文字符串 +//返回: 明文字符串 +//////////////////////////////////////////////////////////////////////////////// +const GString GCryptAlgorithm::decryptStr(const GString &strCipher) +{ + Q_D(GCryptAlgorithm); + + string strCipherString = strCipher.toStdString(); + + string strRecover; + + // 生成解密器对象 + SymmetricCipher* pdecryptor = decryptor(d->m_EnEncodeMode); + + StringSource(strCipher.toLatin1().data(), true, new StreamTransformationFilter(*pdecryptor, new StringSink(strRecover) + , (StreamTransformationFilter::BlockPaddingScheme)d->m_EnPaddingType)); + + return QString(QLatin1String(strRecover.c_str())); +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: 用密钥加密明文文件,返回加密后的密文文件 +//参数: inFilename 明文文件名 +// outFilename 密文文件名 +//返回: 成功or 失败 +//////////////////////////////////////////////////////////////////////////////// +bool GCryptAlgorithm::encryptFile(const GString &strOutFilename, const GString &strInFilename) +{ + Q_D(GCryptAlgorithm); + + if (!GFileStream::exists(strInFilename)) + { + cout << "The file " << strInFilename.data() << " is not exist! " << endl; + return false; + } + + // 生成加密器对象 + SymmetricCipher* penncryptor = encryptor(d->m_EnEncodeMode); + + FileSource(strInFilename.toLatin1().data(), true, + new StreamTransformationFilter(*penncryptor, new FileSink(strOutFilename.toLatin1().data()) + , (StreamTransformationFilter::BlockPaddingScheme)d->m_EnPaddingType)); + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: 用密钥解密密文文件,返回解密后的名文文件 +//参数: decFilename 密文文件名 +// recoverFilename 名文文件名 +//返回: 成功or 失败 +//////////////////////////////////////////////////////////////////////////////// +bool GCryptAlgorithm::decryptFile(const GString &strRecoverFilename, const GString &strDecFilename) +{ + Q_D(GCryptAlgorithm); + + if (!GFileStream::exists(strDecFilename)) + { + cout << "The file " << strDecFilename.data() << " is not exist! " << endl; + return false; + } + + // 生成解密器对象 + SymmetricCipher* pdecryptor = decryptor(d->m_EnEncodeMode); + + FileSource(strDecFilename.toLatin1().data(), true, new StreamTransformationFilter((*pdecryptor), + new FileSink(strRecoverFilename.toLatin1().data()), (StreamTransformationFilter::BlockPaddingScheme)d->m_EnPaddingType)); + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: 根据用户参数加密模式EnEncodeType,返回对应的字符串 +// ,缺省返回"CBC" +//参数: EnEncodeMode 加密模式类型,如CBC, ECB等 +// +//返回:加密模式对应的字符串 +//////////////////////////////////////////////////////////////////////////////// +GString GCryptAlgorithm::encodeModeStr(EnEncodeMode EnEncodeMode) +{ + switch (EnEncodeMode) + { + case ENCODE_MODE_CBC: + { + return "CBC"; + break; + } + + case ENCODE_MODE_ECB: + { + return "ECB"; + break; + } + + default: + assert(false); + } + + return "ECB"; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: 根据用户参数填充模式EnPaddingType,返回对应的字符串,缺省返回"PKCS5Padding" +//参数: EnPaddingType 加密填充类型,如EN_NOPADDING等 +// +//返回:加密填充模式对应的字符串 +//////////////////////////////////////////////////////////////////////////////// +GString GCryptAlgorithm::paddingTypeStr(EnPaddingType EnPaddingType) +{ + switch (EnPaddingType) + { + case EN_NOPADDING: + { + return "NoPadding"; + break; + } + + case EN_PKCS_PADDING: + { + return "PKCS5Padding"; + break; + } + + default: + assert(false); + } + + return "PKCS5Padding"; + +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: 设置加密参数,包括加密算法EnAlgorithmKind,加密模式EnEncodeType,填充类型EnPadding +//参数: EnAlgorithmKind 加密算法类型,如AES, DES等 +// EnEncodeMode 加密模式类型,如CBC, ECB等 +// EnPaddingType 填充模式类型,如NoPadding,PKCS5Padding等? +//返回:无 +//////////////////////////////////////////////////////////////////////////////// +void GCryptAlgorithm::setEncodeMode(EnAlgorithmType EnAlgorithmKind, EnEncodeMode EnEncodeMode, EnPaddingType EnPaddingType) +{ + Q_D(GCryptAlgorithm); + + d->m_EnAlgorithmType = EnAlgorithmKind; + d->m_EnEncodeMode = EnEncodeMode; + d->m_EnPaddingType = EnPaddingType; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: 设置秘钥及秘钥长度,非ECB模式 +//参数: pbyKey 加密秘钥 +// nLength 秘钥长度 +// pbyIv 初始向量 +//返回:无 +//////////////////////////////////////////////////////////////////////////////// +void GCryptAlgorithm::setKey(byte *pbyKey, int nLength, byte *pbyIv) +{ + Q_D(GCryptAlgorithm); + + d->m_pbyKey = pbyKey; + d->m_pbyIv = pbyIv; + d->m_nKeyLength = nLength; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: 设置秘钥及秘钥长度,ECB模式 +//参数: pbyKey 加密秘钥 +// nLength 秘钥长度 +//返回:无 +//////////////////////////////////////////////////////////////////////////////// +void GCryptAlgorithm::setKey(byte *pbyKey, int nLength) +{ + Q_D(GCryptAlgorithm); + + d->m_pbyKey = pbyKey; + d->m_nKeyLength = nLength; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: 获取秘钥 +//参数: +//返回:秘钥字节指针 +//////////////////////////////////////////////////////////////////////////////// +byte* GCryptAlgorithm::key() +{ + Q_D(GCryptAlgorithm); + + return d->m_pbyKey; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: 获取初始向量 +//参数: +//返回:秘钥字节指针 +//////////////////////////////////////////////////////////////////////////////// +byte* GCryptAlgorithm::ivKey() +{ + Q_D(GCryptAlgorithm); + + return d->m_pbyIv; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: AES加解密算法私类构造函数 +//////////////////////////////////////////////////////////////////////////////// +class GAesAlgorithmPrivate : public GCryptAlgorithmPrivate +{ +public: + GAesAlgorithmPrivate() + { + } + +private: + Q_DECLARE_PUBLIC(GAesAlgorithm); + + SymmetricCipher *m_encryptor; //加密器对象,根据加密模式生成不同对象 + SymmetricCipher *m_decryptor; //解密器对象,根据加密模式生成不同对象 +}; + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: AES加解密算法类构造函数,配置加密参数 +//参数:enAlgorithmType 加密算法类型,如AES, DES等 +// EnEncodeMode 加密模式类型,如CBC, ECB等 +// EnPaddingType 填充模式类型,如NoPadding,PKCS5Padding等 +//////////////////////////////////////////////////////////////////////////////// +GAesAlgorithm::GAesAlgorithm(EnEncodeMode EnEncodeMode, EnPaddingType EnPaddingType) + : GCryptAlgorithm(*(new GAesAlgorithmPrivate), EN_ALGORITHM_AES, EnEncodeMode, EnPaddingType) +{ + Q_D(GAesAlgorithm); + + d->m_encryptor = NULL; + d->m_decryptor = NULL; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.8 +//功能: AES加解密算法类析构函数,释放加解密器资源 +//参数: +//////////////////////////////////////////////////////////////////////////////// +GAesAlgorithm::~GAesAlgorithm() +{ + Q_D(GAesAlgorithm); + + if (NULL != d->m_encryptor) + { + delete d->m_encryptor; + } + + if (NULL != d->m_decryptor) + { + delete d->m_decryptor; + } +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.8 +//功能: 根据内部生成随机的加密密钥并设置 +//参数: +//////////////////////////////////////////////////////////////////////////////// +void GAesAlgorithm::setRandomKey() +{ + Q_D(GAesAlgorithm); + + AutoSeededRandomPool rnd; + byte byKey[AES::DEFAULT_KEYLENGTH]; + rnd.GenerateBlock(byKey, AES::DEFAULT_KEYLENGTH); + + if (ENCODE_MODE_CBC != d->m_EnEncodeMode) + { + // Generate a random IV + byte byIv[AES::BLOCKSIZE]; + rnd.GenerateBlock(byIv, AES::BLOCKSIZE); + + setKey(byKey, AES::DEFAULT_KEYLENGTH, byIv); + } + else + { + setKey(byKey, AES::DEFAULT_KEYLENGTH); + } + +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: 根据用户参数加密模式EnEncodeType,填充类型EnPadding等 生成相应的解密器 +//参数: +// EnEncodeMode 加密模式类型,如CBC, ECB等 +//返回: 解密器对象指针 +////////////////////////////////////////////////////////////////////////////////////////////////////////// +SymmetricCipher* GAesAlgorithm::decryptor(EnEncodeMode EnEncodeMode) +{ + Q_D(GAesAlgorithm); + + SymmetricCipher* pdecryptor = NULL; + + switch (EnEncodeMode) + { + case ENCODE_MODE_CBC: + { + pdecryptor = new CBC_Mode::Decryption(d->m_pbyKey, d->m_nKeyLength, d->m_pbyIv); + break; + } + + case ENCODE_MODE_CFB: + { + pdecryptor = new CFB_Mode::Decryption(d->m_pbyKey, d->m_nKeyLength, d->m_pbyIv); + break; + } + + case ENCODE_MODE_ECB: + { + pdecryptor = new ECB_Mode::Decryption(d->m_pbyKey, d->m_nKeyLength); + break; + } + + case ENCODE_MODE_OFB: + { + pdecryptor = new OFB_Mode::Decryption(d->m_pbyKey, d->m_nKeyLength, d->m_pbyIv); + break; + } + + default: + assert(false); + } + + d->m_decryptor = pdecryptor; + + return pdecryptor; + +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: 根据用户参数加密模式EnEncodeType,填充类型EnPadding等 生成相应的加密器 +//参数: +// EnEncodeMode 加密模式类型,如CBC, ECB等 +//返回: 加密器对象指针 +////////////////////////////////////////////////////////////////////////////////////////////////////////// +SymmetricCipher* GAesAlgorithm::encryptor(EnEncodeMode EnEncodeMode) +{ + Q_D(GAesAlgorithm); + + SymmetricCipher* pencryptor = NULL; + + switch (EnEncodeMode) + { + case ENCODE_MODE_CBC: + { + pencryptor = new CBC_Mode::Encryption(d->m_pbyKey, d->m_nKeyLength, d->m_pbyIv); + break; + } + + case ENCODE_MODE_CFB: + { + pencryptor = new CFB_Mode::Encryption(d->m_pbyKey, d->m_nKeyLength, d->m_pbyIv); + break; + } + + case ENCODE_MODE_ECB: + { + pencryptor = new ECB_Mode::Encryption(d->m_pbyKey, d->m_nKeyLength); + break; + } + + case ENCODE_MODE_OFB: + { + pencryptor = new OFB_Mode::Encryption(d->m_pbyKey, d->m_nKeyLength, d->m_pbyIv); + break; + } + + default: + assert(false); + } + + d->m_encryptor = pencryptor; + + return pencryptor; + +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.8 +//功能: DES加解密算法私类 +//////////////////////////////////////////////////////////////////////////////// +class GDesAlgorithmPrivate : public GCryptAlgorithmPrivate +{ +public: + GDesAlgorithmPrivate() + { + } + +private: + Q_DECLARE_PUBLIC(GDesAlgorithm); + + SymmetricCipher *m_encryptor; //加密器对象,根据加密模式生成不同对象 + SymmetricCipher *m_decryptor; //解密器对象,根据加密模式生成不同对象 +}; + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.8 +//功能: DES加解密算法类构造函数,配置加密参数 +//参数: +// EnEncodeMode 加密模式类型,如CBC, ECB等 +// EnPaddingType 填充模式类型,如NoPadding,PKCS5Padding等 +//////////////////////////////////////////////////////////////////////////////// +GDesAlgorithm::GDesAlgorithm(EnEncodeMode EnEncodeMode, EnPaddingType EnPaddingType) + : GCryptAlgorithm(* new GDesAlgorithmPrivate(), EN_ALGORITHM_DES, EnEncodeMode, EnPaddingType) +{ + Q_D(GDesAlgorithm); + + d->m_encryptor = NULL; + d->m_decryptor = NULL; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.8 +//功能: DES加解密算法类析构函数,释放加解密器资源 +//参数: +//////////////////////////////////////////////////////////////////////////////// +GDesAlgorithm::~GDesAlgorithm() +{ + Q_D(GDesAlgorithm); + + if (NULL != d->m_encryptor) + { + delete d->m_encryptor; + } + + if (NULL != d->m_decryptor) + { + delete d->m_decryptor; + } +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.8 +//功能: 根据内部生成随机的加密密钥并设置 +//参数: +//////////////////////////////////////////////////////////////////////////////// +void GDesAlgorithm::setRandomKey() +{ + Q_D(GDesAlgorithm); + + AutoSeededRandomPool rnd; + byte byKey[DES::DEFAULT_KEYLENGTH]; + rnd.GenerateBlock(byKey, DES::DEFAULT_KEYLENGTH); + + if (ENCODE_MODE_CBC != d->m_EnEncodeMode) + { + // Generate a random IV + byte byIv[AES::BLOCKSIZE]; + rnd.GenerateBlock(byIv, DES::BLOCKSIZE); + + setKey(byKey, DES::DEFAULT_KEYLENGTH, byIv); + + } + else + { + setKey(byKey, DES::DEFAULT_KEYLENGTH); + } +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.9 +//功能: 根据用户参数加密模式EnEncodeType,填充类型EnPadding等 生成相应的解密器 +//参数: +// EnEncodeMode 加密模式类型,如CBC, ECB等 +//返回: 解密器对象指针 +////////////////////////////////////////////////////////////////////////////////////////////////////////// +SymmetricCipher* GDesAlgorithm::decryptor(EnEncodeMode EnEncodeKind) +{ + Q_D(GDesAlgorithm); + + SymmetricCipher* decryptor = NULL; + + switch (EnEncodeKind) + { + case ENCODE_MODE_CBC: + { + decryptor = new CBC_Mode::Decryption(d->m_pbyKey, d->m_nKeyLength, d->m_pbyIv); + break; + } + + case ENCODE_MODE_CFB: + { + decryptor = new CFB_Mode::Decryption(d->m_pbyKey, d->m_nKeyLength, d->m_pbyIv); + break; + } + + case ENCODE_MODE_ECB: + { + decryptor = new ECB_Mode::Decryption(d->m_pbyKey, d->m_nKeyLength); + break; + } + + case ENCODE_MODE_OFB: + { + decryptor = new OFB_Mode::Decryption(d->m_pbyKey, d->m_nKeyLength, d->m_pbyIv); + break; + } + + //case ENCODE_MODE_PCBC: + //{ + //decryptor = new PCBC_Mode::Decryption(d->m_pbyKey, d->m_nKeyLength, d->m_pbyIv); + //break; + //} + + default: + assert(false); + } + + d->m_decryptor = decryptor; + + return decryptor; + +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: 根据用户参数加密模式EnEncodeType,填充类型EnPadding等 生成相应的加密器 +//参数: +// EnEncodeKind 加密模式类型,如CBC, ECB等 +//返回: 加密器对象指针 +////////////////////////////////////////////////////////////////////////////////////////////////////////// +SymmetricCipher* GDesAlgorithm::encryptor(EnEncodeMode EnEncodeKind) +{ + Q_D(GDesAlgorithm); + + SymmetricCipher* encryptor = NULL; + + switch (EnEncodeKind) + { + case ENCODE_MODE_CBC: + { + encryptor = new CBC_Mode::Encryption(d->m_pbyKey, d->m_nKeyLength, d->m_pbyIv); + break; + } + + case ENCODE_MODE_CFB: + { + encryptor = new CFB_Mode::Encryption(d->m_pbyKey, d->m_nKeyLength, d->m_pbyIv); + break; + } + + case ENCODE_MODE_ECB: + { + encryptor = new ECB_Mode::Encryption(d->m_pbyKey, d->m_nKeyLength); + break; + } + + case ENCODE_MODE_OFB: + { + encryptor = new OFB_Mode::Encryption(d->m_pbyKey, d->m_nKeyLength, d->m_pbyIv); + break; + } + + //case ENCODE_MODE_PCBC: + //{ + //cryptAlgorithm = new PCBC_Mode::Encryption(d->m_pbyKey, d->m_nKeyLength, d->m_pbyIv); + //break; + //} + + default: + assert(false); + } + + d->m_encryptor = encryptor; + + return encryptor; + +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: 加解密算法策略类私类 +//////////////////////////////////////////////////////////////////////////////// +class GCryptPrivate +{ +public: + GCryptPrivate(GCrypt *parent) + : q_ptr(parent) + { + } + +private: + GCrypt * const q_ptr; + Q_DECLARE_PUBLIC(GCrypt); + + GCryptAlgorithm *m_algorithm; //加密算法对象指针,如AES , DES等 +}; + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: 加解密算法策略类构造函数,配置加密参数; +// 生成加解密算法类对象 +// EnAlgorithmKind 加密算法类型,如AES, DES等 +// EnEncodeMode 加密模式类型,如CBC, ECB等 +// EnPaddingType 填充模式类型,如NoPadding,PKCS5Padding等 +//////////////////////////////////////////////////////////////////////////////// +GCrypt::GCrypt(EnAlgorithmType EnAlgorithmKind, EnEncodeMode EnEncodeMode, EnPaddingType EnPaddingType) + : d_ptr(new GCryptPrivate(this)) +{ + Q_D(GCrypt); + + d->m_algorithm = createAlgorithm(EnAlgorithmKind, EnEncodeMode, EnPaddingType); +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: 根据用户传入的加密参数,生成对应的加解密类对象 +//参数:enAlgorithmType 加密算法类型,如AES, DES等 +// EnEncodeMode 加密模式类型,如CBC, ECB等 +// EnPaddingType 填充模式类型,如NoPadding,PKCS5Padding? +//返回: 加解密类对象指针 +//////////////////////////////////////////////////////////////////////////////// +GCryptAlgorithm* GCrypt::createAlgorithm(EnAlgorithmType EnAlgorithmType, EnEncodeMode EnEncodeMode + ,EnPaddingType EnPaddingType) +{ + GCryptAlgorithm* cryptAlgorithm = NULL; + + switch (EnAlgorithmType) + { + case EN_ALGORITHM_AES: + { + cryptAlgorithm = new GAesAlgorithm(EnEncodeMode, EnPaddingType); + break; + } + + case EN_ALGORITHM_DES: + { + cryptAlgorithm = new GDesAlgorithm(EnEncodeMode, EnPaddingType); + break; + } + + default: + assert(false); + } + + return cryptAlgorithm; + +} + +GCrypt::~GCrypt() +{ + Q_D(GCrypt); + + if (NULL != d->m_algorithm) + { + delete d->m_algorithm; + } + + delete d; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: 使用密钥加密明文字符串plainText 并且返回密文 +//参数: strPlainText 加密原文字符串 +//返回: 加类密文字符串对象 +//////////////////////////////////////////////////////////////////////////////// + +GString GCrypt::encryptStr(const GString &strPlainText) +{ + Q_D(GCrypt); + + return d->m_algorithm->encryptStr(strPlainText); +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: 使用密钥解密密文cipher 并且返回恢复后的明文 +//参数: strCipher 加密密文字符串 +//返回: 返回恢复后的明文 +//////////////////////////////////////////////////////////////////////////////// +GString GCrypt::decryptStr(const GString &strCipher) +{ + Q_D(GCrypt); + + return d->m_algorithm->decryptStr(strCipher); +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: 使用密钥加密明文文件inFilename 并且返回密文文件outFilename +//参数: inFilename 明文文件 +// outFilename 密文文件 +//返回: 成功与否 +//////////////////////////////////////////////////////////////////////////////// +bool GCrypt::encryptFile(const GString &strOutFilename, const GString &strInFilename) +{ + Q_D(GCrypt); + + return d->m_algorithm->encryptFile(strOutFilename, strInFilename); +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: 使用密钥解密密文文件DecFilename 并且返回恢复后的明文文件recoverFilename +//参数: strDecFilename 密文文件 +// strRecoverFilename 恢复后的明文文件recoverFilename +//返回: 成功与否 +//////////////////////////////////////////////////////////////////////////////// +bool GCrypt::decryptFile(const GString &strRecoverFilename, const GString &strDecFilename) +{ + Q_D(GCrypt); + + return d->m_algorithm->decryptFile(strRecoverFilename, strDecFilename); +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: 设置加密参数,包括加密算法EnAlgorithmKind,加密模式EnEncodeType,填充类型EnPadding +//参数: EnAlgorithmKind 加密算法 +// EnEncodeType 加密模式 +// EnPadding 填充类型 +//返回: 无 +//////////////////////////////////////////////////////////////////////////////// +void GCrypt::setEncodeMode(EnAlgorithmType EnAlgorithmKind, EnEncodeMode EnEncodeType, EnPaddingType EnPadding) +{ + Q_D(GCrypt); + + return d->m_algorithm->setEncodeMode(EnAlgorithmKind, EnEncodeType, EnPadding); +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: 根据内部生成随机的加密密钥并设置 +//返回: 无 +//////////////////////////////////////////////////////////////////////////////// +void GCrypt::setRandomKey() +{ + Q_D(GCrypt); + + return d->m_algorithm->setRandomKey(); +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: 设置加密密钥及长度,此处需要重载,因为CBC模式不需要初始向量iv +//参数: key 秘钥字符串 +// length 秘钥长度 +// iv 初始向量 +//返回: 无 +//////////////////////////////////////////////////////////////////////////////// +void GCrypt::setKey(byte *key, int length, byte *iv) +{ + Q_D(GCrypt); + + return d->m_algorithm->setKey(key, length, iv); +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: 设置加密密钥及长度,此处需要重载,因为CBC模式不需要初始向量iv +//参数: key 秘钥字符串 +// length 秘钥长度 +//返回: 无 +//////////////////////////////////////////////////////////////////////////////// +void GCrypt::setKey(byte *key, int length) +{ + Q_D(GCrypt); + + return d->m_algorithm->setKey(key, length); +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: 获取加密密钥 +//参数: 无 +//返回: 秘钥字符串 +//////////////////////////////////////////////////////////////////////////////// +byte * GCrypt::key() +{ + Q_D(GCrypt); + + return d->m_algorithm->key(); +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.06.5 +//功能: 获取加密初始向量 +//参数: 无 +//返回: 初始向量 +//////////////////////////////////////////////////////////////////////////////// +byte * GCrypt::ivKey() +{ + Q_D(GCrypt); + + return d->m_algorithm->ivKey(); +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDDes.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDDes.cpp new file mode 100644 index 00000000..3e61a8fb --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDDes.cpp @@ -0,0 +1,672 @@ +#include "GLDDes.h" + +#include "GLDZlib.h" +#include "GLDGlobal.h" +#include "GLDXMLUtils.h" +#include "GLDException.h" + +const unsigned char c_DefDESKey[16] = {0xCE, 0xD2, 0xCA, 0xC7, 0xC1, 0xF5, 0xCF, 0xFE, + 0xB6, 0xB0, 0xA3, 0xAC, 0xCE, 0xD2, 0xC5, 0xC2}; + +void initEncryptTripleDES(const GKey128 key, GDESContext *context, bool encrypt); +void encryptTripleDES(GDESContext *context, unsigned char *block); +void encryptDES(GDESContext &context, unsigned char *block); + +#define BLOCK_SIZE 8 + +static const unsigned long c_PBox[8][64] = +{ + {0x01010400, 0x00000000, 0x00010000, 0x01010404, + 0x01010004, 0x00010404, 0x00000004, 0x00010000, + 0x00000400, 0x01010400, 0x01010404, 0x00000400, + 0x01000404, 0x01010004, 0x01000000, 0x00000004, + 0x00000404, 0x01000400, 0x01000400, 0x00010400, + 0x00010400, 0x01010000, 0x01010000, 0x01000404, + 0x00010004, 0x01000004, 0x01000004, 0x00010004, + 0x00000000, 0x00000404, 0x00010404, 0x01000000, + 0x00010000, 0x01010404, 0x00000004, 0x01010000, + 0x01010400, 0x01000000, 0x01000000, 0x00000400, + 0x01010004, 0x00010000, 0x00010400, 0x01000004, + 0x00000400, 0x00000004, 0x01000404, 0x00010404, + 0x01010404, 0x00010004, 0x01010000, 0x01000404, + 0x01000004, 0x00000404, 0x00010404, 0x01010400, + 0x00000404, 0x01000400, 0x01000400, 0x00000000, + 0x00010004, 0x00010400, 0x00000000, 0x01010004}, + + {0x80108020, 0x80008000, 0x00008000, 0x00108020, + 0x00100000, 0x00000020, 0x80100020, 0x80008020, + 0x80000020, 0x80108020, 0x80108000, 0x80000000, + 0x80008000, 0x00100000, 0x00000020, 0x80100020, + 0x00108000, 0x00100020, 0x80008020, 0x00000000, + 0x80000000, 0x00008000, 0x00108020, 0x80100000, + 0x00100020, 0x80000020, 0x00000000, 0x00108000, + 0x00008020, 0x80108000, 0x80100000, 0x00008020, + 0x00000000, 0x00108020, 0x80100020, 0x00100000, + 0x80008020, 0x80100000, 0x80108000, 0x00008000, + 0x80100000, 0x80008000, 0x00000020, 0x80108020, + 0x00108020, 0x00000020, 0x00008000, 0x80000000, + 0x00008020, 0x80108000, 0x00100000, 0x80000020, + 0x00100020, 0x80008020, 0x80000020, 0x00100020, + 0x00108000, 0x00000000, 0x80008000, 0x00008020, + 0x80000000, 0x80100020, 0x80108020, 0x00108000}, + + {0x00000208, 0x08020200, 0x00000000, 0x08020008, + 0x08000200, 0x00000000, 0x00020208, 0x08000200, + 0x00020008, 0x08000008, 0x08000008, 0x00020000, + 0x08020208, 0x00020008, 0x08020000, 0x00000208, + 0x08000000, 0x00000008, 0x08020200, 0x00000200, + 0x00020200, 0x08020000, 0x08020008, 0x00020208, + 0x08000208, 0x00020200, 0x00020000, 0x08000208, + 0x00000008, 0x08020208, 0x00000200, 0x08000000, + 0x08020200, 0x08000000, 0x00020008, 0x00000208, + 0x00020000, 0x08020200, 0x08000200, 0x00000000, + 0x00000200, 0x00020008, 0x08020208, 0x08000200, + 0x08000008, 0x00000200, 0x00000000, 0x08020008, + 0x08000208, 0x00020000, 0x08000000, 0x08020208, + 0x00000008, 0x00020208, 0x00020200, 0x08000008, + 0x08020000, 0x08000208, 0x00000208, 0x08020000, + 0x00020208, 0x00000008, 0x08020008, 0x00020200}, + + {0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802080, 0x00800081, 0x00800001, 0x00002001, + 0x00000000, 0x00802000, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00800080, 0x00800001, + 0x00000001, 0x00002000, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002001, 0x00002080, + 0x00800081, 0x00000001, 0x00002080, 0x00800080, + 0x00002000, 0x00802080, 0x00802081, 0x00000081, + 0x00800080, 0x00800001, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00000000, 0x00802000, + 0x00002080, 0x00800080, 0x00800081, 0x00000001, + 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802081, 0x00000081, 0x00000001, 0x00002000, + 0x00800001, 0x00002001, 0x00802080, 0x00800081, + 0x00002001, 0x00002080, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002000, 0x00802080}, + + {0x00000100, 0x02080100, 0x02080000, 0x42000100, + 0x00080000, 0x00000100, 0x40000000, 0x02080000, + 0x40080100, 0x00080000, 0x02000100, 0x40080100, + 0x42000100, 0x42080000, 0x00080100, 0x40000000, + 0x02000000, 0x40080000, 0x40080000, 0x00000000, + 0x40000100, 0x42080100, 0x42080100, 0x02000100, + 0x42080000, 0x40000100, 0x00000000, 0x42000000, + 0x02080100, 0x02000000, 0x42000000, 0x00080100, + 0x00080000, 0x42000100, 0x00000100, 0x02000000, + 0x40000000, 0x02080000, 0x42000100, 0x40080100, + 0x02000100, 0x40000000, 0x42080000, 0x02080100, + 0x40080100, 0x00000100, 0x02000000, 0x42080000, + 0x42080100, 0x00080100, 0x42000000, 0x42080100, + 0x02080000, 0x00000000, 0x40080000, 0x42000000, + 0x00080100, 0x02000100, 0x40000100, 0x00080000, + 0x00000000, 0x40080000, 0x02080100, 0x40000100}, + + {0x20000010, 0x20400000, 0x00004000, 0x20404010, + 0x20400000, 0x00000010, 0x20404010, 0x00400000, + 0x20004000, 0x00404010, 0x00400000, 0x20000010, + 0x00400010, 0x20004000, 0x20000000, 0x00004010, + 0x00000000, 0x00400010, 0x20004010, 0x00004000, + 0x00404000, 0x20004010, 0x00000010, 0x20400010, + 0x20400010, 0x00000000, 0x00404010, 0x20404000, + 0x00004010, 0x00404000, 0x20404000, 0x20000000, + 0x20004000, 0x00000010, 0x20400010, 0x00404000, + 0x20404010, 0x00400000, 0x00004010, 0x20000010, + 0x00400000, 0x20004000, 0x20000000, 0x00004010, + 0x20000010, 0x20404010, 0x00404000, 0x20400000, + 0x00404010, 0x20404000, 0x00000000, 0x20400010, + 0x00000010, 0x00004000, 0x20400000, 0x00404010, + 0x00004000, 0x00400010, 0x20004010, 0x00000000, + 0x20404000, 0x20000000, 0x00400010, 0x20004010}, + + {0x00200000, 0x04200002, 0x04000802, 0x00000000, + 0x00000800, 0x04000802, 0x00200802, 0x04200800, + 0x04200802, 0x00200000, 0x00000000, 0x04000002, + 0x00000002, 0x04000000, 0x04200002, 0x00000802, + 0x04000800, 0x00200802, 0x00200002, 0x04000800, + 0x04000002, 0x04200000, 0x04200800, 0x00200002, + 0x04200000, 0x00000800, 0x00000802, 0x04200802, + 0x00200800, 0x00000002, 0x04000000, 0x00200800, + 0x04000000, 0x00200800, 0x00200000, 0x04000802, + 0x04000802, 0x04200002, 0x04200002, 0x00000002, + 0x00200002, 0x04000000, 0x04000800, 0x00200000, + 0x04200800, 0x00000802, 0x00200802, 0x04200800, + 0x00000802, 0x04000002, 0x04200802, 0x04200000, + 0x00200800, 0x00000000, 0x00000002, 0x04200802, + 0x00000000, 0x00200802, 0x04200000, 0x00000800, + 0x04000002, 0x04000800, 0x00000800, 0x00200002}, + + {0x10001040, 0x00001000, 0x00040000, 0x10041040, + 0x10000000, 0x10001040, 0x00000040, 0x10000000, + 0x00040040, 0x10040000, 0x10041040, 0x00041000, + 0x10041000, 0x00041040, 0x00001000, 0x00000040, + 0x10040000, 0x10000040, 0x10001000, 0x00001040, + 0x00041000, 0x00040040, 0x10040040, 0x10041000, + 0x00001040, 0x00000000, 0x00000000, 0x10040040, + 0x10000040, 0x10001000, 0x00041040, 0x00040000, + 0x00041040, 0x00040000, 0x10041000, 0x00001000, + 0x00000040, 0x10040040, 0x00001000, 0x00041040, + 0x10001000, 0x00000040, 0x10000040, 0x10040000, + 0x10040040, 0x10000000, 0x00040000, 0x10001040, + 0x00000000, 0x10041040, 0x00040040, 0x10000040, + 0x10040000, 0x10001000, 0x10001040, 0x00000000, + 0x10041040, 0x00041000, 0x00041000, 0x00001040, + 0x00001040, 0x00040040, 0x10000000, 0x10041000} +}; + +/*----------------------------------------------------------------------------- + 设计:Linc 2006.04.12 + 功能:初始化 + 参数: +-------------------------------------------------------------------------------*/ +void initEncryptDES(GKey64 key, GDESContext *context, bool encrypt) +{ + const static byte PC1[56] = {56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, + 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, + 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, + 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3}; + + const static byte PC2[48] = {13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 22, 18, 11, 3, + 25, 7, 15, 6, 26, 19, 12, 1, 40, 51, 30, 36, 46, 54, 29, 39, + 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31}; + + const static byte CTotRot[16] = {1, 2, 4, 6, 8, 10, 12, 14, + 15, 17, 19, 21, 23, 25, 27, 28}; + + const static byte CBitMask[8] = {128, 64, 32, 16, 8, 4, 2, 1}; + + byte PC1M[56] = {0}; + byte PC1R[56] = {0}; + byte KS[8] = {0}; + + /*convert PC1 to bits of key*/ + for (int j = 0; j <= 55; j++) + { + const int c_L = PC1[j]; + const int c_M = c_L % 8; + PC1M[j] = int((key[c_L / 8] & CBitMask[c_M]) != 0); + } + + /*key chunk for each iteration*/ + for (int i = 0; i <= 15; i++) + { + int nL = 0; + /*rotate PC1 the right amount*/ + for (int j = 0; j <= 27; j++) + { + nL = j + CTotRot[i]; + if (nL < 28) + { + PC1R[j] = PC1M[nL]; + PC1R[j + 28] = PC1M[nL + 28]; + } + else + { + PC1R[j] = PC1M[nL - 28]; + PC1R[j + 28] = PC1M[nL]; + } + } + + /*select bits individually*/ + memset((void*) KS, 0, sizeof(KS)); + for (int j = 0; j <= 47; j++) + { + if (0 != PC1R[PC2[j]]) + { + nL = j / 6; + KS[nL] = KS[nL] | CBitMask[j % 6] >> 2; + } + } + /*now convert to odd/even interleaved form for use in F*/ + if (encrypt) + { + context->transformedKey[i * 2] + = (int(KS[0]) << 24) | (int(KS[2]) << 16) | (int(KS[4]) << 8) | (int(KS[6])); + context->transformedKey[i * 2 + 1] + = (int(KS[1]) << 24) | (int(KS[3]) << 16) | (int(KS[5]) << 8) | (int(KS[7])); + } + else + { + context->transformedKey[31 - (i * 2 + 1)] + = (int(KS[0]) << 24) | (int(KS[2]) << 16) | (int(KS[4]) << 8) | (int(KS[6])); + context->transformedKey[31 - (i * 2)] + = (int(KS[1]) << 24) | (int(KS[3]) << 16) | (int(KS[5]) << 8) | (int(KS[7])); + } + } + context->encrypt = encrypt; +} + +/*----------------------------------------------------------------------------- + 设计:Linc 2006.06.15 + 功能:初始化 3DES + 参数: +-------------------------------------------------------------------------------*/ +void initEncryptTripleDES(const GKey128 key, GDESContext *context, bool encrypt) +{ + unsigned char keyArray[2][8]; // = {0}; + for (int i = 0; i < 8; i++) + { + keyArray[0][i] = key[i]; + } + for (int i = 0; i < 8; i++) + { + keyArray[1][i] = key[i + 8]; + } + if (encrypt) + { + initEncryptDES(keyArray[0], &context[0], true); + initEncryptDES(keyArray[1], &context[1], false); + } + else + { + initEncryptDES(keyArray[0], &context[0], false); + initEncryptDES(keyArray[1], &context[1], true); + } +} + +/*----------------------------------------------------------------------------- + 设计:Linc 2006.06.15 + 功能:加密 3DES + 参数: +-------------------------------------------------------------------------------*/ +void encryptTripleDES(GDESContext *context, unsigned char *block) +{ + encryptDES(context[0], block); + encryptDES(context[1], block); + encryptDES(context[0], block); +} + +void splitBlock(const unsigned char *block, unsigned long &L, unsigned long &R) +{ + L = (unsigned int)(block[0] << 24) | (block[1] << 16) | (block[2] << 8) | (block[3]); + R = (unsigned int)(block[4] << 24) | (block[5] << 16) | (block[6] << 8) | (block[7]); +} + +void joinBlock(const int L, const int R, unsigned char *block) +{ + block[0] = (unsigned int)(R >> 24) & 0xFF; + block[1] = (unsigned int)(R >> 16) & 0xFF; + block[2] = (unsigned int)(R >> 8) & 0xFF; + block[3] = (unsigned int)R & 0xFF; + block[4] = (unsigned int)(L >> 24) & 0xFF; + block[5] = (unsigned int)(L >> 16) & 0xFF; + block[6] = (unsigned int)(L >> 8) & 0xFF; + block[7] = (unsigned int)L & 0xFF; +} + +void iPerm(unsigned long &L, unsigned long &R) +{ + unsigned long uWork(0); + uWork = ((L >> 4) ^ R) & 0x0F0F0F0F; + R = R ^ uWork; + L = L ^ uWork << 4; + uWork = ((L >> 16) ^ R) & 0x0000FFFF; + R = R ^ uWork; + L = L ^ uWork << 16; + uWork = ((R >> 2) ^ L) & 0x33333333; + L = L ^ uWork; + R = R ^ uWork << 2; + uWork = ((R >> 8) ^ L) & 0x00FF00FF; + L = L ^ uWork; + R = R ^ uWork << 8; + R = (unsigned int)(R << 1) | (unsigned int)(R >> 31); + uWork = (L ^ R) & 0xAAAAAAAA; + L = L ^ uWork; + R = R ^ uWork; + L = (L << 1) | (L >> 31); +} + +void fPerm(unsigned long &L, unsigned long &R) +{ + R = (unsigned int)(R << 31) | (R >> 1); + unsigned long uWork = (unsigned int)(L ^ R) & 0xAAAAAAAA; + L = (unsigned int)L ^ uWork; + R = (unsigned int)R ^ uWork; + L = (L >> 1) | (unsigned int)(L << 31); + uWork = ((L >> 8) ^ R) & 0x00FF00FF; + R = R ^ uWork; + L = L ^ uWork << 8; + uWork = ((L >> 2) ^ R) & 0x33333333; + R = R ^ uWork; + L = L ^ uWork << 2; + uWork = ((unsigned int)(R >> 16) ^ L) & 0x0000FFFF; + L = L ^ uWork; + R = R ^ (unsigned int)(uWork << 16); + uWork = ((R >> 4) ^ L) & 0x0F0F0F0F; + L = L ^ uWork; + R = (unsigned int)R ^ uWork << 4; +} + +void encryptDES(GDESContext &context, unsigned char *block) +{ + unsigned long uLeft = 0; + unsigned long uRight = 0; + splitBlock(block, uLeft, uRight); + iPerm(uLeft, uRight); + unsigned long *cPtr = context.transformedKey; + for (unsigned i = 0; i <= 7; ++i) + { + unsigned long uWork = (unsigned int)((uRight >> 4) | (unsigned int)(uRight << 28)) ^ (*cPtr); + cPtr++; + uLeft = (unsigned int)(uLeft) ^ c_PBox[6][uWork & 0x3F]; + uLeft = (unsigned int)uLeft ^ c_PBox[4][uWork >> 8 & 0x3F]; + uLeft = (unsigned int)uLeft ^ c_PBox[2][uWork >> 16 & 0x3F]; + uLeft = (unsigned int)uLeft ^ c_PBox[0][uWork >> 24 & 0x3F]; + uWork = ((unsigned int)uRight ^ (*cPtr)); + cPtr++; + uLeft = uLeft ^ c_PBox[7][uWork & 0x3F]; + uLeft = uLeft ^ c_PBox[5][uWork >> 8 & 0x3F]; + uLeft = uLeft ^ c_PBox[3][uWork >> 16 & 0x3F]; + uLeft = uLeft ^ c_PBox[1][uWork >> 24 & 0x3F]; + uWork = (((uLeft >> 4) | (unsigned int)(uLeft << 28)) ^ (*cPtr)); + cPtr++; + uRight = uRight ^ c_PBox[6][uWork & 0x3F]; + uRight = uRight ^ c_PBox[4][uWork >> 8 & 0x3F]; + uRight = uRight ^ c_PBox[2][uWork >> 16 & 0x3F]; + uRight = uRight ^ c_PBox[0][uWork >> 24 & 0x3F]; + uWork = (uLeft ^ (*cPtr)); + cPtr++; + uRight = uRight ^ c_PBox[7][uWork & 0x3F]; + uRight = uRight ^ c_PBox[5][uWork >> 8 & 0x3F]; + uRight = uRight ^ c_PBox[3][uWork >> 16 & 0x3F]; + uRight = uRight ^ c_PBox[1][uWork >> 24 & 0x3F]; + } + fPerm(uLeft, uRight); + joinBlock(uLeft, uRight, block); +} + +/////////////////////////////////////////////////////////////////////////////// +//设计:Linc 2006.06.15 +//功能:DES 加密 +//参数: +//注意:只处理长度是 8 倍数的 +//////////////////////////////////////////////////////////////////////////////// +//unsigned char* DES(const unsigned char* inString, int inSize, const unsigned char* key64, bool encrypt) +//{ +// assert((inSize / 8) == 0); +// unsigned char* result = new unsigned char[inSize + 1]; +// memcpy(result, inString, inSize); +// result[inSize] = '\0'; +// DES(result, inSize, key64, encrypt); +// return result; +//} + +/////////////////////////////////////////////////////////////////////////////// +//设计:Linc 2006.06.15 +//功能:DES 加密 +//参数: +//注意:只处理长度是 8 倍数的 +//////////////////////////////////////////////////////////////////////////////// +unsigned char* DES(const unsigned char* inString, int inSize, GKey64 key64, bool encrypt) +{ + assert((inSize % 8) == 0); + if (inSize == 0) + { + return NULL; + } + unsigned char* buffer = new unsigned char[inSize + 1]; + memcpy(buffer, inString, inSize); + buffer[inSize] = '\0'; + unsigned char* temp = buffer; + + GDESContext context; + initEncryptDES(key64, &context, encrypt); + + unsigned long uBlockCount = inSize >> 3; + while (uBlockCount > 0) + { + encryptDES(context, buffer); + buffer += 8; + uBlockCount--; + } + return temp; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计:Linc 2006.04.12 +//功能:DES 处理字符 +//参数: +//////////////////////////////////////////////////////////////////////////////// +unsigned char* DESEncrypt(const unsigned char* inString, int inSize, GKey64 key64, bool encrypt) +{ + GBlockMemoryStream inStream; + inStream.write((const char*)inString, inSize); + inStream.seek(0); + GBlockMemoryStream outStream; + DESEncryptStream(&inStream, &outStream, key64, encrypt); + outStream.seek(0); + unsigned char* result = new unsigned char[outStream.size() + 1]; + outStream.read((char*)result, outStream.size()); + result[outStream.size()] = '\0'; + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计:Linc 2006.04.12 +//功能:DES 处理数据流 +//参数: +//////////////////////////////////////////////////////////////////////////////// +void DESEncryptStream(GStream *inStream, GStream *outStream, GKey64 key64, bool encrypt) +{ + unsigned long uIterator = 0; + unsigned char block[BLOCK_SIZE + 1]; + memset(block, '\0', BLOCK_SIZE + 1); + GDESContext context; + + initEncryptDES(key64, &context, encrypt); + + unsigned long uBlockCount = inStream->size() / BLOCK_SIZE; + + if (encrypt) + { + uBlockCount++; + } + + for (uIterator = 1; uIterator <= uBlockCount - 1; ++uIterator) + { + if (inStream->read((char*)block, BLOCK_SIZE) != BLOCK_SIZE) + { + throw GLDException(""); + } + encryptDES(context, block); + outStream->write((char*)block, BLOCK_SIZE); + } + + if (encrypt) + { + memset(block, '\0', BLOCK_SIZE + 1); + + uIterator = (inStream->size() % BLOCK_SIZE); + if ((unsigned long)inStream->read((char*)block, uIterator) != uIterator) + { + throw GLDException(""); + } + + block[BLOCK_SIZE - 1] = uIterator; + + encryptDES(context, block); + outStream->write((char*)block, BLOCK_SIZE); + } + else + { + if (inStream->read((char*)block, BLOCK_SIZE) != BLOCK_SIZE) + { + throw GLDException(""); + } + encryptDES(context, block); + + uIterator = block[BLOCK_SIZE - 1]; + + outStream->write((char*)block, uIterator); + } +} + +//////////////////////////////////////////////////////////////////////////////// +//设计:Linc 2006.06.15 +//功能:DES 加密 +//参数: +//注意:只处理长度是 8 倍数的 +//////////////////////////////////////////////////////////////////////////////// +unsigned char* tripleDES(unsigned char* inString, int inSize, const GKey128 key128, bool encrypt) +{ + if ((inString == NULL) || (inSize == 0)) + return NULL; + unsigned char* buffer = new unsigned char[inSize + 1]; + memcpy(buffer, inString, inSize); + buffer[inSize] = '\0'; + unsigned char* temp = buffer; + + GDESContext context[2]; + + assert((inSize & 0x7) == 0); + + initEncryptTripleDES(key128, context, encrypt); + int nBlockCount = inSize >> 3; + while (nBlockCount > 0) + { + encryptTripleDES(context, buffer); + buffer += 8; + nBlockCount--; + } + return temp; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计:Linc 2006.04.12 +//功能:3DES 处理字符 +//参数: +//////////////////////////////////////////////////////////////////////////////// +unsigned char* tripleDESEncrypt(const unsigned char* inString, int inSize, GKey128 key128, bool encrypt) +{ + GBlockMemoryStream inStream; + inStream.write((const char*)inString, inSize); + inStream.seek(0); + GBlockMemoryStream outStream; + tripleDESEncryptStream(&inStream, &outStream, key128, encrypt); + outStream.seek(0); + unsigned char* result = new unsigned char[outStream.size() + 1]; + outStream.read((char*)result, outStream.size()); + result[outStream.size()] = '\0'; + return result; +} + +/*----------------------------------------------------------------------------- + 设计:Linc 2006.04.12 + 功能:3DES 处理数据流 + 参数: +-------------------------------------------------------------------------------*/ +void tripleDESEncryptStream(GStream *inStream, GStream *outStream, const GKey128 key128, bool encrypt) +{ + unsigned char block[BLOCK_SIZE + 1]; + memset(block, '\0', BLOCK_SIZE + 1); + GDESContext context[2]; + initEncryptTripleDES(key128, context, encrypt); + + /*get the number of blocks in the file*/ + int nBlockCount = ((inStream->size() - inStream->pos()) / BLOCK_SIZE); + + /*when encrypting, make sure we have a block with at least one free*/ + /*byte at the end. used to store the odd byte count value*/ + if (encrypt) + { + nBlockCount++; + } + + /*process all except the last block*/ + for (int i = 1; i != nBlockCount; i++) + { + if (inStream->read((char *)block, BLOCK_SIZE) != BLOCK_SIZE) + { + throw GLDException(""); + } + encryptTripleDES(context, block); + outStream->write((char *)block, BLOCK_SIZE); + } + if (encrypt) + { + memset(block, '\0', BLOCK_SIZE + 1); + /*set actual number of bytes to read*/ + unsigned int uActual = (inStream->size() % BLOCK_SIZE); + if (inStream->read((char *)block, uActual) != uActual) + { + throw GLDException(""); + } + + /*store number of last(bytes) byte in last block*/ + + // byte (*pByteArray)[32768] = █ + // (*pByteArray)[BLOCK_SIZE - 1] = i; + block[BLOCK_SIZE - 1] = uActual; + + /*encrypt and save full block*/ + encryptTripleDES(context, block); + outStream->write((char *)block, BLOCK_SIZE); + } + else + { + /*encrypted file is always a multiple of the block size*/ + if (inStream->read((char *)block, BLOCK_SIZE) != BLOCK_SIZE) + { + throw GLDException(""); + } + encryptTripleDES(context, block); + + /*get actual number of bytes encoded*/ + unsigned int uLast = block[BLOCK_SIZE - 1]; + + /*save valid portion of block*/ + outStream->write((char *)block, uLast); + } +} + +//////////////////////////////////////////////////////////////////////////////// +//设计:Linc 2006.07.07 +//功能:重叠 DES 加密算法 +//参数: +//注意:要求长度必须 >= 8 且长度为 8 的倍数时和 DES 处理结果相同 +//////////////////////////////////////////////////////////////////////////////// +void overlapDES(unsigned char* inString, int inSize, GKey64 key64, bool encrypt) +{ + unsigned char* pData = inString; + + if (!inString || (inSize < 8)) + { + return; + } + + int nCount = inSize / 8; + int nDelta = inSize % 8; + + if ((!encrypt) && (nDelta != 0)) + { + pData += inSize - 8; + unsigned char* pResult = DES(pData, 8, key64, encrypt); + for (int j = 0; j < 8; ++j) + { + pData[j] = pResult[j]; + } + freeAndNil(pResult); + pData = inString; + } + for (int i = 0; i < nCount; ++i) + { + unsigned char* pResult = DES(pData, 8, key64, encrypt); + for (int j = 0; j < 8; ++j) + { + pData[j] = pResult[j]; + } + freeAndNil(pResult); + + pData += 8; + } + if (encrypt && (nDelta != 0)) + { + pData = inString; + pData += inSize - 8; + unsigned char* pResult = DES(pData, 8, key64, encrypt); + for (int j = 0; j < 8; ++j) + { + pData[j] = pResult[j]; + } + freeAndNil(pResult); + } +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDDrawSymbol.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDDrawSymbol.cpp new file mode 100644 index 00000000..f58601e8 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDDrawSymbol.cpp @@ -0,0 +1,678 @@ +#include "GLDDrawSymbol.h" +#include "GLDStrUtils.h" +#include "GLDGlobal.h" + +#include +#include +#include + +GlodonCustomDrawSymbol *GlodonMeterDrawSymbolFactory::create() +{ + return new GlodonMeterDrawSymbol(); +} + +GlodonCustomDrawSymbol *GlodonDiaDrawSymbolFactory::create() +{ + return new GlodonDiaDrawSymbol(); +} + +bool GlodonMeterDrawSymbol::canHandle(const QString &text) +{ + return includeM2M3(text) || includeSharp(text); +} + +int GlodonMeterDrawSymbol::calcDrawLineLength(QPainter *painter, const QString &text, int &width) +{ + int result = 0; + QString strSubStr; + int nx, nWidth, nIndex, nLength; + nx = width; + nWidth = 0; + nIndex = 0; + nLength = text.length(); + while (nIndex < nLength) + { + if ((text.at(nIndex) == QChar::LineFeed)) + { + result = nIndex + 1; + width -= nx; + return result; + } + strSubStr = text.at(nIndex); + nIndex++; +// if (nIndex < nLength) +// { +// strSubStr = strSubStr + text.at(nIndex); +// nIndex ++; +// } + if (isTextM2M3(strSubStr)) + { + nWidth = calcM2M3Length(painter); + } + else + { + nWidth = painter->fontMetrics().width(strSubStr); + } + if (nWidth <= nx) + { + nx -= nWidth; + } + else + break; + } + width -= nx; + if (nWidth < nx) + { + result = nLength; + } + else + { + nIndex--; + result = nIndex - 1; + } + return result; +} + +int GlodonMeterDrawSymbol::calcDrawTextLength(QPainter *painter, const QString &text, int width, int height) +{ + return painter->fontMetrics().width(text); + G_UNUSED(height); + G_UNUSED(width); +} + +int GlodonMeterDrawSymbol::calcM2M3Length(QPainter *painter) +{ + int nSize, result; + nSize = painter->font().pointSize(); + result = painter->fontMetrics().width(c_MeterSymbol); + QFont tempFont = painter->font(); + tempFont.setPointSize(ceil(c_SuperScale * nSize)); + painter->setFont(tempFont); + result = result + painter->fontMetrics().width(c_SuperSymbol); + tempFont = painter->font(); + tempFont.setPointSize(nSize); + + painter->setFont(tempFont); + return result; +} + +void GlodonMeterDrawSymbol::drawText(QPainter *painter, int scale, const QString &text, + Qt::Alignment align, QRect &rect) +{ + QString strText; + int nHeight = 0; + strText = replaceSymbolText(text); + interDrawText(painter, strText, align, rect.left(), rect.top(), rect.right() - rect.left(), nHeight); + G_UNUSED(scale); +} + +bool GlodonMeterDrawSymbol::isTextM2M3(const QString &text) +{ + return sameText(text, c_SquareReplace) || sameText(text, c_CubeReplace); +} + +bool GlodonMeterDrawSymbol::isTextSharp(const QString &text) +{ + return text == c_SharpReplace; +} + +QString GlodonMeterDrawSymbol::replaceSymbolText(const QString &text) +{ + QString result = text; + result.replace("m2", c_SquareReplace); + result.replace("M2", c_SquareReplace); + result.replace("m3", c_CubeReplace); + result.replace("M3", c_CubeReplace); + return result; +} + +void GlodonMeterDrawSymbol::drawLine(QPainter *painter, const QString &text, int x, int y, int &width, int &height) +{ + int nWidth; + int nHeight; + width = 0; + height = 0; + int nx = x; + int ny = y; + int nIndex= 0; + int nLength = text.length(); + QString strSubStr; + while (nIndex < nLength) + { + strSubStr = text.at(nIndex); + nIndex++; +// if (nIndex < nLength) +// { +// strSubStr = strSubStr + text.at(nIndex); +// nIndex ++; +// } + if (isTextM2M3(strSubStr)) + { + drawM2M3(painter, nx, ny, strSubStr); + nWidth = calcM2M3Length(painter); + } + else if (isTextSharp(strSubStr)) + { + drawSharp(painter, nx, ny, strSubStr); + } + else + { + int nyPosition = ny + painter->fontMetrics().boundingRect(strSubStr).height(); + painter->drawText(nx, nyPosition, strSubStr); + nWidth = painter->fontMetrics().width(strSubStr); + } + nHeight = painter->fontMetrics().boundingRect(strSubStr).height();//ACavas.TextHeight(strSubStr); + nx += nWidth; + height = qMax(height, nHeight); + } + width = nx - x; +} + +void GlodonMeterDrawSymbol::drawM2M3(QPainter *painter, int x, int y, const QString &symbol) +{ + int nx, nSize; + QString strSuper; + int nyPosition = y + painter->fontMetrics().boundingRect(symbol).height(); + if (sameText(symbol, c_SquareReplace)) + { + strSuper = c_SquareSymbol; + } + else if (sameText(symbol, c_CubeReplace)) + { + strSuper = c_CubeSymbol; + } + else + { + painter->drawText(x, nyPosition, symbol); + } + nyPosition = y + painter->fontMetrics().boundingRect(c_MeterSymbol).height(); + painter->drawText(x, nyPosition, c_MeterSymbol); + nx = x + painter->fontMetrics().width(c_MeterSymbol); + QFont tempFont = painter->font(); + nSize = painter->font().pointSize(); + tempFont.setPointSize(c_SharpScale * nSize); + painter->save(); + painter->setFont(tempFont); + nyPosition = y + painter->fontMetrics().boundingRect(strSuper).height(); + painter->drawText(nx, nyPosition, strSuper); + painter->restore(); +} + +void GlodonMeterDrawSymbol::drawSharp(QPainter *painter, int x, int y, const QString &symbol) +{ + int nSize; + QString strSuper; + int nyPosition = y + painter->fontMetrics().boundingRect(symbol).height(); + if (sameText(symbol, c_SharpReplace)) + { + strSuper = c_SharpReplace; + } + else + { + + painter->drawText(x, nyPosition, symbol); + } + nSize = painter->font().pointSize(); + QFont tempFont = painter->font(); + tempFont.setPointSize(c_SharpScale * nSize); + painter->save(); + painter->setFont(tempFont); + nyPosition = y + painter->fontMetrics().boundingRect(strSuper).height(); + painter->drawText(x, nyPosition, strSuper); + tempFont.setPointSize(nSize); + painter->setFont(tempFont); + painter->restore(); +} + +void GlodonMeterDrawSymbol::interDrawText(QPainter *painter, const QString &text, + Qt::Alignment align, int x, int y, int width, int &height) +{ + QString strText, strSubStr; + int nx, ny, nWidth, nHeight, nSize; + height = 0; + strText = text; + nx = x; + ny = y; + nWidth = width; + nHeight = 0; + nSize = calcDrawLineLength(painter, strText, nWidth); + while (nSize != 0) + { + if (align & Qt::AlignLeft) + { + nx = x; + } + else if (align & Qt::AlignRight) + { + nx = x + (width - nWidth); + } + else + { + nx = x + (width - nWidth) / 2; + } + ny += nHeight; + strSubStr = strText.mid(0, nSize); + drawLine(painter, trimRight(strSubStr), nx, ny, nWidth, nHeight);; + height += nHeight; + strText.remove(0, nSize); + nWidth = width; + nSize = calcDrawLineLength(painter, strText, nWidth); + } +} + +bool GlodonDiaDrawSymbol::canHandle(const QString &text) +{ + return includeDiaSymbol(text); +} + +int GlodonDiaDrawSymbol::getContentWidth(QPainter *painter, int scale, const QString &text) +{ + GObjectList *list = createIndexOfDiameterSymbolList(text); + // 计算文字和钢筋符号的宽度 + int nWidth = 0; + int nIndex = 0; + while (nIndexcount(); ++nSymbol) + { + if (nIndex == list->at(nSymbol)->pos) + { + bSymbol = true; + QString strResource = c_DiameterSymbols[nSymbol].resourceName; + QPixmap pixmap(":/icons/" + strResource); + nWidth = nWidth + pixmap.width() * scale / 100; + nIndex = list->at(nSymbol)->pos + c_DiameterSymbols[list->at(nSymbol)->symbolPosIndex].symbol.length(); + } + } + if (!bSymbol) + { + nWidth = nWidth + painter->fontMetrics().width(text.at(nIndex)); + nIndex++; + } + } + freeAndNil(list); + return nWidth; +} + +int GlodonDiaDrawSymbol::getContentHeight(QPainter *painter, int scale, const QString &text) +{ + GObjectList *list = createIndexOfDiameterSymbolList(text); + // 计算文字和钢筋符号的宽度 + int nSymBolHeight = 0; + int nTextHeight = 0; + int nIndex = 0; + while (nIndexcount(); ++nSymbol) + { + if (nIndex == list->at(nSymbol)->pos) + { + bSymbol = true; + QString strResource = c_DiameterSymbols[nSymbol].resourceName; + QPixmap pixmap(":/icons/" + strResource); + if (pixmap.height() * scale / 100 > nSymBolHeight) + { + nSymBolHeight = pixmap.height() * scale / 100; + } + nIndex = list->at(nSymbol)->pos + c_DiameterSymbols[list->at(nSymbol)->symbolPosIndex].symbol.length(); + } + } + if (nIndex < text.length()) + { + if (painter->fontMetrics().width(text.at(nIndex)) > nTextHeight) + { + nTextHeight = painter->fontMetrics().height(); + } + } + nIndex++; + } + freeAndNil(list); + return (nSymBolHeight > nTextHeight) ? nSymBolHeight : nTextHeight; +} + +void GlodonDiaDrawSymbol::draw(QPainter *painter, int scale, const QString &text, + Qt::Alignment align, QRect &rect) +{ + int nPos; + QRect cRect; + QString strText; + GObjectList *list = createIndexOfDiameterSymbolList(text); + + try + { + cRect = rect; + nPos = 0; + int nContentWidth = getContentWidth(painter, scale, text); + int nContentHeight = getContentHeight(painter, scale, text); + + // 根据对齐方式设置开始画的位置 + // 先做横向判断 + if (align & Qt::AlignLeft) + { + // DO NOthing + } + else if (align & Qt::AlignRight) + { + cRect.setLeft(rect.right() - nContentWidth); + } + else if (align & Qt::AlignHCenter) + { + cRect.setLeft((rect.left() + rect.right() - nContentWidth) / 2); + } + // 再做纵向判断 + if (align & Qt::AlignTop) + { + // DO NOthing + } + else if (align & Qt::AlignBottom) + { + cRect.setTop(rect.bottom() - nContentHeight); + } + else if (align & Qt::AlignVCenter) + { + cRect.setTop((rect.bottom() + rect.top() - nContentHeight) / 2); + cRect.setBottom((rect.bottom() + rect.top() + nContentHeight) / 2); + } + + // 开始画文本和钢筋符号的图片 + for (int i = 0; i < list->count(); ++i) + { + if (nPos <= list->at(i)->pos) + { + strText = copy(text, nPos, list->at(i)->pos - nPos); + cRect.setRight(rect.right()); + innerDrawText(painter, align, cRect, strText); + cRect.setLeft(cRect.left() + painter->fontMetrics().width(strText)); + nPos = list->at(i)->pos + c_DiameterSymbols[list->at(i)->symbolPosIndex].symbol.length(); + drawBitMap(painter, scale, align, cRect, list->at(i)->symbolPosIndex); + } + } + if (nPos <= text.length()) + { + strText = copy(text, nPos, MaxInt); + cRect.setRight(rect.right()); + innerDrawText(painter, align, cRect, strText); + } + } + catch (...) + { + freeAndNil(list); + throw; + } + freeAndNil(list); +} + +void GlodonDiaDrawSymbol::drawText(QPainter *painter, int scale, const QString &text, + Qt::Alignment align, QRect &rect) +{ + draw(painter, scale, text, align, rect); +} + +void GlodonDiaDrawSymbol::draw1Symbol(QPainter *painter, int scale, const QString &text, + Qt::Alignment align, QRect &rect, int index) +{ + QRect cRect; + QString strResource, strText; + strResource = c_DiameterSymbols[index].resourceName; + QPixmap pixmap(":/icons/" + strResource); + pixmap.setMask(pixmap.createMaskFromColor(Qt::white)); + if (!pixmap.isNull()) + { + cRect = rect; + int nContentWidth = getContentWidth(painter, scale, text); + if (align & Qt::AlignLeft) + { + // DO NOthing + } + else if (align & Qt::AlignRight) + { + cRect.setLeft(rect.right() - nContentWidth); + } + else + { + cRect.setLeft((rect.left() + rect.right() - nContentWidth) / 2); + } + + cRect.setRight(cRect.left() + pixmap.width() * scale / 100); + cRect.setTop((cRect.top() + cRect.bottom() - pixmap.height()) / 2); + cRect.setBottom(cRect.top() + pixmap.height() * scale / 100); + painter->setBackgroundMode(Qt::TransparentMode); + painter->drawPixmap(cRect, pixmap); + } + strText = copy(text, c_DiameterSymbols[index].symbol.length(), MaxInt); + if (strText != "") + { + if (align & Qt::AlignRight) + { + cRect.setRight(cRect.left()); + cRect.setLeft(rect.left()); + } + else + { + cRect.setLeft(cRect.right()); + cRect.setRight(rect.right()); + } + cRect.setTop((cRect.top() + cRect.bottom() - pixmap.height()) / 2); + cRect.setBottom(rect.bottom()); + painter->drawText(cRect, strText); + } +} + +void GlodonDiaDrawSymbol::drawBitMap(QPainter *painter, int scale, Qt::Alignment align, QRect &rect, int index) +{ + QString strResource = c_DiameterSymbols[index].resourceName; + QPixmap pixmap(":/icons/" + strResource); + pixmap.setMask(pixmap.createMaskFromColor(Qt::white)); + + QRect symBolRect = rect; + + if (pixmap.isNull()) + { + return; + } + else + { + symBolRect.setRight(symBolRect.left() + pixmap.width() * scale / 100); + symBolRect.setBottom(symBolRect.top() + pixmap.height() * scale / 100); + painter->setBackgroundMode(Qt::TransparentMode); + painter->drawPixmap(symBolRect, pixmap); + rect.setLeft(symBolRect.right()); + } + G_UNUSED(align); +} + +void GlodonDiaDrawSymbol::innerDrawText(QPainter *painter, Qt::Alignment align, QRect &rect, const QString &text) +{ + if (text != "") + { + painter->drawText(rect, text); + } + G_UNUSED(align); +} + +GObjectList *createIndexOfDiameterSymbolList(const QString &text) +{ + int nIndex, nPos; + GlodonSymbolPos *pSymbolPos = NULL; + GObjectList *list = new GObjectList(); + for (int i = 0; i < int(sizeof(c_DiameterSymbols) / sizeof(c_DiameterSymbols[0])); ++i) + { + nIndex = 0; + nPos = pos(c_DiameterSymbols[i].symbol, text, nIndex);//rPosEx(c_DiameterSymbols[i].symbol, text, nIndex); + + while (nPos > -1) + { + pSymbolPos = new GlodonSymbolPos; + pSymbolPos->pos = nPos; + pSymbolPos->symbolPosIndex = i; + list->push_back(pSymbolPos); + nIndex = nPos + c_DiameterSymbols[i].symbol.length() - 1; + nPos = pos(c_DiameterSymbols[i].symbol, text, nIndex);//rPosEx(c_DiameterSymbols[i].symbol, text, nIndex); + } + } + if (list->count() > 0) + { + qSort(list->list().begin(), list->list().end(), compare); + } + return list; +} + +bool compare(GlodonSymbolPos *item1, GlodonSymbolPos *item2) +{ + if (item1->pos > item2->pos) + { + return false; + } + else + { + return true; + } +} + +void drawDiaSymbol(QPainter *painter, int scale, const QString &text, Qt::Alignment align, QRect &rect) +{ + GlodonDiaDrawSymbol diaDrawSymbol; + diaDrawSymbol.drawText(painter, scale, text, align, rect); +} + +bool includeM2M3(const QString &text) +{ + return text.contains("m2") || text.contains("M2") || text.contains("m3") || text.contains("M3"); +} + +void drawTextMx(QPainter *painter, const QString &text, Qt::Alignment align, QRect &rect) +{ + GlodonMeterDrawSymbol cDrawSymbol; + cDrawSymbol.drawText(painter, 100, text, align, rect); +} + +bool includeSharp(const QString &text) +{ + return text.contains("#"); +} + +bool includeDiaSymbol(const QString &text) +{ + GObjectList *list = NULL; + bool result; + try + { + list = createIndexOfDiameterSymbolList(text); + result = list->count() > 0; + } + catch (...) + { + freeAndNil(list); + throw; + } + freeAndNil(list); + return result; +} + +GlodonCustomDrawSymbol::GlodonCustomDrawSymbol(QObject *parent) +{ + G_UNUSED(parent); +} + +#ifdef _FONTSYMBOL_ +GlodonSymbols::GlodonSymbols() +{ + initSymbols(c_DiameterSymbols, + sizeof(c_DiameterSymbols)/sizeof(GlodonDiameterSymbolRec)); +} + +QString GlodonSymbols::aliasFromDisplaySymbol(const QString &displaySymbol) +{ + if (displaySymbol.isEmpty()) + { + return ""; + } + + QString alias = m_symbols.key(displaySymbol); + return m_symbols.contains(alias) ? alias : displaySymbol; +} + +QString GlodonSymbols::displaySymbolFromAlias(const QString &alias) +{ + if (alias.isEmpty()) + { + return ""; + } + + return m_symbols.contains(alias) ? m_symbols.value(alias) : alias; +} + +QMap GlodonSymbols::allSymbols() const +{ + return m_symbols; +} + +QString GlodonSymbols::aliasesFromDisplaySymbols(const QString &displaySymbols) +{ + QStringList displaySymbolList; + QString aliases; + // 将钢筋符号串拆分放到list中 + for (int i = 0; i < displaySymbols.length(); ++i) + { + displaySymbolList.push_back(displaySymbols.mid(i, 1)); + } + // 再将钢筋符号的别名加到串中 + foreach (QString subSymbol, displaySymbolList) + { + aliases += aliasFromDisplaySymbol(subSymbol); + } + return aliases; +} + +QString GlodonSymbols::displaySymbolsFromAliases(const QString &aliases) +{ + GObjectList *list = createIndexOfDiameterSymbolList(aliases); + int nPos = 0; + // 用于截取每一位符号的别名 + QString strText; + QString displaySymbols; + for (int i = 0; i < list->count(); ++i) + { + if (nPos <= list->at(i)->pos) + { + strText = copy(aliases, nPos, list->at(i)->pos - nPos); + nPos = list->at(i)->pos; + // 转为用于显示的钢筋符号, 并连接在钢筋符号串中 + displaySymbols += displaySymbolFromAlias(strText); + } + } + // 获取最后一个可识别的钢筋符号的长度 + int lastSymbolLength = 0; + for (int i = 0; i < int(sizeof(c_DiameterSymbols) / sizeof(c_DiameterSymbols[0])); ++i) + { + if (aliases.indexOf(c_DiameterSymbols[i].symbol, nPos) > -1) + { + lastSymbolLength = c_DiameterSymbols[i].symbol.length(); + } + } + + if (nPos <= aliases.length()) + { + // 最后一个可识别的钢筋符号加到符号串中 + strText = copy(aliases, nPos, lastSymbolLength); + displaySymbols += displaySymbolFromAlias(strText); + // 钢筋符号串之后的内容原样加到符号串中 + strText = copy(aliases, nPos + lastSymbolLength, MaxInt); + displaySymbols += strText; + } + return displaySymbols; +} + +void GlodonSymbols::initSymbols(const GlodonDiameterSymbolRec array[], size_t size) +{ + for (size_t i = 0; i < size; ++i) + { + GlodonDiameterSymbolRec symbol = array[i]; + m_symbols.insert(symbol.symbol, symbol.resourceName); + } +} + +#endif + diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDEvent.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDEvent.cpp new file mode 100644 index 00000000..a14c4128 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDEvent.cpp @@ -0,0 +1,36 @@ +#include +#include +#include "GLDEvent.h" +#include "GLDSystem.h" +#include "GLDGlobal.h" + +GLDEvent::GLDEvent(GLDEventType type, GLDWParam wParam, GLDLParam lParam) : + QEvent((QEvent::Type)type), m_wParam(wParam), m_lParam(lParam), m_result(0) +{ + +} + +GLDWParam GLDEvent::wParam() const +{ + return m_wParam; +} + +GLDWParam GLDEvent::lParam() const +{ + return m_lParam; +} + +GLDEventType GLDEvent::type() const +{ + return static_cast(t); +} + +GLDEventResult GLDEvent::result() const +{ + return m_result; +} + +void GLDEvent::setResult(GLDEventResult value) +{ + m_result = value; +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDExcelGridIterator.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDExcelGridIterator.cpp new file mode 100644 index 00000000..2c4af62d --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDExcelGridIterator.cpp @@ -0,0 +1,1606 @@ +#include "GLDExcelGridIterator.h" + +#include +#include +#include +#include +#include "GLDGlobal.h" +#include "GLDStrUtils.h" +#include "GLDException.h" +#include "GLDStrings.h" + +#include "libxl.h" + +const int c_minColWidth = 10; +const int c_isCheckWidth = 50; +const int c_symbolWidth = 100; +const int c_indexWidth = 50; +const int c_minColWidthPix = c_minColWidth * 8.5; + +/*GEGExcelGrid*/ +IGEGRecordIterator *GEGExcelGrid::recordIterator() +{ + return p->recordIterator(); +} + +IGEGFieldIterator *GEGExcelGrid::fieldIterator() +{ + return p->fieldIterator(); +} + +IGEGRecordIterator *GEGExcelGrid::createRecordIterator() +{ + return p->createRecordIterator(); +} + +IGEGFieldIterator *GEGExcelGrid::createFieldIterator() +{ + return p->createFieldIterator(); +} + +/*CGEGExcelGridX*/ + +CGEGExcelGrid::CGEGExcelGrid(GEGExcelModel *model): + m_recordIterator(NULL), m_fieldIterator(NULL), m_xlsModel(model) +{ + +} + +CGEGExcelGrid::~CGEGExcelGrid() +{ + freeAndNil(m_recordIterator); + freeAndNil(m_fieldIterator); +} + +IGEGRecordIterator* CGEGExcelGrid::recordIterator() +{ + if (NULL == m_recordIterator) + { + m_recordIterator = new CGEGRecordIterator(m_xlsModel); + } + return m_recordIterator; +} + +IGEGFieldIterator* CGEGExcelGrid::fieldIterator() +{ + if (NULL == m_fieldIterator) + { + m_fieldIterator = new CGEGFieldIterator(m_xlsModel); + } + return m_fieldIterator; +} + +IGEGRecordIterator* CGEGExcelGrid::createRecordIterator() +{ + freeAndNil(m_recordIterator); + m_recordIterator = new CGEGRecordIterator(m_xlsModel); + return m_recordIterator; +} + +IGEGFieldIterator *CGEGExcelGrid::createFieldIterator() +{ + freeAndNil(m_fieldIterator); + m_fieldIterator = new CGEGFieldIterator(m_xlsModel); + return m_fieldIterator; +} + +HRESULT CGEGExcelGrid::_QueryInterface(const IID &riid, void **ppvObject) +{ + if (riid == __uuidof(IGEGExcelGrid)) + { + this->AddRef(); + *ppvObject = static_cast(this); + return NOERROR; + } + else + return GInterfaceObject::_QueryInterface(riid, ppvObject); +} + +/*GEGRecordIterator*/ +void GEGRecordIterator::first() +{ + p->first(); +} + +void GEGRecordIterator::next() +{ + p->next(); +} + +void GEGRecordIterator::prev() +{ + p->prev(); +} + +void GEGRecordIterator::last() +{ + p->last(); +} + +IGEGRecord *GEGRecordIterator::current() +{ + return p->current(); +} + +bool GEGRecordIterator::isDone() +{ + return p->isDone(); +} + +/*CGEGRecordIterator*/ +CGEGRecordIterator::CGEGRecordIterator(GEGExcelModel *model) : m_currentIndex(0), + m_model(model) +{ + loadItems(); +} + +void CGEGRecordIterator::first() +{ + m_currentIndex = 0; +} + +void CGEGRecordIterator::next() +{ + m_currentIndex++; +} + +void CGEGRecordIterator::prev() +{ + if (m_currentIndex > 0) + { + m_currentIndex--; + } +} + +void CGEGRecordIterator::last() +{ + m_currentIndex = m_recordList.count() - 1; +} + +IGEGRecord* CGEGRecordIterator::current() +{ + return m_recordList.at(m_currentIndex); +} + +bool CGEGRecordIterator::isDone() +{ + return (m_currentIndex == m_recordList.count()); +} + +HRESULT CGEGRecordIterator::_QueryInterface(const IID &riid, void **ppvObject) +{ + if (riid == __uuidof(IGEGRecordIterator)) + { + this->AddRef(); + *ppvObject = static_cast(this); + return NOERROR; + } + else + return GInterfaceObject::_QueryInterface(riid, ppvObject); +} + +void CGEGRecordIterator::loadItems() +{ + m_recordList.clear(); + for (int i = c_DATA_BEGIN_ROWNO; i <= m_model->rowCount(); i++) + { + GString strIdentity = ""; + if (m_model->rowIsIdentity(m_model->dataRow(i), strIdentity)) + { + CGEGRecord *record = new CGEGRecord(); + record->setExcelRowNo(m_model->dataRow(i));//excel中的行号 + record->setCode(strIdentity); + record->setIsChecked(m_model->rowIsChecked(m_model->dataRow(i))); + for (int j = 0; j < m_model->colRuleCount(); j++) + { + GEGColRule *rule = m_model->colRule(j); + if (rule->isMatched()) + { + GEGValue value; + QModelIndex oIndex = m_model->index(i , rule->matchCol() + 3); + value.value = m_model->data(oIndex, Qt::DisplayRole); + value.type = m_model->dataType(m_model->dataRow(i) , rule->matchCol()); + record->addValues(rule->identity(), value); + } + } + m_recordList.push_back(record); + } + } +} + +/*GEGFieldIteratorX*/ +void GEGFieldIterator::first() +{ + p->first(); +} + +void GEGFieldIterator::next() +{ + p->next(); +} + +void GEGFieldIterator::prev() +{ + p->prev(); +} + +void GEGFieldIterator::last() +{ + p->last(); +} + +IGEGField* GEGFieldIterator::current() +{ + return p->current(); +} + +bool GEGFieldIterator::isDone() +{ + return p->isDone(); +} + +/*CGEGFieldIteratorX*/ +CGEGFieldIterator::CGEGFieldIterator(GEGExcelModel *model) : m_currentIndex(0), + m_model(model) +{ + loadItems(); +} + +CGEGFieldIterator::~CGEGFieldIterator() +{ + +} + +void CGEGFieldIterator::first() +{ + m_currentIndex = 0; +} + +void CGEGFieldIterator::next() +{ + m_currentIndex++; +} + +void CGEGFieldIterator::prev() +{ + if (m_currentIndex > 0) + { + m_currentIndex--; + } +} + +void CGEGFieldIterator::last() +{ + m_currentIndex = m_fieldList.count() - 1; +} + +IGEGField* CGEGFieldIterator::current() +{ + return m_fieldList.at(m_currentIndex); +} + +bool CGEGFieldIterator::isDone() +{ + return (m_currentIndex == m_fieldList.count()); +} + +HRESULT CGEGFieldIterator::_QueryInterface(const IID &riid, void **ppvObject) +{ + if (riid == __uuidof(IGEGFieldIterator)) + { + this->AddRef(); + *ppvObject = static_cast(this); + return NOERROR; + } + else + return GInterfaceObject::_QueryInterface(riid, ppvObject); +} + +void CGEGFieldIterator::loadItems() +{ + m_fieldList.clear(); + for (int i = 0; i <= m_model->activeSheet()->lastCol(); i++) + { + GString strRuleIdentity = ""; + if (m_model->colIsIdentity(i, strRuleIdentity)) + { + CGEGField *field = new CGEGField(); + field->setCode(strRuleIdentity); + GEGColRule *rule = m_model->findColRule(strRuleIdentity); + field->setDataType(rule->dataType()); + field->setName(rule->name()); + m_fieldList.push_back(field); + } + } +} + +/*GEGRecordX*/ +GEGValue GEGRecord::fullValues(const GString &fieldName) +{ + return p->fullValues(fieldName); +} + +bool GEGRecord::addValues(const GString &fieldName, const GEGValue &value) +{ + return p->addValues(fieldName, value); +} + +/*CGEGRecordX*/ +CGEGRecord::CGEGRecord() : m_code(""), m_isChecked(false) +{ + +} + +GEGValue CGEGRecord::fullValues(const GString &fieldName) +{ + QHash::const_iterator it = m_values.find(fieldName); + if (it != m_values.end()) + { + return it.value(); + } + else + { + return GEGValue(); + } +} + +bool CGEGRecord::addValues(const GString &fieldName, const GEGValue &value) +{ + QHash::const_iterator it = m_values.find(fieldName); + if (it == m_values.end()) + { + m_values.insert(fieldName, value); + return true; + } + return false; +} + +HRESULT CGEGRecord::_QueryInterface(const IID &riid, void **ppvObject) +{ + if (riid == __uuidof(IGEGRecord)) + { + this->AddRef(); + *ppvObject = static_cast(this); + return NOERROR; + } + else + return GInterfaceObject::_QueryInterface(riid, ppvObject); +} + +/*CGEGFieldX*/ +CGEGField::CGEGField() : m_code(""), m_value(GVariant()) +{ + +} + +HRESULT CGEGField::_QueryInterface(const IID &riid, void **ppvObject) +{ + if (riid == __uuidof(IGEGField)) + { + this->AddRef(); + *ppvObject = static_cast(this); + return NOERROR; + } + else + return GInterfaceObject::_QueryInterface(riid, ppvObject); +} + +/*GEGRule*/ +GEGRule::GEGRule(GEGExcelModel *model) : m_owner(model), + m_identity(""), m_visible(true), m_tag(0) +{ + +} + +GEGRule::~GEGRule() +{ + +} + +/*GEGColRule*/ +GEGColRule::GEGColRule(GEGExcelModel *model) : GEGRule(model), m_matchCol(-1), m_dataType(GEGdtEmply) +{ + +} + +GEGColRule::~GEGColRule() +{ + +} + +bool GEGColRule::macthKeyWord(const GString &value) +{ + bool result = false; + for (int i = 0; i < m_tokens.count(); i++) + { + QRegExp *oExpr = m_tokens.at(i); + if (oExpr->exactMatch(value)) + { + result = true; + break; + } + } + return result; +} + +bool GEGColRule::match(int col, bool force) +{ + bool result = doMatch(col, force); + if (result) + { + m_matchCol = col; +// writeColIdentity(); + } + else + { + m_matchCol = -1; + } + return result; +} + +void GEGColRule::clear() +{ + if (isMatched()) + { + //todo + m_matchCol = -1; + } +} + +void GEGColRule::reset() +{ + if (visible()) + { + m_matchCol = -1; + } +} + +bool GEGColRule::isMatched() +{ + return (m_matchCol != -1); +} + +void GEGColRule::compile() +{ + buildTokens(); +} + +bool GEGColRule::doMatch(int col, bool force) +{ + bool result = false; + if (force) + { + result = true; + } + else + { + int nLastRow = model()->activeSheet()->lastRow(); + for (int i = 0; i <= nLastRow; i++) + { + GString value = GString((const QChar *) model()->activeSheet()->readStr(i, col)); + if (macthKeyWord(value)) + { + result = true; + break; + } + } + } + return result; +} + +//void GEGColRule::writeColIdentity() +//{ +// if (visible()) +// { +// //todo +// } +//} + +void GEGColRule::buildTokens() +{ + GStringList oKeyWords = m_keyWords; + GString strIdentity = identity(); + if (-1 == oKeyWords.indexOf(strIdentity)) + { + oKeyWords.push_back(strIdentity); + } + m_tokens.clear(); + for (int i = 0; i < oKeyWords.count(); ++i) + { + GString sKeyWord = oKeyWords.at(i); + GString sExpr = "(\\w)*"; + for (int j = 0; j < sKeyWord.length(); ++j) + { + if (0 == j) + { + sExpr += sKeyWord.at(j); + } + else + { + sExpr = sExpr + "(\\w|\\s)*" + sKeyWord.at(j); + } + } + sExpr += "(\\w)*"; + + QRegExp *oExpr = new QRegExp(); + oExpr->setPattern(sExpr); + m_tokens.push_back(oExpr); + } +} + +/*GEGRowRule*/ +GEGRowRule::GEGRowRule(GEGExcelModel *model) : GEGRule(model), m_regExpr(new QRegExp) +{ + +} + +GEGRowRule::~GEGRowRule() +{ + freeAndNil(m_regExpr); +} + +bool GEGRowRule::match(int row, bool force) +{ + bool result = doMatch(row, force); + if (result) + { + writeRowIdentity(row); + } + return result; +} + +void GEGRowRule::clear(int row) +{ + G_UNUSED(row); +} + +bool GEGRowRule::doMatch(int row, bool force) +{ + if (force) + { + return true; + } + else + { + return false; + } + G_UNUSED(row); +} + +bool GEGRowRule::excuteRegExpr(const GString ®Expr, const GString &inputStr) +{ + m_regExpr->setPattern(regExpr); + return m_regExpr->exactMatch(inputStr); +} + +GString GEGRowRule::asString(int row, int col) +{ + return model()->asString(row, col); +} + +GString GEGRowRule::asString(GEGColRule *colRule, int row) +{ + return model()->asString(colRule, row); +} + +GString GEGRowRule::asString(const GString &identity, int row) +{ + return model()->asString(identity, row); +} + +bool GEGRowRule::asBool(int row, int col) +{ + return model()->asBool(row, col); +} + +int GEGRowRule::asInt(int row, int col) +{ + return model()->asInteger(row, col); +} + +double GEGRowRule::asDouble(int row, int col) +{ + return model()->asDouble(row, col); +} + +void GEGRowRule::writeRowIdentity(int row) +{ + if (visible()) + { + GString id = identity(); + model()->addRowIdentity(row, id); + } +} + +/* GEGExcelModel */ + +GEGExcelModel::GEGExcelModel(QObject *parent) : GlodonXLSModel(parent), + m_firstDataCol(0), m_firstDataRow(0), m_allowAutoMatch(false) +{ +// registerRules(); +// initializeRules(); +// loadRules(); +} + +GEGExcelModel::~GEGExcelModel() +{ + +} + +GEGColRule *GEGExcelModel::addColRule() +{ + GEGColRule *result = new GEGColRule(this); + m_colRules.push_back(result); + return result; +} + +void GEGExcelModel::addColRule(GEGColRule *rule) +{ + m_colRules.push_back(rule); +} + +GEGColRule *GEGExcelModel::addColRule(const GString &identity, const GLDVector keywords) +{ + GEGColRule *result = addColRule(); + result->setIdentity(identity); + for (int i = 0; i < keywords.count(); i++) + { + GString strKeyWord = keywords.at(i); + result->keyWords().push_back(strKeyWord); + } + return result; +} + +GEGColRule *GEGExcelModel::addColRule(const GString &identity) +{ + return addColRule(identity, GLDVector()); +} + +GEGRowRule *GEGExcelModel::addRowRule() +{ + GEGRowRule *result = new GEGRowRule(this); + m_rowRules.push_back(result); + return result; +} + +void GEGExcelModel::addRowRule(GEGRowRule *rule) +{ + m_rowRules.push_back(rule); +} + +GEGColRule *GEGExcelModel::findColRule(const GString &identity) +{ + int nIndex = indexOfColRule(identity); + if (nIndex != -1) + return m_colRules.at(nIndex); + else + return NULL; +} + +GEGRowRule *GEGExcelModel::findRowRule(const GString &identity) +{ + int nIndex = indexOfRowRule(identity); + if (-1 != nIndex) + return m_rowRules.at(nIndex); + else + return NULL; +} + +GEGColRule *GEGExcelModel::colRule(int index) +{ + if ((index < 0) || (index > m_colRules.count() - 1)) + return NULL; + return m_colRules.at(index); +} + +GEGRowRule *GEGExcelModel::rowRule(int index) +{ + if ((index < 0) || (index > m_rowRules.count() - 1)) + return NULL; + return m_rowRules.at(index); +} + +void GEGExcelModel::clearColRules() +{ + m_colRules.clear(); +} + +void GEGExcelModel::clearRowRules() +{ + m_rowRules.clear(); +} + +void GEGExcelModel::setActive(bool value) +{ + if (value) + { + initializeRules(); + if (m_allowAutoMatch) + { + autoMatch(); + } + } +} + +GString GEGExcelModel::asString(int dataRow, int dataCol) +{ + GString result = ""; + + if ((dataRow < 0) || (dataCol < 0)) + { + return result; + } + + if (NULL != activeSheet()) + { + GEGDataType oType = dataType(dataRow, dataCol); + switch (oType) + { + case GEGdtString: + { + result = GString((const QChar *)(activeSheet()->readStr(dataRow, dataCol))); + break; + } + case GEGdtNumber: + { + double dValue = activeSheet()->readNum(dataRow, dataCol); + result = floatToStr(dValue); + break; + } + default: + break; + } + } + return result; +} + +GString GEGExcelModel::asString(GEGColRule *rule, int dataRow) +{ + GString result = ""; + if ((NULL != rule) && (rule->isMatched())) + { + result = asString(dataRow, rule->matchCol()); + } + return result; +} + +/*! + * \brief 通过列规则的name和行号来取得格子的内容(Excel对应的行号) + * \param name:列规则的name + * \param dataRow:excel当中的行号 + * \return 格子的内容 + */ +GString GEGExcelModel::asString(const GString &name, int dataRow) +{ + bool bFind = false; + GEGColRule *rule = NULL; + for (int i = 0; i < m_colRules.count(); i++) + { + rule = m_colRules.at(i); + if (rule->name() == name) + { + bFind = true; + break; + } + } + if (! bFind) + { + return asString(findColRule(name), dataRow); + } + else + { + return asString(rule, dataRow); + } +} + +bool GEGExcelModel::asBool(int dataRow, int dataCol) +{ + bool result = false; + + if ((dataRow < 0) || (dataCol < 0)) + { + return false; + } + + if (NULL != activeSheet()) + { + result = activeSheet()->readBool(dataRow, dataCol); + } + return result; +} + +int GEGExcelModel::asInteger(int dataRow, int dataCol) +{ + double result = 0; + + if ((dataRow < 0) || (dataCol < 0)) + { + return result; + } + + if (NULL != activeSheet()) + { + result = activeSheet()->readNum(dataRow, dataCol); + } + return result; +} + +double GEGExcelModel::asDouble(int dataRow, int dataCol) +{ + double result = 0; + + if ((dataRow < 0) || (dataCol < 0)) + { + return result; + } + + if (NULL != activeSheet()) + { + result = activeSheet()->readNum(dataRow, dataCol); + } + return result; +} + +GEGDataType GEGExcelModel::dataType(int dataRow, int dataCol) +{ + if (NULL == activeSheet()) + return GEGdtEmply; + + + if ((dataRow < 0) || dataCol < 0) + { + return GEGdtEmply; + } + + switch (activeSheet()->cellType(dataRow, dataCol)) + { + case libxl::CELLTYPE_EMPTY: + return GEGdtEmply; + case libxl::CELLTYPE_NUMBER: + return GEGdtNumber; + case libxl::CELLTYPE_STRING: + return GEGdtString; + case libxl::CELLTYPE_BOOLEAN: + return GEGdtBool; + case libxl::CELLTYPE_BLANK: + return GEGdtBlank; + case libxl::CELLTYPE_ERROR: + return GEGdtError; + default: + return GEGdtEmply; + } +} + +QRect GEGExcelModel::getMergeRect(int row, int col) +{ + if (NULL == activeSheet()) + { + gldError(getGLDi18nStr(g_rsHasNoActiveSheet)); + } + QRect rResult; + int nRowFirst, nRowLast, nColFirst, nColLast; + if (activeSheet()->getMerge(row, col, &nRowFirst, &nRowLast, &nColFirst, &nColLast)) + { + rResult.setTop(nRowFirst); + rResult.setBottom(nRowLast); + rResult.setLeft(nColFirst); + rResult.setRight(nColLast); + } + else + { + rResult.setTop(row); + rResult.setBottom(row); + rResult.setLeft(col); + rResult.setRight(col); + } + return rResult; +} + +GString GEGExcelModel::findRowIdentityByRow(int row) +{ + GString result; + rowIsIdentity(row, result); + return result; +} + +void GEGExcelModel::doRegisterRules() +{ + +} + +void GEGExcelModel::doAutoMatchRow() +{ + if (NULL == activeSheet()) + return; + m_rowIdentityHash.clear(); + for (int i = 0; i < this->rowCount(); ++i) + { + m_rowCheckHash.insert(i, false); + } + GObjectList oList; + for (int i = 0; i < m_rowRules.count(); i++) + { + oList.push_back(m_rowRules.at(i)); + } + QHash::const_iterator it; + while (oList.count() > 0) + { + GEGRowRule *rule = oList.at(0); + oList.remove(rule); + for (int i = 0; i < rowCount(); i++) + { + it = m_rowIdentityHash.find(dataRow(i)); + if (it != m_rowIdentityHash.end()) + continue; + m_rowCheckHash.insert(dataRow(i), rule->match(i, false)); + } + } +} + +void GEGExcelModel::doAutoMatchCol() +{ + if (NULL == activeSheet()) + return; + for (int i = 0; i < m_colRules.count(); ++i) + { + m_colRules.at(i)->reset(); + } + m_colIdentityHash.clear(); + for (int col = m_firstDataCol; col <= activeSheet()->lastCol(); ++col) + { + for (int nRule = 0; nRule < m_colRules.count(); nRule++) + { + GEGColRule *rule = m_colRules.at(nRule); + if (rule->isMatched()) + continue; + if (rule->match(col, false)) + { + if (activeSheet()->colWidth(col) < c_minColWidth) + { + activeSheet()->setCol(col, col + 1, c_minColWidth); + } + m_colIdentityHash.insert(col, rule->identity()); + break; + } + } + } +} + +QVariant GEGExcelModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return GVariant(); + int nCol = index.column(); + int nRow = index.row(); + if (inTitleRow(index)) + { + return indexTitleData(index, role); + } + else if (!inDRange(nRow, nCol)) + { + if (Qt::DisplayRole == role) + { + if (nRow < c_DATA_BEGIN_ROWNO + && nCol < c_DATA_BEGIN_COLNO) + { + return GString(""); + } + else if (inIsExportCol(index)) + { + return configDisplayIsExportData(nRow); + } + else if (inColMatchedResultRow(index)) + { + return configDisplayColData(nCol); + } + else if (inRowMatchedResultCol(index)) + { + return configDisplayRowData(nRow); + } + else + return GVariant(); + } + else if (Qt::FontRole == role) + { + //识别成功的加粗 + QFont headerfont = QFont(); + if (c_COL_METCHED_RESULT_ROWNO == nRow) + { + QHash::const_iterator it = m_colIdentityHash.find(dataCol(nCol)); + if (it != m_colIdentityHash.end()) + { + headerfont.setBold(true); + } + } + else if (c_ROW_METCHED_RESULT_COLNO == nCol) + { + QHash::const_iterator it = m_rowIdentityHash.find(dataRow(nRow)); + if (it != m_rowIdentityHash.end()) + { + headerfont.setBold(true); + } + } + return headerfont; + } + else if (Qt::TextColorRole == role) + { + if (index.row() == c_COL_METCHED_RESULT_ROWNO + || index.column() == c_ROW_METCHED_RESULT_COLNO) + { + return QColor(Qt::blue); + } + } + else if (Qt::TextAlignmentRole == role) + { + if (index.row() == c_COL_METCHED_RESULT_ROWNO + || index.column() == c_ROW_METCHED_RESULT_COLNO) + { + return Qt::AlignCenter; + } + } + else if (Qt::BackgroundColorRole == role) + { + GVariant oColor = QColor(255, 255, 255); + GString sheetName = getSheetName(); + + if (m_queryCellXLSAttributeEventList.count() > 0) + { + m_queryCellXLSAttributeEventList.doEvent(sheetName, index.row() - 1, index.column(), + Qt::BackgroundColorRole, oColor); + } + return oColor; + } + } + else if (inIndexCol(index)) + { + return indexColData(index, role); //序号那列的设置 + } + if (Qt::TextAlignmentRole == role) + { + return Qt::AlignVCenter; //计价需求 + } + else + { + int nDCol = dataCol(index.column()); + int nDRow = dataRow(index.row()); + QModelIndex oIndex = createIndex(nDRow, nDCol, index.internalPointer()); + GVariant oValue = GlodonXLSModel::data(oIndex, role); + GString sheetName = getSheetName(); + + if (role == Qt::BackgroundColorRole) + { + if (m_queryCellXLSAttributeEventList.count() > 0) + { + m_queryCellXLSAttributeEventList.doEvent(sheetName, index.row() - 1, index.column() - 2, + Qt::BackgroundColorRole, oValue); + } + } + return oValue; + } +} + +bool GEGExcelModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + switch (role) + { + case Qt::EditRole: + if (index.row() >= c_DATA_BEGIN_ROWNO + && index.column() >= c_DATA_BEGIN_COLNO) + return doSetEditData(dataRow(index.row()), dataCol(index.column()), value); + else + { + if (inIsExportCol(index)) + { + setRowCheckData(index.row() - c_DATA_BEGIN_ROWNO); + } + // 操作列 + if (inColMatchedResultRow(index)) + { + GString id = value.toString(); + addColIdentity(index.column() - c_IndexCol - 1, id); + } + // 操作行 + if (inRowMatchedResultCol(index)) + { + GString id = value.toString(); + addRowIdentity(index.row() - c_DATA_BEGIN_ROWNO, id); + } + } + return true; + default: + return GlodonXLSModel::setData(index, value, role); + } + return false; +} + +GVariant GEGExcelModel::configDisplayColData(int col) const +{ + QHash::const_iterator it = m_colIdentityHash.find(dataCol(col)); + GString result; + if (it != m_colIdentityHash.end()) + { + result = it.value(); + } + else + { + result = tr("Unrecognized");//"未识别"); + } + return result; +} + +GVariant GEGExcelModel::configDisplayRowData(int row) const +{ + QHash::const_iterator it = m_rowIdentityHash.find(dataRow(row)); + GString result; + if (it != m_rowIdentityHash.end()) + { + result = it.value(); + } + else + { + result = tr("Unrecognized");//"未识别"); + } + return result; +} + +GVariant GEGExcelModel::configDisplayIsExportData(int row) const +{ + QHash::const_iterator it = m_rowCheckHash.find(dataRow(row)); + if (it != m_rowCheckHash.end()) + { + return it.value(); + } + else + { + return GVariant(false); + } +} + +int GEGExcelModel::dataCol(int col) const +{ + return col - c_DATA_BEGIN_COLNO - 1; +} + +int GEGExcelModel::dataRow(int row) const +{ + return row - c_DATA_BEGIN_ROWNO; +} + +void GEGExcelModel::addRowIdentity(int row, GString &identity) +{ + if (m_rowIdentityChangeEventList.count() > 0) + { + GString strOldValue = ""; + QHash::const_iterator it = m_rowIdentityHash.find(row); + if (it != m_rowIdentityHash.end()) + { + strOldValue = it.value(); + } + m_rowIdentityChangeEventList.doEvent(row, strOldValue, identity); + } + + QHash::const_iterator it = m_rowIdentityHash.find(row); + if (it != m_rowIdentityHash.end()) + { + if (sameText(it.value(), identity)) + { + m_rowIdentityHash.remove(row); + m_rowCheckHash.remove(row); + return; + } + } + m_rowIdentityHash.insert(row, identity); + m_rowCheckHash.insert(row, true); +} + +void GEGExcelModel::addColIdentity(int col, GString &identity) +{ + GString strOldValue = ""; + int nSameIdentityCol = -1; + int nSameCol = -1; + for (QHash::const_iterator it = m_colIdentityHash.begin() + ; it != m_colIdentityHash.end() + ; ++it) + { + if (it.value() == identity) + { + nSameIdentityCol = it.key(); + strOldValue = it.value(); + } + if (it.key() == col) + { + GEGColRule *oRule = findColRule(it.value()); + oRule->setMatchCol(-1); + nSameCol = it.key(); + } + } + if (nSameIdentityCol > -1) + { + m_colIdentityHash.remove(nSameIdentityCol); + } + if (nSameCol > -1) + { + m_colIdentityHash.remove(nSameCol); + } + GEGColRule *rule = findColRule(identity); + if (NULL == rule) + { + gldError(getGLDi18nStr(g_rsInvalideRule)); + return; + } + if (m_colIdentityChangeEventList.count() > 0) + { + m_colIdentityChangeEventList.doEvent(col, strOldValue, identity); + } + if (nSameIdentityCol != col) + { + rule->setMatchCol(col); + if (activeSheet()->colWidth(col) < c_minColWidth) + { + activeSheet()->setCol(col, col + 1, c_minColWidth); + } + m_colIdentityHash.insert(col, identity); + } + else + { + rule->setMatchCol(-1); + } +} + +void GEGExcelModel::setRowCheckData(int row) +{ + QHash::const_iterator it = m_rowCheckHash.find(row); + bool bValue = it.value(); + m_rowCheckHash.insert(row, !bValue); +} + +void GEGExcelModel::setAllRowsCheckData(bool value) +{ + for (QHash::const_iterator it = m_rowCheckHash.begin() + ; it != m_rowCheckHash.end() + ; ++it) + { + m_rowCheckHash.insert(it.key(), value); + } +} + +/*! + * \brief 设置行选中 + * \param row + * \param check + */ +void GEGExcelModel::setRowCheck(int row, bool check) +{ + m_rowCheckHash.insert(row, check); +} + +void GEGExcelModel::removeRowIdentity(int row) +{ + m_rowIdentityHash.remove(row); + m_rowCheckHash.insert(row, false); +} + +void GEGExcelModel::removeColIdentity(int col) +{ + m_colIdentityHash.remove(col); +} + +bool GEGExcelModel::colIsIdentity(int col, GString &identity) +{ + QHash::const_iterator it = m_colIdentityHash.find(col); + if (it != m_colIdentityHash.end()) + { + identity = it.value(); + return true; + } + else + { + identity = ""; + return false; + } +} + +bool GEGExcelModel::rowIsIdentity(int row, GString &identity) +{ + QHash::const_iterator it = m_rowIdentityHash.find(row); + if (it != m_rowIdentityHash.end()) + { + identity = it.value(); + return true; + } + else + { + identity = ""; + return false; + } +} + +bool GEGExcelModel::rowIsChecked(int row) +{ + QHash::const_iterator it = m_rowCheckHash.find(row); + if (it != m_rowCheckHash.end()) + { + return it.value(); + } + else + { + return false; + } +} + +int GEGExcelModel::getColWidth(int col) +{ + if (col == c_IS_EXPORT_COLNO) + { + return c_isCheckWidth; + } + else if (col == c_ROW_METCHED_RESULT_COLNO) + { + return c_symbolWidth; + } + else if (col == c_IndexCol) + { + return c_indexWidth; + } + else + { + QModelIndex oIndex = createIndex(c_DATA_BEGIN_ROWNO, col); + GVariant oVar = data(oIndex, gidrColWidthRole); + int nWidth = oVar.toInt(); + return nWidth < c_minColWidthPix ? c_minColWidthPix : nWidth; + } +} + +int GEGExcelModel::getRowHeight(int row) +{ + if ((row == c_COL_METCHED_RESULT_ROWNO) || (row == c_titleRow)) + { + return 20; + } + else + { + // 96 是一般的分辨率;1/72 是 1皮克 = 1/72 英寸; + return this->activeSheet()->rowHeight(dataRow(row)) * 96 * 1.0 / 72; + } +} + +QModelIndex GEGExcelModel::getPrevUnmatchedRow(QModelIndex &index) +{ + for (int nRow = index.row() - 1; nRow >= c_DATA_BEGIN_ROWNO; --nRow) + { + GString sIdentity; + if (!rowIsIdentity(nRow, sIdentity)) + { + return createIndex(nRow, index.column(), index.internalPointer()); + } + } + return QModelIndex(); +} + +QModelIndex GEGExcelModel::getNextUnmatchedRow(QModelIndex &index) +{ + for (int nRow = index.row() + 1; nRow < this->rowCount(); ++nRow) + { + GString sIdentity; + if (!rowIsIdentity(nRow, sIdentity)) + { + return createIndex(nRow, index.column(), index.internalPointer()); + } + } + return QModelIndex(); +} + +bool GEGExcelModel::inRowMatchedResultCol(const QModelIndex &index) const +{ + return (index.row() >= c_DATA_BEGIN_ROWNO + && index.column() == c_ROW_METCHED_RESULT_COLNO); +} + +bool GEGExcelModel::inColMatchedResultRow(const QModelIndex &index) const +{ + return (index.row() == c_COL_METCHED_RESULT_ROWNO + && index.column() > c_IndexCol); +} + +bool GEGExcelModel::inIndexCol(const QModelIndex &index) const +{ + return (index.row() >= c_DATA_BEGIN_ROWNO) + && (index.column() == c_IndexCol); +} + +bool GEGExcelModel::inTitleRow(const QModelIndex &index) const +{ + return (index.row() == c_titleRow); +} + +bool GEGExcelModel::inIsExportCol(const QModelIndex &index) const +{ + return (index.row() >= c_DATA_BEGIN_ROWNO + && index.column() == c_IS_EXPORT_COLNO); +} + +bool GEGExcelModel::isDataCol(int col) const +{ + return col >= c_DATA_BEGIN_COLNO; +} + +bool GEGExcelModel::isDataRow(int row) const +{ + return row >= c_DATA_BEGIN_ROWNO - 1; +} + +bool GEGExcelModel::inDRange(int row, int col) const +{ + return isDataCol(col) && isDataRow(row); +} + +int GEGExcelModel::rowCount(const QModelIndex &parent) const +{ + return GlodonXLSModel::rowCount(parent) + c_DATA_BEGIN_ROWNO; +} + +int GEGExcelModel::columnCount(const QModelIndex &parent) const +{ + return GlodonXLSModel::columnCount(parent) + c_DATA_BEGIN_COLNO + 1; +} + +int GEGExcelModel::indexOfColRule(const GString &identity) +{ + for (int i = 0; i < m_colRules.count(); i++) + { + if (sameText(m_colRules.at(i)->identity(), identity)) + return i; + } + return -1; +} + +int GEGExcelModel::indexOfRowRule(const GString &identity) +{ + for (int i = 0; i < m_rowRules.count(); i++) + { + if (sameText(m_rowRules.at(i)->identity(), identity)) + return i; + } + return -1; +} + +int GEGExcelModel::lastMatchDataCol() +{ + int result = -1; + for (int i = 0; i < m_colRules.count(); i++) + { + result = std::max(m_colRules.at(i)->matchCol(), result); + } + return result; +} + +void GEGExcelModel::autoMatchCol() +{ + doAutoMatchCol(); +} + +void GEGExcelModel::autoMatchRow() +{ + doAutoMatchRow(); +} + +void GEGExcelModel::autoMatch() +{ + autoMatchCol(); + autoMatchRow(); +} + +void GEGExcelModel::initializeRules() +{ + for (int i = 0; i < m_colRules.count(); i++) + { + m_colRules.at(i)->compile(); + } + for (int i = 0; i < m_rowRules.count(); i++) + { + m_rowRules.at(i)->compile(); + } +} + +void GEGExcelModel::registerRules() +{ + //todo + doRegisterRules(); +} + +void GEGExcelModel::loadRules() +{ + +} + +QVariant GEGExcelModel::indexColData(const QModelIndex &index, int role) const +{ + if (Qt::DisplayRole == role) + { + if (index.row() == c_DATA_BEGIN_ROWNO - 1) + { + return getGLDi18nStr(g_rsTitleIndex); //序号 + } + else + { + return QString::number(index.row() - c_DATA_BEGIN_ROWNO + 1); + } + } + else if (Qt::TextAlignmentRole == role) + { + return Qt::AlignCenter; + } + else if (Qt::BackgroundColorRole == role) + { + GVariant oColor = QColor(255, 255, 255); + GString sheetName = getSheetName(); + + if (m_queryCellXLSAttributeEventList.count() > 0) + { + m_queryCellXLSAttributeEventList.doEvent(sheetName, index.row() - 1, index.column(), + Qt::BackgroundColorRole, oColor); + } + return oColor; + } + return QVariant(); +} + +QVariant GEGExcelModel::indexTitleData(const QModelIndex &index, int role) const +{ + if (Qt::DisplayRole == role) + { + if (0 == index.column()) + { + return getGLDi18nStr(g_rsTitleSelect); //选择 + } + else if (1 == index.column()) + { + return getGLDi18nStr(g_rsTitleSymbol);//标识 + } + else if (2 == index.column()) + { + return getGLDi18nStr(g_rsTitleIndex); //序号 + } + else + { + return QChar(QLatin1Char('A' + index.column() - 3)); + } + } + else if (Qt::TextAlignmentRole == role) + { + return Qt::AlignCenter; + } + return QVariant(); +} + +void GEGExcelRowIdentityChangeEventList::doEvent(int row, const GString &oldValue, GString &newValue) +{ + for (int i = 0; i < count(); i++) + { + at(i)->onRowIdentityChanged(row, oldValue, newValue); + } +} + +void GEGExcelColIdentityChangeEventList::doEvent(int col, const GString &oldValue, GString &newValue) +{ + for (int i = 0; i < count(); i++) + { + at(i)->onColIdentityChanged(col, oldValue, newValue); + } +} + +bool GLDXLSQueryCellAttributeEventList::doEvent(GString &sheetName, int row, int col, int role, GVariant &attribute) const +{ + bool result = false; + + for (int i = 0; i < count(); ++i) + { + at(i)->onQueryCellXLSAttribute(sheetName, row, col, role, attribute, result); + if (result) + { + break; + } + } + + return result; +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDExcelIteratorTableView.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDExcelIteratorTableView.cpp new file mode 100644 index 00000000..b578d882 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDExcelIteratorTableView.cpp @@ -0,0 +1,315 @@ +#include "GLDExcelIteratorTableView.h" +#include "GLDTableView_p.h" +#include "GLDStrUtils.h" +#include "GLDStrings.h" + +const char *c_hideAllMatchdRow = QT_TRANSLATE_NOOP("GLD", "hide all identified rows");//"隐藏已识别行"); +const char *c_showAllRow = QT_TRANSLATE_NOOP("GLD", "display all rows"); //"显示所有行"); +const char *c_selectAll = QT_TRANSLATE_NOOP("GLD", "select all"); //"全部选择"); +const char *c_cancelAll = QT_TRANSLATE_NOOP("GLD", "cancel all"); //"全部取消"); +const char *c_markAs = QT_TRANSLATE_NOOP("GLD", "mark as"); //"识别为"); +const char *c_clearMatchRowIndentity = QT_TRANSLATE_NOOP("GLD", "clear all matched records of types"); //"清除已匹配的记录类型"); + +class GlodonTableViewPrivate; +class GLDExcelIteratorTableViewPrivate : public GlodonTableViewPrivate +{ +public: + GLDExcelIteratorTableViewPrivate(GLDExcelIteratorTableView *parent) + : q_ptr(parent), m_excelModel(NULL), m_clearRowRule(NULL), m_clearColRule(NULL), + m_rowPopMenu(NULL), m_colPopMenu(NULL), m_selectPopMenu(NULL), + m_contextMenu(NULL), m_markMenu(NULL) + { + } + +private: + GLDExcelIteratorTableView * const q_ptr; + Q_DECLARE_PUBLIC(GLDExcelIteratorTableView); + + GEGExcelModel *m_excelModel; + + QAction *m_clearRowRule; + QAction *m_clearColRule; + // popu menu + QMenu *m_rowPopMenu; + QMenu *m_colPopMenu; + QMenu *m_selectPopMenu; + + QMenu *m_contextMenu; + QMenu *m_markMenu; + int m_contextRow; + QVector m_selectedRows; +}; + +GLDExcelIteratorTableView::GLDExcelIteratorTableView(QWidget *parent): + GlodonTableView(*new GLDExcelIteratorTableViewPrivate(this), parent) +{ + setItemDelegate(new GLDExcellIteratorDelegate(this)); + setSelectionMode(GlodonAbstractItemView::ExtendedSelection); +} + +void GLDExcelIteratorTableView::setModel(GEGExcelModel *model) +{ + Q_D(GLDExcelIteratorTableView); + GlodonTableView::setModel(model); + d->m_excelModel = model; + createPopupMenus(); + + bindColumSetting(); + bindRowSetting(); + + //设置右键 + setContextMenuPolicy(Qt::CustomContextMenu); + connect(this, SIGNAL(customContextMenuRequested(QPoint)), + this, SLOT(doGridContextMenuRequest(QPoint))); +} + +GEGExcelModel *GLDExcelIteratorTableView::model() const +{ + Q_D(const GLDExcelIteratorTableView); + return d->m_excelModel; +} + +IGEGExcelGrid *GLDExcelIteratorTableView::getExcelGridIterator() +{ + Q_D(GLDExcelIteratorTableView); + return new CGEGExcelGrid(d->m_excelModel); +} + +void GLDExcelIteratorTableView::mouseReleaseEvent(QMouseEvent *event) +{ + Q_D(GLDExcelIteratorTableView); + GlodonTableView::mouseReleaseEvent(event); + if ((d->m_selectedRows.count() > 1) && (Qt::NoButton != (event->button() & Qt::RightButton))) + { + d->m_selectedRows.clear(); + return; + } + QModelIndex currentIndex = indexAt(event->pos()); + if (d->m_excelModel->inColMatchedResultRow(currentIndex)) + { + d->m_colPopMenu->popup(event->globalPos()); + } + if (d->m_excelModel->inRowMatchedResultCol(currentIndex)) + { + d->m_rowPopMenu->popup(event->globalPos()); + } +} + +void GLDExcelIteratorTableView::createPopupMenus() +{ + Q_D(GLDExcelIteratorTableView); + if (NULL == d->m_excelModel) + return; + + d->m_colPopMenu = new QMenu(this); + d->m_rowPopMenu = new QMenu(this); + d->m_selectPopMenu = new QMenu(this); + + d->m_contextMenu = new QMenu(this); +} + +void GLDExcelIteratorTableView::bindColumSetting() +{ + Q_D(GLDExcelIteratorTableView); + for (int col = 0; col < this->model()->columnCount(); ++col) + { + int nWidth = d->m_excelModel->getColWidth(col); + setColumnWidth(col, nWidth); + } +} + +void GLDExcelIteratorTableView::bindRowSetting() +{ + Q_D(GLDExcelIteratorTableView); + for (int row = 0; row < this->model()->rowCount(); ++row) + { + int nHeight = d->m_excelModel->getRowHeight(row); + setRowHeight(row, nHeight, false); + } +} + +void GLDExcelIteratorTableView::hideMatchedRows() +{ + Q_D(GLDExcelIteratorTableView); + GString sIdentity; + for (int i = 2; i <= d->m_excelModel->rowCount(); i++) + { + if (d->m_excelModel->rowIsIdentity(i - 2, sIdentity)) + { + this->setRowHidden(i, true); + } + } + refresh(); +} + +void GLDExcelIteratorTableView::showAllRows() +{ + Q_D(GLDExcelIteratorTableView); + for (int i = 1; i <= d->m_excelModel->rowCount(); i++) + { + if (this->isRowHidden(i)) + { + this->setRowHidden(i, false); + } + } + refresh(); +} + +void GLDExcelIteratorTableView::refresh() +{ + refreshDisplayColRow(); + this->updateAll(); +} + +void GLDExcelIteratorTableView::prevUnmatchedRow() +{ + Q_D(GLDExcelIteratorTableView); + QModelIndex curIndex = this->currentIndex(); + QModelIndex desIndex = d->m_excelModel->getPrevUnmatchedRow(curIndex); + if (desIndex.isValid()) + setCurrentIndex(desIndex); +} + +void GLDExcelIteratorTableView::nextUnmatchedRow() +{ + Q_D(GLDExcelIteratorTableView); + QModelIndex curIndex = this->currentIndex(); + QModelIndex desIndex = d->m_excelModel->getNextUnmatchedRow(curIndex); + if (desIndex.isValid()) + setCurrentIndex(desIndex); +} + +void GLDExcelIteratorTableView::selectAllClick() +{ + Q_D(GLDExcelIteratorTableView); + d->m_excelModel->setAllRowsCheckData(true); +} + +void GLDExcelIteratorTableView::cancelAllClick() +{ + Q_D(GLDExcelIteratorTableView); + d->m_excelModel->setAllRowsCheckData(false); +} + +void GLDExcelIteratorTableView::clearMatchRowIndentity() +{ + Q_D(GLDExcelIteratorTableView); + if (NULL != d->m_excelModel) + { + d->m_excelModel->removeRowIdentity(d->m_contextRow); + } +} + +QMenu *GLDExcelIteratorTableView::colPopMenu() +{ + Q_D(GLDExcelIteratorTableView); + return d->m_colPopMenu; +} + +QMenu *GLDExcelIteratorTableView::rowPopMenu() +{ + Q_D(GLDExcelIteratorTableView); + return d->m_rowPopMenu; +} + +QMenu *GLDExcelIteratorTableView::selectPopMenu() +{ + Q_D(GLDExcelIteratorTableView); + return d->m_selectPopMenu; +} + +QMenu *GLDExcelIteratorTableView::contextMenu() +{ + Q_D(GLDExcelIteratorTableView); + return d->m_contextMenu; +} + +void GLDExcelIteratorTableView::autoMatch() +{ + Q_D(GLDExcelIteratorTableView); + if (NULL != d->m_excelModel) + { + d->m_excelModel->autoMatch(); + updateAll(); + } +} + +void GLDExcelIteratorTableView::setCurrentIndexValue(const GString &value) +{ + Q_D(GLDExcelIteratorTableView); + QModelIndex index = currentIndex(); + d->m_excelModel->setData(index, value); + updateAll(); +} + +void GLDExcelIteratorTableView::doGridContextMenuRequest(QPoint value) +{ + Q_D(GLDExcelIteratorTableView); + QModelIndexList indexList = selectedIndexes(); + if (0 != d->m_selectedRows.count()) + { + d->m_selectedRows.clear(); + } + for(int i = 0; i < indexList.count(); ++i) + { + if (! d->m_selectedRows.contains(indexList[i].row() - c_DATA_BEGIN_ROWNO)) + { + d->m_selectedRows.push_back(indexList[i].row() - c_DATA_BEGIN_ROWNO); + } + } + + QModelIndex currentIndex = indexAt(value); + if (1 == d->m_selectedRows.count()) + { + if ((d->m_excelModel->inColMatchedResultRow(currentIndex)) + || (d->m_excelModel->inRowMatchedResultCol(currentIndex)) + || (0 == currentIndex.column()) + || (1 == currentIndex.row())) + { + return ; + } + d->m_contextMenu->popup(QCursor::pos()); + } + else + { + d->m_selectPopMenu->popup(QCursor::pos()); + } +} + +/* GLDExcellIteratorDelegate */ + +GLDExcellIteratorDelegate::GLDExcellIteratorDelegate(QObject *parent): + GlodonDefaultItemDelegate(parent) +{ + +} + +GEditStyle GLDExcellIteratorDelegate::editStyle(const QModelIndex &index, bool &readOnly) const +{ + if (index.row() >= c_DATA_BEGIN_ROWNO + && index.column() == c_IS_EXPORT_COLNO) + { + return esBool; + } + if (index.row() == 0 || index.column() == 1) + { + return esNone; + } + else + { + return GlodonDefaultItemDelegate::editStyle(index, readOnly); + } +} + +bool GLDExcellIteratorDelegate::editable(const QModelIndex &index) const +{ + if (index.row() >= c_titleRow + && index.column() >= c_IndexCol) + { + return false; + } + else + { + return true; + } +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDExtPropDefs.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDExtPropDefs.cpp new file mode 100644 index 00000000..bedd65c9 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDExtPropDefs.cpp @@ -0,0 +1,403 @@ +#include "GLDExtPropDefs.h" +#include "GLDStreamUtils.h" +#include "GLDException.h" +#include "GLDStrUtils.h" +#include "GLDGlobal.h" +#include "GLDStrings.h" + +class CGLDExtPropDefsPrivate +{ +public: + CGLDExtPropDefsPrivate(CGLDExtPropDefs *parent) + : q_ptr(parent), m_tag(0) + { + } + +private: + CGLDExtPropDefs * const q_ptr; + Q_DECLARE_PUBLIC(CGLDExtPropDefs); + + GLDHash m_codeHash; + GInterfaceObjectList m_list; + PtrInt m_tag; +}; + +/* CGLDExtPropDefs */ +CGLDExtPropDefs::CGLDExtPropDefs() : GInterfaceObject() + , d_ptr(new CGLDExtPropDefsPrivate(this)) +{ +} + +CGLDExtPropDefs::~CGLDExtPropDefs() +{ + Q_D(CGLDExtPropDefs); + d->m_codeHash.clear(); + d->m_list.clear(); + freePtr(d); +} + +CGLDExtPropDef *CGLDExtPropDefs::insertObj(long index) +{ + Q_D(CGLDExtPropDefs); + onChanging(); + CGLDExtPropDef *result = doCreateExtPropDef(); + if (index < 0 || index >= count()) + { + d->m_list.append(result); + } + else + { + d->m_list.insert(index, result); + } + freeCodeHash(); + onChanged(); + return result; +} + +CGLDExtPropDef *CGLDExtPropDefs::findObj(const GString &code) +{ + Q_D(CGLDExtPropDefs); + int nIndex = indexOf(code); + if (nIndex < 0) + return NULL; + else + return d->m_list[nIndex]; +} + +CGLDExtPropDef *CGLDExtPropDefs::itemObjs(long index) +{ + Q_D(CGLDExtPropDefs); + return d->m_list[index]; +} + +void CGLDExtPropDefs::loadFromStream(GStream *stream) +{ + clear(); + int nIntCount = readIntFromStream(stream); + for (int i = 0; i < nIntCount; i++) + { + insertObj(-1)->loadFromStream(stream); + } +} + +void CGLDExtPropDefs::saveToStream(GStream *stream) +{ + Q_D(CGLDExtPropDefs); + writeIntToStream(stream, d->m_list.count()); + for (int i = 0; i < d->m_list.count(); i++) + { + d->m_list[i]->saveToStream(stream); + } +} + +void CGLDExtPropDefs::compile() +{ + buildCodeHash(); +} + +void CGLDExtPropDefs::clearCompileInfo() +{ + freeCodeHash(); +} + +void CGLDExtPropDefs::assign(CGLDExtPropDefs *source) +{ + GMemoryStream stream; + // todo stream.setDevice(); + source->saveToStream(&stream); + stream.seek(0); + loadFromStream(&stream); +} + +CGLDExtPropDef *CGLDExtPropDefs::doCreateExtPropDef() +{ + return new CGLDExtPropDef(this); +} + +void CGLDExtPropDefs::onChanging() +{ + // 派生类实现 +} + +void CGLDExtPropDefs::onChanged() +{ + // 派生类实现 +} + +CGLDExtPropDef *CGLDExtPropDefs::addObj() +{ + return insertObj(-1); +} + +void CGLDExtPropDefs::buildCodeHash() +{ + Q_D(CGLDExtPropDefs); + d->m_codeHash.clear(); + for (int i = 0; i < d->m_list.count(); ++i) + { + GString code = d->m_list[i]->code(); + if (code.length() == 0) + { + gldError(getGLDi18nStr(g_MissingExtPropCode)); + } + else if (d->m_codeHash.contains(code)) + { + gldErrorFmt(getGLDi18nStr(g_ExtPropCodeExist), code); + } + else + { + d->m_codeHash.insert(code, i); + } + } +} + +void CGLDExtPropDefs::freeCodeHash() +{ + Q_D(CGLDExtPropDefs); + d->m_codeHash.clear(); +} + +CGLDExtPropDef * GSPMETHODCALLTYPE CGLDExtPropDefs::add() +{ + return insert(-1); +} + +CGLDExtPropDef * GSPMETHODCALLTYPE CGLDExtPropDefs::insert(long index) +{ + CGLDExtPropDef *result = insertObj(index); + if (result != NULL) + { + result->AddRef(); + } + return result; +} + +void GSPMETHODCALLTYPE CGLDExtPropDefs::Delete(long index) +{ + if (index < 0 || index >= count()) + return; + + Q_D(CGLDExtPropDefs); + d->m_list.removeAt(index); +} + +void GSPMETHODCALLTYPE CGLDExtPropDefs::remove(GString code) +{ + Delete(indexOf(code)); +} + +void GSPMETHODCALLTYPE CGLDExtPropDefs::move(long fromIndex, long toIndex) +{ + Q_D(CGLDExtPropDefs); + d->m_list.move(fromIndex, toIndex); +} + +void GSPMETHODCALLTYPE CGLDExtPropDefs::clear() +{ + Q_D(CGLDExtPropDefs); + d->m_codeHash.clear(); + d->m_list.clear(); +} + +CGLDExtPropDef * GSPMETHODCALLTYPE CGLDExtPropDefs::find(GString code) +{ + CGLDExtPropDef *result = findObj(code); + if (result != NULL) + { + result->AddRef(); + } + return result; +} + +long GSPMETHODCALLTYPE CGLDExtPropDefs::indexOf(GString code) +{ + Q_D(CGLDExtPropDefs); + if (!d->m_codeHash.isEmpty()) + { + return d->m_codeHash.value(code, -1); + } + else + { + for (int i = 0; i < d->m_list.count(); i++) + { + if (sameText(d->m_list[i]->code(), code)) + return i; + } + return -1; + } +} + +long GSPMETHODCALLTYPE CGLDExtPropDefs::count() +{ + Q_D(CGLDExtPropDefs); + return d->m_list.count(); +} + +CGLDExtPropDef * GSPMETHODCALLTYPE CGLDExtPropDefs::items(long index) +{ + CGLDExtPropDef *result = itemObjs(index); + if (result != NULL) + { + result->AddRef(); + } + return result; +} + +GString GSPMETHODCALLTYPE CGLDExtPropDefs::asString() +{ + Q_D(CGLDExtPropDefs); + GString result; + if (d->m_list.count() == 0) + return result; + for (int i = 0; i < d->m_list.count(); i++) + { + result.append(" | ").append(d->m_list[i]->asString()); + } + return result; +} + +void GSPMETHODCALLTYPE CGLDExtPropDefs::setAsString(GString value) +{ + GStringList values = value.split("|"); + clear(); + for (int i = 0; i < values.count(); i++) + { + GString value = trim(values[i]); + if (value.length() > 0) + { + insertObj(-1)->setAsString(value); + } + } +} + +CGLDExtPropDef * GSPMETHODCALLTYPE CGLDExtPropDefs::extPropByName(GString code) +{ + CGLDExtPropDef *result = findObj(code); + if (result != NULL) + result->AddRef(); + return result; +} + +PtrInt GSPMETHODCALLTYPE CGLDExtPropDefs::tag() +{ + Q_D(CGLDExtPropDefs); + return d->m_tag; +} + +void GSPMETHODCALLTYPE CGLDExtPropDefs::setTag(PtrInt value) +{ + Q_D(CGLDExtPropDefs); + d->m_tag = value; +} + +class CGLDExtPropDefPrivate +{ +public: + CGLDExtPropDefPrivate(CGLDExtPropDef *parent) + : q_ptr(parent) + { + } + +private: + CGLDExtPropDef * const q_ptr; + Q_DECLARE_PUBLIC(CGLDExtPropDef); + + CGLDExtPropDefs *m_owner; + GString m_code; + GString m_value; + PtrInt m_tag; +}; +/* CGLDExtPropDef */ + +CGLDExtPropDef::CGLDExtPropDef(CGLDExtPropDefs *owner) + : d_ptr(new CGLDExtPropDefPrivate(this)), GInterfaceObject() + +{ + Q_D(CGLDExtPropDef); + assert(owner != NULL); + d->m_owner = owner; + d->m_tag = 0 ; +} + +CGLDExtPropDef::~CGLDExtPropDef() +{ + Q_D(CGLDExtPropDef); + freePtr(d); +} + +void CGLDExtPropDef::loadFromStream(GStream *stream) +{ + setCode(readStrFromStream(stream)); + setValue(readMemoFromStream(stream)); +} + +void CGLDExtPropDef::saveToStream(GStream *stream) +{ + Q_D(CGLDExtPropDef); + writeStrToStream(stream, d->m_code); + writeMemoToStream(stream, d->m_value); +} + +GString GSPMETHODCALLTYPE CGLDExtPropDef::code() +{ + Q_D(CGLDExtPropDef); + return d->m_code; +} + +void GSPMETHODCALLTYPE CGLDExtPropDef::setCode(GString value) +{ + Q_D(CGLDExtPropDef); + d->m_owner->onChanging(); + d->m_code = trim(value); + d->m_owner->freeCodeHash(); + d->m_owner->onChanged(); +} + +GString GSPMETHODCALLTYPE CGLDExtPropDef::value() +{ + Q_D(CGLDExtPropDef); + return d->m_value; +} + +void GSPMETHODCALLTYPE CGLDExtPropDef::setValue(GString value) +{ + Q_D(CGLDExtPropDef); + d->m_owner->onChanging(); + d->m_value = value; + d->m_owner->onChanged(); +} + +GString GSPMETHODCALLTYPE CGLDExtPropDef::asString() +{ + Q_D(CGLDExtPropDef); + return d->m_code + "=" + d->m_value; +} + +void GSPMETHODCALLTYPE CGLDExtPropDef::setAsString(GString value) +{ + Q_D(CGLDExtPropDef); + GStringList list = value.split("="); + + if (list.count() != 2) + { + d->m_code = ""; + d->m_value = ""; + } + else + { + d->m_code = list[0]; + d->m_value = list[1]; + } +} + +PtrInt GSPMETHODCALLTYPE CGLDExtPropDef::tag() +{ + Q_D(CGLDExtPropDef); + return d->m_tag; +} + +void GSPMETHODCALLTYPE CGLDExtPropDef::setTag(PtrInt value) +{ + Q_D(CGLDExtPropDef); + d->m_tag = value; +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDFileUtils.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDFileUtils.cpp new file mode 100644 index 00000000..e0ed2d91 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDFileUtils.cpp @@ -0,0 +1,555 @@ +/************************************************************************* +* * +* 广联达文件类相关公共函数单元 CPP * +* * +* 设计:Zhangsk 2012.05.21 * +* 备注: * +* 审核: * +* * +* Copyright (c) 2012-2013 Glodon Corporation * +* * +*************************************************************************/ + +#include "GLDFileUtils.h" +#include +#include +#include +#include "GLDDir.h" +#include "GLDFile.h" +#include "GLDFileInfo.h" +#include "GLDException.h" +#include "GLDGlobal.h" +#include "GLDSysUtils.h" + +#ifdef WIN32 +#include +#endif + +G_GLODON_BEGIN_NAMESPACE +G_GLODON_END_NAMESPACE + +/************************************************************************* + 作者: yanyq-a 2013-07-31 + 参数: 无 + 返回: GString + 功能: 获取exe文件完整名称 +*************************************************************************/ +GString exeFullName() +{ +#ifdef WIN32 + // 不支持长路径?? + wchar_t szModuleName[MAX_PATH + 1] = {0}; + GetModuleFileName(NULL, szModuleName, MAX_PATH + 1); + GString strPath = GString::fromUtf16((ushort *)szModuleName); + return strPath; +#else + return qApp->applicationName(); +#endif +} + +/************************************************************************* + 说明:返回当前运行EXE文件的路径 + 参数:无 + 返回:当前运行EXE文件的路径 +*************************************************************************/ +GString exePath() +{ + return exeDir() + pathDelim(); //获取当前应用程序路径 +} + +GString exeDir() +{ +#ifdef WIN32 + GString strPath = exeFullName(); + int nIndex = strPath.lastIndexOf('\\'); + if (nIndex < 0) + { + nIndex = strPath.lastIndexOf('/'); + if (nIndex < 0) + { + return GString(); + } + } + strPath = strPath.left(nIndex); + return strPath; +#else + return QCoreApplication::applicationDirPath(); //获取当前应用程序路径 +#endif +} + +GString moduleName(void *module) +{ + // todo + return exeFullName(); + G_UNUSED(module) +} + +GString getCurrentDir() +{ + return GDir::currentPath(); +} + +bool isLibrary() +{ + const GString strModuleName = moduleName(NULL); + const GString strModuleExt = extractFileExt(strModuleName); + + return GString::compare(strModuleExt, ".dll", Qt::CaseInsensitive) == 0; +} + +bool fileExists(const GString &fileName) +{ + GFileInfo fileInfo(fileName); + + if (fileInfo.isDir()) + { + return false; + } + + return GFile::exists(fileName); +} + +GStream *createFileStream(const GString &fileName) +{ + return new GFileStream(fileName); +} + +GString extractFileExt(const GString &fileName) +{ + int nIndex = rPos('.', fileName); + if (nIndex >= 0 && fileName[nIndex] == '.') + { + return copy(fileName, nIndex); + } + else + { + return GString(); + } +} + +GString changeFileExt(const GString &fileName, const GString &extension) +{ + GString sFileName = fileName; + GFileInfo info(sFileName); + GString sResult(sFileName); + sResult = sResult.replace(info.suffix(), extension); + return sResult; +} + +/************************************************************************* + *作者: zhouyl-a 2013-8-8 + *参数: + * 1)oldFile : 被拷贝的文件名 + * 2)newFile : 新文件名 + * 3)failIfExists : 操作标识; failIfExists == true 则是如果文件存在就失败; + * failIfExists == false则是如果文件存在就覆盖; + *返回:true 成功, false 失败 +*************************************************************************/ +bool copyFile(const GString &oldFile, const GString &newFile, bool failIfExists) +{ + // 如果 failIfExists 为真,且newFile存在,直接返回 + if (failIfExists && fileExists(newFile)) + { + return false; + } + + // 如果 failIfExists 为假,且newFile存在 + if (!failIfExists && fileExists(newFile)) + { + //删除newFile + GFile::remove(newFile); + } + + return (GFile::copy(oldFile, newFile)); + +} + +bool deleteFile(const GString &fileName) +{ + if (fileExists(fileName)) + { + return GFileStream::remove(fileName); + } + return false; +} + +bool deleteTree(const GString &path) +{ + if (path.isEmpty()) + return false; + GString strPath = includeTrailingPathDelimiter(path); + GDir dir(strPath); + if (!dir.exists()) + return true; + + GFileInfoList fileList = dir.entryInfoList(GDir::AllEntries | GDir::Hidden); + GString strFileName; + GString strFile; + foreach (GFileInfo fileInfo, fileList) + { + strFileName = fileInfo.fileName(); + if ((strFileName == GString("..")) || (strFileName == GString("."))) + continue; + if (fileInfo.isDir()) + { + strFile = strPath + strFileName + "/"; + deleteTree(strFile); + } + else + { + strFile = strPath + strFileName; + if (!fileInfo.permission(GFileStream::WriteOwner)) + { + GFileStream file(strFile); + file.setPermissions(GFileStream::WriteOwner); + } + GFileStream::remove(strFile); + } + } + return dir.rmdir(strPath); +} + +/************************************************************************* + 作者: jiangjb 2013-06-04 + 参数: const GString &, GStrings & + 返回: 无 + 功能: 得到所有子目录 +*************************************************************************/ +void findSubFolders(const GString &path, GStrings &folders) +{ + GDir oDir(path); + + oDir.setFilter(GDir::Dirs | GDir::NoDotAndDotDot); + folders.clear(); + folders = oDir.entryList(); +} + +/************************************************************************* + 作者: jiangjb 2013-06-26 + 参数: const GString &, const GStrings &, GStrings & + 返回: 无 + 功能: 通过后缀名寻找目录下以及当前目录下所有子目录的所有文件 +*************************************************************************/ +void findFiles(const GString &path, const GStrings &nameFilters, GStrings &files) +{ + GDir oDir(path); + oDir.setFilter(GDir::Files | GDir::NoDotAndDotDot); + + if (nameFilters.size() == 1) + { + if (!nameFilters.at(0).isEmpty()) + { + oDir.setNameFilters(nameFilters); + } + } + else + { + oDir.setNameFilters(nameFilters); + } + + GStrings oFiles = oDir.entryList(); + for (int i = 0; i < oFiles.size(); i++) + { + files.append(includeTrailingPathDelimiter(path) + oFiles.at(i)); + } + + GStrings oSubFileDirs; + findSubFolders(path, oSubFileDirs); + for (int i = 0; i < oSubFileDirs.size(); i++) + { + findFiles((includeTrailingPathDelimiter(path) + oSubFileDirs.at(i)), nameFilters, files); + } +} + +/************************************************************************* + 作者: jiangjb 2013-06-26 + 参数: const GString &, GStrings &, const GString & + 返回: 无 + 功能: 通过后缀名寻找目录下以及当前目录下所有子目录的所有文件 +*************************************************************************/ +void findFiles(const GString &path, const GString &nameFilter, GStrings &files) +{ + GStrings oNameFilters; + if (nameFilter.isEmpty()) + { + oNameFilters.append("*.*"); + + } + else + { + oNameFilters.append(nameFilter); + } + + findFiles(path, oNameFilters, files); +} + +/************************************************************************* + 作者: jiangjb 2013-06-26 + 参数: const GString &, GStrings &, const GString &, bool + 返回: 无 + 功能: 通过后缀名寻找当前目录下所有文件 +*************************************************************************/ +void getFiles(const GString &path, GStrings &files, const GString &nameFilter) +{ + GStrings oNameFilters; + if (nameFilter.isEmpty()) + { + oNameFilters.append("*.*"); + + } + else + { + oNameFilters.append(nameFilter); + } + + getFiles(path, oNameFilters, files); +} + +void getFiles(const GString &path, const GStrings &nameFilters, GStrings &files, bool includeDir) +{ + GDir oDir(path); + if (includeDir) + { + oDir.setFilter(GDir::Files | GDir::Dirs | GDir::NoDotAndDotDot); + } + else + { + oDir.setFilter(GDir::Files | GDir::NoDotAndDotDot); + } + + if (nameFilters.size() == 1) + { + if (!nameFilters.at(0).isEmpty()) + { + oDir.setNameFilters(nameFilters); + } + } + else + { + oDir.setNameFilters(nameFilters); + } + + files.append(oDir.entryList()); +} + +/************************************************************************* + 作者: yanyq-a 2013-07-31 + 参数: GString& + 返回: GString + 功能: 获取操作系统可接受的文件名(对应原GetValidFileName) +*************************************************************************/ +GString getValidFileName(const GString &fileName) +{ + GStrings oInvalidChars = (GStrings() << "\\" << "/" << ":" << "\"" << ">" << "<" << "\r\n" << "|" << "?" << "*"); + GString sValidFileName(fileName); + for (int i = 0; i < oInvalidChars.count(); ++i) + { + sValidFileName.replace(oInvalidChars[i], "_", Qt::CaseInsensitive); + } + + return sValidFileName; +} + +bool createDir(const GString &path) +{ + GDir oDir; + return oDir.mkdir(path); +} + +bool forceDirectories(const GString &path) +{ + if (path.isEmpty()) + return false; + GString strDir = excludeTrailingPathDelimiter(path); + GDir oDir(strDir); + if (oDir.exists()) + return true; + return oDir.mkpath(strDir); +// GString strParentDir = extractFilePath(strDir); +// if (sameText(strParentDir, strDir)) +// return true; +// return forceDirectories(strParentDir) && oDir.mkdir(strDir); +} + +bool directoryExists(const GString &path) +{ + if (path.isEmpty()) + { + return false; + } + GDir oDir(path); + return oDir.exists(); +} + +GString extractFilePath(const GString &fileName) +{ + int nIndex = pathDelimPos(fileName); + if (nIndex >= 0) + return copy(fileName, 0, nIndex + 1); + else + { + return GString(); + } +} + +/************************************************************************* + 作者: jiangjb 2013-06-20 + 参数: const GString & + 返回: GString + 功能: 从文件名中获取目录名(文件不在根目录下时取得的值后没有“/”,在根目录时一样,都是盘符,例如“C:/”) +*************************************************************************/ +GString extractFileDir(const GString &fileName) +{ + int nIndex = pathDelimPos(fileName); + if (nIndex >= 0) + { + if ((nIndex >= 1) && (fileName[nIndex - 1] == driveDelim())) + { + ++nIndex; + } + return copy(fileName, 0, nIndex); + } + else + return GString(); +} + +GString extractFileName(const GString &fileName) +{ + int nIndex = pathDelimPos(fileName); + return copy(fileName, nIndex + 1); +} + +GString extractFileNameOnly(const GString &fileName) +{ + GString result = extractFileName(fileName); + int nDotPos = rPos(GChar('.'), result); + if (nDotPos >= 0) + return copy(result, 0, nDotPos); + else + return result; +} + +// 相对路径转换为绝对路径 +GString expandFileName(const GString &fileName) +{ + GFileInfo oFileInfo(fileName); +#ifdef WIN32 + return oFileInfo.absoluteFilePath().replace(GChar('/'), pathDelim()); +#else + return oFileInfo.absoluteFilePath(); +#endif +} + +/************************************************************************* + 作者: jiangjb 2013-06-14 + 参数: const GString &, bool + 返回: 无 + 功能: 设置文件只读 +*************************************************************************/ +void fileSetReadOnly(const GString &fileName, bool readOnly) +{ + if (readOnly) + { + GFileStream::setPermissions(fileName, GFileStream::ReadOther); + } + else + { + GFileStream::setPermissions(fileName, GFileStream::WriteOther | GFileStream::ReadOther); + } +} + +/************************************************************************* + + 作者:liudi 2013 原作者: + 参数:const GString &fileName + 返回:gint64 + 功能: 返回文件大小 + + 这个函数原来在TGBQ4ZipFileUtils中 +*************************************************************************/ +gint64 getFileSize(const GString &fileName) +{ + GFileInfo fileInfo(fileName); + + return fileInfo.size(); +} + +/************************************************************************* + 作者: zhangjq 2013-09-25 + 参数: path:基础路径;productName:当前产品名称;version:当前产品版本 + xxxx\CompanyName\ProductName\ProductVersion + 返回: + 功能: 返回符合公司规范的文件路径 +*************************************************************************/ +GString getProductPath(const GString &path, const GString &productName, const GString &version) +{ + return GString("%1GrandSoft\\%2\\%3").arg(includeTrailingPathDelimiter(path), productName, version); +} + +GString getCommonDocumentsPath() +{ +#ifdef Q_OS_WIN + return getSpecialFolderPath(CSIDL_COMMON_DOCUMENTS); +#else + return GString(""); +#endif +} + +GString getTempFile(const GString &prefix, const GString &path) +{ + QTemporaryFile tempFile(includeTrailingPathDelimiter(path) + prefix + "XXXXXX.tmp"); + tempFile.setAutoRemove(false); + if (tempFile.open()) + { + GString result = tempFile.fileName(); + tempFile.close(); + return result; + } + return GString(); +} + +int pathDelimPos(const GString &fileName) +{ + int nPathDelimPos = rPos(pathDelim(), fileName); + int nBackSlashPos = rPos(backSlashDelim(), fileName); + return (nPathDelimPos > nBackSlashPos ? nPathDelimPos : nBackSlashPos); +} + +GString getCommandLineOutput( + const GString &commandLine, const GString &workDir, int &exitCode) +{ + QProcess process; + //process.setReadChannel(QProcess::StandardOutput); + //process.setReadChannelMode(ForwardedChannels); + process.setWorkingDirectory(workDir); + process.start(commandLine); + if (!process.waitForFinished(-1)) + { + exitCode = -2; + return GString(); + } + if (process.exitStatus() == QProcess::NormalExit) + { + exitCode = process.exitCode(); + GByteArray array = process.readAllStandardOutput(); + return GString::fromLocal8Bit(array.constData()); + } + else + { + exitCode = -1; + return GString(); + } +} + +GString loadQssFile(const GString &fileName) +{ + GFile oQssFile(fileName); + if (!oQssFile.open(QIODevice::ReadOnly)) + { + return QString(); + } + else + { + return oQssFile.readAll(); + } +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDFloatFormating.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDFloatFormating.cpp new file mode 100644 index 00000000..e98c1ffa --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDFloatFormating.cpp @@ -0,0 +1,614 @@ +#include "GLDFloatFormating.h" +#include "GLDGlobal.h" +#include "GLDMathUtils.h" +#include "GLDStrUtils.h" + +#if defined(WIN64) || defined(__APPLE__) +const int c_MaxExtPrecision = 18; +#else +const int c_MaxExtPrecision = 16; +#endif + +void floatToDecimal(FloatRec *result, double value, int precision, int decimals); + +class GLDFloatFormatingPrivate +{ +public: + GLDFloatFormatingPrivate(GLDFloatFormating *parent); + +private: + GLDFloatFormating * const q_ptr; + Q_DECLARE_PUBLIC(GLDFloatFormating); + + char m_decimalSep; //小数点符号 + int m_decimalIndex; //小数点在Format里的位置 + char m_thousandsSep; //千分位符号 + bool m_thousandSep; //是否有千分位符号 + GString m_section; //格式字符串 + GString m_format; //传入的格式字符串 + bool m_scientific; //是否是科学计数法 + int m_firstDigit; //第一个数字所在位置 + int m_digitCount; //格式化字符串里数字的个数 + int m_lastDigit; //最后一个数字所在的位置 + FloatRec m_floatValue; + + int m_digitPlace; + int m_digitDelta; + int m_digitLimit; + int m_digitsC; + GString m_result; //返回结果 +}; + +GLDFloatFormatingPrivate::GLDFloatFormatingPrivate(GLDFloatFormating *parent) + : q_ptr(parent), m_decimalSep('.'), m_decimalIndex(-1), m_thousandsSep(','), + m_thousandSep(false), m_section(""), m_format(""), m_firstDigit(32767), m_digitCount(0), m_lastDigit(0), + m_digitPlace(-1), m_digitDelta(-1), m_digitLimit(-1), m_digitsC(-1) +{ +} + +GLDFloatFormating::GLDFloatFormating(): d_ptr(new GLDFloatFormatingPrivate(this)) +{ +} + +GLDFloatFormating::~GLDFloatFormating() +{ + Q_D(GLDFloatFormating); + freePtr(d); +} + +GString GLDFloatFormating::formatFloat(double value, const GString &format) +{ + GString strResult = ""; + GLDFloatFormating *pFloatFormating = new GLDFloatFormating(); + try + { + strResult = pFloatFormating->internalFloatToTextFmt(value, format); + } + catch (...) + { + freeAndNil(pFloatFormating); + throw; + } + freeAndNil(pFloatFormating); + return strResult; +} + +GString GLDFloatFormating::internalFloatToTextFmt(double value, const GString &format) +{ + Q_D(GLDFloatFormating); + d->m_format = format; + value += 1e-12; // double类型精度会丢失,遇到类似于3.315这种保留2位小数的情况,会丢失精度,在此做一个补偿 + + int nIndex = 0; + if (value > 0) + { + nIndex = 0; + } + else + { + if (value < 0) + { + nIndex = 1; + } + else + { + nIndex = 2; + } + } + + int nSectionIndex = findSection(nIndex); + d->m_section = scanSection(nSectionIndex); + int nPrecision = -1; + int nDigits = -1; + if (d->m_scientific) + { + nPrecision = d->m_digitCount; + nDigits = 9999; + } + else + { + nPrecision = c_MaxExtPrecision; + nDigits = d->m_digitCount - d->m_decimalIndex; + } + floatToDecimal(&d->m_floatValue, value, nPrecision, nDigits); + if ((0 == d->m_format.length()) || (QChar(';') == d->m_format[0]) + || ((d->m_floatValue.exponent >= 18) && (!d->m_scientific)) + || (0x7ff == d->m_floatValue.exponent) || (0x800 == d->m_floatValue.exponent)) + { + d->m_result = floatToStr(value); + } + else + { + applyFormat(nSectionIndex); + } + + return d->m_result; +} + +int GLDFloatFormating::findSection(int index) +{ + Q_D(GLDFloatFormating); + int nSection = 0; + int nCharIndex = 0; + + int nFormatLength = d->m_format.length(); + while ((nSection != index) && (nCharIndex < nFormatLength)) + { + switch (d->m_format.at(nCharIndex).toLatin1()) + { + case ';': + { + nSection++; + nCharIndex++; + break; + } + case '\"': + { + nCharIndex++; + while ((nCharIndex < nFormatLength) && (QChar('\"') != d->m_format.at(nCharIndex))) + { + nCharIndex++; + } + if (nCharIndex < nFormatLength) + { + nCharIndex++; + } + break; + } + case '\'': + { + nCharIndex++; + while ((nCharIndex < nFormatLength) && (QChar('\'') != d->m_format.at(nCharIndex))) + { + nCharIndex++; + } + if (nCharIndex < nFormatLength) + { + nCharIndex++; + } + break; + } + default: + { + nCharIndex++; + } + } + } + if ((nSection < index) || (nCharIndex == nFormatLength)) + { + return 0; + } + else + { + return nCharIndex; + } +} + +GString GLDFloatFormating::scanSection(int pos) +{ + Q_D(GLDFloatFormating); + d->m_scientific = false; + int nCharIndex = pos; + int nFormatLength = d->m_format.length(); + while ((nCharIndex < nFormatLength) && (QChar(';') != d->m_format[nCharIndex])) + { + switch (d->m_format[nCharIndex].toLatin1()) + { + case ',': + { + d->m_thousandSep = true; + nCharIndex++; + break; + } + case '.': + { + if (-1 == d->m_decimalIndex) + { + d->m_decimalIndex = d->m_digitCount; + } + nCharIndex++; + break; + } + case '\"': + { + nCharIndex++; + while ((nCharIndex < nFormatLength) && (QChar('\"') != d->m_format[nCharIndex])) + { + nCharIndex++; + } + if (nCharIndex < nFormatLength) + { + nCharIndex++; + } + break; + } + case '\'': + { + nCharIndex++; + while ((nCharIndex < nFormatLength) && (QChar('\'') != d->m_format[nCharIndex])) + { + nCharIndex++; + } + if (nCharIndex < nFormatLength) + { + nCharIndex++; + } + break; + } + case 'e': + case 'E': + { + nCharIndex++; + if (nCharIndex < nFormatLength) + { + QChar aChar = d->m_format[nCharIndex]; + if ((QChar('_') == aChar) || (QChar('+') == aChar)) + { + d->m_scientific = true; + nCharIndex++; + while ((nCharIndex < nFormatLength) && (QChar('0') == d->m_format[nCharIndex])) + { + nCharIndex++; + } + } + } + break; + } + case '#': + { + d->m_digitCount++; + nCharIndex++; + break; + } + case '0': + { + if (d->m_digitCount < d->m_firstDigit) + { + d->m_firstDigit = d->m_digitCount; + } + d->m_digitCount++; + d->m_lastDigit = d->m_digitCount; + nCharIndex++; + break; + } + default: + { + nCharIndex++; + } + } + } + + if (-1 == d->m_decimalIndex) + { + d->m_decimalIndex = d->m_digitCount; + } + d->m_lastDigit = d->m_decimalIndex - d->m_lastDigit; + if (d->m_lastDigit > 0) + { + d->m_lastDigit = 0; + } + + d->m_firstDigit = d->m_decimalIndex - d->m_firstDigit; + if (d->m_firstDigit < 0) + { + d->m_firstDigit = 0; + } + GString result = d->m_format.mid(pos, nCharIndex - pos); + return result; +} + +void GLDFloatFormating::applyFormat(int sectionIndex) +{ + Q_D(GLDFloatFormating); + if ((d->m_floatValue.negative) && (0 == sectionIndex)) + { + d->m_result.append("-"); + } + + if (d->m_scientific) + { + d->m_digitPlace = d->m_decimalIndex; + d->m_digitDelta = 0; + } + else + { + d->m_digitDelta = d->m_floatValue.exponent - d->m_decimalIndex; + if (d->m_digitDelta >= 0) + { + d->m_digitPlace = d->m_floatValue.exponent; + } + else + { + d->m_digitPlace = d->m_decimalIndex; + } + } + + d->m_digitLimit = digitsLength() - 1; + int nCharIndex = 0; + d->m_digitsC = 0; + QChar oldC; + while (nCharIndex <= d->m_section.length()) + { + switch (d->m_section[nCharIndex].toLatin1()) + { + case '0': + case '#': + { + putFmtDigit(); + nCharIndex++; + break; + } + case '.': + case ',': + { + nCharIndex++; + break; + } + case '\"': + case '\'': + { + oldC = d->m_section[nCharIndex]; + nCharIndex++; + while ((nCharIndex < d->m_section.length()) && (oldC != d->m_section[nCharIndex])) + { + d->m_result.append(d->m_section[nCharIndex]); + nCharIndex++; + } + nCharIndex++; + break; + } + case 'E': + case 'e': + { + oldC = d->m_section[nCharIndex]; + nCharIndex++; + if (nCharIndex <= d->m_section.length()) + { + QChar sign = d->m_section[nCharIndex]; + if ((QChar('+') == sign) && (QChar('-') == sign)) + { + d->m_result.append(oldC); + } + else + { + int nZeros = 0; + nCharIndex++; + while ((nCharIndex <= d->m_section.length()) && (QChar('0') == d->m_section[nCharIndex])) + { + nCharIndex++; + if (nZeros < 4) + { + nZeros++; + } + } + putExponent(oldC, sign, nZeros, d->m_floatValue.exponent - d->m_decimalIndex); + } + } + break; + } + default: + { + nCharIndex++; + } + } + } +} + +int GLDFloatFormating::digitsLength() +{ + Q_D(GLDFloatFormating); + int result = 0; + while ((result < 20) && (d->m_floatValue.digits[result] != '\0')) + { + result++; + } + return result; +} + +void GLDFloatFormating::putFmtDigit() +{ + Q_D(GLDFloatFormating); + if (d->m_digitDelta < 0) + { + d->m_digitDelta++; + if (d->m_digitPlace <= d->m_firstDigit) + { + writeDigit('0'); + } + else + { + d->m_digitPlace--; + } + } + else + { + if (d->m_digitDelta == 0) + { + addDigit(); + } + else + { + while (d->m_digitDelta > 0) + { + addDigit(); + d->m_digitDelta--; + } + addDigit(); + } + } +} + +void GLDFloatFormating::writeDigit(char digit) +{ + Q_D(GLDFloatFormating); + if (0 == d->m_digitPlace) + { + d->m_result.append(d->m_decimalSep); + d->m_result.append(digit); + d->m_digitPlace--; + } + else + { + d->m_result.append(digit); + d->m_digitPlace--; + if (d->m_thousandSep && (d->m_digitPlace > 1) && (0 == (d->m_digitPlace % 3))) + { + d->m_result.append(d->m_thousandsSep); + } + } +} + +void GLDFloatFormating::addDigit() +{ + Q_D(GLDFloatFormating); + if (d->m_digitsC <= d->m_digitLimit) + { + char cChar = d->m_floatValue.digits[d->m_digitsC]; + d->m_digitsC++; + writeDigit(cChar); + } + else + { + if (d->m_digitPlace <= d->m_lastDigit) + { + d->m_digitPlace--; + } + else + { + writeDigit('0'); + } + } +} + +void GLDFloatFormating::putExponent(QChar eChar, QChar sign, int zeros, int exponent) +{ + Q_D(GLDFloatFormating); + d->m_result.append(eChar); + GString writeSign; + if ((QChar('+') == sign) && (exponent >= 0)) + { + writeSign = "+"; + } + else + { + if (exponent < 0) + { + writeSign = "-"; + } + else + { + writeSign = ""; + } + } + GString exp = intToStr(abs(exponent)); + for (int i = 0; i < zeros - exp.length(); i++) + { + exp = '0' + exp; + } + exp = writeSign + exp; + d->m_result.append(exp); +} + +/*! + * \brief 把浮点数转成十进制 + * \param result + * \param value + * \param precision + * \param decimals + */ +void floatToDecimal(FloatRec *result, double value, int precision, int decimals) +{ + result->negative = value < 0; + + if (fabs(value) < 1e-16) + { + result->exponent = 0; + result->digits[0] = '\0'; + return; + } + + if (result->negative) + { + value = fabs(value); + } + + GString strDigits = GString::number(value, 'f', 18); + result->exponent = strDigits.indexOf("."); //算出小数点前的位数 + int nStrIndex = 0; + if (value < 1) //小数前的那个0不算 + { + result->exponent = 0; + nStrIndex = 1; + } + int nIndex = 0; + while (true) //把数字压入floatRec中 + { + if (strDigits[nStrIndex] == QChar('.')) + { + nStrIndex++; + continue; + } + if (nStrIndex > 19 || (nStrIndex >= strDigits.length())) + { + break; + } + result->digits[nIndex] = strDigits[nStrIndex].toLatin1(); + nStrIndex++; + nIndex++; + } + + if (result->exponent + decimals < 0) + { + result->exponent = 0; + result->negative = false; + result->digits[0] = 0; + return; + } + + nStrIndex = result->exponent + decimals; + if (nStrIndex > precision) + { + nStrIndex = precision; + } + + if ((nStrIndex >= 18) || (result->digits[nStrIndex] < '5')) + { + if (nStrIndex > 18) + { + nStrIndex = 18; + } + while (true) + { + result->digits[nStrIndex] = 0; + nStrIndex--; + if (nStrIndex < 0) + { + result->negative = false; + return; + } + if (result->digits[nStrIndex] != '0') + { + return; + } + } + } + else //以下会做四舍五入 + { + while (true) + { + result->digits[nStrIndex] = 0; + nStrIndex--; + if (nStrIndex < 0) + { + result->digits[0] = '1'; + result->exponent++; + return; + } + result->digits[nStrIndex]++; + if (result->digits[nStrIndex] <= '9') + { + return; + } + } + } +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDGlobal.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDGlobal.cpp new file mode 100644 index 00000000..0c07c58d --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDGlobal.cpp @@ -0,0 +1,98 @@ +#include "GLDGlobal.h" + +#ifndef _MSC_VER +# include +#endif + +void *gMalloc(size_t size) +{ +#ifdef GDP_QT + return ::malloc(size); +#else + return ::malloc(size); +#endif +} + +void gFree(void *ptr) +{ +#ifdef GDP_QT + ::free(ptr); +#else + ::free(ptr); +#endif +} + +void *gRealloc(void *ptr, size_t size) +{ +#ifdef GDP_QT + return ::realloc(ptr, size); +#else + return ::realloc(ptr, size); +#endif +} + +//void *gMallocAligned(size_t size, size_t alignment) +//{ +//#ifdef GDP_QT +// return qMallocAligned(size, alignment); +//#else +// return qMallocAligned(size, alignment); +//#endif +//} + +//void *gReallocAligned(void *ptr, size_t size, size_t oldsize, size_t alignment) +//{ +//#ifdef GDP_QT +// return qReallocAligned(ptr, size, oldsize, alignment); +//#else +// return qReallocAligned(ptr, size, oldsize, alignment); +//#endif +//} + +//void gFreeAligned(void *ptr) +//{ +//#ifdef GDP_QT +// qFreeAligned(ptr); +//#else +// qFreeAligned(ptr); +//#endif +//} + +//void freeAndNil(void **p) +//{ +// if (*p) +// delete (*p); +// *p = nullptr; +//} + +void *gMemCopy(void *dest, const void *src, size_t n) +{ +#ifdef GDP_QT + return ::memcpy(dest, src, n); +#else + return ::memcpy(dest, src, n); +#endif +} + +void *gMemSet(void *dest, int c, size_t n) +{ +#ifdef GDP_QT + return memset(dest, c, n); +#else + return ::memset(dest, c, n); +#endif +} + +void gMemMove(void *dest, const void *src, size_t n) +{ +#ifdef GDP_QT + ::memmove(dest, src, n); +#else + ::memmove(dest, src, n); +#endif +} + +#ifdef TEST_GSP +int g_sumTime = 0; +int g_sumCount = 0; +#endif diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDGridSetting.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDGridSetting.cpp new file mode 100644 index 00000000..8d83d338 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDGridSetting.cpp @@ -0,0 +1,8258 @@ +#include "GLDGridSetting.h" +#include "GLDStreamUtils.h" +#include "GLDStrings.h" +#include "GLDStrUtils.h" +#include "GLDFileInfo.h" +#include "GLDGridSettingXMLBuilder.h" +#include "GLDException.h" + +const char *SNeedDesignState = QT_TRANSLATE_NOOP("GLD", "This Operation Can Only Be Used in Design Status");// "该操作只能在设计状态下使用"); +//const char *SNeedRunState = QT_TRANSLATE_NOOP("GLD", "This Operation Can Only Be Used in Running Status");// "该操作只能在运行状态下使用"); +//const char *SInvalidFieldName = QT_TRANSLATE_NOOP("GLD", "Invalid Edit Field Name[%1] of Table[%2]");// "表[%s]非法编辑字段名[%s]"); +const char *SInvalidSaveFieldName = QT_TRANSLATE_NOOP("GLD", "Table[%s] has a valide written field name[%s]");// "表[%s]非法写入字段名[%s]"); +//const char *SInvalidFieldNameMark = QT_TRANSLATE_NOOP("GLD", "Table [%1] has illegal field name [%2]");// "表[%s]非法字段名称[%s],\"&\"后必须为枚举字段、表达式字段、时间日期字段"); +const char *SInvalidHeaderRowExpr = QT_TRANSLATE_NOOP("GLD", "Table [%s] has a invalid header row expression [%s]");// "表[%s]非法带区标题行表达式[%s]"); +//const char *SNotExistVisibleCol = QT_TRANSLATE_NOOP("GLD", "No Non Fixed Column to Display");// "没有可显示的非固定列"); + +const char *CDefInvalidValueLabel = QT_TRANSLATE_NOOP("GLD", "! invalid value");// "!非法值"); +const GString CDefFontName = TRANS_STRING("宋体"); + +const char *CDefFormatStr = "";// ""); +const char *CDefComment = "";// ""); +const char *CDelimiter = "*##*";// "*##*"); + +const GLDDataType c_gdtString = 12; +const char *g_GLDGridSettingVersion = "2.2.5"; +const char *g_EditText = "@EditText"; +const char *g_TitleCaptionDelimiter = "||"; + +const GString c_GLDCellSuitTypeStrings[4] = +{ + "cstFixed", "cstSuitRowHeight", "cstSuitColWidth", "cstFitColWidth" +}; +const GString c_GLDGridRuleTypeStrings[20] = +{ + "grtFont", "grtBackColor", "grtEditStyle", "grtBoundLine", "grtAlignment", + "grtMargin", "grtReadonly", "grtCanFocus", "grtHandleSymbol", "grtImage", + "grtComment", "grtVisible", "grtMerge", "grtRejectDelete", "grtRejectInsert", + "grtRejectInsertChild", "grtRejectMove", "grtRejectLevel", "grtEditForm", "grtClearCell" +}; + +GString trimExpression(const GString &s) +{ + GString result = trim(s); + + if (result != "" && result[0].unicode() == '=') + { + result = copy(s, 1); + } + + return result; +} + +bool textIsLabel(const GString &s) +{ + return (s == "") || (s[0].unicode() != '='); +} + +/* GLDCustomGridSetting */ + +GLDCustomGridSetting::GLDCustomGridSetting() : m_active(false), m_loaded(false), + m_extProps(NULL), m_fixedCols(CDefFixedCols), m_fixedEditCols(CDefFixedEditCols), + m_fixedEditRows(CDefFixedEditRows), m_leftMargin(CDefHorzMargin), m_rightMargin(CDefHorzMargin), + m_topMargin(CDefVertMargin), m_bottomMargin(CDefVertMargin), m_gridLineWidth(CDefGridLineWidth), + m_gridLineColor(CDefGridLineColor), m_gridColor(CDefGridColor), m_boundLineColor(CDefBoundLineColor), + m_invalidValueLabel(getGLDi18nStr(CDefInvalidValueLabel)), m_showAsTree(false), m_editing(true), m_vertLine(true), + m_horzLine(true), m_rowSizing(false), m_colSizing(true), m_colMoving(true), m_allowSelectRow(true), + m_allowSelectCol(true), m_allowSelectAll(true), m_multiSelection(true), m_alwaysShowEditor(false), + m_rangeSelect(true), m_autoThemeAdapt(true), m_returnKeyAsTab(false), m_showFixedRow(true), m_cellFilling(false), + m_fixedCellEvent(false), m_allow3DStyle(true), m_allowCopyPaste(true), m_borderStyle(true), m_hideEditOnExit(false), + m_useBlendColor(true), m_cellFillEditField(false), m_designState(true), m_persistentStyle(gpsFromFile), + m_persistentValue(""), m_description(""), m_remark(""), m_identity(""), + m_afterActiveEventList(new GLDGridSettingNotifyEventList()), m_tag(0) +{ + +} + +GLDCustomGridSetting::~GLDCustomGridSetting() +{ + freeAndNil(m_afterActiveEventList) +} + +bool GLDCustomGridSetting::active() const +{ + return m_active; +} + +GLDPersistentStyle GLDCustomGridSetting::persistentStyle() const +{ + return m_persistentStyle; +} + +GString GLDCustomGridSetting::persistentValue() const +{ + return m_persistentValue; +} + +bool GLDCustomGridSetting::designState() const +{ + return m_designState; +} + +unsigned short GLDCustomGridSetting::fixedEditCols() const +{ + return m_fixedEditCols; +} + +void GLDCustomGridSetting::setFixedEditCols(unsigned short value) +{ + m_fixedEditCols = value; +} + +void GLDCustomGridSetting::setActive(const bool value) +{ + if (m_active == value) + { + return; + } + + //todo yaok ComponentState 如何实现 + //if (ComponentState.contains(csReading)) + // m_active = value; + //else + if (m_persistentValue != "") + { + if (value) + { + loadGridSetting(); + } + else + { + doUnload(); + } + } + else + { + if (value) + { + m_active = true; + m_loaded = true; + doAfterActive(); + } + else + { + doUnload(); + } + } +} + +void GLDCustomGridSetting::setPersistentStyle(const GLDPersistentStyle value) +{ + if (m_persistentStyle == value) + { + return; + } + + //todo yaok ComponentState 如何实现 + // if (ComponentState.contains(csReading)) + // m_persistentStyle = Value; + // else + { + if (m_persistentValue != "") /*&& (ComponentState.contains(csDesigning)))*/ + { + if (m_persistentStyle == gpsFromDFM) + { + designing_DfmToFile(); + } + else + { + designing_FileToDfm(); + } + } + else + { + m_persistentValue = ""; + } + + m_persistentStyle = value; + reBuild(); + } +} + +void GLDCustomGridSetting::setPersistentValue(const GString &value) +{ + if (m_persistentValue != value) + { + //todo yaok + // if (ComponentState.contains(csReading)) + // m_persistentValue = Value; + // else + { + m_persistentValue = value; + reBuild(); + } + } +} + +void GLDCustomGridSetting::reLoad() +{ + if (m_active) + { + doBeforeDeactive(); + } + + loadGridSetting(); +} + +void GLDCustomGridSetting::reBuild() +{ + if (!m_active || !m_loaded) + { + return; + } + + //todo yaok Component 处理 + // operationNotify(opBeginRebuild); + try + { + m_loaded = false; + reLoad(); + // operationNotify(opEndRebuild); + } + catch (...) + { + // todo yaok + // operationNotify(opEndRebuild); + } +} + +void GLDCustomGridSetting::reBuildPersistentValue() +{ + GXMLDocument oDoc; + doSaveToXML(oDoc); + m_persistentValue = oDoc.toString(); +} + +void GLDCustomGridSetting::assignData(GLDCustomGridSetting &source) +{ + GMemoryStream oStream; + source.saveToStream(&oStream); + oStream.seek(0); + loadFromStream(&oStream); +} + +void GLDCustomGridSetting::loadFromStream(GStream *stream) +{ + readStrFromStream(stream, m_description); + readStrFromStream(stream, m_identity); + readMemoFromStream(stream, m_remark); + readBoolFromStream(stream, m_showAsTree); + readBoolFromStream(stream, m_editing); + readBoolFromStream(stream, m_vertLine); + readBoolFromStream(stream, m_horzLine); + readBoolFromStream(stream, m_rowSizing); + readBoolFromStream(stream, m_colSizing); + readBoolFromStream(stream, m_colMoving); + readBoolFromStream(stream, m_alwaysShowEditor); + readBoolFromStream(stream, m_rangeSelect); + readBoolFromStream(stream, m_allowSelectRow); + readBoolFromStream(stream, m_allowSelectCol); + readBoolFromStream(stream, m_allowSelectAll); + readBoolFromStream(stream, m_multiSelection); + readBoolFromStream(stream, m_autoThemeAdapt); + readBoolFromStream(stream, m_returnKeyAsTab); + readBoolFromStream(stream, m_showFixedRow); + readBoolFromStream(stream, m_cellFilling); + readBoolFromStream(stream, m_fixedCellEvent); + readBoolFromStream(stream, m_allow3DStyle); + readBoolFromStream(stream, m_allowCopyPaste); + readBoolFromStream(stream, m_hideEditOnExit); + readBoolFromStream(stream, m_borderStyle); + readBoolFromStream(stream, m_useBlendColor); + readBoolFromStream(stream, m_cellFillEditField); + readWordFromStream(stream, m_fixedCols); + readWordFromStream(stream, m_fixedEditRows); + readWordFromStream(stream, m_fixedEditCols); + readByteFromStream(stream, m_leftMargin); + readByteFromStream(stream, m_rightMargin); + readByteFromStream(stream, m_topMargin); + readByteFromStream(stream, m_bottomMargin); + readByteFromStream(stream, m_gridLineWidth); + readColorFromStream(stream, m_gridLineColor); + readColorFromStream(stream, m_gridColor); + readColorFromStream(stream, m_boundLineColor); + readStrFromStream(stream, m_invalidValueLabel); + readBoolFromStream(stream, m_designState); + + m_extProps->loadFromStream(stream); +} + +void GLDCustomGridSetting::saveToStream(GStream *stream) +{ + writeStrToStream(stream, m_description); + writeStrToStream(stream, m_identity); + writeMemoToStream(stream, m_remark); + writeBoolToStream(stream, m_showAsTree); + writeBoolToStream(stream, m_editing); + writeBoolToStream(stream, m_vertLine); + writeBoolToStream(stream, m_horzLine); + writeBoolToStream(stream, m_rowSizing); + writeBoolToStream(stream, m_colSizing); + writeBoolToStream(stream, m_colMoving); + writeBoolToStream(stream, m_alwaysShowEditor); + writeBoolToStream(stream, m_rangeSelect); + writeBoolToStream(stream, m_allowSelectRow); + writeBoolToStream(stream, m_allowSelectCol); + writeBoolToStream(stream, m_allowSelectAll); + writeBoolToStream(stream, m_multiSelection); + writeBoolToStream(stream, m_autoThemeAdapt); + writeBoolToStream(stream, m_returnKeyAsTab); + writeBoolToStream(stream, m_showFixedRow); + writeBoolToStream(stream, m_cellFilling); + writeBoolToStream(stream, m_fixedCellEvent); + writeBoolToStream(stream, m_allow3DStyle); + writeBoolToStream(stream, m_allowCopyPaste); + writeBoolToStream(stream, m_hideEditOnExit); + writeBoolToStream(stream, m_borderStyle); + writeBoolToStream(stream, m_useBlendColor); + writeBoolToStream(stream, m_cellFillEditField); + writeWordToStream(stream, m_fixedCols); + writeWordToStream(stream, m_fixedEditRows); + writeWordToStream(stream, m_fixedEditCols); + writeByteToStream(stream, m_leftMargin); + writeByteToStream(stream, m_rightMargin); + writeByteToStream(stream, m_topMargin); + writeByteToStream(stream, m_bottomMargin); + writeByteToStream(stream, m_gridLineWidth); + writeColorToStream(stream, m_gridLineColor); + writeColorToStream(stream, m_gridColor); + writeColorToStream(stream, m_boundLineColor); + writeStrToStream(stream, m_invalidValueLabel); + writeBoolToStream(stream, m_designState); + m_extProps->saveToStream(stream); +} + +GString GLDCustomGridSetting::shortIdentity() +{ + GFileInfo fileInfo(fileName()); + + return fileInfo.completeBaseName(); +} + +GString GLDCustomGridSetting::fullIdentity() +{ + return shortIdentity(); +} + +void GLDCustomGridSetting::setDesignState(bool value) +{ + if (m_designState == value) + { + return; + } + + if (value) + { + clearCompileInfo(); + } + else + { + compile(); + } + + m_designState = value; +} + +GString GLDCustomGridSetting::version() const +{ + return g_GLDGridSettingVersion; +} + +GString GLDCustomGridSetting:: description() const +{ + return m_description; +} + +void GLDCustomGridSetting::setDescription(GString value) +{ + m_description = value; +} + +GString GLDCustomGridSetting::remark() const +{ + return m_remark; +} + +void GLDCustomGridSetting::setRemark(GString value) +{ + m_remark = value; +} + +GString GLDCustomGridSetting::identity() const +{ + return m_identity; +} + +void GLDCustomGridSetting::setIdentity(GString value) +{ + m_identity = value; +} + +unsigned char GLDCustomGridSetting::leftMargin() const +{ + return m_leftMargin; +} + +void GLDCustomGridSetting::setLeftMargin(unsigned char value) +{ + m_leftMargin = value; +} +unsigned char GLDCustomGridSetting::rightMargin() const +{ + return m_rightMargin; +} + +void GLDCustomGridSetting::setRightMargin(unsigned char value) +{ + m_rightMargin = value; +} +unsigned char GLDCustomGridSetting::topMargin() const +{ + return m_topMargin; +} + +void GLDCustomGridSetting::setTopMargin(unsigned char value) +{ + m_topMargin = value; +} + +unsigned char GLDCustomGridSetting::bottomMargin() const +{ + return m_bottomMargin; +} + +void GLDCustomGridSetting::setBottomMargin(unsigned char value) +{ + m_bottomMargin = value; +} + +unsigned char GLDCustomGridSetting::gridLineWidth() const +{ + return m_gridLineWidth; +} + +void GLDCustomGridSetting::setGridLineWidth(unsigned char value) +{ + m_gridLineWidth = value; +} + +GRgb GLDCustomGridSetting::gridLineColor() const +{ + return m_gridLineColor; +} + +void GLDCustomGridSetting::setGridLineColor(GRgb value) +{ + m_gridLineColor = value; +} + +GRgb GLDCustomGridSetting::gridColor() const +{ + return m_gridColor; +} + +void GLDCustomGridSetting::setGridColor(GRgb value) +{ + m_gridColor = value; +} + +GRgb GLDCustomGridSetting::boundLineColor() const +{ + return m_boundLineColor; +} + +void GLDCustomGridSetting::setBoundLineColor(GRgb value) +{ + m_boundLineColor = value; +} +unsigned short GLDCustomGridSetting::fixedCols() const +{ + return m_fixedCols; +} + +void GLDCustomGridSetting::setFixedCols(unsigned short value) +{ + m_fixedCols = value; +} + +unsigned short GLDCustomGridSetting::fixedEditRows() const +{ + return m_fixedEditRows; +} + +void GLDCustomGridSetting::setFixedEditRows(unsigned short value) +{ + m_fixedEditRows = value; +} + +bool GLDCustomGridSetting::showAsTree() const +{ + return m_showAsTree; +} + +void GLDCustomGridSetting::setShowAsTree(bool value) +{ + m_showAsTree = value; +} + +bool GLDCustomGridSetting::editing() const +{ + return m_editing; +} + +void GLDCustomGridSetting::setEditing(bool value) +{ + m_editing = value; +} + +bool GLDCustomGridSetting::vertLine() const +{ + return m_vertLine; +} + +void GLDCustomGridSetting::setVertLine(bool value) +{ + m_vertLine = value; +} + +bool GLDCustomGridSetting::horzLine() const +{ + return m_horzLine; +} + +void GLDCustomGridSetting::setHorzLine(bool value) +{ + m_horzLine = value; +} + +bool GLDCustomGridSetting::rowSizing() const +{ + return m_rowSizing; +} + +void GLDCustomGridSetting::setRowSizing(bool value) +{ + m_rowSizing = value; +} + +bool GLDCustomGridSetting::colSizing() const +{ + return m_colSizing; +} + +void GLDCustomGridSetting::setColSizing(bool value) +{ + m_colSizing = value; +} +bool GLDCustomGridSetting::colMoving() const +{ + return m_colMoving; +} + +void GLDCustomGridSetting::setColMoving(bool value) +{ + m_colMoving = value; +} + +bool GLDCustomGridSetting::allowSelectRow() const +{ + return m_allowSelectRow; +} + +void GLDCustomGridSetting::setAllowSelectRow(bool value) +{ + m_allowSelectRow = value; +} + +bool GLDCustomGridSetting::allowSelectCol() const +{ + return m_allowSelectCol; +} + +void GLDCustomGridSetting::setAllowSelectCol(bool value) +{ + m_allowSelectCol = value; +} + +bool GLDCustomGridSetting::allowSelectAll() const +{ + return m_allowSelectAll; +} + +void GLDCustomGridSetting::setAllowSelectAll(bool value) +{ + m_allowSelectAll = value; +} + +bool GLDCustomGridSetting::multiSelection() const +{ + return m_multiSelection; +} + +void GLDCustomGridSetting::setMultiSelection(bool value) +{ + m_multiSelection = value; +} + +GString GLDCustomGridSetting::invalidValueLabel() const +{ + return m_invalidValueLabel; +} + +void GLDCustomGridSetting::setInvalidValueLabel(GString value) +{ + m_invalidValueLabel = value; +} + +bool GLDCustomGridSetting::alwaysShowEditor() const +{ + return m_alwaysShowEditor; +} + +void GLDCustomGridSetting::setAlwaysShowEditor(bool value) +{ + m_alwaysShowEditor = value; +} + +bool GLDCustomGridSetting::rangeSelect() const +{ + return m_rangeSelect; +} + +void GLDCustomGridSetting::setRangeSelect(bool value) +{ + m_rangeSelect = value; +} + +bool GLDCustomGridSetting::autoThemeAdapt() const +{ + return m_autoThemeAdapt; +} + +void GLDCustomGridSetting::setAutoThemeAdapt(bool value) +{ + m_autoThemeAdapt = value; +} + +bool GLDCustomGridSetting::returnKeyAsTab() const +{ + return m_returnKeyAsTab; +} + +void GLDCustomGridSetting::setReturnKeyAsTab(bool value) +{ + m_returnKeyAsTab = value; +} + +bool GLDCustomGridSetting::showFixedRow() const +{ + return m_showFixedRow; +} + +void GLDCustomGridSetting::setShowFixedRow(bool value) +{ + m_showFixedRow = value; +} + +bool GLDCustomGridSetting::cellFilling() const +{ + return m_cellFilling; +} + +void GLDCustomGridSetting::setCellFilling(bool value) +{ + m_cellFilling = value; +} + +bool GLDCustomGridSetting::fixedCellEvent() const +{ + return m_fixedCellEvent; +} + +void GLDCustomGridSetting::setFixedCellEvent(bool value) +{ + m_fixedCellEvent = value; +} + +bool GLDCustomGridSetting::allow3DStyle() const +{ + return m_allow3DStyle; +} + +void GLDCustomGridSetting::setAllow3DStyle(bool value) +{ + m_allow3DStyle = value; +} + +bool GLDCustomGridSetting::allowCopyPaste() const +{ + return m_allowCopyPaste; +} +void GLDCustomGridSetting::setAllowCopyPaste(bool value) +{ + m_allowCopyPaste = value; +} + +bool GLDCustomGridSetting::borderStyle() const +{ + return m_borderStyle; +} + +void GLDCustomGridSetting::setBorderStyle(bool value) +{ + m_borderStyle = value; +} + +bool GLDCustomGridSetting::hideEditOnExit() const +{ + return m_hideEditOnExit; +} + +void GLDCustomGridSetting::setHideEditOnExit(bool value) +{ + m_hideEditOnExit = value; +} + +bool GLDCustomGridSetting::useBlendColor() const +{ + return m_useBlendColor; +} + +void GLDCustomGridSetting::setUseBlendColor(bool value) +{ + m_useBlendColor = value; +} + +bool GLDCustomGridSetting::cellFillEditField() const +{ + return m_cellFillEditField; +} + +void GLDCustomGridSetting::setCellFillEditField(bool value) +{ + m_cellFillEditField = value; +} + +CGLDExtPropDefs *GLDCustomGridSetting::extPropDefs() const +{ + return m_extProps; +} + +PtrInt GLDCustomGridSetting::tag() const +{ + return m_tag; +} + +void GLDCustomGridSetting::setTag(PtrInt tag) +{ + m_tag = tag; +} + +GLDGridSettingNotifyEventList *GLDCustomGridSetting::afterActiveEventList() +{ + return m_afterActiveEventList; +} + +GString GLDCustomGridSetting::fileName() +{ + //assert(m_persistentStyle == psFromFile); + return m_persistentValue; +} + +void GLDCustomGridSetting::doAfterActive() +{ + assert(m_active); + assert(m_loaded); + + if (!m_afterActiveEventList) + { + return; + } + + for (int i = 0; i < m_afterActiveEventList->count(); i++) + { + m_afterActiveEventList->at(i)->doEvent(this); + } +} + +void GLDCustomGridSetting::doBeforeDeactive() +{ + //todo yaok + /* + assert(m_active); + beforeDeactiveEventList_->doEvent(this); + */ +} + +void GLDCustomGridSetting::loaded() +{ + if (m_loaded) + { + return; + } + + if (m_active) + { + loadGridSetting(); + } +} + +void GLDCustomGridSetting::doLoad() +{ + GXMLDocument xmlDoc; + clearData(); + + if (m_persistentStyle == gpsFromDFM) + { + if (m_persistentValue != "") + { + doLoadFromXML(xmlDoc); + } + } + else + { + doLoadFromFile(m_persistentValue); + } + + m_active = true; + m_loaded = true; +} + +void GLDCustomGridSetting::doUnload() +{ + doBeforeDeactive(); + clearData(); + m_active = false; + m_loaded = false; +} + +void GLDCustomGridSetting::refreshRule(GLDGridRule *rule) +{ + rule->enable(); + /* todo yaok + int i; + for (i = 0; i <= clients_.count() - 1; i++) + { + assert(dynamic_cast< GSPCustomGrid *>(((TObject *) clients_[i]))); + ((GSPCustomGridHack *) clients_[iI])->refreshRule(rule); + } + */ +} + +void GLDCustomGridSetting::designing_DfmToFile() +{ + /* todo yaok 这个函数在CPP中还有用吗? + IXMLDocument iDoc; + assert(m_persistentValue != ""); + assert(ComponentState.contains(csDesigning)); + assert(m_persistentStyle == psFromDFM); + if (confirmDlg("是否将DFM中的内容保存到文件?") == IDYES) + { + with TSaveDialog.create(nil) do + try + { + setDefaultExt(getSaveDialogDefaultExt()); + setFilter(getSaveDialogFilter()); + if (!execute()) + m_persistentValue = ""; + else + { + iDoc = createXMLDocument(true, true); + iDoc.XML = m_persistentValue; + iDoc.saveToFile(Files[0]); + m_persistentValue = Files[0]; + } + } + __finally + { + Free; + } + } + else + { + m_persistentValue = ""; + } + */ +} + +void GLDCustomGridSetting::designing_FileToDfm() +{ + /* todo yaok 这个函数在CPP中还有用吗? + IXMLDocument iDoc; + assert(m_persistentValue != ""); + assert(ComponentState.contains(csDesigning)); + assert(m_persistentStyle == psFromFile); + if (fileExists(FileName) &&(confirmDlg("是否将文件内容装载到DFM?") == IDYES)) + { + iDoc = createXMLDocument(true, true); + iDoc.loadFromFile(m_persistentValue); + m_persistentValue = iDoc.XML; + } + else + { + m_persistentValue = ""; + } + */ +} + +/* GLDGridSetting */ + +GLDGridSetting::GLDGridSetting() : GLDCustomGridSetting(), m_allowSort(false), + m_sortFieldName(""), m_ascImageIndex(-1), m_descImageIndex(-1), m_totalRowAtFooter(true), + m_colSettings(NULL), m_titleRows(NULL), m_filterRows(NULL), m_tableSettings(NULL), + m_controlRef(0) +{ + m_extProps = new CGLDExtPropDefs; + m_extProps->AddRef(); +} + +GLDGridSetting::~GLDGridSetting() +{ + setActive(false); + //todo yaok TGSPDBComponent 方法 + //clearClientRefs(); + freeAndNil(m_colSettings); + freeAndNil(m_titleRows); + freeAndNil(m_filterRows); + freeAndNil(m_tableSettings); + m_extProps->Release(); +} + +void GLDGridSetting::initialize() +{ + m_colSettings = new GLDColSettings(this); + m_titleRows = new GLDTitleRows(this); + m_titleRows->insert(-1); + m_filterRows = new GLDFilterRows(this); + m_tableSettings = new GLDTableSettings(this); +} + +GLDGridSetting *GLDGridSetting::createGLDGridSetting() +{ + GLDGridSetting *result = new GLDGridSetting(); + result->initialize(); + return result; +} + +void GLDGridSetting::clearData() +{ +// m_colSettings->clearCompileInfo(); +// m_titleRows->clearCompileInfo(); +// m_filterRows->clearCompileInfo(); +// m_tableSettings->clearCompileInfo(); +// m_extProps->clearCompileInfo(); + + m_titleRows->clear(); + m_filterRows->clear(); + m_colSettings->clear(); + m_tableSettings->clear(); +} + +void GLDGridSetting::saveToFile(const GString &fileName) +{ + GLDGridSettingXMLWriter writer; + writer.write(fileName, this); +} + +void GLDGridSetting::loadFromStream(GStream *stream) +{ + // 先清ColSetting,否则会把FixedCols清掉 + if (m_colSettings != NULL) + { + m_colSettings->clear(); + } + + GLDCustomGridSetting::loadFromStream(stream); + + readBoolFromStream(stream, m_allowSort); + readStrFromStream(stream, m_sortFieldName); + readIntFromStream(stream, m_ascImageIndex); + readIntFromStream(stream, m_descImageIndex); + readBoolFromStream(stream, m_totalRowAtFooter); + m_colSettings->loadFromStream(stream); + m_titleRows->loadFromStream(stream); + m_filterRows->loadFromStream(stream); + m_tableSettings->loadFromStream(stream); +} + +void GLDGridSetting::saveToStream(GStream *stream) +{ + GLDCustomGridSetting::saveToStream(stream); + writeBoolToStream(stream, m_allowSort); + writeStrToStream(stream, m_sortFieldName); + writeIntToStream(stream, m_ascImageIndex); + writeIntToStream(stream, m_descImageIndex); + writeBoolToStream(stream, m_totalRowAtFooter); + m_colSettings->saveToStream(stream); + m_titleRows->saveToStream(stream); + m_filterRows->saveToStream(stream); + m_tableSettings->saveToStream(stream); +} + +void GLDGridSetting::compileExpandRow() +{ + if (m_tableSettings->count() == 0) + { + return; + } + + for (int i = 0; i <= m_tableSettings->items(0)->headerRowCount() - 1; i++) + { + for (int j = 0; j <= m_tableSettings->items(0)->headerRows(i)->count() - 1; j++) + { + m_tableSettings ->items(0)->headerRows(i)->items(j)->compile(); + } + } + + for (int i = 0; i <= m_tableSettings->items(0)->totalRowCount() - 1; i++) + { + for (int j = 0; j <= m_tableSettings ->items(0)->totalRows(i)->count() - 1; j++) + { + m_tableSettings->items(0)->totalRows(i)->items(j)->compile(); + } + } +} + +bool GLDGridSetting::allowSort() const +{ + return m_allowSort; +} + +void GLDGridSetting::setAllowSort(bool value) +{ + m_allowSort = value; +} + +GString GLDGridSetting::sortFieldNames() const +{ + return m_sortFieldName; +} + +void GLDGridSetting::setSortFieldNames(GString value) +{ + m_sortFieldName = value; +} + +int GLDGridSetting::ascImageIndex() const +{ + return m_ascImageIndex; +} + +void GLDGridSetting::setAscImageIndex(int value) +{ + m_ascImageIndex = value; +} + +int GLDGridSetting::descImageIndex() const +{ + return m_descImageIndex; +} + +void GLDGridSetting::setDescImageIndex(int value) +{ + m_descImageIndex = value; +} + +bool GLDGridSetting::totalRowAtFooter() const +{ + return m_totalRowAtFooter; +} + +void GLDGridSetting::setTotalRowAtFooter(bool value) +{ + m_totalRowAtFooter = value; +} + +GLDColSettings *GLDGridSetting::colSettings() const +{ + return m_colSettings; +} + +GLDTitleRows *GLDGridSetting::titleRows() const +{ + return m_titleRows; +} + +GLDFilterRows *GLDGridSetting::filterRows() const +{ + return m_filterRows; +} + +GLDTableSettings *GLDGridSetting::tableSettings() const +{ + return m_tableSettings; +} + +void GLDGridSetting::setTableSettings(GLDTableSettings *pTableSettings) +{ + m_tableSettings = pTableSettings; +} + +ULONG GLDGridSetting::AddControlRef() +{ + return m_controlRef++; +} + +ULONG GLDGridSetting::ReleaseControlRef() +{ + m_controlRef--; + + if (m_controlRef == 0) + { + delete this; + return ULONG(0); + } + else + { + return m_controlRef; + } +} + +void GLDGridSetting::compile() +{ + m_colSettings->compile(); + m_titleRows->compile(); + m_filterRows->compile(); + m_tableSettings->compile(); + m_extProps->compile(); +} + +void GLDGridSetting::clearCompileInfo() +{ + m_colSettings->clearCompileInfo(); + m_titleRows->clearCompileInfo(); + m_filterRows->clearCompileInfo(); + m_tableSettings->clearCompileInfo(); + + m_extProps->clearCompileInfo(); +} + +void GLDGridSetting::loadGridSetting() +{ + doLoad(); + doAfterActive(); +} + +void GLDGridSetting::doLoadFromXML(GXMLDocument &doc) +{ + GLDGridSettingXMLReader oBuilder; + oBuilder.read(doc, this); +} + +void GLDGridSetting::doLoadFromFile(const GString &fileName) +{ + GLDGridSettingXMLReader oBuilder; + oBuilder.read(fileName, this); +} + +void GLDGridSetting::doSaveToXML(GXMLDocument &doc) +{ + GLDGridSettingXMLWriter oWriter; + oWriter.write(doc, this); +} + +GString GLDGridSetting::saveDialogDefaultExt() +{ + return "GSF"; +} + +GString GLDGridSetting::saveDialogFilter() +{ + return "GridSetting files(*.GSF)|*.GSF"; +} + +/* GLDColSettings */ + +GLDColSettings::GLDColSettings(GLDGridSetting *owner) +{ + m_owner = owner; +} + +GLDColSettings::~GLDColSettings() +{ + clear(); +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 清除列设置数据 +-----------------------------------------------------------------------------*/ +void GLDColSettings::clear() +{ + for (int i = count() - 1; i >= 0; i--) + { + Delete(i); + } +} + +int GLDColSettings::indexOf(GLDColSetting *colSetting) const +{ + return m_list.indexOf(colSetting); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:删除指定下标列 + 参数:index -- 列下标 +-----------------------------------------------------------------------------*/ +void GLDColSettings::Delete(int index) +{ + assert((index >= 0) && (index < count())); + bool bIsFixedCol = items(index)->isFixedCol(); + // 删除列设置对象 + GLDColSetting *oColSetting = items(index); + m_list.Delete(index); + freeAndNil(oColSetting); + + // 删除字段设置列 + for (int i = 0; i <= m_owner->tableSettings()->count() - 1; i++) + { + m_owner->tableSettings()->items(i)->fieldSettings()->Delete(index); + } + + // 删除带区标题行字段设置 + for (int i = 0; i <= m_owner->tableSettings()->count() - 1; i++) + { + for (int j = 0; j <= m_owner->tableSettings()->items(i)->headerRowCount() - 1; j++) + { + m_owner->tableSettings()->items(i)->headerRows(j)->Delete(index); + } + } + + // 删除合计行字段设置 + for (int i = 0; i <= m_owner->tableSettings()->count() - 1; i++) + { + for (int j = 0; j <= m_owner->tableSettings()->items(i)->totalRowCount() - 1; j++) + { + m_owner->tableSettings()->items(i)->totalRows(j)->Delete(index); + } + } + + // 删除标题行单元格 + for (int i = 0; i <= m_owner->titleRows()->count() - 1; i++) + { + m_owner->titleRows()->items(i)->Delete(index); + } + + // 删除过滤行单元格 + for (int i = 0; i <= m_owner->filterRows()->count() - 1; i++) + { + m_owner->filterRows()->items(i)->Delete(index); + } + + if (bIsFixedCol) + { + m_owner->setFixedCols(m_owner->fixedCols() - 1); + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:插入列 + 参数:index -- 列位置 + 返回:插入的列设置对象 +-----------------------------------------------------------------------------*/ +GLDColSetting *GLDColSettings::insert(int index) +{ + // 插入列设置对象 + GLDColSetting *result = createColSetting(this); + + if (index == -1) + { + index = count(); + } + + m_list.insert(index, result); + + // 插入字段设置 + for (int i = 0; i != m_owner->tableSettings()->count(); i++) + { + GLDFieldSettings *oFieldSettings = m_owner->tableSettings()->items(i)->fieldSettings(); + oFieldSettings->list().insert(index, createFieldSetting(oFieldSettings)); + + for (int j = 0; j <= m_owner->tableSettings()->items(i)->headerRowCount() - 1; j++) + { + GLDHeaderRowFieldSettings *oHeaderRowFieldSettings = m_owner->tableSettings()->items(i)->headerRows(j); + oHeaderRowFieldSettings->list().insert(index, createHeaderRowFieldSetting(oHeaderRowFieldSettings)); + } + + for (int j = 0; j <= m_owner->tableSettings()->items(i)->totalRowCount() - 1; j++) + { + GLDTotalRowFieldSettings *oTotalRowFieldSettings = m_owner->tableSettings()->items(i)->totalRows(j); + oTotalRowFieldSettings->list().insert(index, createTotalRowFieldSetting(oTotalRowFieldSettings)); + } + } + + // 插入标题行单元格 + for (int i = 0; i <= m_owner->titleRows()->count() - 1; i++) + { + m_owner->titleRows()->items(i)->list().insert(index, createTitleCell(m_owner->titleRows()->items(i))); + } + + // 插入过滤行单元格 + for (int i = 0; i <= m_owner->filterRows()->count() - 1; i++) + { + m_owner->filterRows()->items(i)->list().insert(index, createFilterCell(m_owner->filterRows()->items(i))); + } + + return result; +} + +GLDGridSetting *GLDColSettings::owner() const +{ + return m_owner; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 从流对象中装载数据 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDColSettings::loadFromStream(GStream *stream) +{ + int nInts(0); + readIntFromStream(stream, nInts); + clear(); + + for (int i = 0; i <= nInts - 1; i++) + { + insert()->loadFromStream(stream); + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:移动列 + 参数:fromIndex -- 源下标 + toIndex -- 目标下标 +-----------------------------------------------------------------------------*/ +void GLDColSettings::move(int fromIndex, int toIndex) +{ + //assert((fromIndex >= 0) &&(fromIndex < count())); + //assert((toIndex >= 0) &&(toIndex < count())); + if (fromIndex == toIndex) + { + return; + } + + // 移动列设置对象 + m_list.move(fromIndex, toIndex); + + // 移动字段设置对象 + for (int i = 0; i <= m_owner->tableSettings()->count() - 1; i++) + { + m_owner->tableSettings()->items(i)->fieldSettings()->list().move(fromIndex, toIndex); + } + + // 移动带区标题行字段设置对象 + for (int i = 0; i <= m_owner->tableSettings()->count() - 1; i++) + { + for (int j = 0; j <= m_owner->tableSettings()->items(i)->headerRowCount() - 1; j++) + { + m_owner->tableSettings()->items(i)->headerRows(j)->list().move(fromIndex, toIndex); + } + } + + // 移动合计行字段设置对象 + for (int i = 0; i <= m_owner->tableSettings()->count() - 1; i++) + { + for (int j = 0; j <= m_owner->tableSettings()->items(i)->totalRowCount() - 1; j++) + { + m_owner->tableSettings()->items(i)->totalRows(j)->list().move(fromIndex, toIndex); + } + } + + // 移动标题单元格 + for (int i = 0; i <= m_owner->titleRows()->count() - 1; i++) + { + m_owner->titleRows()-> items(i)->list().move(fromIndex, toIndex); + } + + // 移动过滤单元格 + for (int i = 0; i <= m_owner->filterRows()->count() - 1; i++) + { + m_owner->filterRows()->items(i)->list().move(fromIndex, toIndex); + } +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 保存数据到流对象中 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDColSettings::saveToStream(GStream *stream) +{ + writeIntToStream(stream, count()); + + for (int i = 0; i <= count() - 1; i++) + { + items(i)->saveToStream(stream); + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:设置总列数 + 参数:value -- 总列数 +-----------------------------------------------------------------------------*/ +void GLDColSettings::setCount(int value) +{ + int nSize = (int)m_list.size(); + + if (value == nSize) + { + return; + } + + if (value > nSize) + { + for (int i = nSize; i <= value - 1; i++) + { + m_list.push_back(createColSetting(this)); + } + } + + for (int i = 0; i <= m_owner->tableSettings()->count() - 1; i++) + { + m_owner->tableSettings()->items(i)->fieldSettings()->setCount(value); + } + + for (int i = 0; i <= m_owner->titleRows()->count() - 1; i++) + { + m_owner->titleRows()->items(i)->setCellCount(value); + } + + for (int i = 0; i <= m_owner->filterRows()->count() - 1; i++) + { + m_owner->filterRows()->items(i)->setCellCount(value); + } +} + +GLDColSetting *GLDColSettings::items(int index) const +{ + return m_list[index]; +} + +GLDColSetting *GLDColSettings::operator[](int index) +{ + return m_list[index]; +} + +GObjectList &GLDColSettings::visibleCondItems() +{ + return m_visibleCondItems; +} + +int GLDColSettings::findParserIndex(const GString &expr) +{ + Q_UNUSED(expr); + return -1; +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:返回可视列数 + 返回:可视列数 +-----------------------------------------------------------------------------*/ +int GLDColSettings::visibleColCount() +{ + int result = 0; + + for (int i = 0; i <= count() - 1; i++) + { + if (items(i)->visible()) + { + ++result; + } + } + + return result; +} + +GLDColSetting *GLDColSettings::findColSetting(const GString &identity) +{ + for (int i = 0; i <= count() - 1; i++) + { + if (items(i)->fullIdentity().toLower() == identity.toLower()) + { + return items(i); + } + } + + return NULL; +} + +int GLDColSettings::fixedColCount() +{ + int result = 0; + + for (int i = 0; i <= count() - 1; i++) + { + if (items(i)->isFixedCol()) + { + result++; + } + } + + return result; +} + +GIntList GLDColSettings::suitRowHeightCols() +{ + GIntList oResult; + int nFixedColCount = fixedColCount(); + + for (int i = 0; i <= count() - 1; ++i) + { + if (items(i)->cellSuitType() == gcstSuitRowHeight) + { + oResult.push_back(i - nFixedColCount); + } + } + + return oResult; +} + +GIntList GLDColSettings::suitColWidthCols() +{ + GIntList oResult; + int nFixedColCount = fixedColCount(); + + for (int i = 0; i <= count() - 1; i++) + { + if (items(i)->cellSuitType() == gcstSuitColWidth) + { + oResult.push_back(i - nFixedColCount); + } + } + + return oResult; +} + +GIntList GLDColSettings::fitColWidthCols() +{ + GIntList oResult; + int nFixedColCount = fixedColCount(); + + for (int i = 0; i <= count() - 1; i++) + { + if (items(i)->cellSuitType() == gcstFitColWidth) + { + oResult.push_back(i - nFixedColCount); + } + } + + return oResult; +} + +int GLDColSettings::count() const +{ + return (int)m_list.size(); +} + +void GLDColSettings::compile() +{ + int nIndex(0); + GLDColSettingVector *oList = NULL; + // 必须存在显示行 + bool bHasVisibleCol = false; + + for (int i = 0; i <= count() - 1; i++) + { + if (!items(i)->isFixedCol() && items(i)->visible()) + { + bHasVisibleCol = true; + break; + } + } + + if (!bHasVisibleCol) + { + throw GLDColSettingException(getGSPi18nStr(g_NotExistVisibleCol)); + } + + // 编译每列 + for (int i = 0; i <= count() - 1; i++) + { + items(i)->compile(); + } + + // 编译列显示条件表达式 + // 把列显示表达式放在容器层处理,主要目的是为了优化(多个列的显示条件一样) + for (int i = 0; i <= count() - 1; i++) + { + GString sExpr = trimExpression(items(i)->visibleCondition()); + + if (sExpr != "") + { + nIndex = findParserIndex(sExpr); + + if (nIndex == -1) + { + //todo yaok event + // oParser->setOnRefreshValue(doRefreshValue()); + oList = new GLDColSettingVector(); + oList->push_back(items(i)); + m_visibleCondItems.push_back(oList); + } + else + { + oList = m_visibleCondItems[nIndex]; + oList->push_back(items(i)); + } + } + } +} + +GLDColSetting *GLDColSettings::createColSetting(GLDColSettings *owner) +{ + return new GLDColSetting(owner); +} + +GLDFieldSetting *GLDColSettings::createFieldSetting(GLDFieldSettings *owner) +{ + return new GLDFieldSetting(owner); +} + +GLDHeaderRowFieldSetting *GLDColSettings::createHeaderRowFieldSetting(GLDHeaderRowFieldSettings *owner) +{ + return new GLDHeaderRowFieldSetting(owner); +} + +GLDTotalRowFieldSetting *GLDColSettings::createTotalRowFieldSetting(GLDExpandRowFieldSettings *owner) +{ + return new GLDTotalRowFieldSetting(owner); +} + +GLDTitleCell *GLDColSettings::createTitleCell(GLDTitleRow *owner) +{ + return new GLDTitleCell(owner); +} + +GLDFilterCell *GLDColSettings::createFilterCell(GLDFilterRow *owner) +{ + return new GLDFilterCell(owner); +} + +void GLDColSettings::clearClonedColSetting() +{ + for (int i = count() - 1; i >= 0; i--) + { + if (items(i)->cloneFlag()) + { + Delete(i); + } + } +} + +void GLDColSettings::clearCompileInfo() +{ + m_visibleCondItems.clear(); + + for (int i = 0; i <= count() - 1; i++) + { + items(i)->clearCompileInfo(); + } +} + +void GLDColSettings::clone(GLDColSetting *protoType, int insertIndex, int count) +{ + GMemoryStream oStream; + int i, j, k, nSourceIndex, nTargetIndex; + + //assert((insertIndex >= 0) &&(insertIndex <= count())); + //assert(protoType != NULL); + //assert(count() > 0); + for (k = 0; k <= count - 1; k++) + { + GLDColSetting *oColSetting = insert(insertIndex); + oColSetting->setCloneFlag(true); + nSourceIndex = protoType->index(); + nTargetIndex = oColSetting->index(); + + // 克隆列配置 + oStream.seek(0); + protoType->saveToStream(&oStream); + oStream.seek(0); + oColSetting->loadFromStream(&oStream); + + // 克隆标题行 + for (i = 0; i <= m_owner->titleRows()->count() - 1; i++) + { + oStream.seek(0); + m_owner->titleRows()->items(i)->cells(nSourceIndex)->saveToStream(&oStream); + oStream.seek(0); + m_owner->titleRows()->items(i)->cells(nTargetIndex)->loadFromStream(&oStream); + } + + // 克隆过滤行 + for (i = 0; i <= m_owner->filterRows()->count() - 1; i++) + { + oStream.seek(0); + m_owner->filterRows()->items(i)->cells(nSourceIndex)->saveToStream(&oStream); + oStream.seek(0); + m_owner->filterRows()->items(i)->cells(nTargetIndex)->loadFromStream(&oStream); + } + + // 克隆表 + for (i = 0; i <= m_owner->tableSettings()->count() - 1; i++) + { + oStream.seek(0); + m_owner->tableSettings()->items(i)->fieldSettings()->items(nSourceIndex)->saveToStream(&oStream); + oStream.seek(0); + m_owner->tableSettings()->items(i)->fieldSettings()->items(nTargetIndex)->loadFromStream(&oStream); + + for (j = 0; j <= m_owner->tableSettings()->items(i)->headerRowCount() - 1; j++) + { + oStream.seek(0); + m_owner->tableSettings()->items(i)->headerRows(j)->items(nSourceIndex)->saveToStream(&oStream); + oStream.seek(0); + m_owner->tableSettings()->items(i)->headerRows(j)->items(nTargetIndex)->loadFromStream(&oStream); + } + + for (j = 0; j <= m_owner->tableSettings()->items(i)->totalRowCount() - 1; j++) + { + oStream.seek(0); + m_owner->tableSettings()->items(i)->totalRows(j)->items(nSourceIndex)->saveToStream(&oStream); + oStream.seek(0); + m_owner->tableSettings()->items(i)->totalRows(j)->items(nTargetIndex)->loadFromStream(&oStream); + } + } + } +} + +/* GLDColSetting */ + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:构造函数,设置缺省值 +-----------------------------------------------------------------------------*/ +GLDColSetting::GLDColSetting(GLDColSettings *owner) + : m_owner(owner), + m_displayWidth(CDefDisplayWidth), + m_calcedWidth(CDefDisplayWidth), + m_zoomWidth(0), + m_originWidth(0), + m_originIndex(0), + m_visible(true), + m_enabled(true), + m_cloneFlag(false), + m_crossExtFlag(false), + m_cellSuitType(gcstFixed), + m_extProps(new CGLDExtPropDefs()), + m_tag(0) + +{ + m_extProps->AddRef(); +} + +GLDColSetting::~GLDColSetting() +{ + m_extProps->Release(); +} + +void GLDColSetting::setDisplayWidth(int value) +{ + if (value < 0) + { + m_displayWidth = 0; // 自动列宽 + } + else + { + m_displayWidth = value; + } + + m_calcedWidth = m_displayWidth; +} + +void GLDColSetting::setVisibleCondition(const GString &value) +{ + if (m_owner->owner()->designState()) + { + m_visibleCondition = trim(value); + } + else + { + gldError(getGLDi18nStr(g_NeedRunState)); + } +} + +int GLDColSetting::index() +{ + return m_owner->indexOf(this); +} + +bool GLDColSetting::isFixedCol() +{ + int nIndex; + nIndex = m_owner->indexOf(this); + return nIndex < m_owner->owner()->fixedCols(); +} + +void GLDColSetting::refreshVisibleState(int col) +{ + if (-1 == col) + { + return; + } +} + +void GLDColSetting::compile() +{ +} + +void GLDColSetting::clearCompileInfo() +{ +} + +GString GLDColSetting::fullIdentity() +{ + GString result = m_identity; + + if ((result == "") && (m_owner->owner()->titleRows()->count() > 0)) + { + result = m_owner->owner()->titleRows()->items(0)->cells(index())->caption(); + + for (int i = 1; i <= m_owner->owner()->titleRows()->count() - 1; i++) + { + if (!sameText(m_owner->owner()->titleRows()->items(i)->cells(index())->caption(), + m_owner->owner()->titleRows()->items(i - 1)->cells(index())->caption())) + { + result = result + "|" + m_owner->owner()->titleRows()->items(i)->cells(index())->caption(); + } + } + } + + return result; +} + +int GLDColSetting::displayWidth() const +{ + return m_displayWidth; +} + +bool GLDColSetting::enabled() const +{ + return m_enabled; +} + +void GLDColSetting::setEnabled(bool value) +{ + m_enabled = value; +} + +int GLDColSetting::calcedWidth() const +{ + return m_calcedWidth; +} + +void GLDColSetting::setCalcedWidth(int value) +{ + m_calcedWidth = value; +} + +int GLDColSetting::zoomWidth() const +{ + return m_zoomWidth; +} + +void GLDColSetting::setZoomWidth(int value) +{ + m_zoomWidth = value; +} + +int GLDColSetting::originWidth() const +{ + return m_originWidth; +} + +void GLDColSetting::setOriginWidth(int value) +{ + m_originWidth = value; +} + +int GLDColSetting::originIndex() const +{ + return m_originIndex; +} + +void GLDColSetting::setOriginIndex(int value) +{ + m_originIndex = value; +} + +GString GLDColSetting::visibleCondition() const +{ + return m_visibleCondition; +} + +bool GLDColSetting::visible() const +{ + return m_visible && m_enabled; +} + +void GLDColSetting::setVisible(bool value) +{ + m_visible = value; +} + +GLDCellSuitType GLDColSetting::cellSuitType() const +{ + return m_cellSuitType; +} + +void GLDColSetting::setCellSuitType(GLDCellSuitType value) +{ + m_cellSuitType = value; +} + +GString GLDColSetting::identity() const +{ + return m_identity; +} + +void GLDColSetting::setIdentity(GString value) +{ + m_identity = value; +} + +GString GLDColSetting::extData() const +{ + return m_extData; +} + +void GLDColSetting::setExtData(GString value) +{ + m_extData = value; +} + +CGLDExtPropDefs *GLDColSetting::extPropDefs() const +{ + return m_extProps; +} + +bool GLDColSetting::cloneFlag() const +{ + return m_cloneFlag; +} + +void GLDColSetting::setCloneFlag(bool value) +{ + m_cloneFlag = value; +} + +bool GLDColSetting::crossExtFlag() const +{ + return m_crossExtFlag; +} + +void GLDColSetting::setCrossExtFlag(bool value) +{ + m_crossExtFlag = value; +} + +PtrInt GLDColSetting::tag() const +{ + return m_tag; +} + +void GLDColSetting::setTag(PtrInt value) +{ + m_tag = value; +} + +GLDGridSetting *GLDColSetting::gridSetting() const +{ + return m_owner->owner(); +} + +GLDColSettings *GLDColSetting::owner() +{ + return m_owner; +} + +void GLDColSetting::loadFromStream(GStream *stream) +{ + int nCellSuitType; + readIntFromStream(stream, m_displayWidth); + readBoolFromStream(stream, m_visible); + readStrFromStream(stream, m_visibleCondition); + readIntFromStream(stream, nCellSuitType); + m_cellSuitType = ((GLDCellSuitType) nCellSuitType); + readStrFromStream(stream, m_identity); + readIntFromStream(stream, m_calcedWidth); + readStrFromStream(stream, m_extData); + //todo yaok + //GSPExtPropDefsStreamBuilder::read(stream, m_extProps); +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 保存数据到流对象中 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDColSetting::saveToStream(GStream *stream) +{ + writeIntToStream(stream, m_displayWidth); + writeBoolToStream(stream, m_visible); + writeStrToStream(stream, m_visibleCondition); + writeIntToStream(stream, (int)m_cellSuitType); + writeStrToStream(stream, m_identity); + writeIntToStream(stream, m_calcedWidth); + writeStrToStream(stream, m_extData); + //todo yaok + //GSPExtPropDefsStreamBuilder::write(stream, m_extProps); +} + +/* GLDTableSetting */ + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:构造函数 +-----------------------------------------------------------------------------*/ +void GLDTableSetting::initialize() +{ + m_rules = new GLDGridRules(this); + m_fieldSettings = new GLDFieldSettings(this); + m_fieldSettings->setCount(m_owner->owner()->colSettings()->count()); + m_extProps = new CGLDExtPropDefs(); + m_extProps->AddRef(); +} + +GLDTableSetting *GLDTableSetting::createTableSetting(GLDTableSettings *owner) +{ + GLDTableSetting *result = new GLDTableSetting(owner); + result->initialize(); + return result; +} + +GLDHeaderRowFieldSettings *GLDTableSetting::createHeaderRowFieldSettings(GLDTableSetting *owner) +{ + return new GLDHeaderRowFieldSettings(owner); +} + +GLDTotalRowFieldSettings *GLDTableSetting::createTotalRowFieldSettings(GLDTableSetting *owner) +{ + return new GLDTotalRowFieldSettings(owner); +} + +GLDTableSetting::GLDTableSetting(GLDTableSettings *owner) +{ + m_owner = owner; + m_defRowHeight = CDefRowHeight; + m_isTree = true; + m_isTreeWithMasterView = true; + m_cloneFlag = false; + m_customDataSource = false; + m_needExpandTotalExpr = false; +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:析构函数 +-----------------------------------------------------------------------------*/ +GLDTableSetting::~GLDTableSetting() +{ + freeAndNil(m_rules); + freeAndNil(m_fieldSettings); + clearTotalRows(); + clearHeaderRows(); + m_extProps->Release(); +} + +GLDTableSettings *GLDTableSetting::owner() const +{ + return m_owner; +} + +void GLDTableSetting::clearTotalRows() +{ + for (int i = totalRowCount() - 1; i >= 0; i--) + { + deleteTotalRow(i); + } +} + +void GLDTableSetting::clearHeaderRows() +{ + for (int i = headerRowCount() - 1; i >= 0; i--) + { + deleteHeaderRow(i); + } +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2006-01-05 + 功能: 返回RefDatabaseName +-----------------------------------------------------------------------------*/ +GString GLDTableSetting::refFullName() +{ + GString result; + + if (m_refDatabaseName != "") + { + result = m_refDatabaseName + "." + m_refTableName; + } + else + { + result = m_refTableName; + } + + return result; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2006-01-19 + 功能: 根据下标取合计行设置 + 参数: index -- 下标 + 返回: 合计行设置 +-----------------------------------------------------------------------------*/ +GLDTotalRowFieldSettings *GLDTableSetting::totalRows(int index) +{ + //assert((index >= 0) &&(index < m_totalRows.count()())); + return m_totalRows[index]; +} + +void GLDTableSetting::deleteHeaderRow(int index) +{ + assert((index >= 0) && (index < m_headerRows.count())); + m_headerRows.removeAt(index); +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2006-01-19 + 功能: 删除合计行 + 参数: index -- 合计行下标 +-----------------------------------------------------------------------------*/ +void GLDTableSetting::deleteTotalRow(int index) +{ + assert((index >= 0) && (index < m_totalRows.count())); + m_totalRows.removeAt(index); +} + +GLDHeaderRowFieldSettings *GLDTableSetting::insertHeaderRow(int index) +{ + GLDHeaderRowFieldSettings *result; + result = createHeaderRowFieldSettings(this); + result->setCount(m_owner->owner()->colSettings()->count()); + + if (index == -1) + { + m_headerRows.push_back(result); + } + else + { + m_headerRows.insert(index, result); + } + + return result; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2006-01-19 + 功能: 插入合计行 + 参数: index -- 插入的下标 + 返回: 合计行对象 +-----------------------------------------------------------------------------*/ +GLDTotalRowFieldSettings *GLDTableSetting::insertTotalRow(int index) +{ + GLDTotalRowFieldSettings *result = createTotalRowFieldSettings(this); + result->setCount(m_owner->owner()->colSettings()->count()); + + if (index == -1) + { + m_totalRows.push_back(result); + } + else + { + m_totalRows.insert(index, result); + } + + return result; +} + +int GLDTableSetting::index() const +{ + return m_owner->indexOf(const_cast(this)); +} + +int GLDTableSetting::defRowHeight() const +{ + return m_defRowHeight; +} + +void GLDTableSetting::setDefRowHeight(int value) +{ + m_defRowHeight = value; +} + +GLDFieldSettings *GLDTableSetting::fieldSettings() const +{ + return m_fieldSettings; +} + +CGLDExtPropDefs *GLDTableSetting::extPropDefs() const +{ + return m_extProps; +} + +bool GLDTableSetting::hasHeaderRow() +{ + return !m_headerRows.isEmpty(); +} + +bool GLDTableSetting::hasTotalRow() +{ + return !m_totalRows.isEmpty(); +} + +GString GLDTableSetting::refDatabaseName() const +{ + return m_refDatabaseName; +} + +void GLDTableSetting::setRefDatabaseName(const GString &value) +{ + m_refDatabaseName = value; +} + +GString GLDTableSetting::refTableName() const +{ + return m_refTableName; +} + +GLDGridRules *GLDTableSetting::rules() const +{ + return m_rules; +} + +PtrInt GLDTableSetting::tag() const +{ + return m_tag; +} + +void GLDTableSetting::setTag(const PtrInt value) +{ + m_tag = value; +} + +int GLDTableSetting::headerRowCount() const +{ + return (int)m_headerRows.size(); +} + +int GLDTableSetting::totalRowCount() const +{ + return (int)m_totalRows.size(); +} + +GLDHeaderRowFieldSettings *GLDTableSetting::headerRows(int index) +{ + return m_headerRows[index]; +} + +bool GLDTableSetting::customDataSource() const +{ + return m_customDataSource; +} + +void GLDTableSetting::setCustomDataSource(const bool &value) +{ + m_customDataSource = value; +} + +GString GLDTableSetting::masterViewName() const +{ + return m_masterViewName; +} + +void GLDTableSetting::setMasterViewName(const GString &value) +{ + m_masterViewName = value; +} + +GString GLDTableSetting::selfFieldName() const +{ + return m_selfFieldName; +} + +void GLDTableSetting::setSelfFieldName(const GString &value) +{ + m_selfFieldName = value; +} + +GString GLDTableSetting::masterFieldName() const +{ + return m_masterFieldName; +} + +void GLDTableSetting::setMasterFieldName(const GString &value) +{ + m_masterFieldName = value; +} + +GString GLDTableSetting::primaryKeyFieldName() const +{ + return m_primaryKeyFieldName; +} + +void GLDTableSetting::setPrimaryKeyFieldName(const GString &value) +{ + m_primaryKeyFieldName = value; +} + +GString GLDTableSetting::parentKeyFieldName() const +{ + return m_parentKeyFieldName; +} + +void GLDTableSetting::setParentKeyFieldName(const GString &value) +{ + m_parentKeyFieldName = value; +} + +bool GLDTableSetting::isTree() const +{ + return m_isTree; +} + +void GLDTableSetting::setIsTree(bool value) +{ + m_isTree = value; +} + +bool GLDTableSetting::isTreeWithMasterView() const +{ + return m_isTreeWithMasterView; +} + +void GLDTableSetting::setIsTreeWithMasterView(bool value) +{ + m_isTreeWithMasterView = value; +} + +GLDTotalStyle GLDTableSetting::totalStyle() const +{ + return m_totalStyle; +} + +void GLDTableSetting::setTotalStyle(GLDTotalStyle value) +{ + m_totalStyle = value; +} + +bool GLDTableSetting::needExpandTotalExpr() const +{ + return m_needExpandTotalExpr; +} + +void GLDTableSetting::setNeedExpandTotalExpr(const bool value) +{ + m_needExpandTotalExpr = value; +} + +bool GLDTableSetting::cloneFlag() const +{ + return m_cloneFlag; +} + +void GLDTableSetting::setCloneFlag(bool value) +{ + m_cloneFlag = value; +} +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:编译,编译字段设置及规则 +-----------------------------------------------------------------------------*/ +void GLDTableSetting::compile() +{ + // assert(m_owner->owner()->DesignState); + m_needExpandTotalExpr = false; + + for (int i = 0; i <= m_fieldSettings->count() - 1; i++) + { + //if not m_owner.m_owner.colSettings(i).crossExtFlag() then + m_fieldSettings->items(i)->compile(); + } + + for (int i = 0; i <= headerRowCount() - 1; i++) + { + for (int j = 0; j <= headerRows(i)->count() - 1; j++) + { + headerRows(i)->items(j)->compile(); + } + } + + for (int i = 0; i <= totalRowCount() - 1; i++) + { + for (int j = 0; j <= totalRows(i)->count() - 1; j++) + { + totalRows(i)->items(j)->compile(); + } + } + + for (int i = 0; i <= m_rules->count() - 1; i++) + { + m_rules->items(i)->compile(); + } +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 从流对象中装载数据 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDTableSetting::loadFromStream(GStream *stream) +{ + int nInts(0); + int nCount(0); + readStrFromStream(stream, m_refTableName); + readStrFromStream(stream, m_refDatabaseName); + readIntFromStream(stream, m_defRowHeight); + readBoolFromStream(stream, m_customDataSource); + readStrFromStream(stream, m_masterViewName); + readStrFromStream(stream, m_selfFieldName); + readStrFromStream(stream, m_masterFieldName); + readStrFromStream(stream, m_primaryKeyFieldName); + readStrFromStream(stream, m_parentKeyFieldName); + readBoolFromStream(stream, m_isTree); + readBoolFromStream(stream, m_isTreeWithMasterView); + readIntFromStream(stream, nInts); + m_totalStyle = ((GLDTotalStyle) nInts); + m_rules->loadFromStream(stream); + m_fieldSettings->loadFromStream(stream); + readIntFromStream(stream, nCount); + + for (int i = 0; i <= nCount - 1; i++) + { + insertHeaderRow(-1)->loadFromStream(stream); + } + + readIntFromStream(stream, nCount); + + for (int i = 0; i <= nCount - 1; i++) + { + insertTotalRow(-1)->loadFromStream(stream); + } + + //todo yaok + // GSPExtPropDefsStreamBuilder::read(stream, m_extProps); +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 保存数据到流对象中 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDTableSetting::saveToStream(GStream *stream) +{ + writeStrToStream(stream, m_refTableName); + writeStrToStream(stream, m_refDatabaseName); + writeIntToStream(stream, m_defRowHeight); + writeBoolToStream(stream, m_customDataSource); + writeStrToStream(stream, m_masterViewName); + writeStrToStream(stream, m_selfFieldName); + writeStrToStream(stream, m_masterFieldName); + writeStrToStream(stream, m_primaryKeyFieldName); + writeStrToStream(stream, m_parentKeyFieldName); + writeBoolToStream(stream, m_isTree); + writeBoolToStream(stream, m_isTreeWithMasterView); + writeIntToStream(stream, (int)m_totalStyle); + m_rules->saveToStream(stream); + m_fieldSettings->saveToStream(stream); + writeIntToStream(stream, (int)m_headerRows.size()); + + for (int i = 0; i != (int)m_headerRows.size(); i++) + { + headerRows(i)->saveToStream(stream); + } + + writeIntToStream(stream, (int)m_totalRows.size()); + + for (int i = 0; i != (int)m_totalRows.size(); i++) + { + totalRows(i)->saveToStream(stream); + } + + //todo yaok + //GSPExtPropDefsStreamBuilder::write(stream, m_extProps); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:设置参考表名 + 参数:参考表名 +-----------------------------------------------------------------------------*/ +void GLDTableSetting::setRefTableName(const GString &value) +{ + if (!m_owner->owner()->designState()) + { + gldError("SNeedDesignState"); + } + + m_refTableName = value; +} + +void GLDTableSetting::clearCompileInfo() +{ + for (int i = 0; i <= m_fieldSettings->count() - 1; i++) + { + m_fieldSettings->items(i)->clearCompileInfo(); + } + + for (int i = 0; i <= headerRowCount() - 1; i++) + { + for (int j = 0; j <= headerRows(i)->count() - 1; j++) + { + headerRows(i)->items(j)->clearCompileInfo(); + } + } + + for (int i = 0; i <= totalRowCount() - 1; i++) + { + for (int j = 0; j <= totalRows(i)->count() - 1; j++) + { + totalRows(i)->items(j)->clearCompileInfo(); + } + } + + for (int i = 0; i <= m_rules->count() - 1; i++) + { + m_rules->items(i)->clearCompileInfo(); + } +} + +GLDTableSetting *GLDTableSetting::clone() +{ + GLDTableSetting *result = createTableSetting(m_owner); + result->initialize(); + GMemoryStream oStream; + saveToStream(&oStream); + oStream.seek(0); + result->loadFromStream(&oStream); + result->setCloneFlag(true); + return result; +} + +/* GLDFilterRows */ + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:构造函数,创建对象列表 + 参数:owner -- 所属容器 +-----------------------------------------------------------------------------*/ +GLDFilterRows::GLDFilterRows(GLDGridSetting *owner) +{ + m_owner = owner; +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:析构函数,释放对象列表 +-----------------------------------------------------------------------------*/ +GLDFilterRows::~GLDFilterRows() +{ + clear(); +} + +GLDGridSetting *GLDFilterRows::owner() const +{ + return m_owner; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 清除标题行 +-----------------------------------------------------------------------------*/ +void GLDFilterRows::clear() +{ + m_list.clear(); +} + +int GLDFilterRows::count() const +{ + return (int)m_list.size(); +} + +int GLDFilterRows::indexOf(GLDFilterRow *value) const +{ + return m_list.indexOf(value); +} + +GLDFilterRow *GLDFilterRows::items(int index) +{ + return m_list[index]; +} + +GLDFilterRow *GLDFilterRows::operator[](int index) +{ + return items(index); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:删除指定下标标题行 + 参数:index -- 下标 +-----------------------------------------------------------------------------*/ +void GLDFilterRows::Delete(int index) +{ + assert((index >= 0) && (index <= count() - 1)); + m_list.removeAt(index); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:插入标题行 + 参数:index -- 插入位置 + 返回:插入的标题行对象 +-----------------------------------------------------------------------------*/ +GLDFilterRow *GLDFilterRows::insert(int index) +{ + GLDFilterRow *result = createFilterRow(this); + + if (count() == 0) + { + m_list.push_back(result); + } + else + { + if (-1 == index) + { + if (m_list.isEmpty()) + { + m_list.push_back(result); + } + else + { + m_list.insert(m_list.count() - 1, result); + } + } + else + { + m_list.insert(index, result); + } + } + + return result; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 从流对象中装载数据 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDFilterRows::loadFromStream(GStream *stream) +{ + int nInts(0); + readIntFromStream(stream, nInts); + clear(); + + for (int i = 0; i <= nInts - 1; i++) + { + insert()->loadFromStream(stream); + } +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 保存数据到流对象中 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDFilterRows::saveToStream(GStream *stream) +{ + writeIntToStream(stream, count()); + + for (int i = 0; i <= count() - 1; i++) + { + items(i)->saveToStream(stream); + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:设置标题行数 + 参数:value -- 标题行数 +-----------------------------------------------------------------------------*/ +void GLDFilterRows::setCount(const int value) +{ + int nSize = (int)m_list.size(); + + if (value == nSize) + { + return; + } + + if (value > nSize) + { + for (int i = nSize; i <= value - 1; i++) + { + m_list.push_back(createFilterRow(this)); + } + } +} + +void GLDFilterRows::clearCompileInfo() +{ + for (int i = 0; i <= count() - 1; i++) + { + items(i)->clearCompileInfo(); + } +} + +GLDFilterRow *GLDFilterRows::createFilterRow(GLDFilterRows *owner) +{ + return new GLDFilterRow(owner); +} + +void GLDFilterRows::compile() +{ + for (int i = 0; i <= count() - 1; i++) + { + items(i)->compile(); + } +} + +/* GLDFilterRow */ + +void GLDFilterRow::clearCompileInfo() +{ + for (int i = 0; i <= cellCount() - 1; i++) + { + cells(i)->clearCompileInfo(); + } +} + +void GLDFilterRow::compile() +{ + for (int i = 0; i <= cellCount() - 1; i++) + { + cells(i)->compile(); + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:构造函数,创建单元格列表 +-----------------------------------------------------------------------------*/ +GLDFilterRow::GLDFilterRow(GLDFilterRows *owner) +{ + m_owner = owner; + setCellCount(m_owner->owner()->colSettings()->count()); + m_rowHeight = CDefFilterRowHeight; +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:析构函数,释放单元格列表 +-----------------------------------------------------------------------------*/ +GLDFilterRow::~GLDFilterRow() +{ + clear(); +} + +GLDFilterRows *GLDFilterRow::owner() const +{ + return m_owner; +} + +int GLDFilterRow::indexOf(GLDFilterCell *value) +{ + return m_list.indexOf(value); +} + +int GLDFilterRow::index() const +{ + return m_owner->indexOf(const_cast(this)); +} + +int GLDFilterRow::rowHeight() const +{ + return m_rowHeight; +} + +void GLDFilterRow::setRowHeight(const int &value) +{ + m_rowHeight = value; +} + +int GLDFilterRow::cellCount() const +{ + return (int)m_list.size(); +} + +GLDFilterCell *GLDFilterRow::cells(int index) +{ + return m_list[index]; +} + +GLDFilterCell *GLDFilterRow::operator[](int index) +{ + return cells(index); +} + +GObjectList &GLDFilterRow::list() +{ + return m_list; +} + +GLDFilterCell *GLDFilterRow::cellByCaption(const GString &caption) +{ + for (int i = 0; i <= cellCount() - 1; i++) + { + if (cells(i)->caption().toLower() == caption.toLower()) + { + return cells(i); + } + } + + return NULL; +} + +GLDFilterCell *GLDFilterRow::creatrFilterCell(GLDFilterRow *owner) +{ + return new GLDFilterCell(owner); +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 从流对象中装载数据 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDFilterRow::loadFromStream(GStream *stream) +{ + readIntFromStream(stream, m_rowHeight); + + for (int i = 0; i <= cellCount() - 1; i++) + { + cells(i)->loadFromStream(stream); + } +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 保存数据到流对象中 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDFilterRow::saveToStream(GStream *stream) +{ + writeIntToStream(stream, m_rowHeight); + + for (int i = 0; i <= cellCount() - 1; i++) + { + cells(i)->saveToStream(stream); + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:设置单元格数 + 参数:value -- 单元格数 +-----------------------------------------------------------------------------*/ +void GLDFilterRow::setCellCount(int value) +{ + int nSize = (int)m_list.size(); + + if (value == nSize) + { + return; + } + + if (value > nSize) + { + for (int i = nSize; i <= value - 1; i++) + { + m_list.push_back(creatrFilterCell(this)); + } + } +} + +void GLDFilterRow::Delete(int index) +{ + m_list.removeAt(index); +} + +void GLDFilterRow::clear() +{ + m_list.clear(); +} + +/* GLDTitleRows */ + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:构造函数,创建对象列表 + 参数:owner -- 所属容器 +-----------------------------------------------------------------------------*/ +GLDTitleRows::GLDTitleRows(GLDGridSetting *owner) +{ + m_owner = owner; +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:析构函数,释放对象列表 +-----------------------------------------------------------------------------*/ +GLDTitleRows::~GLDTitleRows() +{ + clear(); +} + +GLDGridSetting *GLDTitleRows::owner() const +{ + return m_owner; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 清除标题行 +-----------------------------------------------------------------------------*/ +void GLDTitleRows::clear() +{ + m_list.clear(); +} + +int GLDTitleRows::count() const +{ + return (int)m_list.size(); +} + +int GLDTitleRows::indexOf(GLDTitleRow * value) const +{ + return m_list.indexOf(value); +} + +GLDTitleRow *GLDTitleRows::operator[](int index) +{ + return items(index); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:删除指定下标标题行 + 参数:index -- 下标 +-----------------------------------------------------------------------------*/ +void GLDTitleRows::Delete(int index) +{ + assert((index >= 0) && (index < count())); + m_list.removeAt(index); +} + +GString GLDTitleRows::fullTitle(int index) const +{ + GString result; + + //assert(count() > 0); + if (count() == 0) + { + result = ""; + } + else + { + result = items(0)->cells(index)->caption(); + QString sFirstMerge = result; + + for (int i = 1; i <= count() - 1; i++) + { +// int nTest = items(i)->cells(index)->mergeID(); + if (items(i)->cells(index)->mergeID() != 0 && items(i)->cells(index)->mergeID() == items(i - 1)->cells(index)->mergeID()) + { + result = result + "|" + sFirstMerge; + } + else + { + result = result + "|" + items(i)->cells(index)->caption(); + sFirstMerge = items(i)->cells(index)->caption(); + } + } + } + + return result; +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:返回指定下标标题行对象 + 参数:index -- 下标 + 返回:index对应标题行对象 +-----------------------------------------------------------------------------*/ +GLDTitleRow *GLDTitleRows::items(int index) const +{ + assert((index >= 0) && (index < count())); + return m_list[index]; +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:插入标题行 + 参数:index -- 插入位置 + 返回:插入的标题行对象 +-----------------------------------------------------------------------------*/ +GLDTitleRow *GLDTitleRows::insert(int index) +{ + GLDTitleRow *result = createTitleRow(this); + + if ((count() == 0) || (index == -1)) + { + m_list.push_back(result); + } + else + { + m_list.insert(index, result); + } + + return result; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 从流对象中装载数据 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDTitleRows::loadFromStream(GStream *stream) +{ + int nInts(0); + readIntFromStream(stream, nInts); + clear(); + + for (int i = 0; i <= nInts - 1; i++) + { + insert()->loadFromStream(stream); + } +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 保存数据到流对象中 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDTitleRows::saveToStream(GStream *stream) +{ + writeIntToStream(stream, count()); + + for (int i = 0; i <= count() - 1; i++) + { + items(i)->saveToStream(stream); + } +} + +void GLDTitleRows::setCount(const int value) +{ + int nSize = (int)m_list.size(); + + if (value == nSize) + { + return; + } + + // m_list.setCount(value); + if (value > nSize) + { + for (int i = nSize; i <= value - 1; i++) + { + m_list.push_back(createTitleRow(this)); + } + } +} + +void GLDTitleRows::clearCompileInfo() +{ + for (int i = 0; i <= count() - 1; i++) + { + items(i)->clearCompileInfo(); + } +} + +GLDTitleRow *GLDTitleRows::doCreateTitleRow(GLDTitleRows *owner) +{ + return new GLDTitleRow(owner); +} + +GLDTitleRow *GLDTitleRows::createTitleRow(GLDTitleRows *owner) +{ + GLDTitleRow *result = doCreateTitleRow(owner); + result->setCellCount(owner->owner()->colSettings()->count()); + return result; +} + +void GLDTitleRows::compile() +{ + for (int i = 0; i <= count() - 1; i++) + { + items(i)->compile(); + } +} + +/* GLDTitleRow */ + +void GLDTitleRow::clearCompileInfo() +{ + for (int i = 0; i <= cellCount() - 1; i++) + { + cells(i)->clearCompileInfo(); + } +} + +void GLDTitleRow::compile() +{ + for (int i = 0; i <= cellCount() - 1; i++) + { + cells(i)->compile(); + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:构造函数,创建单元格列表 +-----------------------------------------------------------------------------*/ +GLDTitleRow::GLDTitleRow(GLDTitleRows *owner) +{ + m_owner = owner; + m_rowHeight = CDefTitleRowHeight; +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:析构函数,释放单元格列表 +-----------------------------------------------------------------------------*/ +GLDTitleRow::~GLDTitleRow() +{ + clear(); +} + +void GLDTitleRow::clear() +{ + m_list.clear(); +} + +GLDTitleCell *GLDTitleRow::cellByCaption(const GString &caption) +{ + GLDTitleCell *result = NULL; + + for (int i = 0; i <= cellCount() - 1; i++) + { + if (cells(i)->caption().toLower() == caption.toLower()) + { + result = cells(i); + break; + } + } + + return result; +} + +int GLDTitleRow::index() +{ + return m_owner->indexOf(this); +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 从流对象中装载数据 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDTitleRow::loadFromStream(GStream *stream) +{ + readIntFromStream(stream, m_rowHeight); + + for (int i = 0; i <= cellCount() - 1; i++) + { + cells(i)->loadFromStream(stream); + } +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 保存数据到流对象中 + 参数: stream -- 流 对 象 +-----------------------------------------------------------------------------*/ +void GLDTitleRow::saveToStream(GStream *stream) +{ + writeIntToStream(stream, m_rowHeight); + + for (int i = 0; i <= cellCount() - 1; i++) + { + cells(i)->saveToStream(stream); + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:设置单元格数 + 参数:value -- 单元格数 +-----------------------------------------------------------------------------*/ +void GLDTitleRow::setCellCount(int value) +{ + int nSize = (int)m_list.size(); + + if (value == nSize) + { + return; + } + + if (value > nSize) + { + for (int i = nSize; i <= value - 1; i++) + { + m_list.push_back(createTitleCell(this)); + } + } +} + +void GLDTitleRow::Delete(int index) +{ + m_list.removeAt(index); +} + +GLDGridSetting *GLDTitleRow::gridSetting() +{ + return m_owner->owner(); +} + +GLDTitleCell *GLDTitleRow::createTitleCell(GLDTitleRow *owner) +{ + return new GLDTitleCell(owner); +} + +int GLDTitleRow::rowHeight() const +{ + return m_rowHeight; +} + +void GLDTitleRow::setRowHeight(int value) +{ + m_rowHeight = value; +} + +int GLDTitleRow::cellCount() const +{ + return (int)m_list.size(); +} + +GLDTitleCell *GLDTitleRow::cells(const int index) const +{ + return m_list[index]; +} + +GObjectList &GLDTitleRow::list() +{ + return m_list; +} + +/*GSPHeaderRowFieldSettings */ + +GLDExpandRowFieldSetting *GLDHeaderRowFieldSettings::createExpandRowFieldSetting() +{ + return new GLDHeaderRowFieldSetting(this); +} + +GLDHeaderRowFieldSetting *GLDHeaderRowFieldSettings::items(int index) +{ + // assert((index >= 0) &&(index < count())); + return dynamic_cast(m_list[index]); +} + +/* GLDHeaderRowFieldSetting */ + +void GLDHeaderRowFieldSetting::compile() +{ + try + { + GLDExpandRowFieldSetting::compile(); + } + catch (...) + { + //todo yaok + //throw new eGSPHeaderRowExprException(format(GSPGridSetting_SInvalidHeaderRowExpr, + //refFullName(), m_value), tableIndex(), Index); + } +} + +/* GLDExpandRowFieldSettings */ + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:构造函数,创建对象列表 +-----------------------------------------------------------------------------*/ +GLDExpandRowFieldSettings::GLDExpandRowFieldSettings(GLDTableSetting *owner) +{ + m_owner = owner; + m_visible = true; + m_rowHeight = CDefRowHeight; +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:析构函数,释放对象列表 +-----------------------------------------------------------------------------*/ +GLDExpandRowFieldSettings::~GLDExpandRowFieldSettings() +{ + clear(); +} + +GLDExpandRowFieldSetting *GLDExpandRowFieldSettings::createExpandRowFieldSetting() +{ + return NULL; + // assert(false); +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 从流对象中装载数据 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDExpandRowFieldSettings::loadFromStream(GStream *stream) +{ + readIntFromStream(stream, m_rowHeight); + + for (int i = 0; i <= count() - 1; i++) + { + items(i)->loadFromStream(stream); + } +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 保存数据到流对象中 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDExpandRowFieldSettings::saveToStream(GStream *stream) +{ + writeIntToStream(stream, m_rowHeight); + + for (int i = 0; i <= count() - 1; i++) + { + items(i)->saveToStream(stream); + } +} + +int GLDExpandRowFieldSettings::count() const +{ + return (int)m_list.size(); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:设置字段设置对象数 + 参数:value -- 字段设置对象数 +-----------------------------------------------------------------------------*/ +void GLDExpandRowFieldSettings::setCount(int value) +{ + int nSize = (int)m_list.size(); + + if (value == nSize) + { + return; + } + + if (value > nSize) + { + for (int i = nSize; i <= value - 1; i++) + { + m_list.push_back(createExpandRowFieldSetting()); + } + } +} + +bool GLDExpandRowFieldSettings::visible() const +{ + return m_visible; +} + +void GLDExpandRowFieldSettings::setVisible(bool value) +{ + m_visible = value; +} + +int GLDExpandRowFieldSettings::rowHeight() const +{ + return m_rowHeight; +} + +void GLDExpandRowFieldSettings::setRowHeight(int value) +{ + m_rowHeight = value; +} + +GLDTableSetting *GLDExpandRowFieldSettings::owner() const +{ + return m_owner; +} + +GLDExpandRowFieldSetting *GLDExpandRowFieldSettings::items(int index) +{ + return m_list[index]; +} + +GObjectList &GLDExpandRowFieldSettings::list() +{ + return m_list; +} + +GLDExpandRowFieldSetting *GLDExpandRowFieldSettings::operator[](int index) +{ + return items(index); +} + +GStringList GLDExpandRowFieldSettings::toValueArray() +{ + GStringList result; + + for (int i = 0; i <= count() - 1; i++) + { + result.append(items(i)->value()); + } + + return result; +} + +void GLDExpandRowFieldSettings::Delete(int index) +{ + m_list.removeAt(index); +} + +void GLDExpandRowFieldSettings::clear() +{ + m_list.clear(); +} + +/* GLDExpandRowFieldSetting */ + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-15 + 功能: 构造函数 +-----------------------------------------------------------------------------*/ +GLDExpandRowFieldSetting::GLDExpandRowFieldSetting(GLDExpandRowFieldSettings *owner) +{ + m_isSimpleStr = false; + m_mergeID = 0; + m_owner = owner; + m_cellFormat = new GLDCellFormat; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-15 + 功能: 析构函数 +-----------------------------------------------------------------------------*/ +GLDExpandRowFieldSetting::~GLDExpandRowFieldSetting() +{ + freeAndNil(m_cellFormat); +} + +void GLDExpandRowFieldSetting::clearCompileInfo() +{ +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-16 + 功能: 编译合计行 +-----------------------------------------------------------------------------*/ +void GLDExpandRowFieldSetting::compile() +{ + GString sExpr; + + if (textIsLabel(m_value)) + { + m_resultDataType = c_gdtString; + m_isSimpleStr = true; + } + else + { + sExpr = copy(m_value, 1); + m_isSimpleStr = false; + } +} + +GString GLDExpandRowFieldSetting::varCodes(int index) +{ + Q_UNUSED(index); + return ""; +} + +int GLDExpandRowFieldSetting::varCount() +{ + return -1; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-15 + 功能: 从流对象中装载数据 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDExpandRowFieldSetting::loadFromStream(GStream *stream) +{ + readIntFromStream(stream, m_mergeID); + readStrFromStream(stream, m_value); + m_cellFormat->loadFromStream(stream); +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-15 + 功能: 保存数据到流对象中 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDExpandRowFieldSetting::saveToStream(GStream *stream) +{ + writeIntToStream(stream, m_mergeID); + writeStrToStream(stream, m_value); + m_cellFormat->saveToStream(stream); +} + +bool GLDExpandRowFieldSetting::isSimpleStr() const +{ + return m_isSimpleStr; +} + +int GLDExpandRowFieldSetting::mergeID() const +{ + return m_mergeID; +} + +void GLDExpandRowFieldSetting::setMergeID(int value) +{ + m_mergeID = value; +} + +GLDDataType GLDExpandRowFieldSetting::resultDataType() const +{ + return m_resultDataType; +} + +GString GLDExpandRowFieldSetting::value() const +{ + return m_value; +} + +void GLDExpandRowFieldSetting::setValue(GString value) +{ + m_value = value; +} + +int GLDExpandRowFieldSetting::index() +{ + return m_owner->list().indexOf(this); +} + +GLDCellFormat *GLDExpandRowFieldSetting::cellFormat() const +{ + return m_cellFormat; +} + +void GLDExpandRowFieldSetting::setCellFormat(GLDCellFormat *value) +{ + m_cellFormat = value; +} + +bool GLDExpandRowFieldSetting::isFixedCol() +{ + return m_owner->owner()->owner()->owner()->colSettings()->items(index())->isFixedCol(); +} + +GString GLDExpandRowFieldSetting::refFullName() +{ + return m_owner->owner()->refFullName(); +} + +void GLDExpandRowFieldSetting::setVarCodes(int index, const GString &value) +{ + // todo + //parser_->setVarCodes(index, value); + Q_UNUSED(index); + Q_UNUSED(value); +} + +int GLDExpandRowFieldSetting::tableIndex() +{ + return m_owner->owner()->index(); +} + +/* GLDTotalRowFieldSettings */ + +GLDExpandRowFieldSetting *GLDTotalRowFieldSettings::createExpandRowFieldSetting() +{ + return new GLDTotalRowFieldSetting(this); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:返回指定下标的字段设置对象 + 参数:index -- 下标 + 返回:index对应的字段设置对象 +-----------------------------------------------------------------------------*/ +GLDTotalRowFieldSetting *GLDTotalRowFieldSettings::items(int index) +{ + return dynamic_cast(m_list[index]); +} + +/*GSPTotalRowFieldSetting */ + +void GLDTotalRowFieldSetting::compile() +{ + try + { + GLDExpandRowFieldSetting::compile(); + } + catch (...) + { + //todo yaok + //throw new eGSPTotalRowExprException(format(GSPGridSetting_SInvalidTotalRowExpr, + //refFullName(), m_value), tableIndex(), Index); + } +} + +/* GLDCellFormat */ + +GLDCellFormat::GLDCellFormat() +{ + m_fontName = CDefFontName; + m_fontSize = DefFontSize; + m_foreColor = DefForeColor; + m_fontStyle = 0; + m_backColor = DefBackColor; + m_leftLineWidth = DefLeftLineWidth; + m_topLineWidth = DefTopLineWidth; + m_rightLineWidth = DefRightLineWidth; + m_bottomLineWidth = DefBottomLineWidth; + m_diagonalWidth = DefDiagonalWidth; + m_antiDiagonalWidth = DefAntiDiagonalWidth; + m_horzAlignment = (int)DefHorzAlignment; + m_vertAlignment = (int)DefVertAlignment; + m_formatStr = CDefFormatStr; + m_nullIsZero = DefNullIsZero; + m_leftMargin = DefHorzMargin; + m_rightMargin = DefHorzMargin; + m_topMargin = DefVertMargin; + m_bottomMargin = DefVertMargin; + m_imageIndex = DefImageIndex; + m_imageLayout = CDefImageLayout; +} + +bool GLDCellFormat::isEqual(GLDCellFormat *cellFormat) +{ + + // assert(cellFormat != NULL); + return (cellFormat->m_fontName.toLower() == m_fontName.toLower()) + && (cellFormat->m_fontSize == m_fontSize) + && (cellFormat->m_foreColor == m_foreColor) + && (cellFormat->m_backColor == m_backColor) + && (cellFormat->m_fontStyle == m_fontStyle) + && (cellFormat->m_leftLineWidth == m_leftLineWidth) + && (cellFormat->m_rightLineWidth == m_rightLineWidth) + && (cellFormat->m_topLineWidth == m_topLineWidth) + && (cellFormat->m_bottomLineWidth == m_bottomLineWidth) + && (cellFormat->m_diagonalWidth == m_diagonalWidth) + && (cellFormat->m_antiDiagonalWidth == m_antiDiagonalWidth) + && (cellFormat->m_horzAlignment == m_horzAlignment) + && (cellFormat->m_leftMargin == m_leftMargin) + && (cellFormat->m_rightMargin == m_rightMargin) + && (cellFormat->m_topMargin == m_topMargin) + && (cellFormat->m_bottomMargin == m_bottomMargin) + && (cellFormat->m_imageIndex == m_imageIndex) + && (cellFormat->m_imageLayout == m_imageLayout); +} + +GRgb GLDCellFormat::foreColor() const +{ + return m_foreColor; +} + +void GLDCellFormat::setForeColor(const GRgb value) +{ + m_foreColor = value; +} + +GString GLDCellFormat::fontName() const +{ + return m_fontName; +} + +void GLDCellFormat::setFontName(GString value) +{ + m_fontName = value; +} + +int GLDCellFormat::fontSize() const +{ + return m_fontSize; +} + +void GLDCellFormat::setFontSize(int value) +{ + m_fontSize = value; +} +FontStyles GLDCellFormat::fontStyle() const +{ + return m_fontStyle; +} + +void GLDCellFormat::setFontStyle(FontStyles value) +{ + m_fontStyle = value; +} + +GRgb GLDCellFormat::backColor() const +{ + return m_backColor; +} + +void GLDCellFormat::setBackColor(const GRgb value) +{ + m_backColor = value; +} + +GLDHorzAlignment GLDCellFormat::horzAlignment() const +{ + return (GLDHorzAlignment) m_horzAlignment; +} + +GLDVertAlignment GLDCellFormat::vertAlignment() const +{ + return (GLDVertAlignment) m_vertAlignment; +} + +void GLDCellFormat::setVertAlignment(const GLDVertAlignment value) +{ + m_vertAlignment = (int)value; +} + +unsigned char GLDCellFormat::leftLineWidth() const +{ + return m_leftLineWidth; +} + +void GLDCellFormat::setLeftLineWidth(const unsigned char value) +{ + m_leftLineWidth = value; +} + +unsigned char GLDCellFormat::topLineWidth() const +{ + return m_topLineWidth; +} + +void GLDCellFormat::setTopLineWidth(unsigned char value) +{ + m_topLineWidth = value; +} + +unsigned char GLDCellFormat::rightLineWidth() const +{ + return m_rightLineWidth; +} + +void GLDCellFormat::setRightLineWidth(unsigned char value) +{ + m_rightLineWidth = value; +} + +unsigned char GLDCellFormat::bottomLineWidth() const +{ + return m_bottomLineWidth; +} + +void GLDCellFormat::setBottomLineWidth(unsigned char value) +{ + m_bottomLineWidth = value; +} + +unsigned char GLDCellFormat::diagonalWidth() const +{ + return m_diagonalWidth; +} + +void GLDCellFormat::setDiagonalWidth(unsigned char value) +{ + m_diagonalWidth = value; +} + +unsigned char GLDCellFormat::antiDiagonalWidth() const +{ + return m_antiDiagonalWidth; +} + +void GLDCellFormat::setAntiDiagonalWidth(unsigned char value) +{ + m_antiDiagonalWidth = value; +} + +GString GLDCellFormat::formatStr() const +{ + return m_formatStr; +} + +void GLDCellFormat::setFormatStr(const GString &value) +{ + m_formatStr = trim(value); +} + +bool GLDCellFormat::nullIsZero() const +{ + return m_nullIsZero; +} + +void GLDCellFormat::setNullIsZero(const bool value) +{ + m_nullIsZero = value; +} + +unsigned char GLDCellFormat::leftMargin() const +{ + return m_leftMargin; +} + +void GLDCellFormat::setLeftMargin(unsigned char value) +{ + m_leftMargin = value; +} + +unsigned char GLDCellFormat::rightMargin() const +{ + return m_rightMargin; +} + +void GLDCellFormat::setRightMargin(unsigned char value) +{ + m_rightMargin = value; +} + +unsigned char GLDCellFormat::topMargin() const +{ + return m_topMargin; +} + +void GLDCellFormat::setTopMargin(unsigned char value) +{ + m_topMargin = value; +} + +unsigned char GLDCellFormat::bottomMargin() const +{ + return m_bottomMargin; +} + +void GLDCellFormat::setBottomMargin(unsigned char value) +{ + m_bottomMargin = value; +} + +int GLDCellFormat::imageIndex() const +{ + return m_imageIndex; +} + +void GLDCellFormat::setImageIndex(int value) +{ + m_imageIndex = value; +} + +GLDCellImageLayout GLDCellFormat::imageLayout() +{ + return m_imageLayout; +} + +void GLDCellFormat::setImageLayout(GLDCellImageLayout value) +{ + m_imageLayout = value; +} + +void GLDCellFormat::setHorzAlignment(const GLDHorzAlignment value) +{ + m_horzAlignment = (int)value; +} +void GLDCellFormat::loadFromStream(GStream *stream) +{ + unsigned char ucFontStyle; + int nImageLayout; + readStrFromStream(stream, m_fontName); + readIntFromStream(stream, m_fontSize); + readIntFromStream(stream, m_foreColor); + readIntFromStream(stream, m_backColor); + readByteFromStream(stream, m_leftLineWidth); + readByteFromStream(stream, m_topLineWidth); + readByteFromStream(stream, m_rightLineWidth); + readByteFromStream(stream, m_bottomLineWidth); + readByteFromStream(stream, m_diagonalWidth); + readByteFromStream(stream, m_antiDiagonalWidth); + readIntFromStream(stream, m_horzAlignment); + readIntFromStream(stream, m_vertAlignment); + readStrFromStream(stream, m_formatStr); + readBoolFromStream(stream, m_nullIsZero); + readByteFromStream(stream, ucFontStyle); + m_fontStyle = (FontStyles)ucFontStyle; + readByteFromStream(stream, m_leftMargin); + readByteFromStream(stream, m_rightMargin); + readByteFromStream(stream, m_topMargin); + readByteFromStream(stream, m_bottomMargin); + readIntFromStream(stream, m_imageIndex); + readIntFromStream(stream, nImageLayout); + m_imageLayout = (GLDCellImageLayout)nImageLayout; +} + +void GLDCellFormat::saveToStream(GStream *stream) +{ + writeStrToStream(stream, m_fontName); + writeIntToStream(stream, m_fontSize); + writeIntToStream(stream, m_foreColor); + writeIntToStream(stream, m_backColor); + writeByteToStream(stream, m_leftLineWidth); + writeByteToStream(stream, m_topLineWidth); + writeByteToStream(stream, m_rightLineWidth); + writeByteToStream(stream, m_bottomLineWidth); + writeByteToStream(stream, m_diagonalWidth); + writeByteToStream(stream, m_antiDiagonalWidth); + writeIntToStream(stream, m_horzAlignment); + writeIntToStream(stream, m_vertAlignment); + writeStrToStream(stream, m_formatStr); + writeBoolToStream(stream, m_nullIsZero); + writeByteToStream(stream, (unsigned char)m_fontStyle); + writeByteToStream(stream, m_leftMargin); + writeByteToStream(stream, m_rightMargin); + writeByteToStream(stream, m_topMargin); + writeByteToStream(stream, m_bottomMargin); + writeIntToStream(stream, m_imageIndex); + writeIntToStream(stream, (int)m_imageLayout); +} + +/* GLDCellFormats */ + +GLDCellFormats::GLDCellFormats() +{ + m_list = new GObjectList; +} + +GLDCellFormats::~GLDCellFormats() +{ + freeAndNil(m_list); +} + +int GLDCellFormats::count() const +{ + return (int)m_list->size(); +} + +GLDCellFormat *GLDCellFormats::formats(const int index) const +{ + return m_list->at(index); +} + +/* GLDTableSettings */ + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:构造函数,创建对象列表 +-----------------------------------------------------------------------------*/ +GLDTableSettings::GLDTableSettings(GLDGridSetting *owner) +{ + m_owner = owner; + m_list = new GObjectList; + m_hasHeaderOrTotalRow = false; +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:析构函数,释放对象列表 +-----------------------------------------------------------------------------*/ +GLDTableSettings::~GLDTableSettings() +{ + freeAndNil(m_list); +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 清除表设置数据 + -----------------------------------------------------------------------------*/ +void GLDTableSettings::clear() +{ + m_list->clear(); +} + +int GLDTableSettings::count() const +{ + return (int)m_list->size(); +} + +int GLDTableSettings::indexOf(GLDTableSetting *tableSetting) const +{ + return m_list->indexOf(tableSetting); +} + +GLDTableSetting *GLDTableSettings::operator[](int index) +{ + return items(index) ; +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:编译 + -----------------------------------------------------------------------------*/ +void GLDTableSettings::compile() +{ + m_hasHeaderOrTotalRow = false; + + for (int i = 0; i <= count() - 1; i++) + { + items(i)->compile(); + m_hasHeaderOrTotalRow = m_hasHeaderOrTotalRow || items(i)->hasHeaderRow() + || items(i)->hasTotalRow(); + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:删除指定下标的表设置对象 + 参数:index -- 下标 +-----------------------------------------------------------------------------*/ +void GLDTableSettings::Delete(int index) +{ + assert((index >= 0) && (index < count())); + m_list->removeAt(index); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:返回指定下标的表设置对象 + 参数:index -- 下标 + 返回:index对应的表设置对象 +-----------------------------------------------------------------------------*/ +GLDTableSetting *GLDTableSettings::items(int index) +{ + assert((index >= 0) && (index < count())); + return (*m_list)[index]; +} + +GLDTableSetting *GLDTableSettings::doCreateTableSetting(GLDTableSettings *owner) +{ + return new GLDTableSetting(owner); +} + +GLDTableSetting *GLDTableSettings::createTableSetting(GLDTableSettings *owner) +{ + GLDTableSetting *result = doCreateTableSetting(owner); + result->initialize(); + return result; +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:插入表设置对象 + 参数:index -- 插入下标 + 返回:插入的表设置对象 +-----------------------------------------------------------------------------*/ +GLDTableSetting *GLDTableSettings::insert(int index) +{ + GLDTableSetting *result = createTableSetting(this); + + if (index == -1) + { + m_list->push_back(result); + } + else + { + m_list->insert(index, result); + } + + return result; +} + +GLDGridSetting *GLDTableSettings::owner() const +{ + return m_owner; +} + +bool GLDTableSettings::hasHeaderOrTotalRow() const +{ + return m_hasHeaderOrTotalRow; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 从流对象中装载数据 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDTableSettings::loadFromStream(GStream *stream) +{ + int nints(0); + readIntFromStream(stream, nints); + clear(); + + for (int i = 0; i <= nints - 1; i++) + { + insert()->loadFromStream(stream); + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:移动表设置对象 + 参数:fromIndex -- 源下标 + toIndex -- 目标下标 +-----------------------------------------------------------------------------*/ +void GLDTableSettings::move(int fromIndex, int toIndex) +{ + assert((fromIndex >= 0) && (fromIndex < count())); + assert((toIndex >= 0) && (toIndex < count())); + + if (fromIndex == toIndex) + { + return; + } + else + { + m_list->move(fromIndex, toIndex); + } +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 保存数据到流对象中 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDTableSettings::saveToStream(GStream *stream) +{ + writeIntToStream(stream, count()); + + for (int i = 0; i <= count() - 1; i++) + { + items(i)->saveToStream(stream); + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:设置表设置对象数 + 参数:value -- 表设置对象数 +-----------------------------------------------------------------------------*/ +void GLDTableSettings::setCount(const int value) +{ + int nSize = m_list->count(); + + if (value == nSize) + { + return; + } + + if (value > nSize) + { + for (int i = nSize; i <= value - 1; i++) + { + m_list->push_back(createTableSetting(this)); + } + } +} + +void GLDTableSettings::clearClonedTableSetting() +{ + for (int i = count() - 1; i >= 0; i--) + { + if (items(i)->cloneFlag()) + { + Delete(i); + } + } +} + +void GLDTableSettings::clearCompileInfo() +{ + for (int i = 0; i <= count() - 1; i++) + { + items(i)->clearCompileInfo(); + } +} + +void GLDTableSettings::clone(GLDTableSetting *protoType, int insertIndex, int count) +{ + assert((insertIndex >= 0) && (insertIndex < count)); + assert(protoType != NULL); + assert(count > 0); + + if (insertIndex == -1) + { + for (int i = 0; i <= count - 1; i++) + { + m_list->push_back(protoType->clone()); + } + } + else + { + for (int i = 0; i <= count - 1; i++) + { + m_list->insert(insertIndex, protoType->clone()); + } + } +} + +/* GLDFieldSettings */ + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:构造函数,创建对象列表 +-----------------------------------------------------------------------------*/ +GLDFieldSettings::GLDFieldSettings(GLDTableSetting *owner) +{ + m_owner = owner; +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:析构函数,释放对象列表 +-----------------------------------------------------------------------------*/ +GLDFieldSettings::~GLDFieldSettings() +{ + clear(); +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 从流对象中装载数据 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDFieldSettings::loadFromStream(GStream *stream) +{ + for (int i = 0; i <= count() - 1; i++) + { + items(i)->loadFromStream(stream); + } +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 保存数据到流对象中 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDFieldSettings::saveToStream(GStream *stream) +{ + for (int i = 0; i <= count() - 1; i++) + { + items(i)->saveToStream(stream); + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:设置字段设置对象数 + 参数:value -- 字段设置对象数 +-----------------------------------------------------------------------------*/ +void GLDFieldSettings::setCount(int value) +{ + int nSize = (int)m_list.size(); + + if (value == nSize) + { + return; + } + + if (value > nSize) + { + for (int i = nSize; i <= value - 1; i++) + { + m_list.push_back(createFieldSetting(this)); + } + } +} + +void GLDFieldSettings::Delete(int index) +{ + m_list.removeAt(index); +} + +void GLDFieldSettings::clear() +{ + m_list.clear(); +} + +GLDFieldSetting *GLDFieldSettings::createFieldSetting(GLDFieldSettings *owner) +{ + return new GLDFieldSetting(owner); +} + +GLDFieldSetting *GLDFieldSettings::items(int index) +{ + return m_list[index]; +} + +int GLDFieldSettings::count() const +{ + return (int)m_list.size(); +} + +GLDTableSetting *GLDFieldSettings::owner() const +{ + return m_owner; +} + +GObjectList &GLDFieldSettings::list() +{ + return m_list; +} + +GLDFieldSetting *GLDFieldSettings::operator[](int index) +{ + return items(index); +} + +/* GLDCustomFieldSetting */ + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:构造函数 + 参数:owner -- 所属容器 +-----------------------------------------------------------------------------*/ +GLDCustomFieldSetting::GLDCustomFieldSetting() + : m_mergeID(0), + m_extProps(new CGLDExtPropDefs), + m_cellFormat(new GLDCellFormat), + m_displayExprIsFieldName(false), + m_editTextIsDisplayText(true) +{ + m_extProps->AddRef(); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:析构函数,释放解析器对象 +-----------------------------------------------------------------------------*/ +GLDCustomFieldSetting::~GLDCustomFieldSetting() +{ + freeAndNil(m_cellFormat); + m_extProps->Release(); + m_extProps = NULL; +} + +GString GLDCustomFieldSetting::buildDisplayParserDisplayExpr() +{ + if ((m_displayExpr == "") && (m_editFieldName != "")) + { + return "=" + m_editFieldName; + } + else + { + return m_displayExpr; + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:建立显示表达式解析器 +-----------------------------------------------------------------------------*/ +void GLDCustomFieldSetting::buildDisplayParser() +{ +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:建立写入规则解析器 +-----------------------------------------------------------------------------*/ +void GLDCustomFieldSetting::buildSaveRuleParser() +{ +} + +void GLDCustomFieldSetting::clearCompileInfo() +{ + m_extProps->clearCompileInfo(); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:编译,设置编辑字段、写入字段下标,建立显示表达式解析器和写入规则解析器 +-----------------------------------------------------------------------------*/ +void GLDCustomFieldSetting::compile() +{ + GString sEditFieldName; + GString sSaveFieldName; + + // 编译编辑字段名称 + if (m_editFieldName != "") + { + if (m_editFieldName[0] == CExpressionMark) + { + sEditFieldName = copy(m_editFieldName, 1); + + if (!isExprEnumDateTimeField(sEditFieldName)) + { + gldFieldNameError(format(getGLDi18nStr(g_InvalidFieldNameMark), refFullName(), m_editFieldName), tableIndex(), index()); + } + } + else if (m_editFieldName[0] == CLookupMark) + { + sEditFieldName = copy(m_editFieldName, 1); + } + else + { + sEditFieldName = m_editFieldName; + } + + if (!isValidFieldName(sEditFieldName)) + { + gldFieldNameError(format(getGLDi18nStr(g_InvalidFieldName), GVariantList() << refFullName() << m_editFieldName), + tableIndex(), index()); + } + } + + // 编译保存字段名 + if (m_saveFieldName == "") + { + sSaveFieldName = m_editFieldName; + } + else + { + sSaveFieldName = m_saveFieldName; + } + + if (sSaveFieldName != "") + { + if (sSaveFieldName[0] == CExpressionMark) + { + { + sSaveFieldName = copy(sSaveFieldName, 1); + } + + if (!isExprEnumDateTimeField(sSaveFieldName)) + { + gldSaveFieldNameError(format(getGLDi18nStr(g_InvalidFieldNameMark), refFullName(), m_saveFieldName), tableIndex(), + index()); + } + } + else if (sSaveFieldName[0] == CLookupMark) + { + sSaveFieldName = copy(sSaveFieldName, 1); + } + + if (!isValidFieldName(sSaveFieldName)) + { + gldSaveFieldNameError(format(getGLDi18nStr(SInvalidSaveFieldName), refFullName(), m_saveFieldName), tableIndex(), index()); + } + } + + // 构造表达式解析器 + buildDisplayParser(); + buildSaveRuleParser(); + m_extProps->compile(); +} + +/*----------------------------------------------------------------------------- + 作者:Liuxd 2006-03-30 + 功能:显示表达式是否等于编辑字段 + 返回:相等标志 +-----------------------------------------------------------------------------*/ +bool GLDCustomFieldSetting::displayExprIsFieldName() const +{ + return (m_displayExpr == "") || m_displayExprIsFieldName; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 从流对象中装载数据 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDCustomFieldSetting::loadFromStream(GStream *stream) +{ + readIntFromStream(stream, m_mergeID); + readStrFromStream(stream, m_editFieldName); + readMemoFromStream(stream, m_displayExpr); + readStrFromStream(stream, m_saveFieldName); + readMemoFromStream(stream, m_saveRule); + readMemoFromStream(stream, m_nullValDisplayStr); + readMemoFromStream(stream, m_extData); + readBoolFromStream(stream, m_editTextIsDisplayText); + readStrFromStream(stream, m_editorName); + readMemoFromStream(stream, m_cellIdentity); + m_cellFormat->loadFromStream(stream); + //todo yaok + // GSPExtPropDefsStreamBuilder::read(stream, m_extProps); +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 保存数据到流对象中 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDCustomFieldSetting::saveToStream(GStream *stream) +{ + writeIntToStream(stream, m_mergeID); + writeStrToStream(stream, m_editFieldName); + writeMemoToStream(stream, m_displayExpr); + writeStrToStream(stream, m_saveFieldName); + writeMemoToStream(stream, m_saveRule); + writeMemoToStream(stream, m_nullValDisplayStr); + writeMemoToStream(stream, m_extData); + writeBoolToStream(stream, m_editTextIsDisplayText); + writeStrToStream(stream, m_editorName); + writeMemoToStream(stream, m_cellIdentity); + m_cellFormat->saveToStream(stream); + //todo yaok + // GSPExtPropDefsStreamBuilder::write(stream, m_extProps); +} + +void GLDCustomFieldSetting::setIsLabel(bool value) +{ + Q_UNUSED(value) +} + +GString GLDCustomFieldSetting::cellIdentity() const +{ + return m_cellIdentity; +} + +bool GLDCustomFieldSetting::isLabel() const +{ + return false; +} + +GString GLDCustomFieldSetting::varCodes(int index) const +{ + Q_UNUSED(index); + return ""; +} + +int GLDCustomFieldSetting::varCount() const +{ + return -1; +} + +GString GLDCustomFieldSetting::displayFieldName() const +{ + // assert(displayExprIsFieldName()); + if ("" == m_displayExpr) + { + return m_editFieldName; + } + else + { + return trim(copy(m_displayExpr, 1)); + } +} + +int GLDCustomFieldSetting::mergeID() const +{ + return m_mergeID; +} + +void GLDCustomFieldSetting::setMergeID(int value) +{ + m_mergeID = value; +} + +GString GLDCustomFieldSetting::editFieldName() const +{ + return m_editFieldName; +} + +void GLDCustomFieldSetting::setEditFieldName(const GString &value) +{ + m_editFieldName = value.trimmed(); +} + +GString GLDCustomFieldSetting::displayExpr() const +{ + return m_displayExpr; +} + +void GLDCustomFieldSetting::setDisplayExpr(const GString &value) +{ + m_displayExpr = value.trimmed(); +} + +GString GLDCustomFieldSetting::saveFieldName() const +{ + return m_saveFieldName; +} + +void GLDCustomFieldSetting::setSaveFieldName(const GString &value) +{ + m_saveFieldName = value.trimmed(); +} + +GString GLDCustomFieldSetting::saveRule() const +{ + return m_saveRule; +} + +void GLDCustomFieldSetting::setSaveRule(const GString &value) +{ + m_saveRule = value.trimmed(); +} + +GString GLDCustomFieldSetting::nullValDisplayStr() const +{ + return m_nullValDisplayStr; +} + +void GLDCustomFieldSetting::setNullValDisplayStr(GString value) +{ + m_nullValDisplayStr = value; +} + +void GLDCustomFieldSetting::setCellIdentity(const GString &value) +{ + m_cellIdentity = value.trimmed(); +} + +GString GLDCustomFieldSetting::editorName() const +{ + return m_editorName; +} + +void GLDCustomFieldSetting::setEditorName(const GString &value) +{ + m_editorName = value.trimmed(); +} + +GString GLDCustomFieldSetting::extData() const +{ + return m_extData; +} + +void GLDCustomFieldSetting::setExtData(GString value) +{ + m_extData = value; +} + +CGLDExtPropDefs *GLDCustomFieldSetting::extPropDefs() const +{ + return m_extProps; +} + +GLDCellFormat *GLDCustomFieldSetting::cellFormat() const +{ + return m_cellFormat; +} + +void GLDCustomFieldSetting::setCellFormat(GLDCellFormat * value) +{ + m_cellFormat = value; +} + +bool GLDCustomFieldSetting::editTextIsDisplayText() const +{ + return m_editTextIsDisplayText; +} + +void GLDCustomFieldSetting::setEditTextIsDisplayText(bool value) +{ + m_editTextIsDisplayText = value; +} + +bool GLDCustomFieldSetting::isExprEnumDateTimeField(const GString &fieldName) +{ + Q_UNUSED(fieldName); + return false; +} + +bool GLDCustomFieldSetting::isValidFieldName(const GString &fieldName) +{ + Q_UNUSED(fieldName); + return false; +} + +/* GLDFieldSetting */ + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:构造函数 + 参数:owner -- 所属容器 +-----------------------------------------------------------------------------*/ +GLDFieldSetting::GLDFieldSetting(GLDFieldSettings *owner) : GLDCustomFieldSetting(), + m_owner(owner) +{ +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:析构函数,释放解析器对象 +-----------------------------------------------------------------------------*/ +GLDFieldSetting::~GLDFieldSetting() +{ +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:返回设置状态标志 + 返回:设计状态标志 +-----------------------------------------------------------------------------*/ +bool GLDFieldSetting::designState() +{ + return m_owner->owner()->owner()->owner()->designState(); +} + +GString GLDFieldSetting::cellIdentity() const +{ + GString result; + + if (m_cellIdentity != "") + { + result = m_cellIdentity; + } + else + { + result = m_owner->owner()->owner()->owner()->titleRows()->fullTitle(index()); + } + + return result; +} + +GLDCustomGridSetting *GLDFieldSetting::gridSetting() +{ + return m_owner->owner()->owner()->owner(); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:返回本对象在容器中的下标 + 返回:本对象在容器中的下标 +-----------------------------------------------------------------------------*/ +int GLDFieldSetting::index() const +{ + return m_owner->list().indexOf(const_cast(this)); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:返回所属表设置下标 + 返回:所属表设置下标 +-----------------------------------------------------------------------------*/ +int GLDFieldSetting::tableIndex() +{ + return m_owner->owner()->index(); +} + +GString GLDFieldSetting::title() +{ + int nCol(0); + int nMergeID(0); + GString result = ""; + int nIndex = this->index(); + GLDTitleRows *oTitleRows = m_owner->owner()->owner()->owner()->titleRows(); + int nRow = oTitleRows->count() - 2; + + while (nRow >= 0) + { + nCol = nIndex; + nMergeID = oTitleRows->items(nRow)->cells(nCol)->mergeID(); + + if (nMergeID != 0) + { + while (nCol > 0) + { + if (oTitleRows->items(nRow)->cells(nCol - 1)->mergeID() != nMergeID) + { + break; + } + + nCol--; + } + + while (nRow > 0) + { + if (oTitleRows->items(nRow - 1)->cells(nCol)->mergeID() != nMergeID) + { + break; + } + + nRow--; + } + } + + GString strCaption = oTitleRows->items(nRow)->cells(nCol)->caption(); + + if (strCaption != "") + { + if (result == "") + { + result = strCaption; + } + else + { + result = GString("%1|%2").arg(strCaption, result); + } + } + + nRow--; + } + + return result; +} + +bool GLDFieldSetting::isDefaultCellIdentity() +{ + return (m_cellIdentity == "") + || sameText(m_cellIdentity, m_owner->owner()->owner()->owner()->titleRows()->fullTitle(index())); +} + +GString GLDFieldSetting::refFullName() +{ + return m_owner->owner()->refFullName(); +} + +bool GLDFieldSetting::isFixedCol() +{ + return m_owner->owner()->owner()->owner()->colSettings()->items(index())->isFixedCol(); +} + +GLDFieldSettings *GLDFieldSetting::owner() const +{ + return m_owner; +} + +GLDTableSetting *GLDFieldSetting::tableSetting() const +{ + return m_owner->owner(); +} + +GLDSortState GLDFieldSetting::sortState() const +{ + return m_sortState; +} + +void GLDFieldSetting::setsortState(GLDSortState value) +{ + m_sortState = value; +} + +GLDDataType GLDFieldSetting::displayExprDataType() +{ + unsigned char result = 0; + + if (m_owner->owner()->owner()->owner()->designState()) + { + gldError(getGLDi18nStr(g_NeedRunState)); + } + + return result; +} + +/* GLDTitleCell */ + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:构造函数,设置缺省值 +-----------------------------------------------------------------------------*/ +GLDTitleCell::GLDTitleCell(GLDTitleRow *owner) +{ + assert(owner != NULL); + m_owner = owner; + m_cellFormat = new GLDCellFormat; + m_cellFormat->setHorzAlignment(DefTitleHorzAlignment); + m_isLabel = false; + m_mergeID = 0; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 从流对象中装载数据 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +GLDTitleCell::~GLDTitleCell() +{ + freeAndNil(m_cellFormat) +} + +int GLDTitleCell::index() const +{ + return m_owner->list().indexOf(const_cast(this)); +} + +int GLDTitleCell::colIndex() const +{ + return m_owner->list().indexOf(const_cast(this)); +} + +int GLDTitleCell::rowIndex() const +{ + return m_owner->index(); +} + +void GLDTitleCell::clearCompileInfo() +{ +} + +void GLDTitleCell::compile() +{ + m_isLabel = textIsLabel(m_caption); +} + +GLDGridSetting *GLDTitleCell::gridSetting() +{ + return m_owner->gridSetting(); +} + +bool GLDTitleCell::isLabel() const +{ + return m_isLabel; +} + +GString GLDTitleCell::caption() const +{ + return m_caption; +} + +void GLDTitleCell::setCaption(const GString &value) +{ + m_caption = value; +} + +int GLDTitleCell::mergeID() const +{ + return m_mergeID; +} + +void GLDTitleCell::setMergeID(const int &value) +{ + m_mergeID = value; +} + +GLDCellFormat *GLDTitleCell::cellFormat() const +{ + return m_cellFormat; +} + +void GLDTitleCell::setCellFormat(GLDCellFormat *value) +{ + m_cellFormat = value; +} + +GLDTitleRow *GLDTitleCell::owner() +{ + return m_owner; +} + +void GLDTitleCell::loadFromStream(GStream *stream) +{ + readStrFromStream(stream, m_caption); + readIntFromStream(stream, m_mergeID); + m_cellFormat->loadFromStream(stream); +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 保存数据到流对象中 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDTitleCell::saveToStream(GStream *stream) +{ + writeStrToStream(stream, m_caption); + writeIntToStream(stream, m_mergeID); + m_cellFormat->saveToStream(stream); +} + +/* GLDFilterCell */ + +void GLDFilterCell::clearCompileInfo() +{ +} + +void GLDFilterCell::compile() +{ + m_isLabel = textIsLabel(m_caption); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:构造函数,设置缺省值 +-----------------------------------------------------------------------------*/ +GLDFilterCell::GLDFilterCell(GLDFilterRow *owner) +{ + m_owner = owner; + m_cellFormat = new GLDCellFormat(); + m_isLabel = false; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 从流对象中装载数据 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +GLDFilterCell::~GLDFilterCell() +{ + freeAndNil(m_cellFormat) +} + +GLDGridSetting *GLDFilterCell::gridSetting() +{ + return m_owner->owner()->owner(); +} + +bool GLDFilterCell::isFixedCol() +{ + return m_owner->owner()->owner()->colSettings()->items(index())->isFixedCol(); +} + +void GLDFilterCell::loadFromStream(GStream *stream) +{ + readStrFromStream(stream, m_caption); + readStrFromStream(stream, m_editorName); + readIntFromStream(stream, m_mergeID); + m_cellFormat->loadFromStream(stream); +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 保存数据到流对象中 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDFilterCell::saveToStream(GStream *stream) +{ + writeStrToStream(stream, m_caption); + writeStrToStream(stream, m_editorName); + writeIntToStream(stream, m_mergeID); + m_cellFormat->saveToStream(stream); +} + +int GLDFilterCell::index() +{ + return m_owner->indexOf(const_cast(this)); +} + +int GLDFilterCell::rowIndex() +{ + return m_owner->index(); +} + +int GLDFilterCell::colIndex() +{ + return m_owner->indexOf(const_cast(this)); +} + +bool GLDFilterCell::isLabel() const +{ + return m_isLabel; +} + +GString GLDFilterCell::caption() const +{ + return m_caption; +} + +void GLDFilterCell::setCaption(const GString &value) +{ + m_caption = value; +} + +GString GLDFilterCell::editorName() const +{ + return m_editorName; +} + +void GLDFilterCell::setEditorName(const GString &value) +{ + m_editorName = trim(value); +} + +int GLDFilterCell::mergeID() const +{ + return m_mergeID; +} + +void GLDFilterCell::setMergeID(const int &value) +{ + m_mergeID = value; +} + +GLDCellFormat *GLDFilterCell::cellFormat() const +{ + return m_cellFormat; +} + +void GLDFilterCell::setCellFormat(GLDCellFormat *value) +{ + m_cellFormat = value; +} + +/* GLDGridRules */ + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:构造函数,创建对象列表 + 参数:owner -- 表设置对象 +-----------------------------------------------------------------------------*/ +GLDGridRules::GLDGridRules(GLDTableSetting *owner) +{ + m_owner = owner; +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:析构函数 +-----------------------------------------------------------------------------*/ +GLDGridRules::~GLDGridRules() +{ +} + +GLDCustomGridSetting *GLDGridRules::gridSetting() +{ + return m_owner->owner()->owner(); +} + +bool GLDGridRules::designState() +{ + return m_owner->owner()->owner()->designState(); +} + +int GLDGridRules::tableIndex() +{ + return m_owner->index(); +} + +GString GLDGridRules::refFullName() +{ + return m_owner->refFullName(); +} + +/* GLDCustomGridRules */ + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:构造函数,创建对象列表 + 参数:owner -- 表设置对象 +-----------------------------------------------------------------------------*/ +GLDCustomGridRules::GLDCustomGridRules() +{ + clearRuleArray(); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:析构函数 +-----------------------------------------------------------------------------*/ +GLDCustomGridRules::~GLDCustomGridRules() +{ + clearRuleArray(); + clear(); +} + +void GLDCustomGridRules::assign(GLDCustomGridRules *source) +{ + GMemoryStream oStream; + source->saveToStream(&oStream); + oStream.seek(0); + loadFromStream(&oStream); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:创建指定类型规则数组 + 参数:gridRuleType -- 规则类型 +-----------------------------------------------------------------------------*/ +void GLDCustomGridRules::buildRuleArray(GLDGridRuleType ruleType) +{ + m_ruleArray[ruleType].clear(); + + for (int i = 0; i != (int)m_list.size(); ++i) + { + if (m_list[i]->enable() && (m_list[i]->ruleType() == ruleType)) + { + m_ruleArray[ruleType].push_back(m_list[i]); + } + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:清空规则类型数组 +-----------------------------------------------------------------------------*/ +void GLDCustomGridRules::clear() +{ + clearRuleArray(); + m_list.clear(); +} + +void GLDCustomGridRules::clearRuleArray() +{ + for (int i = 0; i < CGridRuleTypeCount; ++i) + { + m_ruleArray[i].clear(); + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:删除指定下标规则 + 参数:index -- 下标 +-----------------------------------------------------------------------------*/ +void GLDCustomGridRules::Delete(int index) +{ + assert((index >= 0) && (index < count())); + GLDGridRuleType eRuleType = items(index)->ruleType(); + m_list.removeAt(index); + buildRuleArray(eRuleType); +} + +bool GLDCustomGridRules::hasRule(GLDGridRuleType ruleType) +{ + return !m_ruleArray[(int)ruleType].empty(); +} + +GLDGridRule *GLDCustomGridRules::findRule(GLDGridRuleType ruleType, const GString &ruleName) +{ + for (int i = 0; i != m_ruleArray[(int)ruleType].count(); ++i) + { + if (sameText(m_ruleArray[(int)ruleType].at(i)->ruleName(), ruleName)) + { + return m_ruleArray[(int)ruleType].at(i); + } + } + + return NULL; +} + +int GLDCustomGridRules::count() const +{ + return (int)m_list.size(); +} + +int GLDCustomGridRules::indexOf(GLDGridRule* value) const +{ + return m_list.indexOf(value); +} + +GLDGridRule *GLDCustomGridRules::items(int index) const +{ + return m_list[index]; +} + +GLDFontRule *GLDCustomGridRules::createFontRule(GLDCustomGridRules *owner) +{ + return new GLDFontRule(owner); +} + +GLDBackColorRule *GLDCustomGridRules::createBackColorRule(GLDCustomGridRules *owner) +{ + return new GLDBackColorRule(owner); +} + +GLDEditStyleRule *GLDCustomGridRules::createEditStyleRule(GLDCustomGridRules *owner) +{ + return new GLDEditStyleRule(owner); +} + +GLDBoundLineRule *GLDCustomGridRules::createBoundLineRule(GLDCustomGridRules *owner) +{ + return new GLDBoundLineRule(owner); +} + +GLDAlignRule *GLDCustomGridRules::createAlignRule(GLDCustomGridRules *owner) +{ + return new GLDAlignRule(owner); +} + +GLDMarginRule *GLDCustomGridRules::createMarginRule(GLDCustomGridRules *owner) +{ + return new GLDMarginRule(owner); +} + +GLDReadonlyRule *GLDCustomGridRules::createReadonlyRule(GLDCustomGridRules *owner) +{ + return new GLDReadonlyRule(owner); +} + +GLDCanFocusRule *GLDCustomGridRules::createCanFocusRule(GLDCustomGridRules *owner) +{ + return new GLDCanFocusRule(owner); +} + +GLDHandleSymbolRule *GLDCustomGridRules::createHandleSymbolRule(GLDCustomGridRules *owner) +{ + return new GLDHandleSymbolRule(owner); +} + +GLDImageRule *GLDCustomGridRules::createImageRule(GLDCustomGridRules *owner) +{ + return new GLDImageRule(owner); +} + +GLDCommentRule *GLDCustomGridRules::createCommentRule(GLDCustomGridRules *owner) +{ + return new GLDCommentRule(owner); +} + +GLDVisibleRule *GLDCustomGridRules::createVisibleRule(GLDCustomGridRules *owner) +{ + return new GLDVisibleRule(owner); +} + +GLDMergeRule *GLDCustomGridRules::createMergeRule(GLDCustomGridRules *owner) +{ + return new GLDMergeRule(owner); +} + +GLDRejectDeleteRule *GLDCustomGridRules::createRejectDeleteRule(GLDCustomGridRules *owner) +{ + return new GLDRejectDeleteRule(owner); +} + +GLDRejectInsertRule *GLDCustomGridRules::createRejectInsertRule(GLDCustomGridRules *owner) +{ + return new GLDRejectInsertRule(owner); +} + +GLDRejectInsertChildRule *GLDCustomGridRules::createRejectInsertChileRule(GLDCustomGridRules *owner) +{ + return new GLDRejectInsertChildRule(owner); +} + +GLDRejectMoveRule *GLDCustomGridRules::createRejectMoveRule(GLDCustomGridRules *owner) +{ + return new GLDRejectMoveRule(owner); +} + +GLDRejectLevelRule *GLDCustomGridRules::createRejectLevelRule(GLDCustomGridRules *owner) +{ + return new GLDRejectLevelRule(owner); +} + +GLDEditFormRule *GLDCustomGridRules::creataeEditFormRule(GLDCustomGridRules *owner) +{ + return new GLDEditFormRule(owner); +} + +GLDClearCellRule *GLDCustomGridRules::createClearCellRule(GLDCustomGridRules *owner) +{ + return new GLDClearCellRule(owner); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:插入规则 + 参数:index -- 插入下标 + ruleType -- 插入的规则类型 + 返回:插入的规则对象 +-----------------------------------------------------------------------------*/ +GLDGridRule *GLDCustomGridRules::insert(int index, GLDGridRuleType ruleType) +{ + GLDGridRule *result; + + switch (ruleType) + { + case grtFont: + result = createFontRule(this); + break; + + case grtBackColor: + result = createBackColorRule(this); + break; + + case grtEditStyle: + result = createEditStyleRule(this); + break; + + case grtBoundLine: + result = createBoundLineRule(this); + break; + + case grtAlignment: + result = createAlignRule(this); + break; + + case grtMargin: + result = createMarginRule(this); + break; + + case grtReadonly: + result = createReadonlyRule(this); + break; + + case grtCanFocus: + result = createCanFocusRule(this); + break; + + case grtHandleSymbol: + result = createHandleSymbolRule(this); + break; + + case grtImage: + result = createImageRule(this); + break; + + case grtComment: + result = createCommentRule(this); + break; + + case grtVisible: + result = createVisibleRule(this); + break; + + case grtMerge: + result = createMergeRule(this); + break; + + case grtRejectDelete: + result = createRejectDeleteRule(this); + break; + + case grtRejectInsert: + result = createRejectInsertRule(this); + break; + + case grtRejectInsertChild: + result = createRejectInsertChileRule(this); + break; + + case grtRejectMove: + result = createRejectMoveRule(this); + break; + + case grtRejectLevel: + result = createRejectLevelRule(this); + break; + + case grtEditForm: + result = creataeEditFormRule(this); + break; + + case grtClearCell: + result = createClearCellRule(this); + break; + + default: + result = NULL; + return result; + } + + if (index == -1) + { + m_list.push_back(result); + } + else + { + m_list.insert(index, result); + } + + buildRuleArray(ruleType); + + return result; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 从流对象中装载数据 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDCustomGridRules::loadFromStream(GStream *stream) +{ + int nints(0); + unsigned char ucvalue; + clear(); + readIntFromStream(stream, nints); + + for (int i = 0; i <= nints - 1; i++) + { + readByteFromStream(stream, ucvalue); + insert(-1, (GLDGridRuleType)ucvalue)->loadFromStream(stream); + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:移动规则 + 参数:fromIndex -- 源下标 + toIndex -- 目标下标 +-----------------------------------------------------------------------------*/ +void GLDCustomGridRules::move(int fromIndex, int toIndex) +{ + assert((fromIndex >= 0) && (fromIndex < count())); + assert((toIndex >= 0) && (toIndex < count())); + + if (fromIndex == toIndex) + { + return; + } + + GLDGridRuleType eRuleType = items(fromIndex)->ruleType(); + m_list.move(fromIndex, toIndex); + buildRuleArray(eRuleType); +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 保存数据到流对象中 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDCustomGridRules::saveToStream(GStream *stream) +{ + writeIntToStream(stream, count()); + + for (int i = 0; i <= count() - 1; i++) + { + writeByteToStream(stream, byte(items(i)->ruleType())); + items(i)->saveToStream(stream); + } +} + +bool GLDCustomGridRules::designState() +{ + return false; +} + +int GLDCustomGridRules::tableIndex() +{ + return -1; +} + +/* GLDFontRule */ + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:构造函数,设置缺省值 +-----------------------------------------------------------------------------*/ +GLDFontRule::GLDFontRule(GLDCustomGridRules *owner) + : GLDGridRule(owner) +{ + m_fontName = CDefFontName; + m_fontSize = CDefFontSize; + m_fontStyles = CDefFontStyles; + m_fontColor = CDefFontColor; +} + +GLDFontRule::~GLDFontRule() +{ +} + +bool GLDFontRule::autoRefresh() const +{ + return true; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 从流对象中装载数据 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDFontRule::loadFromStream(GStream *stream) +{ + GLDGridRule::loadFromStream(stream); + + byte fontStyles; + int nFontColor; + readStrFromStream(stream, m_fontName); + readIntFromStream(stream, m_fontSize); + readByteFromStream(stream, fontStyles); + readIntFromStream(stream, nFontColor); + + m_fontStyles = (FontStyles)fontStyles; + nFontColor = (GRgb)nFontColor; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 保存数据到流对象中 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDFontRule::saveToStream(GStream *stream) +{ + GLDGridRule::saveToStream(stream); + writeStrToStream(stream, m_fontName); + writeIntToStream(stream, m_fontSize); + writeByteToStream(stream, (byte)m_fontStyles); + writeIntToStream(stream, (int)m_fontColor); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:返回规则类型 + 返回:规则类型 +-----------------------------------------------------------------------------*/ +GLDGridRuleType GLDFontRule::ruleType() +{ + return grtFont; +} + +GRgb GLDFontRule::fontColor() const +{ + return m_fontColor; +} + +void GLDFontRule::setFontColor(GRgb value) +{ + m_fontColor = value; +} + +GString GLDFontRule::fontName() const +{ + return m_fontName; +} + +void GLDFontRule::setFontName(const GString &value) +{ + m_fontName = value; +} + +int GLDFontRule::fontSize() const +{ + return m_fontSize; +} + +void GLDFontRule::setFontSize(int value) +{ + m_fontSize = value; +} + +FontStyles GLDFontRule::fontStyles() const +{ + return m_fontStyles; +} + +void GLDFontRule::setFontStyles(FontStyles value) +{ + m_fontStyles = value; +} + +/* GLDGridRule */ + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:构造函数 +-----------------------------------------------------------------------------*/ +GLDGridRule::GLDGridRule(GLDCustomGridRules *owner) +{ + m_owner = owner; + m_enable = true; + + if (owner) + { + m_fixedCols = owner->gridSetting()->fixedCols(); + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:析构函数 +-----------------------------------------------------------------------------*/ +GLDGridRule::~GLDGridRule() +{ +} + +bool GLDGridRule::autoRefresh() const +{ + return false; +} + +void GLDGridRule::clearCompileInfo() +{ +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:编译,构造记录条件解析器 +-----------------------------------------------------------------------------*/ +void GLDGridRule::compile() +{ +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:返回设计状态标志 + 返回:设计状态标志 +-----------------------------------------------------------------------------*/ +bool GLDGridRule::designState() +{ + return m_owner->designState(); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:返回规则下标 + 返回:当前规则在容器中的下标 +-----------------------------------------------------------------------------*/ +int GLDGridRule::index() +{ + return m_owner->indexOf(this); +} + +GString GLDGridRule::fieldCondition() const +{ + return m_fieldCondition; +} + +void GLDGridRule::setFieldCondition(const GString &value) +{ + m_fieldCondition = trim(value); +} + +GString GLDGridRule::recordCondition() const +{ + return m_recordCondition; +} + +void GLDGridRule::setRecordCondition(const GString &value) +{ + m_recordCondition = trim(value); +} + +GString GLDGridRule::ruleName() const +{ + return m_ruleName; +} + +void GLDGridRule::setRuleName(const GString &value) +{ + m_ruleName = value; +} + +int GLDGridRule::varCount() +{ + return -1; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 从流对象中装载数据 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDGridRule::loadFromStream(GStream *stream) +{ + readStrFromStream(stream, m_ruleName); + readBoolFromStream(stream, m_enable); + readMemoFromStream(stream, m_recordCondition); + readMemoFromStream(stream, m_fieldCondition); +} + +GString GLDGridRule::refFullName() +{ + return m_owner->refFullName(); +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 保存数据到流对象中 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDGridRule::saveToStream(GStream *stream) +{ + writeStrToStream(stream, m_ruleName); + writeBoolToStream(stream, m_enable); + writeMemoToStream(stream, m_recordCondition); + writeMemoToStream(stream, m_fieldCondition); +} + +bool GLDGridRule::enable() const +{ + return m_enable; +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.12.06 + 功能:设置Enable标志 + 参数:value -- 规则Enable标志 +-----------------------------------------------------------------------------*/ +void GLDGridRule::setEnable(const bool value) +{ + if (m_enable == value) + { + return; + } + + m_enable = value; + m_owner->buildRuleArray(ruleType()); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:返回表设置下标 + 返回:表设置下标 +-----------------------------------------------------------------------------*/ +int GLDGridRule::tableIndex() +{ + return m_owner->tableIndex(); +} + +/* GLDBackColorRule */ + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:构造函数,设置缺省值 +-----------------------------------------------------------------------------*/ +GLDBackColorRule::GLDBackColorRule(GLDCustomGridRules *owner) + : GLDGridRule(owner) +{ + m_backColor = CDefBackColor; +} + +GLDBackColorRule::~GLDBackColorRule() +{ +} + +bool GLDBackColorRule::autoRefresh() const +{ + return true; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 从流对象中装载数据 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDBackColorRule::loadFromStream(GStream *stream) +{ + GLDGridRule::loadFromStream(stream); + int nvalue; + readIntFromStream(stream, nvalue); + m_backColor = (GRgb)nvalue; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 保存数据到流对象中 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDBackColorRule::saveToStream(GStream *stream) +{ + GLDGridRule::saveToStream(stream); + writeIntToStream(stream, (int)m_backColor); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:返回规则类型 + 返回:规则类型 +-----------------------------------------------------------------------------*/ +GLDGridRuleType GLDBackColorRule::ruleType() +{ + return grtBackColor; +} + +GRgb GLDBackColorRule::backColor() const +{ + return m_backColor; +} + +void GLDBackColorRule::setBackColor(GRgb value) +{ + m_backColor = value; +} + +/* GLDEditStyleRule */ + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:构造函数,设置缺省值 +-----------------------------------------------------------------------------*/ +GLDEditStyleRule::GLDEditStyleRule(GLDCustomGridRules *owner) + : GLDGridRule(owner) +{ + m_editStyle = CDefEditStyle; +} + +GLDEditStyleRule::~GLDEditStyleRule() +{ +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 从流对象中装载数据 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDEditStyleRule::loadFromStream(GStream *stream) +{ + GLDGridRule::loadFromStream(stream); + byte value; + readByteFromStream(stream, value); + m_editStyle = (GLDEditStyle)value; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 保存数据到流对象中 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDEditStyleRule::saveToStream(GStream *stream) +{ + GLDGridRule::saveToStream(stream); + writeByteToStream(stream, (byte)m_editStyle); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:返回规则类型 + 返回:规则类型 +-----------------------------------------------------------------------------*/ +GLDGridRuleType GLDEditStyleRule::ruleType() +{ + return grtEditStyle; +} + +GLDEditStyle GLDEditStyleRule::editStyle() const +{ + return m_editStyle; +} + +void GLDEditStyleRule::setEditStyle(GLDEditStyle value) +{ + m_editStyle = value; +} + +/* GLDBoundLineRule */ + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:构造函数,设置缺省值 +-----------------------------------------------------------------------------*/ +GLDBoundLineRule::GLDBoundLineRule(GLDCustomGridRules *owner) + : GLDGridRule(owner) +{ + m_rightLine = CDefRightLine; + m_bottomLine = CDefBottomLine; + m_diagonal = CDefDiagonal; + m_antiDiagonal = CDefAntiDiagonal; +} + +GLDBoundLineRule::~GLDBoundLineRule() +{ +} + +bool GLDBoundLineRule::autoRefresh() const +{ + return true; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 从流对象中装载数据 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDBoundLineRule::loadFromStream(GStream *stream) +{ + GLDGridRule::loadFromStream(stream); + readByteFromStream(stream, m_rightLine); + readByteFromStream(stream, m_bottomLine); + readByteFromStream(stream, m_diagonal); + readByteFromStream(stream, m_antiDiagonal); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:返回规则类型 + 返回:规则类型 +-----------------------------------------------------------------------------*/ +GLDGridRuleType GLDBoundLineRule::ruleType() +{ + return grtBoundLine; +} + +byte GLDBoundLineRule::antiDiagonal() const +{ + return m_antiDiagonal; +} + +void GLDBoundLineRule::setAntiDiagonal(const byte value) +{ + m_antiDiagonal = value; +} + +byte GLDBoundLineRule::bottomLine() const +{ + return m_bottomLine; +} + +void GLDBoundLineRule::setBottomLine(const byte value) +{ + m_bottomLine = value; +} + +byte GLDBoundLineRule::diagonal() const +{ + return m_diagonal; +} + +void GLDBoundLineRule::setDiagonal(const byte value) +{ + m_diagonal = value; +} + +byte GLDBoundLineRule::rightLine() const +{ + return m_rightLine; +} + +void GLDBoundLineRule::setRightLine(const byte value) +{ + m_rightLine = value; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 保存数据到流对象中 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDBoundLineRule::saveToStream(GStream *stream) +{ + GLDGridRule::saveToStream(stream); + writeByteToStream(stream, m_rightLine); + writeByteToStream(stream, m_bottomLine); + writeByteToStream(stream, m_diagonal); + writeByteToStream(stream, m_antiDiagonal); +} + +/* GLDAlignRule */ + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:构造函数,设置缺省值 +-----------------------------------------------------------------------------*/ +GLDAlignRule::GLDAlignRule(GLDCustomGridRules *owner) + : GLDGridRule(owner) +{ + m_horzAlignment = CDefHorzAlignment; + m_vertAlignment = CDefVertAlignment; +} + +GLDAlignRule::~GLDAlignRule() +{ +} + +bool GLDAlignRule::autoRefresh() const +{ + return true; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 从流对象中装载数据 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDAlignRule::loadFromStream(GStream *stream) +{ + GLDGridRule::loadFromStream(stream); + byte hvalue; + byte vvalue; + readByteFromStream(stream, hvalue); + readByteFromStream(stream, vvalue); + + m_horzAlignment = (GLDHorzAlignment)hvalue; + m_vertAlignment = (GLDVertAlignment)(vvalue); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:返回规则类型 + 返回:规则类型 +-----------------------------------------------------------------------------*/ +GLDGridRuleType GLDAlignRule::ruleType() +{ + return grtAlignment; +} + +GLDHorzAlignment GLDAlignRule::horzAlignment() const +{ + return m_horzAlignment; +} + +void GLDAlignRule::setHorzAlignment(const GLDHorzAlignment value) +{ + m_horzAlignment = value; +} + +GLDVertAlignment GLDAlignRule::vertAlignment() const +{ + return m_vertAlignment; +} + +void GLDAlignRule::setVertAlignment(const GLDVertAlignment value) +{ + m_vertAlignment = value; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 保存数据到流对象中 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDAlignRule::saveToStream(GStream *stream) +{ + GLDGridRule::saveToStream(stream); + writeByteToStream(stream, (byte)m_horzAlignment); + writeByteToStream(stream, (byte)m_vertAlignment); +} + +/* GLDMarginRule */ + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:构造函数,设置缺省值 +-----------------------------------------------------------------------------*/ +GLDMarginRule::GLDMarginRule(GLDCustomGridRules *owner) + : GLDGridRule(owner) +{ + m_leftMargin = CDefHorzMargin; + m_rightMargin = CDefHorzMargin; + m_topMargin = CDefVertMargin; + m_bottomMargin = CDefVertMargin; +} + +GLDMarginRule::~GLDMarginRule() +{ +} + +bool GLDMarginRule::autoRefresh() const +{ + return true; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 从流对象中装载数据 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDMarginRule::loadFromStream(GStream *stream) +{ + GLDGridRule::loadFromStream(stream); + + readByteFromStream(stream, m_leftMargin); + readByteFromStream(stream, m_rightMargin); + readByteFromStream(stream, m_topMargin); + readByteFromStream(stream, m_bottomMargin); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:返回规则类型 + 返回:规则类型 +-----------------------------------------------------------------------------*/ +GLDGridRuleType GLDMarginRule::ruleType() +{ + return grtMargin; +} + +byte GLDMarginRule::leftMargin() const +{ + return m_leftMargin; +} + +void GLDMarginRule::setLeftMargin(const byte value) +{ + m_leftMargin = value; +} + +byte GLDMarginRule::rightMargin() const +{ + return m_rightMargin; +} + +void GLDMarginRule::setRightMargin(const byte value) +{ + m_rightMargin = value; +} + +byte GLDMarginRule::topMargin() const +{ + return m_topMargin; +} + +void GLDMarginRule::setTopMargin(const byte value) +{ + m_topMargin = value; +} + +byte GLDMarginRule::bottomMargin() const +{ + return m_bottomMargin; +} + +void GLDMarginRule::setBottomMargin(const byte value) +{ + m_bottomMargin = value; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 保存数据到流对象中 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDMarginRule::saveToStream(GStream *stream) +{ + GLDGridRule::saveToStream(stream); + writeByteToStream(stream, byte(m_leftMargin)); + writeByteToStream(stream, byte(m_rightMargin)); + writeByteToStream(stream, byte(m_topMargin)); + writeByteToStream(stream, byte(m_bottomMargin)); +} + +/* GLDReadonlyRule */ + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:构造函数,设置缺省值 +-----------------------------------------------------------------------------*/ +GLDReadonlyRule::GLDReadonlyRule(GLDCustomGridRules *owner) + : GLDGridRule(owner) +{ + m_readonly = CDefReadonly; +} + +GLDReadonlyRule::~GLDReadonlyRule() +{ +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 从流对象中装载数据 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDReadonlyRule::loadFromStream(GStream *stream) +{ + GLDGridRule::loadFromStream(stream); + readBoolFromStream(stream, m_readonly); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:返回规则类型 + 返回:规则类型 +-----------------------------------------------------------------------------*/ +GLDGridRuleType GLDReadonlyRule::ruleType() +{ + return grtReadonly; +} + +bool GLDReadonlyRule::readonly() const +{ + return m_readonly; +} + +void GLDReadonlyRule::setReadonly(bool value) +{ + m_readonly = value; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 保存数据到流对象中 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDReadonlyRule::saveToStream(GStream *stream) +{ + GLDGridRule::saveToStream(stream); + writeBoolToStream(stream, m_readonly); +} + +/* GLDHandleSymbolRule */ + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:构造函数,设置缺省值 +-----------------------------------------------------------------------------*/ +GLDHandleSymbolRule::GLDHandleSymbolRule(GLDCustomGridRules *owner) + : GLDGridRule(owner) +{ + m_handleSymbol = CDefHandleSymbol; +} + +GLDHandleSymbolRule::~GLDHandleSymbolRule() +{ +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 从流对象中装载数据 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDHandleSymbolRule::loadFromStream(GStream *stream) +{ + GLDGridRule::loadFromStream(stream); + readBoolFromStream(stream, m_handleSymbol); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:返回规则类型 + 返回:规则类型 +-----------------------------------------------------------------------------*/ +GLDGridRuleType GLDHandleSymbolRule::ruleType() +{ + return grtHandleSymbol; +} + +bool GLDHandleSymbolRule::handleSymbol() const +{ + return m_handleSymbol; +} +void GLDHandleSymbolRule::setHandleSymbol(bool value) +{ + m_handleSymbol = value; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 保存数据到流对象中 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDHandleSymbolRule::saveToStream(GStream *stream) +{ + GLDGridRule::saveToStream(stream); + writeBoolToStream(stream, m_handleSymbol); +} + +/* GLDImageRule */ + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:构造函数,设置缺省值 +-----------------------------------------------------------------------------*/ +GLDImageRule::GLDImageRule(GLDCustomGridRules *owner) + : GLDGridRule(owner) +{ + m_imageIndex = CDefImageIndex; + m_imageLayout = CDefImageLayout; +} + +GLDImageRule::~GLDImageRule() +{ +} + +bool GLDImageRule::autoRefresh() const +{ + return true; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 从流对象中装载数据 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDImageRule::loadFromStream(GStream *stream) +{ + GLDGridRule::loadFromStream(stream); + readIntFromStream(stream, m_imageIndex); + byte imageLayout; + readByteFromStream(stream, imageLayout); + m_imageLayout = (GLDCellImageLayout)imageLayout; +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:返回规则类型 + 返回:规则类型 +-----------------------------------------------------------------------------*/ +GLDGridRuleType GLDImageRule::ruleType() +{ + return grtImage; +} + +int GLDImageRule::imageIndex() const +{ + return m_imageIndex; +} + +void GLDImageRule::setImageIndex(int value) +{ + m_imageIndex = value; +} + +GLDCellImageLayout GLDImageRule::imageLayout() const +{ + return m_imageLayout; +} + +void GLDImageRule::setImageLayout(GLDCellImageLayout value) +{ + m_imageLayout = value; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 保存数据到流对象中 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDImageRule::saveToStream(GStream *stream) +{ + GLDGridRule::saveToStream(stream); + writeIntToStream(stream, m_imageIndex); + writeByteToStream(stream, (byte)m_imageLayout); +} + +/* GLDCommentRule */ + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:构造函数,设置缺省值 +-----------------------------------------------------------------------------*/ +GLDCommentRule::GLDCommentRule(GLDCustomGridRules *owner) + : GLDGridRule(owner) +{ + m_showComment = CDefShowComment; + m_comment = CDefComment; +} + +GLDCommentRule::~GLDCommentRule() +{ +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 从流对象中装载数据 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDCommentRule::loadFromStream(GStream *stream) +{ + GLDGridRule::loadFromStream(stream); + readBoolFromStream(stream, m_showComment); + readStrFromStream(stream, m_comment); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:返回规则类型 + 返回:规则类型 +-----------------------------------------------------------------------------*/ +GLDGridRuleType GLDCommentRule::ruleType() +{ + return grtComment; +} + +GString GLDCommentRule::comment() const +{ + return m_comment; +} + +void GLDCommentRule::setComment(const GString &value) +{ + m_comment = value; +} + +bool GLDCommentRule::showComment() const +{ + return m_showComment; +} + +void GLDCommentRule::setShowComment(bool value) +{ + m_showComment = value; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 保存数据到流对象中 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDCommentRule::saveToStream(GStream *stream) +{ + GLDGridRule::saveToStream(stream); + writeBoolToStream(stream, m_showComment); + writeStrToStream(stream, m_comment); +} + +/* GLDVisibleRule */ + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:构造函数,设置缺省值 +-----------------------------------------------------------------------------*/ +GLDVisibleRule::GLDVisibleRule(GLDCustomGridRules *owner) + : GLDGridRule(owner) +{ +} + +GLDVisibleRule::~GLDVisibleRule() +{ +} + +bool GLDVisibleRule::autoRefresh() const +{ + return true; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 从流对象中装载数据 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDVisibleRule::loadFromStream(GStream *stream) +{ + GLDGridRule::loadFromStream(stream); + readStrFromStream(stream, m_inVisibleText); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:返回规则类型 + 返回:规则类型 +-----------------------------------------------------------------------------*/ +GLDGridRuleType GLDVisibleRule::ruleType() +{ + return grtVisible; +} + +GString GLDVisibleRule::inVisibleText() const +{ + return m_inVisibleText; +} + +void GLDVisibleRule::setInVisibleText(GString value) +{ + m_inVisibleText = value; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 保存数据到流对象中 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDVisibleRule::saveToStream(GStream *stream) +{ + GLDGridRule::saveToStream(stream); + writeStrToStream(stream, m_inVisibleText); +} + +/* GLDMergeRule */ + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 从流对象中装载数据 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDMergeRule::loadFromStream(GStream *stream) +{ + GLDGridRule::loadFromStream(stream); + readStrFromStream(stream, m_mergeExpr); +} + +bool GLDMergeRule::autoRefresh() const +{ + return true; +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:返回规则类型 + 返回:规则类型 +-----------------------------------------------------------------------------*/ +GLDGridRuleType GLDMergeRule::ruleType() +{ + return grtMerge; +} + +GString GLDMergeRule::mergeExpr() const +{ + return m_mergeExpr; +} + +void GLDMergeRule::setMergeExpr(const GString &value) +{ + m_mergeExpr = trim(value); +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 保存数据到流对象中 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDMergeRule::saveToStream(GStream *stream) +{ + GLDGridRule::saveToStream(stream); + writeStrToStream(stream, m_mergeExpr); +} + +/* GLDRejectDeleteRule */ + +GLDGridRuleType GLDRejectDeleteRule::ruleType() +{ + return grtRejectDelete; +} + +/* GLDRejectRule */ + +void GLDRejectRule::loadFromStream(GStream *stream) +{ + GLDGridRule::loadFromStream(stream); + readIntFromStream(stream, m_isTree); +} + +void GLDRejectRule::saveToStream(GStream *stream) +{ + GLDGridRule::saveToStream(stream); + writeIntToStream(stream, m_isTree); +} + +int GLDRejectRule::isTree() const +{ + return m_isTree; +} + +void GLDRejectRule::setIsTree(int value) +{ + m_isTree = value; +} +/* GLDRejectInsertRule */ + +int GLDRejectInsertRule::isBefore() const +{ + return m_isBefore; +} + +void GLDRejectInsertRule::setIsBefore(const int &value) +{ + m_isBefore = value; +} + +GString GLDRejectInsertRule::tableNames() const +{ + return m_tableNames; +} + +void GLDRejectInsertRule::setTableNames(const GString &value) +{ + m_tableNames = value; +} + +void GLDRejectInsertRule::loadFromStream(GStream *stream) +{ + GLDRejectRule::loadFromStream(stream); + readStrFromStream(stream, m_tableNames); + readIntFromStream(stream, m_isBefore); +} + +void GLDRejectInsertRule::saveToStream(GStream *stream) +{ + GLDRejectRule::saveToStream(stream); + writeStrToStream(stream, m_tableNames); + writeIntToStream(stream, m_isBefore); +} + +GLDGridRuleType GLDRejectInsertRule::ruleType() +{ + return grtRejectInsert; +} + +/* GLDRejectInsertChildRule */ + +int GLDRejectInsertChildRule::level() const +{ + return m_level; +} + +void GLDRejectInsertChildRule::setLevel(int value) +{ + m_level = value; +} + +GLDRejectInsertChildRule::~GLDRejectInsertChildRule() +{ +} + +void GLDRejectInsertChildRule::loadFromStream(GStream *stream) +{ + GLDRejectInsertRule::loadFromStream(stream); + readIntFromStream(stream, m_level); +} + +GLDGridRuleType GLDRejectInsertChildRule::ruleType() +{ + return grtRejectInsertChild; +} + +void GLDRejectInsertChildRule::saveToStream(GStream *stream) +{ + GLDRejectInsertRule::saveToStream(stream); + writeIntToStream(stream, m_level); +} + +/* GLDRejectMoveRule */ + +int GLDRejectMoveRule::isMoveUp() const +{ + return m_isMoveUp; +} + +void GLDRejectMoveRule::setIsMoveUp(int value) +{ + m_isMoveUp = value; +} + +int GLDRejectMoveRule::includeChild() const +{ + return m_includeChild; +} + +void GLDRejectMoveRule::setIncludeChild(int value) +{ + m_includeChild = value; +} + +void GLDRejectMoveRule::saveToStream(GStream *stream) +{ + GLDRejectRule::saveToStream(stream); + writeIntToStream(stream, m_isMoveUp); + writeIntToStream(stream, m_includeChild); +} + +void GLDRejectMoveRule::loadFromStream(GStream *stream) +{ + GLDRejectRule::loadFromStream(stream); + readIntFromStream(stream, m_isMoveUp); + readIntFromStream(stream, m_includeChild); +} + +GLDGridRuleType GLDRejectMoveRule::ruleType() +{ + return grtRejectMove; +} + +/* GLDRejectLevelRule */ + +int GLDRejectLevelRule::isLevelUp() const +{ + return m_isLevelUp; +} + +void GLDRejectLevelRule::setIsLevelUp(int value) +{ + m_isLevelUp = value; +} + +int GLDRejectLevelRule::isFixPos() const +{ + return m_isFixPos; +} + +void GLDRejectLevelRule::setIsFixPos(int value) +{ + m_isFixPos = value; +} + +void GLDRejectLevelRule::loadFromStream(GStream *stream) +{ + GLDRejectRule::loadFromStream(stream); + readIntFromStream(stream, m_isLevelUp); + readIntFromStream(stream, m_isFixPos); +} + +GLDGridRuleType GLDRejectLevelRule::ruleType() +{ + return grtRejectLevel; +} + +void GLDRejectLevelRule::saveToStream(GStream *stream) +{ + GLDRejectRule::saveToStream(stream); + writeIntToStream(stream, m_isLevelUp); + writeIntToStream(stream, m_isFixPos); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:构造函数,设置缺省值 +-----------------------------------------------------------------------------*/ +GLDEditFormRule::GLDEditFormRule(GLDCustomGridRules *owner) + : GLDGridRule(owner) +{ + m_enable = true; +} + +GLDEditFormRule::~GLDEditFormRule() +{ +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 从流对象中装载数据 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDEditFormRule::loadFromStream(GStream *stream) +{ + GLDGridRule::loadFromStream(stream); + readBoolFromStream(stream, m_enable); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.10 + 功能:返回规则类型 + 返回:规则类型 +-----------------------------------------------------------------------------*/ +GLDGridRuleType GLDEditFormRule::ruleType() +{ + return grtEditForm; +} + +bool GLDEditFormRule::enable() const +{ + return m_enable; +} + +void GLDEditFormRule::setEnable(bool value) +{ + m_enable = value; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 保存数据到流对象中 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDEditFormRule::saveToStream(GStream *stream) +{ + GLDGridRule::saveToStream(stream); + writeBoolToStream(stream, m_enable); +} + +/* GLDClearCellRule */ + +GLDClearCellRule::GLDClearCellRule(GLDCustomGridRules *owner) + : GLDGridRule(owner) +{ + m_allowClear = true; +} + +GLDClearCellRule::~GLDClearCellRule() +{ +} + +bool GLDClearCellRule::allowClear() const +{ + return m_allowClear; +} + +void GLDClearCellRule::setAllowClear(bool value) +{ + m_allowClear = value; +} + +void GLDClearCellRule::loadFromStream(GStream *stream) +{ + GLDGridRule::loadFromStream(stream); + readBoolFromStream(stream, m_allowClear); +} + +GLDGridRuleType GLDClearCellRule::ruleType() +{ + return grtClearCell; +} + +void GLDClearCellRule::saveToStream(GStream *stream) +{ + GLDGridRule::saveToStream(stream); + writeBoolToStream(stream, m_allowClear); +} + +/* GLDRecordGridSetting */ + +void GLDRecordGridSetting::doLoadFromXML(GXMLDocument &doc) +{ + GLDRecordGridSettingXMLReader oRead; + oRead.read(doc, this); +} + +void GLDRecordGridSetting::doSaveToXML(GXMLDocument &doc) +{ + GLDRecordGridSettingXMLWriter oWriter; + oWriter.write(doc, this); +} + +void GLDRecordGridSetting::doLoadFromFile(const GString &fileName) +{ + //assert(m_persistentStyle == psFromFile); + GLDRecordGridSettingXMLReader oRead; + oRead.read(fileName, this); +} + +GString GLDRecordGridSetting::intAryToStr(GIntList &ary) +{ + GString result = ""; + + for (int i = 0; i != ary.size(); i++) + { + if (0 == i) + { + result = GString::number(ary[i], 10); + } + else + { + result = result + ";" + GString::number(ary[i], 10); + } + } + + return result; + +} + +void GLDRecordGridSetting::setLength(GIntList &ary, int count) +{ + ary.clear(); + + for (int i = 0; i != count; i++) + { + ary.push_back(0); + } +} + +void GLDRecordGridSetting::setLength(GStringList &ary, int count) +{ + ary.clear(); + + for (int i = 0; i != count; i++) + { + ary.push_back(""); + } +} + +GString GLDRecordGridSetting::colWidthsToStr() +{ +// return intAryToStr(m_originColWidths);//Delphi中取原始数据? + return intAryToStr(m_colWidths); +} + +void GLDRecordGridSetting::compile() +{ + m_recordSettings->compile(); + m_fieldSettings->compile(); + m_fieldCols.clear(); + + for (int i = 0; i != m_colStyles.size(); i++) + { + if (m_colStyles[i] != 0) + { + m_fieldCols.push_back(i); + } + } + + setLength(m_colWidths, m_colCount); + setLength(m_colZoomWidths, m_colCount); + + for (int i = 0; i != m_colCount; i++) + { + m_colWidths[i] = m_originColWidths[i]; + } +} + +void GLDRecordGridSetting::initialize() +{ + m_recordSettings = new GLDRecordSettings(this); + m_fieldSettings = new GLDRecordFieldSettings(this); + m_extProps = new CGLDExtPropDefs(); + m_extProps->AddRef(); + + for (int i = 0; i <= m_rowCount * m_colCount - 1; i++) + { + m_fieldSettings->insert(-1); + } +} + +GLDRecordGridSetting::GLDRecordGridSetting() : m_fixedRows(1), m_ignoreInvalidCell(true), + m_allowLabelSelection(false), m_rowCount(5), m_colCount(4) +{ + setLength(m_rowHeights, m_rowCount); + setLength(m_colWidths, m_colCount); + setLength(m_colZoomWidths, m_colCount); + setLength(m_originColWidths, m_colCount); + setLength(m_minColWidths, m_colCount); + setLength(m_colStyles, m_colCount); + setLength(m_colIdentitys, m_colCount); + + for (int i = 0; i < m_rowCount; i++) + { + m_rowHeights[i] = CDefRowHeight; + } + + for (int i = 0; i < m_colCount; i++) + { + m_originColWidths[i] = CDefDisplayWidth; + m_colWidths[i] = CDefDisplayWidth; + m_minColWidths[i] = -1; + } + + m_recordSettings = NULL; + m_fieldSettings = NULL; +} + +GLDRecordGridSetting::~GLDRecordGridSetting() +{ + setActive(false); + freeAndNil(m_recordSettings); + freeAndNil(m_fieldSettings); + m_extProps->Release(); +} + +GLDRecordGridSetting *GLDRecordGridSetting::createGLDRecordGridSetting() +{ + GLDRecordGridSetting *result = new GLDRecordGridSetting(); + result->initialize(); + return result; +} + +void GLDRecordGridSetting::deleteCol(int index) +{ + assert((index >= 0) && (index < m_colCount)); + + for (int i = m_rowCount - 1; i >= 0; i--) + { + m_fieldSettings->Delete(i * m_colCount + index); + } + + m_colCount--; + + for (int i = index; i <= m_colCount - 1; i++) + { + m_colWidths[i] = m_colWidths[i + 1]; + m_originColWidths[i] = m_originColWidths[i + 1]; + m_minColWidths[i] = m_minColWidths[i + 1]; + } + + m_colWidths.removeAt(m_colCount); + m_colZoomWidths.removeAt(m_colCount); + m_originColWidths.removeAt(m_colCount); + m_minColWidths.removeAt(m_colCount); + m_colStyles.removeAt(m_colCount); + m_colIdentitys.removeAt(m_colCount); + + if (index < m_fixedCols) + { + m_fixedCols--; + } +} + +void GLDRecordGridSetting::deleteRow(int index) +{ + //assert((index >= 0) &&(index < m_rowCount)); + for (int i = 0; i <= m_colCount - 1; i++) + { + m_fieldSettings->Delete(m_colCount * index); + } + + m_rowCount--; + + for (int i = index; i <= m_rowCount - 1; i++) + { + m_rowHeights[i] = m_rowHeights[i + 1]; + } + + m_rowHeights.removeAt(m_rowCount); + + if (index < m_fixedRows) + { + m_fixedRows--; + } +} +GLDRecordSettings *GLDRecordGridSetting::recordSettings() +{ + return m_recordSettings; +} + +GLDRecordFieldSettings *GLDRecordGridSetting::fieldSettings() const +{ + return m_fieldSettings; +} + +GLDRecordFieldSetting *GLDRecordGridSetting::cells(int col, int row) +{ + assert((col >= 0) && (col < m_colCount)); + assert((row >= 0) && (row < m_rowCount)); + return m_fieldSettings->items(row * m_colCount + col); +} + +GString GLDRecordGridSetting::saveDialogDefaultExt() +{ + return "RGF"; +} + +GString GLDRecordGridSetting::saveDialogFilter() +{ + return "RecordGridSetting files(*.RGF)|*.RGF"; +} + +void GLDRecordGridSetting::insertCol(int index) +{ + //assert((index >= - 1) &&(index <= m_colCount)); + if (index == -1) + { + index = m_colCount; + } + + for (int i = m_rowCount - 1; i >= 0; i--) + { + m_fieldSettings->insert(i * m_colCount + index); + } + + m_colCount++; + m_colWidths.append(0); + m_colZoomWidths.append(0); + m_originColWidths.append(0); + m_minColWidths.append(0); + m_colStyles.append(0); + m_colIdentitys.append(0); + + for (int i = m_colCount - 2; i >= 0; i--) + { + if (i >= index) + { + m_colWidths[i + 1] = m_colWidths[i]; + m_originColWidths[i + 1] = m_originColWidths[i]; + m_minColWidths[i + 1] = m_minColWidths[i]; + } + } + + m_colWidths[index] = CDefDisplayWidth; + m_originColWidths[index] = CDefDisplayWidth; + m_minColWidths[index] = -1; +} + +void GLDRecordGridSetting::insertRow(int index) +{ + if (index == -1) + { + index = m_rowCount; + } + + for (int i = 0; i <= m_colCount - 1; i++) + { + m_fieldSettings->insert(m_colCount * index); + } + + m_rowCount++; + m_rowHeights.append(0); + + for (int i = m_rowCount - 2; i >= 0; i--) + { + if (i >= index) + { + m_rowHeights[i + 1] = m_rowHeights[i]; + } + } + + m_rowHeights[index] = CDefRowHeight; +} + +void GLDRecordGridSetting::loadColWidthsFromStr(const GString &s) +{ + GStringList strings = s.split(";"); + int nIndex = 0; + + for (QStringList::Iterator it = strings.begin(); it != strings.end(); ++it) + { + GString value = *it; + m_originColWidths[nIndex] = value.toInt(); + m_colWidths[nIndex] = value.toInt(); + nIndex++; + } +} + +void GLDRecordGridSetting::loadFromStream(GStream *stream) +{ + GLDCustomGridSetting::loadFromStream(stream); + + setRowCount(readIntFromStream(stream)); + setColCount(readIntFromStream(stream)); + m_fixedRows = readWordFromStream(stream); + m_ignoreInvalidCell = readBoolFromStream(stream); + m_allowLabelSelection = readBoolFromStream(stream); + loadRowHeightsFromStr(readStrFromStream(stream)); + loadColWidthsFromStr(readStrFromStream(stream)); + loadMinColWidthsFromStr(readStrFromStream(stream)); + loadColStylesFromStr(readStrFromStream(stream)); + loadColIdentitysFromStr(readStrFromStream(stream)); + m_recordSettings->loadFromStream(stream); + m_fieldSettings->loadFromStream(stream); +} + +void GLDRecordGridSetting::loadGridSetting() +{ + doLoad(); + doAfterActive(); +} + +void GLDRecordGridSetting::loadMinColWidthsFromStr(const GString &s) +{ + GStringList strings = s.split(";"); + + // assert(count() == m_colCount); + int nIndex = 0; + + for (GStringList::Iterator it = strings.begin(); it != strings.end(); ++it) + { + GString value = *it; + m_minColWidths[nIndex] = value.toInt(); + nIndex++; + } +} + +void GLDRecordGridSetting::loadRowHeightsFromStr(const GString &s) +{ + GStringList strings = s.split(";"); + // assert(count() == m_colCount); + int nIndex = 0; + int nCount = strings.count() ; + + if (nCount > m_rowCount) + { + setRowCount(nCount); + } + + for (QStringList::Iterator it = strings.begin(); it != strings.end(); ++it) + { + GString strValue = *it; + m_rowHeights[nIndex] = strValue.toInt(); + nIndex++; + } +} + +GString GLDRecordGridSetting::minColWidthsToStr() +{ + return intAryToStr(m_minColWidths); +} + +void GLDRecordGridSetting::moveCol(int fromIndex, int toIndex) +{ + assert((fromIndex >= 0) && (fromIndex < m_rowCount)); + assert((toIndex >= 0) && (toIndex < m_rowCount)); + assert(fromIndex != toIndex); + + for (int i = 0; i <= m_rowCount - 1; i++) + { + m_fieldSettings->list().move(i * m_colCount + fromIndex, i * m_colCount + toIndex); + } + + int nColWidth = m_colWidths[fromIndex]; + m_colWidths[fromIndex] = m_colWidths[toIndex]; + m_colWidths[toIndex] = nColWidth; + nColWidth = m_originColWidths[fromIndex]; + m_originColWidths[fromIndex] = m_originColWidths[toIndex]; + m_originColWidths[toIndex] = nColWidth; + nColWidth = m_minColWidths[fromIndex]; + m_minColWidths[fromIndex] = m_minColWidths[toIndex]; + m_minColWidths[toIndex] = nColWidth; +} + +void GLDRecordGridSetting::moveRow(int fromIndex, int toIndex) +{ + //assert((fromIndex >= 0) &&(fromIndex < m_rowCount)); + //assert((toIndex >= 0) &&(toIndex < m_rowCount)); + //assert(fromIndex != toIndex); + for (int i = 0; i <= m_colCount - 1; i++) + { + m_fieldSettings->list().move(fromIndex * m_colCount + i, toIndex * m_colCount + i); + } + + int nRowHeight = m_rowHeights[fromIndex]; + m_rowHeights[fromIndex] = m_rowHeights[toIndex]; + m_rowHeights[toIndex] = nRowHeight; +} + +GString GLDRecordGridSetting::rowHeightsToStr() +{ + return intAryToStr(m_rowHeights); +} + +void GLDRecordGridSetting::saveToFile(const GString &fileName) +{ + GLDRecordGridSettingXMLWriter oWriter; + oWriter.write(fileName, this); +} + +void GLDRecordGridSetting::saveToStream(GStream *stream) +{ + GLDCustomGridSetting::saveToStream(stream); + writeIntToStream(stream, rowCount()); + writeIntToStream(stream, colCount()); + writeWordToStream(stream, m_fixedRows); + writeBoolToStream(stream, m_ignoreInvalidCell); + writeBoolToStream(stream, m_allowLabelSelection); + writeStrToStream(stream, rowHeightsToStr()); + writeStrToStream(stream, colWidthsToStr()); + writeStrToStream(stream, minColWidthsToStr()); + writeStrToStream(stream, colStylesToStr()); + writeStrToStream(stream, colIdentitysToStr()); + m_recordSettings->saveToStream(stream); + m_fieldSettings->saveToStream(stream); +} + +void GLDRecordGridSetting::setColCount(const int value) +{ + int nOffset(0); + + //assert(value >= 0); + if (m_colCount == value) + { + return; + } + + if (m_colCount < value) + { + nOffset = value - m_colCount; + + for (int i = 0; i <= nOffset - 1; i++) + { + insertCol(-1); + } + } + else + { + nOffset = m_colCount - value; + + for (int i = 0; i <= nOffset - 1; i++) + { + deleteCol(m_colCount - 1); + } + } +} + +void GLDRecordGridSetting::setOriginColWidths(int index, const int value) +{ + assert((index >= 0) && (index < m_colCount)); + m_originColWidths[index] = value; + m_colWidths[index] = value; +} + +void GLDRecordGridSetting::setMinColWidths(int index, const int value) +{ + assert((index >= 0) && (index < m_colCount)); + m_minColWidths[index] = value; +} + +void GLDRecordGridSetting::setRowCount(const int value) +{ + int nOffset(0); + assert(value >= 0); + + if (m_rowCount == value) + { + return; + } + + if (m_rowCount < value) + { + nOffset = value - m_rowCount; + + for (int i = 0; i <= nOffset - 1; i++) + { + insertRow(-1); + } + } + else + { + nOffset = m_rowCount - value; + + for (int i = 0; i <= nOffset - 1; i++) + { + deleteRow(m_rowCount - 1); + } + } +} + +void GLDRecordGridSetting::setRowHeights(int index, const int value) +{ + assert((index >= 0) && (index < m_rowCount)); + + if (value < 0) + { + return; + } + + m_rowHeights[index] = value; +} + +GLDRecordFieldSetting *GLDRecordGridSetting::fieldsetting(int row, int col) +{ + assert((col >= 0) && (col < m_colCount)); + assert((row >= 0) && (row < m_rowCount)); + return fieldSettings()->items(row * m_colCount + col); +} + +void GLDRecordGridSetting::clearCompileInfo() +{ + m_recordSettings->clearCompileInfo(); + m_fieldSettings->clearCompileInfo(); +} + +void GLDRecordGridSetting::clearData() +{ + m_rowCount = 0; + m_colCount = 0; + m_fixedRows = 0; + m_fixedCols = 0; + m_fixedEditRows = 0; + m_fixedEditCols = 0; + m_rowHeights.clear(); + m_colWidths.clear(); + m_originColWidths.clear(); + m_minColWidths.clear(); + m_colStyles.clear(); + m_colIdentitys.clear(); + m_recordSettings->clear(); + m_fieldSettings->clear(); +} + +GLDCellSuitType GLDRecordGridSetting::colStyles(int index) +{ + assert((index >= 0) && (index < m_colCount)); + return (GLDCellSuitType) m_colStyles[index]; +} + +void GLDRecordGridSetting::setColStyles(int index, const GLDCellSuitType value) +{ + assert((index >= 0) && (index < m_colCount)); + m_colStyles[index] = (int)value; +} + +void GLDRecordGridSetting::setColWidths(int index, const int value) +{ + assert((index >= 0) && (index < m_colCount)); + m_colWidths[index] = value; +} + +void GLDRecordGridSetting::setColZoomWidths(int index, const int value) +{ + assert((index >= 0) && (index < m_colCount)); + m_colZoomWidths[index] = value; +} + +GString GLDRecordGridSetting::colStylesToStr() +{ + return intAryToStr(m_colStyles); +} + +void GLDRecordGridSetting::loadColStylesFromStr(const GString &s) +{ + GStringList strings = s.split(";"); + // assert(count() == m_colCount); + int nCounter = 0; + + for (GStringList::Iterator it = strings.begin(); it != strings.end(); ++it) + { + GString strValue = *it; + m_colStyles[nCounter] = strValue.toInt(); + nCounter++; + } +} + +GString GLDRecordGridSetting::colIdentitysToStr() +{ + GString result = m_colIdentitys[0]; + + for (int i = 1; i <= m_colCount - 1; i++) + { + result = result + CDelimiter + m_colIdentitys[i]; + } + + return result; +} + +void GLDRecordGridSetting::loadColIdentitysFromStr(const GString &s) +{ + GStringList strings = s.split(CDelimiter); + int nIndex = 0; + + for (GStringList::Iterator it = strings.begin(); it != strings.end(); ++it) + { + m_colIdentitys[nIndex] = *it; + nIndex++; + } +} + +void GLDRecordGridSetting::setColIdentitys(int index, const GString &value) +{ + assert((index >= 0) && (index < m_colCount)); + m_colIdentitys[index] = value; +} + +GIntList GLDRecordGridSetting::suitColWidthCols() +{ + GIntList result; + + for (int i = 0; i != m_colCount; i++) + { + if (m_colStyles[i] == gcstSuitColWidth) + { + result.push_back(i); + } + } + + return result; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2006-01-05 + 功能: 返回自动折行的列的下标列表 +-----------------------------------------------------------------------------*/ +GIntList GLDRecordGridSetting::suitRowHeightCols() +{ + GIntList result; + + for (int i = 0; i != m_colCount; i++) + { + if (m_colStyles[i] == gcstSuitRowHeight) + { + result.push_back(i); + } + } + + return result; +} + +GIntList GLDRecordGridSetting::fitColWidthCols() +{ + GIntList result; + + int nFixedColCount = fixedCols(); + for (int i = 0; i != m_colCount; i++) + { + if (m_colStyles[i] == gcstFitColWidth) + { + result.push_back(i - nFixedColCount); + } + } + + return result; +} + +int GLDRecordGridSetting::rowCount() const +{ + return m_rowCount; +} + +int GLDRecordGridSetting::colCount() const +{ + return m_colCount; +} + +int GLDRecordGridSetting::rowHeights(const int index) const +{ + return m_rowHeights[index]; +} + +int GLDRecordGridSetting::colWidths(int index) const +{ + return m_colWidths[index]; +} + +int GLDRecordGridSetting::colZoomWidths(int index) const +{ + return m_colZoomWidths[index]; +} + +int GLDRecordGridSetting::originColWidths(int index) const +{ + return m_originColWidths[index]; +} +int GLDRecordGridSetting::minColWidths(int index) const +{ + return m_minColWidths[index]; +} + +GString GLDRecordGridSetting::colIdentitys(int index) const +{ + return m_colIdentitys[index]; +} + +unsigned short GLDRecordGridSetting::fixedRows() const +{ + return m_fixedRows; +} + +void GLDRecordGridSetting::setFixedRows(unsigned short value) +{ + m_fixedRows = value; +} + +bool GLDRecordGridSetting::ignoreInvalidCell() const +{ + return m_ignoreInvalidCell; +} + +void GLDRecordGridSetting::setIgnoreInvalidCell(bool value) +{ + m_ignoreInvalidCell = value; +} + +bool GLDRecordGridSetting::allowLabelSelection() const +{ + return m_allowLabelSelection; +} + +void GLDRecordGridSetting::setAllowLabelSelection(bool value) +{ + m_allowLabelSelection = value; +} + +/* GLDRecordSettings */ + +GLDRecordSettings::GLDRecordSettings(GLDRecordGridSetting *owner) +{ + m_owner = owner; + insert(-1); +} + +GLDRecordSettings::~GLDRecordSettings() +{ + clear(); +} + +void GLDRecordSettings::clear() +{ + m_list.clear(); +} + +int GLDRecordSettings::count() const +{ + return (int)m_list.size(); +} + +GLDRecordSetting *GLDRecordSettings::items(int index) const +{ + return m_list[index]; +} + +GLDRecordSetting *GLDRecordSettings::operator[](int index) +{ + return items(index); +} + +GLDRecordGridSetting *GLDRecordSettings::owner() +{ + return m_owner; +} + +void GLDRecordSettings::clearCompileInfo() +{ + for (int i = 0; i <= count() - 1; i++) + { + items(i)->clearCompileInfo(); + } +} + +void GLDRecordSettings::compile() +{ + for (int i = 0; i <= count() - 1; i++) + { + items(i)->compile(); + } +} + +void GLDRecordSettings::Delete(int index) +{ + assert((index >= 0) && (index < count())); + m_list.removeAt(index); +} + +GLDRecordSetting *GLDRecordSettings::insert(int index) +{ + GLDRecordSetting *result = createRecordSetting(this); + + if (index == -1) + { + m_list.push_back(result); + } + else + { + m_list.insert(index, result); + } + + return result; +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 从流对象中装载数据 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDRecordSettings::loadFromStream(GStream *stream) +{ + int nInts(0); + readIntFromStream(stream, nInts); + clear(); + + for (int i = 0; i <= nInts - 1; i++) + { + insert()->loadFromStream(stream); + } +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-12 + 功能: 保存数据到流对象中 + 参数: stream -- 流对象 +-----------------------------------------------------------------------------*/ +void GLDRecordSettings::saveToStream(GStream *stream) +{ + writeIntToStream(stream, count()); + + for (int i = 0; i <= count() - 1; i++) + { + items(i)->saveToStream(stream); + } +} + +void GLDRecordSettings::move(int fromIndex, int toIndex) +{ + assert((fromIndex >= 0) && (fromIndex < count())); + assert((toIndex >= 0) && (toIndex < count())); + + if (fromIndex == toIndex) + { + return; + } + + m_list.move(fromIndex, toIndex); +} + +void GLDRecordSettings::setCount(const int value) +{ + int nSize = (int)m_list.size(); + + if (value == nSize) + { + return; + } + + if (value > nSize) + { + for (int i = nSize; i <= value - 1; i++) + { + m_list.push_back(createRecordSetting(this)); + } + } +} + +GLDRecordSetting *GLDRecordSettings::doCreateRecordSetting(GLDRecordSettings *owner) +{ + return new GLDRecordSetting(owner); +} + +GLDRecordSetting *GLDRecordSettings::createRecordSetting(GLDRecordSettings *owner) +{ + GLDRecordSetting *result = doCreateRecordSetting(owner); + result->initialize(); + return result; +} + +/* GLDRecordSetting */ + +void GLDRecordSetting::initialize() +{ + m_rules = createGridRules(this); +} + +GLDRecordSetting::GLDRecordSetting(GLDRecordSettings *owner) +{ + assert(owner != NULL); + m_owner = owner; +} + +GLDRecordSetting::~GLDRecordSetting() +{ + freeAndNil(m_rules) +} + +void GLDRecordSetting::clearCompileInfo() +{ + for (int i = 0; i <= m_rules->count() - 1; i++) + { + m_rules->items(i)->clearCompileInfo(); + } +} + +void GLDRecordSetting::compile() +{ + for (int i = 0; i <= m_rules->count() - 1; i++) + { + m_rules->items(i)->compile(); + } +} + +GString GLDRecordSetting::refFullName() +{ + if (m_refDatabaseName != "") + { + return m_refDatabaseName + "." + m_refTableName; + } + else + { + return m_refTableName; + } +} + +GString GLDRecordSetting::refDatabaseName() const +{ + return m_refDatabaseName; +} + +void GLDRecordSetting::setRefDatabaseName(const GString &value) +{ + m_refDatabaseName = value; +} + +GString GLDRecordSetting::refTableName() const +{ + return m_refTableName; +} + +void GLDRecordSetting::setRefTableName(const GString &value) +{ + m_refTableName = value; +} + +GLDRecordGridRules *GLDRecordSetting::rules() +{ + return m_rules; +} + +GLDRecordSettings *GLDRecordSetting::owner() +{ + return m_owner; +} + +GLDRecordGridRules *GLDRecordSetting::createGridRules(GLDRecordSetting *owner) +{ + return new GLDRecordGridRules(owner); +} + +void GLDRecordSetting::loadFromStream(GStream *stream) +{ + readStrFromStream(stream, m_refDatabaseName); + readStrFromStream(stream, m_refTableName); + m_rules->loadFromStream(stream); +} + +void GLDRecordSetting::saveToStream(GStream *stream) +{ + writeStrToStream(stream, m_refDatabaseName); + writeStrToStream(stream, m_refTableName); + m_rules->saveToStream(stream); +} + +/* GLDRecordFieldSettings */ + +GLDRecordFieldSettings::GLDRecordFieldSettings(GLDRecordGridSetting *owner) +{ + m_owner = owner; +} + +GLDRecordFieldSettings::~GLDRecordFieldSettings() +{ + clear(); +} + +void GLDRecordFieldSettings::Delete(int index) +{ + assert((index >= 0) && (index < m_list.count())); + m_list.removeAt(index); +} + +void GLDRecordFieldSettings::clear() +{ + m_list.clear(); +} + +GLDRecordFieldSetting *GLDRecordFieldSettings::items(int index) const +{ + return m_list[index]; +} + +GLDRecordFieldSetting *GLDRecordFieldSettings::operator[](int index) +{ + return items(index); +} + +int GLDRecordFieldSettings::indexOf(GLDRecordFieldSetting *value) const +{ + return m_list.indexOf(value); +} + +GObjectList &GLDRecordFieldSettings::list() +{ + return m_list; +} + +int GLDRecordFieldSettings::count() +{ + return (int)m_list.size(); +} + +GLDRecordGridSetting *GLDRecordFieldSettings::owner() const +{ + return m_owner; +} + +GLDRecordFieldSetting *GLDRecordFieldSettings::createFieldSetting(GLDRecordFieldSettings *owner) +{ + return new GLDRecordFieldSetting(owner); +} + +void GLDRecordFieldSettings::clearCompileInfo() +{ + for (int i = 0; i <= count() - 1; i++) + { + items(i)->clearCompileInfo(); + } +} + +void GLDRecordFieldSettings::compile() +{ + for (int i = 0; i <= count() - 1; i++) + { + items(i)->compile(); + } +} + +GLDRecordFieldSetting *GLDRecordFieldSettings::insert(int index) +{ +// assert((index >= - 1) && (index <= m_list.count()())); + GLDRecordFieldSetting *result = createFieldSetting(this); + + if (index == -1) + { + m_list.push_back(result); + } + else + { + m_list.insert(index, result); + } + + return result; +} + +void GLDRecordFieldSettings::loadFromStream(GStream *stream) +{ + for (int i = 0; i <= count() - 1; i++) + { + items(i)->loadFromStream(stream); + } +} + +void GLDRecordFieldSettings::saveToStream(GStream *stream) +{ + for (int i = 0; i <= count() - 1; i++) + { + items(i)->saveToStream(stream); + } +} + +/* GLDRecordFieldSetting */ + +GLDRecordFieldSetting::GLDRecordFieldSetting(GLDRecordFieldSettings *owner) +{ + m_owner = owner; + m_visible = true; + m_isLabel = false; + m_isPasswordChar = false; +} + +GLDRecordFieldSetting::~GLDRecordFieldSetting() +{ +} + +void GLDRecordFieldSetting::assign(GLDRecordFieldSetting *fieldSetting) +{ + assert(fieldSetting != NULL); + GMemoryStream oStream; + fieldSetting->saveToStream(&oStream); + oStream.seek(0); + loadFromStream(&oStream); +} + +bool GLDRecordFieldSetting::isLabel() const +{ + return m_isLabel; +} + +void GLDRecordFieldSetting::setIsLabel(bool value) +{ + m_isLabel = value; +} + +bool GLDRecordFieldSetting::visible() const +{ + return m_visible; +} + +void GLDRecordFieldSetting::setVisible(const bool &value) +{ + m_visible = value; +} + +GString GLDRecordFieldSetting::visibleCondition() const +{ + return m_visibleCondition; +} + +void GLDRecordFieldSetting::setVisibleCondition(const GString &value) +{ + m_visibleCondition = trim(value); +} + +int GLDRecordFieldSetting::dataSourceID() const +{ + return m_dataSourceID; +} + +void GLDRecordFieldSetting::setDataSourceID(const int value) +{ + m_dataSourceID = value; +} + +bool GLDRecordFieldSetting::isPasswordChar() const +{ + return m_isPasswordChar; +} + +void GLDRecordFieldSetting::setIsPasswordChar(bool value) +{ + m_isPasswordChar = value; +} + +GLDRecordFieldSettings *GLDRecordFieldSetting::owner() +{ + return m_owner; +} + +void GLDRecordFieldSetting::clearCompileInfo() +{ + GLDCustomFieldSetting::clearCompileInfo(); + m_isLabel = false; + m_visible = true; +} + +void GLDRecordFieldSetting::compile() +{ + GString strExpr; + + try + { + m_isLabel = false; + GLDCustomFieldSetting::compile(); + strExpr = trimExpression(m_visibleCondition); + + if (strExpr != "") + { + doNothingMacro();// + } + } + catch (...) + { + if (!m_owner->owner()->ignoreInvalidCell()) + { + throw; + } + } +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2006-09-13 + 功能:Index 相当于 ColNo +-----------------------------------------------------------------------------*/ +int GLDRecordFieldSetting::colNo() +{ + int nIndex = recordGridSetting()->fieldSettings()->indexOf(this); + return nIndex % recordGridSetting()->colCount(); +} + +GLDDataType GLDRecordFieldSetting::displayExprDataType() +{ + if (m_owner->owner()->designState()) + { + gldError("GSPGridSetting_SNeedRunState"); + } + + return 0; +} + +GLDCustomGridSetting *GLDRecordFieldSetting::gridSetting() +{ + return m_owner->owner(); +} + +int GLDRecordFieldSetting::index() const +{ + return recordGridSetting()->fieldSettings()->indexOf(const_cast(this)); +} + +bool GLDRecordFieldSetting::designState() +{ + return m_owner->owner()->designState(); +} + +GLDRecordSetting *GLDRecordFieldSetting::recordSetting() +{ + if (m_owner->owner()->recordSettings()->count() == 0) + { + return NULL; + } + else + { + return m_owner->owner()->recordSettings()->items(m_dataSourceID); + } +} + +int GLDRecordFieldSetting::rowNo() +{ + int nIndex = recordGridSetting()->fieldSettings()->indexOf(this); + return nIndex / recordGridSetting()->colCount(); +} + +GLDRecordGridSetting *GLDRecordFieldSetting::recordGridSetting() const +{ + return m_owner->owner(); +} + +void GLDRecordFieldSetting::loadFromStream(GStream *stream) +{ + GLDCustomFieldSetting::loadFromStream(stream); + readIntFromStream(stream, m_dataSourceID); + readBoolFromStream(stream, m_isPasswordChar); +} + +void GLDRecordFieldSetting::saveToStream(GStream *stream) +{ + GLDCustomFieldSetting::saveToStream(stream); + writeIntToStream(stream, m_dataSourceID); + writeBoolToStream(stream, m_isPasswordChar); +} + +GString GLDRecordFieldSetting::refFullName() +{ + return m_owner->owner()->recordSettings()->items(m_dataSourceID)->refFullName(); +} + +int GLDRecordFieldSetting::tableIndex() +{ + int nIndex = recordGridSetting()->fieldSettings()->indexOf(this); + return nIndex / recordGridSetting()->rowCount(); +} + +/* GLDRecordGridRules */ + +GLDRecordGridRules::GLDRecordGridRules(GLDRecordSetting *owner) +{ + m_owner = owner; +} + +bool GLDRecordGridRules::designState() +{ + return m_owner->owner()->owner()->designState(); +} + +GLDRecordGridRules::~GLDRecordGridRules() +{ +} + +GLDCustomGridSetting *GLDRecordGridRules::gridSetting() +{ + return m_owner->owner()->owner(); +} + +int GLDRecordGridRules::tableIndex() +{ + return 0; +} + +GString GLDRecordGridRules::refFullName() +{ + return m_owner->refFullName(); +} + +bool isNullTitleCell(GLDTitleCell *cell) +{ + return (cell->mergeID() == 0) && (cell->caption() == "") + && isDefaultCellFormat(cell->cellFormat(), ghaCenter); +} + +bool isDefaultCellFormat(GLDCellFormat *cellFormat, GLDHorzAlignment defHorzAlignment) +{ + return sameText(cellFormat->fontName(), CDefFontName) + && sameText(cellFormat->formatStr(), CDefFormatStr) + && (cellFormat->fontSize() == DefFontSize) + && (cellFormat->foreColor() == DefForeColor) + && (cellFormat->backColor() == DefBackColor) + //todo yaok(cellFormat->fontStyle() == DefFontStyle) && + && (cellFormat->leftLineWidth() == DefLeftLineWidth) + && (cellFormat->topLineWidth() == DefTopLineWidth) + && (cellFormat->rightLineWidth() == DefRightLineWidth) + && (cellFormat->bottomLineWidth() == DefBottomLineWidth) + && (cellFormat->diagonalWidth() == DefDiagonalWidth) + && (cellFormat->antiDiagonalWidth() == DefAntiDiagonalWidth) + && (cellFormat->horzAlignment() == defHorzAlignment) + && (cellFormat->vertAlignment() == DefVertAlignment) + && (cellFormat->nullIsZero() == DefNullIsZero); +} + +bool isNullFilterCell(GLDFilterCell *filterCell) +{ + return (filterCell->mergeID() == 0) + && (filterCell->caption() == "") + && (filterCell->editorName() == "") + && isDefaultCellFormat(filterCell->cellFormat()); +} + +bool isNullFieldSetting(GLDFieldSetting *fieldSetting) +{ + return (fieldSetting->mergeID() == 0) + && (fieldSetting->editFieldName() == "") + && (fieldSetting->displayExpr() == "") + && (fieldSetting->saveFieldName() == "") + && (fieldSetting->saveRule() == "") + && (fieldSetting->nullValDisplayStr() == "") + && (fieldSetting->extData() == "") + && (fieldSetting->editorName() == "") + && !fieldSetting->editTextIsDisplayText() + && fieldSetting->isDefaultCellIdentity() + && isDefaultCellFormat(fieldSetting->cellFormat()) + && true; + //todo yaok (fieldSetting->ExtPropDefs.Count = 0); +} + +bool isNullExpandFieldSetting(GLDExpandRowFieldSetting *fieldSetting) +{ + return (fieldSetting->mergeID() == 0) + && (fieldSetting->value() == "") + && isDefaultCellFormat(fieldSetting->cellFormat()); +} + +bool isNullFieldSetting(GLDRecordFieldSetting *fieldSetting) +{ + return (fieldSetting->dataSourceID() == 0) + && (fieldSetting->mergeID() == 0) + && (fieldSetting->editFieldName() == "") + && (fieldSetting->displayExpr() == "") + && (fieldSetting->saveFieldName() == "") + && (fieldSetting->saveRule() == "") + && (fieldSetting->nullValDisplayStr() == "") + && (fieldSetting->visibleCondition() == "") + && (fieldSetting->extData() == "") + && (fieldSetting->cellIdentity() == "") + && !fieldSetting->editTextIsDisplayText() + && !fieldSetting->isPasswordChar() + && isDefaultCellFormat(fieldSetting->cellFormat()); + //todo yaok(fieldSetting->ExtPropDefs.Count = 0); +} + +/* GLDCanFocusRule */ + +GLDCanFocusRule::GLDCanFocusRule(GLDCustomGridRules *owner) : GLDGridRule(owner) +{ + m_canFocus = CDefCanFocus; +} + +GLDCanFocusRule::~GLDCanFocusRule() +{ +} + +void GLDCanFocusRule::loadFromStream(GStream *stream) +{ + GLDGridRule::loadFromStream(stream); + readBoolFromStream(stream, m_canFocus); +} + +void GLDCanFocusRule::saveToStream(GStream *stream) +{ + GLDGridRule::saveToStream(stream); + writeBoolToStream(stream, m_canFocus); +} + +GLDGridRuleType GLDCanFocusRule::ruleType() +{ + return grtCanFocus; +} + +bool GLDCanFocusRule::canFocus() const +{ + return m_canFocus; +} + +void GLDCanFocusRule::setCanFocus(const bool value) +{ + m_canFocus = value; +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDGridSettingXMLBuilder.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDGridSettingXMLBuilder.cpp new file mode 100644 index 00000000..7c671e87 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDGridSettingXMLBuilder.cpp @@ -0,0 +1,2259 @@ +#include "GLDGridSettingXMLBuilder.h" +#include "GLDFile.h" +#include "GLDGlobal.h" +#include "GLDException.h" +#include "GLDStreamUtils.h" +#include "GLDXMLUtils.h" +#include "GLDStrUtils.h" +#include "GLDStrings.h" +#include "GLDTextStream.h" + +//const char *SInvalidXMLNode = QT_TRANSLATE_NOOP("GLD", "Invalid configuration file");// "配置文件非法"); +//const char *SNeedXMLNode = QT_TRANSLATE_NOOP("GLD", "XML Node field cannot be null");// "XML节点不能为空"); + +GString g_OldVersion; +int g_DefHeaderRowHeight; +int g_DefTotalRowHeight; + +static GRgb g_clSilver = qRgb(125,125,125); +static GRgb g_clWindow = qRgb(255,255,255); +static GRgb g_clBlack = qRgb(0,0,0); + +GLDCellSuitType StrToCellSuitType(const GString &type) +{ + bool ok; + int nValue; + if (type.length() == 0) + return gcstFixed; + + nValue = type.toInt(&ok); + if (ok) + return (GLDCellSuitType)nValue; + + for (int i=0; i<=3; i++) + { + if (sameText(c_GLDCellSuitTypeStrings[i], type)) + return (GLDCellSuitType)i; + } + + return gcstFixed; +} + +GString CellSuitTypeToStr(GLDCellSuitType type) +{ + return c_GLDCellSuitTypeStrings[(int)type]; +} + +GLDGridRuleType StrToGridRuleType(const GString &type) +{ + bool ok; + int nValue; + if (type.length() == 0) + return grtFont; + + nValue = type.toInt(&ok); + if (ok) + return (GLDGridRuleType)nValue; + + for (int i=0; i<=19; i++) + { + if (sameText(c_GLDGridRuleTypeStrings[i], type)) + return (GLDGridRuleType)i; + } + + return grtFont; +} + +GString GridRuleTypeToStr(GLDGridRuleType type) +{ + return c_GLDGridRuleTypeStrings[(int)type]; +} + +/* GLDRecordGridSettingXMLReader */ +GLDRecordGridSettingXMLReader::GLDRecordGridSettingXMLReader() +{ + +} + +GLDRecordGridSettingXMLReader::~GLDRecordGridSettingXMLReader() +{ + +} + +/* GLDGridSettingXMLBaseReader */ +GLDGridSettingXMLBaseReader::~GLDGridSettingXMLBaseReader() +{ +} + +void GLDGridSettingXMLBaseReader::readGridRule(const GXMLNode &node, GLDGridRule *rule) +{ + unsigned char ucFontStyles; +// if (evaluateVersion(GOldVersion) < evaluateVersion("2.2.3")) +// { +// rule->setRuleName(readStrFromXML(node, "a:RuleName")); +// rule->setEnable(readBoolFromXML(node, "a:Enable")); +// } +// else + { + rule->setRuleName(readStrFromXMLAttr(node, "Name")); + rule->setEnable(readBoolFromXMLAttr(node, "Enable")); + } + rule->setRecordCondition(readStrFromXML(node, "a:RecordCondition")); + rule->setFieldCondition(readStrFromXML(node, "a:FieldCondition")); + switch (rule->ruleType()) + { + case grtClearCell: + { + dynamic_cast(rule)->setAllowClear(readBoolFromXML(node, "a:AllowClear", true)); + } + break; + case grtFont: + { + dynamic_cast(rule)->setFontName(readStrFromXML(node, "a:FontName")); + dynamic_cast(rule)->setFontSize(readIntFromXML(node, "a:FontSize")); + dynamic_cast(rule)->setFontColor((GRgb)readIntFromXML(node, "a:FontColor")); + ucFontStyles = readIntFromXML(node, "a:FontStyles"); + dynamic_cast(rule)->setFontStyles((FontStyles)ucFontStyles); + } + break; + case grtBackColor: + dynamic_cast(rule)->setBackColor(readIntFromXML(node, "a:BackColor")); + break; + case grtEditStyle: + dynamic_cast(rule)->setEditStyle((GLDEditStyle)readIntFromXML(node, "a:EditStyle")); + break; + case grtBoundLine: + { + dynamic_cast(rule)->setRightLine(readIntFromXML(node, "a:RightLine")); + dynamic_cast(rule)->setBottomLine(readIntFromXML(node, "a:BottomLine")); + dynamic_cast(rule)->setDiagonal(readIntFromXML(node, "a:Diagonal")); + dynamic_cast(rule)->setAntiDiagonal(readIntFromXML(node, "a:AntiDiagonal")); + } + break; + case grtAlignment: + { + dynamic_cast(rule)->setHorzAlignment((GLDHorzAlignment) readIntFromXML(node, + "a:HorzAlignment")); + dynamic_cast(rule)->setVertAlignment((GLDVertAlignment) readIntFromXML(node, + "a:VertAlignment")); + } + break; + case grtMargin: + { + dynamic_cast(rule)->setLeftMargin(readIntFromXML(node, "a:LeftMargin")); + dynamic_cast(rule)->setRightMargin(readIntFromXML(node, "a:RightMargin")); + dynamic_cast(rule)->setTopMargin(readIntFromXML(node, "a:TopMargin")); + dynamic_cast(rule)->setBottomMargin(readIntFromXML(node, "a:BottomMargin")); + } + break; + case grtReadonly: + dynamic_cast(rule)->setReadonly(readBoolFromXML(node, "a:Readonly")); + break; + case grtCanFocus: + dynamic_cast(rule)->setCanFocus(readBoolFromXML(node, "a:CanFocus")); + break; + case grtHandleSymbol: + dynamic_cast(rule)->setHandleSymbol(readBoolFromXML(node, "a:HandleSymbol")); + break; + case grtImage: + { + dynamic_cast(rule)->setImageIndex(readIntFromXML(node, "a:ImageIndex")); + dynamic_cast(rule)->setImageLayout((GLDCellImageLayout)readIntFromXML(node, "a:ImageLayout")); + } + break; + case grtComment: + { + dynamic_cast(rule)->setShowComment(readBoolFromXML(node, "a:ShowComment")); + dynamic_cast(rule)->setComment(readStrFromXML(node, "a:Comment")); + } + break; + case grtVisible: + dynamic_cast(rule)->setInVisibleText(readStrFromXML(node, "a:InVisibleText")); + break; + case grtMerge: + { + dynamic_cast(rule)->setMergeExpr(readStrFromXML(node, "a:MergeExpr")); + } + break; + case grtRejectDelete: + { + dynamic_cast(rule)->setIsTree(readIntFromXML(node, "a:IsTree")); + } + break; + case grtRejectInsert: + { + dynamic_cast(rule)->setIsTree(readIntFromXML(node, "a:IsTree")); + dynamic_cast(rule)->setIsBefore(readIntFromXML(node, "a:IsBefore")); + dynamic_cast(rule)->setTableNames(readStrFromXML(node, "a:TableNames")); + } + break; + case grtRejectInsertChild: + { + dynamic_cast(rule)->setIsTree(readIntFromXML(node, "a:IsTree")); + dynamic_cast(rule)->setIsBefore(readIntFromXML(node, "a:IsBefore")); + dynamic_cast(rule)->setTableNames(readStrFromXML(node, "a:TableNames")); + dynamic_cast(rule)->setLevel(readIntFromXML(node, "a:Level")); + } + break; + case grtRejectMove: + { + dynamic_cast(rule)->setIsTree(readIntFromXML(node, "a:IsTree")); + dynamic_cast(rule)->setIsMoveUp(readIntFromXML(node, "a:IsMoveUp")); + dynamic_cast(rule)->setIncludeChild(readIntFromXML(node, "a:IncludeChild")); + } + break; + case grtRejectLevel: + { + dynamic_cast(rule)->setIsTree(readIntFromXML(node, "a:IsTree")); + dynamic_cast(rule)->setIsLevelUp(readIntFromXML(node, "a:IsLevelUp")); + dynamic_cast(rule)->setIsFixPos(readIntFromXML(node, "a:IsFixPos")); + } + break; + case grtEditForm: + dynamic_cast(rule)->setEnable(readBoolFromXML(node, "a:Enable")); + break; + } +} + +void GLDGridSettingXMLBaseReader::readCellFormat(const GXMLNode &node, GLDCellFormat *cellFormat, + GLDHorzAlignment defHorzAlignment) +{ + cellFormat->setFontName(readStrFromXMLAttr(node, "FontName", CDefFontName)); + cellFormat->setFontSize(readIntFromXMLAttr(node, "FontSize", DefFontSize)); + cellFormat->setForeColor(readIntFromXMLAttr(node, "ForeColor", DefForeColor)); + cellFormat->setBackColor(readIntFromXMLAttr(node, "BackColor", DefBackColor)); + cellFormat->setFontStyle((FontStyles)readIntFromXMLAttr(node, "FontStyle", 0)); + cellFormat->setLeftLineWidth(readIntFromXMLAttr(node, "LeftLineWidth", DefLeftLineWidth)); + cellFormat->setTopLineWidth(readIntFromXMLAttr(node, "TopLineWidth", DefTopLineWidth)); + cellFormat->setRightLineWidth(readIntFromXMLAttr(node, "RightLineWidth", DefRightLineWidth)); + cellFormat->setBottomLineWidth(readIntFromXMLAttr(node, "BottomLineWidth", DefBottomLineWidth)); + cellFormat->setDiagonalWidth(readIntFromXMLAttr(node, "DiagonalWidth", DefDiagonalWidth)); + cellFormat->setAntiDiagonalWidth(readIntFromXMLAttr(node, "AntiDiagonalWidth", DefAntiDiagonalWidth)); + cellFormat->setHorzAlignment((GLDHorzAlignment) readIntFromXMLAttr(node, "HorzAlignment", (int)DefHorzAlignment)); + cellFormat->setVertAlignment((GLDVertAlignment) readIntFromXMLAttr(node, "VertAlignment", (int)DefVertAlignment)); + cellFormat->setFormatStr(readStrFromXMLAttr(node, "FormatStr", CDefFormatStr)); + cellFormat->setNullIsZero(readBoolFromXMLAttr(node, "NullIsZero", DefNullIsZero)); + cellFormat->setLeftMargin(readIntFromXMLAttr(node, "LeftMargin", DefHorzMargin)); + cellFormat->setRightMargin(readIntFromXMLAttr(node, "RightMargin", DefHorzMargin)); + cellFormat->setTopMargin(readIntFromXMLAttr(node, "TopMargin", DefVertMargin)); + cellFormat->setBottomMargin(readIntFromXMLAttr(node, "BottomMargin", DefVertMargin)); + cellFormat->setImageIndex(readIntFromXMLAttr(node, "ImageIndex", DefImageIndex)); + cellFormat->setImageLayout((GLDCellImageLayout)readIntFromXMLAttr(node, "ImageLayout", (int)CDefImageLayout)); + Q_UNUSED(defHorzAlignment); +} + +void GLDGridSettingXMLBaseReader::readExtPropDefs(const GXMLNode &node, CGLDExtPropDefs *extPropDefs) +{ + CGLDExtPropDef *propDef; + extPropDefs->clear(); + if (node.isNull()) + return; + // if (evaluateVersion(GOldVersion) < evaluateVersion("2.2.3")) + // { + // for (i = 0; i != node.childNodes().count() - 1; i++) + // { + // iNode = node.childNodes(i); + // if (!sameText(iNode.name(), "o:ExtPropDef")) + // Continue; + // /*with extPropDefs.insert(-1) do*/ + // { + // setCode(readStrFromXML(iNode, "a:Code")); + // setValue(readStrFromXML(iNode, "a:Value")); + // } + // } + // } + // else + GXMLNode iNode= node.firstChildElement(); + while (!iNode.isNull()) + { + if (!sameText(iNode.nodeName(), GLatin1String("o:ExtPropDef"))) + continue; + propDef = extPropDefs->insertObj(-1); + propDef->setCode(readStrFromXMLAttr(iNode, "Code")); + propDef->setValue(readStrFromXMLAttr(iNode, "Value")); + iNode = iNode.nextSiblingElement(); + + } +} + +/* GLDGridSettingXMLReader */ + +void GLDGridSettingXMLReader::read(const GString &fileName, GLDGridSetting *gridSetting) +{ + GXMLDocument iXMLDoc = loadXMLDocument(fileName); + if (iXMLDoc.isNull()) + return; + read(iXMLDoc, gridSetting); +} + +void GLDGridSettingXMLReader::read(GXMLDocument &xmlDoc, GLDGridSetting *gridSetting) +{ + GXMLNode root = xmlDoc.documentElement(); + if (root.isNull()) + gldError(getGSPi18nStr(g_NeedXMLNode)); + if (sameText(root.nodeName(), GLatin1String("c:GridSettings"))) + { + if (root.childNodes().count() == 0) + gldError(getGSPi18nStr(g_InvalidXMLNode)); + else + read(firstChildNode(root), gridSetting); + } + else + read(root, gridSetting); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.11 + 功能:从XML文档中读取Grid属性设置对象 + 参数:node -- XML节点 + gridSetting -- Grid属性设置对象 +-----------------------------------------------------------------------------*/ +void GLDGridSettingXMLReader::read(const GXMLNode &node, GLDGridSetting *gridSetting) +{ + if (node.isNull()) + gldError(getGSPi18nStr(g_NeedXMLNode)); + + GXMLNode oNode = node; + // 兼容之前的版本 + if (sameText(oNode.nodeName(), GLatin1String("c:GridSettings"))) + { + if (!oNode.hasChildNodes()) + return; + oNode = oNode.firstChildElement(); + if (oNode.isNull()) + gldError(getGSPi18nStr(g_NeedXMLNode)); + } + if (!sameText(oNode.nodeName(), GLatin1String("o:GridSetting"))) + gldError(getGSPi18nStr(g_InvalidXMLNode)); + + // 版本信息TGridSettings已经读取 + g_OldVersion = oNode.attribute("Version"); + gridSetting->setDesignState(true); + gridSetting->setDescription(readStrFromXMLAttr(oNode, "Description")); + gridSetting->setIdentity(readStrFromXMLAttr(oNode, "Identity")); + gridSetting->setRemark(readStrFromXMLAttr(oNode, "Remark")); + + // 版本转换用 + if (oNode.hasAttribute("Name")) + gridSetting->setDescription(readStrFromXMLAttr(oNode,"Name")); + + // 先清ColSetting,否则会把FixedCols清掉 + gridSetting->colSettings()->clear(); + gridSetting->setFixedCols(readIntFromXML(oNode, "a:FixedCols")); + gridSetting->setFixedEditRows(readIntFromXML(oNode, "a:FixedEditRows")); + gridSetting->setFixedEditCols(readIntFromXML(oNode, "a:FixedEditCols")); + /* todo yaok if (evaluateVersion(GOldVersion) < evaluateVersion("2.1.2")) + { + gridSetting->setLeftMargin(readIntFromXML(node, "a:CellHorzMargin")); + gridSetting->setRightMargin(readIntFromXML(node, "a:CellHorzMargin")); + gridSetting->setTopMargin(readIntFromXML(node, "a:CellVertMargin")); + gridSetting->setBottomMargin(readIntFromXML(node, "a:CellVertMargin")); + } + else */ + { + gridSetting->setLeftMargin(readIntFromXML(oNode, "a:LeftMargin")); + gridSetting->setRightMargin(readIntFromXML(oNode, "a:RightMargin")); + gridSetting->setTopMargin(readIntFromXML(oNode, "a:TopMargin")); + gridSetting->setBottomMargin(readIntFromXML(oNode, "a:BottomMargin")); + } + gridSetting->setInvalidValueLabel(readStrFromXML(oNode, "a:InvalidValueLabel")); + gridSetting->setGridLineWidth(readIntFromXML(oNode, "a:GridLineWidth", 0)); + gridSetting->setGridLineColor(readIntFromXML(oNode, "a:GridLineColor", g_clSilver)); + gridSetting->setGridColor(readIntFromXML(oNode, "a:GridColor", g_clWindow)); + gridSetting->setBoundLineColor(readIntFromXML(oNode, "a:BoundLineColor", g_clBlack)); + gridSetting->setAllowSort(readBoolFromXML(oNode, "a:AllowSort")); + gridSetting->setAllowCopyPaste(readBoolFromXML(oNode, "a:AllowCopyPaste", true)); + gridSetting->setSortFieldNames(readStrFromXML(oNode, "a:SortFieldNames")); + gridSetting->setAscImageIndex(readIntFromXML(oNode, "a:AscImageIndex", -1)); + gridSetting->setDescImageIndex(readIntFromXML(oNode, "a:DescImageIndex", -1)); + GXMLNode iNode = findChildNode(oNode, "a:Options"); + //todo yaok + // if (iNode != NULL) + // readOldVertionOptions(iNode); + // else + { + gridSetting->setShowAsTree(readBoolFromXML(oNode, "a:ShowAsTree")); + gridSetting->setEditing(readBoolFromXML(oNode, "a:Editing", true)); + gridSetting->setVertLine(readBoolFromXML(oNode, "a:VertLine", true)); + gridSetting->setHorzLine(readBoolFromXML(oNode, "a:HorzLine", true)); + gridSetting->setRowSizing(readBoolFromXML(oNode, "a:RowSizing")); + gridSetting->setColSizing(readBoolFromXML(oNode, "a:ColSizing", true)); + gridSetting->setColMoving(readBoolFromXML(oNode, "a:ColMoving", true)); + gridSetting->setAlwaysShowEditor(readBoolFromXML(oNode, "a:AlwaysShowEditor")); + gridSetting->setRangeSelect(readBoolFromXML(oNode, "a:RangeSelect", true)); + gridSetting->setAllowSelectRow(readBoolFromXML(oNode, "a:AllowSelectRow", true)); + gridSetting->setAllowSelectCol(readBoolFromXML(oNode, "a:AllowSelectCol", true)); + gridSetting->setAllowSelectAll(readBoolFromXML(oNode, "a:AllowSelectAll", true)); + gridSetting->setMultiSelection(readBoolFromXML(oNode, "a:MultiSelection", true)); + gridSetting->setAutoThemeAdapt(readBoolFromXML(oNode, "a:AutoThemeAdapt", true)); + gridSetting->setReturnKeyAsTab(readBoolFromXML(oNode, "a:ReturnKeyAsTab")); + gridSetting->setShowFixedRow(readBoolFromXML(oNode, "a:ShowFixedRow", true)); + gridSetting->setCellFilling(readBoolFromXML(oNode, "a:CellFilling")); + gridSetting->setFixedCellEvent(readBoolFromXML(oNode, "a:FixedCellEvent")); + gridSetting->setAllow3DStyle(readBoolFromXML(oNode, "a:Allow3DStyle", true)); + gridSetting->setHideEditOnExit(readBoolFromXML(oNode, "a:HideEditOnExit")); + gridSetting->setBorderStyle(readBoolFromXML(oNode, "a:BorderStyle", true)); + gridSetting->setUseBlendColor(readBoolFromXML(oNode, "a:UseBlendColor", true)); + gridSetting->setCellFillEditField(readBoolFromXML(oNode, "a:CellFillEditField")); + gridSetting->setTotalRowAtFooter(readBoolFromXML(oNode, "a:TotalRowAtFooter", true)); + } + iNode = findChildNode(oNode,"c:ExtPropDefs"); + if (!iNode.isNull()) + readExtPropDefs(iNode, gridSetting->extPropDefs()); + readColSettings(findChildNode(oNode, "c:ColSettings"), gridSetting->colSettings()); + readTitleRows(findChildNode(oNode, "c:TitleRows"), gridSetting->titleRows()); + readFilterRows(findChildNode(oNode, "c:FilterRows"), gridSetting->filterRows()); + readTableSettings(findChildNode(oNode, "c:TableSettings"), gridSetting->tableSettings()); + //todo yaok + // int i; + // int nFixedColWidth; + // if (evaluateVersion(GOldVersion) <= evaluateVersion("1.0.3")) + // { + // nFixedColWidth = readIntFromXML(node, "a:FixedColWidth"); + // if (nFixedColWidth == 0) + // nFixedColWidth = 20; + // /*with gridSetting.colSettings().insert(0) do*/ + // { + // gridSetting->ColSettings->insert(0).setDisplayWidth(nFixedColWidth); + // gridSetting->ColSettings->insert(0).setVisible(true); + // gridSetting->ColSettings->insert(0).setCellSuitType(cstSuitColWidth); + // } + // for (i = 0; i != gridSetting->TableSettings->Count - 1; i++) + // gridSetting->TableSettings->Items[i]->FieldSettings->Items[0].setDisplayExpr(CDefFixedColDisplayExpr); + // } + +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.11 + 功能:从XML文档中读取列设置容器对象 + 参数:node -- XML节点 + colSettings -- 列设置容器对象 +-----------------------------------------------------------------------------*/ +void GLDGridSettingXMLReader::readColSettings(const GXMLNode &node, GLDColSettings *colSettings) +{ + colSettings->clear(); + if (node.isNull()) + return; + GXMLNode child= node.firstChildElement(); + while (!child.isNull()) + { + if (sameText(child.nodeName(), GLatin1String("o:ColSetting"))) + { + readColSetting(child, colSettings->insert(-1)); + } + child = child.nextSiblingElement(); + + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.11 + 功能:从XML文档中读取列设置对象 + 参数:node -- XML节点 + colSetting -- 列设置对象 +-----------------------------------------------------------------------------*/ +void GLDGridSettingXMLReader::readColSetting(const GXMLNode &node, GLDColSetting *colSetting) +{ + //todo yaok + // bool bVisible; + // if (evaluateVersion(GOldVersion) < evaluateVersion("2.2.3")) + // { + // colSetting->setDisplayWidth(readIntFromXML(node, "a:DisplayWidth")); + // colSetting->setVisibleCondition(readStrFromXML(node, "a:VisibleCondition")); + // if (evaluateVersion(GOldVersion) < evaluateVersion("1.0.11")) + // colSetting->setVisibleCondition(readStrFromXML(node, "a:Expr")); + // if (evaluateVersion(GOldVersion) < evaluateVersion("1.0.8")) + // { + // bVisible = GXMLDocument(node, "a:Visible"); + // if (!bVisible) + // colSetting->setVisibleCondition("=False"); + // } + // colSetting->CellSuitType = ((GLDCellSuitType) readIntFromXML(node, "a:AutoWrapType")); + // colSetting->setIdentity(readStrFromXML(node, "a:Identity")); + // if (evaluateVersion(GOldVersion) < evaluateVersion("1.0.19")) + // { + // if (GXMLDocument(node, "a:IsFixedCol")) + // colSetting->GridSetting->setFixedCols(colSetting->GridSetting->FixedCols + 1); + // } + // colSetting->setExtData(readStrFromXML(node, "a:ExtData")); + // } + // else + { + colSetting->setDisplayWidth(readIntFromXMLAttr(node, "DisplayWidth")); + colSetting->setCellSuitType(StrToCellSuitType(readStrFromXMLAttr(node, "AutoWrapType", "cstFixed"))); + colSetting->setIdentity(readStrFromXMLAttr(node, "Identity")); + colSetting->setExtData(readStrFromXMLAttr(node, "ExtData")); + colSetting->setVisibleCondition(readStrFromXMLAttr(node, "VisibleCondition")); + GXMLNode iNode = findChildNode(node, "c:ExtPropDefs"); + if (!iNode.isNull()) + { + readExtPropDefs(iNode, colSetting->extPropDefs()); + } + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.11 + 功能:从XML文档中读取标题行容器对象 + 参数:node -- XML节点 + titleRows -- 标题行容器对象 +-----------------------------------------------------------------------------*/ +void GLDGridSettingXMLReader::readTitleRows(const GXMLNode &node, GLDTitleRows *titleRows) +{ + titleRows->clear(); + if (!node.isNull()) + { + GXMLNode child= node.firstChildElement(); + while (!child.isNull()) + { + if (sameText(child.nodeName(), GLatin1String("o:TitleRow"))) + { + readTitleRow(child, titleRows->insert(-1)); + } + child = child.nextSiblingElement(); + } + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.11 + 功能:从XML文档中读取标题行对象 + 参数:node -- XML节点 + titleRow -- 标题行对象 +-----------------------------------------------------------------------------*/ +void GLDGridSettingXMLReader::readTitleRow(const GXMLNode &node, GLDTitleRow *titleRow) +{ + if (!node.isNull()) + { + titleRow->setRowHeight(readIntFromXML(node, "a:RowHeight")); + GXMLNode iNode = findChildNode(node, "c:TitleCells"); + if (!iNode.isNull()) + readTitleCells(iNode, titleRow); + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.11 + 功能:从XML文档中读取标题单元格对象列表 + 参数:node -- XML节点 + titleCell -- 标题单元格对象 +-----------------------------------------------------------------------------*/ +void GLDGridSettingXMLReader::readTitleCells(const GXMLNode &node, GLDTitleRow *titleRow) +{ + int nIndex; + //todo yaok + // if (evaluateVersion(GOldVersion) < evaluateVersion("2.2.2")) + // { + // for (i = 0; i != node.childNodes().count() - 1; i++) + // if (sameText(node.childNodes(i).name(), "o:TitleCell")) + // readTitleCell(node.childNodes(i), titleRow->Cells[i]); + // } + // else + // { + if (!node.hasChildNodes()) + return; + GXMLNode child= node.firstChildElement(); + while (!child.isNull()) + { + if (sameText(child.nodeName(), GLatin1String("o:TitleCell"))) + { + nIndex = readIntFromXMLAttr(child, "Index"); + readTitleCell(child, titleRow ->cells(nIndex)); + } + child = child.nextSiblingElement(); + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.11 + 功能:从XML文档中读取标题单元格对象 + 参数:node -- XML节点 + titleCell -- 标题单元格对象 +-----------------------------------------------------------------------------*/ +void GLDGridSettingXMLReader::readTitleCell(const GXMLNode &node, GLDTitleCell *titleCell) +{ + //todo yaok + // if (evaluateVersion(GOldVersion) < evaluateVersion("2.2.3")) + // { + // titleCell->setCaption(readStrFromXML(node, "a:Caption")); + // titleCell->setMergeID(readIntFromXML(node, "a:MergeID")); + // } + // else + { + titleCell->setCaption(readStrFromXMLAttr(node, "Caption")); + titleCell->setMergeID(readIntFromXMLAttr(node, "MergeID")); + } + GXMLNode iNode = findChildNode(node, "o:CellFormat"); + if (!iNode.isNull()) + readCellFormat(iNode, titleCell->cellFormat(), ghaCenter); + else + titleCell->cellFormat()->setHorzAlignment(ghaCenter); +} + +void GLDGridSettingXMLReader::readFilterRows(const GXMLNode &node, GLDFilterRows *filterRows) +{ + filterRows->clear(); + if (!node.isNull()) + { + GXMLNode child= node.firstChildElement(); + while (!child.isNull()) + { + if (sameText(child.text(), GLatin1String("o:FilterRow"))) + { + readFilterRow(child, filterRows->insert(-1)); + } + child = child.nextSiblingElement(); + } + } +} + +void GLDGridSettingXMLReader::readFilterRow(const GXMLNode &node, GLDFilterRow *filterRow) +{ + if (!node.isNull()) + { + filterRow->setRowHeight(readIntFromXML(node, "a:RowHeight")); + GXMLNode iNode = findChildNode(node, "c:FilterCells"); + if (!iNode.isNull()) + readFilterCells(iNode, filterRow); + } +} + +void GLDGridSettingXMLReader::readFilterCells(const GXMLNode &node, GLDFilterRow *filterRow) +{ + int nIndex; + GXMLNode child= node.firstChildElement(); + while (!child.isNull()) + { + if (sameText(child.nodeName(), GLatin1String("o:FilterCell"))) + { + nIndex = readIntFromXMLAttr(child, "Index"); + readFilterCell(child, filterRow ->cells(nIndex)); + } + child = child.nextSiblingElement(); + } +} + +void GLDGridSettingXMLReader::readFilterCell(const GXMLNode &node, GLDFilterCell *filterCell) +{ + filterCell->setCaption(readStrFromXMLAttr(node, "Caption")); + filterCell->setEditorName(readStrFromXMLAttr(node, "EditorName")); + filterCell->setMergeID(readIntFromXMLAttr(node, "MergeID")); + GXMLNode iNode = findChildNode( node, "o:CellFormat"); + if (!iNode.isNull()) + { + if (filterCell->isFixedCol()) + readCellFormat(iNode, filterCell->cellFormat(), ghaCenter); + else + readCellFormat(iNode, filterCell->cellFormat()); + } + else + if (filterCell->isFixedCol()) + filterCell->cellFormat()->setHorzAlignment(ghaCenter); + +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.11 + 功能:从XML文档中读取表设置容器对象 + 参数:node -- XML节点 + tableSettings -- 表设置容器对象 +-----------------------------------------------------------------------------*/ +void GLDGridSettingXMLReader::readTableSettings(const GXMLNode &node, GLDTableSettings *tableSettings) +{ + tableSettings->clear(); + if (!node.isNull()) + { + GXMLNode child = node.firstChildElement(); + while (!child.isNull()) + { + if (sameText(child.nodeName(), GLatin1String("o:TableSetting"))) + { + readTableSetting(child, tableSettings->insert(-1)); + } + child = child.nextSiblingElement(); + } + + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.11 + 功能:从XML文档中读取表设置对象 + 参数:node -- XML节点 + tableSetting -- 表设置对象 +-----------------------------------------------------------------------------*/ +void GLDGridSettingXMLReader::readTableSetting(const GXMLNode &node, GLDTableSetting *tableSetting) +{ + GXMLNode child; + // if (evaluateVersion(GOldVersion) < evaluateVersion("1.0.20")) + // { + // tableSetting->setCustomDataSource(false); + // tableSetting->setMasterViewName(""); + // tableSetting->setSelfFieldName(""); + // tableSetting->setMasterFieldName(""); + // tableSetting->setPrimaryKeyFieldName(""); + // tableSetting->setParentKeyFieldName(""); + // } + // else + { + tableSetting->setCustomDataSource(readBoolFromXML(node, "a:CustomDataSource")); + tableSetting->setMasterViewName(readStrFromXML(node, "a:MasterViewName")); + tableSetting->setSelfFieldName(readStrFromXML(node, "a:SelfFieldName")); + tableSetting->setMasterFieldName(readStrFromXML(node, "a:MasterFieldName")); + tableSetting->setPrimaryKeyFieldName(readStrFromXML(node, "a:PrimaryKeyFieldName")); + tableSetting->setParentKeyFieldName(readStrFromXML(node, "a:ParentKeyFieldName")); + } + tableSetting->setIsTree(readBoolFromXML(node, "a:IsTree")); + tableSetting->setIsTreeWithMasterView(readBoolFromXML(node, "a:IsTreeWithMasterView")); + tableSetting->setTotalStyle((GLDTotalStyle) readIntFromXML(node, "a:TotalStyle")); + tableSetting->setRefTableName(readStrFromXML(node, "a:RefTableName")); + tableSetting->setRefDatabaseName(readStrFromXML(node, "a:RefDatabaseName")); + tableSetting->setDefRowHeight(readIntFromXML(node, "a:DefRowHeight")); + g_DefHeaderRowHeight = readIntFromXML(node, "a:DefHeaderRowHeight"); + if (g_DefHeaderRowHeight == 0) + g_DefHeaderRowHeight = CDefRowHeight; + g_DefTotalRowHeight = readIntFromXML(node, "a:DefTotalRowHeight"); + if (g_DefTotalRowHeight == 0) + g_DefTotalRowHeight = CDefRowHeight; + GXMLNode iNode = findChildNode(node, "c:FieldSettings"); + if (!iNode.isNull()) + readFieldSettings(iNode, tableSetting->fieldSettings()); + iNode = findChildNode( node,"c:Rules"); + if (!iNode.isNull()) + readGridRules(iNode, tableSetting->rules()); + iNode = findChildNode(node, "c:HeaderRows"); + if (!iNode.isNull()) + { + // if (evaluateVersion(GOldVersion) < evaluateVersion("2.2.2")) + // { + // for (i = 0; i != iNode.childNodes().count() - 1; i++) + // { + // if (!sameText(iNode.childNodes(i).name(), "c:HeaderRowFieldSettings")) + // Continue; + // readHeaderRowFieldSettings(iNode.childNodes(i), tableSetting->insertHeaderRow(- 1)); + // } + // } + // else + { + child = iNode.firstChildElement(); + while (!child.isNull()) + { + if (sameText(child.nodeName(), GLatin1String("o:HeaderRow"))) + { + readHeaderRowFieldSettings(child, tableSetting->insertHeaderRow(-1)); + } + child = child.nextSiblingElement(); + } + } + } + iNode = findChildNode(node, "c:TotalRows"); + if (!iNode.isNull()) + { + // if (evaluateVersion(GOldVersion) < evaluateVersion("2.2.2")) + // { + // for (i = 0; i != iNode.childNodes().count() - 1; i++) + // { + // if (!sameText(iNode.childNodes(i).name(), "c:TotalRowFieldSettings")) + // Continue; + // readTotalRowFieldSettings(iNode.childNodes(i), tableSetting->insertTotalRow(- 1)); + // } + // } + // else + { + + child = iNode.firstChildElement(); + while (!child.isNull()) + { + if (sameText(child.nodeName(), GLatin1String("o:TotalRow"))) + { + readTotalRowFieldSettings(child, tableSetting->insertTotalRow(-1)); + } + child = child.nextSiblingElement(); + } + } + } + iNode = findChildNode(node, "c:ExtPropDefs"); + if (!iNode.isNull()) + readExtPropDefs(iNode, tableSetting->extPropDefs()); + +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.11 + 功能:从XML文档中读取字段设置容器对象 + 参数:node -- XML节点 + fieldSetting -- 字段设置容器对象 +-----------------------------------------------------------------------------*/ +void GLDGridSettingXMLReader::readFieldSettings(const GXMLNode &node, GLDFieldSettings *fieldSettings) +{ + int nIndex; + if (!node.isNull()) + { + // if (evaluateVersion(GOldVersion) < evaluateVersion("2.2.2")) + // { + // for (i = 0; i != node.childNodes().count() - 1; i++) + // if (sameText(node.childNodes(i).name(), "o:FieldSetting")) + // readFieldSetting(node.childNodes(i), fieldSettings->Items[i]); + // } + // else + { + if (!node.hasChildNodes()) + return; + GXMLNode child = node.firstChildElement(); + while (!child.isNull()) + { + if (sameText(child.nodeName(), GLatin1String("o:FieldSetting"))) + { + nIndex = readIntFromXMLAttr(child, "Index"); + readFieldSetting(child, fieldSettings->items(nIndex)); + } + child = child.nextSiblingElement(); + } + } + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.11 + 功能:从XML文档中读取字段设置对象 + 参数:node -- XML节点 + fieldSetting -- 字段设置对象 +-----------------------------------------------------------------------------*/ +void GLDGridSettingXMLReader::readFieldSetting(const GXMLNode &node, GLDFieldSetting *fieldSetting) +{ + // if (evaluateVersion(GOldVersion) < evaluateVersion("2.2.3")) + // { + // fieldSetting->setMergeID(readIntFromXML(node, "a:MergeID")); + // fieldSetting->setEditFieldName(readStrFromXML(node, "a:EditFieldName")); + // fieldSetting->setDisplayExpr(readStrFromXML(node, "a:DisplayExpr")); + // fieldSetting->setSaveFieldName(readStrFromXML(node, "a:SaveFieldName")); + // fieldSetting->setSaveRule(readStrFromXML(node, "a:SaveRule")); + // fieldSetting->setNullValDisplayStr(readStrFromXML(node, "a:NullValDisplayStr")); + // fieldSetting->setExtData(readStrFromXML(node, "a:ExtData")); + // fieldSetting->setEditTextIsDisplayText(readBoolFromXML(node, "a:EditTextIsDisplayText", true)); + // fieldSetting->setCellIdentity(readStrFromXML(node, "a:CellIdentity")); + // } + // else + { + fieldSetting->setMergeID(readIntFromXMLAttr(node, "MergeID")); + fieldSetting->setEditFieldName(readStrFromXMLAttr(node, "EditFieldName")); + fieldSetting->setDisplayExpr(readStrFromXMLAttr(node, "DisplayExpr")); + fieldSetting->setSaveFieldName(readStrFromXMLAttr(node, "SaveFieldName")); + fieldSetting->setSaveRule(readStrFromXMLAttr(node, "SaveRule")); + fieldSetting->setNullValDisplayStr(readStrFromXMLAttr(node, "NullValDisplayStr")); + fieldSetting->setExtData(readStrFromXMLAttr(node, "ExtData")); + fieldSetting->setEditTextIsDisplayText(readBoolFromXMLAttr(node, "EditTextIsDisplayText", true)); + fieldSetting->setEditorName(readStrFromXMLAttr(node, "EditorName")); + fieldSetting->setCellIdentity(readStrFromXMLAttr(node, "CellIdentity")); + } + GXMLNode iNode = findChildNode( node, "o:CellFormat"); + if (!iNode.isNull()) + { + if (fieldSetting->isFixedCol()) + readCellFormat(iNode, fieldSetting->cellFormat(), ghaCenter); + else + readCellFormat(iNode, fieldSetting->cellFormat()); + } + else + if (fieldSetting->isFixedCol()) + fieldSetting->cellFormat()->setHorzAlignment(ghaCenter); + // if (evaluateVersion(GOldVersion) < evaluateVersion("1.0.7")) + // { + // if (fieldSetting->DisplayExpr != "") + // fieldSetting->setDisplayExpr("=" + fieldSetting->DisplayExpr); + // } + iNode = findChildNode( node, "c:ExtPropDefs"); + if (!iNode.isNull()) + readExtPropDefs(iNode, fieldSetting->extPropDefs()); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.11 + 功能:从XML文档中读取显示规则容器对象 + 参数:node -- XML节点 + gridRules -- 显示规则容器对象 +-----------------------------------------------------------------------------*/ +void GLDGridSettingXMLReader::readGridRules(const GXMLNode &node, GLDGridRules *gridRules) +{ + GLDGridRuleType eRuleType; + gridRules->clear(); + if (node.isNull()) + return; + + GXMLNode child; + child = node.firstChildElement(); + while (!child.isNull()) + { + + if (sameText(child.nodeName(), GLatin1String("o:GridRule"))) + { + eRuleType = StrToGridRuleType(readStrFromXMLAttr(child, "RuleType")); + readGridRule(child, gridRules->insert(-1, eRuleType)); + } + child = child.nextSiblingElement(); + } +} + +void GLDGridSettingXMLReader::readHeaderRowFieldSettings(const GXMLNode &node, + GLDHeaderRowFieldSettings *headerRowFieldSettings) +{ + if (!node.isNull()) + { + headerRowFieldSettings->setRowHeight(readIntFromXML(node, "a:RowHeight")); + // if (evaluateVersion(GOldVersion) < evaluateVersion("1.0.18")) + // headerRowFieldSettings->setRowHeight(GDefHeaderRowHeight); + //N = 0; + // if (evaluateVersion(GOldVersion) < evaluateVersion("2.2.2")) + // { + // for (i = 0; i != node.childNodes().count() - 1; i++) + // if (sameText(node.childNodes(i).name(), "o:HeaderRowFieldSetting")) + // { + // readHeaderRowFieldSetting(node.childNodes(i), headerRowFieldSettings->Items[N]); + // N ++; + // } + // } + // else + { + GXMLNode iNode = findChildNode( node, "c:FieldSettings"); + if (!iNode.isNull()) + { + GXMLNode child = iNode.firstChildElement(); + while (!child.isNull()) + { + if (sameText(child.nodeName(), GLatin1String("o:FieldSetting"))) + { + int nIndex = readIntFromXMLAttr(child, "Index"); + readHeaderRowFieldSetting(child, headerRowFieldSettings->items(nIndex)); + } + child = child.nextSiblingElement(); + } + } + } + } +} + +void GLDGridSettingXMLReader::readHeaderRowFieldSetting(const GXMLNode &node, + GLDHeaderRowFieldSetting *headerRowFieldSetting) +{ + // if (evaluateVersion(GOldVersion) < evaluateVersion("2.2.3")) + // { + // headerRowFieldSetting->setMergeID(readIntFromXML(node, "a:MergeID")); + // headerRowFieldSetting->setValue(readStrFromXML(node, "a:Value")); + // } + // else + { + headerRowFieldSetting->setMergeID(readIntFromXMLAttr(node, "MergeID")); + headerRowFieldSetting->setValue(readStrFromXMLAttr(node, "Value")); + } + GXMLNode iNode = findChildNode(node, "o:CellFormat"); + if (!iNode.isNull()) + readCellFormat(iNode, headerRowFieldSetting->cellFormat(), ghaCenter); + else + { + if (headerRowFieldSetting->isFixedCol()) + { + headerRowFieldSetting->cellFormat()->setHorzAlignment(ghaCenter); + } + } +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-16 + 功能: 从XML文档中读取合计行设置容器 + 参数: node: GXMLNode &-- XML节点 + totalRowFieldSettings -- 合计行设置容器 +-----------------------------------------------------------------------------*/ +void GLDGridSettingXMLReader::readTotalRowFieldSettings(const GXMLNode &node, + GLDTotalRowFieldSettings *totalRowFieldSettings) +{ + int nIndex; + GXMLNode child; + if (!node.isNull()) + { + totalRowFieldSettings->setRowHeight(readIntFromXML(node, "a:RowHeight")); + // if (evaluateVersion(GOldVersion) < evaluateVersion("1.0.18")) + // totalRowFieldSettings->setRowHeight(GDefTotalRowHeight); + // N = 0; + // if (evaluateVersion(GOldVersion) < evaluateVersion("2.2.2")) + // { + // for (i = 0; i != node.childNodes().count() - 1; i++) + // if (sameText(node.childNodes(i).name(), "o:TotalRowFieldSetting")) + // { + // readTotalRowFieldSetting(node.childNodes(i), totalRowFieldSettings->Items[N]); + // N ++; + // } + // } + // else + { + GXMLNode iNode = findChildNode(node, "c:FieldSettings"); + if (!iNode.isNull()) + { + child = iNode.firstChildElement(); + while (!child.isNull()) + { + if (sameText(child.nodeName(), GLatin1String("o:FieldSetting"))) + { + nIndex = readIntFromXMLAttr(child, "Index"); + readTotalRowFieldSetting(child, totalRowFieldSettings->items(nIndex)); + } + child = child.nextSiblingElement(); + } + } + } + } +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-16 + 功能: 从XML文档中读取合计行设置对象 + 参数: node: GXMLNode &-- XML节点 + totalRowFieldSetting -- 合计行设置对象 +-----------------------------------------------------------------------------*/ +void GLDGridSettingXMLReader::readTotalRowFieldSetting(const GXMLNode &node, + GLDTotalRowFieldSetting *totalRowFieldSetting) +{ + // if (evaluateVersion(GOldVersion) < evaluateVersion("2.2.3")) + // { + // totalRowFieldSetting->setMergeID(readIntFromXML(node, "a:MergeID")); + // totalRowFieldSetting->setValue(readStrFromXML(node, "a:Value")); + // } + // else + { + totalRowFieldSetting->setMergeID(readIntFromXMLAttr(node, "MergeID")); + totalRowFieldSetting->setValue(readStrFromXMLAttr(node, "Value")); + } + GXMLNode iNode = findChildNode(node, "o:CellFormat"); + if (!iNode.isNull()) + { + if (totalRowFieldSetting->isFixedCol()) + readCellFormat(iNode, totalRowFieldSetting->cellFormat(), ghaCenter); + else + readCellFormat(iNode, totalRowFieldSetting->cellFormat()); + } + else + if (totalRowFieldSetting->isFixedCol()) + totalRowFieldSetting->cellFormat()->setHorzAlignment(ghaCenter); +} + +void GLDRecordGridSettingXMLReader::read(const GString &fileName, GLDRecordGridSetting *gridSetting) +{ + GXMLDocument iXMLDoc = loadXMLDocument(fileName); + if (iXMLDoc.isNull()) + return; + read(iXMLDoc, gridSetting); +} + +void GLDRecordGridSettingXMLReader::read(const GXMLDocument &xmlDoc, GLDRecordGridSetting *gridSetting) +{ + GXMLNode root = xmlDoc.documentElement(); + if (root.isNull()) + gldError(getGSPi18nStr(g_NeedXMLNode)); + if (sameText(root.nodeName(), GLatin1String("c:RecordGridSettings"))) + { + if (root.childNodes().count() == 0) + gldError(getGSPi18nStr(g_InvalidXMLNode)); + else + read(root.firstChildElement(), gridSetting); + } + else + read(root, gridSetting); +} + +void GLDRecordGridSettingXMLReader::read(const GXMLNode &node, GLDRecordGridSetting *gridSetting) +{ + if (!sameText(node.nodeName(), GLatin1String("o:RecordGridSetting"))) + gldError(getGSPi18nStr(g_InvalidXMLNode)); + gridSetting->setDesignState(true); + if (node.hasAttribute("Version")) + g_OldVersion = readStrFromXMLAttr(node, "Version"); + // 版本转换用 + if (node.hasAttribute("Name")) + gridSetting->setDescription(readStrFromXMLAttr(node, "Name")); + if (node.hasAttribute("Description")) + gridSetting->setDescription(readStrFromXMLAttr(node, "Description")); + if (node.hasAttribute("Identity")) + gridSetting->setIdentity(readStrFromXMLAttr(node, "Identity")); + if (node.hasAttribute("Remark")) + gridSetting->setRemark(readStrFromXMLAttr(node, "Remark")); + gridSetting->setRowCount(0); + gridSetting->setColCount(0); + gridSetting->fieldSettings()->clear(); + gridSetting->setInvalidValueLabel(readStrFromXML(node, "a:InvalidValueLabel")); + gridSetting->setRowCount(readIntFromXML(node, "a:RowCount")); + gridSetting->setColCount(readIntFromXML(node, "a:ColCount")); + gridSetting->setFixedRows(readIntFromXML(node, "a:FixedRows")); + gridSetting->setFixedCols(readIntFromXML(node, "a:FixedCols")); + gridSetting->setFixedEditRows(readIntFromXML(node, "a:FixedEditRows")); + gridSetting->setFixedEditCols(readIntFromXML(node, "a:FixedEditCols")); + // if (evaluateVersion(GOldVersion) < evaluateVersion("2.1.2")) + // { + // gridSetting->setLeftMargin(readIntFromXML(node, "a:CellHorzMargin")); + // gridSetting->setRightMargin(readIntFromXML(node, "a:CellHorzMargin")); + // gridSetting->setTopMargin(readIntFromXML(node, "a:CellVertMargin")); + // gridSetting->setBottomMargin(readIntFromXML(node, "a:CellVertMargin")); + // } + // else + { + gridSetting->setLeftMargin(readIntFromXML(node, "a:LeftMargin")); + gridSetting->setRightMargin(readIntFromXML(node, "a:RightMargin")); + gridSetting->setTopMargin(readIntFromXML(node, "a:TopMargin")); + gridSetting->setBottomMargin(readIntFromXML(node, "a:BottomMargin")); + } + gridSetting->setIgnoreInvalidCell(readBoolFromXML(node, "a:IgnoreInvalidCell")); + gridSetting->setGridLineWidth(readIntFromXML(node, "a:GridLineWidth", 1)); + gridSetting->setGridLineColor(readIntFromXML(node, "a:GridLineColor", g_clSilver)); + gridSetting->setGridColor(readIntFromXML(node, "a:GridColor", g_clWindow)); + gridSetting->setBoundLineColor(readIntFromXML(node, "a:BoundLineColor", g_clBlack)); + gridSetting->setAllowLabelSelection(readBoolFromXML(node, "a:AllowLabelSelection")); + gridSetting->setAllowCopyPaste(readBoolFromXML(node, "a:AllowCopyPaste", true)); + gridSetting->loadRowHeightsFromStr(readStrFromXML(node, "a:RowHeights")); + gridSetting->loadColWidthsFromStr(readStrFromXML(node, "a:ColWidths")); + gridSetting->loadMinColWidthsFromStr(readStrFromXML(node, "a:MinColWidths")); + // if (evaluateVersion(GOldVersion) >= evaluateVersion("1.0.9")) + gridSetting->loadColStylesFromStr(readStrFromXML(node, "a:ColStyles")); + // if (evaluateVersion(GOldVersion) >= evaluateVersion("1.0.10")) + gridSetting->loadColIdentitysFromStr(readStrFromXML(node, "a:ColIdentitys")); + // int i; + // if (evaluateVersion(GOldVersion) < evaluateVersion("1.0.14")) + // { + // for (i = 0; i != gridSetting->ColCount - 1; i++) + // if (gridSetting->ColStyles[i] == cstSuitRowHeight) + // gridSetting->setColStyles(i, cstSuitColWidth); + // } + // if (evaluateVersion(GOldVersion) < evaluateVersion("2.1.1")) + // { + // for (i = 0; i != gridSetting->ColCount - 1; i++) + // if (gridSetting->ColStyles[i] == cstSuitColWidth) + // gridSetting->setColStyles(i, cstFitColWidth); + // } + // iNode = node. node.firstChildElement("a:Options"); + // if (!iNode.isNull()) + // readOldVertionOptions(iNode); + // else + { + gridSetting->setShowAsTree(readBoolFromXML(node, "a:ShowAsTree")); + gridSetting->setEditing(readBoolFromXML(node, "a:Editing", true)); + gridSetting->setVertLine(readBoolFromXML(node, "a:VertLine", true)); + gridSetting->setHorzLine(readBoolFromXML(node, "a:HorzLine", true)); + gridSetting->setRowSizing(readBoolFromXML(node, "a:RowSizing")); + gridSetting->setColSizing(readBoolFromXML(node, "a:ColSizing", true)); + gridSetting->setColMoving(readBoolFromXML(node, "a:ColMoving", true)); + gridSetting->setAlwaysShowEditor(readBoolFromXML(node, "a:AlwaysShowEditor")); + gridSetting->setRangeSelect(readBoolFromXML(node, "a:RangeSelect", true)); + gridSetting->setAllowSelectRow(readBoolFromXML(node, "a:AllowSelectRow", true)); + gridSetting->setAllowSelectCol(readBoolFromXML(node, "a:AllowSelectCol", true)); + gridSetting->setAllowSelectAll(readBoolFromXML(node, "a:AllowSelectAll", true)); + gridSetting->setMultiSelection(readBoolFromXML(node, "a:MultiSelection", true)); + gridSetting->setAutoThemeAdapt(readBoolFromXML(node, "a:AutoThemeAdapt", true)); + gridSetting->setReturnKeyAsTab(readBoolFromXML(node, "a:ReturnKeyAsTab")); + gridSetting->setShowFixedRow(readBoolFromXML(node, "a:ShowFixedRow", true)); + gridSetting->setCellFilling(readBoolFromXML(node, "a:CellFilling")); + gridSetting->setFixedCellEvent(readBoolFromXML(node, "a:FixedCellEvent")); + gridSetting->setAllow3DStyle(readBoolFromXML(node, "a:Allow3DStyle", true)); + gridSetting->setHideEditOnExit(readBoolFromXML(node, "a:HideEditOnExit")); + gridSetting->setBorderStyle(readBoolFromXML(node, "a:BorderStyle", true)); + gridSetting->setUseBlendColor(readBoolFromXML(node, "a:UseBlendColor", true)); + gridSetting->setCellFillEditField(readBoolFromXML(node, "a:CellFillEditField")); + } + GXMLNode iNode = node.firstChildElement("c:ExtPropDefs"); ;//node.firstChildElement("c:ExtPropDefs"); + if (!iNode.isNull()) + readExtPropDefs(iNode, gridSetting->extPropDefs()); + iNode = node.firstChildElement("c:RecordSettings"); + if (!iNode.isNull()) + readRecordSettings(iNode, gridSetting->recordSettings()); + iNode = node.firstChildElement("c:FieldSettings"); + if (!iNode.isNull()) + readFieldSettings(iNode, gridSetting->fieldSettings()); + // if (evaluateVersion(GOldVersion) < evaluateVersion("1.0.16")) + // { + // gridSetting->RecordSettings->clear(); + // /*with gridSetting.recordSettings().insert(-1) do*/ + // { + // gridSetting->RecordSettings->insert(- 1).setRefDatabaseName( + // readStrFromXML(node, "a:RefDatabaseName")); + // gridSetting->RecordSettings->insert(- 1).setRefTableName(readStrFromXML(node, "a:RefTableName")); + // iNode = node.firstChildElement("c:Rules"); + // if (!iNode.isNull()) + // readGridRules(iNode, gridSetting->RecordSettings->insert(- 1).rules()); + // } + // } +} + +void GLDRecordGridSettingXMLReader::readRecordSettings(const GXMLNode &node, GLDRecordSettings *recordSettings) +{ + recordSettings->clear(); + GXMLNode child = node.firstChildElement("o:RecordSetting"); + while (!child.isNull()) + { + readRecordSetting(child, recordSettings->insert(-1)); + child = child.nextSiblingElement("o:RecordSetting"); + } +} + +void GLDRecordGridSettingXMLReader::readRecordSetting(const GXMLNode &node, GLDRecordSetting *recordSetting) +{ + recordSetting->setRefDatabaseName(readStrFromXML(node, "a:RefDatabaseName")); + recordSetting->setRefTableName(readStrFromXML(node, "a:RefTableName")); + GXMLNode iNode = node.firstChildElement("c:Rules"); + if (!iNode.isNull()) + readGridRules(iNode, recordSetting->rules()); +} + +void GLDRecordGridSettingXMLReader::readGridRules(const GXMLNode &node, GLDRecordGridRules *gridRules) +{ + GLDGridRuleType eRuleType; + gridRules->clear(); + if (node.isNull()) + return; + + GXMLNode iNode = node.firstChildElement("o:GridRule"); + while (!iNode.isNull()) + { + eRuleType = StrToGridRuleType(readStrFromXMLAttr(iNode, "RuleType")); + readGridRule(iNode, gridRules->insert(-1, eRuleType)); + iNode = iNode.nextSiblingElement("o:GridRule"); + } + +} + +void GLDRecordGridSettingXMLReader::readFieldSettings(const GXMLNode &node, GLDRecordFieldSettings *fieldSettings) +{ + int nIndex; + // if (evaluateVersion(GOldVersion) < evaluateVersion("2.2.2")) + // { + // for (i = 0; i != node.childNodes().count() - 1; i++) + // if (sameText(node.childNodes(i).name(), "o:FieldSetting")) + // readFieldSetting(node.childNodes(i), fieldSettings->Items[i]); + // } + // else + { + GXMLNode child = node.firstChildElement("o:FieldSetting"); + while (!child.isNull()) + { + nIndex = readIntFromXMLAttr(child, "Index"); + readFieldSetting(child, fieldSettings->items(nIndex)); + child = child.nextSiblingElement("o:FieldSetting"); + } + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.11 + 功能:从XML文档中读取显示规则对象 + 参数:node -- XML节点 + rule -- 显示规则对象 +-----------------------------------------------------------------------------*/ +void GLDRecordGridSettingXMLReader::readFieldSetting(const GXMLNode &node, GLDRecordFieldSetting *fieldSetting) +{ + // void result; + + // if (evaluateVersion(GOldVersion) < evaluateVersion("2.2.3")) + // { + // fieldSetting->setDataSourceID(readIntFromXML(node, "a:DataSourceID")); + // fieldSetting->setMergeID(readIntFromXML(node, "a:MergeID")); + // fieldSetting->setEditFieldName(readStrFromXML(node, "a:EditFieldName")); + // fieldSetting->setDisplayExpr(readStrFromXML(node, "a:DisplayExpr")); + // fieldSetting->setSaveFieldName(readStrFromXML(node, "a:SaveFieldName")); + // fieldSetting->setSaveRule(readStrFromXML(node, "a:SaveRule")); + // fieldSetting->setNullValDisplayStr(readStrFromXML(node, "a:NullValDisplayStr")); + // fieldSetting->setExtData(readStrFromXML(node, "a:ExtData")); + // fieldSetting->setEditTextIsDisplayText(readBoolFromXML(node, "a:EditTextIsDisplayText", true)); + // fieldSetting->setIsPasswordChar(readBoolFromXML(node, "a:IsPasswordChar")); + // fieldSetting->setCellIdentity(readStrFromXML(node, "a:CellIdentity")); + // fieldSetting->setVisibleCondition(readStrFromXML(node, "a:VisibleCondition")); + // } + // else + { + fieldSetting->setDataSourceID(readIntFromXMLAttr(node, "DataSourceID")); + fieldSetting->setMergeID(readIntFromXMLAttr(node, "MergeID")); + fieldSetting->setEditFieldName(readStrFromXMLAttr(node, "EditFieldName")); + fieldSetting->setDisplayExpr(readStrFromXMLAttr(node, "DisplayExpr")); + fieldSetting->setSaveFieldName(readStrFromXMLAttr(node, "SaveFieldName")); + fieldSetting->setSaveRule(readStrFromXMLAttr(node, "SaveRule")); + fieldSetting->setNullValDisplayStr(readStrFromXMLAttr(node, "NullValDisplayStr")); + fieldSetting->setExtData(readStrFromXMLAttr(node, "ExtData")); + fieldSetting->setEditTextIsDisplayText(readBoolFromXMLAttr(node, "EditTextIsDisplayText", true)); + fieldSetting->setIsPasswordChar(readBoolFromXMLAttr(node, "IsPasswordChar")); + fieldSetting->setEditorName(readStrFromXMLAttr(node, "EditorName")); + fieldSetting->setCellIdentity(readStrFromXMLAttr(node, "CellIdentity")); + fieldSetting->setVisibleCondition(readStrFromXMLAttr(node, "VisibleCondition")); + } + GXMLNode iNode = node.firstChildElement("o:CellFormat"); + if (!iNode.isNull()) + readCellFormat(iNode, fieldSetting->cellFormat()); + // if (evaluateVersion(GOldVersion) < evaluateVersion("1.0.7")) + // { + // if (fieldSetting->DisplayExpr != "") + // fieldSetting->setDisplayExpr("=" + fieldSetting->DisplayExpr); + // } + iNode = node.firstChildElement("c:ExtPropDefs"); + if (!iNode.isNull()) + readExtPropDefs(iNode, fieldSetting->extPropDefs()); + +} + +//GLDGridSettingXMLBaseWriter + +void GLDGridSettingXMLBaseWriter::writeCellFormat(GXMLNode &node, GLDCellFormat *cellFormat, + GLDHorzAlignment defHorzAlignment) +{ + // assert(cellFormat != NULL); + writeStrToXMLAttr(node, "FontName",cellFormat->fontName(), CDefFontName); + writeIntToXMLAttr(node, "FontSize",cellFormat->fontSize(), DefFontSize); + writeIntToXMLAttr(node, "ForeColor",cellFormat->foreColor(), DefForeColor); + writeIntToXMLAttr(node, "BackColor",cellFormat->backColor(), DefBackColor); + writeIntToXMLAttr(node, "FontStyle", (byte)cellFormat->fontStyle(), 0); + writeIntToXMLAttr(node, "LeftLineWidth",cellFormat->leftLineWidth(), DefLeftLineWidth); + writeIntToXMLAttr(node, "TopLineWidth",cellFormat->topLineWidth(), DefTopLineWidth); + writeIntToXMLAttr(node, "RightLineWidth",cellFormat->rightLineWidth(), DefRightLineWidth); + writeIntToXMLAttr(node, "BottomLineWidth",cellFormat->bottomLineWidth(), DefBottomLineWidth); + writeIntToXMLAttr(node, "DiagonalWidth",cellFormat->diagonalWidth(), DefDiagonalWidth); + writeIntToXMLAttr(node, "AntiDiagonalWidth",cellFormat->antiDiagonalWidth(), DefAntiDiagonalWidth); + writeIntToXMLAttr(node, "HorzAlignment", (int)cellFormat->horzAlignment(), (int)defHorzAlignment); + writeIntToXMLAttr(node, "VertAlignment", (int)cellFormat->vertAlignment(), (int)DefVertAlignment); + writeStrToXMLAttr(node, "FormatStr",cellFormat->formatStr(), CDefFormatStr); + writeBoolToXMLAttr(node, "NullIsZero",cellFormat->nullIsZero(), DefNullIsZero); + writeIntToXMLAttr(node, "LeftMargin",cellFormat->leftMargin(), DefHorzMargin); + writeIntToXMLAttr(node, "RightMargin",cellFormat->rightMargin(), DefHorzMargin); + writeIntToXMLAttr(node, "TopMargin",cellFormat->topMargin(), DefVertMargin); + writeIntToXMLAttr(node, "BottomMargin",cellFormat->bottomMargin(), DefVertMargin); + writeIntToXMLAttr(node, "ImageIndex",cellFormat->imageIndex(), DefImageIndex); + writeIntToXMLAttr(node, "ImageLayout", (int)cellFormat->imageLayout(), (int)CDefImageLayout); + +} + +void GLDGridSettingXMLBaseWriter::writeGridRule(GXMLNode &node, GLDGridRule *rule) +{ + writeStrToXMLAttr(node, "Name", rule->ruleName()); + writeBoolToXMLAttr(node, "Enable", rule->enable()); + writeStrToXML(node, "a:RecordCondition", rule->recordCondition()); + writeStrToXML(node, "a:FieldCondition", rule->fieldCondition()); + switch (rule->ruleType()) + { + case grtClearCell: + writeBoolToXML(node, "a:AllowClear", dynamic_cast(rule)->allowClear(), true); + break; + case grtFont: + { + writeStrToXML(node, "a:FontName", dynamic_cast(rule)->fontName()); + writeIntToXML(node, "a:FontSize", dynamic_cast(rule)->fontSize()); + writeIntToXML(node, "a:FontColor", dynamic_cast(rule)->fontColor()); + writeIntToXML(node, "a:FontStyles", byte(dynamic_cast(rule)->fontStyles())); + } + break; + case grtBackColor: + writeIntToXML(node, "a:BackColor", dynamic_cast(rule)->backColor()); + break; + case grtEditStyle: + writeIntToXML(node, "a:EditStyle", (int)(dynamic_cast(rule)->editStyle())); + break; + case grtBoundLine: + { + writeIntToXML(node, "a:RightLine", dynamic_cast(rule)->rightLine()); + writeIntToXML(node, "a:BottomLine", dynamic_cast(rule)->bottomLine()); + writeIntToXML(node, "a:Diagonal", dynamic_cast(rule)->diagonal()); + writeIntToXML(node, "a:AntiDiagonal", dynamic_cast(rule)->antiDiagonal()); + } + break; + case grtAlignment: + { + writeIntToXML(node, "a:HorzAlignment", (int)(dynamic_cast(rule)->horzAlignment())); + writeIntToXML(node, "a:VertAlignment", (int)(dynamic_cast(rule)->vertAlignment())); + } + break; + case grtMargin: + { + writeIntToXML(node, "a:LeftMargin", dynamic_cast(rule)->leftMargin()); + writeIntToXML(node, "a:RightMargin", dynamic_cast(rule)->rightMargin()); + writeIntToXML(node, "a:TopMargin", dynamic_cast(rule)->topMargin()); + writeIntToXML(node, "a:BottomMargin", dynamic_cast(rule)->bottomMargin()); + } + break; + case grtReadonly: + writeBoolToXML(node, "a:Readonly", dynamic_cast(rule)->readonly()); + break; + case grtCanFocus: + writeBoolToXML(node, "a:CanFocus", dynamic_cast(rule)->canFocus()); + break; + case grtHandleSymbol: + writeBoolToXML(node, "a:HandleSymbol", dynamic_cast(rule)->handleSymbol()); + break; + case grtImage: + { + writeIntToXML(node, "a:ImageIndex", dynamic_cast(rule)->imageIndex()); + writeIntToXML(node, "a:ImageLayout", (int)(dynamic_cast(rule)->imageLayout())); + } + break; + case grtComment: + { + writeBoolToXML(node, "a:ShowComment", dynamic_cast(rule)->showComment()); + writeStrToXML(node, "a:Comment", dynamic_cast(rule)->comment()); + } + break; + case grtVisible: + writeStrToXML(node, "a:InVisibleText", dynamic_cast(rule)->inVisibleText()); + break; + case grtMerge: + writeStrToXML(node, "a:MergeExpr", dynamic_cast(rule)->mergeExpr()); + break; + case grtRejectDelete: + writeIntToXML(node, "a:IsTree", dynamic_cast(rule)->isTree()); + break; + case grtRejectInsert: + { + writeIntToXML(node, "a:IsTree", dynamic_cast(rule)->isTree()); + writeIntToXML(node, "a:IsBefore", dynamic_cast(rule)->isBefore()); + writeStrToXML(node, "a:TableNames", dynamic_cast(rule)->tableNames()); + } + break; + case grtRejectInsertChild: + { + writeIntToXML(node, "a:IsTree", dynamic_cast(rule)->isTree()); + writeIntToXML(node, "a:IsBefore", dynamic_cast(rule)->isBefore()); + writeStrToXML(node, "a:TableNames", dynamic_cast(rule)->tableNames()); + writeIntToXML(node, "a:Level", dynamic_cast(rule)->level()); + } + break; + case grtRejectMove: + { + writeIntToXML(node, "a:IsTree", dynamic_cast(rule)->isTree()); + writeIntToXML(node, "a:IsMoveUp", dynamic_cast(rule)->isMoveUp()); + writeIntToXML(node, "a:IncludeChild", dynamic_cast(rule)->includeChild()); + } + break; + case grtRejectLevel: + { + writeIntToXML(node, "a:IsTree", dynamic_cast(rule)->isTree()); + writeIntToXML(node, "a:IsLevelUp", dynamic_cast(rule)->isLevelUp()); + writeIntToXML(node, "a:IsFixPos", dynamic_cast(rule)->isFixPos()); + + } + break; + case grtEditForm: + writeBoolToXML(node, "a:Enable", dynamic_cast(rule)->enable()); + break; + } +} + +void GLDGridSettingXMLBaseWriter::writeExtPropDefs(GXMLNode &node, CGLDExtPropDefs *extPropDefs) +{ + GXMLNode iNode; + for (int i = 0; i <= extPropDefs->count() - 1; i++) + { + iNode = addChild(node, "o:ExtPropDef"); + writeStrToXMLAttr(iNode, "Code", extPropDefs->itemObjs(i)->code()); + writeStrToXMLAttr(iNode, "Value", extPropDefs->itemObjs(i)->value()); + } +} + +/*GLDGridSettingXMLWriter*/ +void GLDGridSettingXMLWriter::write(const GString &fileName, GLDGridSetting *gridSetting) +{ + GFile file(fileName); + if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) + return; + GXMLDocument iXMLDoc = createXMLDocument(); + write(iXMLDoc, gridSetting); +#ifdef GLD_XML + iXMLDoc.saveToStream(&file); +#else + GTextStream out(&file); + iXMLDoc.save(out, 4); +#endif + file.close(); +} + +void GLDGridSettingXMLWriter::write(GXMLDocument &xmlDoc, GLDGridSetting *gridSetting) +{ + if (xmlDoc.documentElement().isNull()) + { + GXMLNode root = xmlDoc.createElement("o:GridSetting"); + xmlDoc.appendChild(root); + } + GXMLNode oNode = xmlDoc.documentElement(); + write(oNode, gridSetting); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.11 + 功能:保存Grid属性设置对象为XML文档 + 参数:node -- XML节点 + gridSetting -- Grid属性设置对象 +-----------------------------------------------------------------------------*/ +void GLDGridSettingXMLWriter::write(GXMLNode &node, GLDGridSetting *gridSetting) +{ + if (node.isNull()) + return; + + writeStrToXMLAttr(node, "xmlns:a", "attribute"); + writeStrToXMLAttr(node, "xmlns:c", "collection"); + writeStrToXMLAttr(node, "xmlns:o", "object"); + writeStrToXMLAttr(node, "Version", gridSetting->version()); + + writeStrToXMLAttr(node, "Description", gridSetting->description()); + writeStrToXMLAttr(node, "Identity", gridSetting->identity()); + writeStrToXMLAttr(node, "Remark",gridSetting->remark()); + writeIntToXML(node, "a:FixedCols",gridSetting->fixedCols()); + writeIntToXML(node, "a:FixedEditRows",gridSetting->fixedEditRows()); + writeIntToXML(node, "a:FixedEditCols",gridSetting->fixedEditCols()); + writeIntToXML(node, "a:LeftMargin",gridSetting->leftMargin()); + writeIntToXML(node, "a:RightMargin",gridSetting->rightMargin()); + writeIntToXML(node, "a:TopMargin",gridSetting->topMargin()); + writeIntToXML(node, "a:BottomMargin",gridSetting->bottomMargin()); + writeStrToXML(node, "a:InvalidValueLabel",gridSetting->invalidValueLabel()); + writeIntToXML(node, "a:GridLineWidth",gridSetting->gridLineWidth()); + writeIntToXML(node, "a:GridLineColor",gridSetting->gridLineColor()); + writeIntToXML(node, "a:GridColor",gridSetting->gridColor()); + writeIntToXML(node, "a:BoundLineColor",gridSetting->boundLineColor()); + writeBoolToXML(node, "a:AllowSort",gridSetting->allowSort()); + writeBoolToXML(node, "a:AllowCopyPaste",gridSetting->allowCopyPaste(), true); + writeStrToXML(node, "a:SortFieldNames",gridSetting->sortFieldNames()); + writeIntToXML(node, "a:AscImageIndex",gridSetting->ascImageIndex(), -1); + writeIntToXML(node, "a:DescImageIndex",gridSetting->descImageIndex(), -1); + writeBoolToXML(node, "a:ShowAsTree",gridSetting->showAsTree()); + writeBoolToXML(node, "a:Editing",gridSetting->editing(), true); + writeBoolToXML(node, "a:VertLine",gridSetting->vertLine(), true); + writeBoolToXML(node, "a:HorzLine",gridSetting->horzLine(), true); + writeBoolToXML(node, "a:RowSizing",gridSetting->rowSizing()); + writeBoolToXML(node, "a:ColSizing",gridSetting->colSizing(), true); + writeBoolToXML(node, "a:ColMoving",gridSetting->colMoving(), true); + writeBoolToXML(node, "a:AlwaysShowEditor",gridSetting->alwaysShowEditor()); + writeBoolToXML(node, "a:RangeSelect",gridSetting->rangeSelect(), true); + writeBoolToXML(node, "a:AllowSelectRow",gridSetting->allowSelectRow(), true); + writeBoolToXML(node, "a:AllowSelectCol",gridSetting->allowSelectCol(), true); + writeBoolToXML(node, "a:AllowSelectAll",gridSetting->allowSelectAll(), true); + writeBoolToXML(node, "a:MultiSelection",gridSetting->multiSelection(), true); + writeBoolToXML(node, "a:AutoThemeAdapt",gridSetting->autoThemeAdapt(), true); + writeBoolToXML(node, "a:ReturnKeyAsTab",gridSetting->returnKeyAsTab()); + writeBoolToXML(node, "a:ShowFixedRow",gridSetting->showFixedRow(), true); + writeBoolToXML(node, "a:CellFilling",gridSetting->cellFilling()); + writeBoolToXML(node, "a:FixedCellEvent",gridSetting->fixedCellEvent()); + writeBoolToXML(node, "a:Allow3DStyle",gridSetting->allow3DStyle(), true); + writeBoolToXML(node, "a:HideEditOnExit",gridSetting->hideEditOnExit()); + writeBoolToXML(node, "a:BorderStyle",gridSetting->borderStyle(), true); + writeBoolToXML(node, "a:UseBlendColor",gridSetting->useBlendColor(), true); + writeBoolToXML(node, "a:CellFillEditField",gridSetting->cellFillEditField()); + writeBoolToXML(node, "a:TotalRowAtFooter",gridSetting->totalRowAtFooter(), true); + + if (gridSetting->extPropDefs()->count() > 0) + { + GXMLNode oNode = addChild(node, "c:ExtPropDefs"); + writeExtPropDefs(oNode, gridSetting->extPropDefs()); + } + if (gridSetting->colSettings()->count() > 0) + { + GXMLNode oNode = addChild(node, "c:ColSettings"); + writeColSettings(oNode, gridSetting->colSettings()); + } + if (gridSetting->titleRows()->count() > 0) + { + GXMLNode oNode = addChild(node, "c:TitleRows"); + writeTitleRows(oNode, gridSetting->titleRows()); + } + if (gridSetting->filterRows()->count() > 0) + { + GXMLNode oNode = addChild(node, "c:FilterRows"); + writeFilterRows(oNode, gridSetting->filterRows()); + } + if (gridSetting->tableSettings()->count() > 0) + { + GXMLNode oNode = addChild(node, "c:TableSettings"); + writeTableSettings(oNode, gridSetting->tableSettings()); + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.11 + 功能:保存列设置容器对象为XML文档 + 参数:node -- XML节点 + colSettings -- 列设置容器对象 +-----------------------------------------------------------------------------*/ +void GLDGridSettingXMLWriter::writeColSettings(GXMLNode &node, GLDColSettings *colSettings) +{ + for (int i = 0; i <= colSettings->count() - 1; i++) + { + GXMLNode oNode = addChild(node, "o:ColSetting"); + writeColSetting(oNode, colSettings->items(i)); + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.11 + 功能:保存列设置对象为XML文档 + 参数:node -- XML节点 + colSetting -- 列设置对象 +-----------------------------------------------------------------------------*/ +void GLDGridSettingXMLWriter::writeColSetting(GXMLNode &node, GLDColSetting *colSetting) +{ + writeIntToXMLAttr(node, "DisplayWidth", colSetting->displayWidth()); + writeStrToXMLAttr(node, "AutoWrapType", CellSuitTypeToStr(colSetting->cellSuitType()), "cstFixed"); + writeStrToXMLAttr(node, "Identity", colSetting->identity()); + writeStrToXMLAttr(node, "ExtData", colSetting->extData()); + writeStrToXMLAttr(node, "VisibleCondition", colSetting->visibleCondition()); + if (colSetting->extPropDefs()->count() > 0) + { + GXMLNode oNode = addChild(node, "c:ExtPropDefs"); + writeExtPropDefs(oNode, colSetting->extPropDefs()); + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.11 + 功能:保存标题行容器对象为XML文档 + 参数:node -- XML节点 + titleRows -- 标题行容器对象 +-----------------------------------------------------------------------------*/ +void GLDGridSettingXMLWriter::writeTitleRows(GXMLNode &node, GLDTitleRows *titleRows) +{ + for (int i = 0; i <= titleRows->count() - 1; i++) + { + GXMLNode oNode = addChild(node, "o:TitleRow"); + writeTitleRow(oNode, titleRows->items(i)); + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.11 + 功能:保存标题行对象为XML文档 + 参数:node -- XML节点 + titleRow -- 标题行对象 +-----------------------------------------------------------------------------*/ +void GLDGridSettingXMLWriter::writeTitleRow(GXMLNode &node, GLDTitleRow *titleRow) +{ + writeIntToXML(node, "a:RowHeight", titleRow->rowHeight()); + GXMLNode iNode = addChild(node, "c:TitleCells"); + writeTitleCells(iNode, titleRow); + if (!iNode.hasChildNodes()) + node.removeChild(iNode); +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.11 + 功能:保存标题行单元格容器对象为XML文档 + 参数:node -- XML节点 + titleRow -- 标题行对象 +-----------------------------------------------------------------------------*/ +void GLDGridSettingXMLWriter::writeTitleCells(GXMLNode &node, GLDTitleRow *titleRow) +{ + for (int i = 0; i <= titleRow->cellCount() - 1; i++) + { + if (isNullTitleCell(titleRow->cells(i))) + continue; + GXMLNode oNode = addChild(node, "o:TitleCell"); + writeTitleCell(oNode, titleRow->cells(i)); + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.11 + 功能:保存标题单元格对象为XML文档 + 参数:node -- XML节点 + titleCell -- 标题单元格对象 +-----------------------------------------------------------------------------*/ +void GLDGridSettingXMLWriter::writeTitleCell(GXMLNode &node, GLDTitleCell *titleCell) +{ + writeIntToXMLAttr(node, "Index", titleCell->index(), -1); + writeStrToXMLAttr(node, "Caption", titleCell->caption()); + writeIntToXMLAttr(node, "MergeID", titleCell->mergeID()); + if (!isDefaultCellFormat(titleCell->cellFormat(), ghaCenter)) + { + GXMLNode oNode = addChild(node, "o:CellFormat"); + writeCellFormat(oNode, titleCell->cellFormat(), ghaCenter); + } +} + +void GLDGridSettingXMLWriter::writeFilterRows(GXMLNode &node, GLDFilterRows *filterRows) +{ + for (int i = 0; i <= filterRows->count() - 1; i++) + { + GXMLNode oNode = addChild(node, "o:FilterRow"); + writeFilterRow(oNode, filterRows->items(i)); + } +} + +void GLDGridSettingXMLWriter::writeFilterRow(GXMLNode &node, GLDFilterRow *filterRow) +{ + writeIntToXML(node, "a:RowHeight", filterRow->rowHeight()); + GXMLNode iNode = addChild(node, "c:FilterCells"); + writeFilterCells(iNode, filterRow); + if (iNode.hasChildNodes()) + node.removeChild(iNode); +} + +void GLDGridSettingXMLWriter::writeFilterCells(GXMLNode &node, GLDFilterRow *filterRow) +{ + for (int i = 0; i <= filterRow->cellCount() - 1; i++) + { + if (isNullFilterCell(filterRow->cells(i))) + continue; + GXMLNode oNode = addChild(node, "o:FilterCell"); + writeFilterCell(oNode, filterRow->cells(i)); + } +} + +void GLDGridSettingXMLWriter::writeFilterCell(GXMLNode &node, GLDFilterCell *filterCell) +{ + + GLDHorzAlignment eDefHorzAlignment; + writeIntToXMLAttr(node, "Index", filterCell->index(), -1); + writeStrToXMLAttr(node, "Caption", filterCell->caption()); + writeStrToXMLAttr(node, "EditorName", filterCell->editorName()); + writeIntToXMLAttr(node, "MergeID", filterCell->mergeID()); + if (filterCell->isFixedCol()) + eDefHorzAlignment = ghaCenter; + else + eDefHorzAlignment = ghaAuto; + if (!isDefaultCellFormat(filterCell->cellFormat(), eDefHorzAlignment)) + { + GXMLNode oNode = addChild(node, "o:CellFormat"); + writeCellFormat(oNode, filterCell->cellFormat(), eDefHorzAlignment); + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.11 + 功能:保存表设置容器对象为XML文档 + 参数:node -- XML节点 + tableSettings -- 表设置容器对象 +-----------------------------------------------------------------------------*/ +void GLDGridSettingXMLWriter::writeTableSettings(GXMLNode &node, GLDTableSettings *tableSettings) +{ + for (int i = 0; i <= tableSettings->count() - 1; i++) + { + GXMLNode oNode = addChild(node, "o:TableSetting"); + writeTableSetting(oNode, tableSettings->items(i)); + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.11 + 功能:保存表设置对象为XML文档 + 参数:node -- XML节点 + tableSetting -- 表设置对象 +-----------------------------------------------------------------------------*/ +void GLDGridSettingXMLWriter::writeTableSetting(GXMLNode &node, GLDTableSetting *tableSetting) +{ + writeBoolToXML(node, "a:CustomDataSource",tableSetting->customDataSource()); + writeStrToXML(node, "a:MasterViewName",tableSetting->masterViewName()); + writeStrToXML(node, "a:SelfFieldName",tableSetting->selfFieldName()); + writeStrToXML(node, "a:MasterFieldName",tableSetting->masterFieldName()); + writeStrToXML(node, "a:PrimaryKeyFieldName",tableSetting->primaryKeyFieldName()); + writeStrToXML(node, "a:ParentKeyFieldName",tableSetting->parentKeyFieldName()); + writeBoolToXML(node, "a:IsTree",tableSetting->isTree()); + writeBoolToXML(node, "a:IsTreeWithMasterView",tableSetting->isTreeWithMasterView()); + writeIntToXML(node, "a:TotalStyle", (int)tableSetting->totalStyle(), (int)gtsByTree); + writeStrToXML(node, "a:RefTableName",tableSetting->refTableName()); + writeStrToXML(node, "a:RefDatabaseName",tableSetting->refDatabaseName()); + writeIntToXML(node, "a:DefRowHeight",tableSetting->defRowHeight()); + GXMLNode iNode = addChild(node, "c:FieldSettings"); + writeFieldSettings(iNode, tableSetting->fieldSettings()); + if (!iNode.hasChildNodes()) + { + node.removeChild(iNode); + } + + if (tableSetting->rules()->count() > 0) + { + GXMLNode oNode = addChild(node, "c:Rules"); + writeGridRules(oNode, tableSetting->rules()); + } + if (tableSetting->headerRowCount() != 0) + { + iNode = addChild(node, "c:HeaderRows"); + for (int i = 0; i <= tableSetting->headerRowCount() - 1; i++) + { + GXMLNode oNode = addChild(iNode, "o:HeaderRow"); + writeHeaderRowFieldSettings(oNode, tableSetting->headerRows(i)); + } + } + if (tableSetting->totalRowCount() != 0) + { + iNode = addChild(node, "c:TotalRows"); + for (int i = 0; i <= tableSetting->totalRowCount() - 1; i++) + { + GXMLNode oNode = addChild(iNode, "o:TotalRow"); + writeTotalRowFieldSettings(oNode, tableSetting->totalRows(i)); + } + } + + if (tableSetting->extPropDefs()->count() > 0) + { + GXMLNode oNode = addChild(node, "c:ExtPropDefs"); + writeExtPropDefs(oNode, tableSetting->extPropDefs()); + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.11 + 功能:保存字段设置容器对象为XML文档 + 参数:node -- XML节点 + fieldSettings -- 字段设置容器对象 +-----------------------------------------------------------------------------*/ +void GLDGridSettingXMLWriter::writeFieldSettings(GXMLNode &node, GLDFieldSettings *fieldSettings) +{ + for (int i = 0; i <= fieldSettings->count() - 1; i++) + { + if (isNullFieldSetting(fieldSettings->items(i))) + continue; + GXMLNode oNode = addChild(node, "o:FieldSetting"); + writeFieldSetting(oNode, fieldSettings->items(i)); + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.11 + 功能:保存字段设置对象为XML文档 + 参数:node -- XML节点 + fieldSetting -- 字段设置对象 +-----------------------------------------------------------------------------*/ +void GLDGridSettingXMLWriter::writeFieldSetting(GXMLNode &node, GLDFieldSetting *fieldSetting) +{ + GLDHorzAlignment eDefHorzAlignment; + writeIntToXMLAttr(node, "Index", fieldSetting->index(), -1); + writeIntToXMLAttr(node, "MergeID", fieldSetting->mergeID()); + writeStrToXMLAttr(node, "EditFieldName", fieldSetting->editFieldName()); + writeStrToXMLAttr(node, "DisplayExpr", fieldSetting->displayExpr()); + writeStrToXMLAttr(node, "SaveFieldName",fieldSetting->saveFieldName()); + writeStrToXMLAttr(node, "SaveRule",fieldSetting->saveRule()); + writeStrToXMLAttr(node, "NullValDisplayStr",fieldSetting->nullValDisplayStr()); + writeStrToXMLAttr(node, "ExtData",fieldSetting->extData()); + writeBoolToXMLAttr(node, "EditTextIsDisplayText",fieldSetting->editTextIsDisplayText(), true); + writeStrToXMLAttr(node, "EditorName",fieldSetting->editorName()); + if (!fieldSetting->isDefaultCellIdentity()) + writeStrToXMLAttr(node, "CellIdentity", fieldSetting->cellIdentity()); + if (fieldSetting->isFixedCol()) + eDefHorzAlignment = ghaCenter; + else + eDefHorzAlignment = ghaAuto; + if (!isDefaultCellFormat(fieldSetting->cellFormat(), eDefHorzAlignment)) + { + GXMLNode oNode = addChild(node, "o:CellFormat"); + writeCellFormat(oNode, fieldSetting->cellFormat(), eDefHorzAlignment); + } + if (fieldSetting->extPropDefs()->count() > 0) + { + GXMLNode oNode = addChild(node, "c:ExtPropDefs"); + writeExtPropDefs(oNode, fieldSetting->extPropDefs()); + } + +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.11 + 功能:保存呈现规则容器对象为XML文档 + 参数:node -- XML节点 + gridRules -- 呈现规则容器对象 +-----------------------------------------------------------------------------*/ +void GLDGridSettingXMLWriter::writeGridRules(GXMLNode &node, GLDGridRules *gridRules) +{ + GXMLNode iNode; + for (int i = 0; i <= gridRules->count() - 1; i++) + { + iNode = addChild(node, "o:GridRule"); + writeStrToXMLAttr(iNode, "RuleType", GridRuleTypeToStr(gridRules->items(i)->ruleType())); + writeGridRule(iNode, gridRules->items(i)); + } +} + +void GLDGridSettingXMLWriter::writeHeaderRowFieldSettings(GXMLNode &node, + GLDHeaderRowFieldSettings *headerRowFieldSettings) +{ + GXMLNode iNode; + writeIntToXML(node, "a:RowHeight", headerRowFieldSettings->rowHeight()); + iNode = addChild(node, "c:FieldSettings"); + for (int i = 0; i <= headerRowFieldSettings->count() - 1; i++) + { + if (isNullExpandFieldSetting(headerRowFieldSettings->items(i))) + continue; + GXMLNode oNode = addChild(iNode, "o:FieldSetting"); + writeHeaderRowFieldSetting(oNode, headerRowFieldSettings->items(i)); + } + if (!iNode.hasChildNodes()) + node.removeChild(iNode); +} + +void GLDGridSettingXMLWriter::writeHeaderRowFieldSetting(GXMLNode &node, + GLDHeaderRowFieldSetting *headerRowFieldSetting) +{ + writeIntToXMLAttr(node, "Index", headerRowFieldSetting->index(), -1); + writeIntToXMLAttr(node, "MergeID", headerRowFieldSetting->mergeID()); + writeStrToXMLAttr(node, "Value", headerRowFieldSetting->value()); + if (!isDefaultCellFormat(headerRowFieldSetting->cellFormat(), ghaCenter)) + { + GXMLNode oNode = addChild(node, "o:CellFormat"); + writeCellFormat(oNode, headerRowFieldSetting->cellFormat(), ghaCenter); + } +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-16 + 功能: 保存合计行设置容器为XML文档 + 参数: node: GXMLNode &-- XML节点 + totalRowFieldSettings -- 合计行设置容器 +-----------------------------------------------------------------------------*/ +void GLDGridSettingXMLWriter::writeTotalRowFieldSettings(GXMLNode &node, + GLDTotalRowFieldSettings *totalRowFieldSettings) +{ + GXMLNode iNode; + writeIntToXML(node, "a:RowHeight", totalRowFieldSettings->rowHeight()); + iNode = addChild(node, "c:FieldSettings"); + for (int i = 0; i <= totalRowFieldSettings->count() - 1; i++) + { + if (isNullExpandFieldSetting(totalRowFieldSettings->items(i))) + continue; + GXMLNode oNode = addChild(iNode, "o:FieldSetting"); + writeTotalRowFieldSetting(oNode, totalRowFieldSettings->items(i)); + } + if (!iNode.hasChildNodes()) + node.removeChild(iNode); +} + +/*----------------------------------------------------------------------------- + 创建: Liuxd 2005-12-16 + 功能: 保存合计行设置对象为XML文档 + 参数: node: GXMLNode &-- XML节点 + totalRowFieldSettings -- 合计行设置对象 +-----------------------------------------------------------------------------*/ +void GLDGridSettingXMLWriter::writeTotalRowFieldSetting(GXMLNode &node, GLDTotalRowFieldSetting *totalRowFieldSetting) +{ + GLDHorzAlignment eDefHorzAlignment; + writeIntToXMLAttr(node, "Index",totalRowFieldSetting->index(), -1); + writeIntToXMLAttr(node, "MergeID",totalRowFieldSetting->mergeID()); + writeStrToXMLAttr(node, "Value",totalRowFieldSetting->value()); + if (totalRowFieldSetting->isFixedCol()) + eDefHorzAlignment = ghaCenter; + else + eDefHorzAlignment = ghaAuto; + if (!isDefaultCellFormat(totalRowFieldSetting->cellFormat(), eDefHorzAlignment)) + { + GXMLNode oNode = addChild(node, "o:CellFormat"); + writeCellFormat(oNode, totalRowFieldSetting->cellFormat(), eDefHorzAlignment); + } +} + +void GLDRecordGridSettingXMLWriter::write(const GString &fileName, GLDRecordGridSetting *gridSetting, bool encryptData) +{ + GFile file(fileName); + if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) + return; + GXMLDocument iXMLDoc = createXMLDocument(); + write(iXMLDoc, gridSetting); +#ifdef GLD_XML + iXMLDoc.saveToStream(&file); +#else + GTextStream out(&file); + iXMLDoc.save(out, 4); +#endif + file.close(); + Q_UNUSED(encryptData); +} + +void GLDRecordGridSettingXMLWriter::write(GXMLDocument &xmlDoc, GLDRecordGridSetting *gridSetting) +{ + if (xmlDoc.documentElement().isNull()) + { + GXMLNode root = xmlDoc.createElement("o:RecordGridSetting"); + xmlDoc.appendChild(root); + } + GXMLNode oNode = xmlDoc.documentElement(); + write(oNode, gridSetting); +} + +void GLDRecordGridSettingXMLWriter::write(GXMLNode &node, GLDRecordGridSetting *gridSetting) +{ + if (node.isNull()) + return; + + writeStrToXMLAttr(node, "xmlns:a", "attribute"); + writeStrToXMLAttr(node, "xmlns:c", "collection"); + writeStrToXMLAttr(node, "xmlns:o", "object"); + writeStrToXMLAttr(node, "Version", gridSetting->version()); + writeStrToXMLAttr(node, "Description",gridSetting->description()); + writeStrToXMLAttr(node, "Identity",gridSetting->identity()); + writeStrToXMLAttr(node, "Remark",gridSetting->remark()); + writeIntToXML(node, "a:RowCount",gridSetting->rowCount()); + writeIntToXML(node, "a:ColCount",gridSetting->colCount()); + writeStrToXML(node, "a:RowHeights",gridSetting->rowHeightsToStr()); + writeStrToXML(node, "a:ColWidths",gridSetting->colWidthsToStr()); + writeStrToXML(node, "a:MinColWidths",gridSetting->minColWidthsToStr()); + writeStrToXML(node, "a:ColStyles",gridSetting->colStylesToStr()); + writeStrToXML(node, "a:ColIdentitys",gridSetting->colIdentitysToStr()); + writeStrToXML(node, "a:InvalidValueLabel",gridSetting->invalidValueLabel()); + writeIntToXML(node, "a:GridLineWidth",gridSetting->gridLineWidth()); + writeIntToXML(node, "a:GridLineColor",gridSetting->gridLineColor()); + writeIntToXML(node, "a:GridColor",gridSetting->gridColor()); + writeIntToXML(node, "a:BoundLineColor",gridSetting->boundLineColor(), g_clBlack); + writeBoolToXML(node, "a:ShowAsTree",gridSetting->showAsTree()); + writeBoolToXML(node, "a:Editing",gridSetting->editing(), true); + writeBoolToXML(node, "a:VertLine",gridSetting->vertLine(), true); + writeBoolToXML(node, "a:HorzLine",gridSetting->horzLine(), true); + writeBoolToXML(node, "a:RowSizing",gridSetting->rowSizing()); + writeBoolToXML(node, "a:ColSizing",gridSetting->colSizing(), true); + writeBoolToXML(node, "a:ColMoving",gridSetting->colMoving(), true); + writeBoolToXML(node, "a:AlwaysShowEditor",gridSetting->alwaysShowEditor()); + writeBoolToXML(node, "a:RangeSelect",gridSetting->rangeSelect(), true); + writeBoolToXML(node, "a:AllowSelectRow",gridSetting->allowSelectRow(), true); + writeBoolToXML(node, "a:AllowSelectCol",gridSetting->allowSelectCol(), true); + writeBoolToXML(node, "a:AllowSelectAll",gridSetting->allowSelectAll(), true); + writeBoolToXML(node, "a:MultiSelection",gridSetting->multiSelection(), true); + writeBoolToXML(node, "a:AutoThemeAdapt",gridSetting->autoThemeAdapt(), true); + writeBoolToXML(node, "a:ReturnKeyAsTab",gridSetting->returnKeyAsTab()); + writeBoolToXML(node, "a:ShowFixedRow",gridSetting->showFixedRow(), true); + writeBoolToXML(node, "a:CellFilling",gridSetting->cellFilling()); + writeBoolToXML(node, "a:FixedCellEvent",gridSetting->fixedCellEvent()); + writeBoolToXML(node, "a:Allow3DStyle",gridSetting->allow3DStyle(), true); + writeBoolToXML(node, "a:AllowCopyPaste",gridSetting->allowCopyPaste(), true); + writeBoolToXML(node, "a:HideEditOnExit",gridSetting->hideEditOnExit()); + writeBoolToXML(node, "a:BorderStyle",gridSetting->borderStyle(), true); + writeBoolToXML(node, "a:UseBlendColor",gridSetting->useBlendColor(), true); + writeBoolToXML(node, "a:CellFillEditField",gridSetting->cellFillEditField()); + writeIntToXML(node, "a:FixedRows",gridSetting->fixedRows()); + writeIntToXML(node, "a:FixedCols",gridSetting->fixedCols()); + writeIntToXML(node, "a:FixedEditRows",gridSetting->fixedEditRows()); + writeIntToXML(node, "a:FixedEditCols",gridSetting->fixedEditCols()); + writeIntToXML(node, "a:LeftMargin",gridSetting->leftMargin()); + writeIntToXML(node, "a:RightMargin",gridSetting->rightMargin()); + writeIntToXML(node, "a:TopMargin",gridSetting->topMargin()); + writeIntToXML(node, "a:BottomMargin",gridSetting->bottomMargin()); + writeBoolToXML(node, "a:IgnoreInvalidCell",gridSetting->ignoreInvalidCell()); + writeBoolToXML(node, "a:AllowLabelSelection",gridSetting->allowLabelSelection()); + + if (gridSetting->extPropDefs()->count() > 0) + { + GXMLNode oNode = addChild(node, "c:ExtPropDefs"); + writeExtPropDefs(oNode, gridSetting->extPropDefs()); + } + GXMLNode oNode = addChild(node, "c:RecordSettings"); + writeRecordSettings(oNode, gridSetting->recordSettings()); + GXMLNode iNode = addChild(node, "c:FieldSettings"); + writeFieldSettings(iNode, gridSetting->fieldSettings()); + if (!iNode.hasChildNodes()) + node.removeChild(iNode); + +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.11 + 功能:保存呈现规则容器对象为XML文档 + 参数:node -- XML节点 + gridRules -- 呈现规则容器对象 +-----------------------------------------------------------------------------*/ +void GLDRecordGridSettingXMLWriter::writeGridRules(GXMLNode &node, GLDRecordGridRules *gridRules) +{ + GXMLNode iNode; + for (int i = 0; i <= gridRules->count() - 1; i++) + { + iNode = addChild(node, "o:GridRule"); + writeStrToXMLAttr(iNode, "RuleType", GridRuleTypeToStr(gridRules->items(i)->ruleType())); + writeGridRule(iNode, gridRules->items(i)); + } +} + +/*----------------------------------------------------------------------------- + 创建:Tu Jianhua 2005.11.11 + 功能:保存呈现规则对象为XML文档 + 参数:node -- XML节点 + rule -- 呈现规则对象 +-----------------------------------------------------------------------------*/ +void GLDRecordGridSettingXMLWriter::writeFieldSetting(GXMLNode &node, GLDRecordFieldSetting *fieldSetting) +{ + writeIntToXMLAttr(node, "Index",fieldSetting->index(), -1); + writeIntToXMLAttr(node, "DataSourceID",fieldSetting->dataSourceID()); + writeIntToXMLAttr(node, "MergeID",fieldSetting->mergeID()); + writeStrToXMLAttr(node, "EditFieldName",fieldSetting->editFieldName()); + writeStrToXMLAttr(node, "DisplayExpr",fieldSetting->displayExpr()); + writeStrToXMLAttr(node, "SaveFieldName",fieldSetting->saveFieldName()); + writeStrToXMLAttr(node, "SaveRule",fieldSetting->saveRule()); + writeStrToXMLAttr(node, "NullValDisplayStr",fieldSetting->nullValDisplayStr()); + writeStrToXMLAttr(node, "ExtData",fieldSetting->extData()); + writeBoolToXMLAttr(node, "EditTextIsDisplayText",fieldSetting->editTextIsDisplayText(), true); + writeBoolToXMLAttr(node, "IsPasswordChar",fieldSetting->isPasswordChar()); + writeStrToXMLAttr(node, "EditorName",fieldSetting->editorName()); + writeStrToXMLAttr(node, "CellIdentity",fieldSetting->cellIdentity()); + writeStrToXMLAttr(node, "VisibleCondition",fieldSetting->visibleCondition()); + + if (!isDefaultCellFormat(fieldSetting->cellFormat())) + { + GXMLNode oNode = addChild(node, "o:CellFormat"); + writeCellFormat(oNode, fieldSetting->cellFormat()); + } + if (fieldSetting->extPropDefs()->count() > 0) + { + GXMLNode oNode = addChild(node, "c:ExtPropDefs"); + writeExtPropDefs(oNode, fieldSetting->extPropDefs()); + } +} + +void GLDRecordGridSettingXMLWriter::writeFieldSettings(GXMLNode &node, GLDRecordFieldSettings *fieldSettings) +{ + for (int i = 0; i <= fieldSettings->count() - 1; i++) + { + if (isNullFieldSetting(fieldSettings->items(i))) + continue; + GXMLNode oNode = addChild(node, "o:FieldSetting"); + writeFieldSetting(oNode, fieldSettings->items(i)); + } +} + +void GLDRecordGridSettingXMLWriter::writeRecordSetting(GXMLNode &node, GLDRecordSetting *recordSetting) +{ + writeStrToXML(node, "a:RefDatabaseName",recordSetting->refDatabaseName()); + writeStrToXML(node, "a:RefTableName",recordSetting->refTableName()); + + if (recordSetting->rules()->count() > 0) + { + GXMLNode oNode = addChild(node, "c:Rules"); + writeGridRules(oNode, recordSetting->rules()); + } +} + +void GLDRecordGridSettingXMLWriter::writeRecordSettings(GXMLNode &node, GLDRecordSettings *recordSettings) +{ + for (int i = 0; i <= recordSettings->count() - 1; i++) + { + GXMLNode oNode = addChild(node, "o:RecordSetting"); + writeRecordSetting(oNode, recordSettings->items(i)); + } +} + +//#include + +////XMLStreamReader测试,实际工作别使用此类 +//class GLDRecordGridSettingXMLStreamReader: public QXmlStreamReader +//{ +//private: +// void readGridSetting(GLDRecordGridSetting *gridSetting); +// void readRecordSettings(GLDRecordSettings *recordSettings); +// void readRecordSetting(GLDRecordSetting *recordSetting); +// void readRules(GLDRecordGridRules *rules); +// void readGridRule(GLDGridRule *rule); +// void readFieldSettings(GLDRecordGridSetting *gridSetting); +//public: +// void read(const GString fileName, GLDRecordGridSetting *gridSetting); +//public: +// inline GLDRecordGridSettingXMLStreamReader() {} +// inline ~GLDRecordGridSettingXMLStreamReader() {} +//}; + +///* GLDRecordGridSettingXMLStreamReader */ + +//void GLDRecordGridSettingXMLStreamReader::read(const GString fileName, GLDRecordGridSetting *gridSetting) +//{ +// GFile file(fileName); +// if (!file.open(QIODevice::ReadOnly)) +// return; + +// setDevice(&file); +// while (!atEnd()) +// { +// readNext(); +// if (isStartElement()) +// { +// if (sameText(name().toString(), "o:RecordGridSetting")) +// readGridSetting(gridSetting); +// else if (sameText(name().toString(), "a:RowCount")) +// gridSetting->setRowCount(readElementText().toInt()); +// else if (sameText(name().toString(), "c:RecordSettings")) +// readRecordSettings(gridSetting->recordSettings()); +// else if (sameText(name().toString(), "c:FieldSettings")) +// readFieldSettings(gridSetting); + +// } +// else if (isEndElement()) +// { +// // +// } + +// } + +// file.close(); +//} + +//void GLDRecordGridSettingXMLStreamReader::readGridSetting(GLDRecordGridSetting *gridSetting) +//{ +// if (attributes().hasAttribute("Description")) +// gridSetting->setDescription(attributes().value("Description").toString()); + + +//} + +//void GLDRecordGridSettingXMLStreamReader::readRecordSettings(GLDRecordSettings *recordSettings) +//{ +// while (!atEnd()) +// { +// readNext(); +// if (isStartElement() && sameText(name().toString(), "c:RecordSetting")) +// readRecordSetting(recordSettings->insert(-1)); +// else if (isEndElement() && sameText(name().toString(), "c:RecordSettings")) +// return; +// } +//} + +//void GLDRecordGridSettingXMLStreamReader::readRecordSetting(GLDRecordSetting *recordSetting) +//{ +// while (!atEnd()) +// { +// readNext(); +// if (isStartElement() ) +// { +// if (sameText(name().toString(), "a:RefDatabaseName")) +// recordSetting->setRefDatabaseName(readElementText()); +// else if (sameText(name().toString(), "a:RefTableName")) +// recordSetting->setRefTableName(readElementText()); +// else if (sameText(name().toString(), "c:Rules")) +// readRules(recordSetting->rules()); +// } +// if (isEndElement() && sameText(name().toString(), "c:RecordSetting")) +// return; +// readNext(); +// } +//} + +//void GLDRecordGridSettingXMLStreamReader::readRules(GLDRecordGridRules *rules) +//{ +// GLDGridRuleType eRuleType; +// while (!atEnd()) +// { +// readNext(); +// if (isStartElement() && sameText(name().toString(), "o:GridRule")) +// { +// eRuleType = StrToGridRuleType(attributes().value("RuleType").toString()); +// readGridRule(rules->insert(- 1, eRuleType)); +// } +// if (isEndElement() && sameText(name().toString(), "c:Rules")) +// return; +// } +//} + +//void GLDRecordGridSettingXMLStreamReader::readGridRule(GLDGridRule *rule) +//{ +// if (attributes().hasAttribute("Name")) +// rule->setRuleName(attributes().value("name").toString()); +// if (attributes().hasAttribute("Enable")) +// rule->setEnable(sameText(attributes().value("Enable").toString(), "true")); + +// while (!atEnd()) +// { +// readNext(); +// if (isStartElement()) +// { +// if (sameText(name().toString(), "a:FieldCondition")) +// rule->setFieldCondition(readElementText()); +// else if (sameText(name().toString(), "a:RecordCondition")) +// rule->setRecordCondition(readElementText()); +// else if (sameText(name().toString(), "a:AllowClear")) +// dynamic_cast(rule)->setAllowClear(sameText(readElementText(), "true")); +// else if (sameText(name().toString(), "a:FontName")) +// dynamic_cast(rule)->setFontName(readElementText()); +// } +// if (isEndElement() && sameText(name().toString(), "o:GridRule")) +// return; +// } +//} + +//void GLDRecordGridSettingXMLStreamReader::readFieldSettings(GLDRecordGridSetting *gridSetting) +//{ +// G_UNUSED(gridSetting); +//} + diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDIniFiles.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDIniFiles.cpp new file mode 100644 index 00000000..20803b90 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDIniFiles.cpp @@ -0,0 +1,966 @@ +#include +#include "GLDStream.h" +#include "GLDFile.h" +#include "GLDTextStream.h" +#include "GLDIniFiles.h" +#include "GLDStrUtils.h" +#include "GLDFileUtils.h" +#include "GLDException.h" + +class GLDCustomIniFilePrivate +{ +public: + GLDCustomIniFilePrivate(GLDCustomIniFile *parent = 0) + : q_ptr(parent) + { + } + +private: + GLDCustomIniFile * const q_ptr; + Q_DECLARE_PUBLIC(GLDCustomIniFile); + GString m_fileName; +}; + +/*GLDCustomIniFile*/ +GLDCustomIniFile::GLDCustomIniFile(const GString &fileName):d_ptr(new GLDCustomIniFilePrivate(this)) +{ + Q_D(GLDCustomIniFile); + d->m_fileName = fileName; +} + +GLDCustomIniFile::GLDCustomIniFile(const GString &fileName, GLDCustomIniFilePrivate &d_private) + : d_ptr(&d_private) +{ + Q_D(GLDCustomIniFile); + d->m_fileName = fileName; +} + +GLDCustomIniFile::~GLDCustomIniFile() +{ + Q_D(GLDCustomIniFile); + delete d; +} + +bool GLDCustomIniFile::sectionExists(const GString §ion) +{ + GStringObjectList strObjList; + bool result = false; + try + { + readSection(section, &strObjList); + result = strObjList.size() > 0; + } + catch(...) + { + strObjList.clear(); + throw; + } + strObjList.clear(); + return result; +} + +long GLDCustomIniFile::readInteger(const GString §ion, const GString &ident, long defVal) +{ + GString intStr = readString(section, ident, ""); + if ((length(intStr) > 2) && (intStr[0].toLatin1() == '0') + && ((intStr[1].toLatin1() == 'X') || (intStr[1].toLatin1() == 'x'))) + { + intStr = "$" + copy(intStr, 2); + } + return strToIntDef(intStr, defVal); +} + +void GLDCustomIniFile::writeInteger(const GString §ion, const GString &ident, long value) +{ + writeString(section, ident, intToStr(value)); +} + +bool GLDCustomIniFile::readBool(const GString §ion, const GString &ident, bool defVal) +{ + return readInteger(section, ident, defVal) != 0; +} + +void GLDCustomIniFile::writeBool(const GString §ion, const GString &ident, bool value) +{ + writeString(section, ident, boolToStr(value, false)); +} + +int GLDCustomIniFile::readBinaryStream(const GString §ion, const GString &name, GStream *value) +{ + GString text = readString(section, name, ""); + int result = 0; + if (text != "") + { + int nPos = value->pos(); + GByteArray array = GByteArray::fromHex(text.toLatin1()); + value->write(array); + result = value->size() - nPos; + } + return result; +} + +void GLDCustomIniFile::writeBinaryStream(const GString §ion, const GString &name, GStream *value) +{ + int nSize = value->size() - value->pos(); + GString text(nSize * 2, Qt::Uninitialized); + if (length(text) > 0) + { + text = GString::fromLatin1(value->read(nSize).toHex()); + } + writeString(section, name, text); +} + +GDate GLDCustomIniFile::readDate(const GString §ion, const GString &name, GDate &defVal) +{ + GString dateStr = readString(section, name, ""); + GDate result = defVal; + if (dateStr != "") + { + try + { + result = GDate::fromString(dateStr); + } + catch(...) + { + throw; + } + } + return result; +} + +void GLDCustomIniFile::writeDate(const GString §ion, const GString &name, GDate &value) +{ + writeString(section, name, value.toString()); +} + +GDateTime GLDCustomIniFile::readDateTime(const GString §ion, const GString &name, GDateTime &defVal) +{ + GString dateStr = readString(section, name, ""); + GDateTime result = defVal; + if (dateStr != "") + { + try + { + result = strToDateTime(dateStr); + } + catch(...) + { + throw; + } + } + return result; +} + +void GLDCustomIniFile::writeDateTime(const GString §ion, const GString &name, GDateTime &value) +{ + writeString(section, name, dateTimeToStr(value)); +} + +double GLDCustomIniFile::readFloat(const GString §ion, const GString &name, double defVal) +{ + GString floatStr = readString(section, name, ""); + double result = defVal; + if (floatStr != "") + { + try + { + result = strToFloat(floatStr); + } + catch(...) + { + throw; + } + } + return result; +} + +void GLDCustomIniFile::writeFloat(const GString §ion, const GString &name, double value) +{ + writeString(section, name, floatToStr(value)); +} + +GTime GLDCustomIniFile::readTime(const GString §ion, const GString &name, GTime &defVal) +{ + GString timeStr = readString(section, name, ""); + GTime result = defVal; + if (timeStr != "") + { + try + { + result = GTime::fromString(timeStr); + } + catch(...) + { + throw; + } + } + return result; +} + +void GLDCustomIniFile::writeTime(const GString §ion, const GString &name, GTime &value) +{ + writeString(section, name, value.toString()); +} + +void GLDCustomIniFile::readSections(const GString §ion, GStringObjectList *strings) +{ + readSections(strings); + for (int i = strings->count() - 1; i >= 0; i--) + { + if (!sameText(section, copy(strings->at(i)->str, 0, length(section)))) + strings->removeAt(i); + } +} + +bool GLDCustomIniFile::valueExists(const GString §ion, const GString &ident) +{ + GStringObjectList strTmp; + readSection(section, &strTmp); + return strTmp.indexOf(ident) > -1; +} + +void GLDCustomIniFile::setFileName(const GString &fileName) +{ + Q_D(GLDCustomIniFile); + d->m_fileName = fileName; +} + +GString GLDCustomIniFile::fileName() +{ + Q_D(GLDCustomIniFile); + return d->m_fileName; +} + +/*GLDIniFile*/ +GLDIniFile::GLDIniFile(const GString &fileName) : GLDCustomIniFile(fileName) +{ +} + +GLDIniFile::~GLDIniFile() +{ + updateFile(); +} + +GString GLDIniFile::readString(const GString §ion, const GString &ident, const GString &defVal) +{ + const int c_BufSize = 2048; + char *buffer = new char[c_BufSize]; + memset(buffer, 0, c_BufSize); + + int nSize = getPrivateProfileString(section, ident, defVal, buffer, c_BufSize, fileName()); + char *newBuffer = new char[1024]; + memcpy(newBuffer, buffer, nSize); + newBuffer[nSize] = '\0'; + GString result = GString::fromLocal8Bit(newBuffer); + delete newBuffer; + delete buffer; + return result; +} + +void GLDIniFile::writeString(const GString §ion, const GString &ident, const GString &value) +{ + if (!writePrivateProfileString(section, ident, value, fileName())) + throw GLDException(format("Unable to write to %s", fileName()));//??tr +} + +void GLDIniFile::readSection(const GString §ion, GStringObjectList *strings) +{ + const int c_BufSize = 16384; + char *buffer = new char[c_BufSize]; + memset(buffer, 0, c_BufSize); + try + { + strings->clear(); + if (getPrivateProfileString(section, "", "", buffer, c_BufSize, fileName()) != 0) + { + char *tmpP = buffer; + while (*tmpP != '\0') + { + strings->add(GString::fromLocal8Bit(tmpP)); + tmpP += strlen(tmpP) + 1; + } + } + } + catch(...) + { + freeAndNil(buffer); + throw; + } + freeAndNil(buffer); +} + +void GLDIniFile::readSections(GStringObjectList *strings) +{ + const int c_BufSize = 16384; + char *buffer = new char[c_BufSize]; + memset(buffer, 0, c_BufSize); + try + { + strings->clear(); + if (getPrivateProfileString("", "", "", buffer, c_BufSize, fileName()) != 0) + { + char *tmpP = buffer; + while (*tmpP != '\0') + { + strings->add(GString::fromLocal8Bit(tmpP)); + tmpP += strlen(tmpP) + 1; + } + } + } + catch(...) + { + freeAndNil(buffer); + throw; + } + freeAndNil(buffer); +} + +void GLDIniFile::readSectionValues(const GString §ion, GStringObjectList *strings) +{ + GStringObjectList keyList; + readSection(section, &keyList); + strings->clear(); + for (int i = 0; i < keyList.count(); i++) + { + strings->add(keyList.at(i)->str + "=" + readString(section, keyList.at(i)->str, "")); + } +} + +void GLDIniFile::eraseSection(const GString §ion) +{ + if (!writePrivateProfileString(section, "", "", fileName())) + { + throw GLDException(format("Unable to write to %s", fileName())); + } +} + +void GLDIniFile::deleteKey(const GString §ion, const GString &ident) +{ + writePrivateProfileString(section, ident, "", fileName()); +} + +void GLDIniFile::updateFile() +{ + writePrivateProfileString("", "", "", fileName()); +} + +int GLDIniFile::strCopy(const GString &source, char *dest, int size) +{ + GByteArray temp = source.toLocal8Bit(); + //拷贝字符串; + //size合适,返回不加'/0'的字符串长度 + int nStrLength = temp.size(); + if ((size == -1) || (nStrLength <= size - 1)) + { + memcpy(dest, temp.data(), nStrLength); + dest[nStrLength] = '\0'; + return nStrLength; + } + //拷贝字符串; + //size过小,返回size-1 + else + { + memcpy(dest, temp.data(), size - 1); + dest[size - 1] = '\0'; + return size - 1; + } +} + +int GLDIniFile::getPrivateProfileString(const GString &strSectionName, const GString &strKeyName, + GString strDefault, char *pReturnedValue, int size, const GString &strFileName) +{ + //设置默认返回字符串 + if (strDefault == NULL) + { + strDefault = ""; + } + //文件不存在,返回默认字符串及其长度 + if (!GFileStream::exists(strFileName)) + { + return strCopy(strDefault, pReturnedValue, size); + } + + GFileStream readFile(strFileName); + + //打开失败,返回默认字符串及其长度 + if (!readFile.open(GStream::ReadOnly)) + { + return strCopy(strDefault, pReturnedValue, size); + } + GTextStream readStream(&readFile); + + if ((strSectionName != "") && (strKeyName != "")) + { + GString strSection("[" + strSectionName + "]"); + GString strKey(strKeyName + "="); + + while (!readStream.atEnd()) + { + GString line(readStream.readLine()); + if (line.indexOf(strSection) == 0) //找到Section + { + line = readStream.readLine(); + while (line.indexOf(strKey) != 0 && line.indexOf("[") != 0 && !readStream.atEnd()) + { + line = readStream.readLine(); + } + if (line.indexOf(strKey) == 0) //找到Key + { + GString source(line.mid(strKey.length())); + readFile.close(); + return strCopy(source, pReturnedValue, size); + } + } + } + readFile.close(); + //未找到,返回默认值及其长度 + return strCopy(strDefault, pReturnedValue, size); + } + else + { + char *tmpP = pReturnedValue; + int nPos = 0; + if (strSectionName == "") //读取所有小结名 + { + while (!readStream.atEnd()) + { + GString line(readStream.readLine()); + if (line.indexOf("[") == 0) // 找到section + { + line = line.mid(1, line.length() - 2); + nPos = strCopy(line, tmpP); + tmpP[++nPos] = '\0'; + tmpP += nPos; + } + } + } + else if (strKeyName == "") + { + GString strSection("[" + strSectionName + "]"); + while (!readStream.atEnd()) + { + GString line(readStream.readLine()); + if (line.indexOf(strSection) == 0) //找到Section + { + line = readStream.readLine(); + while (line.indexOf("[") != 0) + { + GString sKey = copy(line, 0, pos("=", line)); + nPos = strCopy(sKey, tmpP); + tmpP[++nPos] = '\0'; + tmpP += nPos; + if (readStream.atEnd()) + break; + line = readStream.readLine(); + } + } + } + } + tmpP[++nPos] = '\0'; + readFile.close(); + return nPos; + } +} + +bool GLDIniFile::writePrivateProfileString(const GString &strSectionName, const GString &strKeyName, + const GString &strValue, const GString &strFileName) +{ + bool result = false; + + //section是null则直接返回false + if (strSectionName.length() == 0) + { + return result; + } + + bool bFlagFindSection = false;//是否找到了section + GString strSection("[" + strSectionName + "]"); + GString strKey(strKeyName + "="); + + //文件不存在,则创建,且直接写入 + if (!GFileStream::exists(strFileName)) + { + GFileStream createFile(strFileName); + if (!createFile.open(GStream::WriteOnly)) + { + return result; + } + //如果key不是null,才写内容 + if (!strKeyName.isEmpty()) + { + GTextStream createStream(&createFile); + createStream << strSection << "\r\n"; + createStream << strKey << strValue << "\r\n"; + createStream.flush(); + + result = true; + } + createFile.close(); + return result; + } + + GFileStream readFile(strFileName); + + if (!readFile.open(GStream::ReadOnly)) + { + result = false; + return result; + } + + GFileStream writeFile(strFileName); + + //读入流和写入流 + //写入流文件在最后才WriteOnly打开 + GTextStream readStream(&readFile); + GTextStream writeStream(&writeFile); + + //查找每一行是否包含section + while (!readStream.atEnd()) + { + GString line(readStream.readLine()); + + if (line.indexOf(strSection) == -1) //该行不包含section,直接写入流 + { + writeStream << line << "\r\n"; + } + else + { + bFlagFindSection = true; //查到section + result = true; + + //key是null,则跳过该section,写入其余section + if (strKeyName.isEmpty()) + { + do //跳过该section + { + line = GString(readStream.readLine()); + } while (line.indexOf("[") != 0 && !readStream.atEnd()); + + if (readStream.atEnd()) + { + break; + } + else //写入其余section + { + writeStream << line << "\r\n"; + while (!readStream.atEnd()) + { + writeStream << readStream.readLine() << "\r\n"; + } + break; + } + } + + writeStream << line << "\r\n";//section写入流 + line = GString(readStream.readLine()); + while (line.indexOf(strKey) != 0 && line.indexOf("[") != 0) + { + writeStream << line << "\r\n"; + if (!readStream.atEnd()) + line = GString(readStream.readLine()); + else + break; + } + if (readStream.atEnd())//文件末尾,若value!=null则直接加上key + { + //直接加上 + if (!strValue.isEmpty()) + { + writeStream << strKey << strValue << "\r\n"; + } + } + else if (line.indexOf("[") == 0)//查到下一个section,若value!=null则在下一个section前直接加上key + { + if (!strValue.isEmpty()) + { + writeStream << strKey << strValue << "\r\n"; + } + writeStream << line << "\r\n"; + while (!readStream.atEnd()) //剩余行写入流中 + { + writeStream << readStream.readLine() << "\r\n"; + } + break; + } + else if (line.indexOf(strKeyName) == 0)//查到key,若value!=null则修改value + { + if (!strValue.isEmpty()) + { + line = line.mid(0, line.indexOf("=") + 1) + strValue; + writeStream << line << "\r\n"; + } + while (!readStream.atEnd()) //剩余行写入流中 + { + writeStream << readStream.readLine() << "\r\n"; + } + break; + } + } + } + if (!bFlagFindSection)//若未查到该section,且key和value!=null,写入section和key=value + { + if (!strKeyName.isEmpty()) + { + writeStream << strSection << "\r\n"; + writeStream << strKey << strValue << "\r\n"; + result = true; + } + } + readFile.close(); + + //写打开文件 + if (!writeFile.open(GStream::WriteOnly)) + { + result = false; + return result; + } + writeStream.flush();//写入流到文件 + + writeFile.close(); + return result; +} + +class GLDMemIniFilePrivate : public GLDCustomIniFilePrivate +{ +public: + GLDMemIniFilePrivate(GLDMemIniFile *parent = 0) + : q_ptr(parent), m_sections(new GHashedStringObjectList), m_allowValueHasSpace(false) + { + //m_sections = new GHashedStringObjectList; + //m_allowValueHasSpace = false; + } + +private: + GLDMemIniFile * const q_ptr; + Q_DECLARE_PUBLIC(GLDMemIniFile); + GStringObjectList *m_sections; + bool m_allowValueHasSpace; +}; + +GLDMemIniFile::GLDMemIniFile(const GString &fileName) + : GLDCustomIniFile(fileName, (*new GLDMemIniFilePrivate(this))) +{ +#ifndef WIN32 + Q_D(GLDMemIniFile); + d->m_sections->setCaseSensitive(true); +#endif + loadValues(); +} + +GLDMemIniFile::~GLDMemIniFile() +{ + Q_D(GLDMemIniFile); + if (d->m_sections) + { + clear(); + } + freeAndNil(d->m_sections); +} + +void GLDMemIniFile::clear() +{ + Q_D(GLDMemIniFile); + for (int i = 0; i < d->m_sections->count(); ++i) + { + GStringObjectList* list = (GStringObjectList*)(d->m_sections->object(i)); + freeAndNil(list); + } + d->m_sections->clear(); +} + +void GLDMemIniFile::deleteKey(const GString §ion, const GString &ident) +{ + Q_D(GLDMemIniFile); + int nIndex = d->m_sections->indexOf(section); + if (nIndex >= 0) + { + GStringObjectList *strings = (GStringObjectList*)(d->m_sections->object(nIndex)); + int nNameIndex = strings->indexOfName(ident); + if (nNameIndex >= 0) + { + strings->Delete(nNameIndex); + } + } +} + +void GLDMemIniFile::eraseSection(const GString §ion) +{ + Q_D(GLDMemIniFile); + int nIndex = d->m_sections->indexOf(section); + if (nIndex >= 0) + { + GStringObjectList *strings = (GStringObjectList*)(d->m_sections->object(nIndex)); + freeAndNil(strings); + d->m_sections->Delete(nIndex); + } +} + +void GLDMemIniFile::strings(GStringObjectList *list) +{ + list->beginUpdate(); + try + { + Q_D(GLDMemIniFile); + for (int i = 0; i < d->m_sections->count(); ++i) + { + list->add("[" + d->m_sections->at(i)->str + "]"); + GStringObjectList *strings = (GStringObjectList*)(d->m_sections->object(i)); + for (int j = 0; j < strings->count(); ++j) + { + list->add(strings->at(j)->str); + } + list->add(""); + } + } + catch(...) + { + list->endUpdate(); + throw; + } + list->endUpdate(); +} + +void GLDMemIniFile::readSection(const GString §ion, GStringObjectList *strings) +{ + strings->beginUpdate(); + try + { + strings->clear(); + Q_D(GLDMemIniFile); + int nIndex = d->m_sections->indexOf(section); + if (nIndex >= 0) + { + GStringObjectList *sectionStrings = (GStringObjectList*)(d->m_sections->object(nIndex)); + for (int j = 0; j < sectionStrings->count(); ++j) + { + strings->add(sectionStrings->names(j)); + } + } + } + catch(...) + { + strings->endUpdate(); + throw; + } +} + +void GLDMemIniFile::readSections(GStringObjectList *strings) +{ + Q_D(GLDMemIniFile); + strings->assign(d->m_sections); +} + +void GLDMemIniFile::readSectionValues(const GString §ion, GStringObjectList *strings) +{ + strings->beginUpdate(); + try + { + strings->clear(); + Q_D(GLDMemIniFile); + int nIndex = d->m_sections->indexOf(section); + if (nIndex >= 0) + { + strings->assign((GStringObjectList*)(d->m_sections->object(nIndex))); + } + } + catch(...) + { + strings->endUpdate(); + throw; + } + strings->endUpdate(); +} + +GString GLDMemIniFile::readString(const GString §ion, const GString &ident, const GString &Default) +{ + Q_D(GLDMemIniFile); + int nIndex = d->m_sections->indexOf(section); + if (nIndex >= 0) + { + GStringObjectList *strings = (GStringObjectList*)(d->m_sections->object(nIndex)); + int nIndex = strings->indexOfName(ident); + if (nIndex >= 0) + { + return copy(strings->at(nIndex)->str, ident.length() + 1, MaxInt); + } + } + return Default; +} + +void GLDMemIniFile::rename(const GString &fileName, bool reload) +{ + setFileName(fileName); + if (reload) + { + loadValues(); + } +} + +void GLDMemIniFile::setStrings(GStringObjectList *list) +{ + clear(); + GStringObjectList *strings = NULL; + + Q_D(GLDMemIniFile); + for (int i = 0; i < list->count(); ++i) + { + GString strTrim; + if (d->m_allowValueHasSpace) + { + strTrim = trimLeft(list->at(i)->str); + } + else + { + strTrim = trim(list->at(i)->str); + } + if ((strTrim.length() > 0) && (strTrim.at(0).toLatin1() != ';')) + { + if ((strTrim.at(0).toLatin1() == '[') && (strTrim.at(strTrim.length() - 1).toLatin1() == ']')) + { + strTrim = copy(strTrim, 1, strTrim.length() - 2); + strings = addSection(trim(strTrim)); + } + else + { + if (strings != NULL) + { + int nPos = pos("=", strTrim); + // remove spaces before and after '=' + if (nPos >= 0) + { + if (d->m_allowValueHasSpace) + { + strings->add(trim(copy(strTrim, 0, nPos)) + "=" + copy(strTrim, nPos + 1, MaxInt)); + } + else + { + strings->add(trim(copy(strTrim, 0, nPos)) + "=" + trim(copy(strTrim, nPos + 1, MaxInt))); + } + } + else + { + strings->add(strTrim); + } + } + } + } + } +} + +void GLDMemIniFile::updateFile() +{ + GStringObjectList *list = new GStringObjectList(); + try + { + strings(list); + list->saveToFile(fileName()); + } + catch(...) + { + freeAndNil(list); + throw; + } + freeAndNil(list); +} + +void GLDMemIniFile::writeString(const GString §ion, const GString &ident, const GString &value) +{ + GStringObjectList *strings = NULL; + + Q_D(GLDMemIniFile); + int nIndex = d->m_sections->indexOf(section); + if (nIndex >= 0) + { + strings = (GStringObjectList *)(d->m_sections->object(nIndex)); + } + else + { + strings = addSection(section); + } + GString strTmp = ident + "=" + value; + nIndex = strings->indexOfName(ident); + if (nIndex >= 0) + { + strings->at(nIndex)->str = strTmp; + } + else + { + strings->add(strTmp); + } +} + +GStringObjectList *GLDMemIniFile::addSection(const GString §ion) +{ + GHashedStringObjectList *result = new GHashedStringObjectList(); + try + { + Q_D(GLDMemIniFile); + result->setCaseSensitive(caseSensitive()); + d->m_sections->addObject(section, result); + } + catch(...) + { + freeAndNil(result); + throw; + } + return result; +} + +bool GLDMemIniFile::caseSensitive() +{ + Q_D(GLDMemIniFile); + return d->m_sections->caseSensitive(); +} + +void GLDMemIniFile::setCaseSensitive(bool value) +{ + Q_D(GLDMemIniFile); + if (value != d->m_sections->caseSensitive()) + { + d->m_sections->setCaseSensitive(value); + for (int i = 0; i < d->m_sections->count(); ++i) + { + GHashedStringObjectList* hashList = (GHashedStringObjectList*)(d->m_sections->object(i)); + hashList->setCaseSensitive(value); + hashList->changed(); + ((GHashedStringObjectList*)(d->m_sections))->changed(); + } + } +} + +void GLDMemIniFile::loadValues() +{ + if ((fileName().length() > 0) && fileExists(fileName())) + { + GStringObjectList *list = new GStringObjectList(); + try + { + list->loadFromFile(fileName()); + setStrings(list); + } + catch(...) + { + freeAndNil(list); + throw; + } + freeAndNil(list); + } + else + { + clear(); + } +} + +bool GLDMemIniFile::allowValueHasSpace() +{ + Q_D(GLDMemIniFile); + return d->m_allowValueHasSpace; +} + +void GLDMemIniFile::setAllowValueHasSpace(bool allowValueHasSpace) +{ + Q_D(GLDMemIniFile); + d->m_allowValueHasSpace = allowValueHasSpace; + loadValues(); +} + diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDJSONUtils.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDJSONUtils.cpp new file mode 100644 index 00000000..64b25f31 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDJSONUtils.cpp @@ -0,0 +1,188 @@ +#include "GLDJSONUtils.h" +#include "GLDStrUtils.h" +#include "GLDMathUtils.h" + +#include "GLDFile.h" +#include "GLDTextStream.h" + +void saveJSONDocument(GJsonDocument &doc, const GString &fileName) +{ + GFileStream file(fileName); + if (!file.open(QIODevice::WriteOnly)) + { + return; + } + QTextStream oStream(&file); + oStream << doc.toJson(); + file.close(); +} + + +void saveJSONDocument(GJsonDocument &doc, QTextStream &stream) +{ + stream << doc.toJson(); +} + +GString readStrFromJSON(const GJsonObject &jsonObject, const GString &jsonObjectKey, const GString &defVal) +{ + if (jsonObject.contains(jsonObjectKey)) + { + return jsonObject.find(jsonObjectKey).value().toString(defVal); + } + else + { + return defVal; + } +} + +bool readBoolFromJSON(const GJsonObject &jsonObject, const GString &jsonObjectKey, bool defVal) +{ + if (jsonObject.contains(jsonObjectKey)) + return jsonObject.find(jsonObjectKey).value().toBool(defVal); + else + return defVal; +} + +int readIntFromJSON(const GJsonObject &jsonObject, const GString &jsonObjectKey, int defVal) +{ + if (jsonObject.contains(jsonObjectKey)) + return jsonObject.find(jsonObjectKey).value().toDouble(defVal); + else + return defVal; +} + +gint64 readInt64FromJSON(const GJsonObject &jsonObject, const GString &jsonObjectKey, long long defVal) +{ + // 在 GJsonValue 中我们使用 string 来存储 int64; + if (jsonObject.contains(jsonObjectKey)) + { + GString sDefValue = int64ToStr(defVal); + GString sResult = jsonObject.find(jsonObjectKey).value().toString(sDefValue); + return strToInt64Def(sResult, defVal); + } + else + return defVal; +} + +guint64 readUInt64FromJSON(const GJsonObject &jsonObject, const GString &jsonObjectKey, guint64 defVal) +{ + // 在 GJsonValue 中我们使用 string 来存储 int64; + if (jsonObject.contains(jsonObjectKey)) + { + GString sDefValue = uint64ToStr(defVal); + GString sResult = jsonObject.find(jsonObjectKey).value().toString(sDefValue); + return strToUInt64Def(sResult, defVal); + } + else + return defVal; +} + +double readFloatFromJSON(const GJsonObject &jsonObject, const GString &jsonObjectKey, double defVal) +{ + if (jsonObject.contains(jsonObjectKey)) + { + return jsonObject.find(jsonObjectKey).value().toDouble(defVal); + } + else + return defVal; +} + +void writeStrToJSON(GJsonObject &jsonObject, const GString &jsonObjectKey, const GString &value, const GString &defVal) +{ + if (value == defVal) + return; + jsonObject.insert(jsonObjectKey, value); +} + +void writeBoolToJSON(GJsonObject &jsonObject, const GString &jsonObjectKey, bool value, bool defVal) +{ + if (value == defVal) + return; + jsonObject.insert(jsonObjectKey, value); +} + +void writeIntToJSON(GJsonObject &jsonObject, const GString &jsonObjectKey, int value, int defVal) +{ + if (value == defVal) + return; + jsonObject.insert(jsonObjectKey, value); +} + +void writeInt64ToJSON(GJsonObject &jsonObject, const GString &jsonObjectKey, long long value, long long defVal) +{ + if (value == defVal) + return; + + writeStrToJSON(jsonObject, jsonObjectKey, int64ToStr(value)); +} + +void writeUInt64ToJSON(GJsonObject &jsonObject, const GString &jsonObjectKey, guint64 value, guint64 defVal) +{ + if (value == defVal) + return; + + writeStrToJSON(jsonObject, jsonObjectKey, uint64ToStr(value)); +} + +void writeFloatToJSON(GJsonObject &jsonObject, const GString &jsonObjectKey, double value, double defVal) +{ + if (sameValue(value, defVal)) + return; + + jsonObject.insert(jsonObjectKey, value); +} + +GJsonDocument loadJSONDocument(const GString &fileName) +{ + GFile oJsonFile(fileName); + if (!oJsonFile.exists()) + { + return GJsonDocument(); + } + if (!oJsonFile.open(QIODevice::ReadOnly | QIODevice::Text)) + { + return GJsonDocument(); + } + QTextStream oStream(&oJsonFile); + return loadJSONDocument(oStream); +} + +GJsonDocument loadJSONDocument(QTextStream &stream) +{ + GString sJson = stream.readAll(); + if (sJson.isEmpty()) + { + return GJsonDocument(); + } + return GJsonDocument::fromJson(sJson.toUtf8()); +} + + +GString readEnCodeStrFromJSON(const GJsonObject &jsonObject, const GString &jsonObjectKey, const GString &defVal) +{ + if (jsonObject.contains(jsonObjectKey)) + { + GString sValue = jsonObject.find(jsonObjectKey).value().toString(); + if (!sValue.isEmpty()) + { + QByteArray bValue = sValue.toLatin1(); + bValue = QByteArray::fromBase64(bValue); + return QString::fromLocal8Bit(bValue); + } + else + return defVal; + } + else + { + return defVal; + } +} + + +void writeEnCodeStrToJSON(GJsonObject &jsonObject, const GString &jsonObjectKey, const GString &value, const GString &defVal) +{ + if (value == defVal) + return; + GByteArray bValue = value.toLocal8Bit(); + jsonObject.insert(jsonObjectKey, GString(bValue.toBase64())); +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDMD5.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDMD5.cpp new file mode 100644 index 00000000..e9f8f8e1 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDMD5.cpp @@ -0,0 +1,366 @@ +/* + * This code implements the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an + * MD5Context structure, pass it to MD5Init, call MD5Update as + * needed on buffers full of bytes, and then call MD5Final, which + * will fill a supplied 16-byte array with the digest. + * + * Changed so as no longer to depend on Colin Plumb's `usual.h' header + * definitions; now uses stuff from dpkg's config.h. + * - Ian Jackson . + * Still in the public domain. + */ + +#include "GLDMD5.h" +#include "GLDGlobal.h" +#include "GLDStrUtils.h" +#include "GLDFile.h" + +#include /* for memcpy() */ +#ifndef _WIN32_WCE +#include /* for stupid systems */ +#else +#include +#include +#endif + +GString getMD5(const char *buffer, size_t bufSize) +{ + md5byte arrMD5Digest[16]; + for (int i = 0; i != 16; ++i) + { + arrMD5Digest[i] = i + 1; + } + MD5Context oMD5Context; + MD5Init(&oMD5Context); + MD5UpdateBuffer(&oMD5Context, buffer, bufSize); + MD5Final(&oMD5Context, arrMD5Digest); + GString result; + for (int i = 0; i != 16; ++i) + { + result.append(intToHex(arrMD5Digest[i], 2)); + } + return result; +} + +GString getMD5(GStream *stream) +{ + md5byte arrMD5Digest[16]; + for (int i = 0; i != 16; ++i) + { + arrMD5Digest[i] = i + 1; + } + MD5Context oMD5Context; + MD5Init(&oMD5Context); + MD5UpdateBuffer(&oMD5Context, stream); + MD5Final(&oMD5Context, arrMD5Digest); + GString result; + for (int i = 0; i != 16; ++i) + { + result.append(intToHex(arrMD5Digest[i], 2)); + } + return result; +} + +GString strMD5(const GString &buffer) +{ + GByteArray buf = strToByteArray(buffer); + return getMD5(buf.constData(), buf.size()); +} + +GString fileMD5(const GString &fileName) +{ + GString result; + GFileStream file(fileName); + if (!file.open(GStream::ReadOnly)) + return result; + else + { + result = getMD5(&file); + file.close(); + return result; + } +} + +static void byteSwap(UWORD32 *buf, unsigned words) +{ + const quint32 c_ByteOrderTest = 0x1; + if (((char *)&c_ByteOrderTest)[0] == 0) + { + md5byte *pBuf = (md5byte *)buf; + + do + { + *buf++ = (UWORD32)((unsigned)pBuf[3] << 8 | pBuf[2]) << 16 + | ((unsigned)pBuf[1] << 8 | pBuf[0]); + pBuf += 4; + } while (--words != 0); + } +} + +/* + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious + * initialization constants. + */ +static void MD5Init(struct MD5Context *ctx) +{ + memset(ctx, 0, sizeof(MD5Context)); + ctx->buf[0] = 0x67452301; + ctx->buf[1] = 0xefcdab89; + ctx->buf[2] = 0x98badcfe; + ctx->buf[3] = 0x10325476; + + ctx->bytes[0] = 0; + ctx->bytes[1] = 0; +} + +/* + * Update context to reflect the concatenation of another buffer full + * of bytes. + */ +static void MD5Update(struct MD5Context *ctx, md5byte const *buf, unsigned len) +{ + UWORD32 uTmp; + + /* Update byte count */ + + uTmp = ctx->bytes[0]; + if ((ctx->bytes[0] = uTmp + len) < uTmp) + ctx->bytes[1]++; /* Carry from low to high */ + + uTmp = 64 - (uTmp & 0x3f); /* Space available in ctx->in (at least 1) */ + if (uTmp > len) + { + memcpy((md5byte *)ctx->in + 64 - uTmp, buf, len); + return; + } + /* First chunk is an odd size */ + memcpy((md5byte *)ctx->in + 64 - uTmp, buf, uTmp); + byteSwap(ctx->in, 16); + MD5Transform(ctx->buf, ctx->in); + buf += uTmp; + len -= uTmp; + + /* Process data in 64-byte chunks */ + while (len >= 64) + { + memcpy(ctx->in, buf, 64); + byteSwap(ctx->in, 16); + MD5Transform(ctx->buf, ctx->in); + buf += 64; + len -= 64; + } + + /* Handle any remaining bytes of data. */ + memcpy(ctx->in, buf, len); +} + +/* + * Final wrapup - pad to 64-byte boundary with the bit pattern + * 1 0* (64-bit count of bits processed, MSB-first) + */ +static void MD5Final(struct MD5Context *ctx, md5byte digest[16]) +{ + int nCount = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */ + md5byte *pByte = (md5byte *)ctx->in + nCount; + + /* Set the first char of padding to 0x80. There is always room. */ + *pByte++ = 0x80; + + /* Bytes of padding needed to make 56 bytes (-8..55) */ + nCount = 56 - 1 - nCount; + + if (nCount < 0) + { /* Padding forces an extra block */ + memset(pByte, 0, nCount + 8); + byteSwap(ctx->in, 16); + MD5Transform(ctx->buf, ctx->in); + pByte = (md5byte *)ctx->in; + nCount = 56; + } + memset(pByte, 0, nCount); + byteSwap(ctx->in, 14); + + /* Append length in bits and transform */ + ctx->in[14] = ctx->bytes[0] << 3; + ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29; + MD5Transform(ctx->buf, ctx->in); + + byteSwap(ctx->buf, 4); + memcpy(digest, ctx->buf, 16); + memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ +} + +#ifndef ASM_MD5 + +/* The four core functions - F1 is optimized somewhat */ + +/* #define F1(x, y, z) (x & y | ~x & z) */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +/* This is the central step in the MD5 algorithm. */ +#define MD5STEP(f,w,x,y,z,in,s) \ + (w += f(x,y,z) + in, w = (w<>(32-s)) + x) + +/* + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data. MD5Update blocks + * the data and converts bytes into longwords for this routine. + */ +static void MD5Transform(UWORD32 buf[4], UWORD32 const in[16]) +{ + register UWORD32 uA; + register UWORD32 uB; + register UWORD32 uC; + register UWORD32 uD; + + uA = buf[0]; + uB = buf[1]; + uC = buf[2]; + uD = buf[3]; + + MD5STEP(F1, uA, uB, uC, uD, in[0] + 0xd76aa478, 7); + MD5STEP(F1, uD, uA, uB, uC, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, uC, uD, uA, uB, in[2] + 0x242070db, 17); + MD5STEP(F1, uB, uC, uD, uA, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, uA, uB, uC, uD, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, uD, uA, uB, uC, in[5] + 0x4787c62a, 12); + MD5STEP(F1, uC, uD, uA, uB, in[6] + 0xa8304613, 17); + MD5STEP(F1, uB, uC, uD, uA, in[7] + 0xfd469501, 22); + MD5STEP(F1, uA, uB, uC, uD, in[8] + 0x698098d8, 7); + MD5STEP(F1, uD, uA, uB, uC, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, uC, uD, uA, uB, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, uB, uC, uD, uA, in[11] + 0x895cd7be, 22); + MD5STEP(F1, uA, uB, uC, uD, in[12] + 0x6b901122, 7); + MD5STEP(F1, uD, uA, uB, uC, in[13] + 0xfd987193, 12); + MD5STEP(F1, uC, uD, uA, uB, in[14] + 0xa679438e, 17); + MD5STEP(F1, uB, uC, uD, uA, in[15] + 0x49b40821, 22); + + MD5STEP(F2, uA, uB, uC, uD, in[1] + 0xf61e2562, 5); + MD5STEP(F2, uD, uA, uB, uC, in[6] + 0xc040b340, 9); + MD5STEP(F2, uC, uD, uA, uB, in[11] + 0x265e5a51, 14); + MD5STEP(F2, uB, uC, uD, uA, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, uA, uB, uC, uD, in[5] + 0xd62f105d, 5); + MD5STEP(F2, uD, uA, uB, uC, in[10] + 0x02441453, 9); + MD5STEP(F2, uC, uD, uA, uB, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, uB, uC, uD, uA, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, uA, uB, uC, uD, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, uD, uA, uB, uC, in[14] + 0xc33707d6, 9); + MD5STEP(F2, uC, uD, uA, uB, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, uB, uC, uD, uA, in[8] + 0x455a14ed, 20); + MD5STEP(F2, uA, uB, uC, uD, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, uD, uA, uB, uC, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, uC, uD, uA, uB, in[7] + 0x676f02d9, 14); + MD5STEP(F2, uB, uC, uD, uA, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, uA, uB, uC, uD, in[5] + 0xfffa3942, 4); + MD5STEP(F3, uD, uA, uB, uC, in[8] + 0x8771f681, 11); + MD5STEP(F3, uC, uD, uA, uB, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, uB, uC, uD, uA, in[14] + 0xfde5380c, 23); + MD5STEP(F3, uA, uB, uC, uD, in[1] + 0xa4beea44, 4); + MD5STEP(F3, uD, uA, uB, uC, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, uC, uD, uA, uB, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, uB, uC, uD, uA, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, uA, uB, uC, uD, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, uD, uA, uB, uC, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, uC, uD, uA, uB, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, uB, uC, uD, uA, in[6] + 0x04881d05, 23); + MD5STEP(F3, uA, uB, uC, uD, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, uD, uA, uB, uC, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, uC, uD, uA, uB, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, uB, uC, uD, uA, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, uA, uB, uC, uD, in[0] + 0xf4292244, 6); + MD5STEP(F4, uD, uA, uB, uC, in[7] + 0x432aff97, 10); + MD5STEP(F4, uC, uD, uA, uB, in[14] + 0xab9423a7, 15); + MD5STEP(F4, uB, uC, uD, uA, in[5] + 0xfc93a039, 21); + MD5STEP(F4, uA, uB, uC, uD, in[12] + 0x655b59c3, 6); + MD5STEP(F4, uD, uA, uB, uC, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, uC, uD, uA, uB, in[10] + 0xffeff47d, 15); + MD5STEP(F4, uB, uC, uD, uA, in[1] + 0x85845dd1, 21); + MD5STEP(F4, uA, uB, uC, uD, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, uD, uA, uB, uC, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, uC, uD, uA, uB, in[6] + 0xa3014314, 15); + MD5STEP(F4, uB, uC, uD, uA, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, uA, uB, uC, uD, in[4] + 0xf7537e82, 6); + MD5STEP(F4, uD, uA, uB, uC, in[11] + 0xbd3af235, 10); + MD5STEP(F4, uC, uD, uA, uB, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, uB, uC, uD, uA, in[9] + 0xeb86d391, 21); + + buf[0] += uA; + buf[1] += uB; + buf[2] += uC; + buf[3] += uD; +} + +const unsigned short c_MaxBufSize = 16384; + +static void MD5UpdateBuffer(struct MD5Context *context, const char *buffer, size_t bufSize) +{ + md5byte *pBufTmp = (md5byte *)gMalloc(c_MaxBufSize); + unsigned short uBytes; + try + { + const char *pBufPtr = buffer; + do + { + if (bufSize > c_MaxBufSize) + uBytes = c_MaxBufSize; + else + uBytes = (unsigned short)bufSize; + gMemMove(pBufTmp, pBufPtr, uBytes); + pBufPtr += uBytes; + bufSize -= uBytes; + if (uBytes > 0) + MD5Update(context, pBufTmp, uBytes); + } while (uBytes >= c_MaxBufSize); + } + catch (...) + { + gFree(pBufTmp); + throw; + } + gFree(pBufTmp); +} + +static void MD5UpdateBuffer(struct MD5Context *context, GStream *stream) +{ + md5byte *pBufTmp = (md5byte *)gMalloc(c_MaxBufSize); + unsigned short uBytes; + try + { + long long llBufSize = stream->size(); + stream->seek(0); + do + { + if (llBufSize > c_MaxBufSize) + uBytes = c_MaxBufSize; + else + uBytes = (unsigned short)llBufSize; + stream->read((char *)pBufTmp, uBytes); + llBufSize -= uBytes; + if (uBytes > 0) + MD5Update(context, pBufTmp, uBytes); + } while (uBytes >= c_MaxBufSize); + } + catch (...) + { + gFree(pBufTmp); + throw; + } + gFree(pBufTmp); +} + +#endif diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDMathUtils.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDMathUtils.cpp new file mode 100644 index 00000000..e368f05c --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDMathUtils.cpp @@ -0,0 +1,887 @@ +#include "GLDMathUtils.h" + +#ifdef WIN32 +#include "WTypes.h" +#endif + +#include +#include + +#include "GLDGlobal.h" +#include "GLDStrUtils.h" +#include "GLDFloatFormating.h" + +//const int CFuzzFactor = 1000; +//const int CExtendedResolution = 1e-19 * CFuzzFactor; +//const int CDoubleResolution = 1e-15 * CFuzzFactor; +//const int CSingleResolution = 1e-7 * CFuzzFactor; + +const double c_defDoubleEpsilon = 1e-12; + +double ln(double v) +{ + assert(v > 0); + return qLn(v); +} + +// Log.N(X) := Log.2(X) / Log.2(N) +double logN(double x, double n) +{ + assert(x > 0); + assert(n > 0); + assert(n != 1); + return ln(x) / ln(n); +} + +double arcSin(double v) +{ + return qAsin(v); +} + +double arcCos(double v) +{ + return qAcos(v); +} + +double arctan(double v) +{ + return qAtan(v); +} + +double sqr(double v) +{ + return v * v; +} + +bool sameFloat(float firstNum, float secondNum) +{ + return (fabs(firstNum - secondNum) < 0.00001 ? true : false); +} + +bool sameValue(double a, double b, double epsilon) +{ + return fabs(a - b) < epsilon; +} + +GLDValueRelationship compareValue(double a, double b, double epsilon) +{ + if (sameValue(a, b, epsilon)) + { + return gvrEqualsValue; + } + else if (a < b) + { + return gvrLessThanValue; + } + else + { + return gvrGreaterThanValue; + } +} + +// 去尾取整 trunc(5.6) == 5; trunc(-5.6) == -5 +long long itrunc(double v) +{ + return (long long)(v); +} + +// 四舍六入五留双 round(2.5) == 2; round(3.5) == 4; round(-2.5) == -2; round(-3.5) == -4; +long long iround(double v) +{ + // todo 浮点数+1 + double dFabsVal = fabs(v); + long long llTmp = itrunc(dFabsVal); + if (dFabsVal - llTmp > 0.5) + { + ++llTmp; + } + else if (dFabsVal - llTmp == 0.5) + { + if ((llTmp % 2) != 0) + { + ++llTmp; + } + } + if (v < 0) + return -llTmp; + else + return llTmp; +} + +//////////////////////////////////////////////////////////////////////////////// +// 说明:浮点数取指定位小数精度 +// 参数:F -- 浮点数 +// ADecimal -- 小数位数 +// 返回:F按ADecimal位小数精度四舍五入后的浮点数 +// 注意:FRound( 518.775, 2) = 518.78 +// FRound(-518.775, 2) = -518.78 +// FRound(-518.775, -1) = -520 +// 为了避免误差问题,根据 IEEE 的规定直接在 F 尾数上加 1,可能 2 或 4 等 +// 备注:添加 ADecimal 为负数时的处理,即整数部分的精度计算; zhangjq 2011.12.13 +//////////////////////////////////////////////////////////////////////////////// +double fRound(double v, int decimal, double epsilon) +{ + const static double c_DecBase[10] = {1, 1E1, 1E2, 1E3, 1E4, 1E5, 1E6, 1E7, 1E8, 1E9}; + if ((v > c_MaxInt64) || (v < c_MinInt64)) + return v; + else if (decimal < 0) + { + // todo + return v; + } + else if (decimal <= 8) + { + //当数值超过10位时,+512带来的误差会比较大,但是能保证数比较小的时候是正确的-by huangp 2015.9.6 + long long *ptmp = (long long *)(&v); + *ptmp += 512; // 支持512个相同的有误差的数相加后fRound + long long llIntVal = itrunc(v); + long long llDecimalVal = itrunc((v - llIntVal) * c_DecBase[decimal + 1]); + long long llModVal = llDecimalVal % 10; + if (llModVal >= 5) + { + llDecimalVal += 10; + } + else if (llModVal <= -5) + { + llDecimalVal -= 10; + } + llDecimalVal = llDecimalVal / 10; + return llIntVal + llDecimalVal / c_DecBase[decimal]; + } + else + { + double result = strToFloat( + formatFloat("0." + stringOfChar(char('#'), decimal), v + epsilon)); + if (sameValue(result, 0.0)) + { + result = 0; + } + return result; + } +} + +double frac(double v) +{ + return v - itrunc(v); +} + +double drandom() +{ +#ifdef WIN32 + srand(GetTickCount()); + return double(rand()) / double(RAND_MAX); +#else + return drand48(); +#endif +} + +int random(int n) +{ + if (n <= 0) + { + return 0; + } + srand(time(0)); + return rand() % (n); +} + +int randomRange(int from, int to) +{ + if (sameValue(from, to)) + { + return from; + } + else if (from > to) + { + return random(from - to) + to; + } + else + { + return random(to - from) + from; + } +} + +double radToDeg(double radians) +{ + return radians * 180.0 / PI; +} + +double degToRad(double degrees) +{ + return degrees * PI / 180.0; +} + +double power(double x, double y) +{ + return qPow(x, y); +} + +bool isZero(double value, double epsilon) +{ + if (epsilon == 0) + epsilon = 1E-19 * 1000;; + return fabs(value) <= epsilon; +} + +bool varIsNullEx(const GVariant &value) +{ + return value.isNull(); +} + +GVariant varArrayOf(GLDVector &values) +{ + GVariantList result; + for (int i = 0; i != values.count(); ++i) + { + result << values.at(i); + } + return GVariant(result); +} + +GVariant inc(const GVariant &value) +{ + GVariant result; + switch (value.type()) + { + case GVariant::LongLong: + result.setValue(value.toLongLong() + 1); + break; + case GVariant::ULongLong: + result.setValue(value.toULongLong() + 1); + break; + case GVariant::Int: + result.setValue(value.toInt() + 1); + break; + case GVariant::UInt: + result.setValue(value.toUInt() + 1); + break; + case GVariant::Double: + result.setValue(value.toDouble() + 1); + break; + case GVariant::ByteArray: + result.setValue(GUIDToByteArray(createGUID())); + break; + case GVariant::String: + result.setValue(GUIDToVariant(createGUID())); + break; + case GVariant::Uuid: + result.setValue(GUIDToVariant(createGUID())); + break; + default: + assert(false); + break; + } + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +// 说明:数字转换为汉字数字 +// 参数: n -- 数字(1~99) +// 返回: 数字对应的汉字 +//////////////////////////////////////////////////////////////////////////////// +GString num2CChar(int n) +{ + GString result; + if ((n < 1) || (n > 99)) + { + return ""; + } + int nNumber = n % 10; + switch (nNumber) + { + case 0: + result = ""; + break; + case 1: + result = TRANS_STRING("一"); + break; + case 2: + result = TRANS_STRING("二"); + break; + case 3: + result = TRANS_STRING("三"); + break; + case 4: + result = TRANS_STRING("四"); + break; + case 5: + result = TRANS_STRING("五"); + break; + case 6: + result = TRANS_STRING("六"); + break; + case 7: + result = TRANS_STRING("七"); + break; + case 8: + result = TRANS_STRING("八"); + break; + case 9: + result = TRANS_STRING("九"); + break; + default: + assert(false); + break; + } + nNumber = n / 10; + switch (nNumber) + { + case 1: + result = TRANS_STRING("十") + result; + break; + case 2: + result = TRANS_STRING("二十") + result; + break; + case 3: + result = TRANS_STRING("三十") + result; + break; + case 4: + result = TRANS_STRING("四十") + result; + break; + case 5: + result = TRANS_STRING("五十") + result; + break; + case 6: + result = TRANS_STRING("六十") + result; + break; + case 7: + result = TRANS_STRING("七十") + result; + break; + case 8: + result = TRANS_STRING("八十") + result; + break; + case 9: + result = TRANS_STRING("九十") + result; + break; + } + return result; +} + +// 将阿拉伯数字转成中文数字字串 +// 示例: Num2CNum(10002.34) ==> 一万零二点三四 +GString num2ChsNum(double arabic) +{ + const GString c_ChineseNumeric = TRANS_STRING("零一二三四五六七八九"); + GString result; + GString sIntArabic; + GString strSectionArabic; + GString strSection; + int nDigit = 0; + bool bInZero = true; + bool bMinus = false; + + GString strArabic = floatToStr(arabic); // 将数字转成阿拉伯数字字串 + if ('-' == strArabic.at(0).toLatin1()) + { + bMinus = true; + strArabic = copy(strArabic, 1); + } + int nPosOfDecimalPoint = pos('.', strArabic); // 取得小数点的位置 + // 先处理整数的部分 + if (nPosOfDecimalPoint < 0) + { + sIntArabic = reverseString(strArabic); + } + else + { + sIntArabic = reverseString(copy(strArabic, 0, nPosOfDecimalPoint)); + } + int nSection = 0; + // 从个位数起以每四位数为一小节 + for (nSection = 0; nSection <= (sIntArabic.length() - 1) / 4; ++nSection) + { + strSectionArabic = copy(sIntArabic, nSection * 4, 4); + strSection = ""; + // 以下的 i 控制: 个十百千位四个位数 + for (int i = 0; i != strSectionArabic.length(); ++i) + { + nDigit = strSectionArabic.at(i).toLatin1() - 48; + if (0 == nDigit) + { + // 1. 避免 '零' 的重覆出现 + // 2. 个位数的 0 不必转成 '零' + if ((!bInZero) && (i != 0)) + { + strSection = TRANS_STRING("零") + strSection; + } + bInZero = true; + } + else + { + switch (i) + { + case 1: + strSection = TRANS_STRING("十") + strSection; + break; + case 2: + strSection = TRANS_STRING("百") + strSection; + break; + case 3: + strSection = TRANS_STRING("千") + strSection; + break; + default: + break; + } + strSection = c_ChineseNumeric[nDigit] + strSection; + bInZero = false; + } + } + // 加上该小节的位数 + if (0 == strSection.length()) + { + if ((result.length() > 0) && (copy(result, 0, 2)) != TRANS_STRING("零")) + { + result = TRANS_STRING("零") + result; + } + } + else + { + switch (nSection) + { + case 0: + result = strSection; + break; + case 1: + result = strSection + TRANS_STRING("万") + result; + break; + case 2: + result = strSection + TRANS_STRING("亿") + result; + break; + case 3: + result = strSection + TRANS_STRING("兆") + result; + break; + default: + break; + } + } + } + // 处理小数点右边的部分 + if (nPosOfDecimalPoint >= 0) + { + result = result + TRANS_STRING("点"); + for (int i = nPosOfDecimalPoint + 1; i != strArabic.length(); ++i) + { + nDigit = strArabic.at(i).toLatin1() - 48; + result = result + c_ChineseNumeric[nDigit]; + } + } + + // 其他例外状况的处理 + if (0 == result.length()) + { + result = TRANS_STRING("零"); + } + if (copy(result, 0, 2) == TRANS_STRING("一十")) + { + result = copy(result, 1); + } + if (copy(result, 0, 1) == TRANS_STRING("点")) + { + result = TRANS_STRING("零") + result; + } + + // 是否为负数 + if (bMinus) + { + result = TRANS_STRING("负") + result; + } + return result; +} + +GString fourNumToChnNum(const GString &str, const GString &chnNum, bool &pre) +{ + const GString c_Digits = TRANS_STRING("零壹贰叁肆伍陆柒捌玖"); + GString result; + int nLen = str.length(); + for (int i = 0; i != nLen; ++i) + { + int nOffset = str.at(i).toLatin1() - '0'; + if (0 == nOffset) + { + pre = true; + } + else + { + if (pre) + { + result = result + c_Digits[0]; + } + result = result + c_Digits[nOffset] + copy(chnNum, nLen - i - 1, 1); + pre = false; + } + } + return stringReplace(result, TRANS_STRING("币"), ""); +} + +//将格式化好的小写串转换为大写串 +GString stringToChnNum(const GString &str) +{ +#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) + const GString c_chnNum1 = GString("元万亿兆"); +#else + const GString c_chnNum1 = TRANS_STRING("元万亿兆"); +#endif + GString result; + GString strTmp; + GString strTmp1; + int nLen = pos(".", str); + int nLevel = (nLen + 3) / 4; + int nLen1 = nLen % 4; + if (0 == nLen1) + { + nLen1 = 4; + } + int nStart = 0; + bool bPre = false; + for (int i = 1; i <= nLevel; ++i) + { + bPre = false; + strTmp = copy(str, nStart, nLen1); + strTmp1 = fourNumToChnNum(strTmp, TRANS_STRING("币拾佰仟"), bPre); // 两个空格改为币占位符 + if ((strTmp1 != "") || ((i > 1) && (i == nLevel))) + { + result = result + strTmp1 + copy(c_chnNum1, nLevel - i, 1); + } + nStart = nStart + nLen1; + nLen1 = 4; + } + bPre = false; + strTmp1 = fourNumToChnNum(copy(str, nLen + 1, 2), TRANS_STRING("分角"), bPre); + if (strTmp1.length() == 0) + { + strTmp1 = TRANS_STRING("整"); + } + return result + strTmp1; +} + +// 说明:将小写金额转换为大写 +GString currToChnNum(double currnum) +{ + if (fabs(currnum) < c_defDoubleEpsilon) + { + return TRANS_STRING("零元整"); + } + GString result; + if (currnum < c_defDoubleEpsilon) + { + result = TRANS_STRING("负"); + } + GString strTmp = GString::number(fabs(currnum), 'f', 2); + return result + stringToChnNum((trim(strTmp))); +} + +int rightZeroNumber(const GString &str) +{ + int nCount = 0; + for (int i = str.length() - 1; i >= 0; --i) + { + if (str.at(i) == QChar('0')) + { + ++nCount; + } + else if (str.at(i) == QChar('.')) + { + ++nCount; + break; + } + else + { + break; + } + } + return nCount; +} + +int leftZeroNumber(const GString &str) +{ + int nCount = 0; + for (int i = 0; i <= str.length() - 1; ++i) + { + if (str.at(i) == QChar('0')) + { + ++nCount; + } + else + { + break; + } + } + return nCount; +} + +int rightZeroNumberNextDot(const GString &str) +{ + int result = 0; + for (int i = str.length() - 1; i >= 0; i--) + { + if (str.at(i) == QChar('0')) + { + ++result; + } + else if (str.at(i) == QChar('.')) + { + break; + } + } + return result; +} + +int zeroNumberAfterDot(const GString &str) +{ + int result = 0; + int nPos = str.indexOf('.'); + if (nPos < 0) + { + return result; + } + for (int i = nPos + 1; i < str.length() - 1; ++i) + { + if (str.at(i) == QChar('0')) + { + ++result; + } + else + { + break; + } + } + return result; +} + +/*! + * \brief 补齐format的后面的0的个数 + * \param format + * \param value + * \param nAfter + * \return + */ +GString makeUpZero(const GString &format, const GString &value, int nAfter) +{ + GString result = value; + int nRightZeroNum = 0; + if (format.at(format.length() - 1) == QChar('0'))//最后一位是0, 后面补齐0 + { + nRightZeroNum = nAfter; + } + else + { + nRightZeroNum = rightZeroNumberNextDot(format); + } + if ((result.length() <= nRightZeroNum) && (nRightZeroNum > 0)) + { + int nCount = result.length(); + for (int i = 0; i < nRightZeroNum - nCount; i++) + { + result += '0'; + } + } + return result; +} + +GString formatFloat(const GString &format, double value) +{ + return GLDFloatFormating::formatFloat(value, format); + +// GString sValue = GString::number(value, 'g', 14); +// if (sValue.contains('e') || sValue.contains('E')) +// { +// sValue = GString::number(value, 'f', 15); +// } +// value = sValue.toDouble(); +// GString result; +// if (format.toLower().contains('e')) +// { +// // todo +// } +// else if (format.contains(',')) +// { +// int nPos = pos(".", format); +// int nAfter = format.length() - 1 - nPos; +// int nCommaPos = format.lastIndexOf(','); +// GString strAfterDot; +// if (nPos > 0) +// { +// int nIndex = sValue.indexOf('.'); +// if (nIndex > 0) +// { +// strAfterDot = copy(sValue, sValue.indexOf('.') + 1); +// } +// else +// { +// strAfterDot = ""; +// } +// sValue = GString::number(trunc(abs(value))); +// } +// else +// { +// sValue = GString::number(qRound(abs(value))); +// strAfterDot = ""; +// } +// if (nPos > 0)//小数点后的格式处理 +// { +// if (nAfter >= strAfterDot.length()) +// { +// strAfterDot = makeUpZero(format, strAfterDot, nAfter); +// } +// else //截取小数,四舍五入处理 +// { +// double dValue = strToInt64(strAfterDot); +// long long llValue = pow(10.0, strAfterDot.length() - nAfter); +// dValue = dValue / llValue; +// long long nTrancValue = trunc(dValue); +// GString strTrancValue = GString::number(nTrancValue); +// strAfterDot = GString::number(qRound(dValue)); +// if (strTrancValue.length() < strAfterDot.length()) +// { +// strAfterDot = ""; +// sValue = GString::number(strToInt64(sValue) + 1); +// strAfterDot = makeUpZero(format, strAfterDot, nAfter); +// } +// else +// { +// int nLen = nAfter - strAfterDot.length(); +// for (int i = 0; i < nLen; i++) +// { +// strAfterDot = '0' + strAfterDot; +// } +// } +// } +// } +// if (sValue != "")//小数点前的格式处理 +// { +// int nLength; +// if (nPos > 0) +// { +// nLength = nPos - nCommaPos - 1; +// } +// else +// { +// nLength = format.length() - nCommaPos - 1; +// } +// int nSum = sValue.length() / nLength; +// result = sValue; +// if (nSum > 0) +// { +// int nInsert = sValue.length() % nLength; +// if (nInsert > 0) +// { +// result = result.insert(nInsert, ','); +// } +// for (int i = 0; i < nSum - 1; i++) +// { +// nInsert = nInsert + nLength + 1; +// result = result.insert(nInsert, ','); +// } +// } +// } +// if (value < 0) +// { +// result = "-" + result; +// } +// if ("" == strAfterDot) +// { +// return result; +// } +// else +// { +// return GString("%1.%2").arg(result).arg(strAfterDot); +// } +// } +// else if (format.contains('.')) +// { +// int nPos = pos(".", format); +// int nPosByValue = pos(".", sValue); +// int nBefore = nPos; +// int nAfter = format.length() - 1 - nPos; +// double dAfterDot = fabs(frac(value)); +// int nAfterDot = int(dAfterDot * power(10, nAfter)); +// int nAfterByValue = sValue.length() - pos('.', sValue) - 1; + +// // value为整数补0 +// if (!sValue.contains('.')) +// { +// result = GString("%1.%2").arg(trunc(value), nBefore, 'f', 0, '0').arg(nAfterDot, nAfter, 'f', 0, '0'); +// } +// else +// { +// // value的有效长度较小补0 +// if (nAfterByValue < nAfter) +// { +// GString strTmp(nAfter - nAfterByValue, '0'); +// result = GString("%1").arg(trunc(value), nBefore, 'f', 0, '0') + sValue.mid(nPosByValue) + strTmp; +// } +// else if (nAfter <= zeroNumberAfterDot(sValue)) +// { +// result = GString("%1").arg(trunc(value), nBefore, 'f', 0, '0'); +// } +// // 直接删除尾数 +// else +// { +// long long lValue = pow(10.0, nAfter); +// double dValue = sValue.toDouble(); +// dValue = dValue * lValue; +// GString strTrans = QString::number(trunc(dValue)); +// int nRoundValue = qRound(dValue); +// GString strRound = GString::number(nRoundValue); +// dValue = nRoundValue * 1.0 / lValue; +// sValue = GString::number(dValue); +// if (strTrans.length() < strRound.length()) +// { +// sValue = ""; +// result = GString("%1").arg(trunc(value + 1), nBefore, 'f', 0, '0'); +// } +// else +// { +// result = GString("%1").arg(trunc(value), nBefore, 'f', 0, '0'); +// } +// nPosByValue = 0; +// if (sValue != "") +// { +// nPosByValue = pos(".", sValue); +// if (nPosByValue > 0) +// { +// sValue = sValue.mid(nPosByValue + 1); +// } +// } +// int nCount = rightZeroNumber(format) - sValue.length() - 1; +// for (int i = 0; i < nCount; i++) +// { +// sValue += '0'; +// } +// if (sValue != "") +// { +// result = GString("%1.%2").arg(result).arg(sValue); +// } +// else +// { +// return result; +// } +// } +// } + +// if (format.at(format.length() - 1) == '#') +// { +// result = copy(result, 0, result.length() - rightZeroNumber(result)); +// } +// if ((result.length() > 1) && ((format.at(0) == '#') || (format.at(0) == '.'))) +// { +// result = copy(result, leftZeroNumber(result)); +// } +// if (value < 0) +// { +// result = "-" + result; +// } +// return result; +// } +// else +// { +// // todo +// } +// return result; +} + + +GRgb turnRgb(GRgb rgb) +{ + return ((rgb & 0xff) << 16) | (rgb & 0xff00) | ((rgb & 0xff0000) >> 16); +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDObject.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDObject.cpp new file mode 100644 index 00000000..bef656f1 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDObject.cpp @@ -0,0 +1,144 @@ +#include "GLDObject.h" + +#include "GLDGlobal.h" + +/* GInterfaceObject */ + +GInterfaceObject::GInterfaceObject() +{ + m_cRef.store(0); +} + +GInterfaceObject::~GInterfaceObject() +{ +} + +HRESULT GInterfaceObject::_QueryInterface(const IID &riid, void **ppvObject) +{ + if (riid == IID_IUnknown) + { + this->AddRef(); + *ppvObject = static_cast(this); + return NOERROR; + } + else + { + *ppvObject = NULL; + return E_NOINTERFACE; + } +} + +ULONG GInterfaceObject::_AddRef() +{ + ULONG result = m_cRef.ref(); + return result; +} + +ULONG GInterfaceObject::_Release() +{ + ULONG result = m_cRef.deref(); + if (result == 0) + { + delete this; + return ULONG(0); + } + else + { + return result; + } +} + +void GInterfaceObject::beforeDestruction() +{ + m_cRef.ref(); +} + +void GInterfaceObject::afterConstruction() +{ + m_cRef.deref(); +} + +/* GNoRefInterfaceObject */ +GNoRefInterfaceObject::GNoRefInterfaceObject() +{ +} + +GNoRefInterfaceObject::~GNoRefInterfaceObject() +{ +} + +HRESULT GNoRefInterfaceObject::_QueryInterface(const IID &riid, void **ppvObject) +{ + if (riid == IID_IUnknown) + { + this->AddRef(); + *ppvObject = static_cast(this); + return NOERROR; + } + else + { + *ppvObject = NULL; + return E_NOINTERFACE; + } +} + +ULONG GNoRefInterfaceObject::_AddRef() +{ + return -1; +} + +ULONG GNoRefInterfaceObject::_Release() +{ + return -1; +} + +/* GAutoIntfObject */ +HRESULT GAutoIntfObject::_GetTypeInfoCount(UINT *pctinfo) +{ + return NOERROR; + G_UNUSED(pctinfo); +} + +HRESULT GAutoIntfObject::_GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) +{ + return NOERROR; + G_UNUSED(iTInfo); + G_UNUSED(lcid); + G_UNUSED(ppTInfo); +} + +HRESULT GAutoIntfObject::_GetIDsOfNames(const IID &riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) +{ + return NOERROR; + G_UNUSED(riid); + G_UNUSED(rgszNames); + G_UNUSED(cNames); + G_UNUSED(lcid); + G_UNUSED(rgDispId); +} + +HRESULT GAutoIntfObject::_Invoke(DISPID dispIdMember, const IID &riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + return NOERROR; + G_UNUSED(dispIdMember); + G_UNUSED(riid); + G_UNUSED(lcid); + G_UNUSED(wFlags); + G_UNUSED(pDispParams); + G_UNUSED(pVarResult); + G_UNUSED(pExcepInfo); + G_UNUSED(puArgErr); +} + +HRESULT STDMETHODCALLTYPE GAutoIntfObject::_QueryInterface(REFIID riid, void **ppvObject) +{ + if (riid == IID_IDispatch) + { + this->AddRef(); + *ppvObject = static_cast(this); + return GLD_OK; + } + else + return GInterfaceObject::_QueryInterface(riid, ppvObject); +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDSHA1.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDSHA1.cpp new file mode 100644 index 00000000..67960fd3 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDSHA1.cpp @@ -0,0 +1,368 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + Based on the public domain implementation of the SHA-1 algorithm + Copyright (C) Dominik Reichl +*/ + +#include "GLDSHA1.h" +#include "GLDStrUtils.h" +#include "GLDGlobal.h" + +#include + +#ifdef Q_CC_MSVC +# include +#endif + + +// #define or #undef this, if you want the to wipe all +// temporary variables after processing +#define SHA1_WIPE_VARIABLES + + +struct Sha1State +{ + quint32 h0; + quint32 h1; + quint32 h2; + quint32 h3; + quint32 h4; + + quint64 messageSize; + unsigned char buffer[64]; +}; + +typedef union +{ + quint8 bytes[64]; + quint32 words[16]; +} Sha1Chunk; + +static inline quint32 rol32(quint32 value, unsigned int shift) +{ +#ifdef Q_CC_MSVC + return _rotl(value, shift); +#else + return ((value << shift) | (value >> (32 - shift))); +#endif +} + +static inline quint32 sha1Word(Sha1Chunk *chunk, const uint position) +{ + return (chunk->words[position & 0xf] = rol32( chunk->words[(position+13) & 0xf] + ^ chunk->words[(position+ 8) & 0xf] + ^ chunk->words[(position+ 2) & 0xf] + ^ chunk->words[(position) & 0xf], 1)); +} + +static inline void sha1Round0(Sha1Chunk *chunk, const uint position, + quint32 &v, quint32 &w, quint32 &x, quint32 &y, quint32 &z) +{ + z += ((( w & (x ^ y)) ^ y) + chunk->words[position] + 0x5A827999 + rol32(v, 5)); + w = rol32(w, 30); +} + +static inline void sha1Round1(Sha1Chunk *chunk, const uint position, + quint32 &v, quint32 &w, quint32 &x, quint32 &y, quint32 &z) +{ + z += ((( w & (x ^ y)) ^ y) + sha1Word(chunk,position) + 0x5A827999 + rol32(v, 5)); + w = rol32(w, 30); +} + +static inline void sha1Round2(Sha1Chunk *chunk, const uint position, + quint32 &v, quint32 &w, quint32 &x, quint32 &y, quint32 &z) +{ + z += (( w ^ x ^ y) + sha1Word(chunk, position) + 0x6ED9EBA1 + rol32(v, 5)); + w = rol32(w, 30); +} + +static inline void sha1Round3(Sha1Chunk *chunk, const uint position, + quint32 &v, quint32 &w, quint32 &x, quint32 &y, quint32 &z) +{ + z += (((( w | x) & y) | (w & x)) + sha1Word(chunk, position) + 0x8F1BBCDC + rol32(v, 5)); + w = rol32(w, 30); +} + +static inline void sha1Round4(Sha1Chunk *chunk, const uint position, + quint32 &v, quint32 &w, quint32 &x, quint32 &y, quint32 &z) +{ + z += ((w ^ x ^ y) + sha1Word(chunk, position) + 0xCA62C1D6 + rol32(v, 5)); + w = rol32(w, 30); +} + +static inline void sha1ProcessChunk(Sha1State *state, const unsigned char *buffer) +{ + // Copy state[] to working vars + quint32 ua = state->h0; + quint32 ub = state->h1; + quint32 uc = state->h2; + quint32 ud = state->h3; + quint32 ue = state->h4; + + quint8 chunkBuffer[64]; + memcpy(chunkBuffer, buffer, 64); + + Sha1Chunk *chunk = reinterpret_cast(&chunkBuffer); + + for (int i = 0; i < 16; ++i) + { + chunk->words[i] = qFromBigEndian(chunk->words[i]); + } + + sha1Round0(chunk, 0, ua,ub,uc,ud,ue); sha1Round0(chunk, 1, ue,ua,ub,uc,ud); + sha1Round0(chunk, 2, ud,ue,ua,ub,uc); sha1Round0(chunk, 3, uc,ud,ue,ua,ub); + sha1Round0(chunk, 4, ub,uc,ud,ue,ua); sha1Round0(chunk, 5, ua,ub,uc,ud,ue); + sha1Round0(chunk, 6, ue,ua,ub,uc,ud); sha1Round0(chunk, 7, ud,ue,ua,ub,uc); + sha1Round0(chunk, 8, uc,ud,ue,ua,ub); sha1Round0(chunk, 9, ub,uc,ud,ue,ua); + sha1Round0(chunk, 10, ua,ub,uc,ud,ue); sha1Round0(chunk, 11, ue,ua,ub,uc,ud); + sha1Round0(chunk, 12, ud,ue,ua,ub,uc); sha1Round0(chunk, 13, uc,ud,ue,ua,ub); + sha1Round0(chunk, 14, ub,uc,ud,ue,ua); sha1Round0(chunk, 15, ua,ub,uc,ud,ue); + sha1Round1(chunk, 16, ue,ua,ub,uc,ud); sha1Round1(chunk, 17, ud,ue,ua,ub,uc); + sha1Round1(chunk, 18, uc,ud,ue,ua,ub); sha1Round1(chunk, 19, ub,uc,ud,ue,ua); + sha1Round2(chunk, 20, ua,ub,uc,ud,ue); sha1Round2(chunk, 21, ue,ua,ub,uc,ud); + sha1Round2(chunk, 22, ud,ue,ua,ub,uc); sha1Round2(chunk, 23, uc,ud,ue,ua,ub); + sha1Round2(chunk, 24, ub,uc,ud,ue,ua); sha1Round2(chunk, 25, ua,ub,uc,ud,ue); + sha1Round2(chunk, 26, ue,ua,ub,uc,ud); sha1Round2(chunk, 27, ud,ue,ua,ub,uc); + sha1Round2(chunk, 28, uc,ud,ue,ua,ub); sha1Round2(chunk, 29, ub,uc,ud,ue,ua); + sha1Round2(chunk, 30, ua,ub,uc,ud,ue); sha1Round2(chunk, 31, ue,ua,ub,uc,ud); + sha1Round2(chunk, 32, ud,ue,ua,ub,uc); sha1Round2(chunk, 33, uc,ud,ue,ua,ub); + sha1Round2(chunk, 34, ub,uc,ud,ue,ua); sha1Round2(chunk, 35, ua,ub,uc,ud,ue); + sha1Round2(chunk, 36, ue,ua,ub,uc,ud); sha1Round2(chunk, 37, ud,ue,ua,ub,uc); + sha1Round2(chunk, 38, uc,ud,ue,ua,ub); sha1Round2(chunk, 39, ub,uc,ud,ue,ua); + sha1Round3(chunk, 40, ua,ub,uc,ud,ue); sha1Round3(chunk, 41, ue,ua,ub,uc,ud); + sha1Round3(chunk, 42, ud,ue,ua,ub,uc); sha1Round3(chunk, 43, uc,ud,ue,ua,ub); + sha1Round3(chunk, 44, ub,uc,ud,ue,ua); sha1Round3(chunk, 45, ua,ub,uc,ud,ue); + sha1Round3(chunk, 46, ue,ua,ub,uc,ud); sha1Round3(chunk, 47, ud,ue,ua,ub,uc); + sha1Round3(chunk, 48, uc,ud,ue,ua,ub); sha1Round3(chunk, 49, ub,uc,ud,ue,ua); + sha1Round3(chunk, 50, ua,ub,uc,ud,ue); sha1Round3(chunk, 51, ue,ua,ub,uc,ud); + sha1Round3(chunk, 52, ud,ue,ua,ub,uc); sha1Round3(chunk, 53, uc,ud,ue,ua,ub); + sha1Round3(chunk, 54, ub,uc,ud,ue,ua); sha1Round3(chunk, 55, ua,ub,uc,ud,ue); + sha1Round3(chunk, 56, ue,ua,ub,uc,ud); sha1Round3(chunk, 57, ud,ue,ua,ub,uc); + sha1Round3(chunk, 58, uc,ud,ue,ua,ub); sha1Round3(chunk, 59, ub,uc,ud,ue,ua); + sha1Round4(chunk, 60, ua,ub,uc,ud,ue); sha1Round4(chunk, 61, ue,ua,ub,uc,ud); + sha1Round4(chunk, 62, ud,ue,ua,ub,uc); sha1Round4(chunk, 63, uc,ud,ue,ua,ub); + sha1Round4(chunk, 64, ub,uc,ud,ue,ua); sha1Round4(chunk, 65, ua,ub,uc,ud,ue); + sha1Round4(chunk, 66, ue,ua,ub,uc,ud); sha1Round4(chunk, 67, ud,ue,ua,ub,uc); + sha1Round4(chunk, 68, uc,ud,ue,ua,ub); sha1Round4(chunk, 69, ub,uc,ud,ue,ua); + sha1Round4(chunk, 70, ua,ub,uc,ud,ue); sha1Round4(chunk, 71, ue,ua,ub,uc,ud); + sha1Round4(chunk, 72, ud,ue,ua,ub,uc); sha1Round4(chunk, 73, uc,ud,ue,ua,ub); + sha1Round4(chunk, 74, ub,uc,ud,ue,ua); sha1Round4(chunk, 75, ua,ub,uc,ud,ue); + sha1Round4(chunk, 76, ue,ua,ub,uc,ud); sha1Round4(chunk, 77, ud,ue,ua,ub,uc); + sha1Round4(chunk, 78, uc,ud,ue,ua,ub); sha1Round4(chunk, 79, ub,uc,ud,ue,ua); + + // Add the working vars back into state + state->h0 += ua; + state->h1 += ub; + state->h2 += uc; + state->h3 += ud; + state->h4 += ue; + + // Wipe variables +#ifdef SHA1_WIPE_VARIABLES + ua = ub = uc = ud = ue = 0; + memset(chunkBuffer, 0, 64); +#endif +} + +static inline void sha1InitState(Sha1State *state) +{ + state->h0 = 0x67452301; + state->h1 = 0xEFCDAB89; + state->h2 = 0x98BADCFE; + state->h3 = 0x10325476; + state->h4 = 0xC3D2E1F0; + + state->messageSize = 0; +} + +static inline void sha1Update(Sha1State *state, const unsigned char *data, gint64 len) +{ + quint32 rest = static_cast(state->messageSize & Q_UINT64_C(63)); + + quint64 availableData = static_cast(len) + static_cast(rest); + state->messageSize += len; + + if (availableData < Q_UINT64_C(64)) + { + memcpy(&state->buffer[rest], &data[0], len); + } + else + { + gint64 nIter = static_cast(64 - rest); + memcpy(&state->buffer[rest], &data[0], static_cast(nIter)); + sha1ProcessChunk(state, state->buffer); + + gint64 lastI = len - ((len + rest) & Q_INT64_C(63)); + for( ; nIter < lastI; nIter += 64) + sha1ProcessChunk(state, &data[nIter]); + + memcpy(&state->buffer[0], &data[nIter], len - nIter); + } +} + +static inline void sha1FinalizeState(Sha1State *state) +{ + quint64 messageSize = state->messageSize; + unsigned char sizeInBits[8]; + qToBigEndian(messageSize << 3, sizeInBits); + + sha1Update(state, (const unsigned char *)"\200", 1); + + unsigned char zero[64]; + memset(zero, 0, 64); + if (static_cast(messageSize & 63) > 56 - 1) + { + sha1Update(state, zero, 64 - 1 - static_cast(messageSize & 63)); + sha1Update(state, zero, 64 - 8); + } + else + { + sha1Update(state, zero, 64 - 1 - 8 - static_cast(messageSize & 63)); + } + + sha1Update(state, sizeInBits, 8); +#ifdef SHA1_WIPE_VARIABLES + memset(state->buffer, 0, 64); + memset(zero, 0, 64); + state->messageSize = 0; +#endif +} + +//static inline void sha1ToHash(Sha1State *state, unsigned char* buffer) +//{ +// qToBigEndian(state->h0, buffer); +// qToBigEndian(state->h1, buffer + 4); +// qToBigEndian(state->h2, buffer + 8); +// qToBigEndian(state->h3, buffer + 12); +// qToBigEndian(state->h4, buffer + 16); +//} + + +GString getSHA1(const unsigned char *buffer, size_t bufSize) +{ + SHA1Digest digest; + SHA1HashBuffer(digest, buffer, bufSize); + GString result; + for (int i = 0; i != 20; ++i) + { + result.append(intToHex(digest.bytes[i], 2)); + } + return result; +} + +GString getSHA1(GStream *stream) +{ + SHA1Digest digest; + SHA1HashStream(digest, stream); + GString result; + for (int i = 0; i != 20; ++i) + { + result.append(intToHex(digest.bytes[i], 2)); + } + return result; +} + +void Sha1StateToSHA1Digest(const Sha1State &state, SHA1Digest &digest) +{ + gMemMove(&digest, &state, 20); + for (byte i = 0; i != 5; ++i) + { + for (byte j = 0; j != 2; ++j) + { + byte byteValue = digest.bytes[i * 4 + j]; + digest.bytes[i * 4 + j] = digest.bytes[i * 4 + 3 - j]; + digest.bytes[i * 4 + 3 - j] = byteValue; + } + } +} + +void SHA1HashBuffer(SHA1Digest &digest, const unsigned char *buffer, size_t bufSize) +{ + Sha1State state; + sha1InitState(&state); + sha1Update(&state, buffer, bufSize); + sha1FinalizeState(&state); + Sha1StateToSHA1Digest(state, digest); +} + +static inline void sha1UpdateStream(Sha1State *state, GStream *stream) +{ + gint64 len = stream->size() - stream->pos(); + quint32 rest = static_cast(state->messageSize & Q_UINT64_C(63)); + + quint64 availableData = static_cast(len) + static_cast(rest); + state->messageSize += len; + + if (availableData < Q_UINT64_C(64)) + { + //memcpy(&state->buffer[rest], &data[0], len); + stream->read((char *)(&state->buffer[rest]), len); + } + else + { + gint64 nIter = static_cast(64 - rest); + //memcpy(&state->buffer[rest], &data[0], static_cast(i)); + stream->read((char *)(&state->buffer[rest]), static_cast(nIter)); + sha1ProcessChunk(state, state->buffer); + + gint64 lastI = len - ((len + rest) & Q_INT64_C(63)); + unsigned char buf[64]; + for( ; nIter < lastI; nIter += 64) + { + //sha1ProcessChunk(state, &data[i]); + stream->read((char *)&buf[0], 64); + sha1ProcessChunk(state, &buf[0]); + } + //memcpy(&state->buffer[0], &data[i], len - i); + stream->read((char *)(&state->buffer[0]), len - nIter); + } +} + +void SHA1HashStream(SHA1Digest &digest, GStream *stream) +{ + Sha1State state; + sha1InitState(&state); + sha1UpdateStream(&state, stream); + sha1FinalizeState(&state); + Sha1StateToSHA1Digest(state, digest); +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDSingleInstance.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDSingleInstance.cpp new file mode 100644 index 00000000..3fee97c5 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDSingleInstance.cpp @@ -0,0 +1,53 @@ +#include "GLDSingleInstance.h" + +class GLDUniqueAppInstancePrivate +{ +public: + GLDUniqueAppInstancePrivate(GLDUniqueAppInstance *parent) + : q_ptr(parent) + { + } + +private: + GLDUniqueAppInstance * const q_ptr; + Q_DECLARE_PUBLIC(GLDUniqueAppInstance); + + bool m_isRunning; + GString m_uniqueKey; + QSharedMemory m_sharedMemory; +}; + +GLDUniqueAppInstance::GLDUniqueAppInstance(const GString &uniqueKey) + : d_ptr(new GLDUniqueAppInstancePrivate(this)) + +{ + Q_D(GLDUniqueAppInstance); + d->m_uniqueKey = uniqueKey; + d->m_sharedMemory.setKey(d->m_uniqueKey); + if (d->m_sharedMemory.attach()) + { + d->m_isRunning = true; + } + else + { + d->m_isRunning = false; + // create shared memory. + if (!d->m_sharedMemory.create(1)) + { + qDebug("Unable to create single instance."); + return; + } + } +} + +GLDUniqueAppInstance::~GLDUniqueAppInstance() +{ + Q_D(GLDUniqueAppInstance); + freePtr(d); +} + +bool GLDUniqueAppInstance::isRunning() +{ + Q_D(GLDUniqueAppInstance); + return d->m_isRunning; +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDSortUtils.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDSortUtils.cpp new file mode 100644 index 00000000..7cac73fa --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDSortUtils.cpp @@ -0,0 +1,48 @@ +#include "GLDSortUtils.h" + +void fast_sort(int *ptr, int begin, int end) +{ + if (!ptr) + { + return; + } + int nTemp = *(ptr + begin);//设置初始比较基准数据 + int nIt1 = begin + 1; + int nIt2 = end; + int nCurPosition = begin;//定义开头和结尾的I j + bool bDirection = false; + while (nIt1 <= nIt2) + { + if (bDirection) + { + if (*(ptr + nIt1) < nTemp)//如果当前数据小于基准数据 那么换位置 改当前位置 + { + *(ptr + nCurPosition) = *(ptr + nIt1); + nCurPosition = nIt1; + bDirection = false; + } + nIt1++; + } + else + { + //先从后到前比较数据 + if (*(ptr + nIt2) > nTemp) + {//如果最后一个大于基准 那么最后一个数据赋值给当前基准数据的那个位置 调整基准数据的位置 + *(ptr + nCurPosition) = *(ptr + nIt2);// + nCurPosition = nIt2; + bDirection = true; + } + nIt2--; + } + } + + *(ptr + nCurPosition) = nTemp; + if (nCurPosition - begin > 1)//前面小的比较 + { + fast_sort(ptr, begin, nCurPosition - 1); + } + if (end - nCurPosition > 1)//后面大的比较 + { + fast_sort(ptr, nCurPosition + 1, end); + } +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDStrUtils.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDStrUtils.cpp new file mode 100644 index 00000000..30810cfc --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDStrUtils.cpp @@ -0,0 +1,2132 @@ +#ifdef WIN32 +# include +#else + +#endif +#include + +#include +#include + +#include "GLDStrUtils.h" +#include "GLDSysUtils.h" +#include "GLDMathUtils.h" +#include "GLDException.h" +#include "GLDStrings.h" +#include "GLDStream.h" + +typedef QTextCodec GTextCodec; + +const int c_HoursPerDay = 24; +const int c_MinsPerHour = 60; +const int c_SecsPerMin = 60; +const int c_MSecsPerSec = 1000; +const int c_MinsPerDay = c_HoursPerDay * c_MinsPerHour; +const int c_SecsPerDay = c_MinsPerDay * c_SecsPerMin; +const int c_MSecsPerDay = c_SecsPerDay * c_MSecsPerSec; + +static GTextCodec *s_gldGBKCodec = NULL; +static GTextCodec *s_gldUTF8Codec = NULL; + +#ifdef WIN32 + DEFINE_RESOURCESTRING(sLineBreak, "\r\n"); +#else + DEFINE_RESOURCESTRING(sLineBreak, "\r"); +#endif + +class GLDTextCodec +{ +public: + static GTextCodec *codecForGBK(); + static GTextCodec *codecForUTF8(); + static GTextCodec *codecForLocale(); +}; + +/* GLDTextCodec */ + +GTextCodec *GLDTextCodec::codecForGBK() +{ + if (!s_gldGBKCodec) + { + s_gldGBKCodec = GTextCodec::codecForName("GBK"); + assert(s_gldGBKCodec); + } + return s_gldGBKCodec; +} + +GTextCodec *GLDTextCodec::codecForUTF8() +{ + if (!s_gldUTF8Codec) + { + s_gldUTF8Codec = GTextCodec::codecForName("UTF-8"); + assert(s_gldUTF8Codec); + } + return s_gldUTF8Codec; +} + +GTextCodec *GLDTextCodec::codecForLocale() +{ + return GTextCodec::codecForLocale(); +} + +// public +/* +//获取C风格字符串(\0结尾的字符串)的长度 +size_t CStrLength(const char *sz) +{ + int i = 0; + while (sz[i]) + { + ++i; + } + return i; +} + +size_t CStrLength(const wchar_t *wsz) +{ + return WideCStrLength(wsz); +} + +size_t WideCStrLength(const wchar_t *wsz) +{ + int i = 0; + while (wsz[i]) + { + i++; + } + return i; +} + +wchar_t *WideLowerCase(wchar_t **ppWsz) +{ + GString s((const GChar *)(*ppWsz)); + s = s.toLower(); + wstring ws = s.toLower().toStdWString(); + + wchar_t *wCh = new wchar_t[ws.size() + 1]; + wCh[ws.size()] = '\0'; + for (int i = 0; i < int(ws.size()); ++i) + { + wCh[i] = ws[i]; + } + return wCh; +} + +//比较两个字符串,大小写敏感 +bool SameStr(const char *szA, const char *szB) +{ + return 0 == strcmp(szA, szB); +} + +//比较两个字符串,大小写敏感,宽字符版本 +bool WideSameStr(const wchar_t *wszA, const wchar_t *wszB) +{ + return 0 == wcscmp(wszA, wszB); +} + +//比较两个字符串,大小写不敏感 +bool SameText(const char *szA, const char *szB) +{ +#ifdef WIN32 + return 0 == _stricmp(szA, szB); +#else + return 0 == strcasecmp(szA, szB); +#endif +} + +//比较两个字符串,大小写不敏感,宽字符版本 +bool WideSameText(const wchar_t *wszA, const wchar_t *wszB) +{ +#ifdef WIN32 + return 0 == _wcsicmp(wszA, wszB); +#else + return 0 == sameText(GString((const GChar *)wszA), + GString((const GChar *)wszB)); +#endif +} + +wchar_t *charToWchar(const char *str) +{ + wchar_t* buffer; + if(str) + { + size_t nu = strlen(str); + size_t n =(size_t)MultiByteToWideChar(CP_ACP,0,(const char *)str,int(nu),NULL,0); + buffer=0; + buffer = new wchar_t[n+1]; + ::MultiByteToWideChar(CP_ACP,0,(const char *)str,int(nu),buffer,int(n)); + buffer[n] = 0; + } + return buffer; + delete buffer; +} + +char *wcharToChar(const wchar_t *pwstr) +{ + int nlength = (int)wcslen(pwstr); + //获取转换后的长度 + int nbytes = WideCharToMultiByte( 0, // specify the code page used to perform the conversion + 0, // no special flags to handle unmapped characters + pwstr, // wide character string to convert + nlength, // the number of wide characters in that string + NULL, // no output buffer given, we just want to know how long it needs to be + 0, + NULL, // no replacement character given + NULL ); // we don't want to know if a character didn't make it + // through the translation + char *pcstr = new char[nbytes + 1]; + // 通过以上得到的结果,转换unicode 字符为ascii 字符 + WideCharToMultiByte( 0, // specify the code page used to perform the conversion + 0, // no special flags to handle unmapped characters + pwstr, // wide character string to convert + nlength, // the number of wide characters in that string + pcstr, // put the output ascii characters at the end of the buffer + nbytes, // there is at least this much space there + NULL, // no replacement character given + NULL ); + pcstr[nbytes] = 0; + return pcstr; +} +*/ + +GString utf8ToUnicode(const char *in, int length) +{ + return GLDTextCodec::codecForUTF8()->toUnicode( + in, (-1 != length) ? length : (int)strlen(in)); +} + +GByteArray unicodeToUTF8(const GChar *in, int length) +{ + return GLDTextCodec::codecForUTF8()->fromUnicode( + in, (-1 != length) ? length : (int)wcslen((const wchar_t *)in)); +} + +GString asciiToUnicode(const char *in, int length, const char *name) +{ + if (name == NULL) + { + return GLDTextCodec::codecForLocale()->toUnicode( + in, (-1 != length) ? length : (int)strlen(in)); + } + else + { + return GTextCodec::codecForName(name)->toUnicode( + in, (-1 != length) ? length : (int)strlen(in)); + } + +} + +GByteArray unicodeToAscii(const GChar *in, int length, const char *name) +{ + if (name == NULL) + { + return GLDTextCodec::codecForGBK()->fromUnicode( + in, (-1 != length) ? length : (int)wcslen((const wchar_t *)in)); + } + else + { + return GTextCodec::codecForName(name)->fromUnicode( + in, (-1 != length) ? length : (int)wcslen((const wchar_t *)in)); + } +} + +GString gbkToUnicode(const char *in, int length) +{ + return GLDTextCodec::codecForGBK()->toUnicode( + in, (-1 != length) ? length : (int)strlen(in)); +} + +GByteArray unicodeToGBK(const GChar *in, int length) +{ + return GLDTextCodec::codecForGBK()->fromUnicode( + in, (-1 != length) ? length : (int)wcslen((const wchar_t *)in)); +} + +GString ansiUpperCase(const GString &value) +{ + return value.toUpper(); +} + +GString ansiLowerCase(const GString &value) +{ + return value.toLower(); +} + +GString upperCase(const GString &value) +{ + return value.toUpper(); +} + +GString lowerCase(const GString &value) +{ + return value.toLower(); +} + +char upperCase(const char ch) +{ + GChar chStr(ch); + return chStr.toUpper().toLatin1(); +} + +char lowerCase(const char ch) +{ + GChar chStr(ch); + return chStr.toLower().toLatin1(); +} + +wchar_t upperCase(const wchar_t ch) +{ + if ((int)ch > 256) + { + return ch; + } + GChar chStr(ch); + return chStr.toUpper().toLatin1(); +} + +wchar_t lowerCase(const wchar_t ch) +{ + if ((int)ch > 256) + { + return ch; + } + GChar chStr(ch); + return chStr.toLower().toLatin1(); +} + +int compareStr(const GStringRef &s1, const GStringRef &s2) +{ + return GStringRef::compare(s1, s2, Qt::CaseSensitive); +} + +int compareStr(const GStringRef &s1, const GString &s2) +{ + return s1.compare(s2, Qt::CaseSensitive); +} + +// call CompareString : 'A' > 'a' > '9' > '0' +int compareStr(const GString &s1, const GString &s2) +{ + return GString::localeAwareCompare(s1, s2); +} + +int compareStr(const GByteArray &s1, const GByteArray &s2) +{ + return strcmp(s1.constData(), s2.constData()); +} + +int compareText(const GStringRef &s1, const GStringRef &s2) +{ + return s1.compare(s1, s2, Qt::CaseInsensitive); +} + +int compareText(const GStringRef &s1, const GString &s2) +{ + return s1.compare(s2, Qt::CaseInsensitive); +} + +int compareText(const GString &s1, const GString &s2) +{ + return GString::localeAwareCompare(s1.toUpper(), s2.toUpper()); +} + +int compareText(const GByteArray &s1, const GByteArray &s2) +{ +#ifdef WIN32 + return _stricmp(s1.constData(), s2.constData()); +#else + return strcasecmp(s1.constData(), s2.constData()); +#endif +} + +// 如果类型不匹配则抛异常 +GLDValueRelationship compareGVariant(const GVariant &v1, const GVariant &v2) +{ + if (!v1.isValid() || !v2.isValid() || v1.isNull() || v2.isNull()) + { + if (!v1.isValid() || !v2.isValid()) + { + return v1.isValid() == v2.isValid() ? gvrEqualsValue : (v1.isValid() ? gvrGreaterThanValue : gvrLessThanValue); + } + else + { + return v1.isNull() == v2.isNull() ? gvrEqualsValue : (!v1.isNull() ? gvrGreaterThanValue : gvrLessThanValue); + } + } + GVariant::Type t1 = v1.type(); + GVariant::Type t2 = v2.type(); + if (t1 == t2) + { + if (variantTypeIsUnsigned(t1)) + { + unsigned long long n1 = v1.toULongLong(); + unsigned long long n2 = v2.toULongLong(); + return compareDigit(n1, n2); + } + else if (variantTypeIsDigit(t1)) + { + long long ll1 = v1.toLongLong(); + long long ll2 = v2.toLongLong(); + return compareDigit(ll1, ll2); + } + else if (variantTypeIsDateTime(t1)) + { + GDateTime n1 = v1.toDateTime(); + GDateTime n2 = v2.toDateTime(); + return compareDigit(n1, n2); + } + else if (variantTypeIsNumeric(t1) && variantTypeIsNumeric(t2)) + { + double d1 = v1.toDouble(); + double d2 = v2.toDouble(); + if (sameValue(d1, d2)) + { + return gvrEqualsValue; + } + return compareDigit(d1, d2); + } + else if (t1 == GVariant::ByteArray) + { + return GLDValueRelationship(compareStr(v1.toByteArray(), v2.toByteArray())); // todo 优化 + } + else if (t1 == GVariant::String) + { + return GLDValueRelationship(compareStr(v1.toString(), v2.toString())); + } + else if (t1 == GVariant::Uuid) + { + return GLDValueRelationship(compareGUID(variantToGUID(v1.toUuid()), variantToGUID(v2.toUuid()))); + } + else if (t1 == GVariant::Bool) + { + if (v1 == v2) + { + return gvrEqualsValue; + } + else if (v1.toBool()) + { + return gvrGreaterThanValue; + } + else + { + return gvrLessThanValue; + } + } + else + { + if (v1 == v2) + { + return gvrEqualsValue; + } + gldError(getGLDi18nStr(g_InvalidTypeCompare)); + return gvrEqualsValue; + } + } + else if (variantTypeIsDigit(t1) && variantTypeIsDigit(t2)) + { + if (variantTypeIsUnsigned(t1) || variantTypeIsUnsigned(t2)) + { + unsigned long long n1 = v1.toULongLong(); + unsigned long long n2 = v2.toULongLong(); + return compareDigit(n1, n2); + } + else + { + long long ll1 = v1.toLongLong(); + long long ll2 = v2.toLongLong(); + return compareDigit(ll1, ll2); + } + } + else if (variantTypeIsNumeric(t1) && variantTypeIsNumeric(t2)) + { + double d1 = v1.toDouble(); + double d2 = v2.toDouble(); + if (sameValue(d1, d2)) + { + return gvrEqualsValue; + } + return compareDigit(d1, d2); + } + else + { + if (v1 == v2) + { + return gvrEqualsValue; + } + else + { + // no exception + return gvrGreaterThanValue; + } + } +} + +bool sameGVariant(const GVariant &v1, const GVariant &v2) +{ + if (variantTypeIsFloat(v1.type()) || variantTypeIsFloat(v2.type())) + { + // 只要有一个不是数字则不等 + if (!variantTypeIsNumeric(v1.type()) || !variantTypeIsNumeric(v2.type())) + { + return false; + } + double d1 = v1.toDouble(); + double d2 = v2.toDouble(); + if (sameValue(d1, d2)) + { + return true; + } + else + { + return false; + } + } + return v1 == v2; +} + +// 区分大小写 +bool sameStr(const GString &s1, const GString &s2) +{ + return s1 == s2; +} + +int length(const GString &s) +{ + return s.length(); +} + +int pos(const GString &subs, const GString &s) +{ + if ((subs.length() == 0) || (s.length() == 0)) + { + return -1; + } + return s.indexOf(subs); +} + +int pos(const GChar &subs, const GString &s) +{ + if (s.length() == 0) + { + return -1; + } + return s.indexOf(subs); +} + +int pos(const GString &subs, const GString &s, int nFrom) +{ + if ((subs.length() == 0) || (s.length() == 0)) + { + return -1; + } + return s.indexOf(subs, nFrom); +} + +int rPos(const GString &subs, const GString &s, int times) +{ + if ((subs.length() == 0) || (s.length() == 0)) + { + return -1; + } + assert(times >= 1); + int result = 0; + for (int i = 1; i <= times; ++i) + { + result = s.lastIndexOf(subs, result - 1); + if (-1 == result) + break; + } + return result; +} + +int rPos(const GChar &subs, const GString &s, int times) +{ + if (s.length() == 0) + { + return -1; + } + assert(times >= 1); + int result = 0; + for (int i = 1; i <= times; ++i) + { + result = s.lastIndexOf(subs, result - 1); + if (-1 == result) + break; + } + return result; +} + +int rPosEx(const GChar &subs, const GString &s, int offset) +{ + if (s.length() == 0) + { + return -1; + } + return s.lastIndexOf(subs, offset); +} + +GString trim(const GString &s) +{ + return s.trimmed(); +} + +GString trimRight(const GString &s) +{ + int nIter = s.length() - 1; + while ((nIter >= 0) && (s[nIter] <= ' ')) + { + nIter--; + } + return copy(s, 0, nIter + 1); +} + +GString trimLeft(const GString &s) +{ + int nLen = s.length() - 1; + int nIter = 0; + while ((nIter <= nLen) && (s[nIter] <= ' ')) + { + nIter++; + } + return copy(s, nIter, nLen + 1); +} + +GString copy(const GString &s, int position, int n) +{ + if (position < 0) + { + position = 0; + } + if (n == MaxInt) + { + n = -1; + } + return s.mid(position, n); +} + +GString stringReplace(const GString &s, const GString &before, const GString &after) +{ + GString result = s; + result.replace(before, after); + return result; +} + +bool containsText(const GString &text, const GString subText) +{ + return pos(upperCase(subText), upperCase(text)) >= 0; +} + +GString leftStr(const GString &text, int count) +{ + return text.left(count); +} + +GString rightStr(const GString &text, int count) +{ + return text.right(count); +} + +GStringList split(const GString &s, GChar sep) +{ + if (s == "") + return GStringList(); + else + return s.split(sep); +} + +GStringList split(const GString &s, const GString &sep) +{ + if (s == "") + return GStringList(); + else + return s.split(sep); +} + +bool isInt(const GString &s) +{ + bool result = false; + s.toInt(&result); + return result; +} + +bool isInt64(const GString &s) +{ + bool result = false; + s.toLongLong(&result); + return result; +} + +bool isNumeric(const GString &s) +{ + bool result = false; + if (s.contains('e', Qt::CaseInsensitive)) + { + GString value = s.toLower(); + // 找到最后一个e + int nIndex = rPos('e', value); + // 找到e后的最后一个点 + nIndex = rPos('.', value); + if (nIndex > 0) + { + bool bIncludeNoZero = false; + // 判断最后一个点后是否全都是非0 + for (int i = nIndex + 1; i < value.length(); ++i) + { + if (value[i] != '0') + { + bIncludeNoZero = true; + break; + } + } + // 如果最后一个点后全都是0,则去掉点和0 + if (!bIncludeNoZero) + { + value = value.mid(0, nIndex); + } + // 重新检查是否合法 + value.toDouble(&result); + return result; + } + } + s.toDouble(&result); + return result; +} + +bool isDateTime(const GString &s) +{ + bool result = false; + s.toDouble(&result); + return result; +} + +bool charIsDigit(const GChar &ch) +{ + return ch.isDigit(); +} + +bool variantTypeIsByte(const GVariant::Type type) +{ + return (type == GVariant::Char) + || (type == (GVariant::Type)QMetaType::UChar) + || (type == (GVariant::Type)QMetaType::SChar); +} + +bool variantTypeIsShort(const GVariant::Type type) +{ + return (type == (GVariant::Type)QMetaType::Short) + || (type == (GVariant::Type)QMetaType::UShort); +} + +bool variantTypeIsInt(const GVariant::Type type) +{ + return (type == GVariant::Int) || (type == GVariant::UInt) + || (type == (GVariant::Type)QMetaType::Long) + || (type == (GVariant::Type)QMetaType::ULong); +} + +bool variantTypeIsDigit(const GVariant::Type type) +{ + return (type >= QVariant::Int && type <= QVariant::ULongLong) + || (type >= (GVariant::Type)QMetaType::Long && type <= (GVariant::Type)QMetaType::UChar) + || (type == (GVariant::Type)QMetaType::SChar); + //return variantTypeIsByte(type) || variantTypeIsShort(type) || + // variantTypeIsInt(type) || variantTypeIsInt64(type); +} + +bool variantTypeIsFloat(const GVariant::Type type) +{ + return (type == GVariant::Double) || (type == (GVariant::Type)QMetaType::Float); +} + +bool variantTypeIsNumeric(const GVariant::Type type) +{ + return (type >= QVariant::Int && type <= QVariant::Double) + || (type >= (GVariant::Type)QMetaType::Long && type <= (GVariant::Type)QMetaType::Float) + || (type == (GVariant::Type)QMetaType::SChar); + //return variantTypeIsDigit(type) || variantTypeIsFloat(type); +} + +bool variantTypeIsDateTime(const GVariant::Type type) +{ + return (type == GVariant::Date) || (type == GVariant::Time) || (type == GVariant::DateTime); +} + +bool variantTypeIsUnsigned(const QVariant::Type type) +{ + return (type == (GVariant::Type)QMetaType::UChar) + || (type == (GVariant::Type)QMetaType::UShort) + || (type == (GVariant::Type)QMetaType::ULong) + || (type == GVariant::UInt) + || (type == GVariant::ULongLong); +} + +#ifdef WIN32 +size_t getBSTRLen(const BSTR & s) +{ + return ::SysStringLen(s); +} + +GString BSTRToGString(const BSTR &s) +{ +#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) + return GString::fromUtf16((ushort *)s, (int)getBSTRLen(s)); +#else + return GString::fromUtf16(s, BSTRLen(s)); +#endif +} + +BSTR GStringToBSTR(const GString & s) +{ + BSTR result = NULL; + if (length(s) != 0) + { + result = ::SysAllocString((wchar_t *)s.unicode()); + } + return result; +} + +void freeBSTR(BSTR & s) +{ + ::SysFreeString(s); +} + +#endif + +void checkFormatDataType(QChar ch, GVariant &v) +{ + ch = ch.toLower(); + GVariant::Type type = v.type(); + if (ch == QLatin1Char('s')) + { + if (type != GVariant::String) + { + gldError("format '%s' invalid or incompatible with argument."); + } + } + else if (ch == QLatin1Char('d')) + { + if (!variantTypeIsDigit(type)) + { + gldError("format '%d' invalid or incompatible with argument."); + } + } + else if (ch == QLatin1Char('u')) + { + if (!variantTypeIsDigit(type)) + gldError("format '%u' invalid or incompatible with argument."); + v = GVariant((unsigned int)(v.toInt())); + } + else if (ch == QLatin1Char('f')) + { + if (!variantTypeIsDigit(type) && !variantTypeIsFloat(type)) + gldError("format '%f' invalid or incompatible with argument."); + v = GString::number(v.toDouble(), 14, 2); + } + else if (ch == QLatin1Char('g')) + { + if (!variantTypeIsDigit(type) && !variantTypeIsFloat(type)) + gldError("format '%g' invalid or incompatible with argument."); + } + else if (ch == QLatin1Char('n')) + { + if (!variantTypeIsDigit(type) && !variantTypeIsFloat(type)) + gldError("format '%n' invalid or incompatible with argument."); + } + else if (ch == QLatin1Char('m')) + { + if (!variantTypeIsDigit(type) && !variantTypeIsFloat(type)) + gldError("format '%m' invalid or incompatible with argument."); + } + else if (ch == QLatin1Char('x')) + { + if (!variantTypeIsDigit(type)) + gldError("format '%x' invalid or incompatible with argument."); + v = GString::number(v.toLongLong(), 16).toUpper(); + } + else if (!ch.isDigit()) + { + gldError("format '%' invalid or incompatible with argument."); + } +} + +GString format(const GString &s, const GVariantList &a) +{ + GString result; + int nLength = s.length(); + const QChar *data = s.constData(); + int nBefore = 0; + int nIndex = 0; + for (int i = 0; i < nLength; ++i) + { + if (data[i] == QLatin1Char('%')) + { + result.append(s.mid(nBefore, i - nBefore)); + ++i; + if (i == nLength) + { + nBefore = nLength; + break; + } + + nBefore = i + 1; + QChar ch = data[i]; + if (ch == QLatin1Char('%')) + { + result.append(QLatin1Char('%')); + } + else + { + GVariant var = a.at(nIndex); + if (nIndex == a.count()) + gldError("format '%' invalid or incompatible with argument."); + checkFormatDataType(ch, var); + result.append(var.toString()); + ++nIndex; + } + } + } + result.append(s.mid(nBefore, nLength - nBefore)); + return result; +} + +GString format(const GString &s, const GString &after, const GString &before) +{ + GString result = s; + int nIndex = result.indexOf(before); + if (nIndex >= 0) + { + //result.replace(i, before.length(), after); + result.remove(nIndex, length(before)); + result.insert(nIndex, after); + } + else + result = result.arg(after); + return result; +} + +GString format(const GString &s, const GChar &after, const GString &before) +{ + return format(s, GString(after), before); +} + +GString format(const GString &s, int a) +{ + return format(s, intToStr(a), "%d"); +} + +GString format(const GString &s, long a) +{ + return format(s, intToStr(a), "%d"); +} + +GString format(const GString &s, ULONGLONG a) +{ + return format(s, uint64ToStr(a), "%ld"); +} + +GString format(const GString &s, long long a) +{ + return format(s, int64ToStr(a), "%ld"); +} + +GString format(const GString &s, double a) +{ + return format(s, floatToStr(a), "%lf"); +} + +//GString format(const GString &s, const GVariant &a) +//{ +// switch (a.type()) +// { +// case GVariant::UInt: +// case GVariant::Int: +// return format(s, a.toInt()); +// case GVariant::LongLong: +// return format(s, a.toLongLong()); +// case GVariant::ULongLong: +// return format(s, a.toULongLong()); +// case GVariant::Double: +// return format(s, a.toDouble()); +// case GVariant::String: +// return format(s, a.toString()); +// case GVariant::ByteArray: +// return format(s, GString(a.toByteArray())); +// case GVariant::Uuid: +// return format(s, GString(a.toString())); +// default: +// break; +// } +// return GString(); +//} + +GString boolToStr(bool a, bool useBoolStrs) +{ + if (useBoolStrs) + { + if (a) + return "True"; + else + return "False"; + } + else + { + if (a) + return "1"; + else + return "0"; + } +} + +bool strToBool(const GString &s) +{ + if (s.isEmpty()) + return false; + else if (s[0].toUpper() == 'T') + return true; + else if (s[0].toUpper() == '1') + return true; + else + return false; +} + +bool strToBoolDef(const GString &s, bool def) +{ + if (s.isEmpty()) + return def; + else if (s[0].toUpper() == 'T') + return true; + else if (s[0].toUpper() == 'F') + return false; + else if (s[0].toUpper() == '1') + return true; + else if (s[0].toUpper() == '0') + return false; + else + return def; +} + +GString intToStr(int a) +{ +#ifdef _WIN32 + char str[20]; + memset(str, '\0', 20); + _itoa_s(a, str, 10); + GString result = QString::fromLatin1(str); + return result; +#else + return GString::number(a, 10); +#endif +} + +GString int64ToStr(gint64 a) +{ + return GString::number(a, 10); +} + +GString uint64ToStr(guint64 a) +{ + return GString::number(a, 10); +} + +int strToInt(const GString &s) +{ + bool bOk; + int result = s.toInt(&bOk); + if (bOk) + return result; + else + { + gldError(format(getGLDi18nStr(g_InvalidInteger), s)); + return 0; + } +} + +int strToIntDef(const GString &s, int def) +{ + bool bOk; + int result = s.toInt(&bOk); + if (bOk) + return result; + else + return def; +} + +gint64 strToInt64(const GString &s, int base) +{ + bool bOk; + gint64 result = s.toLongLong(&bOk, base); + if (bOk) + return result; + else + throw GLDException(format(getGLDi18nStr(g_InvalidInteger), s)); +} + +gint64 strToInt64Def(const GString &s, gint64 def) +{ + bool bOk; + gint64 result = s.toLongLong(&bOk); + if (bOk) + return result; + else + return def; +} + +GString floatToStr(double a) +{ + // 为了跟fRound匹配, 浮点数显示14位有效数字 + // 为了跟delphi保持一致, 浮点数显示15位有效数字 + if ((fabs(a) < 2e9) && (sameValue(itrunc(a), a, 1e-307))) + { + return intToStr(a); + } + else + { + //把结果格式化进入字符串 + char pbufer[32]; + sprintf_s(pbufer, 32, "%.15g", a);//格式化字符串 + QString result = GString(GLatin1String(pbufer));//将char转换成GString + return result; + +// QString result; +// result.setNum(a, 'g', 15); +// return result; + } +} + +double strToFloat(const GString &s) +{ + bool bOk; + double result = s.toDouble(&bOk); + if (bOk) + return result; + else + throw GLDException(format(getGLDi18nStr(g_InvalidFloat), s)); +} + +double strToFloatDef(const GString &s, double def) +{ + bool bOk; + double result = s.toDouble(&bOk); + if (bOk) + return result; + else + return def; +} + +GString dateTimeToStr(const GDateTime &datetime, GString format) +{ + if (datetime.time() == GTime(0, 0, 0)) + format = format.mid(0, format.indexOf(' '));//日期为整时 yyyy-MM-dd hh:mm:ss --->yyyy-MM-dd + return datetime.toString(format); +} + +GDateTime strToDateTime(const GString &s, GString format) +{ + if (s.indexOf(' ') < 0) + { + int nIndex = format.indexOf(' '); + if (nIndex >= 0) + format = format.mid(0, nIndex); + } + GDateTime result = GDateTime::fromString(s, format); + if (!result.isValid()) + { + result = GDateTime::fromString(s, Qt::ISODate); + } + return result; +} + +GString byteArrayToStr(const GByteArray &a) +{ + return GString(a); +} + +GByteArray strToByteArray(const GString &s) +{ + return s.toLocal8Bit(); +} + +GString intToHex(int value, int digits) +{ + GString val = GString::number(value, 16).toUpper(); + if (val.length() < digits) + val.push_front('0'); + return val; +} + +GString intToColorHex(int value, int length) +{ + GString val = GString::number(value, 16).toUpper(); + for (int i = val.length(); i < length; ++i) + { + val.push_front('0'); + } + val.push_front('#'); + return val; +} + +GString stuffString(const GString &text, int nStart, int nLength, const GString &subText) +{ + return copy(text, 0, nStart - 1).append(subText).append(copy(text, nStart + nLength - 1, MaxInt)); +} + +//////////////////////////////////////////////////////////////////////////////// +//创建:Tu Jianhua 2004.1.18 +//功能:计算分隔符在字符串中出现的次数 +//参数:delimiter -- 分隔符 +// srcStr -- 字符串串 +//返回:delimiter在字符串ASrcStr中出现的次数 +//////////////////////////////////////////////////////////////////////////////// +int occurs(const char delimiter, const GString &srcStr) +{ + int nCount = 0; + for (int i = 0; i < srcStr.length(); ++i) + { + if (delimiter == srcStr[i].unicode()) + { + nCount++; + } + } + return nCount; +} + +GByteArray base64Encode(const GByteArray &in) +{ + return in.toBase64(); +} + +GStream* base64Encode(GStream *in) +{ + if (!in) + { + return NULL; + } + return new GMemoryStream(new GByteArray(in->readAll().toBase64()), true); +} + +GByteArray base64Decode(const GByteArray &in) +{ + return GByteArray::fromBase64(in); +} + +GStream* base64Decode(GStream *in) +{ + if (!in) + { + return NULL; + } + return new GMemoryStream(new GByteArray(GByteArray::fromBase64(in->readAll())), true); +} + +GString quotedStr(const GString &str, const char quote) +{ + GString result = str; + GString quotes(2, quote); + result.replace(quote, quotes); + result.push_front(quote); + result.push_back(quote); + return result; +} + +GByteArray quotedStr(const GByteArray &str, const char quote) +{ + GByteArray result = str; + GByteArray quotes(2, quote); + result.replace(quote, quotes); + result.push_front(quote); + result.push_back(quote); + return result; +} + +GString dequotedStr(const GString &str, const char quote) +{ + GString result = str; + if (result[0] == quote) + result.remove(0, 1); + if (result[result.size() - 1] == quote) + result.remove(result.size() - 1, 1); + GString quotes(2, quote); + result.replace(quotes, GString(1, quote)); + return result; +} + +GString extractQuotedStr(GString &str, const char quote) +{ + str = dequotedStr(str, quote); + return str; +} + +GByteArray dequotedStr(const GByteArray &str, const char quote) +{ + GByteArray result = str; + if (result[0] == quote) + result.remove(0, 1); + if (result[result.size() - 1] == quote) + result.remove(result.size() - 1, 1); + GByteArray quotes(2, quote); + result.replace(quotes, GByteArray(1, quote)); + return result; +} + +GStream* stringToStream(const GString &in) +{ + return new GMemoryStream(new GByteArray(in.toLocal8Bit()), true); +} + +GString streamToString(GStream* in) +{ + if (!in) + { + return GString(); + } + return GString(in->readAll()); +} + +GStream* byteArrayToStream(const GByteArray &in) +{ + if (0 == in.size()) + { + return NULL; + } + return new GMemoryStream(new GByteArray(in), true); +} + +GByteArray streamToByteArray(GStream* in) +{ + if (!in) + { + return GByteArray(); + } + return in->readAll(); +} + +GDate intToDate(int d) +{ + return GDate(1899, 12, 30).addDays(d); +} + +int dateToInt(const GDate &date) +{ + return GDate(1899, 12, 30).daysTo(date); +} + +GTime doubleToTime(double t) +{ + t = frac(t); + int nMsec = iround(t * double(c_MSecsPerDay)); + int nSecond = itrunc(double(nMsec) / double(c_MSecsPerSec)); + nMsec = nMsec % c_MSecsPerSec; + int nMinute = itrunc(double(nSecond) / double(c_SecsPerMin)); + nSecond = nSecond % c_SecsPerMin; + int nHour = itrunc(double(nMinute) / double(c_MinsPerHour)); + nMinute = nMinute % c_MinsPerHour; + return GTime(nHour, nMinute, nSecond, nMsec); +} + +double timeToDouble(const GTime &time) +{ + return (0.0 + ((time.hour() * c_MinsPerHour + time.minute()) * c_SecsPerMin + time.second()) + * c_MSecsPerSec + time.msec()) / c_MSecsPerDay; +} + +GDateTime doubleToDateTime(double d) +{ + GDate date = intToDate(itrunc(d)); + GTime time = doubleToTime(d); + return GDateTime(date, time); +} + +double dateTimeToDouble(const GDateTime &dateTime) +{ + return dateToInt(dateTime.date()) + timeToDouble(dateTime.time()); +} + +int yearOf(double d) +{ + GDateTime dataTime = doubleToDateTime(d); + return dataTime.date().year(); +} + +int monthOf(double d) +{ + GDateTime dataTime = doubleToDateTime(d); + return dataTime.date().month(); +} + +int weekOf(double d) +{ + GDateTime dataTime = doubleToDateTime(d); + return dataTime.date().weekNumber(); +} + +int dayOf(double d) +{ + GDateTime dataTime = doubleToDateTime(d); + return dataTime.date().day(); +} + +int hourOf(double d) +{ + GTime time = doubleToTime(d); + return time.hour(); +} + +int minuteOf(double d) +{ + GTime time = doubleToTime(d); + return time.minute(); +} + +int secondOf(double d) +{ + GTime time = doubleToTime(d); + return time.second(); +} + +int milliSecondOf(double d) +{ + GTime time = doubleToTime(d); + return time.msec(); +} + +//// 返回中文平台下的时间日期格式 +//// XP 的标准样式,和 VISTA 的不同 +//GFormatSettings g_DefFormatSettings = { +// 0, +// 2, +// ',', +// '.', +// 2, +// '-', +// ':', +// ',', +// "¥", "yyyy-MM-dd", +// "yyyy年M月d日", +// "上午", +// "下午", +// "hh:mm", +// "hh:mm:ss", +// { +// "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月" +// }, +// { +// "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月" +// }, +// { +// "日", "一", "二", "三", "四", "五", "六" +// }, +// { +// "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" +// }, +// 14180 +//}; + +//// 非标准样式,使用 / 分隔时间 +//GFormatSettings g_DefFormatSettings1 = { +// 0, +// 2, +// ',', +// '.', +// 2, +// '/', +// ':', +// ',', +// "¥", +// "yyyy/MM/dd", +// "yyyy年M月d日", +// "上午", +// "下午", +// "hh:mm", +// "hh:mm:ss", +// { +// "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月" +// }, +// { +// "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月" +// }, +// { +// "日", "一", "二", "三", "四", "五", "六" +// }, +// { +// "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" +// }, +// 14180, +//}; + +//// 非标准样式,使用 \ 分隔时间 +//GFormatSettings g_DefFormatSettings2 = { +// 0, +// 2, +// ',', +// '.', +// 2, +// '\\', +// ':', +// ',', +// "¥", +// "yyyy\\MM\\dd", +// "yyyy年M月d日", +// "上午", +// "下午", +// "hh:mm", +// "hh:mm:ss", +// { +// "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月" +// }, +// { +// "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月" +// }, +// { +// "日", "一", "二", "三", "四", "五", "六" +// }, +// { +// "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" +// }, +// 14180, +//}; + +/*/////////////////////////////////////////////////////////////////////////////// +//设计: Liuxd 2007.02.02 +//功能: 使用中文平台时间日期格式进行类型转换 +//参数: +//注意:同时兼容 -、/、\、三种时间分隔符 +///////////////////////////////////////////////////////////////////////////////*/ +double chsStrToDateTime(const GString &s) +{ +// GDateTime result; + // todo +// if ((!tryStrToDateTime(s, result, g_DefFormatSettings)) && +// (!tryStrToDateTime(s, result, g_DefFormatSettings1)) && +// (!tryStrToDateTime(s, result, g_DefFormatSettings2)) && +// (!tryStrToDateTime(s, result))) +// { +// gldErrorFmt(rsInvalidTimeFormat, s); +// } + GDateTime date = strToDateTime(s); + return dateTimeToDouble(date); +} + +GString dateTimeToChsStr(double dateTime) +{ + GDateTime date = doubleToDateTime(dateTime); + return dateTimeToStr(date); +} + +/*////////////////////////////////////////////////////////////////////////////// +//设计: Linw 2008.03.19 +//功能: 判断是否是使用中文平台时间日期格式 +//注意:同时兼容 -、/、\、三种时间分隔符 +///////////////////////////////////////////////////////////////////////////////*/ +bool isChsDateTime(const GString &s) +{ + GDateTime dValue; + // todo duanb + return true; + G_UNUSED(s) +// return tryStrToDateTime(s, dValue, g_DefFormatSettings) || +// tryStrToDateTime(s, dValue, g_DefFormatSettings1) || +// tryStrToDateTime(s, dValue, g_DefFormatSettings2); +} + +bool tryStrToDateTime(const GString &s, GDateTime &value) +{ + Q_UNUSED(s); + Q_UNUSED(value); + // todo +// int nPos = 1; +// GDateTime date, time; + bool result = true; +//Time := 0; +// if not ScanDate(S, Pos, Date) or +// not ((Pos > Length(S)) or ScanTime(S, Pos, Time)) then + +// // Try time only +// Result := TryStrToTime(S, Value) +// else +// if Date >= 0 then +// Value := Date + Time +// else +// Value := Date - Time; + return result; +} + +bool tryStrToDateTime(const GString &s, GDateTime &value, + const GFormatSettings &formatSettings) +{ + Q_UNUSED(s); + Q_UNUSED(value); + Q_UNUSED(formatSettings); + // todo +// GDateTime date, time; + bool result = true; +// int nPos = 1; + // Time := 0; + // if not ScanDate(S, Pos, Date, FormatSettings) or + // not ((Pos > Length(S)) or ScanTime(S, Pos, Time, FormatSettings)) then + + // // Try time only + // Result := TryStrToTime(S, Value, FormatSettings) + // else + // if Date >= 0 then + // Value := Date + Time + // else + // Value := Date - Time; + return result; +} + +bool sameDateTime(double dateTime1, double dateTime2) +{ + double dHoursPerDay = 24; + double dMinsPerHour = 60; + double dSecsPerMin = 60; + double dMSecsPerSec = 1000; + double dMinsPerDay = dHoursPerDay * dMinsPerHour; + double dSecsPerDay = dMinsPerDay * dSecsPerMin; + double dMSecsPerDay = dSecsPerDay * dMSecsPerSec; + double dOneMillisecond = 1.0 / dMSecsPerDay; + return fabs(dateTime1 - dateTime2) < dOneMillisecond; +} + +GLDValueRelationship compareDateTime(double dateTime1, double dateTime2) +{ + double dHoursPerDay = 24; + double dMinsPerHour = 60; + double dSecsPerMin = 60; + double dMSecsPerSec = 1000; + double dMinsPerDay = dHoursPerDay * dMinsPerHour; + double dSecsPerDay = dMinsPerDay * dSecsPerMin; + double dMSecsPerDay = dSecsPerDay * dMSecsPerSec; + double dOneMillisecond = 1.0 / dMSecsPerDay; + if (fabs(dateTime1 - dateTime2) < dOneMillisecond) + return gvrEqualsValue; + else if (dateTime1 < dateTime2) + return gvrLessThanValue; + else + return gvrGreaterThanValue; +} + +GString getHZPY(const GString &src) +{ + unsigned char ucHigh; + unsigned char ucLow; + int nCode; + GString result; + GByteArray byteArray = unicodeToGBK(src); + const char *str = byteArray.constData(); + for (int i = 0; i < byteArray.length(); ++i) + { + ucHigh = str[i]; + if (ucHigh < 0x80)//英文字母 + { + result.append(str[i]); + continue; + } + ucLow = str[i + 1]; + if ((ucHigh < 0xa1) || (ucLow < 0xa1)) + { + continue; + } + else + { + nCode = (ucHigh - 0xa0) * 100 + ucLow - 0xa0; + } + result.append(firstLetter(nCode)); + ++i; + } + return result; +} + +GString firstLetter(int nCode) +{ + if (nCode >= 1601 && nCode < 1637) + return "A"; + if (nCode >= 1637 && nCode < 1833) + return "B"; + if (nCode >= 1833 && nCode < 2078) + return "C"; + if (nCode >= 2078 && nCode < 2274) + return "D"; + if (nCode >= 2274 && nCode < 2302) + return "E"; + if (nCode >= 2302 && nCode < 2433) + return "F"; + if (nCode >= 2433 && nCode < 2594) + return "G"; + if (nCode >= 2594 && nCode < 2787) + return "H"; + if (nCode >= 2787 && nCode < 3106) + return "J"; + if (nCode >= 3106 && nCode < 3212) + return "K"; + if (nCode >= 3212 && nCode < 3472) + return "L"; + if (nCode >= 3472 && nCode < 3635) + return "M"; + if (nCode >= 3635 && nCode < 3722) + return "N"; + if (nCode >= 3722 && nCode < 3730) + return "O"; + if (nCode >= 3730 && nCode < 3858) + return "P"; + if (nCode >= 3858 && nCode < 4027) + return "Q"; + if (nCode >= 4027 && nCode < 4086) + return "R"; + if (nCode >= 4086 && nCode < 4390) + return "S"; + if (nCode >= 4390 && nCode < 4558) + return "T"; + if (nCode >= 4558 && nCode < 4684) + return "W"; + if (nCode >= 4684 && nCode < 4925) + return "X"; + if (nCode >= 4925 && nCode < 5249) + return "Y"; + if (nCode >= 5249 && nCode < 5590) + return "Z"; + return ""; +} + +GString reverseString(const GString &s) +{ + GString result; + for (int i = s.length() - 1; i >= 0; i--) + { + result.append(s[i]); + } + return result; +} + +/*------------------------------------------------------------------------------- +设计:zhangjq 2012.10.31 +参数:const AText, 源字符串 + ARegEx, 正则表达式 + AReplacement: 用来替换的字符串,支持反向引用 \1,\2?? +功能:正则表达式替换函数 +-------------------------------------------------------------------------------*/ +GString regExprReplace(const GString &text, const GString ®Ex, const GString &replacement) +{ + QRegExp regExp; + regExp.setPattern(regEx); + //将匹配设置为最小(短)匹配 + regExp.setMinimal(true); + GString result = text; + result.replace(regExp,replacement); + return result; +} + +int posN(const GString subStr, const GString srcStr, int times) +{ + int result = -1; + int nOffSet = 0; + int nSubLen = length(subStr); + if (nSubLen == 1) + { + result = posN(subStr[0].toLatin1(), srcStr, times); + } + else + { + for (int i = 1; i <= times; i++) + { + nOffSet = srcStr.indexOf(subStr, nOffSet); + if (nOffSet == -1) + break; + if (i == times) + result = nOffSet; + else + nOffSet += nSubLen; + } + } + return result; +} + +int posN(const char delimiter, const GString srcStr, int times) +{ + int result = -1; + int nCounter = 0; + for (int i = 0; i < length(srcStr); i++) + { + if (srcStr[i] == delimiter) + { + nCounter++; + if (nCounter == times) + { + result = i; + break; + } + } + } + return result; +} + +/*------------------------------------------------------------------------------- +创建:Tu Jianhua 2004.1.18 +功能:根据指定的分隔符取指定项 +参数:ASrcStr -- 字符串 + ADelimiter -- 分隔符字符 + AIndex -- 项号 +返回:字符串ASrcStr以Delimiter为分隔符第AIndex项的子串 +-------------------------------------------------------------------------------*/ +GString getSubString(const GString &srcStr, char delimiter, int index) +{ + int nP1; + int nP2; + GString result = ""; + GString strText = srcStr; + if ((index < 1) || (strText.length() == 0)) + return result; + if (index == 1) + { + nP1 = posN(delimiter, strText, index); + if (nP1 == -1) + result = strText; + else + result = copy(strText, 0, nP1); + } + else + { + nP1 = posN(delimiter, strText, index - 1); + if (nP1 == -1) + return result; + nP2 = strText.indexOf(delimiter, nP1 + 1); + if (nP2 == -1) + result = copy(strText, nP1 + 1); + else + result = copy(strText, nP1 + 1, nP2 - nP1 - 1); + } + return trim(result); +} + +/*------------------------------------------------------------------------------- +创建:Tu Jianhua 2004.1.18 +功能:根据指定的分隔符取指定项 +参数:ASrcStr -- 字符串 + ADelimiter -- 分隔符串 + AIndex -- 项号 +返回:字符串ASrcStr以Delimiter为分隔符第AIndex项的子串 +-------------------------------------------------------------------------------*/ +GString getSubString(const GString &srcStr, const GString &delimiter, int index) +{ + int nP1; + int nP2; + GString result = ""; + GString strText = srcStr; + if ((index < 1) || (strText.length() == 0)) + return result; + int nSize = length(delimiter); + if (nSize == 0) + return result; + else if (nSize == 1) + result = getSubString(strText, delimiter.at(0).toLatin1(), index); + else + { + if (index == 1) + { + nP1 = posN(delimiter, strText, index); + if (nP1 == -1) + result = strText; + else + result = copy(strText, 0, nP1); + } + else + { + nP1 = posN(delimiter, strText, index - 1); + if (nP1 == -1) + return result; + nP2 = strText.indexOf(delimiter, nP1 + nSize); + if (nP2 == -1) + result = copy(strText, nP1 + nSize); + else + result = copy(strText, nP1 + nSize, nP2 - nP1 - nSize); + } + } + return trim(result); +} + +GString stringOfChar(char Char, int count) +{ + GString result(""); + + for (int i = 0; i < count; ++i) + { + result.append(Char); + } + return result; +} + +GString createGuidString() +{ + GUuid oUuid; + return oUuid.createUuid().toString(); +} + +GString boolToXMLString(bool v) +{ + if (v) + return "True"; + else + return "False"; +} + +bool xmlStringToBool(const GString &s) +{ + return sameText(s, "True"); +} + +GString floatToXMLString(double v) +{ + GString result = floatToStr(double(v)); + //todo Lipl +// if (CurrentDecimalSeparator != '.') +// { +// int nPos = PosXMLString(CurrentDecimalSeparator, result); +// if (nPos != 0) +// result[nPos] = '.'; +// } + return result; +} + +GString encodeXMLString(const GString &value, bool encodeCrLf) +{ + int nLength = length(value); + if (nLength == 0) + { + return value; + } + GString result = value; + int nI = nLength - 1; + while (nI >= 0) + { + switch (value[nI].toLatin1()) + { + case '<': + result.replace(nI, 1, "<"); + break; + case '>': + result.replace(nI, 1, ">"); + break; + case '&': + result.replace(nI, 1, "&"); + break; + case '\'': + result.replace(nI, 1, "'"); + break; + case '"': + result.replace(nI, 1, """); + break; + case '\n': + if (encodeCrLf) + { + result.replace(nI, 1, " "); + } + break; + case '\r': + if (encodeCrLf) + { + result.replace(nI, 1, " "); + } + break; + default: + break; + } + --nI; + } + return result; +} + +/** + * GUID 操作函数 + */ + +GUID strToGUID(const GString &text) +{ +#if defined(Q_OS_WIN) + return GUID(GUuid(text)); +#else + return GUuidToGUID(GUuid(text)); +#endif +} + +GString GUIDToStr(const GUID &a) +{ +#if defined(Q_OS_WIN) + return GUuid(a).toString(); +#else + return GUIDToGUuid(a).toString(); +#endif +} + +bool isGUID(const GString &s) +{ + return !GUuid(s).isNull(); +} + +bool variantTypeIsGUID(const QVariant::Type type) +{ + return type == GVariant::Uuid; +} + +GUuid GUIDToGUuid(const GUID &value) +{ +#if defined(Q_OS_WIN) + return GUuid(value).toString(); +#else + return QUuid(value.Data1, value.Data2, value.Data3, value.Data4[0], value.Data4[1], value.Data4[2], value.Data4[3], + value.Data4[4], value.Data4[5], value.Data4[6], value.Data4[7]); +#endif +} + +GUID GUuidToGUID(const GUuid &value) +{ +#if defined(Q_OS_WIN) + return GUID(value); +#else + GUID result; + result.Data1 = value.data1; + result.Data2 = value.data2; + result.Data3 = value.data3; + result.Data4[0] = value.data4[0]; + result.Data4[1] = value.data4[1]; + result.Data4[2] = value.data4[2]; + result.Data4[3] = value.data4[3]; + result.Data4[4] = value.data4[4]; + result.Data4[5] = value.data4[5]; + result.Data4[6] = value.data4[6]; + result.Data4[7] = value.data4[7]; + return result; +#endif +} + +int compareGUID(const GUID &g1, const GUID &g2) +{ + GUuid uuid1 = GUIDToGUuid(g1); + GUuid uuid2 = GUIDToGUuid(g2); + if (uuid1 > uuid2) + { + return 1; + } + else if (uuid1 < uuid2) + { + return -1; + } + else + { + return 0; + } +} + +GVariant GUIDToVariant(const GUID &a) +{ + return GVariant(GUIDToGUuid(a)); +} + +GUID variantToGUID(const GVariant &text) +{ + return GUuidToGUID(text.toUuid()); +} + +GUID byteArrayToGUID(const GByteArray &ba) +{ + return GUuidToGUID(GUuid(ba)); +} + +GByteArray GUIDToByteArray(const GUID value) +{ + return GUIDToGUuid(value).toByteArray(); +} + +GUID createGUID() +{ + GUuid uuid; + return GUuidToGUID(uuid.createUuid()); +} + +bool isUInt64(const GString &s) +{ + bool result = false; + s.toULongLong(&result); + return result; +} + +guint64 strToUInt64(const GString &s) +{ + bool bOK; + guint64 result; + result = s.toULongLong(&bOK); + if (bOK) + { + return result; + } + else + { + throw GLDException(format(getGLDi18nStr(g_InvalidInteger), s)); + } +} + +guint64 strToUInt64Def(const GString &s, guint64 def) +{ + bool bOk = false; + guint64 result; + result = s.toULongLong(&bOk); + if (bOk) + { + return result; + } + else + { + return def; + } +} + +/*! + * \brief 用于兼容delphi,引擎copy函数用 + * \param s + * \param position + * \param n + * \return + */ +GString copyForDelphi(const GString &s, int position, int n) +{ + if (position < 0) + { + position = 0; + } + if (n < 0) + { + return ""; + } + + if (n == MaxInt) + { + n = -1; + } + return s.mid(position, n); +} + +LONGLONG getStartTime() +{ +#ifdef WIN32 + LARGE_INTEGER litmp; + QueryPerformanceCounter(&litmp); + return litmp.QuadPart;// 获得初始值 +#else + return 0; +#endif +} + +double getLastTime(LONGLONG startTime) +{ +#ifdef WIN32 + LARGE_INTEGER litmp; + QueryPerformanceFrequency(&litmp); + double dfFreq = (double)litmp.QuadPart;// 获得计数器的时钟频率 + + QueryPerformanceCounter(&litmp); + LONGLONG endTime = litmp.QuadPart;// 获得初始值 + double dfMinus = (double)(endTime - startTime) * 1000; + double result = dfMinus / dfFreq;// 获得对应的时间值,单位为毫秒 + return result; +#else + return 0; +#endif +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDStream.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDStream.cpp new file mode 100644 index 00000000..58091380 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDStream.cpp @@ -0,0 +1,894 @@ +#include "GLDStream.h" + +#include "GLDGlobal.h" +#include "GLDSysUtils.h" +#include "GLDFileUtils.h" +#include "private/qiodevice_p.h" + +//块的大小 +const int c_nBlockSize = 3800; + +class GMemoryStreamPrivate +{ +public: + GMemoryStreamPrivate(GMemoryStream *parent) + : q_ptr(parent) + { + } + +private: + GMemoryStream * const q_ptr; + Q_DECLARE_PUBLIC(GMemoryStream); + bool m_ownerBuf; + GByteArray *m_buf; +}; + +/* GMemoryStream */ + +GMemoryStream::GMemoryStream(GStream::OpenMode flags) + : GBuffer(), d_ptr(new GMemoryStreamPrivate(this)) +{ + Q_D(GMemoryStream); + d->m_ownerBuf = false; + open(flags); +} + +GMemoryStream::GMemoryStream(GByteArray *buf, bool ownerBuf, GStream::OpenMode flags) + : GBuffer(buf), d_ptr(new GMemoryStreamPrivate(this)) +{ + Q_D(GMemoryStream); + d->m_ownerBuf = ownerBuf; + d->m_buf = buf; + open(flags); +} + +GMemoryStream::~GMemoryStream() +{ + Q_D(GMemoryStream); + if (d->m_ownerBuf && d->m_buf) + { + delete d->m_buf; + } + + freePtr(d); +} + +/* +gint64 GMemoryStream::read(char *data, gint64 maxlen) +{ + return GBuffer::read(data, maxlen); +} + +GByteArray GMemoryStream::read(gint64 maxlen) +{ + return GBuffer::read(maxlen); +} + +gint64 GMemoryStream::readData(char *data, gint64 maxlen) +{ + return GBuffer::readData(data, maxlen); +} + +gint64 GMemoryStream::writeData(const char *data, gint64 len) +{ + return GBuffer::writeData(data, len); +} + +gint64 GMemoryStream::write(const GByteArray &data) +{ + return GBuffer::write(data); +} + +gint64 GMemoryStream::write(const char *data, gint64 len) +{ + return GBuffer::write(data, len); +} + +gint64 GMemoryStream::write(const char *data) +{ + return GBuffer::write(data); +} + +bool GMemoryStream::seek(gint64 pos) +{ + return GBuffer::seek(pos); +} + +gint64 GMemoryStream::pos() const +{ + return GBuffer::pos(); +} + +gint64 GMemoryStream::size() const +{ + return GBuffer::size(); +} + +GByteArray GMemoryStream::readAll() +{ + return GBuffer::readAll(); +} + +void GMemoryStream::close() +{ + GBuffer::close(); +} + +bool GMemoryStream::open(GStream::OpenMode mode) +{ + return GBuffer::open(mode); +} + +bool GMemoryStream::reset() +{ + return GBuffer::reset(); +}*/ + +/* GBlockMemoryStream */ +class GBlockMemoryStreamPrivate : public QIODevicePrivate +{ +public: + GBlockMemoryStreamPrivate() + : m_size(0), m_position(0)/*, m_blockSize(3800)*/ + , m_blockCount(0), m_curBlockIndex(0), m_curBlockPosition(0) + { + } + +private: + Q_DECLARE_PUBLIC(GBlockMemoryStream); + + GObjectList m_buf; + gint64 m_size; + gint64 m_position; +// gint64 m_blockSize; + gint64 m_blockCount; + gint64 m_curBlockIndex; + gint64 m_curBlockPosition; +}; + + +GBlockMemoryStream::GBlockMemoryStream(OpenMode flags) + : GStream(*(new GBlockMemoryStreamPrivate)) +{ + open(flags); +} + +GBlockMemoryStream::~GBlockMemoryStream() +{ + clearData(); +} + +GObjectList &GBlockMemoryStream::buffer() +{ + Q_D(GBlockMemoryStream); + return d->m_buf; +} + +void GBlockMemoryStream::setBuffer(GObjectList *byteArray) +{ + if (isOpen()) + { + qWarning("QBuffer::setBuffer: Buffer is open"); + return; + } + clearData(); + if (byteArray) + { + // todo复制数据 + // d->buf = byteArray; + } +} + +gint64 GBlockMemoryStream::readData(char *data, gint64 len) +{ + gint64 nResult = 0; + + Q_D(GBlockMemoryStream); + if ((d->m_position >= 0) && (len > 0)) + { + nResult = d->m_size - d->m_position; + if (nResult > len) + { + nResult = len; + } + doRead(data, nResult); + d->m_position += nResult; + } + return nResult; +} + +gint64 GBlockMemoryStream::writeData(const char *data, gint64 len) +{ + Q_D(GBlockMemoryStream); + if ((d->m_position >= 0) && (len > 0)) + { + gint64 nPos = d->m_position + len; + if (nPos > d->m_size) + { + if (nPos > (c_nBlockSize * d->m_blockCount)) + { + setCapacity(nPos); + } + d->m_size = nPos; + } + doWrite(data, len); + d->m_position = nPos; + return len; + } + return 0; +} + +bool GBlockMemoryStream::open(GStream::OpenMode flags) +{ + if ((flags & (Append | Truncate)) != 0) + { + flags = GStream::OpenMode(flags | WriteOnly); + } + if ((flags & (GStream::ReadOnly | WriteOnly)) == 0) + { + qWarning("QBuffer::open: Buffer access not specified"); + return false; + } + + if ((flags & Truncate) == Truncate) + { + // todo + // d->buf->resize(0); + } + return GStream::open(flags); +} + +void GBlockMemoryStream::close() +{ + GStream::close(); +} + +gint64 GBlockMemoryStream::size() const +{ + Q_D(const GBlockMemoryStream); + return gint64(d->m_size); +} + +gint64 GBlockMemoryStream::pos() const +{ + return GStream::pos(); +} + +bool GBlockMemoryStream::seek(gint64 pos) +{ + seek(pos, 0); + return GStream::seek(pos); +} + +bool GBlockMemoryStream::atEnd() const +{ + return GStream::atEnd(); +} + +bool GBlockMemoryStream::canReadLine() const +{ +// G_D(GBlockMemoryStream); + if (!isOpen()) + { + return false; + } + // todo + return true; + // return d->buf->indexOf('\n', int(pos())) != -1 || GStream::canReadLine(); +} + +gint64 GBlockMemoryStream::seek(gint64 nOffset, int nFlag) +{ + Q_D(GBlockMemoryStream); + switch (nFlag) + { + case soBeginning: + doSetPosition(nOffset); + break; + case soCurrent: + doSetPosition(d->m_position + nOffset); + break; + case soEnd: + doSetPosition(d->m_size + nOffset); + break; + } + return d->m_position; +} + +bool GBlockMemoryStream::reset() +{ + clearData(); + return seek(0); +} + +void GBlockMemoryStream::clearData() +{ + Q_D(GBlockMemoryStream); + d->m_size = 0; + d->m_blockCount = 0; + d->m_buf.clear(); +} + +void GBlockMemoryStream::loadFromStream(GStream *stream, gint64 len) +{ + if (!stream->isOpen()) + { + stream->open(GStream::ReadOnly); + } + + //分块读,节约内存 + gint64 nReadLength = -1; + if (len < 0) + { + nReadLength = stream->size(); + } + else + { + nReadLength = len; + } + + int nCount = nReadLength / c_nBlockSize; + for (int i = 0; i < nCount; ++i) + { + write(stream->read(c_nBlockSize)); + } + write(stream->read(nReadLength % c_nBlockSize)); +} + +void GBlockMemoryStream::saveToStream(GStream *stream) +{ + seek(0); + + int nCount = size() / c_nBlockSize; + + for (int i = 0; i < nCount; ++i) + { + stream->write(read(c_nBlockSize)); + } + stream->write(read(size() % c_nBlockSize)); +} + +void GBlockMemoryStream::loadFromFile(const GString &fileName) +{ + GFileStream *fileStream = new GFileStream(fileName); + if (!fileStream->exists()) + { + freeAndNil(fileStream) + return; + } + loadFromStream(fileStream); + freeAndNil(fileStream); +} + +void GBlockMemoryStream::saveToFile(const GString &fileName) +{ + GString SDirName = extractFileDir(fileName); + if (!directoryExists(SDirName)) + { + forceDirectories(SDirName); + } + + GFileStream *stream = new GFileStream(fileName); + stream->open(GStream::ReadWrite); + saveToStream(stream); + stream->close(); + freeAndNil(stream) +} + +void GBlockMemoryStream::doSetPosition(gint64 nPos) +{ + Q_D(GBlockMemoryStream); + d->m_position = nPos; + d->m_curBlockPosition = nPos % c_nBlockSize; + d->m_curBlockIndex = nPos / c_nBlockSize; +} + +void GBlockMemoryStream::setCapacity(gint64 nNewCapacity) +{ + Q_D(GBlockMemoryStream); + gint64 nCount = (nNewCapacity / c_nBlockSize) + 1; + for (gint64 i = d->m_blockCount - 1; i >= nCount; --i) + { + d->m_buf.removeAt(i); + } + for (gint64 i = d->m_blockCount; i < nCount; ++i) + { + GByteArray *data = new GByteArray; + data->resize(c_nBlockSize); + d->m_buf.push_back(data); + } + d->m_blockCount = nCount; +} + +void GBlockMemoryStream::setSize(gint64 nNewSize) +{ + Q_D(GBlockMemoryStream); + if (d->m_size < 0) + { + d->m_size = 0; + } + gint64 nOldPosition = d->m_position; + setCapacity(nNewSize); + d->m_size = nNewSize; + if (nOldPosition > nNewSize) + { + seek(0, soEnd); + } +} + +void GBlockMemoryStream::doRead(char *data, gint64 nReadCount) +{ + gint64 nCount = 0; + gint64 nBufSize = 0; + + Q_D(GBlockMemoryStream); + while (nCount < nReadCount) + { + gint64 nSize = c_nBlockSize - d->m_curBlockPosition; + if (nReadCount - nCount >= nSize) + { + nBufSize = nSize; + } + else + { + nBufSize = nReadCount - nCount; + } + const char* bufPtr = d->m_buf[d->m_curBlockIndex]->constData(); + memcpy(data + nCount, bufPtr + d->m_curBlockPosition, nBufSize); + if (nReadCount - nCount >= nSize) + { + d->m_curBlockIndex++; + d->m_curBlockPosition = 0; + } + else + { + d->m_curBlockPosition += nBufSize; + } + nCount += nBufSize; + } +} + +void GBlockMemoryStream::doWrite(const char *data, gint64 nWriteCount) +{ + gint64 nCount = 0; + gint64 nBufSize = 0; + + Q_D(GBlockMemoryStream); + while (nCount < nWriteCount) + { + gint64 count = c_nBlockSize - d->m_curBlockPosition; + if (nWriteCount - nCount >= count) + { + nBufSize = count; + } + else + { + nBufSize = nWriteCount - nCount; + } + char* bufPtr = (char*)(d->m_buf.at(d->m_curBlockIndex)->constData()); + memcpy(bufPtr + d->m_curBlockPosition, data + nCount, nBufSize); + if (nWriteCount - nCount >= count) + { + d->m_curBlockIndex++; + d->m_curBlockPosition = 0; + } + else + { + d->m_curBlockPosition += nBufSize; + } + nCount += nBufSize; + } +} + +class GReadBufferedStreamPrivate : public QIODevicePrivate +{ +public: + GReadBufferedStreamPrivate(GReadBufferedStream *parent = 0) + : q_ptr(parent) + { + } + +private: + GReadBufferedStream * const q_ptr; + Q_DECLARE_PUBLIC(GReadBufferedStream); + + bool m_autoDestroy; + GStream *m_baseStream; + gint64 m_baseSize; + char *m_buffer; + int m_bufferSize; + int m_bufferData; + gint64 m_basePosition; + gint64 m_bufferOffset; + char *m_bufferPtr; +}; +/*CReadBufferedStream*/ + +GReadBufferedStream::GReadBufferedStream(GStream *baseStream, int bufferSize, bool autoDestroyWrappedStream): + GStream(*(new GReadBufferedStreamPrivate(this))) +{ + Q_D(GReadBufferedStream); + d->m_autoDestroy = autoDestroyWrappedStream; + d->m_baseStream = baseStream; + d->m_baseSize = baseStream->size(); + d->m_bufferSize = bufferSize; + d->m_bufferData = 0; + d->m_basePosition = baseStream->pos(); + d->m_bufferOffset = baseStream->pos(); + + d->m_buffer = new char[bufferSize + 1]; + d->m_bufferPtr = d->m_buffer; + // cuidc 添加 | GStream::Unbuffered 使其绕过缓存,也就是不需要将来将d->m_buffer中的内容复制到 GStream 的内存中。 + open(GStream::ReadOnly | GStream::Unbuffered); +} + +GReadBufferedStream::~GReadBufferedStream() +{ + Q_D(GReadBufferedStream); + freeAndNil(d->m_buffer); + if (d->m_autoDestroy) + { + freeAndNil(d->m_baseStream); + } + close(); + +} + +gint64 GReadBufferedStream::size() const +{ + Q_D(const GReadBufferedStream); + return d->m_baseSize; +} + +gint64 GReadBufferedStream::readData(char *data, gint64 maxlen) +{ + Q_D(GReadBufferedStream); + if ((maxlen = min(maxlen, gint64(size() - currentPosition()))) <= 0) + { + return gint64(0); + } + if (maxlen >= d->m_bufferSize) + { + maxlen = d->m_bufferSize / 2; + } + gint64 result = 0; + char *pOut = data; + while (maxlen > 0) + { + int nCanMove = maxlen; + if (d->m_bufferData < nCanMove) + { + nCanMove = d->m_bufferData; + } + if (nCanMove > 0) + { + gMemMove(pOut, d->m_bufferPtr, nCanMove); + d->m_bufferPtr += nCanMove; + pOut += nCanMove; + result += nCanMove; + d->m_bufferData -= nCanMove; + maxlen -= nCanMove; + } + if (maxlen >= d->m_bufferSize) + { + d->m_bufferOffset = d->m_basePosition; + int nDataRead = d->m_baseStream->read(pOut, maxlen); + d->m_basePosition += nDataRead; + result += nDataRead; + break; + } + else if (maxlen > 0) + { + d->m_bufferOffset = d->m_basePosition; + d->m_bufferData = d->m_baseStream->read(d->m_buffer, d->m_bufferSize); + d->m_basePosition += d->m_bufferData; + d->m_bufferPtr = d->m_buffer; + if (d->m_bufferData == 0) + { + break; + } + } + } + return result; +} + +gint64 GReadBufferedStream::writeData(const char *data, gint64 len) +{ + Q_D(GReadBufferedStream); + gint64 oldPos = pos(); + d->m_baseStream->seek(oldPos); + gint64 result = d->m_baseStream->write(data, len); + d->m_bufferData = 0; + d->m_basePosition = oldPos + result; + d->m_bufferPtr = d->m_buffer; + d->m_bufferOffset = oldPos + result; + return result; +} + +bool GReadBufferedStream::autoDestroyWrappedStream() +{ + Q_D(GReadBufferedStream); + return d->m_autoDestroy; +} + +void GReadBufferedStream::setAutoDestroyWrappedStream(bool value) +{ + Q_D(GReadBufferedStream); + d->m_autoDestroy = value; +} + +GStream *GReadBufferedStream::wrappedStream() +{ + Q_D(GReadBufferedStream); + return d->m_baseStream; +} + +gint64 GReadBufferedStream::currentPosition() const +{ + Q_D(const GReadBufferedStream); + return d->m_bufferPtr - d->m_buffer + d->m_bufferOffset; +} + +gint64 GReadBufferedStream::internalSeek(gint64 offset) +{ + Q_D(GReadBufferedStream); + gint64 bufferEnd = currentPosition() + d->m_bufferData; //last AOffset in Buffer + if ((offset < d->m_bufferData) || (offset > bufferEnd)) + { + d->m_bufferData = 0; + d->m_baseStream->seek(offset); + d->m_basePosition = offset; + d->m_bufferPtr = d->m_buffer; + d->m_bufferOffset = offset; + } + else + { + d->m_bufferPtr = d->m_buffer + (offset - d->m_bufferOffset); + d->m_bufferData = bufferEnd - currentPosition(); + } + return currentPosition(); +} + +gint64 GReadBufferedStream::pos() const +{ + return currentPosition(); +} + +bool GReadBufferedStream::seek(gint64 off) +{ + GStream::seek(off); + return 0 != seek(off, soBeginning); +} + +gint64 GReadBufferedStream::seek(gint64 offset, GSeekOrigin origin) +{ + Q_D(GReadBufferedStream); + switch (origin) + { + case soBeginning: + return internalSeek(offset); + case soEnd: + return internalSeek(d->m_baseStream->size() + offset); + default: + return internalSeek(currentPosition() + offset); + } +} + +class GWriteBufferedStreamPrivate : public QIODevicePrivate +{ +public: + GWriteBufferedStreamPrivate(GWriteBufferedStream *parent = 0) + : q_ptr(parent) + { + } + +private: + GWriteBufferedStream * const q_ptr; + Q_DECLARE_PUBLIC(GWriteBufferedStream); + + bool m_autoDestroy; + GStream *m_baseStream; + gint64 m_baseSize; + gint64 m_basePosition; + int m_bufferData; + int m_bufferSize; + char *m_buffer; +}; +/*GWriteBufferedStream*/ + +GWriteBufferedStream::GWriteBufferedStream(GStream *baseStream, int bufferSize, bool autoDestroyWrappedStream): + GStream(*(new GWriteBufferedStreamPrivate(this))) +{ + Q_D(GWriteBufferedStream); + + assert(baseStream != NULL); + assert(bufferSize >= 8); + d->m_buffer = new char[bufferSize + 1]; + d->m_autoDestroy = autoDestroyWrappedStream; + d->m_baseStream = baseStream; + d->m_baseSize = baseStream->size(); + d->m_bufferSize = bufferSize; + d->m_bufferData = 0; + d->m_basePosition = baseStream->pos(); + + // cuidc 添加 | GStream::Unbuffered 使其绕过缓存,也就是不需要将来将d->m_buffer中的内容复制到 GStream 的内存中。 + open(GStream::ReadWrite | GStream::Unbuffered); +} + +GWriteBufferedStream::~GWriteBufferedStream() +{ + Q_D(GWriteBufferedStream); + flushStream(); + freeAndNil(d->m_buffer); + + if (d->m_autoDestroy) + { + freeAndNil(d->m_baseStream); + } + close(); +} + +void GWriteBufferedStream::flushStream() +{ + Q_D(GWriteBufferedStream); + if (d->m_bufferData > 0) + { + d->m_basePosition = d->m_basePosition + d->m_baseStream->write(d->m_buffer, d->m_bufferData); + d->m_bufferData = 0; + if (d->m_baseSize < d->m_basePosition) + { + d->m_baseSize = d->m_basePosition; + } + } +} + +bool GWriteBufferedStream::seek(gint64 off) +{ + GStream::seek(off); + return 0 != seek(off, soBeginning); +} + +gint64 GWriteBufferedStream::seek(const gint64 offset, GSeekOrigin origin) +{ + gint64 result = 0; + switch (origin) + { + case soBeginning: + result = internalSeek(offset); + break; + case soEnd: + result = internalSeek(currentSize() + offset); + break; + case soCurrent: + if (offset != 0) + { + result = internalSeek(currentPosition() + offset); + } + else + { + result = currentPosition(); + } + break; + default: + result = 0; + assert(false); + break; + } + return result; +} + +gint64 GWriteBufferedStream::readData(char *data, gint64 maxlen) +{ + Q_D(GWriteBufferedStream); + if ((maxlen = min(maxlen, gint64(size() - currentPosition()))) <= 0) + { + return gint64(0); + } + flushStream(); + gint64 result = d->m_baseStream->read(data, maxlen); + d->m_basePosition = d->m_basePosition + result; + return result; +} + +gint64 GWriteBufferedStream::writeData(const char *data, gint64 len) +{ + Q_D(GWriteBufferedStream); + const char *pOut = data; + char *pBufferPtr = d->m_buffer + d->m_bufferData; + int nCanMove = d->m_bufferData + len; + if (nCanMove < d->m_bufferSize) + { + gMemMove(pBufferPtr, pOut, len); + d->m_bufferData += len; + } + else if (nCanMove == d->m_bufferSize) + { + gMemMove(pBufferPtr, pOut, len); + d->m_bufferData = d->m_bufferSize; + flushStream(); + } + else if (nCanMove < d->m_bufferSize * 2) + { + int nCount = d->m_bufferSize - d->m_bufferData; + gMemMove(pBufferPtr, pOut, nCount); + pOut += nCount; + nCount = len - nCount; + d->m_bufferData = d->m_bufferSize; + flushStream(); + gMemMove(d->m_buffer, pOut, nCount); + d->m_bufferData += nCount; + } + else + { + flushStream(); + d->m_baseStream->write(data, len); + d->m_basePosition = d->m_basePosition + len; + if (d->m_baseSize < d->m_basePosition) + { + d->m_baseSize = d->m_basePosition; + } + } + return len; +} + +bool GWriteBufferedStream::autoDestroyWrappedStream() +{ + Q_D(GWriteBufferedStream); + return d->m_autoDestroy; +} + +void GWriteBufferedStream::setAutoDestroyWrappedStream(bool value) +{ + Q_D(GWriteBufferedStream); + d->m_autoDestroy = value; +} + +GStream *GWriteBufferedStream::wrappedStream() +{ + Q_D(GWriteBufferedStream); + return d->m_baseStream; +} + +gint64 GWriteBufferedStream::size() const +{ + return currentSize(); +} + +gint64 GWriteBufferedStream::pos() const +{ + return currentPosition(); +} + +gint64 GWriteBufferedStream::currentPosition() const +{ + Q_D(const GWriteBufferedStream); + return d->m_basePosition + d->m_bufferData; +} + +gint64 GWriteBufferedStream::currentSize() const +{ + Q_D(const GWriteBufferedStream); + gint64 result = currentPosition(); + if (result < d->m_baseSize) + { + return d->m_baseSize; + } + return result; +} + +gint64 GWriteBufferedStream::internalSeek(gint64 offset) +{ + Q_D(GWriteBufferedStream); + gint64 result = currentPosition(); + if (offset != result) + { + flushStream(); + if (d->m_baseStream->seek(offset)) + { + result = d->m_baseStream->pos(); + d->m_basePosition = result; + } + } + return result; +} + diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDStreamUtils.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDStreamUtils.cpp new file mode 100644 index 00000000..0219242d --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDStreamUtils.cpp @@ -0,0 +1,766 @@ +#include "GLDStreamUtils.h" + +#include +#include "GLDGlobal.h" +#include "GLDStrUtils.h" +#include "private/qiodevice_p.h" + +const unsigned char c_GCharSize = 2; + +long long streamLength(IStream *stream) +{ + long long result; + LARGE_INTEGER lMov; + lMov.QuadPart = 0; + ULARGE_INTEGER ulEnd; + ULARGE_INTEGER ulBegin; + ULARGE_INTEGER ulPos; + // 记录当前位置 + stream->Seek(lMov, STREAM_SEEK_CUR, &ulPos); + try + { + stream->Seek(lMov, STREAM_SEEK_END, &ulEnd); + stream->Seek(lMov, STREAM_SEEK_SET, &ulBegin); + result = ulEnd.QuadPart - ulBegin.QuadPart; + } + catch (...) + { + lMov.QuadPart = ulPos.QuadPart; + stream->Seek(lMov, STREAM_SEEK_SET, &ulPos); + throw; + } + lMov.QuadPart = ulPos.QuadPart; + stream->Seek(lMov, STREAM_SEEK_SET, &ulPos); + return result; +} + +GByteArray readByteArrayFromStream(GStream *stream, char *buf, uint length) +{ + stream->read(buf, length); + buf[length] = '\0'; + return GByteArray(buf, length); +} + +GByteArray readByteArrayFromStream(GStream *stream, uint length) +{ + GByteArray result; + if (0 != length) + { + char *buf = new char[length + 1]; + try + { + result = readByteArrayFromStream(stream, buf, length); + } + catch (...) + { + delete buf; + throw; + } + delete buf; + } + return result; +} + +GString readFromStream(GStream *stream, uint length, bool useUnicode) +{ + if (0 == length) + return GString(); + if (useUnicode) + { + GString result(length, Qt::Uninitialized); + char *buf = (char *)(result.constData()); + stream->read(buf, length * c_GCharSize); + return result; + } + else + { + GString result; + if (0 != length) + { + char *buf = new char[length + 1]; + try + { + stream->read(buf, length); + buf[length] = '\0'; + result = gbkToUnicode(buf, length); + } + catch (...) + { + delete buf; + throw; + } + delete buf; + } + return result; + } +} + +// ===================================================== +// 从流中读出一个字符串 +// 参数: pStream 保存创建的流 +// value 字符串 +// 返回值: +// 备注:按GSP存字符串留格式,每个字符串由长度,加字符串本身构成 +// ===================================================== +void readStrFromStream(GStream *stream, GString &value, bool useUnicode) +{ + if (useUnicode) + { + unsigned int ucInts = 0; + readUIntFromStream(stream, ucInts); + value = readFromStream(stream, ucInts, useUnicode); + } + else + { + unsigned char ucInts = 0; + readByteFromStream(stream, ucInts); + value = readFromStream(stream, ucInts, useUnicode); + } +} + +void readByteArrayFromStream(GStream *stream, GByteArray &value) +{ + uint uInts = 0; + readUIntFromStream(stream, uInts); + value = readByteArrayFromStream(stream, uInts); +} + +GByteArray readByteArrayFromStream(GStream *stream) +{ + uint uInts = 0; + readUIntFromStream(stream, uInts); + GByteArray value = readByteArrayFromStream(stream, uInts); + return value; +} + +void readMemoFromStream(GStream *stream, GString &value, bool useUnicode) +{ + uint uInts = 0; + readUIntFromStream(stream, uInts); + value = readFromStream(stream, uInts, useUnicode); +} + +void readStreamFromStream(GStream *src, GStream *dst, unsigned int length) +{ + // todo 分块 + char *buf = new char[length]; + src->read(buf, length); + dst->write(buf, length); + delete buf; +} + +unsigned int readStreamFromStream(GStream *src, GStream *dst) +{ + unsigned int uLength(0); + readUIntFromStream(src, uLength); + if (0 != uLength) + { + readStreamFromStream(src, dst, uLength); + } + return uLength; +} + +#define GBSWAP(value) value +#define GBSWAPVALUE +//#define GBSWAP(value) qbswap(value) +//#define GBSWAPVALUE value = GBSWAP(value); + +void readColorFromStream(GStream *stream, TColor &color) +{ + int nValue; + //转用整形操作是为了同DELPHI产生的流兼容 + readIntFromStream(stream, nValue); + color = (TColor)nValue; +} + +GString readStrFromStream(GStream *stream, bool useUnicode) +{ + if (useUnicode) + { + int nLength = 0; + readIntFromStream(stream, nLength); + if (nLength > 0) + { + GString result(nLength, Qt::Uninitialized); + char *buf = (char *)(result.constData()); + stream->read(buf, nLength * c_GCharSize); + return result; + } + else + return GString(); + } + else + { + unsigned char ucN = 0; + readByteFromStream(stream, ucN); + return readFromStream(stream, ucN, useUnicode); + } +} + +GString readMemoFromStream(GStream *stream, bool useUnicode) +{ + GString result; + readMemoFromStream(stream, result, useUnicode); + return result; +} + +TColor readColorFromStream(GStream *stream) +{ + TColor result(0); + readColorFromStream(stream, result); + return result; +} + +GVariant readGVariantFromStream(GStream *stream) +{ + GVariant var; + readGVariantFromStream(stream, var); + return var; +} + +void readGVariantFromStream(GStream *stream, GVariant &result) +{ + short nType = readShortFromStream(stream); + switch (nType) + { + case gbdtUnknown: + assert(false); + break; + case gbdtInteger: + result.setValue(readIntFromStream(stream)); + break; + case gbdtFloat: + result.setValue(readDoubleFromStream(stream)); + break; + case gbdtString: + result.setValue(readStrFromStream(stream)); + break; + case gbdtBoolean: + result.setValue(readBoolFromStream(stream)); + break; + case gbdtDateTime: + result.setValue(readDoubleFromStream(stream)); + break; + case gbdtTable: + assert(false); + break; + case gbdtInt64: + result.setValue(readInt64FromStream(stream)); + break; + case gbdtUInt64: + result.setValue(readUInt64FromStream(stream)); + break; + case gbdtBlob: + result.setValue(readByteArrayFromStream(stream)); + break; + case gbdtGUID: + result.setValue(GUIDToVariant(readGUIDFromStream(stream))); + break; + default: + assert(false); + break; + } +} + +void writeGVariantToStream(GStream *stream, const GVariant &value) +{ + switch (value.type()) + { + case gbdtUnknown: + assert(false); + break; + case GVariant::Int: + writeShortToStream(stream, short(gbdtInteger)); + writeIntToStream(stream, value.toInt()); + break; +// case GVariant::Short: +// writeShortToStream(stream, short(gbdtInt64)); +// writeDoubleToStream(stream, value.toDouble()); +// break; + case GVariant::String: + writeShortToStream(stream, short(gbdtString)); + writeStrToStream(stream, value.toString()); + break; + case GVariant::Bool: + writeShortToStream(stream, short(gbdtBoolean)); + writeBoolToStream(stream, value.toBool()); + break; + case GVariant::Double: + writeShortToStream(stream, short(gbdtFloat)); + writeDoubleToStream(stream, value.toDouble()); + break; +// case GVariant::Int: +// assert(false); +// break; + case GVariant::LongLong: + writeShortToStream(stream, short(gbdtInt64)); + writeInt64ToStream(stream, value.toLongLong()); + break; + case GVariant::ULongLong: + writeShortToStream(stream, short(gbdtUInt64)); + writeUInt64ToStream(stream, value.toULongLong()); + break; + case GVariant::ByteArray: + { + writeShortToStream(stream, short(gbdtGUID)); + GByteArray byteAarray = value.toByteArray(); + writeByteArrayToStream(stream, byteAarray.constData(), byteAarray.size()); + break; + } + case GVariant::Uuid: + { + writeShortToStream(stream, short(gbdtGUID)); + writeGUIDToStream(stream, variantToGUID(value)); + break; + } + default: + assert(false); + break; + } +} + +void writeStrToStream(GStream *stream, const GString &value, bool useUnicode) +{ + if (useUnicode) + { + int nSize = value.length(); + stream->write((const char *)(&nSize), sizeof(int)); + const char *buf = (const char *)(value.constData()); + stream->write(buf, nSize * c_GCharSize); + return; + } + else + { + GByteArray byteArray = unicodeToGBK(value); + writeStrToStream(stream, byteArray.constData(), byteArray.length(), useUnicode); + } +} + +void writeStrToStream(GStream *stream, const char *value, int size, bool useUnicode) +{ + if (useUnicode) + { + int nSize = size / (c_GCharSize); + writeUIntToStream(stream, nSize); + } + else + { + writeByteToStream(stream, size); + } + if (size > 0) + { + stream->write(value, size); + } +} + +void writeByteArrayToStream(GStream *stream, const char *value, int size) +{ + writeIntToStream(stream, size); + if (size > 0) + { + stream->write(value, size); + } +} + +void writeByteArrayToStream(GStream *stream, const GByteArray &value) +{ + writeByteArrayToStream(stream, value.constData(), value.size()); +} + +void writeMemoToStream(GStream *stream, const char *value, int size, bool useUnicode) +{ + if (useUnicode) + { + int nSize = size / (c_GCharSize); + writeUIntToStream(stream, nSize); + } + else + { + writeUIntToStream(stream, size); + } + if (size > 0) + { + stream->write(value, size); + } +} + +void writeMemoToStream(GStream *stream, const GString &value, bool useUnicode) +{ + if (useUnicode) + { + uint nSize = value.length(); + writeUIntToStream(stream, nSize); + const char *buf = (const char *)(value.constData()); + stream->write(buf, nSize * c_GCharSize); + return; + } + else + { + GByteArray byteArray = unicodeToGBK(value); + writeMemoToStream(stream, byteArray.constData(), byteArray.length(), useUnicode); + } +} + +void writeColorToStream(GStream *stream, const TColor color) +{ + int nValue = (int)(color); + //转用整形操作是为了同DELPHI产生的流兼容 + writeIntToStream(stream, nValue); +} + +GMemoryStream *createMemoryStream() +{ + return new GMemoryStream(); +} + +class GIStreamImplPrivate +{ +public: + GIStreamImplPrivate(GIStreamImpl *parent) + : q_ptr(parent) + { + } + +private: + GIStreamImpl * const q_ptr; + Q_DECLARE_PUBLIC(GIStreamImpl); + + GStream *m_stream; + bool m_ownStream; +}; + +/* GStreamImpl */ + +GIStreamImpl::GIStreamImpl(GStream *stream) : d_ptr(new GIStreamImplPrivate(this)) +{ + Q_D(GIStreamImpl); + if (stream) + { + d->m_stream = stream; + d->m_ownStream = false; + } + else + { + d->m_stream = new GBlockMemoryStream(); + d->m_ownStream = true; + } +} + +GIStreamImpl::~GIStreamImpl() +{ + Q_D(GIStreamImpl); + if (d->m_ownStream) + { + d->m_stream->close(); + freeAndNil(d->m_stream) + } + + freePtr(d); +} + +GStream *GIStreamImpl::stream() const +{ + Q_D(const GIStreamImpl); + return d->m_stream; +} + +HRESULT GIStreamImpl::Read(void *pv, ULONG cb, ULONG *pcbRead) +{ + if (pv == NULL) + return STG_E_INVALIDPOINTER; + try + { + Q_D(GIStreamImpl); + *pcbRead = d->m_stream->read((char *)pv, cb); + return S_OK; + } + catch(...) + { + return S_FALSE; + } +} + +HRESULT GIStreamImpl::Write(const void *pv, ULONG cb, ULONG *pcbWritten) +{ + if (pv == NULL) + return STG_E_INVALIDPOINTER; + try + { + Q_D(GIStreamImpl); + *pcbWritten = d->m_stream->write((char *)pv, cb); + return S_OK; + } + catch(...) + { + return S_FALSE; + } +} + +HRESULT GIStreamImpl::Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition) +{ + try + { + Q_D(GIStreamImpl); + if ((dwOrigin > STREAM_SEEK_END))//(dwOrigin < STREAM_SEEK_SET) || + return STG_E_INVALIDFUNCTION; + switch (dwOrigin) + { + case STREAM_SEEK_SET: + { + d->m_stream->seek(dlibMove.QuadPart); + break; + } + case STREAM_SEEK_CUR: + { + long long llPos = d->m_stream->pos(); + d->m_stream->seek(llPos + dlibMove.QuadPart); + break; + } + case STREAM_SEEK_END: + { + long long llPos = d->m_stream->size(); + d->m_stream->seek(llPos + dlibMove.QuadPart); + break; + } + default: + break; + } + plibNewPosition->QuadPart = d->m_stream->pos(); + return S_OK; + } + catch(...) + { + return STG_E_INVALIDPOINTER; + } +} + +HRESULT GIStreamImpl::SetSize(ULARGE_INTEGER libNewSize) +{ + return S_OK; + G_UNUSED(libNewSize) +} + +HRESULT GIStreamImpl::CopyTo(IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten) +{ + char *buf = new char[cb.QuadPart]; + HRESULT result = S_OK; + try + { + Q_D(GIStreamImpl); + int nOldPos = d->m_stream->pos(); + pcbRead->QuadPart = d->m_stream->read(buf, cb.QuadPart); + pstm->Write(buf, cb.QuadPart, (ULONG *)&(pcbWritten->QuadPart)); + d->m_stream->seek(nOldPos); + result = S_OK; + } + catch(...) + { + result = E_UNEXPECTED; + } + freeAndNil(buf); + return result; +} + +HRESULT GIStreamImpl::Commit(DWORD grfCommitFlags) +{ + return S_OK; + G_UNUSED(grfCommitFlags) +} + +HRESULT GIStreamImpl::Revert() +{ + Q_D(GIStreamImpl); + d->m_stream->reset(); + return STG_E_REVERTED; +} + +HRESULT GIStreamImpl::LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) +{ + return STG_E_INVALIDFUNCTION; + G_UNUSED(libOffset); + G_UNUSED(cb); + G_UNUSED(dwLockType); +} + +HRESULT GIStreamImpl::UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) +{ + return STG_E_INVALIDFUNCTION; + G_UNUSED(libOffset); + G_UNUSED(cb); + G_UNUSED(dwLockType); +} + +HRESULT GIStreamImpl::Stat(STATSTG *pstatstg, DWORD grfStatFlag) +{ + HRESULT result = S_OK; + try + { + if (pstatstg != NULL) + { + Q_D(GIStreamImpl); + pstatstg->type = STGTY_STREAM; + pstatstg->cbSize.QuadPart = d->m_stream->size(); + pstatstg->mtime.dwLowDateTime = 0; + pstatstg->mtime.dwHighDateTime = 0; + pstatstg->ctime.dwLowDateTime = 0; + pstatstg->ctime.dwHighDateTime = 0; + pstatstg->atime.dwLowDateTime = 0; + pstatstg->atime.dwHighDateTime = 0; + pstatstg->grfLocksSupported = LOCK_WRITE; + } + } + catch(...) + { + result = E_UNEXPECTED; + throw; + } + return result; + G_UNUSED(grfStatFlag) +} + +HRESULT GIStreamImpl::Clone(IStream **ppstm) +{ + GIStreamImpl *iStream = new GIStreamImpl(); + iStream->AddRef(); + *ppstm = iStream; + try + { + Q_D(GIStreamImpl); + int nPos = d->m_stream->pos(); + d->m_stream->seek(0); + GByteArray array = d->m_stream->readAll(); + ULONG written = 0; + (*ppstm)->Write(array.constData(), array.length(), &written); + d->m_stream->seek(nPos); + } + catch(...) + { + return S_FALSE; + } + return S_OK; +} + +HRESULT GIStreamImpl::_QueryInterface(const IID &riid, void **ppvObject) +{ + if (riid == IID_IStream) + { + *ppvObject = static_cast(this); + this->AddRef(); + return NOERROR; + } + else + return GInterfaceObject::_QueryInterface(riid, ppvObject); +} + +class GStreamImplPrivate : public QIODevicePrivate +{ +public: + GStreamImplPrivate(GStreamImpl *parent) + : q_ptr(parent) + { + } + +private: + GStreamImpl * const q_ptr; + Q_DECLARE_PUBLIC(GStreamImpl); + + IStream *m_stream; + bool m_ownStream; +}; + +/* GIStream */ +GStreamImpl::GStreamImpl(IStream *stream, QIODevice::OpenMode flags) + : GStream(*(new GStreamImplPrivate(this))) +{ + Q_D(GStreamImpl); + if (stream == NULL) + { + d->m_stream = new GIStreamImpl(); + d->m_stream->AddRef(); + d->m_ownStream = true; + } + else + { + d->m_stream = stream; + d->m_ownStream = false; + } + open(flags); +} + +GStreamImpl::~GStreamImpl() +{ + Q_D(GStreamImpl); + if (d->m_ownStream) + { + freeAndNilIntf(d->m_stream) + } +} + +gint64 GStreamImpl::size() const +{ + Q_D(const GStreamImpl); + return streamLength(d->m_stream); +} + +gint64 GStreamImpl::pos() const +{ + return GStream::pos(); +} + +bool GStreamImpl::seek(gint64 off) +{ + Q_D(GStreamImpl); + ULARGE_INTEGER newPositon; + LARGE_INTEGER offset; + offset.QuadPart = off; + d->m_stream->Seek(offset, STREAM_SEEK_SET, &newPositon); + return GStream::seek(off); +} + +gint64 GStreamImpl::readData(char *data, gint64 maxlen) +{ + Q_D(GStreamImpl); + if (data == NULL) + return 0; + ULONG lRead = 0; + d->m_stream->Read(data, maxlen, &lRead); + return lRead; +} + +gint64 GStreamImpl::writeData(const char *data, gint64 len) +{ + Q_D(GStreamImpl); + if (data == NULL) + return 0; + ULONG lWrite(0); + d->m_stream->Write(data, len, &lWrite); + return lWrite; +} + +IStream *GStreamImpl::streamIntf() const +{ + Q_D(const GStreamImpl); + return d->m_stream; +} + +void readGUIDFromStream(GStream *stream, GUID &value) +{ + GByteArray baValue; + readByteArrayFromStream(stream, baValue); + + value = byteArrayToGUID(baValue); +} + +void writeGUIDToStream(GStream *stream, GUID value) +{ + writeByteArrayToStream(stream, GUIDToByteArray(value)); +} + +void copyStream(GStream *dst, GStream *src) +{ + const int nMaxReadSize = 4096; + while(src->pos() < src->size()) + { + dst->write(src->read(nMaxReadSize)); + } +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDStringObjectList.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDStringObjectList.cpp new file mode 100644 index 00000000..4ea3323a --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDStringObjectList.cpp @@ -0,0 +1,1271 @@ +#include "GLDStringObjectList.h" + +#include + +#include "GLDStream.h" +#include "GLDFile.h" +#include "GLDStrUtils.h" +#include "GLDException.h" +#include "GLDStreamUtils.h" +#include "GLDStrings.h" + +const char *g_DuplicateString = QT_TRANSLATE_NOOP("GLD", "String list does not allow duplicates");// "String list does not allow duplicates"); +const char *g_SortedListError = QT_TRANSLATE_NOOP("GLD", "Operation not allowed on sorted list");// "Operation not allowed on sorted list"); +const char *g_ListIndexError = QT_TRANSLATE_NOOP("GLD", "List index out of bounds (%d)");// "List index out of bounds (%d)"); + + +class GStringObjectListCompareEvent : public CSortCompareEvent +{ +public: + explicit GStringObjectListCompareEvent(GStringObjectList *stringObjectList); + CompareResult compare(void *item1, void *item2); +private: + explicit GStringObjectListCompareEvent(); +private: + GStringObjectList *m_stringObjectList; +}; + +GStringObjectListCompareEvent::GStringObjectListCompareEvent(GStringObjectList *stringObjectList) +{ + assert(stringObjectList != NULL); + m_stringObjectList = stringObjectList; +} + +CompareResult GStringObjectListCompareEvent::compare(void *item1, void *item2) +{ + GStringItem *it1 = (GStringItem*)item1; + GStringItem *it2 = (GStringItem*)item2; + int result = m_stringObjectList->compareStrings(it1->str, it2->str); + if (result > 0) + { + return crGreaterThan; + } + else if (result < 0) + { + return crLessThan; + } + else + { + return crEqual; + } +} + +class GStringObjectListPrivate +{ +public: + GStringObjectListPrivate(GStringObjectList *parent) + : q_ptr(parent) + { + } + + GStringObjectListPrivate() + : q_ptr(NULL) + { + } + +protected: + GStringObjectList * const q_ptr; + Q_DECLARE_PUBLIC(GStringObjectList); + +private: + bool m_caseSensitive; + bool m_sorted; + GStringObjectList::GDuplicates m_duplicates; + char m_delimiter; + byte m_defined; + GString m_lineBreak; + char m_quoteChar; + char m_nameValueSeparator; + bool m_strictDelimiter; + GObjectList m_list; + GString m_delimitedTextist; + int m_updateCount; +}; + +GStringObjectList::GStringObjectList() + : d_ptr(new GStringObjectListPrivate(this)) +{ + Q_D(GStringObjectList); + d->m_caseSensitive = false; + d->m_sorted = false; + d->m_duplicates = dupIgnore; + d->m_delimiter = '\0'; + d->m_defined = 0; + d->m_quoteChar = '\0' ; + d->m_nameValueSeparator = '\0'; + d->m_strictDelimiter = false; + d->m_updateCount = 0; +} + +GStringObjectList::GStringObjectList(GStringObjectListPrivate &dd) + : d_ptr(&dd) +{ + Q_D(GStringObjectList); + d->m_caseSensitive = false; + d->m_sorted = false; + d->m_duplicates = dupIgnore; + d->m_delimiter = '\0'; + d->m_defined = 0; + d->m_quoteChar = '\0' ; + d->m_nameValueSeparator = '\0'; + d->m_strictDelimiter = false; + d->m_updateCount = 0; +} + +GStringObjectList::GStringObjectList(const GStringObjectList &other) + : d_ptr(new GStringObjectListPrivate(this)) +{ + Q_D(GStringObjectList); + d->m_caseSensitive = other.d_ptr->m_caseSensitive; + d->m_sorted = other.d_ptr->m_sorted; + d->m_duplicates = other.d_ptr->m_duplicates; + d->m_delimiter = other.d_ptr->m_delimiter; + d->m_defined = other.d_ptr->m_defined; + d->m_lineBreak = other.d_ptr->m_lineBreak; + d->m_quoteChar = other.d_ptr->m_quoteChar; + d->m_nameValueSeparator = other.d_ptr->m_nameValueSeparator; + d->m_strictDelimiter = other.d_ptr->m_strictDelimiter; + + for (int i = 0; i < other.count(); ++i) + { + GStringItem *item = new GStringItem(); + item->str = other.d_ptr->m_list.at(i)->str; + item->object = other.d_ptr->m_list.at(i)->object; + + d->m_list.push_back(item); + } + d->m_delimitedTextist = other.d_ptr->m_delimitedTextist; + d->m_updateCount = other.d_ptr->m_updateCount; +} + +GStringObjectList::~GStringObjectList() +{ + Q_D(GStringObjectList); + clear(); + freePtr(d); +} + +int GStringObjectList::add(const GString &s) +{ + return addObject(s, NULL); +} + +int GStringObjectList::add(GStringItem *item) +{ + assert(item != NULL); + int result = findItem(item->str, item->object); + insertItem(result, item); + return result; +} + +int GStringObjectList::findItem(const GString &s, void *object) +{ + int result = 0; + + Q_D(GStringObjectList); + if (!d->m_sorted) + { + result = d->m_list.count(); + } + else if (find(s, result)) + { + switch (d->m_duplicates) + { + case dupIgnore: + return result; + case dupError: + gldError(getGLDi18nStr(g_DuplicateString), 0); + break; + default: + break; + } + } + return result; + G_UNUSED(object) +} + +int GStringObjectList::addObject(const GString &s, void *object) +{ + int result = findItem(s, object); + insertItem(result, s, object); + return result; +} + +int GStringObjectList::addStrings(GStringObjectList *list) +{ + Q_D(GStringObjectList); + beginUpdate(); + try + { + for (int i = 0; i < list->count(); ++i) + { + addObject(list->at(i)->str, list->at(i)->object); + } + } + catch(...) + { + endUpdate(); + throw; + } + endUpdate(); + return d->m_list.count(); +} + +void GStringObjectList::insert(int index, const GString &s) +{ + insertObject(index, s, NULL); +} + +void GStringObjectList::insertObject(int index, const GString &s, void *object) +{ + Q_D(GStringObjectList); + if (d->m_sorted) + { + gldError(getGLDi18nStr(g_SortedListError), 0); + } + if (index < 0) + { + index = 0; + } + else if (index > d->m_list.count()) + { + index = d->m_list.count(); + } + insertItem(index, s, object); +} + +bool GStringObjectList::find(const GString &s, int &index) +{ + Q_D(GStringObjectList); + bool result = false; + int nlow = 0; + int nHigh = d->m_list.count() - 1; + while (nlow <= nHigh) + { + int nIter = (nlow + nHigh) >> 1; + int nCompare = compareStrings(d->m_list.at(nIter)->str, s); + if (nCompare < 0) + { + nlow = nIter + 1; + } + else + { + nHigh = nIter - 1; + if (nCompare == 0) + { + result = true; + if (d->m_duplicates != dupAccept) + { + nlow = nIter; + } + } + } + } + index = nlow; + return result; +} + +bool GStringObjectList::caseSensitive() const +{ + Q_D(const GStringObjectList); + return d->m_caseSensitive; +} + +void GStringObjectList::setCaseSensitive(bool caseSensitive) +{ + Q_D(GStringObjectList); + if (d->m_caseSensitive != caseSensitive) + { + d->m_caseSensitive = caseSensitive; + if (d->m_sorted) + { + sort(); + } + } +} + +char GStringObjectList::delimiter() +{ + Q_D(GStringObjectList); + if (!contains(d->m_defined, sdDelimiter)) + { + d->m_delimiter = ','; + } + return d->m_delimiter; +} + +void GStringObjectList::setDelimiter(char delimiter) +{ + Q_D(GStringObjectList); + if ((d->m_delimiter != delimiter) || !contains(d->m_defined, sdDelimiter)) + { + include(d->m_defined, sdDelimiter); + d->m_delimiter = delimiter; + } +} + +GStringObjectList::GDuplicates GStringObjectList::duplicates() const +{ + Q_D(const GStringObjectList); + return d->m_duplicates; +} + +void GStringObjectList::setDuplicates(const GDuplicates &duplicates) +{ + Q_D(GStringObjectList); + d->m_duplicates = duplicates; +} + +bool GStringObjectList::sorted() const +{ + Q_D(const GStringObjectList); + return d->m_sorted; +} + +void GStringObjectList::setSorted(bool sorted) +{ + Q_D(GStringObjectList); + if (d->m_sorted != sorted) + { + if (sorted) + { + sort(); + } + d->m_sorted = sorted; + } +} + +GString GStringObjectList::lineBreak() +{ + Q_D(GStringObjectList); + if (!contains(d->m_defined, sdLineBreak)) + { + d->m_lineBreak = sLineBreak; + } + return d->m_lineBreak; +} + +void GStringObjectList::setLineBreak(const GString &lineBreak) +{ + Q_D(GStringObjectList); + if ((d->m_lineBreak != lineBreak) || !contains(d->m_defined, sdLineBreak)) + { + include(d->m_defined, sdLineBreak); + d->m_lineBreak = lineBreak; + } +} + +char GStringObjectList::quoteChar() +{ + Q_D(GStringObjectList); + if (!contains(d->m_defined, sdQuoteChar)) + { + d->m_quoteChar = '"'; + } + return d->m_quoteChar; +} + +void GStringObjectList::setQuoteChar(char quoteChar) +{ + Q_D(GStringObjectList); + if ((d->m_quoteChar != quoteChar) || !contains(d->m_defined, sdQuoteChar)) + { + include(d->m_defined, sdQuoteChar); + d->m_quoteChar = quoteChar; + } +} + +char GStringObjectList::nameValueSeparator() +{ + Q_D(GStringObjectList); + if (!contains(d->m_defined, sdNameValueSeparator)) + { + d->m_nameValueSeparator = '='; + } + return d->m_nameValueSeparator; +} + +void GStringObjectList::setNameValueSeparator(char nameValueSeparator) +{ + Q_D(GStringObjectList); + if ((d->m_nameValueSeparator != nameValueSeparator) || !contains(d->m_defined, sdNameValueSeparator)) + { + include(d->m_defined, sdNameValueSeparator); + d->m_nameValueSeparator = nameValueSeparator; + } +} + +bool GStringObjectList::strictDelimiter() +{ + Q_D(GStringObjectList); + if (!contains(d->m_defined, sdStrictDelimiter)) + { + d->m_strictDelimiter = false; + } + return d->m_strictDelimiter; +} + +void GStringObjectList::setStrictDelimiter(bool strictDelimiter) +{ + Q_D(GStringObjectList); + if ((d->m_strictDelimiter != strictDelimiter) || !contains(d->m_defined, sdStrictDelimiter)) + { + include(d->m_defined, sdStrictDelimiter); + d->m_strictDelimiter = strictDelimiter; + } +} + +GString GStringObjectList::delimitedText() +{ + gint64 lDelimiters(0); + + GString result; + int nCount = count(); + if ((nCount == 1) && (at(0)->str.length() == 0)) + { + result = quoteChar() + quoteChar(); + } + else + { + includeOfGint64(lDelimiters, 0); + includeOfGint64(lDelimiters, quoteChar()); + includeOfGint64(lDelimiters, delimiter()); + if (!strictDelimiter()) + { + for (gint64 i = 1; i <= ' '; ++i) + { + includeOfGint64(lDelimiters, i); + } + } + for (int i = 0; i < nCount; ++i) + { + GString strTmp = at(i)->str; + int nIndex = 0; + while ((nIndex < strTmp.length()) && + ((strTmp.at(nIndex).unicode() >= 64) || (!containsOfGint64(lDelimiters, gint64(strTmp.at(nIndex).unicode()))))) + { + nIndex++; + } + + if (nIndex <= strTmp.length() - 1) + { + strTmp = quotedStr(strTmp, quoteChar()); + } + result = result + strTmp + delimiter(); + } + result = copy(result, 0, result.length() - 1); + } + + return result; +} + +bool GStringObjectList::containsBeforeSpace(const gint64 set) +{ + bool result = false; + for (gint64 i = 1; i <= ' '; ++i) + { + result = containsOfGint64(set, i); + if (result) + { + break; + } + } + return result; +} + +void GStringObjectList::setDelimitedText(const GString &value) +{ + Q_D(GStringObjectList); + GString delimitedText(value); + beginUpdate(); + try + { + clear(); + if (value.length() == 0) + { + return; + } + int nIndex = 0; + int nIndex1 = 0; + if (!strictDelimiter()) + { + gint64 context = 1; + while ((delimitedText.at(nIndex).unicode() >= 1) && (delimitedText.at(nIndex).unicode() <= ' ')) + { + ++nIndex; + ++context; + } + } + while (nIndex < delimitedText.length()) + { + GString strTmp; + if (delimitedText.at(nIndex).unicode() == quoteChar()) + { + delimitedText = copy(delimitedText, nIndex); + strTmp = extractQuotedStr(delimitedText, quoteChar()); + } + else + { + nIndex1 = nIndex; + int nLength = delimitedText.length(); + while ((nIndex < nLength) + && ((!d->m_strictDelimiter && (delimitedText.at(nIndex).unicode() > ' ')) + || (d->m_strictDelimiter && (delimitedText.at(nIndex) != delimiter())))) + { + nIndex++; + } + strTmp = copy(delimitedText, nIndex1, nIndex - nIndex1); + } + add(strTmp); + int nLength = delimitedText.length(); + if (!d->m_strictDelimiter) + { + while ((nIndex < nLength) + && (delimitedText.at(nIndex).toLatin1() >= 1) && (delimitedText.at(nIndex).toLatin1() <= ' ')) + { + ++nIndex; + } + } + if ((nIndex < nLength) && (delimitedText.at(nIndex).unicode() == delimiter())) + { + nIndex1 = nIndex; + if (nIndex1 == delimitedText.length()) + { + add(""); + } + do + { + ++nIndex; + } while ((nIndex < delimitedText.length()) + && (!d->m_strictDelimiter + && ((delimitedText.at(nIndex).toLatin1() >= 1) + && (delimitedText.at(nIndex).toLatin1() <= ' ')))); + } + } + } + catch(...) + { + endUpdate(); + throw; + } + endUpdate(); +} + +void GStringObjectList::setCommaText(const GString &value) +{ + setDelimiter(','); + setQuoteChar('\"'); + setDelimitedText(value); +} + +GString GStringObjectList::commaText() +{ + Q_D(GStringObjectList); + byte lOldDefined = d->m_defined; + char cOldDelimiter = d->m_delimiter; + char cOldQuoteChar = d->m_quoteChar; + setDelimiter(','); + setQuoteChar('"'); + GString result; + try + { + result = delimitedText(); + } + catch(...) + { + d->m_delimiter = cOldDelimiter; + d->m_quoteChar = cOldQuoteChar; + d->m_defined = lOldDefined; + throw; + } + d->m_delimiter = cOldDelimiter; + d->m_quoteChar = cOldQuoteChar; + d->m_defined = lOldDefined; + return result; +} + +void GStringObjectList::insertItem(int index, const GString &s, void* object) +{ + Q_D(GStringObjectList); + changing(); + GStringItem *item = new GStringItem(); + item->str = s; + item->object = object; + d->m_list.insert(index, item); + changed(); +} + +void GStringObjectList::insertItem(int index, GStringItem *item) +{ + Q_D(GStringObjectList); + assert(item != NULL); + changing(); + d->m_list.insert(index, item); + changed(); +} + +void GStringObjectList::changed() +{ + // todo +} + +void GStringObjectList::loadFromFile(const GString &fileName) +{ + GFileStream file(fileName); + if (!file.open(GStream::ReadOnly)) + { + return; + } + file.seek(0); + try + { + loadFromStream(&file); + } + catch(...) + { + file.close(); + throw; + } + file.close(); +} + +void GStringObjectList::loadFromStream(GStream *stream) +{ + beginUpdate(); + try + { + int nSize = stream->size() - stream->pos(); + GString strReaded = readFromStream(stream, nSize); + setTextStr(strReaded); + } + catch(...) + { + endUpdate(); + throw; + } + endUpdate(); +} + +void GStringObjectList::saveToFile(const GString &fileName) +{ + GFileStream file(fileName); + if (!file.open(GStream::WriteOnly)) + { + return; + } + file.seek(0); + try + { + saveToStream(&file); + } + catch(...) + { + file.close(); + throw; + } + file.close(); +} + +void GStringObjectList::saveToStream(GStream *stream) +{ + GString value = textStr(); + QTextStream textStream(stream); + textStream << value; + textStream.flush(); +} + +void GStringObjectList::beginUpdate() +{ + Q_D(GStringObjectList); + if (d->m_updateCount == 0) + { + setUpdateState(true); + } + d->m_updateCount++; +} + +void GStringObjectList::endUpdate() +{ + Q_D(GStringObjectList); + d->m_updateCount--; + if (d->m_updateCount == 0) + { + setUpdateState(false); + } +} + +void GStringObjectList::setUpdateState(bool updating) +{ + if (updating) + { + changing(); + } + else + { + changed(); + } +} + +void GStringObjectList::assign(GStringObjectList *source) +{ + Q_D(GStringObjectList); + beginUpdate(); + try + { + clear(); + d->m_defined = source->d_ptr->m_defined; + d->m_nameValueSeparator = source->d_ptr->m_nameValueSeparator; + d->m_quoteChar = source->d_ptr->m_quoteChar; + d->m_delimiter = source->d_ptr->m_delimiter; + d->m_lineBreak = source->d_ptr->m_lineBreak; + d->m_strictDelimiter = source->d_ptr->m_strictDelimiter; + addStrings(source); + } + catch(...) + { + endUpdate(); + throw; + } + endUpdate(); +} + +void GStringObjectList::changing() +{ + // todo +} + +void GStringObjectList::put(int index, const GString &s) +{ + Q_D(GStringObjectList); + if (sorted()) + { + gldError(getGLDi18nStr(g_SortedListError), 0); + } + checkIndex(index); + changing(); + d->m_list.at(index)->str = s; + changed(); +} + +GString GStringObjectList::extractName(const GString &s) +{ + int nPos = pos(nameValueSeparator(), s); + if (nPos >= 0) + { + return copy(s, 0, nPos); + } + else + { + return GString(); + } +} + +int GStringObjectList::indexOfObject(void* value) +{ + Q_D(GStringObjectList); + for (int i = 0; i < d->m_list.count(); ++i) + { + if (d->m_list.at(i)->object == value) + { + return i; + } + } + return -1; +} + +int GStringObjectList::indexOf(const GString &value) +{ + Q_D(GStringObjectList); + for (int i = 0; i < d->m_list.count(); ++i) + { + if (sameText(d->m_list.at(i)->str, value)) + { + return i; + } + } + return -1; +} + +void GStringObjectList::checkIndex(int index) const +{ + Q_D(const GStringObjectList); + if ((index < 0) || (index >= d->m_list.count())) + { + gldErrorFmt(getGLDi18nStr(g_ListIndexError), index); + } +} + +GString GStringObjectList::string(int index) +{ + Q_D(GStringObjectList); + checkIndex(index); + return d->m_list.at(index)->str; +} + +void GStringObjectList::putString(int index, const GString &s) +{ + put(index, s); +} + +void *GStringObjectList::object(int index) +{ + Q_D(GStringObjectList); + checkIndex(index); + return d->m_list.at(index)->object; +} + +void GStringObjectList::putObject(int index, void *object) +{ + Q_D(GStringObjectList); + checkIndex(index); + changing(); + d->m_list.at(index)->object = object; + changed(); +} + +void GStringObjectList::clear() +{ + Q_D(GStringObjectList); + changing(); + d->m_list.clear(); + changed(); +} + +bool GStringObjectList::isEmpty() +{ + Q_D(GStringObjectList); + return d->m_list.isEmpty(); +} + +int GStringObjectList::count() const +{ + Q_D(const GStringObjectList); + return d->m_list.count(); +} + +int GStringObjectList::size() +{ + Q_D(GStringObjectList); + return int(d->m_list.size()); +} + +GStringItem *GStringObjectList::at(int index) const +{ + Q_D(const GStringObjectList); + checkIndex(index); + return d->m_list.at(index); +} + +void GStringObjectList::setIndex(int index, GStringItem *item) +{ + Q_D(GStringObjectList); + if (d->m_sorted) + { + gldError(getGLDi18nStr(g_SortedListError), 0); + } + checkIndex(index); + freeAndNil(d->m_list[index]); + changing(); + d->m_list[index] = item; + changed(); +} + +GStringItem *&GStringObjectList::operator [](int index) +{ + Q_D(GStringObjectList); + checkIndex(index); + return d->m_list[index]; +} + +void GStringObjectList::push_back(GStringItem *item) +{ + Q_D(GStringObjectList); + if (d->m_sorted) + { + gldError(getGLDi18nStr(g_SortedListError), 0); + } + changing(); + d->m_list.push_back(item); + changed(); +} + +void GStringObjectList::append(GStringItem *item) +{ + Q_D(GStringObjectList); + if (d->m_sorted) + { + gldError(getGLDi18nStr(g_SortedListError), 0); + } + changing(); + d->m_list.append(item); + changed(); +} + +void GStringObjectList::append(GObjectList &items) +{ + Q_D(GStringObjectList); + if (d->m_sorted) + { + gldError(getGLDi18nStr(g_SortedListError), 0); + } + changing(); + d->m_list.append(items); + changed(); +} + +GObjectList &GStringObjectList::list() +{ + Q_D(GStringObjectList); + return d->m_list; +} + +void GStringObjectList::Delete(int index) +{ + changing(); + removeAt(index); + changed(); +} + +void GStringObjectList::removeAt(int index) +{ + Q_D(GStringObjectList); + changing(); + d->m_list.removeAt(index); + changed(); +} + +void GStringObjectList::exchange(int index1, int index2) +{ + Q_D(GStringObjectList); + if (d->m_sorted) + { + gldError(getGLDi18nStr(g_SortedListError), 0); + } + changing(); + swap(index1, index2); + changed(); +} + +void GStringObjectList::swap(int index1, int index2) +{ + Q_D(GStringObjectList); + if (d->m_sorted) + { + gldError(getGLDi18nStr(g_SortedListError), 0); + } + changing(); + d->m_list.swap(index1, index2); + changed(); +} + +void GStringObjectList::sort(bool ascend) +{ + GStringObjectListCompareEvent event(this); + customSort(&event, ascend); +} + +void GStringObjectList::customSort(CSortCompareEvent *customSortEvent, bool ascend) +{ + Q_D(GStringObjectList); + changing(); + quickSort(d->m_list.list(), customSortEvent, ascend); + changing(); +} + +GString GStringObjectList::value(const GString &name) +{ + Q_D(GStringObjectList); + int nIndex = indexOfName(name); + if (nIndex >= 0) + { + return copy(d->m_list.at(nIndex)->str, name.length() + 1, MaxInt); + } + else + { + return GString(); + } +} + +void GStringObjectList::setValue(const GString &name, const GString &value) +{ + Q_D(GStringObjectList); + int nIndex = indexOfName(name); + if (value.length() > 0) + { + if (nIndex < 0) + { + nIndex = add(""); + } + put(nIndex, name + nameValueSeparator() + value); + } + else + { + if (nIndex >= 0) + { + d->m_list.removeAt(nIndex); + } + } +} + +GString GStringObjectList::valueFromIndex(int index) +{ + Q_D(GStringObjectList); + if (index >= 0) + { + if (index >= 0) + { + QString sValue = d->m_list.at(index)->str; + QString sName = names(index); + if (!sName.isEmpty()) + { + sValue = copy(sValue, sName.length() + 1, MaxInt); //+1:跳过等于符号 + } + return sValue; + } + } + return GString(); +} + +void GStringObjectList::setValueFromIndex(int index, const GString &value) +{ + Q_D(GStringObjectList); + if (value.length() > 0) + { + if (index < 0) + { + index = add(""); + } + put(index, names(index) + nameValueSeparator() + value); + } + else + { + if (index >= 0) + { + changing(); + d->m_list.removeAt(index); + changed(); + } + } +} + +GString GStringObjectList::names(int index) +{ + Q_D(GStringObjectList); + return extractName(d->m_list.at(index)->str); +} + +int GStringObjectList::indexOfName(const GString &name) +{ + Q_D(GStringObjectList); + int result = 0; + for (result = 0; result < d->m_list.count(); ++result) + { + GString strTmp = d->m_list.at(result)->str; + int nPos = pos(nameValueSeparator(), strTmp); + if ((nPos >= 0) && (compareStrings(copy(strTmp, 0, nPos), name) == 0)) + { + return result; + } + } + return -1; +} + +int GStringObjectList::compareStrings(const GString &s1, const GString &s2) +{ + Q_D(GStringObjectList); + int result = 0; + if (d->m_caseSensitive) + { + result = compareStr(s1, s2); + } + else + { + result = compareText(s1, s2); + } + return result; +} + +void GStringObjectList::setTextStr(const GString &value) +{ + beginUpdate(); + try + { + clear(); + int nPos = value.length(); + if (nPos > 0) + { +#ifdef WIN32 + nPos = 0; + while (nPos < value.length()) + { + int nStart = nPos; + ushort ch = value.at(nPos).unicode(); + while ((ch != '\0') && (ch != '\r') && (ch != '\n')) + { + nPos++; + if (nPos >= value.size()) + { + break; + } + ch = value.at(nPos).unicode(); + } + GString strTmp = copy(value, nStart, nPos - nStart); + add(strTmp); + if (nPos >= value.size()) + { + break; + } + ch = value.at(nPos).unicode(); + if (ch == '\r') + { + nPos++; + } + ch = value.at(nPos).unicode(); + if (ch == '\n') + { + nPos++; + } + } +#else + // todo + assert(false); +#endif + } + } + catch(...) + { + endUpdate(); + throw; + } + endUpdate(); +} + +GString GStringObjectList::textStr() +{ + GString result; + GString sLineBreak = lineBreak(); + for (int i = 0; i != count(); ++i) + { + result += (at(i)->str + sLineBreak); + } + return result; +} + +class GHashedStringObjectListPrivate : public GStringObjectListPrivate +{ +public: + GHashedStringObjectListPrivate() + : m_valueHashValid(false), m_nameHashValid(false) + { + } + +private: + Q_DECLARE_PUBLIC(GHashedStringObjectList); + + GLDHash m_valueHash; + GLDHash m_nameHash; + bool m_valueHashValid; + bool m_nameHashValid; +}; + +GHashedStringObjectList::GHashedStringObjectList() + : GStringObjectList(* (new GHashedStringObjectListPrivate)) +{ +} + +GHashedStringObjectList::~GHashedStringObjectList() +{ + Q_D(GHashedStringObjectList); + d->m_valueHash.clear(); + d->m_nameHash.clear(); +} + +int GHashedStringObjectList::indexOfName(const GString &name) +{ + Q_D(GHashedStringObjectList); + int result = -1; + updateNameHash(); + if (!caseSensitive()) + { + result = d->m_nameHash.value(upperCase(name), -1); + } + else + { + result = d->m_nameHash.value(name, -1); + } + return result; +} + +int GHashedStringObjectList::indexOf(const GString &value) +{ + Q_D(GHashedStringObjectList); + int result = -1; + updateValueHash(); + if (!caseSensitive()) + { + result = d->m_valueHash.value(upperCase(value), -1); + } + else + { + result = d->m_valueHash.value(value, -1); + } + return result; +} + +void GHashedStringObjectList::changed() +{ + Q_D(GHashedStringObjectList); + GStringObjectList::changed(); + d->m_valueHashValid = false; + d->m_nameHashValid = false; +} + +void GHashedStringObjectList::updateValueHash() +{ + Q_D(GHashedStringObjectList); + if (d->m_valueHashValid) + { + return; + } + d->m_valueHash.clear(); + for (int i = 0; i < count(); ++i) + { + if (!caseSensitive()) + { + d->m_valueHash[upperCase(at(i)->str)] = i; + } + else + { + d->m_valueHash[at(i)->str] = i; + } + d->m_valueHashValid = true; + } +} + +void GHashedStringObjectList::updateNameHash() +{ + Q_D(GHashedStringObjectList); + if (d->m_nameHashValid) + { + return; + } + d->m_nameHash.clear(); + for (int i = 0; i < count(); ++i) + { + GString key = at(i)->str; + int nPos = pos(nameValueSeparator(), key); + if (nPos >= 0) + { + if (!caseSensitive()) + { + key = upperCase(copy(key, 0, nPos)); + } + else + { + key = copy(key, 0, nPos); + } + d->m_nameHash[key] = i; + } + } + d->m_nameHashValid = true; +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDStrings.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDStrings.cpp new file mode 100644 index 00000000..455f6c12 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDStrings.cpp @@ -0,0 +1,88 @@ +#include "GLDStrings.h" +#include + +const char *g_InvalidInteger = QT_TRANSLATE_NOOP("GLD", "Invalid integer [%s]");// "非法整数值[%s]"); +const char *g_InvalidFloat = QT_TRANSLATE_NOOP("GLD", "Illegal floating number [%s]");// "非法浮点数[%s]"); +const char *g_InvalidGUID = QT_TRANSLATE_NOOP("GLD", "Invalid GUID[%s]");// "非法GUID值[%s]"); +const char *g_InvalidTypeCompare = QT_TRANSLATE_NOOP("GLD", "Types dosn`t match");// "类型不匹配"); + +const char *g_rsInvalidBase64Data = QT_TRANSLATE_NOOP("GLD", "Invalid Base64 Data");// "字符串编码格式非法"); +const char *g_rsInvalidTimeFormat = QT_TRANSLATE_NOOP("GLD", "\'%1\'is not a valid date and time");// "\'%s\' 不是合法的日期时间"); + +const char *g_MissingExtPropCode = QT_TRANSLATE_NOOP("GLD", "Extended attribute code cannot be null");// "扩展属性代码不能为空"); +const char *g_ExtPropCodeExist = QT_TRANSLATE_NOOP("GLD", "Extended attribute code[%1] is repeated");// "扩展属性代码[%s]重复"); + +const char *g_InvalidFieldName = QT_TRANSLATE_NOOP("GLD", "Invalid Edit Field Name[%1] of Table[%2]");// "表[%s]非法编辑字段名[%s]"); +const char *g_NeedRunState = QT_TRANSLATE_NOOP("GLD", "This Operation Can Only Be Used in Running Status");// "该操作只能在运行状态下使用"); +const char *g_InvalidFieldNameMark = QT_TRANSLATE_NOOP("GLD", "Table [%1] has illegal field name [%2]");// "表[%s]非法字段名称[%s],\"&\"后必须为枚举字段、表达式字段、时间日期字段"); +const char *g_NotExistVisibleCol = QT_TRANSLATE_NOOP("GSP", "No Non Fixed Column to Display");// "没有可显示的非固定列"); + +const char *g_InvalidXMLNode = QT_TRANSLATE_NOOP("GSP", "Invalid configuration file");// "配置文件非法"); +const char *g_NeedXMLNode = QT_TRANSLATE_NOOP("GSP", "XML Node field cannot be null");// "XML节点不能为空"); + +const char *g_SelectImage = QT_TRANSLATE_NOOP("GLD", "select image");//选择图片 +const char *g_SquareReplace = QT_TRANSLATE_NOOP("GLD", "two");//TRANS_STRING("弍"); +const char *g_CubeReplace = QT_TRANSLATE_NOOP("GLD", "three");//TRANS_STRING("弎"); + +const char *g_rsInvalideRule = QT_TRANSLATE_NOOP("GLD", "Current rule not exist"); //"当前Rule不存在"); +const char *g_rsHasNoActiveSheet = QT_TRANSLATE_NOOP("GLD", "No actived Sheet"); //"没有激活的Sheet"); +const char *g_rsGetMergeRectFailed = QT_TRANSLATE_NOOP("GLD", "Getting merge cell failed"); //"获得合并格失败"); +const char *g_rsTitleIndex = QT_TRANSLATE_NOOP("GLD", "Index"); //序号 +const char *g_rsTitleSelect = QT_TRANSLATE_NOOP("GLD", "Select"); //选择 +const char *g_rsTitleSymbol = QT_TRANSLATE_NOOP("GLD", "Symbol"); //标识 + +// BinFile2 +const char *g_InvalidBinFile = QT_TRANSLATE_NOOP("GSP", "InvalidBinFile"); // 无效的二进制文件 +const char *g_ReadBinFileError = QT_TRANSLATE_NOOP("GSP", "ReadBinFileError"); // 读取二进制文件错误 + +const char *g_rsMonth = QT_TRANSLATE_NOOP("GLD", "Month"); +const char *g_rsYear = QT_TRANSLATE_NOOP("GLD", "Year"); +const char *g_rsDay = QT_TRANSLATE_NOOP("GLD", "Day"); +const char *g_rsMonDay = QT_TRANSLATE_NOOP("GLD", "Mon"); +const char *g_rsTueDay = QT_TRANSLATE_NOOP("GLD", "Tue"); +const char *g_rsWedDay = QT_TRANSLATE_NOOP("GLD", "Wed"); +const char *g_rsThuDay = QT_TRANSLATE_NOOP("GLD", "Thu"); +const char *g_rsFriDay = QT_TRANSLATE_NOOP("GLD", "Fri"); +const char *g_rsSatDay = QT_TRANSLATE_NOOP("GLD", "Sat"); +const char *g_rsSunDay = QT_TRANSLATE_NOOP("GLD", "Sun"); + +const char *g_rsFontEffect = QT_TRANSLATE_NOOP("GLD", "FontEffect"); +const char *g_rsEffect = QT_TRANSLATE_NOOP("GLD", "Effect"); +const char *g_rsNoLine = QT_TRANSLATE_NOOP("GLD", "NoLine"); +const char *g_rsOtherLine = QT_TRANSLATE_NOOP("GLD", "OtherLine(w)..."); +const char *g_rsLineWidth = QT_TRANSLATE_NOOP("GLD", "Pounds"); + +const char *g_rsAutoHide = QT_TRANSLATE_NOOP("GLD", "AutoHide"); +const char *g_rsLocked = QT_TRANSLATE_NOOP("GLD", "Locked"); + +const char *g_rsSimsun = QT_TRANSLATE_NOOP("GLD", "Simsun"); +const char *g_rsAccount = QT_TRANSLATE_NOOP("GLD", "Account:"); +const char *g_rsPassword = QT_TRANSLATE_NOOP("GLD", "Password:"); +const char *g_rsLogin = QT_TRANSLATE_NOOP("GLD", "Login"); +const char *g_rsCancel = QT_TRANSLATE_NOOP("GLD", "Cancel"); +const char *g_rsRegisterAccount = QT_TRANSLATE_NOOP("GLD", "RegisterAccount"); +const char *g_rsGetBackPassword = QT_TRANSLATE_NOOP("GLD", "GetBackPassword"); +const char *g_rsRemeberPassword = QT_TRANSLATE_NOOP("GLD", "RemeberPassword"); +const char *g_rsAutoLogin = QT_TRANSLATE_NOOP("GLD", "AutoLogin"); +const char *g_rsOpenVirtualKeyboard = QT_TRANSLATE_NOOP("GLD", "OpenVirtualKeyboard"); +const char *g_rsAccountError = QT_TRANSLATE_NOOP("GLD", "The username or password is error, please enter again!"); +const char *g_rsLoginError = QT_TRANSLATE_NOOP("GLD", "Login failed, please try again later!"); +const char *g_rsNetworkError = QT_TRANSLATE_NOOP("GLD", "Network connection error, please check your network!"); + +GString getGLDi18nStr(const char *originalStr) +{ + static const char *s_context = "GLD"; + return qApp->translate(s_context, originalStr); +} + +GString getGSPi18nStr(const char *originalStr) +{ + static const char *s_context = "GSP"; + return qApp->translate(s_context, originalStr); +} + +GString getGEPEnginei18nStr(const char *originalStr) +{ + static const char *s_context = "GEPEngine"; + return qApp->translate(s_context, originalStr); +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDSysUtils.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDSysUtils.cpp new file mode 100644 index 00000000..03fa5bd3 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDSysUtils.cpp @@ -0,0 +1,651 @@ +#include "GLDSysUtils.h" + +#include + +#include "GLDGlobal.h" +#include "GLDVector.h" +#include "GLDStrUtils.h" +#include "GLDSettings.h" +#include "GLDDir.h" + +#ifdef WIN32 +# include +# include +# include +# ifdef _MSC_VER +# pragma comment(lib, "NETAPI32.LIB") +# endif +#else +# include +//# include +# include +# include +# include +# include +# include +#endif + +#if defined(__GNUC__) // GCC +#include +#endif + +#if _MSC_VER >=1400 // VC2005才支持intrin.h +#include // 所有Intrinsics函数 +#endif + +#ifdef WIN32 +const GChar c_GLDPathDelim = 0x5c; // '\\' +const GChar c_GLDPathDelim_Linux = '/'; // '\\' +const GChar c_GLDDriveDelim = 0x3a; // ':' +#else +const GChar c_GLDPathDelim = 0x2f; // '/' +const GChar c_GLDPathDelim_Linux = '/'; // '\\' +const GChar c_GLDDriveDelim = 0x00; // '' +#endif + +GChar pathDelim() +{ + return c_GLDPathDelim; +} + +GChar driveDelim() +{ + return c_GLDDriveDelim; +} + +GChar backSlashDelim() +{ + return 0x2f; // '/' +} + +bool isPathDelimiter(const GString &s, int index) +{ + return (index > 0) && (index < s.length()) && ((s.at(index) == c_GLDPathDelim) || (s.at(index) == c_GLDPathDelim_Linux)); +} + +GString includeTrailingBackslash(const GString &s) +{ + return includeTrailingPathDelimiter(s); +} + +GString includeTrailingPathDelimiter(const GString &s) +{ + GString result = s; + if (!isPathDelimiter(s, s.length() - 1)) + { + result += c_GLDPathDelim; + } + return result; +} + +GString excludeTrailingBackslash(const GString &s) +{ + return excludeTrailingPathDelimiter(s); +} + +GString excludeTrailingPathDelimiter(const GString &s) +{ + GString result = s; + if (isPathDelimiter(s, s.length() - 1)) + result.chop(1); + return result; +} + +double fileDateToDateTime(int fileDate) +{ + int nYear(0); + int nMonth(0); + int nDay(0); + int nHour(0); + int nMin(0); + int nSec(0); + int nHi(0); + int nLow(0); + nHi = (fileDate & 0xffff0000) >> 16; + nYear = (nHi >> 9) + 1980; + nMonth = (nHi >> 5) & 15; + nDay = (nHi & 31); + nLow = fileDate & 0x0000ffff; + nHour = nLow >> 11; + nMin = (nLow >> 5) & 63; + nSec = (nLow & 31) << 1; + return dateTimeToDouble(GDateTime(GDate(nYear, nMonth, nDay), GTime(nHour, nMin, nSec))); +} + +int DateTimeToFileDate(double value) +{ + int nResult = 0; + int nYear(0); + int nMonth(0); + int nDay(0); + int nHour(0); + int nMin(0); + int nSec(0); + GDateTime dateTime = doubleToDateTime(value); + GDate date = dateTime.date(); + GTime time = dateTime.time(); + if ((yearOf(value) < 1980) || (yearOf(value) > 2107)) + nResult = 0; + else + { + nYear = date.year(); + nMonth = date.month(); + nDay = date.day(); + nHour = time.hour(); + nMin = time.minute(); + nSec = time.second(); + nResult |= ((nSec >> 1) | (nMin << 5) | (nHour << 11)) & 0x0000ffff; + nResult |= ((nDay | (nMonth << 5) | (nYear - 1980) << 9)) << 16; + } + return nResult; +} + +GString getUserNameDef() +{ +#ifdef _MSC_VER + char *pBuff; + size_t nLen; + + if (0 == _dupenv_s(&pBuff, &nLen, "USERNAME")) + { + GString sName(pBuff); + free(pBuff); + + return sName; + } + + free(pBuff); + return GString(""); +#else + return GString(getenv("USER")); +#endif +} + +GString getHostName() +{ + char szAddr[255] = { '\0' }; + +#ifdef Q_OS_WIN + unsigned long uSize = 255; + GetComputerNameA(szAddr, &uSize); +#else + gethostname(szAddr, sizeof(szAddr)); +#endif + + return GString(szAddr); +} + +unsigned getCoreCount() +{ + unsigned uCount = 1; // 至少一个 + +#ifdef Q_OS_WIN + SYSTEM_INFO si; + GetSystemInfo(&si); + uCount = si.dwNumberOfProcessors; +#else + uCount = sysconf(_SC_NPROCESSORS_CONF); +#endif + + return uCount; +} + +/**************************************************************************************************** + 作者: ruanlz 2015-07-14 + 函数名称:getCPUIdString + 返回: GString + 功能: 获取cpuID + 备注: 使用__cpuid函数获取cpuid,对于不支持__cpuid函数的win32下的编译器使用了内联汇编实现__cpuid函数 + 在windows下使用wmic命令做了验证,非windows平台在ubuntu 12.04.01和maxos 10.9上做了验证但因为 + 是在虚拟机上运行,硬件信息不能验证,所以准确性不能定论。 + 注意: cpu序列号不唯一,相同型号的cpu的cpu序列号可能相同 + 处理器:Intel 486以上和AMD am486以上的X86架构的处理器,不支持除X86以外架构的处理器 +****************************************************************************************************/ + +#if defined(_WIN64) +// 64位下不支持内联汇编. 应使用__cpuid、__cpuidex等Intrinsics函数。 +#elif defined(WIN32) +#if _MSC_VER < 1600 // VS2010. 据说VC2008 SP1之后才支持__cpuidex +void __cpuidex(INT32 CPUInfo[4], INT32 InfoType, INT32 ECXValue) +{ + if (NULL==CPUInfo) return; + _asm{ + // load. 读取参数到寄存器 + mov edi, CPUInfo; // 准备用edi寻址CPUInfo + mov eax, InfoType; + mov ecx, ECXValue; + // CPUID + cpuid; + // save. 将寄存器保存到CPUInfo + mov [edi], eax; + mov [edi+4], ebx; + mov [edi+8], ecx; + mov [edi+12], edx; + } +} +#endif // #if _MSC_VER < 1600 // VS2010. 据说VC2008 SP1之后才支持__cpuidex + +#if _MSC_VER < 1400 // VC2005才支持__cpuid +void __cpuid(INT32 CPUInfo[4], INT32 InfoType) +{ + __cpuidex(CPUInfo, InfoType, 0); +} +#endif // #if _MSC_VER < 1400 // VC2005才支持__cpuid + +#endif // #if defined(_WIN64) + +GString getCPUIdString() +{ +#ifdef Q_OS_WIN + GString sCpuid;//存储cpuid的字符串 + INT32 nCpuid[4];//存储寄存器数据 + + //获取cpuid + __cpuid(nCpuid,0x01); + + //把结果格式化进入字符串 + char pbufer[17]; + sprintf_s(pbufer,17,"%.8X%.8X",nCpuid[3],nCpuid[0]);//格式化字符串 + sCpuid = GString(GLatin1String(pbufer));//将char转换成GString + return sCpuid; +#else + /*在ubuntu 12.04.1上测试可以获取到cpuid号,但因为在虚拟机上运行的Linux,硬件是虚拟的,不能保证绝对正确*/ +//#define cpuid(in,a,b,c,d) asm("cpuid":"=a"(a),"=b"(b),"=c"(c),"=d"(d):"a"(in)); + //定义AT&T风格的汇编代码,用来完成cpuid命令。 + int eax,ebx,ecx,edx;//存储寄存器的内容 + GString sCpuid;//存储cpuid的字符串 + __cpuid(1,eax,ebx,ecx,edx); + char pbufer[17]; + sprintf(pbufer, "%.8X%.8X",edx,eax);//格式化字符串 + sCpuid = GString(GLatin1String(pbufer));//将char转换成GString + return sCpuid; +#endif +} + +/**************************************************************************************************** + 作者: ruanlz 2015-07-14 + 函数名称:getDiskSerialNoString + 返回: GString + 功能: 获取系统的第一块硬盘的序列号,并不一定是c盘或者系统盘所在的硬盘 + 注意: 获取硬盘id时,程序必须有管理员权限才能获取,否则返回空 + 操作系统:支持windows95及以上版本的windows操作系统,暂不支持其他操作系统。 +****************************************************************************************************/ +#ifdef Q_OS_WIN +//把WORD数组调整字节序为little-endian,并滤除字符串结尾的空格。 +void ToLittleEndian(PUSHORT pWords, int nFirstIndex, int nLastIndex, LPTSTR pBuf) +{ + int index; + LPTSTR pDest = pBuf; + for(index = nFirstIndex; index <= nLastIndex; ++index) + { + pDest[0] = pWords[index] >> 8; + pDest[1] = pWords[index] & 0xFF; + pDest += 2; + } + *pDest = 0; + + //trim space at the endof string; 0x20: _T(' ') + --pDest; + while(*pDest == 0x20) + { + *pDest = 0; + --pDest; + } +} + +//滤除字符串起始位置的空格 +void TrimStart(LPTSTR pBuf) +{ + if(*pBuf != 0x20) + { + return; + } + + LPTSTR pDest = pBuf; + LPTSTR pSrc = pBuf + 1; + while(*pSrc == 0x20) + ++pSrc; + + while(*pSrc) + { + *pDest = *pSrc; + ++pDest; + ++pSrc; + } + *pDest = 0; +} + +GString getDiskSerialNoString() +{ + TCHAR szSerialNo[24]; + BYTE IdentifyResult[sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1]; + DWORD dwBytesReturned; + GETVERSIONINPARAMS get_version; + SENDCMDINPARAMS send_cmd = { 0 }; + + HANDLE hFile = CreateFile(L"\\\\.\\PHYSICALDRIVE0", GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + if(hFile == INVALID_HANDLE_VALUE) + { + return GString(""); + } + + //get version + DeviceIoControl(hFile, SMART_GET_VERSION, NULL, 0, + &get_version, sizeof(get_version), &dwBytesReturned, NULL); + //identify device + + //send_cmd.irDriveRegs.bCommandReg = (get_version.bIDEDeviceMap & 0x10)? ATAPI_ID_CMD : ID_CMD; + //说明: 当以ATAPI_ID_CMD的形式去获取硬盘信息时会获取不到,ID_CMD则可以获取,暂时测得电脑上还没有测出错误, + // 暂时对这个问题没有更好的解决方法,所以暂时先改为都已ID_CMD的命令格式去获取硬盘信息。 + send_cmd.irDriveRegs.bCommandReg = (get_version.bIDEDeviceMap & 0x10)? ID_CMD : ID_CMD; + DeviceIoControl(hFile, SMART_RCV_DRIVE_DATA, &send_cmd, sizeof(SENDCMDINPARAMS) - 1, + IdentifyResult, sizeof(IdentifyResult), &dwBytesReturned, NULL); + CloseHandle(hFile); + + //获取结果 + PUSHORT pWords = (USHORT*)(((SENDCMDOUTPARAMS*)IdentifyResult)->bBuffer); + + ToLittleEndian(pWords, 10, 19, szSerialNo); + TrimStart(szSerialNo); + QString sDiskSerialNo; + sDiskSerialNo = QString::fromWCharArray(szSerialNo); + return sDiskSerialNo; +} +#else +//非windows操作系统统一返回空字符串 +GString getDiskSerialNoString() +{ + return GString(""); +} +#endif + +/**************************************************************************************************** + 作者: ruanlz 2015-07-14 + 函数名称:getComputerGUID + 返回: GString + 功能: 获取电脑唯一标示,返回结果是32位的字符串 + 注意: 因为依赖于getDiskSerialNoString函数,所以在没有管理员权限下返回的磁盘序列号可能 + 是空的,在有管理员权限和没有管理员权限的情况下,此函数的返回值可能不一样。 +****************************************************************************************************/ +#ifdef Q_OS_WIN +GString getComputerGUID() +{ + GString sCpuid,sDiskSerialNo; + GString sComputerGUID; + + //获取cpuid和磁盘序列号 + sCpuid = getCPUIdString(); + sDiskSerialNo = getDiskSerialNoString(); + sComputerGUID = sCpuid + sDiskSerialNo; + return sComputerGUID; +} +#endif + + +#ifdef Q_OS_WIN +unsigned getNetworkCardCount() +{ + LANA_ENUM leAdapt; + NCB ncb; + memset(&ncb, 0, sizeof(ncb)); + + ncb.ncb_command = NCBENUM; + ncb.ncb_buffer = (unsigned char*)&leAdapt; + ncb.ncb_length = sizeof(leAdapt); + + if (Netbios(&ncb) == 0) + { + return leAdapt.length; + } + + return 0; +} + +#endif + +GString getMacString() +{ +#ifdef Q_OS_WIN + + //int nCount = getNetworkCardCount(); + NCB ncb; + ADAPTER_STATUS adapt; + + GLDVector vecRes; + memset(&ncb, 0, sizeof(ncb)); + + UCHAR uRetCode; + LANA_ENUM lenum; + ncb.ncb_command = NCBENUM; + ncb.ncb_buffer = (UCHAR * ) & lenum; + ncb.ncb_length = sizeof (lenum); + uRetCode = Netbios( & ncb ); + + for (int i = 0; i < lenum.length; ++i) + { + memset( & ncb, 0 , sizeof (ncb) ); + ncb.ncb_command = NCBRESET; + ncb.ncb_lana_num = lenum.lana[i]; + uRetCode = Netbios(&ncb); + if (NRC_GOODRET != uRetCode) + { + continue; + } + memset(&ncb, 0 , sizeof(ncb)); + ncb.ncb_command = NCBASTAT; + ncb.ncb_lana_num = lenum.lana[i]; + strcpy_s((char*)ncb.ncb_callname, sizeof(ncb.ncb_callname), "*"); + ncb.ncb_buffer = (unsigned char*)&adapt; + ncb.ncb_length = sizeof(adapt); + + char szBuff[128] = { '\0' }; + + Netbios(&ncb); +#ifdef _MSC_VER + sprintf_s( +#else + sprintf( +#endif + szBuff, "%02X-%02X-%02X-%02X-%02X-%02X\r\n", + adapt.adapter_address[0], + adapt.adapter_address[1], + adapt.adapter_address[2], + adapt.adapter_address[3], + adapt.adapter_address[4], + adapt.adapter_address[5]); + + vecRes.push_back(GString(szBuff)); + } + + if (vecRes.size() > 0) + { + return vecRes[0]; + } +#else + struct ifreq ifreq; + int sock; + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) > 0) + { + strcpy(ifreq.ifr_name, ""); + if (ioctl(sock, SIOCGIFADDR, &ifreq) > 0) + { + char szBuff[128] = { '\0' }; + sprintf(szBuff, "%02X-%02X-%02X-%02X-%02X-%02X\r\n", + (unsigned char)ifreq.ifr_ifru.ifru_addr.sa_data[0], + (unsigned char)ifreq.ifr_ifru.ifru_addr.sa_data[1], + (unsigned char)ifreq.ifr_ifru.ifru_addr.sa_data[2], + (unsigned char)ifreq.ifr_ifru.ifru_addr.sa_data[3], + (unsigned char)ifreq.ifr_ifru.ifru_addr.sa_data[4], + (unsigned char)ifreq.ifr_ifru.ifru_addr.sa_data[5]); + + return GString(szBuff); + } + } +#endif + + return GString(""); +} + +/**************************************************************************************************** + 作者: yanyq-a 2013-07-30 + 参数: const GString&, const GString& + 返回: GString + 功能: 读取注册表相应键值(对应原GrandFileUtils::GetShellFolderPath) +****************************************************************************************************/ +GString valueFromRegistry(const GString ®Path, const GString ®Key) +{ + GSettings oSetting(regPath, GSettings::NativeFormat); + GString result = oSetting.value(regKey, "").toString(); + if ((result.length() > 0) && !((result.right(1) == "\\") || result.right(1) == "/")) + { + result += "/"; + } + return GDir::fromNativeSeparators(result); +} + +GString environmentVariable(const GString &envVAR) +{ + QByteArray vardir = qgetenv(envVAR.toStdString().data()); + + if (vardir.size() > 0 ) + { + return vardir; + } + + return envVAR; +} + +bool setEnvironmentVariable(const GString &name, const GString &value) +{ + // todo + return false; + G_UNUSED(name) + G_UNUSED(value) +} + +/**************************************************************************************************** + 作者: yanyq-a 2013-07-30 + 参数: 无 + 返回: GString + 功能: 获取当前用户的文档目录 +****************************************************************************************************/ +GString getUserDocumentsPath() +{ + return QDir::fromNativeSeparators(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation).append('/')); +} + +/**************************************************************************************************** + 作者: yanyq-a 2013-07-30 + 参数: 无 + 返回: GString + 功能: 获取当前用户的应用程序数据目录 +****************************************************************************************************/ +GString getUserAppDataPath() +{ +#ifdef WIN32 + return getSpecialFolderPath(CSIDL_APPDATA); +#else + return GString(); +#endif +} + +/**************************************************************************************************** + 作者: yanyq-a 2013-08-09 + 参数: 无 + 返回: gint64 + 功能: 可用物理内存 +****************************************************************************************************/ +gint64 getAvailPhysMem() +{ +#ifdef Q_OS_WIN + MEMORYSTATUSEX oMemory; + oMemory.dwLength = sizeof(MEMORYSTATUSEX); + GlobalMemoryStatusEx(&oMemory); + return oMemory.ullAvailPhys; +#else + FILE *pfd; + char *pend; + gint64 nFree = 0; + char szBuff[256] = { '\0' }; + + pfd = fopen("/proc/meminfo", "r"); + + while (true) + { + memset(szBuff, 0, 256); + pend = fgets(szBuff, 256, pfd); + + if (NULL == pend) break; + if (strncmp(szBuff, "MemFree", 7) == 0) + { + nFree = atoll(szBuff); + break; + } + } + + return nFree; +#endif +} + +/************************************************************************** + 作者: yanyq-a 2013-08-09 + 参数: 无 + 返回: unsigned long + 功能: 物理内存使用率 +**************************************************************************/ +unsigned long memoryUsage() +{ +#ifdef Q_OS_WIN + MEMORYSTATUSEX oMemory; + oMemory.dwLength = sizeof(MEMORYSTATUSEX); + GlobalMemoryStatusEx(&oMemory); + return oMemory.dwMemoryLoad; +#else + FILE *pfd; + char *pend; + gint64 nTotal = 0; + gint64 nFree = 0; + char szBuff[256] = { '\0' }; + + pfd = fopen("/proc/meminfo", "r"); + + while (true) + { + memset(szBuff, 0, 256); + pend = fgets(szBuff, 256, pfd); + + if (NULL == pend) break; + if (strncmp(szBuff, "MemTotal", 8) == 0) + { + nTotal = atoll(szBuff); + } + if (strncmp(szBuff, "MemFree", 7) == 0) + { + nFree = atoll(szBuff); + } + } + + if (nTotal <= 0) + { + return 0; + } + else + { + return ((nTotal - nFree) * 100) / nTotal; + } +#endif +} + +GString getSpecialFolderPath(int CSIDL) +{ +#ifdef WIN32 + wchar_t path[MAX_PATH]; + if (SHGetSpecialFolderPath(0, path, CSIDL, FALSE)) + return QDir::fromNativeSeparators(QString::fromWCharArray(path).append('/')); + else + return GString(); +#else + return GString(); +#endif +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDTableViewExport.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDTableViewExport.cpp new file mode 100644 index 00000000..920f0d3a --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDTableViewExport.cpp @@ -0,0 +1,1735 @@ +#include +#include +#include "GLDDir.h" +#include "GLDPaperWidget.h" +#include "GLDTableViewExport.h" +#include "GLDGlobal.h" +#include "GLDFile.h" +#include "GLDXLS.h" +#include "GLDStrUtils.h" +#include "GLDUITypes.h" +#include "GLDAbstractItemModel.h" +#include "GLDMultiHeaderView.h" +#include "GLDUIUtils.h" +#include "GLDException.h" +#include "GLDFooterTableView.h" +#include "GLDDrawSymbol.h" +#include "GLDPaperTableView.h" + +// 微软官方说:一般取的时标准字体宽度值 7.55,但是对比Excel得到的比例大概是7.2 +const int c_nPixToExcelUnit = 7.2; + +class GlodonTableViewToExcelPrivate +{ +public: + GlodonTableViewToExcelPrivate(GlodonTableViewToExcel *parent) + : q_ptr(parent), m_sheet(NULL), m_book(NULL), m_format(NULL), m_titleFormat(NULL), + m_tableView(NULL), m_horzRowCount(0), + m_vertColCount(0), m_exportIcon(true), + m_nRowCount(0), m_nStartRow(0), + m_bIsToSingleSheet(false), m_bIsOverWrite(true), + m_showPrompt(true), m_groupCollapsed(false), + m_borderStyle(BORDERSTYLE_THIN) + { + } + +private: + GlodonTableViewToExcel * const q_ptr; + Q_DECLARE_PUBLIC(GlodonTableViewToExcel); + + libxl::Sheet *m_sheet; + libxl::Book *m_book; + libxl::Format *m_format; + libxl::Format *m_titleFormat; + + GlodonTableView *m_tableView; + + QHash m_diffFormat; + QHash m_diffTitleFormat; + + int m_horzRowCount; + int m_vertColCount; + bool m_exportIcon; + int m_nStartRow; + bool m_bIsOverWrite; + bool m_bIsToSingleSheet; + int m_nRowCount; + bool m_showPrompt; + bool m_groupCollapsed; + + BorderStyle m_borderStyle; +}; + +GlodonTableViewToExcel::GlodonTableViewToExcel() : + d_ptr(new GlodonTableViewToExcelPrivate(this)) +{ +} + +GlodonTableViewToExcel::~GlodonTableViewToExcel() +{ + Q_D(GlodonTableViewToExcel); + if (NULL != d->m_book) + { + d->m_book->release(); + } + + //释放表单元格申请资源 + QHash::const_iterator allCellFormat = d->m_diffFormat.constBegin(); + + while (allCellFormat != d->m_diffFormat.constEnd()) + { + TableCellLocation *perCellLocation = allCellFormat.key(); + TableCellFormat *perCellFormat = allCellFormat.value(); + freeAndNil(perCellLocation); + freeAndNil(perCellFormat); + allCellFormat++; + } + + //释放表标题栏单元格申请资源 + QHash::const_iterator allTitleCellFormat = d->m_diffTitleFormat.constBegin(); + + while (allTitleCellFormat != d->m_diffTitleFormat.constEnd()) + { + TableCellFormat *perTitleCellFormat = allTitleCellFormat.value(); + freeAndNil(perTitleCellFormat); + allTitleCellFormat++; + } + + freePtr(d); +} + +ExportState GlodonTableViewToExcel::execute(GlodonTableView *tableView, + const GString &fileName, + const GString &sheetName, + bool isCollapsed, + bool isToSingleSheet, + bool isOverWrite, + bool showPrompt) +{ + GlodonTableViewToExcel *exporter = new GlodonTableViewToExcel; + + ExportState exportState; + try + { + exporter->setGroupCollapsed(isCollapsed); + exporter->setTableView(tableView); + exporter->setShowPrompt(showPrompt); + exporter->setIsToSingleSheet(isToSingleSheet); + exporter->setIsOverWrite(isOverWrite); + exporter->load(); + exporter->doExport(sheetName); + exportState = exporter->save(fileName); + } + catch (...) + { + freeAndNil(exporter); + throw; + } + + freeAndNil(exporter); + return exportState; +} + +ExportState GlodonTableViewToExcel::save(const GString &fileName) +{ + bool bResult = false; + GString strError = "ok"; + + Q_D(GlodonTableViewToExcel); + try + { + GString fileNameDir = fileName; + + if (fileNameDir.contains("/")) + { + fileNameDir.replace("/", "\\"); + } + + GString fileDirPath = fileNameDir.left(fileNameDir.lastIndexOf("\\")); + QDir fileDir(fileDirPath); + + if (!fileDir.exists()) + { + fileDir.mkpath(fileDirPath); + } + + bResult = d->m_book->save((const wchar_t *)fileName.constData()); + strError = GString::fromLocal8Bit(d->m_book->errorMessage()); + } + catch (...) + { + //把异常吃掉 + } + + if (d->m_showPrompt) + { + if (bResult) + { + showPrompt(tr("success export to excel")); + } + else if (!bResult && strError == GString::fromLocal8Bit("can't open file for writing")) + { + gldError(tr("can't open file for writing")); + } + else + { + gldError(tr("error on saving")); + } + } + else + { + if (bResult) + { + return EXPORT_SUCCESS; + } + else if (!bResult && strError == GString::fromLocal8Bit("can't open file for writing")) + { + return EXPORT_NOTWRITING; + } + } + + return EXPORT_ERRSAVE; +} + +void GlodonTableViewToExcel::load(const GString &fileName) +{ + Q_D(GlodonTableViewToExcel); + d->m_book = createXLSBook(true); + + if (GFile::exists(fileName)) + { + if (d->m_bIsOverWrite) + { + GFile::remove(fileName); + } + else + { + d->m_book->load((const wchar_t *)fileName.constData()); + } + } +} + +void GlodonTableViewToExcel::setTableView(GlodonTableView *tableView) +{ + Q_D(GlodonTableViewToExcel); + d->m_tableView = tableView; +} + +void GlodonTableViewToExcel::setExportIcon(bool value) +{ + Q_D(GlodonTableViewToExcel); + d->m_exportIcon = value; +} + +void GlodonTableViewToExcel::setIsOverWrite(bool isOverWrite) +{ + Q_D(GlodonTableViewToExcel); + d->m_bIsOverWrite = isOverWrite; +} + +void GlodonTableViewToExcel::setIsToSingleSheet(bool isToSingleSheet) +{ + Q_D(GlodonTableViewToExcel); + d->m_bIsToSingleSheet = isToSingleSheet; +} + +void GlodonTableViewToExcel::setShowPrompt(bool value) +{ + Q_D(GlodonTableViewToExcel); + d->m_showPrompt = value; +} + +void GlodonTableViewToExcel::setGroupCollapsed(bool collapse) +{ + Q_D(GlodonTableViewToExcel); + d->m_groupCollapsed = collapse; +} + +void GlodonTableViewToExcel::doExport(const GString &sheetName) +{ + Q_D(GlodonTableViewToExcel); + initExcel(sheetName); + initSheet(); + + transTitleAllMergeCells(); + transMergeCells(); + transTitleData(); + transCellDatas(); + transFootData(); + + groupRows(); + + if (d->m_bIsToSingleSheet) + { + // 最后一行被折叠,应该是合计行之类的高度计算有问题,先加1处理 + d->m_nStartRow = d->m_nStartRow + d->m_nRowCount + 1; + } +} + +void GlodonTableViewToExcel::initExcel(const GString &sheetName) +{ + Q_D(GlodonTableViewToExcel); + G_ASSERT(d->m_book != NULL); + + if ("" == sheetName) + { + d->m_sheet = d->m_book->addSheet(L"sheet1"); + } + else + { + // 不管是不是覆盖,都只需要获取每个页签一次,即第一次写入时 + if (0 == d->m_nStartRow) + { + const wchar_t *pWchar = (const wchar_t *)sheetName.constData(); + d->m_sheet = d->m_book->addSheet(pWchar); + + if (NULL == d->m_sheet) + { + gldError(tr("current tag page existing"));//当前标签页已经存在")); // + } + } + } +} + +void GlodonTableViewToExcel::initSheet() +{ + Q_D(GlodonTableViewToExcel); + // 设置打印的时候有格线 + d->m_sheet->setPrintGridlines(true); + + if (!d->m_bIsToSingleSheet) + { + d->m_sheet->clear(); + } + + // 列表头如果可见,获取列表头行数 + GlodonMultiHeaderView *pHorzHeader = dynamic_cast(d->m_tableView->horizontalHeader()); + + if (NULL != pHorzHeader && !pHorzHeader->isHidden()) + { + d->m_horzRowCount = pHorzHeader->rowCount(); + } + else if (d->m_tableView->horizontalHeader() && !d->m_tableView->horizontalHeader()->isHidden()) + { + d->m_horzRowCount = 1; + } + else + { + d->m_horzRowCount = 0; + } + + int nRowCount = d->m_horzRowCount + d->m_tableView->model()->rowCount(); + d->m_nRowCount = nRowCount; + d->m_sheet->insertRow(d->m_nStartRow, nRowCount); + + // 行表头如果可见,获取行表头行数 + GlodonMultiHeaderView *pVertHeader = dynamic_cast(d->m_tableView->verticalHeader()); + + if (NULL != pVertHeader && !pVertHeader->isHidden()) + { + d->m_vertColCount = pVertHeader->colCount(); + } + else if (d->m_tableView->verticalHeader() && !d->m_tableView->verticalHeader()->isHidden()) + { + d->m_vertColCount = 1; + } + else + { + d->m_vertColCount = 0; + } + + int nColCount = d->m_vertColCount + d->m_tableView->model()->columnCount(); + + // 设置表头的高 + if (NULL != pHorzHeader) + { + if (d->m_horzRowCount == 1) + { + double dHeight = pHorzHeader->height(); + + if (dHeight <= 0) //如果取出是0的话,给个默认行高 + { + dHeight = 30; + } + + dHeight *= 72.0 / 96; + d->m_sheet->setRow(d->m_nStartRow, dHeight); + } + else + { + double dHeight; + + for (int i = 0; i < pHorzHeader->headerList.count(); i++) + { + dHeight = pHorzHeader->headerList.at(i)->minimumHeight(); + + if (dHeight <= 0) + { + dHeight = 30; + } + + dHeight *= 72.0 / 96; + d->m_sheet->setRow(i + d->m_nStartRow, dHeight); + } + + dHeight = pHorzHeader->minimumHeight(); + + if (dHeight <= 0) + { + dHeight = 30; + } + + dHeight *= 72.0 / 96; + d->m_sheet->setRow(pHorzHeader->headerList.count() + d->m_nStartRow, + dHeight); + } + } + else + { + d->m_sheet->setRow(d->m_nStartRow, d->m_tableView->horizontalHeader()->height()); + } + + const int nViewPortRowCount = nRowCount - d->m_horzRowCount; + + GIntList oSuitHeightCols = d->m_tableView->suitRowHeights(); + for (int i = 0; i < nViewPortRowCount; i++) + { + if (d->m_tableView->isRowHidden(i)) + { + d->m_sheet->setRowHidden(i + d->m_horzRowCount + d->m_nStartRow, true); + continue; + } + + QModelIndex index = d->m_tableView->model()->index(i, 0); + const int nManualRowHeight = d->m_tableView->model()->data(index, gidrRowHeightRole).toInt(); + + int nCalcRowHeight = d->m_tableView->calcSuitHeight(oSuitHeightCols, i); + + if (0 == nCalcRowHeight) + { + nCalcRowHeight = d->m_tableView->rowHeight(i); + } + const int nMaxRowHeight = qMax(nManualRowHeight, nCalcRowHeight); + + // 96 是一般的分辨率;1/72 是 1皮克 = 1/72 英寸; + d->m_sheet->setRow(i + d->m_horzRowCount + d->m_nStartRow, nMaxRowHeight * 72.0 / 96); + } + + // 设置每列的宽 + if (d->m_vertColCount > 0) + { + const int nWidth = d->m_tableView->verticalHeader()->width() / c_nPixToExcelUnit; + d->m_sheet->setCol(0, 1, nWidth); + } + + GIntList oSuitColWidths = d->m_tableView->suitColWidths(); + const int nViewPortColumnCount = nColCount - d->m_vertColCount; + + // 合适列宽不处理 + for (int i = 0; i < nViewPortColumnCount; i++) + { + int nWidth = 0; + + if (oSuitColWidths.contains(i)) + { + nWidth = d->m_tableView->calcSuitWidth(i); + } + else + { + nWidth = d->m_tableView->columnWidth(i) / c_nPixToExcelUnit; + } + + d->m_sheet->setCol(i + d->m_vertColCount, i + d->m_vertColCount + 1, nWidth); + } + + //设置导出excel是否绘制格线 + initBorderFormat(); +} + +void GlodonTableViewToExcel::transTitleData() +{ + Q_D(GlodonTableViewToExcel); + QAbstractItemModel *oModel = d->m_tableView->model(); + + if (!d->m_tableView->horizontalHeader()->isHidden()) + { + int nMaxRowCount = 0; + + for (int i = 0; i < oModel->columnCount(); i++) + { + GString strTitle = oModel->headerData(i, Qt::Horizontal).toString(); + GStringList titles = strTitle.split("|"); + nMaxRowCount = qMax(nMaxRowCount, titles.count()); + + for (int j = 0; j < titles.count(); j++) + { + Format *oFormat = getTitleFormat(oModel, i, Qt::Horizontal); + const wchar_t *pWchar = (const wchar_t *)(titles.at(j).constData()); + d->m_sheet->writeStr(j + d->m_nStartRow, + i + d->m_vertColCount, pWchar, oFormat); + } + } + + //补齐合并格的右边线 + for (int i = 0; i < nMaxRowCount; i++) + { + Format *oFormat = getTitleFormat(oModel, oModel->columnCount() - 1, Qt::Horizontal); + d->m_sheet->setCellFormat(i, oModel->columnCount() + d->m_vertColCount - 1, oFormat); + } + } + + if (!d->m_tableView->verticalHeader()->isHidden()) + { + int nMaxColumnCount = 0; + + for (int i = 0; i < oModel->rowCount(); i++) + { + GString strTitle = oModel->headerData(i, Qt::Vertical).toString(); + GStringList titles = strTitle.split("|"); + nMaxColumnCount = qMax(nMaxColumnCount, titles.count()); + + for (int j = 0; j < titles.count(); j++) + { + Format *oFormat = getTitleFormat(oModel, i, Qt::Vertical); + const wchar_t *pWchar = (const wchar_t *)(titles.at(j).constData()); + d->m_sheet->writeStr(i + d->m_horzRowCount + d->m_nStartRow, + j, pWchar, oFormat); + } + } + + //补齐合并格的下边线 + for (int i = 0; i < nMaxColumnCount; i++) + { + Format *oFormat = getTitleFormat(oModel, oModel->rowCount() - 1, Qt::Vertical); + d->m_sheet->setCellFormat(oModel->rowCount() + d->m_horzRowCount - 1, i, oFormat); + } + } +} + +void GlodonTableViewToExcel::transCellDatas() +{ + Q_D(GlodonTableViewToExcel); + QAbstractItemModel *oModel = d->m_tableView->model(); + + for (int i = 0; i < oModel->rowCount(); i++) + { + for (int j = 0; j < oModel->columnCount(); j++) + { + Format *oFormat = getFormat(oModel, i, j); + QModelIndex oIndex = oModel->index(i, j); + GVariant variant = oModel->data(oIndex); + + int nRow = i + d->m_horzRowCount + d->m_nStartRow; + int nCol = j + d->m_vertColCount; + + // 判断是否是钢筋符号 + + GlodonDefaultItemDelegate *gldDelegate = dynamic_cast(d->m_tableView->itemDelegate(oIndex)); + + Q_ASSERT_X(gldDelegate, "transCellDatas", "Must use GlodonDefaultItemDelegate"); + + bool bReadOnly = false; + + GEditStyle edtStyle = gldDelegate->editStyle( + gldDelegate->dataIndex(oIndex), + bReadOnly); + + GObjectList *pSymbolList = createIndexOfDiameterSymbolList(variant.toString()); + + if (pSymbolList->count() > 0) + { + writeCellSymbol(i, j); + } + else if (esVectorGraph == edtStyle) + { + writeCellSymbol(i, j); + } + else + { + if ((GVariant::Image == variant.type()) || (GVariant::Icon == variant.type())) + { + writeCellIcon(nRow, nCol, variant, oFormat); + } + else + { + if (variant.isNull()) + { + writeCellValue("", oFormat, nRow, nCol); + } + else + { + writeCellValue(variant, oFormat, nRow, nCol); + } + } + } + + freeAndNil(pSymbolList); + } + } +} + +struct GMegerSpan +{ + int top; + int bottom; + int left; + int right; +}; + +void GlodonTableViewToExcel::transTitleAllMergeCells() +{ + Q_D(GlodonTableViewToExcel); + QString strTitle; + QAbstractItemModel *oModel = d->m_tableView->model(); + + //水平表头 + QList titles; + int nColCount = oModel->columnCount(); + int nMaxCount = 0; + + for (int i = 0; i < nColCount; i++) + { + strTitle = oModel->headerData(i, Qt::Horizontal).toString(); + titles.append(strTitle.split('|')); + nMaxCount = qMax(nMaxCount, strTitle.split('|').count()); + } + + //垂直表头 + int nRowCount = oModel->rowCount(); + QList verTitles; + int nVerMaxCount = 0; + + for (int i = 0; i < nRowCount; i++) + { + strTitle = oModel->headerData(i, Qt::Vertical).toString(); + verTitles.append(strTitle.split('|')); + nVerMaxCount = qMax(nVerMaxCount, strTitle.split('|').count()); + } + + //参考parseSpan代码 + GHeaderSpanCollection *spanCollection = new GHeaderSpanCollection(); + GHeaderSpanCollection *verSpanCollection = new GHeaderSpanCollection(); + + try + { + //水平表头合并 + for (int i = 0; i < titles.count(); i++) + { + int nCurrentCount = titles.at(i).count(); + + for (int j = 0; j < nCurrentCount - 1; j++) + { + GLDHeaderSpan *newspan + = new GLDHeaderSpan(j, i, 1, 1, titles.at(i).at(j), i); + spanCollection->addSpan(newspan); + } + + GLDHeaderSpan *newspan = new GLDHeaderSpan(nCurrentCount - 1, i, + nMaxCount - nCurrentCount + 1, 1, + titles.at(i).at(nCurrentCount - 1), i); + spanCollection->addSpan(newspan); + } + + for (int i = 0; i < spanCollection->spans.count(); i++) + { + GLDHeaderSpan *span = (GLDHeaderSpan *)(spanCollection->spans.at(i)); + + if ((span->top() != span->bottom()) || (span->left() != span->right())) + { + d->m_sheet->setMerge(span->top() , + span->bottom(), + span->left() + d->m_vertColCount, + span->right() + d->m_vertColCount); + } + } + + //垂直表头合并 + for (int i = 0; i < verTitles.count(); i++) + { + int nCurrentCount = verTitles.at(i).count(); + + for (int j = 0; j < nCurrentCount - 1; j++) + { + GLDHeaderSpan *newSpan = new GLDHeaderSpan(i, j, 1, 1, verTitles.at(i).at(j), i); + verSpanCollection->addSpan(newSpan); + } + + GLDHeaderSpan *newSpan = new GLDHeaderSpan(i, nCurrentCount - 1, + 1, nVerMaxCount - nCurrentCount + 1, + verTitles.at(i).at(nCurrentCount - 1), i); + verSpanCollection->addSpan(newSpan); + } + + for (int i = 0; i < verSpanCollection->spans.count(); i++) + { + GLDHeaderSpan *span = (GLDHeaderSpan *)(verSpanCollection->spans.at(i)); + + if ((span->top() != span->bottom()) || (span->left() != span->right())) + { + d->m_sheet->setMerge(span->top() + d->m_horzRowCount, + span->bottom() + d->m_horzRowCount, + span->left(), + span->right()); + } + } + } + catch (...) + { + freeAndNil(spanCollection); + freeAndNil(verSpanCollection); + throw; + } + + freeAndNil(spanCollection); + freeAndNil(verSpanCollection); + + //合并左上角 + if ((d->m_vertColCount > 1) && (d->m_horzRowCount > 1)) + { + d->m_sheet->setMerge(d->m_nStartRow, d->m_horzRowCount - 1, d->m_nStartRow, d->m_vertColCount - 1); + } +} + +void GlodonTableViewToExcel::transMergeCells() +{ + Q_D(GlodonTableViewToExcel); + QMultiHash oDirtyRect; + QAbstractItemModel *oModel = d->m_tableView->model(); + GMegerSpan span; + int nRowCount = oModel->rowCount(); + int nColCount = oModel->columnCount(); + + for (int k = 0; k < nRowCount; k++) + { + int nCounter = 0; + + while (nCounter < nColCount) + { + QMultiHash::const_iterator it = oDirtyRect.find(k, nCounter); + + if (it != oDirtyRect.end()) + { + nCounter++; + continue; + } + + span.bottom = k; + span.top = k; + span.left = nCounter; + span.right = nCounter; + bool bSetMerge = false; + QModelIndex oIndex = oModel->index(k, nCounter); + GVariant value = oModel->data(oIndex, gidrMergeIDRole); + int nMergeID = value.toInt(); + + if (nMergeID > 0) + { + int nRow = k + 1; + + while (nRow < nRowCount) + { + oIndex = oModel->index(nRow, nCounter); + int nID = oModel->data(oIndex, gidrMergeIDRole).toInt(); + + if (nID == nMergeID) + { + span.bottom = nRow; + oDirtyRect.insert(nRow, nCounter); + bSetMerge = true; + } + else + { + break; + } + + nRow++; + } + + int nCol = nCounter + 1; + + while (nCol < nColCount) + { + oIndex = oModel->index(k, nCol); + int nID = oModel->data(oIndex, gidrMergeIDRole).toInt(); + + if (nID == nMergeID) + { + span.right = nCol; + oDirtyRect.insert(k, nCol); + bSetMerge = true; + } + else + { + break; + } + + nCol++; + } + + for (int i = k + 1; i < nRow; i++) + { + for (int j = nCounter + 1; j < nCol; j++) + { + oDirtyRect.insert(i, j); + } + } + } + + if (bSetMerge) + { + d->m_sheet->setMerge(span.top + d->m_horzRowCount + d->m_nStartRow, + span.bottom + d->m_horzRowCount + d->m_nStartRow, + span.left + d->m_vertColCount, + span.right + d->m_vertColCount); + } + + nCounter++; + } + } +} + +void GlodonTableViewToExcel::transFootData() +{ + Q_D(GlodonTableViewToExcel); + GlodonFooterTableView *pFooterTableView = dynamic_cast(d->m_tableView); + + if (NULL == pFooterTableView) + { + return; + } + + GFooterView *pFootView = pFooterTableView->footer(); + QAbstractItemModel *pModel = pFootView->model(); + + if (NULL == pModel) + { + return; + } + + int nRow = d->m_horzRowCount + pFooterTableView->model()->rowCount(); + + for (int i = 0; i < pModel->rowCount(); i++) + { + int nHeight = 30; + d->m_sheet->setRow(i + nRow + d->m_nStartRow, nHeight); + } + + for (int i = 0; i < pModel->rowCount(); i++) + { + GString strTitle = pModel->headerData(i, Qt::Horizontal).toString(); + GStringList titles = strTitle.split("|"); + + for (int j = 0; j < titles.count(); j++) + { + Format *oFormat = getTitleFormat(pModel, i, Qt::Vertical); + const wchar_t *pWchar = (const wchar_t *)(titles.at(j).constData()); + d->m_sheet->writeStr(nRow + i + d->m_nStartRow, j, pWchar, oFormat); + } + } + + for (int i = 0; i < pModel->rowCount(); i++) + { + for (int j = 0; j < pModel->columnCount(); j++) + { + Format *oFormat = getFormat(pModel, i, j); + QModelIndex oIndex = pModel->index(i, j); + GVariant value = pModel->data(oIndex, Qt::DisplayRole); + int nRow = d->m_horzRowCount + pFooterTableView->model()->rowCount() + i + d->m_nStartRow; + int nCol = d->m_vertColCount + j; + writeCellValue(value, oFormat, nRow, nCol); + } + } + +} + +/** + * @brief GlodonTableViewToExcel::groupRows + * 有两点需要注意:1,分组必须从最小到最大分组,即 调用按照m_sheet->groupRows(2, 17); m_sheet->groupRows(3, 7);这个顺序, + * 如果按照m_sheet->groupRows(3, 7);m_sheet->groupRows(2, 17);就会出现显示问题 + * 2,从excel的操作来看,分组开始是第一个孩子的rownumber,而不是本身 + * 对于以上两点的处理,第一个,就是用map存放,然后,按照从0到rowcount来获取。 + * 第二个,就是在处理的时候每次都加1。 + */ +void GlodonTableViewToExcel::groupRows() +{ + Q_D(GlodonTableViewToExcel); + if (d->m_tableView->isTree()) + { + int rowcount = d->m_tableView->model()->rowCount(); + GMap groups; + + try + { + for (int i = 0; i < rowcount; ++i) + { + i += recursiveGroupRowsParent(i, &groups); + } + + // 设置组 + for (GMap::Iterator it = groups.begin(); + it != groups.end(); ++it) + { + GlodonExcelGroupStruct parent = getLastParentGroup(it.value(), &groups); + + if (parent.start != -1 && !parent.visible) + { + it.value().visible = false; + } + + d->m_sheet->groupRows(it.value().start + d->m_horzRowCount, it.value().end + d->m_horzRowCount, !it.value().visible); + } + +// for (int i = 0; i < rowcount; ++i) +// { +// // 判断i的子是否是group +// if (groups.find(i+1) != groups.end()) +// { +// bool isRowExpanded = d->m_tableView->isRowExpanded(i); +// d->m_sheet->groupRows(i + 1 + d->m_horzRowCount, groups.value(i + 1) + d->m_horzRowCount, !isRowExpanded); +// } +// } + } + catch (...) + { + throw; + } + + d->m_sheet->setGroupSummaryBelow(false); + d->m_sheet->setGroupSummaryRight(true); + } +} + +//int GlodonTableViewToExcel::recursiveGroupRows(int currentIndex, int childCount, GMap *groups) +//{ +// if (0 == childCount) +// { +// return 1; +// } +// int startindex = currentIndex; + +// for (int i = 0; i < childCount; i++) +// { +// QModelIndex modeindex = d->m_tableView->model()->index(currentIndex, 0); +// QModelIndex dataIndex = d->m_tableView->dataIndex(modeindex); +// int childcont = dataIndex.model()->rowCount(dataIndex); +// currentIndex += recursiveGroupRows(currentIndex + 1, childcont, groups); +// } + +// if (currentIndex > startindex) +// { +// groups->insert(startindex, currentIndex); +// } +// // + 1:包含本身 +// return currentIndex - startindex + 1; +//} + +int GlodonTableViewToExcel::recursiveGroupRowsParent(int parentIndex, GMap *groups) +{ + Q_D(GlodonTableViewToExcel); + QModelIndex modeindex = d->m_tableView->model()->index(parentIndex, 0); + QModelIndex dataIndex = d->m_tableView->dataIndex(modeindex); + int childCount = dataIndex.model()->rowCount(dataIndex); + + int endIndex = parentIndex; + + for (int i = 0; i < childCount; ++i) + { + // 探测下一个节点 + ++endIndex; + endIndex += recursiveGroupRowsParent(endIndex, groups); + } + + if (childCount > 0) + { + GlodonExcelGroupStruct group; + group.start = parentIndex + 1; + group.end = endIndex; + group.visible = d->m_tableView->isRowExpanded(parentIndex); + groups->insert(group.start, group); + return endIndex - parentIndex; + } + else + { + return 0; + } +} + +GlodonTableViewToExcel::GlodonExcelGroupStruct +GlodonTableViewToExcel::getLastParentGroup( + const GlodonTableViewToExcel::GlodonExcelGroupStruct &group, + GMap *groups) +{ + GlodonExcelGroupStruct result; + + for (GMap::Iterator it = groups->begin(); + it != groups->end(); ++it) + { + if (it.key() >= group.start) + { + break; + } + + if (it.value().start <= group.start && it.value().end >= group.end) + { + if (result.start <= it.value().start && result.end >= it.value().end) + { + result = it.value(); + } + } + } + + return result; +} + +void GlodonTableViewToExcel::writeCellValue(const GVariant &value, Format *format, int row, int col) +{ + Q_D(GlodonTableViewToExcel); + if (GVariant::String == value.type() || GVariant::DateTime == value.type() + || GVariant::Date == value.type()) + { + const wchar_t *pWchar; + GString strDateTime; + + if (GVariant::String == value.type()) + { + pWchar = (const wchar_t *)value.toString().constData(); + } + else if (GVariant::DateTime == value.type()) + { + strDateTime = value.value().toString("yyyy-MM-dd"); + pWchar = (const wchar_t *)(strDateTime.constData()); + } + else if (GVariant::Date == value.type()) + { + strDateTime = value.value().toString("yyyy-MM-dd"); + pWchar = (const wchar_t *)(strDateTime.constData()); + } + + if (!value.isNull() && (pWchar[0] == L'=')) + { + pWchar++; + d->m_sheet->writeFormula(row, col, pWchar, format); + } + else + { + d->m_sheet->writeStr(row, col, pWchar, format); + } + } + else if (GVariant::Bool == value.type()) + { + d->m_sheet->writeBool(row, col, value.toBool(), format); + } + else if (variantTypeIsNumeric(value.type())) + { + d->m_sheet->writeNum(row, col, value.toDouble(), format); + } + else if (GVariant::Color == value.type()) + { + QColor color = qvariant_cast(value); + Color xlsColorFont = d->m_book->colorPack(color.red(), color.green(), color.blue()); + + if (COLOR_WHITE != xlsColorFont) + { + format->setFillPattern(libxl::FILLPATTERN_SOLID); + format->setPatternForegroundColor(xlsColorFont); + } + } + + format->setBorderTop(d->m_borderStyle); + format->setBorderBottom(d->m_borderStyle); + format->setBorderLeft(d->m_borderStyle); + format->setBorderRight(d->m_borderStyle); + d->m_sheet->setCellFormat(row, col, format); +} +/** + * @brief GlodonTableViewToExcel::writeIcon + * 现在只是支撑icon和string在一个格子里面,别的现在还不支持 + * @param model + * @param oIndex + * @param format + * @param row + * @param col + */ +void GlodonTableViewToExcel::writeIcon(const QAbstractItemModel *model, QModelIndex oIndex, Format *format, int row, int col) +{ + Q_D(GlodonTableViewToExcel); + GVariant valueIcon = model->data(oIndex); + + if ((GVariant::Icon != valueIcon.type()) && (GVariant::Image != valueIcon.type())) + { + return; + } + + GString fileName; + QSize c_size; + int picId; + + if (GVariant::Image == valueIcon.type()) + { + QImage oImage = qvariant_cast(valueIcon); + fileName = oImage.text("Image"); + picId = d->m_book->addPicture((const wchar_t *)(fileName.constData())); + c_size = oImage.size(); + } + else if (GVariant::Icon == valueIcon.type()) + { + GIcon iconConetct = qvariant_cast(valueIcon); + fileName = iconConetct.themeName(); + QStyleOptionViewItem item4 = ((GlodonAbstractItemView *)d->m_tableView)->StyleOptionViewItem(); + c_size = iconConetct.actualSize(item4.decorationSize); + + picId = d->m_book->addPicture((const wchar_t *)fileName.constData()); + } + + d->m_sheet->setPicture2(row, col, picId, c_size.width(), c_size.height()); + + GString text = model->data(oIndex, Qt::DisplayRole).toString(); + const wchar_t *wchar = (const wchar_t *)(text.constData()); + + if (!text.isNull() && (wchar[0] == L'=')) + { + wchar++; + format->setIndent(4); + setFomatIndentSize(format, c_size.width()); + d->m_sheet->writeFormula(row, col, wchar, format); + } + else + { + setFomatIndentSize(format, c_size.width()); + d->m_sheet->writeStr(row, col, wchar, format); + } +} + +void GlodonTableViewToExcel::writeCellIcon(int row, int col, const GVariant value, const Format *format) +{ + Q_D(GlodonTableViewToExcel); + if ((GVariant::Icon != value.type()) && (GVariant::Image != value.type())) + { + return; + } + + GString fileName; + QSize c_size; + int picId; + + if (GVariant::Image == value.type()) + { + QImage oImage = qvariant_cast(value); + QStringList imageKeys = oImage.textKeys(); + + for (int i = 0; i < imageKeys.count(); i++) + { + QString key = imageKeys.at(i); + } + + fileName = oImage.text("Image"); + picId = d->m_book->addPicture((const wchar_t *)(fileName.constData())); + c_size = oImage.size(); + } + else if (GVariant::Icon == value.type()) + { + GIcon iconConetct = qvariant_cast(value); + fileName = iconConetct.themeName(); + QStyleOptionViewItem item4 = ((GlodonAbstractItemView *)d->m_tableView)->StyleOptionViewItem(); + c_size = iconConetct.actualSize(item4.decorationSize); + + picId = d->m_book->addPicture((const wchar_t *)fileName.constData()); + } + + int nOffsetX; + + if ((format->alignH() & ALIGNH_LEFT) == ALIGNH_LEFT) + { + nOffsetX = 1; + } + else if ((format->alignH() & ALIGNH_RIGHT) == ALIGNH_RIGHT) + { + nOffsetX = d->m_sheet->colWidth(col) * 7.55 - c_size.width(); + } + else + { + nOffsetX = (d->m_sheet->colWidth(col) * 7.55 - c_size.width()) / 2; + } + + int nOffsetY; + + if ((format->alignV() & ALIGNV_TOP) == ALIGNV_TOP) + { + nOffsetY = 0; + } + else if ((format->alignV() & ALIGNV_BOTTOM) == ALIGNV_BOTTOM) + { + nOffsetY = d->m_sheet->rowHeight(row) * 96.0 / 72 - c_size.height(); + } + else + { + nOffsetY = (d->m_sheet->rowHeight(row) * 96.0 / 72 - c_size.height()) / 2; + } + + d->m_sheet->setPicture2(row, col, picId, c_size.width(), + c_size.height(), nOffsetX, nOffsetY); + + Format *pFormat = d->m_book->addFormat(); + pFormat->setBorderTop(d->m_borderStyle); + pFormat->setBorderBottom(d->m_borderStyle); + pFormat->setBorderLeft(d->m_borderStyle); + pFormat->setBorderRight(d->m_borderStyle); + d->m_sheet->setCellFormat(row, col, pFormat); +} + +void GlodonTableViewToExcel::writeCellSymbol(int row, int col) +{ + Q_D(GlodonTableViewToExcel); + QModelIndex index = d->m_tableView->model()->index(row, col); + int nCellRow = row + d->m_horzRowCount + d->m_nStartRow; + int nCellCol = col + d->m_vertColCount; + + QRect cellRect(-1, -1, -1, -1); + cellRect = d->m_tableView->visualRect(index); + + QPixmap pixmap = d->m_tableView->viewport()->grab(cellRect); + + int nWidth = d->m_tableView->columnWidth(col); + + d->m_sheet->setCol(nCellCol, nCellCol, nWidth / c_nPixToExcelUnit); + + d->m_sheet->setRow(nCellRow, d->m_sheet->rowHeight(nCellRow) + 2); + + QString sFileName = QDir::tempPath() + "/Symbol.jpg"; + pixmap.save(sFileName); + int picId = d->m_book->addPicture((const wchar_t *)sFileName.constData()); + + int nFirstRow = -1; + int nLastRow = -1; + int nFirstCol = -1; + int nLastCol = -1; + d->m_sheet->getMerge(nCellRow, nCellCol, &nFirstRow, &nLastRow, + &nFirstCol, &nLastCol); + + if (-1 == nFirstRow) + { + nFirstRow = nCellRow; + nFirstCol = nCellCol; + } + + d->m_sheet->setPicture(nFirstRow, nFirstCol, picId, 1, 1, 1); + + Format *format = d->m_book->addFormat(); + format->setBorderTop(d->m_borderStyle); + format->setBorderBottom(d->m_borderStyle); + format->setBorderLeft(d->m_borderStyle); + format->setBorderRight(d->m_borderStyle); + d->m_sheet->setCellFormat(nCellRow, nCellCol, format); + + GFile::remove(sFileName); +} + +/** + * @brief GlodonTableViewToExcel::setFomatIndentSize + * excel的缩进不是按照像素来的,是按照字体大小来缩进的,所以需要把像素点转换到相应的字体大小。 + * + */ +void GlodonTableViewToExcel::setFomatIndentSize(Format *format, int pixMaSize) +{ + int fontSize = format->font()->size(); + int indentSize = (pixMaSize / fontSize) ; + format->setIndent(indentSize); +} + +Format *GlodonTableViewToExcel::getFormat(const QAbstractItemModel *model, int row, int col) +{ + Q_D(GlodonTableViewToExcel); + if (d->m_diffFormat.isEmpty()) + { + d->m_format = addDiffFormat(model, row, col); + } + else + { + if (!hasMatchedFormat(model, row, col)) + { + d->m_format = addDiffFormat(model, row, col); + } + } + + return d->m_format; +} + +Format *GlodonTableViewToExcel::getTitleFormat(const QAbstractItemModel *model, int section, + Qt::Orientation orientation) +{ + Q_D(GlodonTableViewToExcel); + if (d->m_diffTitleFormat.isEmpty()) + { + d->m_titleFormat = addDiffTitleFormat(model, section, orientation); + } + else + { + if (!hasMatchedTitleFormat(model, section, orientation)) + { + d->m_titleFormat = addDiffTitleFormat(model, section, orientation); + } + } + + return d->m_titleFormat; +} + +Format *GlodonTableViewToExcel::addDiffTitleFormat(const QAbstractItemModel *model, int section, + Qt::Orientation orientation) +{ + Q_D(GlodonTableViewToExcel); + TableCellFormat *titleCellFormat = new TableCellFormat; + Format *format = d->m_book->addFormat(); + GVariant value = model->headerData(section, orientation, Qt::FontRole); + GFont font = qvariant_cast(value); + Font *pFont = d->m_book->addFont(); + pFont->setName((const wchar_t *)font.family().constData()); + titleCellFormat->fontName = const_cast(font.family().constData()); + pFont->setSize(font.pointSize()); + titleCellFormat->fontSize = font.pointSize(); + pFont->setBold(font.bold()); + titleCellFormat->fontIsBold = font.bold(); + + if (font.underline()) + { + pFont->setUnderline(libxl::UNDERLINE_SINGLE); + } + + titleCellFormat->fontIsUnderline = font.underline(); + pFont->setStrikeOut(font.strikeOut()); + titleCellFormat->fontIsStrikeOut = font.strikeOut(); + pFont->setItalic(font.italic()); + titleCellFormat->fontIsItalic = font.italic(); + + value = model->headerData(section, orientation, Qt::ForegroundRole); + QColor oColor = qvariant_cast(value); + Color pColor = d->m_book->colorPack(oColor.red(), oColor.green(), oColor.blue()); + pFont->setColor(pColor); + titleCellFormat->foregroundRed = oColor.red(); + titleCellFormat->foregroundGreen = oColor.green(); + titleCellFormat->foregroundBlue = oColor.blue(); + format->setFont(pFont); + + value = model->headerData(section, orientation, Qt::TextAlignmentRole); + Qt::Alignment align = Qt::AlignCenter; + + if (GVariant() != value) + { + align = (Qt::Alignment)(qvariant_cast(value)); + } + + AlignH horizontal = QtAlignmentToXLSHorzAlignment(align); + AlignV vertical = QtAlignmentToXLSVertAlignment(align); + format->setAlignH(horizontal); + format->setAlignV(vertical); + titleCellFormat->textAlignment = align; + + value = model->headerData(section, orientation, Qt::BackgroundColorRole); + + if (GVariant() != value) + { + oColor = qvariant_cast(value); + pColor = d->m_book->colorPack(oColor.red(), oColor.green(), oColor.blue()); + format->setFillPattern(libxl::FILLPATTERN_SOLID); + titleCellFormat->backColorRed = oColor.red(); + titleCellFormat->backColorGreen = oColor.green(); + titleCellFormat->backColorBlue = oColor.blue(); + + if (pColor == Color(-1)) + { + format->setPatternForegroundColor(COLOR_WHITE); + } + else + { + format->setPatternForegroundColor(pColor); + } + } + + format->setWrap(d->m_tableView->wordWrap()); + format->setBorderTop(d->m_borderStyle); + format->setBorderBottom(d->m_borderStyle); + format->setBorderLeft(d->m_borderStyle); + format->setBorderRight(d->m_borderStyle); + + titleCellFormat->diffFormat = format; + d->m_diffTitleFormat.insert(section, titleCellFormat); + return format; +} + +bool GlodonTableViewToExcel::hasMatchedTitleFormat(const QAbstractItemModel *model, int section, Qt::Orientation orientation) +{ + Q_D(GlodonTableViewToExcel); + GFont font = qvariant_cast(model->headerData(section, orientation, Qt::FontRole)); + QColor oForeColor = qvariant_cast(model->headerData(section, orientation, Qt::ForegroundRole)); + QVariant value = model->headerData(section, orientation, Qt::TextAlignmentRole); + Qt::Alignment align = Qt::AlignCenter; + + if (GVariant() != value) + { + align = (Qt::Alignment)(qvariant_cast(value)); + } + + value = model->headerData(section, orientation, Qt::BackgroundColorRole); + QColor oBackColor; + + if (GVariant() != value) + { + oBackColor = qvariant_cast(value); + } + + QHash::const_iterator tableTitleCellIter = d->m_diffTitleFormat.constBegin(); + + while (tableTitleCellIter != d->m_diffTitleFormat.constEnd()) + { + //Hash中存储的Format样式 + TableCellFormat *matchCellFormat = tableTitleCellIter.value(); + + //Qt::FontRole比较结果 + bool isSameFontRole = false; + + if (matchCellFormat->fontName == font.family().constData() + && matchCellFormat->fontSize == font.pointSize() + && matchCellFormat->fontIsBold == font.bold() + && matchCellFormat->fontIsUnderline == font.underline() + && matchCellFormat->fontIsStrikeOut == font.strikeOut() + && matchCellFormat->fontIsItalic == font.italic()) + { + isSameFontRole = true; + } + + //Qt::ForegroundRole比较结果 + bool isSameForegroundRole = false; + + if (matchCellFormat->foregroundRed == oForeColor.red() + && matchCellFormat->foregroundGreen == oForeColor.green() + && matchCellFormat->foregroundBlue == oForeColor.blue()) + { + isSameForegroundRole = true; + } + + //Qt::TextAlignmentRole比较结果 + bool isSameTextAligRole = false; + + if (matchCellFormat->textAlignment == align) + { + isSameTextAligRole = true; + } + + //Qt::BackgroundColorRole比较结果 + bool isSameBackColorRole = false; + + if (matchCellFormat->backColorRed == oBackColor.red() + && matchCellFormat->backColorGreen == oBackColor.green() + && matchCellFormat->backColorBlue == oBackColor.blue()) + { + isSameBackColorRole = true; + } + + if (isSameFontRole + && isSameForegroundRole + && isSameTextAligRole + && isSameBackColorRole) + { + d->m_titleFormat = matchCellFormat->diffFormat; + return true; + } + + tableTitleCellIter++; + } + + return false; +} + +void GlodonTableViewToExcel::initBorderFormat() +{ + Q_D(GlodonTableViewToExcel); + if (d->m_tableView->gridLineWidth() == 0) + { + d->m_borderStyle = BORDERSTYLE_NONE; + } +} + +Format *GlodonTableViewToExcel::addDiffFormat(const QAbstractItemModel *model, int row, int col) +{ + Q_D(GlodonTableViewToExcel); + TableCellLocation *cellLocation = new TableCellLocation(row, col); + TableCellFormat *cellFormat = new TableCellFormat; + Format *format = d->m_book->addFormat(); + QModelIndex oIndex = model->index(row, col); + GVariant value = model->data(oIndex, Qt::FontRole); + GFont font = qvariant_cast(value); + Font *pFont = d->m_book->addFont(); + pFont->setName((const wchar_t *)font.family().constData()); + cellFormat->fontName = const_cast(font.family().constData()); + pFont->setSize(font.pointSize()); + cellFormat->fontSize = font.pointSize(); + pFont->setBold(font.bold()); + cellFormat->fontIsBold = font.bold(); + + if (font.underline()) + { + pFont->setUnderline(libxl::UNDERLINE_SINGLE); + } + + cellFormat->fontIsUnderline = font.underline(); + pFont->setStrikeOut(font.strikeOut()); + cellFormat->fontIsStrikeOut = font.strikeOut(); + pFont->setItalic(font.italic()); + cellFormat->fontIsItalic = font.italic(); + + value = model->data(oIndex, Qt::ForegroundRole); + QColor oColor = qvariant_cast(value); + Color pColor = d->m_book->colorPack(oColor.red(), oColor.green(), oColor.blue()); + pFont->setColor(pColor); + cellFormat->foregroundRed = oColor.red(); + cellFormat->foregroundGreen = oColor.green(); + cellFormat->foregroundBlue = oColor.blue(); + format->setFont(pFont); + + value = model->data(oIndex, Qt::TextAlignmentRole); + + if (GVariant() != value) + { + Qt::Alignment align = (Qt::Alignment)(qvariant_cast(value)); + AlignH horizontal = QtAlignmentToXLSHorzAlignment(align); + AlignV vertical = QtAlignmentToXLSVertAlignment(align); + format->setAlignH(horizontal); + format->setAlignV(vertical); + cellFormat->textAlignment = align; + } + + value = model->data(oIndex, Qt::BackgroundColorRole); + + if (GVariant() != value) + { + oColor = qvariant_cast(value); + pColor = d->m_book->colorPack(oColor.red(), oColor.green(), oColor.blue()); + + format->setFillPattern(libxl::FILLPATTERN_SOLID); + + if (pColor == Color(-1)) + { + format->setPatternForegroundColor(COLOR_WHITE); + } + else + { + format->setPatternForegroundColor(pColor); + } + + cellFormat->backColorRed = oColor.red(); + cellFormat->backColorGreen = oColor.green(); + cellFormat->backColorBlue = oColor.blue(); + } + + format->setWrap(d->m_tableView->wordWrap()); + format->setBorderTop(d->m_borderStyle); + format->setBorderBottom(d->m_borderStyle); + format->setBorderLeft(d->m_borderStyle); + format->setBorderRight(d->m_borderStyle); + cellFormat->diffFormat = format; + d->m_diffFormat.insert(cellLocation, cellFormat); + return format; +} + +bool GlodonTableViewToExcel::hasMatchedFormat(const QAbstractItemModel *model, int row, int col) +{ + Q_D(GlodonTableViewToExcel); + QModelIndex oIndex = model->index(row, col); + GFont font = qvariant_cast(model->data(oIndex, Qt::FontRole)); + QColor oForeColor = qvariant_cast(model->data(oIndex, Qt::ForegroundRole)); + Qt::Alignment align = (Qt::Alignment)qvariant_cast(model->data(oIndex, Qt::TextAlignmentRole)); + QColor oBackColor = qvariant_cast(model->data(oIndex, Qt::BackgroundColorRole)); + + //判断存储在Hash中是否有相同的Format + QHash::const_iterator tableTitleCellIter = d->m_diffFormat.constBegin(); + + while (tableTitleCellIter != d->m_diffFormat.constEnd()) + { + //Hash中存储的Format样式 + TableCellFormat *matchCellFormat = tableTitleCellIter.value(); + + //Qt::FontRole比较结果 + bool isSameFontRole = false; + + if (matchCellFormat->fontName == font.family().constData() + && matchCellFormat->fontSize == font.pointSize() + && matchCellFormat->fontIsBold == font.bold() + && matchCellFormat->fontIsUnderline == font.underline() + && matchCellFormat->fontIsStrikeOut == font.strikeOut() + && matchCellFormat->fontIsItalic == font.italic()) + { + isSameFontRole = true; + } + + //Qt::ForegroundRole比较结果 + bool isSameForegroundRole = false; + + if (matchCellFormat->foregroundRed == oForeColor.red() + && matchCellFormat->foregroundGreen == oForeColor.green() + && matchCellFormat->foregroundBlue == oForeColor.blue()) + { + isSameForegroundRole = true; + } + + //Qt::TextAlignmentRole比较结果 + bool isSameTextAligRole = false; + + if (matchCellFormat->textAlignment == align) + { + isSameTextAligRole = true; + } + + //Qt::BackgroundColorRole比较结果 + bool isSameBackColorRole = false; + + if (matchCellFormat->backColorRed == oBackColor.red() + && matchCellFormat->backColorGreen == oBackColor.green() + && matchCellFormat->backColorBlue == oBackColor.blue()) + { + isSameBackColorRole = true; + } + + if (isSameFontRole + && isSameForegroundRole + && isSameTextAligRole + && isSameBackColorRole) + { + d->m_format = matchCellFormat->diffFormat; + return true; + } + + tableTitleCellIter++; + } + + return false; +} + +class GLDDocViewToExcelPrivate +{ +public: + GLDDocViewToExcelPrivate(GLDDocViewToExcel *parent) + : q_ptr(parent), m_nStartExportPage(0), m_nEndExportPage(0), + m_sLoadFileName(""), m_sSaveFileName(""), + m_sSheetName("") + { + } + +private: + GLDDocViewToExcel * const q_ptr; + Q_DECLARE_PUBLIC(GLDDocViewToExcel); + + GLDDocView *m_docView; + GlodonTableViewToExcel *m_tableViewToXls; + int m_nStartExportPage; + int m_nEndExportPage; + QString m_sLoadFileName; + QString m_sSaveFileName; + QString m_sSheetName; +}; + +GLDDocViewToExcel::GLDDocViewToExcel() : d_ptr(new GLDDocViewToExcelPrivate(this)) + +{ + Q_D(GLDDocViewToExcel); + d->m_docView = NULL; + d->m_tableViewToXls = new GlodonTableViewToExcel(); +} + +GLDDocViewToExcel::~GLDDocViewToExcel() +{ + Q_D(GLDDocViewToExcel); + freeAndNil(d->m_docView); + freeAndNil(d->m_tableViewToXls); + freePtr(d); +} + +bool GLDDocViewToExcel::execute(GLDDocView *docView, + const GString &fileName, + const GString &sheetName, + bool isToSingleSheet, + bool isOverWrite, + bool showPrompt) +{ + GlodonTableViewToExcel *exporter = new GlodonTableViewToExcel(); + + try + { + exporter->setIsToSingleSheet(isToSingleSheet); + exporter->setIsOverWrite(isOverWrite); + exporter->load(fileName); + exporter->setShowPrompt(showPrompt); + + for (int i = 0; i < docView->pageCount(); ++i) + { + GLDPaperWidget *pPaper = docView->newPaper(i); + exporter->setTableView(pPaper->tableView()); + exporter->doExport(sheetName); + freeAndNil(pPaper); + } + + exporter->save(fileName); + } + catch (...) + { + freeAndNil(exporter); + throw; + } + + freeAndNil(exporter); + return true; +} + +void GLDDocViewToExcel::setDocView(GLDDocView *docView) +{ + Q_D(GLDDocViewToExcel); + d->m_docView = docView; + d->m_nEndExportPage = d->m_docView->pageCount() - 1; +} + +ExportState GLDDocViewToExcel::exportToExcel(bool isToSingleSheet, bool isOverWrite, bool showPrompt) +{ + Q_D(GLDDocViewToExcel); + d->m_tableViewToXls->setShowPrompt(showPrompt); + d->m_tableViewToXls->setIsToSingleSheet(isToSingleSheet); + d->m_tableViewToXls->setIsOverWrite(isOverWrite); + d->m_tableViewToXls->load(d->m_sLoadFileName); + + for (int i = d->m_nStartExportPage; i <= d->m_nEndExportPage; ++i) + { + GLDPaperWidget *pPaper = d->m_docView->newPaper(i); + d->m_tableViewToXls->setTableView(pPaper->tableView()); + d->m_tableViewToXls->doExport(d->m_sSheetName); + freeAndNil(pPaper); + } + + return d->m_tableViewToXls->save(d->m_sSaveFileName); +} + +void GLDDocViewToExcel::setStartExportPage(int startExportPage) +{ + Q_D(GLDDocViewToExcel); + d->m_nStartExportPage = startExportPage; +} + +void GLDDocViewToExcel::setEndExportPage(int endExportPage) +{ + Q_D(GLDDocViewToExcel); + d->m_nEndExportPage = endExportPage; +} + +void GLDDocViewToExcel::setLoadFileName(QString fileName) +{ + Q_D(GLDDocViewToExcel); + d->m_sLoadFileName = fileName; +} + +void GLDDocViewToExcel::setSaveFileName(QString fileName) +{ + Q_D(GLDDocViewToExcel); + d->m_sSaveFileName = fileName; +} + +void GLDDocViewToExcel::setSheetName(QString sheetName) +{ + Q_D(GLDDocViewToExcel); + d->m_sSheetName = sheetName; +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDTranslations.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDTranslations.cpp new file mode 100644 index 00000000..d4668ac1 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDTranslations.cpp @@ -0,0 +1,116 @@ +#include +#include + +#include "GLDGlobal.h" +#include "GLDFileUtils.h" +#include "GLDFile.h" +#include "GLDTranslations.h" + +#include + +class GLDTranslationsPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(GLDTranslations) + +private: + QList *m_tsFileNames; + QList *m_translators; + GXMLDocument m_configDom; +}; + +GLDTranslations::GLDTranslations(QObject *parent) + : QObject(*(new GLDTranslationsPrivate), parent) +{ + Q_D(GLDTranslations); + d->m_tsFileNames = new QList; + d->m_translators = new QList; +} + +GLDTranslations::~GLDTranslations() +{ + Q_D(GLDTranslations); + d->m_tsFileNames->clear(); + freeAndNil(d->m_tsFileNames); + + d->m_translators->clear(); + freeAndNil(d->m_translators); +} + +bool GLDTranslations::loadConfigFile(const GString filePath, const GString configfileName) +{ + Q_D(GLDTranslations); + if (0 == filePath.length()) return false; + GString split = filePath.endsWith("/") ? "":(filePath.endsWith("\\") ? "" : (filePath.contains("/") ? "/" : "\\")); + GString fileName = filePath + split + configfileName; + if (0 == configfileName.length() || filePath.endsWith(".xml")) + { + fileName = filePath; + } + if (!fileName.endsWith("TranslationsConfig.xml")) + { + fileName += "TranslationsConfig.xml"; + } + GFile file(fileName, this); + if (!file.open(QIODevice::ReadOnly)) + { + return false; + } + + if (!d->m_configDom.setContent(&file)) + { + file.close(); + return false; + } + + GXMLNode docElem = d->m_configDom.documentElement(); + GXMLNode elmtTRFiles = docElem.firstChildElement("TRFiles"); + QLocale defaultLocale; + while (!elmtTRFiles.isNull()) + { + GString strLanguage = elmtTRFiles.attribute("Language"); + + if (strLanguage.compare(defaultLocale.name(), Qt::CaseInsensitive) == 0) + { + break; + } + elmtTRFiles = elmtTRFiles.nextSiblingElement("Language"); + } + + if (elmtTRFiles.isNull()) + { + return false; + } + + GXMLNode elmtTrFile = elmtTRFiles.firstChildElement("TRFile"); + while (!elmtTrFile.isNull()) + { + GString strFileName = elmtTrFile.firstChild().nodeValue(); + d->m_tsFileNames->append(filePath + split + strFileName); + elmtTrFile = elmtTrFile.nextSiblingElement("TRFile"); + } + + return true; +} + +// 加载翻译文件 +bool GLDTranslations::installTranslators() +{ + Q_D(GLDTranslations); + for (int i = 0; i < d->m_tsFileNames->count(); ++i) + { + QTranslator *translator = new QTranslator(this); + GString strFileName = d->m_tsFileNames->value(i); + GString strFileAbPath = /*exePath() + */strFileName; + translator->load(strFileAbPath); + bool isOK = qApp->installTranslator(translator); + if (isOK) + { + d->m_translators->append(translator); + } + else + { + freeAndNil(translator); + } + } + return true; +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDUIUtils.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDUIUtils.cpp new file mode 100644 index 00000000..9fb23f6e --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDUIUtils.cpp @@ -0,0 +1,71 @@ +#include "GLDUIUtils.h" + +#include +#include +#include +#include +#include "GLDWidget_Global.h" +#include "GLDFileUtils.h" +#include "GLDStrings.h" + +const char *SPrompt = QT_TRANSLATE_NOOP("GLD", "Prompt");// "提示"); +const char *rsConfirmCaption = QT_TRANSLATE_NOOP("GLD", "Confirm");// "确认"); +const char *rsErrorCaption = QT_TRANSLATE_NOOP("GLD", "Error");// "错误"); +const char *rsWarningCaption = QT_TRANSLATE_NOOP("GLD", "Warning");// "警告"); +const char *rsMsgDlgOK = QT_TRANSLATE_NOOP("GLD", "OK");// "确定"); +const char *rsMsgDlgCancel = QT_TRANSLATE_NOOP("GLD", "Cancel");// "取消"); + + +void showPrompt(const GString &msg, bool bShowClose, QWidget *parent) +{ + if (bShowClose) + QMessageBox::information(parent, getGLDi18nStr(SPrompt), msg, QMessageBox::Ok); + else + { + QMessageBox messageBox; + messageBox.setParent(parent); + messageBox.setWindowTitle(getGLDi18nStr(SPrompt)); + messageBox.setText(msg); + messageBox.setStandardButtons(QMessageBox::Ok); + Qt::WindowFlags wFlags = Qt::CustomizeWindowHint | Qt::WindowTitleHint; + messageBox.setWindowFlags(wFlags); + messageBox.setIcon(QMessageBox::Information); + messageBox.exec(); + } +} + +//////////////////////////////////////////////////////////////////////////////// +//设计:Linc 2009.10.26 +//功能:确认对话框 +//参数:AMsg -- 错误信息串 +// cancelButton -- 释放包含Cancel按钮 +//返回:选择的按钮 +//注意:会尽量选择 Vista 风格的 TaskDialogs +//////////////////////////////////////////////////////////////////////////////// +int confirmDlg(const GString msg, bool cancelButton, QWidget *parent) +{ + if (cancelButton) + { + return QMessageBox::question(parent, getGLDi18nStr(rsConfirmCaption), msg, QMessageBox::Yes, QMessageBox::No, + QMessageBox::Cancel); + } + else + { + return QMessageBox::question(parent, getGLDi18nStr(rsConfirmCaption), msg, QMessageBox::Yes, QMessageBox::No); + } +} + +void showError(const GString &msg, QWidget *parent) +{ + QMessageBox::critical(parent, getGLDi18nStr(rsErrorCaption), msg, QMessageBox::Ok); +} + +void showWarnning(const GString &msg, QWidget *parent) +{ + QMessageBox::warning(parent, getGLDi18nStr(rsWarningCaption), msg, QMessageBox::Ok); +} + +int showConfirm(const GString &msg, QWidget *parent) +{ + return QMessageBox::question(parent, getGLDi18nStr(rsConfirmCaption), msg, QMessageBox::Yes, QMessageBox::No); +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDXLS.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDXLS.cpp new file mode 100644 index 00000000..5983d901 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDXLS.cpp @@ -0,0 +1,106 @@ +#include "GLDXLS.h" +#include "GLDStrUtils.h" +const GString c_LibXlUser = TRANS_STRING("延平 贾"); + +libxl::Book *createXLSBook(bool isXls) +{ + libxl::Book* result; + if (isXls) + { + result = xlCreateBook(); + } + else + { + result = xlCreateXMLBook(); + } +#ifdef _UNICODE + result->setKey((const wchar_t *)c_LibXlUser.constData(), L"windows-232f2f0705c9e4006db5636aaao7dbt8"); +#else + result->setKey("延平 贾", "windows-232f2f0705c9e4006db5636aaao7dbt8"); +#endif + return result; +} + +Qt::Alignment XLSHorzAlignmentToQtAlignment(libxl::AlignH align) +{ + switch (align) + { + case libxl::ALIGNH_GENERAL: + return 0; + case libxl::ALIGNH_LEFT: + return Qt::AlignLeft | Qt::AlignJustify; + case libxl::ALIGNH_RIGHT: + return Qt::AlignRight | Qt::AlignJustify; + case libxl::ALIGNH_CENTER: + case libxl::ALIGNH_MERGE: + case libxl::ALIGNH_DISTRIBUTED: + return Qt::AlignHCenter | Qt::AlignJustify; + default: + return 0; + } +} + +Qt::Alignment XLSVertAlignmentToQtAlignment(libxl::AlignV align) +{ + switch (align) + { + case libxl::ALIGNV_TOP: + return Qt::AlignTop | Qt::AlignJustify; + case libxl::ALIGNV_BOTTOM: + return Qt::AlignBottom | Qt::AlignJustify; + case libxl::ALIGNV_CENTER: + case libxl::ALIGNV_DISTRIBUTED: + return Qt::AlignVCenter | Qt::AlignJustify; + default: + return 0; + } +} + +Qt::Alignment XLSAlignmentToQtAlignment(libxl::AlignH horzAlignment, libxl::AlignV vertAlignment) +{ + return XLSHorzAlignmentToQtAlignment(horzAlignment) | XLSVertAlignmentToQtAlignment(vertAlignment); +} + +libxl::AlignV QtAlignmentToXLSVertAlignment(Qt::Alignment align) +{ + if (Qt::AlignTop == (Qt::AlignTop & align)) + { + return libxl::ALIGNV_TOP; + } + else if (Qt::AlignBottom == (Qt::AlignBottom & align)) + { + return libxl::ALIGNV_BOTTOM; + } + else if (Qt::AlignVCenter == (Qt::AlignVCenter & align)) + { + return libxl::ALIGNV_CENTER; + } + else if (Qt::AlignJustify == (Qt::AlignJustify & align)) + { + return libxl::ALIGNV_JUSTIFY; + } + else + return libxl::ALIGNV_CENTER; +} + +libxl::AlignH QtAlignmentToXLSHorzAlignment(Qt::Alignment align) +{ + if (0x00 == (0x0f & align)) + { + return libxl::ALIGNH_GENERAL; + } + else if (Qt::AlignRight == (Qt::AlignRight & align)) + { + return libxl::ALIGNH_RIGHT; + } + else if (Qt::AlignLeft == (Qt::AlignLeft & align)) + { + return libxl::ALIGNH_LEFT; + } + else if (Qt::AlignJustify == (Qt::AlignJustify & align)) + { + return libxl::ALIGNH_JUSTIFY; + } + else + return libxl::ALIGNH_CENTER; +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDXMLBuilder.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDXMLBuilder.cpp new file mode 100644 index 00000000..9367f2a2 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDXMLBuilder.cpp @@ -0,0 +1,285 @@ +#include "GLDXMLBuilder.h" +#include "GLDStrUtils.h" +#include "GLDXMLDoc.h" + +const GString c_gconCDataFmt = ""; +const GString c_gconCommentFmt = ""; + +const char* c_gdefIndentText = " "; +const GByteArray c_glineBreak = "\r\n"; + +class GXMLBuilderPrivate +{ +public: + GXMLBuilderPrivate(GXMLBuilder *parent); +private: + GXMLBuilder * const q_ptr; + Q_DECLARE_PUBLIC(GXMLBuilder); + + GStream *m_pStream; + bool m_bAutoIndent; + EnXMLEncode m_enEncoding; + QByteArray m_strLineBreak; + bool m_bReplaceChars; +}; + +GXMLBuilderPrivate::GXMLBuilderPrivate(GXMLBuilder *parent) + : q_ptr(parent), m_bAutoIndent(false), m_enEncoding(XE_UTF8), + m_strLineBreak(c_glineBreak), m_bReplaceChars(false) +{ +} + +GXMLBuilder::GXMLBuilder(GStream *stream) : d_ptr(new GXMLBuilderPrivate(this)) +{ + Q_D(GXMLBuilder); + assert(stream != NULL); + d->m_pStream = stream; +} + +GXMLBuilder::~GXMLBuilder() +{ + Q_D(GXMLBuilder); + d->m_pStream = NULL; + freePtr(d); +} + +GString GXMLBuilder::saveDocText(CGLDXMLDocument *doc, bool replaceChars) +{ + GBlockMemoryStream *pStream = new GBlockMemoryStream; + GXMLBuilder *pBuilder = new GXMLBuilder(pStream); + GByteArray strTemp; + try + { + pBuilder->saveXMLDocument(doc, replaceChars, false); + pStream->seek(0); + strTemp = pStream->readAll(); + } + catch(...) + { + freeAndNil(pBuilder); + freeAndNil(pStream); + throw; + } + freeAndNil(pBuilder); + freeAndNil(pStream); + return GString::fromUtf8(strTemp); +} + +void GXMLBuilder::saveDoc(CGLDXMLDocument *doc, GStream *stream) +{ + GXMLBuilder *pXMLBuilder = new GXMLBuilder(stream); + try + { + pXMLBuilder->saveXMLDocument(doc, true, false); + } + catch (...) + { + freeAndNil(pXMLBuilder); + throw; + } + freeAndNil(pXMLBuilder); +} + +void GXMLBuilder::saveNode(CGLDXMLNode *node, GStream *stream) +{ + GXMLBuilder *pBuilder = new GXMLBuilder(stream); + try + { + pBuilder->d_ptr->m_bAutoIndent = false; + pBuilder->d_ptr->m_enEncoding = XE_ANSI; + pBuilder->d_ptr->m_strLineBreak = ""; + pBuilder->d_ptr->m_bReplaceChars = true; + pBuilder->recursionWriteNode(node); + } + catch(...) + { + freeAndNil(pBuilder); + throw; + } + freeAndNil(pBuilder); +} + +GString GXMLBuilder::getNodeOpenTag(CGLDXMLNode *node, bool end) +{ + assert(node != NULL); + + GString strOpenTag; + if (node->attributesObj()->count() == 0) + { + strOpenTag = GString("<%1>").arg(node->name()); + } + else + { + strOpenTag = GString("<%1 %2>").arg(node->name(), node->attributesObj()->xml()); + } + + if (end) + { + strOpenTag.insert(strOpenTag.length() - 1, '/'); + } + return strOpenTag; +} + +GString GXMLBuilder::getNodeCloseTag(CGLDXMLNode *node) +{ + assert(node != NULL); + return GString("").arg(node->name()); +} + +void GXMLBuilder::saveXMLDocument(CGLDXMLDocument *doc, bool replaceChars, bool ignoreEncode) +{ + Q_D(GXMLBuilder); + d->m_bAutoIndent = doc->autoIndent(); + if (ignoreEncode) + { + d->m_enEncoding = XE_ANSI; + } + else if (sameText(doc->encoding(), c_uft8Encoding)) // 字符串优化 + { + d->m_enEncoding = XE_UTF8; + } + else + { + d->m_enEncoding = XE_ANSI; + } + + if (doc->autoIndent()) + { + d->m_strLineBreak = c_glineBreak; + } + else + { + d->m_strLineBreak = " "; + } + + d->m_bReplaceChars = replaceChars; + if (doc->includeHeader()) + { + writeText(doc->getXMLHeader()); + } + recursionWriteNode(doc->rootObj()); +} + +void GXMLBuilder::recursionWriteNode(CGLDXMLNode *node) +{ + Q_D(GXMLBuilder); + if (NULL == node) + return; + + int nCount = node->childNodesObj()->count(); + GString strValue; + GString strLine; + + if (0 == nCount) + { + if (d->m_bReplaceChars) + { + strValue = node->text(); + } + else + { + strValue = node->asString(); + } + + switch (node->nodeType()) + { + case TEXT: + { + strLine = strValue; + break; + } + case CDATA: + { + strLine = c_gconCDataFmt.arg(strValue); + break; + } + case COMMENT: + { + strLine = c_gconCommentFmt.arg(strValue); + break; + } + default: + { + if (!strValue.isEmpty()) + { + strLine = getNodeOpenTag(node, false) + strValue + getNodeCloseTag(node); + } + else + { + strLine = getNodeOpenTag(node, true); + } + break; + } + } + + if (node->nodeType() != TEXT) + { + writeIndentText(node->level()); + writeText(strLine, true); + } + else + { + writeText(strLine, false); + } + } + else + { + strLine = getNodeOpenTag(node); + writeIndentText(node->level()); + + if (node->childNodesObj()->nodeObj(0)->nodeType() != TEXT) + { + writeText(strLine); + } + else + { + writeText(strLine, false); + } + + for (int nNode = 0; nNode < node->childNodesObj()->count(); ++nNode) + { + recursionWriteNode(dynamic_cast(node->childNodesObj()->nodeObj(nNode))); + } + + strLine = getNodeCloseTag(node); + if (node->childNodesObj()->nodeObj(0)->nodeType() != TEXT) + { + writeIndentText(node->level()); + } + writeText(strLine); + } +} + +void GXMLBuilder::writeIndentText(int level) +{ + Q_D(GXMLBuilder); + if (d->m_bAutoIndent) + { + while (level > 0) + { + d->m_pStream->write(c_gdefIndentText, 4);// to test + --level; + } + } +} + +void GXMLBuilder::writeText(const GString &text, bool addLineBreak) +{ + Q_D(GXMLBuilder); + GByteArray strTemp; + if (d->m_enEncoding == XE_UTF8) + { + strTemp = text.toUtf8(); + } + else + { + strTemp = strToByteArray(text); + } + d->m_pStream->write(strTemp.data(), strTemp.length()); //to test + + if (addLineBreak && !d->m_strLineBreak.isEmpty()) + { + d->m_pStream->write(d->m_strLineBreak, d->m_strLineBreak.length());// WriteBuffer(Pointer(FLineBreak)^, Length(FLineBreak) * SizeOf(AnsiChar)) + } + +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDXMLCore.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDXMLCore.cpp new file mode 100644 index 00000000..03a5a5bc --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDXMLCore.cpp @@ -0,0 +1,962 @@ +#include "GLDXMLCore.h" +#include "GLDXMLDoc.h" + +/*GLDXMLDocument*/ +GLDXMLDocument::GLDXMLDocument() : GComPtr() +{ +} + +GLDXMLNode GLDXMLDocument::createElement(const GString &name) +{ + if (NULL == p) + { + innerCreateXMLDocument(); + } + return GLDXMLNode(p->createElement(name), false); +} + +GLDXMLNode GLDXMLDocument::createNode(const GString &name, EnXMLNodeType type) +{ + if (NULL == p) + { + innerCreateXMLDocument(); + } + return GLDXMLNode(p->createNode(name, type), false); +} + +bool GLDXMLDocument::isEmpty() +{ + if (NULL == p) + { + return true; + } + return p->isEmpty(); +} + +void GLDXMLDocument::loadFromFile(const GString &fileName) +{ + if (NULL == p) + { + innerCreateXMLDocument(); + } + p->loadFromFile(fileName); +} + +void GLDXMLDocument::saveToFile(const GString &fileName) +{ + assert(p != NULL); + p->saveToFile(fileName); +} + +void GLDXMLDocument::loadFromStream(GStream *stream) +{ + if (NULL == p) + { + innerCreateXMLDocument(); + } + p->loadFromStream(stream); +} + +void GLDXMLDocument::saveToStream(GStream *stream) +{ + assert(p != NULL); + p->saveToStream(stream); +} + +bool GLDXMLDocument::autoIndent() +{ + return p->autoIndent(); +} + +void GLDXMLDocument::setAutoIndent(bool value) +{ + p->setAutoIndent(value); +} + +GString GLDXMLDocument::displayText() +{ + return p->displayText(); +} + +GLDXMLNode GLDXMLDocument::documentElement() const +{ + if (NULL == p) + { + return NULL; + } + return GLDXMLNode(p->documentElement(), false); +} + +GString GLDXMLDocument::encoding() +{ + return p->encoding(); +} + +void GLDXMLDocument::setEncoding(const GString &value) +{ + p->setEncoding(value); +} + +GString GLDXMLDocument::fileName() +{ + return p->fileName(); +} + +void GLDXMLDocument::setFileName(const GString &value) +{ + p->setFileName(value); +} + +bool GLDXMLDocument::includeHeader() +{ + return p->includeHeader(); +} + +void GLDXMLDocument::setIncludeHeader(bool value) +{ + p->setIncludeHeader(value); +} + +EnTXMLOptions GLDXMLDocument::options() +{ + return p->options(); +} + +void GLDXMLDocument::setOptions(EnTXMLOptions xmlOptionsSet) +{ + p->setOptions(xmlOptionsSet); +} + +GString GLDXMLDocument::version() +{ + return p->version(); +} + +void GLDXMLDocument::setVersion(const GString &value) +{ + p->setVersion(value); +} + +GString GLDXMLDocument::xml() +{ + return p->xml(); +} + +void GLDXMLDocument::setXML(const GString &value) +{ + if (NULL == p) + { + innerCreateXMLDocument(); + } + p->setXML(value); +} + +GLDXMLNode GLDXMLDocument::root() +{ + return GLDXMLNode(p->root(), false); +} + +void GLDXMLDocument::setRoot(const GLDXMLNode &root) +{ + if (NULL == p) + { + innerCreateXMLDocument(); + } + p->setRoot(root); +} + +GLDXMLNode GLDXMLDocument::appendChild(GLDXMLNode newChild) +{ + if (NULL == p) + { + return GLDXMLNode(); + } + return GLDXMLNode(p->appendChild(newChild), false); +} + +bool GLDXMLDocument::setContent(GStream *dev, GString *errorMsg, int *errorLine, int *errorColumn) +{ + if (NULL == p) + { + innerCreateXMLDocument(); + } + return p->setContent(dev, errorMsg, errorLine, errorColumn); +} + +bool GLDXMLDocument::setContent(const GString &text, bool namespaceProcessing, GString *errorMsg, int *errorLine, int *errorColumn) +{ + G_UNUSED(errorLine); + if (NULL == p) + { + innerCreateXMLDocument(); + } + return p->setContent(text, namespaceProcessing, errorMsg, errorColumn); +} + +bool GLDXMLDocument::setContent(const GString &text, GString *errorMsg, int *errorLine, int *errorColumn) +{ + if (NULL == p) + { + innerCreateXMLDocument(); + } + return p->setContent(text, errorMsg, errorLine, errorColumn); +} + +bool GLDXMLDocument::setContent(const QByteArray &text, GString *errorMsg, int *errorLine, int *errorColumn) +{ + if (NULL == p) + { + innerCreateXMLDocument(); + } + return p->setContent(text, errorMsg, errorLine, errorColumn); +} + +GLDXMLNode GLDXMLDocument::firstChild() const +{ + if (NULL == p) + return GLDXMLNode(); + return GLDXMLNode(p->firstChild(), false); +} + +void GLDXMLDocument::save(GStream *stream, int indent) +{ + if (NULL == p) + return; + return p->save(stream, indent); +} + +GString GLDXMLDocument::toString(int indent) const +{ + if (NULL == p) + return GString(); + return p->toString(indent); +} + +GLDXMLNode GLDXMLDocument::elementById(const GString &elementId) +{ + return GLDXMLNode(); + G_UNUSED(elementId); +} + +GLDXMLNodeAttribute GLDXMLDocument::createAttribute(const GString &name) +{ + if (NULL == p) + innerCreateXMLDocument(); + return GLDXMLNodeAttribute(p->createAttribute(name), false); +} + +GLDXMLNode GLDXMLDocument::firstChildElement(const GString &tagName) const +{ + if (NULL == p) + return GLDXMLNode(); + return GLDXMLNode(p->firstChildElement(tagName), false); +} + +GLDXMLNode GLDXMLDocument::createTextNode(const GString &data) +{ + if (NULL == p) + innerCreateXMLDocument(); + return GLDXMLNode(p->createTextNode(data), false); +} + +GLDXMLNodeList GLDXMLDocument::childNodes() const +{ + if (NULL == p) + return GLDXMLNodeList(); + return GLDXMLNodeList(p->childNodes(), false); +} + +void GLDXMLDocument::clear() +{ + if (p != NULL) + { + freeAndNilIntf(p); + } +} + +GLDXMLNode GLDXMLDocument::toElement() const +{ + if (NULL == p) + return NULL; + return GLDXMLNode(p->toElement(), false); +} + +bool GLDXMLDocument::isNull() const +{ + return p == NULL; +} + +void GLDXMLDocument::innerCreateXMLDocument() +{ + CGLDXMLDocument *xmlDocument = new CGLDXMLDocument; + xmlDocument->setAutoIndent(true); + xmlDocument->setIncludeHeader(true); + p = xmlDocument; + p->AddRef(); +} + +/* GLDXMLNode */ +GLDXMLNode GLDXMLNode::addChild(const GString &strName) +{ + return GLDXMLNode(p->addChild(strName), false); +} + +GLDXMLNode GLDXMLNode::cloneNode(bool deep) +{ + return GLDXMLNode(p->cloneNode(deep), false); +} + +bool GLDXMLNode::hasAttribute(const GString &strName) const +{ + return p->hasAttribute(strName); +} + +GLDXMLNode GLDXMLNode::nextSibling() +{ + return GLDXMLNode(p->nextSibling(), false); +} + +GLDXMLNode GLDXMLNode::prevSibling() +{ + return GLDXMLNode(p->prevSibling(), false); +} + +bool GLDXMLNode::asBoolean() +{ + return p->asBoolean(); +} + +double GLDXMLNode::asFloat() +{ + return p->asFloat(); +} + +gint64 GLDXMLNode::asInt64() +{ + return p->asInt64(); +} + +int GLDXMLNode::asInteger() +{ + return p->asInteger(); +} + +GString GLDXMLNode::asString() +{ + return p->asString(); +} + +GVariant GLDXMLNode::asVariant() +{ + return p->asVariant(); +} + +GLDXMLNodeAttributes GLDXMLNode::attributes() const +{ + if (NULL == p) + { + return GLDXMLNodeAttributes(); + } + return GLDXMLNodeAttributes(p->attributes(), false); +} + +GLDXMLNodeList GLDXMLNode::childNodes() const +{ + if (NULL == p) + { + return GLDXMLNodeList(); + } + return GLDXMLNodeList(p->childNodes(), false); +} + +int GLDXMLNode::level() +{ + return p->level(); +} + +GString GLDXMLNode::name() +{ + return p->name(); +} + +EnXMLNodeType GLDXMLNode::nodeType() +{ + return p->nodeType(); +} + +GLDXMLNode GLDXMLNode::parent() const +{ + return GLDXMLNode(p->parent(), false); +} + +GString GLDXMLNode::text() const +{ + return p->asString(); +} + +GString GLDXMLNode::xml() +{ + return p->xml(); +} + +void GLDXMLNode::setAsBoolean(bool value) +{ + p->setAsBoolean(value); +} + +void GLDXMLNode::setAsFloat(float value) +{ + p->setAsFloat(value); +} + +void GLDXMLNode::setAsInt64(gint64 value) +{ + p->setAsInt64(value); +} + +void GLDXMLNode::setAsInteger(int value) +{ + p->setAsInteger(value); +} + +void GLDXMLNode::setAsString(const GString &value) +{ + p->setAsString(value); +} + +void GLDXMLNode::setAsVariant(const GVariant value) +{ + p->setAsVariant(value); +} + +void GLDXMLNode::setName(const GString &value) +{ + p->setName(value); +} + +void GLDXMLNode::setNodeType(const EnXMLNodeType value) +{ + p->setNodeType(value); +} + +void GLDXMLNode::setParent(const GLDXMLNode &parent) +{ + p->setParent(parent); +} + +void GLDXMLNode::setText(const GString &value) +{ + p->setText(value); +} + +void GLDXMLNode::setXML(const GString &value) +{ + p->setXML(value); +} + +void GLDXMLNode::loadFromStream(GStream *pStream) +{ + p->loadFromStream(pStream); +} + +void GLDXMLNode::saveToStream(GStream *pStream) +{ + p->saveToStream(pStream); +} + +GLDXMLNode GLDXMLNode::firstChildElement(const GString &tagName) const +{ + if (NULL == p) + return GLDXMLNode(); + return GLDXMLNode(p->firstChildElement(tagName), false); +} + +GString GLDXMLNode::nodeName() const +{ + if (NULL == p) + return GString(); + return p->nodeName(); +} + +GLDXMLNode GLDXMLNode::nextSiblingElement(const GString &taName) const +{ + if (NULL == p) + return GLDXMLNode(); + return GLDXMLNode(p->nextSiblingElement(taName), false); +} + +GLDXMLDocument GLDXMLNode::ownerDocument() const +{ + if (NULL == p) + return GLDXMLDocument(); + return GLDXMLDocument(p->ownerDocument(), false); +} + +GLDXMLNode GLDXMLNode::appendChild(const GLDXMLNode &newChild) +{ + if (NULL == p) + return GLDXMLNode(); + return GLDXMLNode(p->appendChild(newChild), false); +} + +GString GLDXMLNode::attribute(const GString &name, const GString &defValue) const +{ + if (NULL == p) + return GString(); + return p->attribute(name, defValue); +} + +void GLDXMLNode::setAttribute(const GString &name, const GString &value) +{ + return p->setAttribute(name, value); +} + +void GLDXMLNode::setAttribute(const GString &name, int value) +{ + return p->setAttribute(name, value); +} + +GLDXMLNode GLDXMLNode::insertBefore(const GLDXMLNode &newChild, const GLDXMLNode &refChild) +{ + if (NULL == p) + return GLDXMLNode(); + return GLDXMLNode(p->insertBefore(newChild, refChild), false); +} + +GLDXMLNode GLDXMLNode::removeChild(const GLDXMLNode &oldChild) +{ + if (NULL == p) + return GLDXMLNode(); + return GLDXMLNode(p->removeChild(oldChild), false); +} + +bool GLDXMLNode::hasChildNodes() const +{ + if (NULL == p) + return false; + return p->hasChildNodes(); +} + +GLDXMLNode GLDXMLNode::parentNode() const +{ + if (NULL == p) + return GLDXMLNode(); + return GLDXMLNode(p->parentNode(), false); +} + +void GLDXMLNode::setNodeValue(const GString &value) +{ + if (NULL == p) + return; + p->setNodeValue(value); +} + +GLDXMLNodeAttribute GLDXMLNode::attributeNode(const GString &name) +{ + if (NULL == p) + return GLDXMLNodeAttribute(); + return GLDXMLNodeAttribute(p->attributeNode(name), false); +} + +void GLDXMLNode::clear() +{ + if (p != NULL) + { + freeAndNilIntf(p); + } +} + +void GLDXMLNode::setTagName(const GString &name) +{ + if (p != NULL) + { + p->setTagName(name); + } +} + +GString GLDXMLNode::tagName() const +{ + if (NULL == p) + return GString(); + return p->tagName(); +} + +GLDXMLNode GLDXMLNode::toElement() const +{ + if (NULL == p) + return GLDXMLNode(); + return GLDXMLNode(p->toElement(), false); +} + +GLDXMLNodeList GLDXMLNode::elementsByTagName(const GString &tagname) const +{ + if (NULL == p) + { + return GLDXMLNodeList(); + } + return GLDXMLNodeList(p->elementsByTagName(tagname), false); +} + +GLDXMLNode GLDXMLNode::firstChild() const +{ + if (NULL == p) + return GLDXMLNode(); + return GLDXMLNode(p->firstChild(), false); +} + +GString GLDXMLNode::nodeValue() const +{ + if (NULL == p) + return GString(); + return p->nodeValue(); +} + +GLDXMLNode GLDXMLNode::lastChild() const +{ + if (NULL == p) + return GLDXMLNode(); + return GLDXMLNode(p->lastChild(), false); +} + +GLDXMLNode GLDXMLNode::toText() const +{ + if (NULL == p) + return GLDXMLNode(); + return GLDXMLNode(p->toText(), false); +} + +GString GLDXMLNode::data() const +{ + if (NULL == p) + return GString(); + return p->data(); +} + +void GLDXMLNode::removeAttribute(const GString &name) +{ + if (NULL == p) + return; + p->removeAttribute(name); +} + +GLDXMLNodeAttribute GLDXMLNode::setAttributeNode(GLDXMLNodeAttribute &newAttr) +{ + if (NULL == p) + return GLDXMLNodeAttribute(); + return GLDXMLNodeAttribute(p->setAttributeNode(newAttr), false); +} + +bool GLDXMLNode::isNull() const +{ + return p == NULL; +} + +bool GLDXMLNode::isElement() const +{ + if (NULL == p) + return false; + return p->isElement(); +} + +GLDXMLNode GLDXMLNode::replaceChild(const GLDXMLNode &newChild, const GLDXMLNode &oldChild) +{ + if (NULL == p || NULL == newChild.p || NULL == oldChild.p) + return GLDXMLNode(); + return GLDXMLNode(p->replaceChild(newChild, oldChild), false); +} + +GLDXMLNode GLDXMLNode::insertAfter(const GLDXMLNode &newChild, const GLDXMLNode &refChild) +{ + if (NULL == p) + return GLDXMLNode(); + return GLDXMLNode(p->insertAfter(newChild, refChild), false); +} + +GLDXMLNode GLDXMLNode::namedItem(const GString &name) const +{ + if (NULL == p) + return GLDXMLNode(); + return GLDXMLNode(p->namedItem(name), false); +} + +/* GLDXMLNodeList */ +int GLDXMLNodeList::add(const GLDXMLNode &node) +{ + return p->add(node); +} + +int GLDXMLNodeList::deleteNode(const GString &name) +{ + return p->deleteNode(name); +} + +void GLDXMLNodeList::deleteNode(int index) +{ + p->deleteNode(index); +} + +int GLDXMLNodeList::indexOf(const GLDXMLNode &node) +{ + return p->indexOf(node); +} + +int GLDXMLNodeList::indexOf(const GString &name) +{ + return p->indexOf(name); +} + +int GLDXMLNodeList::remove(const GLDXMLNode &node) +{ + return p->remove(node); +} + +void GLDXMLNodeList::clear() +{ + p->clear(); +} + +void GLDXMLNodeList::exChange(int cureIndex, int newIndex) +{ + p->exChange(cureIndex, newIndex); +} + +void GLDXMLNodeList::insert(int index, const GLDXMLNode &node) +{ + p->insert(index, node); +} + +void GLDXMLNodeList::move(int cureIndex, int newIndex) +{ + p->move(cureIndex, newIndex); +} + +GLDXMLNode GLDXMLNodeList::findNode(const GString &name) +{ + return GLDXMLNode(p->findNode(name), false); +} + +int GLDXMLNodeList::count() const +{ + if (NULL == p) + { + return 0; + } + return p->count(); +} + +GLDXMLNode GLDXMLNodeList::node(int index) +{ + return GLDXMLNode(p->node(index), false); +} + +GLDXMLNode GLDXMLNodeList::at(int index) const +{ + return GLDXMLNode(p->node(index), false); +} + +GLDXMLNode GLDXMLNodeList::item(int index) +{ + if (NULL == p) + return GLDXMLNode(); + return GLDXMLNode(p->item(index), false); +} + +GLDXMLNode GLDXMLNodeList::nodeByName(const GString &name) +{ + return GLDXMLNode(p->nodeByName(name), false); +} + +/*GLDXMLNodeAttribute*/ +bool GLDXMLNodeAttribute::asBoolean() +{ + return p->asBoolean(); +} + +double GLDXMLNodeAttribute::asFloat() +{ + return p->asFloat(); +} + +gint64 GLDXMLNodeAttribute::asInt64() +{ + return p->asInt64(); +} + +int GLDXMLNodeAttribute::asInteger() +{ + return p->asInteger(); +} + +GString GLDXMLNodeAttribute::asString() +{ + return p->asString(); +} + +GVariant GLDXMLNodeAttribute::asVariant() +{ + return p->asVariant(); +} + +int GLDXMLNodeAttribute::hashData() +{ + return p->hashData(); +} + +GString GLDXMLNodeAttribute::name() +{ + return p->name(); +} + +GString GLDXMLNodeAttribute::text() +{ + return p->text(); +} + +GString GLDXMLNodeAttribute::xml() +{ + return p->xml(); +} + +void GLDXMLNodeAttribute::setAsBoolean(bool value) +{ + p->setAsBoolean(value); +} + +void GLDXMLNodeAttribute::setAsFloat(double value) +{ + p->setAsFloat(value); +} + +void GLDXMLNodeAttribute::setAsInt64(gint64 value) +{ + p->setAsInt64(value); +} + +void GLDXMLNodeAttribute::setAsInteger(int value) +{ + p->setAsInteger(value); +} + +void GLDXMLNodeAttribute::setAsString(const GString &value) +{ + p->setAsString(value); +} + +void GLDXMLNodeAttribute::setAsVariant(const GVariant value) +{ + p->setAsVariant(value); +} + +void GLDXMLNodeAttribute::setName(const GString &strName) +{ + p->setName(strName); +} + +void GLDXMLNodeAttribute::setText(const GString &strText) +{ + p->setText(strText); +} + +void GLDXMLNodeAttribute::setXml(const GString &strXML) +{ + p->setXml(strXML); +} + +void GLDXMLNodeAttribute::setNodeValue(const GString &value) +{ + if (NULL == p) + return; + p->setText(value); +} + +GString GLDXMLNodeAttribute::nodeValue() const +{ + if (NULL == p) + return GString(); + return p->nodeValue(); +} + +GLDXMLNodeAttribute GLDXMLNodeAttribute::toAttr() const +{ + if (NULL == p) + return GLDXMLNodeAttribute(); + return GLDXMLNodeAttribute(p->toAttr(), false); +} + +GString GLDXMLNodeAttribute::value() const +{ + if (NULL == p) + return GString(); + return p->value(); +} + +GString GLDXMLNodeAttribute::nodeName() const +{ + if (NULL == p) + return GString(); + return p->nodeName(); +} + +/*GLDXMLNodeAttributes*/ +void GLDXMLNodeAttributes::clear() +{ + p->clear(); +} + +void GLDXMLNodeAttributes::remove(int nIndex) +{ + p->remove(nIndex); +} + +void GLDXMLNodeAttributes::setXml(const GString &value) +{ + p->setXml(value); +} + +int GLDXMLNodeAttributes::count() +{ + if (NULL == p) + { + return 0; + } + return p->count(); +} + +int GLDXMLNodeAttributes::indexOf(const GString &strName) +{ + return p->indexOf(strName); +} + +GString GLDXMLNodeAttributes::xml() +{ + return p->xml(); +} + +GLDXMLNodeAttribute GLDXMLNodeAttributes::add(const GString &strName) +{ + return GLDXMLNodeAttribute(p->add(strName), false); +} + +GLDXMLNodeAttribute GLDXMLNodeAttributes::item(int nIndex) +{ + return GLDXMLNodeAttribute(p->item(nIndex), false); +} + +GLDXMLNodeAttribute GLDXMLNodeAttributes::itemsByName(const GString &strName) +{ + return GLDXMLNodeAttribute(p->itemsByName(strName), false); +} + +GLDXMLNodeAttribute GLDXMLNodeAttributes::namedItem(const GString &name) const +{ + if (NULL == p) + return GLDXMLNodeAttribute(); + return GLDXMLNodeAttribute(p->namedItem(name), false); +} + +bool GLDXMLNodeAttributes::contains(const GString &name) +{ + if (NULL == p) + return false; + return p->contains(name); +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDXMLDoc.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDXMLDoc.cpp new file mode 100644 index 00000000..7c5dbdfc --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDXMLDoc.cpp @@ -0,0 +1,2591 @@ +#include "GLDXMLDoc.h" +#include "GLDStrUtils.h" +#include "GLDFile.h" +#include "GLDXMLParser.h" +#include "GLDXMLUtils.h" +#include "GLDStreamUtils.h" +#include "GLDXMLBuilder.h" + +GChar g_CurrentDecimalSeparator; +const GString c_gdefXMLDataHeader = ""; +const GString c_gconCommentPrex = ""; +const GString c_gconSpecificationFmt = ""; +const GString c_gconSpecificationFmtEx = ""; +const GString c_gconAttribFmt = "%1=\"%2\""; +const GString c_gconEncoding = "encoding"; +const GString c_gconVersion = "version"; +const GString c_uft8Encoding = "utf-8"; +const GString c_gdefVersion = "1.0"; +const GString c_gconLtTag = "<"; +const GString c_gconGtTag = ">"; +const GString c_gconAmpTag = "&"; +const GString c_gconAposTag = "'"; +const GString c_gconQuotTag = """; + +const GString c_gconXATag = " "; +const GString c_gconXDTag = " "; +const GString c_gconXaTag = " "; +const GString c_gconXdTag = " "; + +const GString c_grsErrInvalidRootNode = TRANS_STRING("XML 文档只能有一个顶层节点"); +const GString c_gdefNodeName[4] = {"#element","#text","#cdata-section","#comment"}; + +void replaceText(const GString &subStr, GChar aChar, GString &result) +{ + int nPos = 0; + nPos = posXMLString(subStr, result, nPos); + + while (nPos != -1) + { + result.replace(nPos, subStr.length(), aChar); + nPos = posXMLString(subStr, result, nPos + 1); + } +} + +GString decodeXMLString(const GString &value, bool decodeCrLf) +{ + int nTemp; + GString strResult = ""; + int nLength = value.length(); + + if (0 == nLength) + { + return strResult; + } + GString strBuffer = value; + bool bHasTag = false; + + for (nTemp = 0; nTemp < nLength; ++nTemp) + { + GChar aChar = strBuffer[nTemp]; + if (aChar == '&') + { + bHasTag = true; + break; + } + } + + if (bHasTag) + { + replaceText(c_gconLtTag, '<', strBuffer); + replaceText(c_gconGtTag, '>', strBuffer); + replaceText(c_gconAmpTag, '&', strBuffer); + replaceText(c_gconAposTag, '\'', strBuffer); + replaceText(c_gconQuotTag, '\"', strBuffer); + if (decodeCrLf) + { + replaceText(c_gconXATag, '\n', strBuffer); + replaceText(c_gconXDTag, '\r', strBuffer); + replaceText(c_gconXaTag, '\n', strBuffer); + replaceText(c_gconXdTag, '\r', strBuffer); + } + } + + strResult = strBuffer; + return strResult; + +} + +int adjustUtf8BufferSize(int nPos, int nReadLen, GStream *inStream) +{ + int result = 0; + char *arrLastWord = NULL; + byte cLast; + byte cPenult; + if (nReadLen < 2) + { + return result; + } + inStream->seek(nPos + nReadLen - 2); + inStream->read(&arrLastWord[0], 2); + cLast = arrLastWord[1]; + cPenult = arrLastWord[0]; + if (cLast <= 0X7F) + { + result = 0; + } + else if ((cLast > 0X7F) && (cLast <= 0XBF)) + { + if (cPenult > 0XDF && cPenult <= 0XEF) + { + result = 2; + } + else + { + result = 0; + } + } + else if (cLast > 0XBF && cLast < 0XDF) + { + result = 1; + } + else if (cLast > 0XDF && cLast <= 0XEF) + { + result = 1; + } + else + { + result = 1; + } + return result; +} + +GString utf8StreamDecode(GStream* inStream) +{ + if (inStream->size() == 0) + { + return ""; + } + GString result = ""; + int nMaxBufSize = 1 * 1024 * 1024; + GString strDest; + int nReadLen = 0; + int nPos = 0; + int nUtf8Delta = 0; + int nIndex = 0; + nIndex = inStream->size(); + if (nIndex == 0) + { + return result; + } + inStream->seek(0); + if (nIndex < nMaxBufSize) + { + //QString strBuffer; + //inStream->read(strToByteArray(strBuffer).data(), inStream->size()); + //result = strBuffer; + result = readFromStream(inStream,inStream->size()); + } + else + { + nPos = 0; + while (nPos < nIndex) + { + if (nPos + nMaxBufSize <= nIndex) + { + nReadLen = nMaxBufSize; + } + else + { + nReadLen = nIndex - nPos; + } + nUtf8Delta = adjustUtf8BufferSize(nPos, nReadLen, inStream); + if (nUtf8Delta == -1) + { + //QException.raise(); + return ""; + } + + nReadLen = nReadLen - nUtf8Delta; + inStream->seek(nPos); + //QString strBuffer; + //inStream->read(strToByteArray(strBuffer).data(), nReadLen); + //strDest = utf8ToUnicode(strToByteArray(strBuffer).data()); + strDest = readFromStream(inStream, nReadLen); + result = result + strDest; + nPos += nReadLen; + } + } + return result; +} + +int posExcludeQuotationMark(const GChar &xmlChar, const GString &xmlString, int offset = 0) // 注意数组下标问题 +{ + int nPos = -1; + + if (xmlChar.isNull() || xmlString.isEmpty()) + { + return nPos; + } + + int nLength = xmlString.length(); + int nIndex = offset; + + if (nIndex < 0) + { + nIndex = 0; + } + else if (nIndex >= nLength) + { + nIndex = nLength - 1; + } + + int nQuoTimes = 0; + int nAposTimes = 0; + + while (nIndex < nLength) + { + const GChar indexChar = xmlString[nIndex]; + if ('\"' == indexChar) + { + ++nQuoTimes; + } + else if ('\'' == indexChar) + { + ++nAposTimes; + } + else if ((indexChar == xmlChar) && (nQuoTimes % 2 == 0) && (nAposTimes % 2 == 0)) + { + nPos = nIndex; + break; + } + ++nIndex; + } + return nPos; +} + +GString copyTrimXMLString(GString &value, int start, int end) +{ + GString strResult = ""; + int nLength = value.length(); + if (end == nLength - 1) + { + end = nLength - 1; + } + while (start <= end && value[start] <= ' ') + { + ++start; + } + while ( end >= start && value[end] <= ' ') + { + --end; + } + if (start > end) + { + strResult = ""; + } + else + { + nLength = end - start + 1; + strResult = value.mid(start, nLength); + } + return strResult; +} + +class CGLDXMLNodePrivate +{ +public: + CGLDXMLNodePrivate::CGLDXMLNodePrivate(CGLDXMLNode *parent): q_ptr(parent) + { + } + +private: + CGLDXMLNode * const q_ptr; + Q_DECLARE_PUBLIC(CGLDXMLNode); + + EnXMLNodeType m_enNodeType; + GString m_strName; + GString m_strValue; + EnTXMLOptions m_enOptions; + CGLDXMLNode *m_pParent; + CGLDXMLNodeAttributes *m_pAttributes; + CGLDXMLNodeList *m_pNodeList; + CGLDXMLDocument *m_pOwnerDocument; +}; + +/* CGLDXMLNode */ +CGLDXMLNode::CGLDXMLNode(IGLDXMLNode *pParentNode, EnTXMLOptions enOptions, + EnXMLNodeType enType, IGLDXMLDocument *ownerDocument) + : d_ptr(new CGLDXMLNodePrivate(this)), GInterfaceObject() +{ + Q_D(CGLDXMLNode); + d->m_enNodeType = enType; + d->m_enOptions = enOptions; + d->m_pParent = dynamic_cast (pParentNode); + d->m_pOwnerDocument = dynamic_cast(ownerDocument); + + d->m_pAttributes = new CGLDXMLNodeAttributes(enOptions); + d->m_pAttributes->AddRef(); + d->m_pNodeList = new CGLDXMLNodeList(this); + d->m_pNodeList->AddRef(); +} + +CGLDXMLNode::~CGLDXMLNode() +{ + Q_D(CGLDXMLNode); + freeAndNilIntf(d->m_pNodeList); + freeAndNilIntf(d->m_pAttributes); + freePtr(d); +} + +IGLDXMLNode *CGLDXMLNode::addChild(GString strName) +{ + Q_D(CGLDXMLNode); + CGLDXMLNode *node = new CGLDXMLNode(this, d->m_enOptions, ELEMENT, d->m_pOwnerDocument); + node->setName(strName); + d->m_pNodeList->add(node); + if (node != NULL) + { + node->AddRef(); + } + return node; +} + +IGLDXMLNode *CGLDXMLNode::cloneNode(bool deep) +{ + CGLDXMLNode *pNode = cloneNodeObj(deep); + if (pNode != NULL) + { + pNode->AddRef(); + } + return pNode; +} + +bool CGLDXMLNode::hasAttribute(const GString &strName) const +{ + Q_D(const CGLDXMLNode); + return d->m_pAttributes->indexOf(strName) > -1; +} + +IGLDXMLNode *CGLDXMLNode::nextSibling() +{ + CGLDXMLNode *pNode = nextSiblingObj(); + if (pNode != NULL) + { + pNode->AddRef(); + } + return pNode; +} + +IGLDXMLNode *CGLDXMLNode::prevSibling() +{ + CGLDXMLNode *pNode = prevSiblingObj(); + if (pNode != NULL) + { + pNode->AddRef(); + } + return pNode; +} + +IGLDXMLNode *CGLDXMLNode::firstChildElement(const GString &tagName) const +{ + Q_D(const CGLDXMLNode); + CGLDXMLNode *pNode = d->m_pNodeList->findNodeObj(tagName); + if (pNode != NULL) + { + pNode->AddRef(); + } + return pNode; +} + +IGLDXMLNode *CGLDXMLNode::insertBefore(IGLDXMLNode *newChild, IGLDXMLNode *refChild) +{ + Q_D(CGLDXMLNode); + CGLDXMLNode *pNewChild = dynamic_cast(newChild); + CGLDXMLNode *pRefChild = dynamic_cast(refChild); + if (!pNewChild) + { + return NULL; + } + else + { + int nRefIndex = d->m_pNodeList->indexOf(pRefChild); + int nNewIndex = d->m_pNodeList->indexOf(pNewChild); + if (-1 == nRefIndex) + { + if (-1 == nNewIndex) + { + d->m_pNodeList->insert(0, pNewChild); + } + else + { + d->m_pNodeList->move(nNewIndex, 0); + } + } + else + { + if (-1 == nNewIndex) + { + d->m_pNodeList->insert(nRefIndex, pNewChild); + } + else + { + d->m_pNodeList->move(nNewIndex, nRefIndex); + } + } + } + + if (pNewChild != NULL) + { + pNewChild->AddRef(); + } + return pNewChild; +} + +bool CGLDXMLNode::asBoolean() +{ + Q_D(CGLDXMLNode); + return sameText("true", d->m_strValue); +} + +double CGLDXMLNode::asFloat() +{ + Q_D(CGLDXMLNode); + return strToFloat(d->m_strValue); +} + +gint64 CGLDXMLNode::asInt64() +{ + Q_D(CGLDXMLNode); + return strToInt64(d->m_strValue); +} + +int CGLDXMLNode::asInteger() +{ + Q_D(CGLDXMLNode); + return strToInt(d->m_strValue); +} + +GString CGLDXMLNode::asString() +{ + Q_D(CGLDXMLNode); + //用byte(char)存储的枚举 给枚举赋值是 char c=9 不能为 char c='9'(变成了arsii码), + return decodeXMLString(d->m_strValue, contains(d->m_enOptions, XO_DECODE_CRLF)); +} + +GVariant CGLDXMLNode::asVariant() +{ + // TODO + return GVariant(); +// return base64Decode(d->m_strValue.toLocal8Bit()); +} + +IGLDXMLNodeAttributes *CGLDXMLNode::attributes() const +{ + Q_D(const CGLDXMLNode); + if (d->m_pAttributes) + { + d->m_pAttributes->AddRef(); + } + return d->m_pAttributes; +} + +IGLDXMLNodeList *CGLDXMLNode::childNodes() const +{ + Q_D(const CGLDXMLNode); + if (d->m_pNodeList) + { + d->m_pNodeList->AddRef(); + } + return d->m_pNodeList; +} + +int CGLDXMLNode::level() +{ + Q_D(CGLDXMLNode); + int result = 0; + CGLDXMLNode *pParent = d->m_pParent; + while (pParent != NULL) + { + pParent = pParent->parentObj(); + ++result; + } + return result; +} + +QString CGLDXMLNode::name() +{ + Q_D(CGLDXMLNode); + return d->m_strName; +} + +EnXMLNodeType CGLDXMLNode::nodeType() +{ + Q_D(CGLDXMLNode); + return d->m_enNodeType; +} + +IGLDXMLNode *CGLDXMLNode::parent() const +{ + Q_D(const CGLDXMLNode); + if (d->m_pParent) + { + d->m_pParent->AddRef(); + } + return d->m_pParent; +} + +QString CGLDXMLNode::text() const +{ + Q_D(const CGLDXMLNode); + return d->m_strValue; +} + +QString CGLDXMLNode::xml() +{ + Q_D(CGLDXMLNode); + switch (d->m_enNodeType) + { + case TEXT: + return d->m_strValue; + case CDATA: + return GString(c_gconCDataPrex).append(d->m_strValue).append(c_gconCDataPosx); + case COMMENT: + return GString(c_gconCommentPrex).append(d->m_strValue).append(c_gconCommentPosx); + default: + if (d->m_pAttributes->count() > 0) + { + return GString("<").append(d->m_strName).append(" ").append(d->m_pAttributes->xml()).append(">"); + } + else + { + return GString("<").append(d->m_strName).append(">"); + } + } + + return ""; +} + +QString CGLDXMLNode::nodeValue() const +{ + return const_cast(this)->asString(); +} + +IGLDXMLNodeAttribute *CGLDXMLNode::attributeNode(const QString &name) +{ + Q_D(CGLDXMLNode); + if(d->m_pAttributes->indexOf(name) == -1) + return NULL; + + return d->m_pAttributes->itemsByName(name); +} + +IGLDXMLNode *CGLDXMLNode::replaceChild(IGLDXMLNode *newChild, IGLDXMLNode *oldChild) +{ + Q_D(CGLDXMLNode); + if (!newChild) + { + return NULL; + } + else + { + int nValue = d->m_pNodeList->indexOf(oldChild); + int nTemp = d->m_pNodeList->indexOf(newChild); + + if (-1 == nValue) + { + return NULL; + } + else + { + if (-1 == nTemp) + { + d->m_pNodeList->insert(nValue, newChild); + d->m_pNodeList->deleteNode(nValue + 1); + } + else + { + d->m_pNodeList->deleteNode(newChild->name()); + d->m_pNodeList->insert(nValue, newChild); + d->m_pNodeList->deleteNode(nValue + 1); + } + } + } + + if (newChild != NULL) + { + newChild->AddRef(); + } + return newChild; +} + +IGLDXMLNode *CGLDXMLNode::insertAfter(IGLDXMLNode *newChild, IGLDXMLNode *refChild) +{ + Q_D(CGLDXMLNode); + if (!newChild) + { + return NULL; + } + else + { + int nValue = d->m_pNodeList->indexOf(refChild); + int nTemp = d->m_pNodeList->indexOf(newChild); + if (-1 == nValue) + { + if (-1 == nTemp) + { + d->m_pNodeList->insert(0, newChild); + } + else + { + d->m_pNodeList->deleteNode(newChild->name()); + d->m_pNodeList->insert(0, newChild); + } + } + else + { + if (-1 == nTemp) + { + d->m_pNodeList->insert(nValue + 1, newChild); + } + else + { + d->m_pNodeList->deleteNode(newChild->name()); + d->m_pNodeList->insert(nValue + 1, newChild); + } + } + } + + if (newChild != NULL) + { + newChild->AddRef(); + } + return newChild; +} + + +void CGLDXMLNode::setAsBoolean(bool value) +{ + Q_D(CGLDXMLNode); + if (value) + { + d->m_strValue = "true"; + } + else + { + d->m_strValue = "false"; + } +} + +void CGLDXMLNode::setAsFloat(double value) +{ + Q_D(CGLDXMLNode); + d->m_strValue = floatToStr(value); +} + +void CGLDXMLNode::setAsInt64(gint64 value) +{ + Q_D(CGLDXMLNode); + d->m_strValue = int64ToStr(value); +} + +void CGLDXMLNode::setAsInteger(int value) +{ + Q_D(CGLDXMLNode); + d->m_strValue = intToStr(value); +} + +void CGLDXMLNode::setAsString(const GString &value) +{ + Q_D(CGLDXMLNode); + d->m_strValue = encodeXMLString(value, contains(d->m_enOptions, XO_ENCODE_CRLF)); +} + +void CGLDXMLNode::setName(const GString &value) +{ + Q_D(CGLDXMLNode); + d->m_strName = value; +} + +void CGLDXMLNode::setNodeType(const EnXMLNodeType value) +{ + Q_D(CGLDXMLNode); + if (value != d->m_enNodeType) + { + d->m_enNodeType = value; + if (value != ELEMENT) + { + d->m_strName = c_gdefNodeName[d->m_enNodeType]; + } + } +} + +void CGLDXMLNode::setParent(IGLDXMLNode *value) +{ + Q_D(CGLDXMLNode); + if (d->m_pParent != value) + { + d->m_pParent = dynamic_cast(value); + } +} + +void CGLDXMLNode::setXML(const GString &value) +{ + Q_D(CGLDXMLNode); + int nLength = 0; + int nStart = 0; + int nEnd = value.length() - 1; + + nStart = getFirstNonCharIdx(value, ' ', nStart); + if (value.at(nStart) == '<') + { + ++nStart; + } + nEnd = getFirstNonCharIdx(value, ' ', nEnd, true); + + if (value.at(nEnd) == '>') + { + --nEnd; + } + + if (value.at(nEnd) == '/') + { + --nEnd; + } + + nStart = getFirstNonCharIdx(value, ' ', nStart); + nEnd = getFirstNonCharIdx(value, ' ', nEnd, true); + + int nSpacePos = 0; + nSpacePos = getFirstCharIdx(value, ' ', nStart); + + if ((nSpacePos > nStart) && (nSpacePos < nEnd)) + { + nLength = nSpacePos - nStart; + d->m_strName = value.mid(nStart, nLength); + d->m_pAttributes->setXml(value.mid(nSpacePos + 1, nEnd - nSpacePos)); + } + else + { + nLength = (nEnd - nStart) + 1; + d->m_strName = value.mid(nStart, nLength); + d->m_pAttributes->clear(); + } +} + +void CGLDXMLNode::loadFromStream(GStream *pStream) +{ + Q_D(CGLDXMLNode); + assert(pStream != NULL); + + d->m_pNodeList->clear(); + d->m_pAttributes->clear(); + + QString strBuffer = pStream->readAll(); + GXMLParser::execute(strBuffer, this, d->m_enOptions); +} + +void CGLDXMLNode::saveToStream(GStream *pStream) +{ + GXMLBuilder::saveNode(this, pStream); +} + +void CGLDXMLNode::setAttribute(const GString &name, const GString &value) +{ + Q_D(CGLDXMLNode); + CGLDXMLNodeAttribute *pAttr = d->m_pAttributes->itemsByNameObj(name); + pAttr->setAsString(value); +} + +void CGLDXMLNode::setAttribute(const GString &name, int value) +{ + Q_D(CGLDXMLNode); + CGLDXMLNodeAttribute *pAttr = d->m_pAttributes->itemsByNameObj(name); + pAttr->setAsInteger(value); +} + +GString CGLDXMLNode::attribute(const GString &name, const GString &defValue) +{ + Q_D(CGLDXMLNode); + if (hasAttribute(name)) + { + CGLDXMLNodeAttribute* oAttribute = d->m_pAttributes->itemsByNameObj(name); + return oAttribute->asString(); + } + else + { + return defValue; + } +} + +IGLDXMLDocument *CGLDXMLNode::ownerDocument() const +{ + Q_D(const CGLDXMLNode); + if (d->m_pOwnerDocument != NULL) + { + d->m_pOwnerDocument->AddRef(); + } + return d->m_pOwnerDocument; +} + +void CGLDXMLNode::setAsVariant(const GVariant value) +{ + Q_D(CGLDXMLNode); + //TODO + //d->m_strValue = GXMLUtils::base64Encode(value.toByteArray()); + d->m_strValue = value.toString(); +} + +void CGLDXMLNode::setText(const GString &value) +{ + Q_D(CGLDXMLNode); + d->m_strValue = value; +} + +IGLDXMLNode *CGLDXMLNode::toElement() const +{ + CGLDXMLNode *pNode = toElementObj(); + if (pNode != NULL) + { + pNode->AddRef(); + } + return pNode; +} + +bool CGLDXMLNode::isElement() const +{ + Q_D(const CGLDXMLNode); + if (d->m_enNodeType == ELEMENT) + { + return true; + } + else + { + return false; + } +} + +bool CGLDXMLNode::isNull() const +{ + //DO Nothing + return false; +} + +bool CGLDXMLNode::hasChildNodes() const +{ + Q_D(const CGLDXMLNode); + return d->m_pNodeList->count() > 0; +} + +IGLDXMLNode* CGLDXMLNode::parentNode() const +{ + return parent(); +} + +void CGLDXMLNode::setNodeValue(const GString &value) +{ + setAsString(value); +} + +IGLDXMLNode* CGLDXMLNode::firstChild() const +{ + Q_D(const CGLDXMLNode); + if (hasChildNodes()) + { + return d->m_pNodeList->node(0); + } + return NULL; +} + +IGLDXMLNode *CGLDXMLNode::lastChild() const +{ + Q_D(const CGLDXMLNode); + if (hasChildNodes()) + { + return d->m_pNodeList->node(d->m_pNodeList->count() - 1); + } + return NULL; +} + +void CGLDXMLNode::removeAttribute(const GString &name) +{ + Q_D(CGLDXMLNode); + int nIndex = d->m_pAttributes->indexOf(name); + if (nIndex > -1) + { + d->m_pAttributes->remove(nIndex); + } +} + +IGLDXMLNodeAttribute *CGLDXMLNode::setAttributeNode(IGLDXMLNodeAttribute *newAttr) +{ + Q_D(CGLDXMLNode); + GString attrName = newAttr->name(); + IGLDXMLNodeAttribute *pAttr = NULL; + if (hasAttribute(attrName)) + { + pAttr = d->m_pAttributes->itemsByNameObj(attrName); + pAttr->setAsString(newAttr->asString()); + } + else + { + pAttr = d->m_pAttributes->add(newAttr->name()); + pAttr->setAsString(newAttr->asString()); + } + + if (pAttr != NULL) + { + pAttr->AddRef(); + } + return pAttr; +} + +void CGLDXMLNode::clear() +{ + //Do Nothing +} + +//setXML中调用 +int CGLDXMLNode::getFirstNonCharIdx(const GString str, const GChar ch, int nOffSet, bool isReverse) +{ + int nLength = str.length(); + + assert(nOffSet >= 0); + assert(nOffSet < nLength); + if (!isReverse) + { + for (int i = nOffSet; i < nLength; ++i) + { + if (str.at(i) != ch) + return i; + } + } + else + { + for (int i = nOffSet; i >= 0; --i) + { + if (str.at(i) != ch) + return i; + } + } + return nOffSet; +} + +int CGLDXMLNode::getFirstCharIdx(const GString str, const GChar ch, int nOffSet, bool isReverse) +{ + int nLength = str.length(); + + assert(nOffSet >= 0); + assert(nOffSet < nLength); + if (!isReverse) + { + for (int i = nOffSet; i < nLength; ++i) + { + if (str.at(i) == ch) + return i; + } + } + else + { + for (int i = nOffSet; i >= 0; --i) + { + if (str.at(i) == ch) + return i; + } + } + return nOffSet; +} + +void CGLDXMLNode::elementsByTagName(CGLDXMLNodeList *list, CGLDXMLNode *parent, const GString &value) +{ + list->add(parent); + if (parent->hasChildNodes()) + { + for (int i = 0; i < parent->childNodesObj()->count(); ++i) + { + if (parent->childNodesObj()->nodeObj(i)->tagName() == value) + { + elementsByTagName(list, parent->childNodesObj()->nodeObj(i), value); + } + } + } +} + +CGLDXMLNode *CGLDXMLNode::nextSiblingObj() +{ + Q_D(CGLDXMLNode); + int nIndex = 0; + if (d->m_pParent == NULL) + return NULL; + else + { + nIndex = d->m_pParent->childNodesObj()->indexOf(this); + if (nIndex < d->m_pParent->childNodesObj()->count() - 1) + { + return d->m_pParent->childNodesObj()->nodeObj(nIndex + 1); + } + else + { + return NULL; + } + } + return NULL; +} + +CGLDXMLNode *CGLDXMLNode::prevSiblingObj() +{ + Q_D(CGLDXMLNode); + int nIndex = 0; + if (d->m_pParent == NULL) + { + return NULL; + } + else + { + nIndex = d->m_pParent->childNodesObj()->indexOf(this); + if (nIndex > 0) + { + return d->m_pParent->childNodesObj()->nodeObj(nIndex - 1); + } + else + { + return NULL; + } + } + return NULL; +} + +CGLDXMLNodeAttributes *CGLDXMLNode::attributesObj() +{ + Q_D(CGLDXMLNode); + return d->m_pAttributes; +} + +CGLDXMLNode *CGLDXMLNode::cloneNodeObj(bool deep) +{ + Q_D(CGLDXMLNode); + CGLDXMLNode *pNode = new CGLDXMLNode(NULL, d->m_enOptions, d->m_enNodeType, d->m_pOwnerDocument); + pNode->setName(d->m_strName); + pNode->setText(d->m_strValue); + pNode->attributesObj()->setXml(d->m_pAttributes->xml()); + if (!deep) + { + return pNode; + } + for (int i = 0; i < d->m_pNodeList->count(); ++i) + { + CGLDXMLNode *pSrcNode = d->m_pNodeList->nodeObj(i); + CGLDXMLNode *pDesNode = pSrcNode->cloneNodeObj(true); + pNode->childNodesObj()->add(pDesNode); + } + return pNode; +} + +CGLDXMLNode *CGLDXMLNode::toElementObj() const +{ + if (isElement()) + { + return const_cast(this); + } + else + { + return NULL; + } +} + +CGLDXMLNode *CGLDXMLNode::parentObj() const +{ + Q_D(const CGLDXMLNode); + return d->m_pParent; +} + +CGLDXMLNodeList *CGLDXMLNode::childNodesObj() const +{ + Q_D(const CGLDXMLNode); + return d->m_pNodeList; +} + +QString CGLDXMLNode::asJSON() +{ + //TODO + return ""; +} + +void CGLDXMLNode::setAsJSON(const GString &strValue) +{ + //TODO + G_UNUSED(strValue); +} + +GString CGLDXMLNode::nodeName() +{ + Q_D(CGLDXMLNode); + return d->m_strName; +} + +IGLDXMLNode* CGLDXMLNode::nextSiblingElement(const GString &tagName) +{ + for (CGLDXMLNode *pSib = nextSiblingObj(); pSib != NULL; pSib = pSib->nextSiblingObj()) { + if (pSib->isElement()) { + CGLDXMLNode *pElt = pSib->toElementObj(); + if (tagName.isEmpty() || sameStr(pElt->tagName(), tagName)) + { + pElt->AddRef(); + return pElt; + } + } + } + return NULL; +} + +IGLDXMLNode* CGLDXMLNode::appendChild(IGLDXMLNode *node) +{ + Q_D(CGLDXMLNode); + d->m_pNodeList->add(node); + if (node != NULL) + { + node->AddRef(); + } + return node; +} + +IGLDXMLNode* CGLDXMLNode::removeChild(IGLDXMLNode *node) +{ + Q_D(CGLDXMLNode); + for (int i = 0; i < d->m_pNodeList->count(); i++) + { + IGLDXMLNode *pNode = d->m_pNodeList->at(i); + if (pNode == node) + { + d->m_pNodeList->deleteNode(i); + break; + } + pNode->Release(); + } + return node; +} + +void CGLDXMLNode::setTagName(const GString &name) +{ + Q_D(CGLDXMLNode); + d->m_strName = name; +} + +GString CGLDXMLNode::tagName() +{ + Q_D(CGLDXMLNode); + return d->m_strName; +} + +IGLDXMLNodeList* CGLDXMLNode::elementsByTagName(const GString &value) +{ + Q_D(CGLDXMLNode); + CGLDXMLNodeList *pList = new CGLDXMLNodeList(); + for (int i = 0; i < d->m_pNodeList->count(); ++i) + { + if (d->m_pNodeList->nodeObj(i)->tagName() == value) + { + elementsByTagName(pList, d->m_pNodeList->nodeObj(i), value); + } + } + + if (pList != NULL) + { + pList->AddRef(); + } + return pList; +} + +IGLDXMLNode* CGLDXMLNode::toText() +{ + AddRef(); + return this; +} + +GString CGLDXMLNode::data() +{ + return nodeValue(); +} + +IGLDXMLNode *CGLDXMLNode::namedItem(const GString &name) const +{ + Q_D(const CGLDXMLNode); + for (int i = 0; i < d->m_pNodeList->count(); ++i) + { + if (d->m_pNodeList->nodeObj(i)->name() == name) + { + return d->m_pNodeList->at(i); + } + } + return NULL; +} +/**********************/ + +double xmlStringToFloat(const GString &str) +{ + int nPos = 0; + GString sBuffer = ""; + double result = 0.0; + + if (str.isEmpty()) + { + return 0.0; + } + // TODO + else if (g_CurrentDecimalSeparator != c_gdefXMLDecimalSeparator) + { + sBuffer = str; + nPos = posXMLString(c_gdefXMLDecimalSeparator, sBuffer); + + if (0 != nPos) + { + result = sBuffer.toDouble(); + } + } + else + { + result = str.toDouble(); + } + return result; +} + +int hashOf(const GString &value) +{ + int nResult = 0; + for (int nTemp = 0; nTemp < value.length(); ++nTemp) + { + GChar aChar; + aChar = value.at(nTemp); + if (aChar >= 'A' && aChar <= 'Z') + { + aChar.toLower(); + } + nResult = nResult<<2 | nResult>>(sizeof(nResult) * 8 - 2) ^ int (aChar.toLatin1()); + } + return nResult; +} + +class CGLDXMLNodeAttributePrivate +{ +public: + CGLDXMLNodeAttributePrivate(CGLDXMLNodeAttribute *parent) + : q_ptr(parent) + { + } + +private: + CGLDXMLNodeAttribute * const q_ptr; + Q_DECLARE_PUBLIC(CGLDXMLNodeAttribute); + + GString m_strName; + GString m_strValue; + int m_hashData; + EnTXMLOptions m_options; +}; + +CGLDXMLNodeAttribute::CGLDXMLNodeAttribute(const GString &name, EnTXMLOptions options) + : d_ptr(new CGLDXMLNodeAttributePrivate(this)) +{ + Q_D(CGLDXMLNodeAttribute); + d->m_strName = name; + d->m_strValue = ""; + d->m_options = options; + d->m_hashData = hashOf(name); +} + +CGLDXMLNodeAttribute::~CGLDXMLNodeAttribute() +{ + Q_D(CGLDXMLNodeAttribute); + freePtr(d); +} + +void CGLDXMLNodeAttribute::setXml(const GString &strXML) +{ + Q_D(CGLDXMLNodeAttribute); + int nPos = posExcludeQuotationMark('=', strXML); + + if (-1 == nPos) + { + d->m_strName = strXML; + d->m_strValue = ""; + } + else + { + d->m_strName = strXML.mid(0, nPos - 1); + d->m_strName = d->m_strName.trimmed(); + d->m_strValue = copyTrimSpaceAndQuotaionMark(strXML, nPos + 1); + } + d->m_hashData = hashOf(d->m_strName); +} + +void CGLDXMLNodeAttribute::setNodeValue(const GString &value) +{ + setAsString(value); +} + +GString CGLDXMLNodeAttribute::copyTrimSpaceAndQuotaionMark(const GString &str, int index) +{ + int nLength = str.length(); + int nIndex = index; + GString result; + + while ((nIndex <= nLength) && str[nIndex] <= ' ') + { + nIndex++; + } + if ((nIndex <= nLength) && (str[nIndex] == '"')) + { + nIndex++; + } + if (nIndex > nLength) + { + result = ""; + } + else + { + while (str[nLength - 1] <= ' ') + { + nLength--; + } + if ((nLength > 0) && (str[nLength - 1] == '"')) + { + nLength--; + } + result = str.mid(nIndex, nLength - nIndex + 1); + } + result = result.trimmed(); + + return result; +} + +void CGLDXMLNodeAttribute::setText(const GString &strText) +{ + Q_D(CGLDXMLNodeAttribute); + d->m_strValue = strText; +} + +void CGLDXMLNodeAttribute::setName(const GString &strName) +{ + Q_D(CGLDXMLNodeAttribute); + d->m_strName = strName.trimmed(); + d->m_hashData = hashOf(strName); +} + +void CGLDXMLNodeAttribute::setAsVariant(const GVariant value) +{ + Q_D(CGLDXMLNodeAttribute); + d->m_strValue = base64Encode(value.toByteArray()); +} + +void CGLDXMLNodeAttribute::setAsString(const GString &value) +{ + Q_D(CGLDXMLNodeAttribute); + d->m_strValue = encodeXMLString(value, contains(d->m_options, XO_ENCODE_CRLF)); +} + +void CGLDXMLNodeAttribute::setAsInteger(int value) +{ + Q_D(CGLDXMLNodeAttribute); + d->m_strValue = intToStr(value); +} + +void CGLDXMLNodeAttribute::setAsInt64(gint64 value) +{ + Q_D(CGLDXMLNodeAttribute); + d->m_strValue = int64ToStr(value); +} + +void CGLDXMLNodeAttribute::setAsFloat(double value) +{ + Q_D(CGLDXMLNodeAttribute); + d->m_strValue = floatToStr(value); +} + +void CGLDXMLNodeAttribute::setAsBoolean(bool value) +{ + Q_D(CGLDXMLNodeAttribute); + d->m_strValue = boolToXMLString(value); +} + +GString CGLDXMLNodeAttribute::xml() +{ + Q_D(const CGLDXMLNodeAttribute); + return GString("%1=\"%2\"").arg(d->m_strName).arg(d->m_strValue); +} + +GString CGLDXMLNodeAttribute::nodeName() const +{ + Q_D(const CGLDXMLNodeAttribute); + return d->m_strName; +} + +CGLDXMLNodeAttribute* CGLDXMLNodeAttribute::toAttr() +{ + AddRef(); + return this; +} + +GString CGLDXMLNodeAttribute::value() +{ + return asString(); +} + +GString CGLDXMLNodeAttribute::nodeValue() +{ + return asString(); +} + +GString CGLDXMLNodeAttribute::text() +{ + Q_D(CGLDXMLNodeAttribute); + return d->m_strValue; +} + +GString CGLDXMLNodeAttribute::name() +{ + Q_D(CGLDXMLNodeAttribute); + return d->m_strName; +} + +int CGLDXMLNodeAttribute::hashData() +{ + Q_D(CGLDXMLNodeAttribute); + return d->m_hashData; +} + +GVariant CGLDXMLNodeAttribute::asVariant() +{ + Q_D(CGLDXMLNodeAttribute); + return base64Decode(d->m_strValue.toLocal8Bit()); +} + +GString CGLDXMLNodeAttribute::asString() +{ + Q_D(CGLDXMLNodeAttribute); + return decodeXMLString(d->m_strValue, contains(d->m_options, XO_DECODE_CRLF)); +} + +int CGLDXMLNodeAttribute::asInteger() +{ + Q_D(CGLDXMLNodeAttribute); + return strToInt(d->m_strValue); +} + +gint64 CGLDXMLNodeAttribute::asInt64() +{ + Q_D(CGLDXMLNodeAttribute); + return strToInt64(d->m_strValue); +} + +double CGLDXMLNodeAttribute::asFloat() +{ + Q_D(CGLDXMLNodeAttribute); + return strToFloat(d->m_strValue); +} + +bool CGLDXMLNodeAttribute::asBoolean() +{ + Q_D(CGLDXMLNodeAttribute); + return strToBool(d->m_strValue); +} + +class CGLDXMLDocumentPrivate +{ +public: + CGLDXMLDocumentPrivate(CGLDXMLDocument *parent) + : q_ptr(parent), m_pRoot(NULL), m_bAutoIndent(true), m_bIncludeHeader(true), + m_strEncoding("utf-8"), m_strVersion("1.0"), m_enOptionsSet(0) + { + } + +private: + CGLDXMLDocument * const q_ptr; + Q_DECLARE_PUBLIC(CGLDXMLDocument); + + CGLDXMLNode *m_pRoot; + bool m_bAutoIndent; + bool m_bIncludeHeader; + GString m_strEncoding; + GString m_strFileName; + GString m_strVersion; + EnTXMLOptions m_enOptionsSet; +}; + +CGLDXMLDocument::CGLDXMLDocument() : d_ptr(new CGLDXMLDocumentPrivate(this)) +{ +} + +CGLDXMLDocument::~CGLDXMLDocument() +{ + Q_D(CGLDXMLDocument); + freeAndNilIntf(d->m_pRoot); + + freePtr(d); +} + +IGLDXMLNode *CGLDXMLDocument::createElement(const GString &name) +{ + CGLDXMLNode *pXMLNode = createNodeObj(name); + if (pXMLNode) + { + pXMLNode->AddRef(); + } + return pXMLNode; +} + +IGLDXMLNode *CGLDXMLDocument::createNode(const GString &name, EnXMLNodeType type ) +{ + CGLDXMLNode *pXMLNode = createNodeObj(name, type); + if (pXMLNode) + { + pXMLNode->AddRef(); + } + return pXMLNode; +} + +bool CGLDXMLDocument::isEmpty() +{ + Q_D(CGLDXMLDocument); + return !d->m_pRoot; +} + +void CGLDXMLDocument::loadFromFile(const GString &fileName) +{ + Q_D(CGLDXMLDocument); + GFileStream oStream(fileName); + if (oStream.open(QIODevice::ReadOnly)) + { + try + { + oStream.seek(0); + loadFromStream(&oStream); + d->m_strFileName = fileName; + } + catch(...) + { + oStream.close(); + throw; + } + oStream.close(); + } +} + +void CGLDXMLDocument::saveToFile(const GString &fileName) +{ + GFileStream oStream(fileName); + if (oStream.open(QIODevice::WriteOnly)) + { + try + { + saveToStream(&oStream); + } + catch (...) + { + oStream.close(); + throw; + } + oStream.close(); + } +} + +void CGLDXMLDocument::loadFromStream(GStream *stream) +{ + loadFromStream(stream, false); +} + +void CGLDXMLDocument::loadFromStream(GStream *stream, bool useUtf8Optimize) +{ + assert(stream != NULL); + assert(stream->isOpen()); + // TODO + GString strData; + GString strEncoding; + bool bBOM = false; + + Q_D(CGLDXMLDocument); + int nSize = stream->size() - stream->pos(); + GByteArray strBuffer; + strBuffer.resize(nSize); + stream->read(strBuffer.data(), nSize); + + bool bEncode = findEncoding(strBuffer, bBOM, strEncoding); + if (bEncode && (!strEncoding.isEmpty())) + { + d->m_strEncoding = strEncoding; + } +// else if (!bEncode && (strEncoding.isEmpty())) +// { +// d->m_strEncoding = ""; +// } + if (sameText(d->m_strEncoding, c_uft8Encoding)) + { + if (useUtf8Optimize) + { + strBuffer = ""; + stream->seek(0); + strData = utf8StreamDecode(stream); + } + else + { + strData = utf8ToUnicode(strBuffer.data()); + } + } + else + { + strData = asciiToUnicode(strBuffer); + } + strBuffer = ""; + parse(strData, 0); +// if (d->m_strEncoding.length() == 0) +// { +// d->m_strEncoding = "utf-8"; +// } +} + +void CGLDXMLDocument::saveToStream(GStream *stream) +{ + GXMLBuilder::saveDoc(this, stream); +} + +GString CGLDXMLDocument::getXMLHeader() +{ + GString strVersion; + + Q_D(CGLDXMLDocument); + if (d->m_strVersion.isEmpty()) + { + strVersion = c_gconAttribFmt.arg(c_gconVersion, c_gdefVersion); + } + else + { + strVersion = c_gconAttribFmt.arg(c_gconVersion, d->m_strVersion); + } + + GString strEncoding; + if (!d->m_strEncoding.isEmpty()) + { + strEncoding = c_gconAttribFmt.arg(c_gconEncoding, d->m_strEncoding); + } + else + { + strEncoding = ""; + } + + if (strEncoding.isEmpty()) + return c_gconSpecificationFmt.arg(strVersion); + else + return c_gconSpecificationFmtEx.arg(strVersion, strEncoding); +} + +IGLDXMLNode *CGLDXMLDocument::appendChild(IGLDXMLNode *newChild) +{ + //TODO + Q_D(CGLDXMLDocument); + if (d->m_pRoot) + { + xmlDocError(c_grsErrInvalidRootNode); + } + else + { + d->m_pRoot = dynamic_cast(newChild); + if (d->m_pRoot) + { + d->m_pRoot->AddRef(); + d->m_pRoot->AddRef(); + } + return d->m_pRoot; + } + return NULL; +} + +IGLDXMLNode *CGLDXMLDocument::firstChild() const +{ + Q_D(const CGLDXMLDocument); + d->m_pRoot->AddRef(); + return d->m_pRoot; +} + +void CGLDXMLDocument::save(GStream *stream, int indent) const +{ + G_UNUSED(indent); + GXMLBuilder::saveDoc(const_cast(this), stream); +} + +bool CGLDXMLDocument::setContent(GStream *dev, GString *errorMsg, int *errorLine, int *errorColumn) +{ + G_UNUSED(errorMsg); + G_UNUSED(errorLine); + G_UNUSED(errorColumn); + try + { + loadFromStream(dev); + } + catch (...) + { + throw; + } + return true; +} + +bool CGLDXMLDocument::setContent(const GString &text, bool namespaceProcessing, GString *errorMsg, int *errorLine, int *errorColumn) +{ + G_UNUSED(namespaceProcessing); + return setContent(text.toUtf8(), errorMsg, errorLine, errorColumn); +} + +bool CGLDXMLDocument::setContent(const QString &text, QString *errorMsg, int *errorLine, int *errorColumn) +{ + return setContent(text, false, errorMsg, errorLine, errorColumn); +} + +bool CGLDXMLDocument::setContent(const QByteArray &text, QString *errorMsg, int *errorLine, int *errorColumn) +{ + G_UNUSED(errorMsg); + G_UNUSED(errorLine); + G_UNUSED(errorColumn); + GBlockMemoryStream pMemoryStream; + pMemoryStream.write(text.data(), text.length()); + pMemoryStream.seek(0); + loadFromStream(&pMemoryStream); + return true; +} + +IGLDXMLNodeAttribute* CGLDXMLDocument::createAttribute(const QString &name) +{ + CGLDXMLNodeAttribute *pNodeAttributr = new CGLDXMLNodeAttribute(name, ELEMENT); + if (pNodeAttributr != NULL) + { + pNodeAttributr->AddRef(); + } + return pNodeAttributr; +} + +IGLDXMLNode *CGLDXMLDocument::createTextNode(const GString &data) +{ + Q_D(CGLDXMLDocument); + CGLDXMLNode *pNode = new CGLDXMLNode(NULL, d->m_enOptionsSet, TEXT, this); + pNode->setName("#text"); + pNode->setAsString(data); + + if (pNode != NULL) + { + pNode->AddRef(); + } + return pNode; +} + +IGLDXMLNodeList *CGLDXMLDocument::childNodes() const +{ + Q_D(const CGLDXMLDocument); + return d->m_pRoot->childNodes(); +} + +void CGLDXMLDocument::clear() +{ + //Do Nothing +} + +bool CGLDXMLDocument::autoIndent() +{ + Q_D(CGLDXMLDocument); + return d->m_bAutoIndent; +} + +void CGLDXMLDocument::setAutoIndent(bool value) +{ + Q_D(CGLDXMLDocument); + d->m_bAutoIndent = value; +} + +GString CGLDXMLDocument::displayText() +{ + return GXMLBuilder::saveDocText(this, false); +} + +IGLDXMLNode *CGLDXMLDocument::documentElement() const +{ + Q_D(const CGLDXMLDocument); + if (d->m_pRoot != NULL) + { + d->m_pRoot->AddRef(); + } + return d->m_pRoot; +} + +GString CGLDXMLDocument::encoding() +{ + Q_D(CGLDXMLDocument); + return d->m_strEncoding; +} + +void CGLDXMLDocument::setEncoding(const GString &value) +{ + Q_D(CGLDXMLDocument); + d->m_strEncoding = value; +} + +GString CGLDXMLDocument::fileName() +{ + Q_D(CGLDXMLDocument); + return d->m_strFileName; +} + +void CGLDXMLDocument::setFileName(const GString &value) +{ + Q_D(CGLDXMLDocument); + d->m_strFileName = value; +} + +bool CGLDXMLDocument::includeHeader() +{ + Q_D(CGLDXMLDocument); + return d->m_bIncludeHeader; +} + +void CGLDXMLDocument::setIncludeHeader(bool value) +{ + Q_D(CGLDXMLDocument); + d->m_bIncludeHeader = value; +} + +EnTXMLOptions CGLDXMLDocument::options() +{ + Q_D(CGLDXMLDocument); + return EnTXMLOptions(d->m_enOptionsSet); +} + +void CGLDXMLDocument::setOptions(EnTXMLOptions xmlOptionsSet) +{ + Q_D(CGLDXMLDocument); + d->m_enOptionsSet = xmlOptionsSet; +} + +GString CGLDXMLDocument::version() +{ + Q_D(CGLDXMLDocument); + return d->m_strVersion; +} + +void CGLDXMLDocument::setVersion(const GString &value) +{ + Q_D(CGLDXMLDocument); + d->m_strVersion = value; +} + +GString CGLDXMLDocument::xml() +{ + return GXMLBuilder::saveDocText(this, true); +} + +void CGLDXMLDocument::setXML(const GString &value) +{ + parse(value, 0); +} + +IGLDXMLNode *CGLDXMLDocument::root() +{ + return documentElement(); +} + +void CGLDXMLDocument::setRoot(IGLDXMLNode *root) +{ + Q_D(CGLDXMLDocument); + d->m_pRoot = dynamic_cast(root); + if (d->m_pRoot != NULL) + { + d->m_pRoot->AddRef(); + } +} + +IGLDXMLNode* CGLDXMLDocument::toElement() const +{ + return NULL; +} + +bool CGLDXMLDocument::isNull() const +{ + Q_D(const CGLDXMLDocument); + //DO Nothing + if (d->m_pRoot == NULL) + { + return true; + } + return false; +} + +GString CGLDXMLDocument::toString(int indent) const +{ + GBlockMemoryStream pStream; + save(&pStream, indent); + pStream.seek(0); + QString str = GString::fromUtf8(pStream.readAll()); + + return str; +} + +IGLDXMLNode *CGLDXMLDocument::elementById(const GString &elementID) +{ + G_UNUSED(elementID); + //DO Nothing + return NULL; +} + +IGLDXMLNode *CGLDXMLDocument::firstChildElement(const GString &tagName) const +{ + Q_D(const CGLDXMLDocument); + if (tagName.isEmpty() || sameText(d->m_pRoot->tagName(), tagName)) + { + d->m_pRoot->AddRef(); + return d->m_pRoot; + } + else + { + return NULL; + } +} + +GString CGLDXMLDocument::asJSON() +{ + //TODO + return NULL; +} + +void CGLDXMLDocument::setAsJSON(const GString &value) +{ + //TODO + G_UNUSED(value); +} + +void CGLDXMLDocument::loadFromJSONFile(const GString &fileName) +{ + //TODO + G_UNUSED(fileName); +} + +void CGLDXMLDocument::loadFromJSONStream(GStream *stream) +{ + //TODO + G_UNUSED(stream); +} + +void CGLDXMLDocument::saveAsJSONToFile(const GString &fileName) +{ + //TODO + G_UNUSED(fileName); +} + +void CGLDXMLDocument::saveAsJSONToStream(GStream *stream) +{ + //TODO + G_UNUSED(stream); +} + +CGLDXMLNode *CGLDXMLDocument::createNodeObj(const GString &name, EnXMLNodeType type) +{ + Q_D(CGLDXMLDocument); + CGLDXMLNode *pNode = new CGLDXMLNode(NULL, d->m_enOptionsSet, type, this); + pNode->setName(name); + return pNode; +} + +void CGLDXMLDocument::setRootObj(CGLDXMLNode *root) +{ + Q_D(CGLDXMLDocument); + d->m_pRoot = root; +} + +CGLDXMLNode *CGLDXMLDocument::rootObj() +{ + Q_D(CGLDXMLDocument); + return d->m_pRoot; +} + +bool CGLDXMLDocument::findEncoding(const char *data, bool &bom, GString &enCoding) +{ + //TODO + bom = false; + GString strData = GString::fromLatin1(data); + + if (strData.isEmpty()) + { + return false; + } + + int nIndex = 0; + int nLength = strData.length(); + QString str = QString::fromLatin1(c_gdefXMLUtf8Header); + + if (strData.startsWith(str)) + { + enCoding = c_uft8Encoding; + bom = true; + return true; + } + + while (nIndex < nLength && ((strData.at(nIndex) == '\n') + || (strData.at(nIndex) == '\t') + || (strData.at(nIndex) == '\r') + || (strData.at(nIndex) == ' '))) + { + ++nIndex; + } + + if (nIndex >= nLength) + { + return false; + } + + if (strData.indexOf(c_gdefXMLDataHeader, nIndex) != nIndex) + { + return false; + } + + int nStart = strData.indexOf(c_gdefEncodingPrex, nIndex); + + if (-1 == nStart) + { + return true; + } + else + { + nStart = nStart + c_gdefEncodingPrex.length(); + } + + int nEnd = strData.indexOf("\"", nStart + 1); // to test enconding=""测试空还是未找到 + + if (-1 == nEnd) + { + return true; + } + + enCoding = strData.mid(nStart, nEnd - nStart); + return true; +} + +void CGLDXMLDocument::parse(const GString &data, int pos) +{ + Q_D(CGLDXMLDocument); + d->m_pRoot = NULL; + d->m_strVersion = c_gdefVersion; + GXMLParser::execute(data, this, pos); +} + +class CGLDXMLNodeAttributesPrivate +{ +public: + CGLDXMLNodeAttributesPrivate(CGLDXMLNodeAttributes *parent) + : q_ptr(parent) + { + } + +private: + CGLDXMLNodeAttributes * const q_ptr; + Q_DECLARE_PUBLIC(CGLDXMLNodeAttributes); + + EnTXMLOptions m_options; + GInterfaceObjectList m_list; +}; + +CGLDXMLNodeAttributes::CGLDXMLNodeAttributes(EnTXMLOptions enOptions) + : d_ptr(new CGLDXMLNodeAttributesPrivate(this)) +{ + Q_D(CGLDXMLNodeAttributes); + d->m_options = enOptions; +} + +CGLDXMLNodeAttributes::~CGLDXMLNodeAttributes() +{ +} + +/*新增属性*/ +IGLDXMLNodeAttribute *CGLDXMLNodeAttributes::add(const GString &strName) +{ + CGLDXMLNodeAttribute *pAttribute = addObj(strName); + if (pAttribute != NULL) + { + pAttribute->AddRef(); + } + return pAttribute; +} + +/*通过属性名查找相应的索引*/ +int CGLDXMLNodeAttributes::indexOf(const GString &strName) +{ + Q_D(CGLDXMLNodeAttributes); + CGLDXMLNodeAttribute *pXmlNodeAttribute = NULL; + int nResult = -1; + if (!d->m_list.isEmpty()) + { + for (nResult = 0; nResult < d->m_list.length(); ++nResult) + { + pXmlNodeAttribute = itemObj(nResult); + if (strName == pXmlNodeAttribute->name()) + { + return nResult; + } + } + return -1; + } + else + { + return -1; + } +} + +/*属性的个数*/ +int CGLDXMLNodeAttributes::count() +{ + Q_D(CGLDXMLNodeAttributes); + return d->m_list.count(); +} + +/*清空属性个数*/ +void CGLDXMLNodeAttributes::clear() +{ + Q_D(CGLDXMLNodeAttributes); + d->m_list.clear(); +} + +/*删除某个属性*/ +void CGLDXMLNodeAttributes::remove(int index) +{ + Q_D(CGLDXMLNodeAttributes); + if (index >=0 && index < d->m_list.count()) + { + d->m_list.removeAt(index); + } +} + +/*取得某个属性*/ +IGLDXMLNodeAttribute *CGLDXMLNodeAttributes::item(int index) +{ + CGLDXMLNodeAttribute *pAttribute = itemObj(index); + if (pAttribute != NULL) + { + pAttribute->AddRef(); + } + return pAttribute; +} + +/*通过属性名取得相应属性*/ +IGLDXMLNodeAttribute *CGLDXMLNodeAttributes::itemsByName(const GString &strName) +{ + CGLDXMLNodeAttribute *pXmlNodeAttribute = itemsByNameObj(strName); + if (pXmlNodeAttribute != NULL) + { + pXmlNodeAttribute->AddRef(); + } + return pXmlNodeAttribute; +} + +bool CGLDXMLNodeAttributes::contains(const GString &name) +{ + return indexOf(name) != -1; +} + +IGLDXMLNodeAttribute *CGLDXMLNodeAttributes::namedItem(const GString &name) +{ + return itemsByName(name); +} + +/*读取属性值*/ +GString CGLDXMLNodeAttributes::xml() +{ + Q_D(CGLDXMLNodeAttributes); + GString result; + for (int i = 0; i < d->m_list.length(); ++i) + { + result.append(d->m_list.at(i)->xml()).append(' '); + } + if (!result.isEmpty()) + { + result = result.mid(0, result.length() - 1); + } + return result; +} + +/*设置属性值*/ +void CGLDXMLNodeAttributes::setXml(const GString &value) +{ + int nPos = 0; + int nIndex = 0; + int nLength = value.length(); + GString sValue = trimSpecialChar(value); + GString strText = ""; + clear(); + while (nIndex < nLength) + { + nPos = posExcludeQuotationMark('=', sValue, nIndex); + if (nPos != 0) + { + GString strName = copyTrimXMLString(sValue, nIndex, nPos - 1); + nIndex = nPos + 1; + if(findQuotationStr(sValue, nIndex, strText, nPos)) + { + doAddAttribute(strName, strText); + nIndex = nPos + 1; + } + else + { + break; + } + } + else + { + break; + } + } +} + +/*取出末尾的特殊字符*/ +GString CGLDXMLNodeAttributes::trimSpecialChar(const GString &value) +{ + GString sValue = value; + int nLength = sValue.length() - 1; + while (nLength >= 0 && (sValue[nLength] == '\r' || sValue[nLength] == '\n' || sValue[nLength] == ' ' + || sValue[nLength] == '\t')) + { + --nLength; + } + return sValue.mid(0, nLength + 1); +} + +int CGLDXMLNodeAttributes::hashOf(const GString &strName) +{ + int nResult = 0; + GChar cChar ; + for (int i = 0; i < strName.length(); ++i) + { + cChar = strName[i].toLatin1(); + if (cChar >= 'A' && cChar <= 'Z') + { + cChar = cChar.toLower() ; + } + nResult = (nResult << 2) | (nResult >> (sizeof(nResult) * 8 - 2)) ^ cChar.digitValue(); + } + return nResult; +} + +/*新增属性*/ +void CGLDXMLNodeAttributes::doAddAttribute(const GString &strName, const GString &strText) +{ + Q_D(CGLDXMLNodeAttributes); + CGLDXMLNodeAttribute *pXmlNodeAttribute = NULL; + if (strName.length() == 0) + { + return; + } + int nIndex = indexOf(strName); + if (nIndex != -1) + { + pXmlNodeAttribute = d->m_list.at(nIndex); + } + else + { + pXmlNodeAttribute = new CGLDXMLNodeAttribute(strName, d->m_options); + d->m_list.append(pXmlNodeAttribute); + } + pXmlNodeAttribute->setText(strText); + +} + +/*处理字符 '与"*/ +bool CGLDXMLNodeAttributes::findQuotationStr(const GString &str, int nstartPos, GString &squotedString, int &nendPos) +{ + //检查参数合法性 + if (str.isEmpty()) + { + return false; + } + if (nstartPos < 0) + { + nstartPos = 0; + } + else if (nstartPos > str.length()) + { + nstartPos = str.length(); + } + + //找到第一个引号的位置,并确定是单引号还是双引号 + GChar cStartChar = '\0'; + int nStartPos = nstartPos; + for(int i = nstartPos; i < str.length(); i++) + { + if(str[i] == '\"' || str[i] == '\'') + { + cStartChar = str[i]; + nStartPos = i; + break; + } + } + if(cStartChar == '\0') + return false; + for(int i = nStartPos + 1; i < str.length(); i++) + { + //确定单引号还是双引号之后,另一种引号被忽略 + if(str[i] == cStartChar) + { + nendPos = i; + squotedString = str.mid(nStartPos + 1, nendPos - nStartPos - 1); + return true; + } + } + return false; +} + +CGLDXMLNodeAttribute *CGLDXMLNodeAttributes::itemsByNameObj(const GString &strName) +{ + Q_D(CGLDXMLNodeAttributes); + CGLDXMLNodeAttribute *pXmlNodeAttribute = NULL; + int nIndex = indexOf(strName); + if (nIndex != -1) + { + pXmlNodeAttribute = d->m_list.at(nIndex); + } + else + { + pXmlNodeAttribute = new CGLDXMLNodeAttribute(strName, d->m_options); + d->m_list.append(pXmlNodeAttribute); + } + return pXmlNodeAttribute; +} + +CGLDXMLNodeAttribute *CGLDXMLNodeAttributes::addObj(const GString &strName) +{ + Q_D(CGLDXMLNodeAttributes); + CGLDXMLNodeAttribute *pXmlNodeAttribute = NULL; + int nIndex = indexOf(strName); //查找是否已经存在strName的属性; + if (nIndex != -1) //判断,有则赋值,没有则new一个; + { + pXmlNodeAttribute = d->m_list.at(nIndex); + } + else + { + pXmlNodeAttribute = new CGLDXMLNodeAttribute(strName, d->m_options); + d->m_list.append(pXmlNodeAttribute); + } + return pXmlNodeAttribute; +} + +CGLDXMLNodeAttribute *CGLDXMLNodeAttributes::itemObj(int nIndex) +{ + Q_D(CGLDXMLNodeAttributes); + if (d->m_list.isEmpty()) + { + return NULL; + } + else + { + CGLDXMLNodeAttribute *pAttribute = d->m_list.at(nIndex); + return pAttribute; + } +} + +class CGLDXMLNodeListPrivate +{ +public: + CGLDXMLNodeListPrivate(CGLDXMLNodeList *parent) + : q_ptr(parent), m_parent(NULL) + { + } + +private: + CGLDXMLNodeList * const q_ptr; + Q_DECLARE_PUBLIC(CGLDXMLNodeList); + + GInterfaceObjectList m_list; + CGLDXMLNode *m_parent; +}; + +CGLDXMLNodeList::CGLDXMLNodeList(IGLDXMLNode *parent) : d_ptr(new CGLDXMLNodeListPrivate(this)) +{ + Q_D(CGLDXMLNodeList); + d->m_parent = dynamic_cast(parent); +} + +CGLDXMLNodeList::~CGLDXMLNodeList() +{ + Q_D(CGLDXMLNodeList); + freePtr(d); +} + +int CGLDXMLNodeList::add(IGLDXMLNode *node) +{ + Q_D(CGLDXMLNodeList); + if (node == NULL) + { + return -1; + } + else + { + d->m_list.append(dynamic_cast(node)); + node->setParent(d->m_parent); + return d->m_list.count() - 1; + } +} + +int CGLDXMLNodeList::deleteNode(const GString &name) +{ + int nIndex = indexOf(name); + if (nIndex != -1) + { + deleteNode(nIndex); + } + return nIndex; +} + +void CGLDXMLNodeList::deleteNode(int index) +{ + Q_D(CGLDXMLNodeList); + d->m_list.removeAt(index); +} + +IGLDXMLNode *CGLDXMLNodeList::findNode(const GString &name) +{ + CGLDXMLNode *piNode = findNodeObj(name); + if (piNode != NULL) + { + piNode->AddRef(); + } + return piNode; +} + +IGLDXMLNode *CGLDXMLNodeList::at(int index) +{ + if(count() <= index) + { + return NULL; + } + + CGLDXMLNode *pNode = nodeObj(index); + if (pNode != NULL) + { + pNode->AddRef(); + } + return pNode; +} + +IGLDXMLNode *CGLDXMLNodeList::item(int index) +{ + if(count() <= index) + { + return NULL; + } + + CGLDXMLNode *pNode = nodeObj(index); + if (pNode != NULL) + { + pNode->AddRef(); + } + return pNode; +} + +int CGLDXMLNodeList::indexOf(IGLDXMLNode *node) const +{ + Q_D(const CGLDXMLNodeList); + return d->m_list.indexOf(dynamic_cast(node)); +} + +int CGLDXMLNodeList::indexOf(const GString &name) const +{ + Q_D(const CGLDXMLNodeList); + int result = -1; + int j = d->m_list.count(); + for (int i = 0; i < j; ++i) + { + if (name.isEmpty() || sameText(name, d->m_list.at(i)->name())) + { + result = i; + break; + } + } + return result; +} + +int CGLDXMLNodeList::remove(IGLDXMLNode *node) +{ + Q_D(CGLDXMLNodeList); + CGLDXMLNode *pNode = dynamic_cast(node); + if (NULL == pNode) + { + return -1; + } + int result = -1; + result = d->m_list.indexOf(pNode); + if (result > -1) + { + d->m_list.removeAt(result); + return result; + } + return result; +} + +void CGLDXMLNodeList::clear() +{ + Q_D(CGLDXMLNodeList); + for (int i = d->m_list.count()-1; i >= 0; --i) + { + deleteNode(i); + } +} + +void CGLDXMLNodeList::exChange(int cureIndex, int newIndex) +{ + Q_D(CGLDXMLNodeList); + if ((cureIndex > -1) && (cureIndex < d->m_list.count())) + { + if ((newIndex > -1) && (newIndex < d->m_list.count())) + { + d->m_list.swap(cureIndex, newIndex); + } + } +} + +void CGLDXMLNodeList::insert(int index, IGLDXMLNode* node) +{ + Q_D(CGLDXMLNodeList); + CGLDXMLNode *pNode = dynamic_cast(node); + if (pNode != NULL) + { + d->m_list.insert(index, pNode); + pNode->setParent(d->m_parent); + } +} + +int CGLDXMLNodeList::count() const +{ + Q_D(const CGLDXMLNodeList); + return d->m_list.count(); +} + +IGLDXMLNode *CGLDXMLNodeList::node(int index) +{ + CGLDXMLNode *pNode = nodeObj(index); + if (pNode != NULL) + { + pNode->AddRef(); + } + return pNode; +} + +IGLDXMLNode *CGLDXMLNodeList::nodeByName(const GString &name) +{ + CGLDXMLNode *pNode = findNodeObj(name); + if (pNode != NULL) + { + pNode->AddRef(); + } + return pNode; +} + +CGLDXMLNode *CGLDXMLNodeList::nodeObj(int index) +{ + Q_D(CGLDXMLNodeList); + if ((index < d->m_list.count()) && (index > -1)) + { + return d->m_list.at(index); + } + return NULL; +} + +CGLDXMLNode *CGLDXMLNodeList::findNodeObj(const GString &name) const +{ + Q_D(const CGLDXMLNodeList); + int nIndex = indexOf(name); + if (-1 == nIndex) + { + return NULL; + } + else + { + return d->m_list.at(nIndex); + } +} + +void CGLDXMLNodeList::move(int cureIndex, int newIndex) +{ + Q_D(CGLDXMLNodeList); + if ((cureIndex > -1) && (cureIndex < d->m_list.count())) + { + if ((newIndex > -1) && (newIndex < d->m_list.count())) + { + d->m_list.move(cureIndex, newIndex); + } + } +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDXMLParser.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDXMLParser.cpp new file mode 100644 index 00000000..6ee0060c --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDXMLParser.cpp @@ -0,0 +1,364 @@ +#include "GLDXMLParser.h" +#include "GLDXMLUtils.h" + +const int c_gconCDataMinLength = c_gconCDataPosx.length() + c_gconCDataPrex.length(); +const GString c_grsErrTagNotMatch = TRANS_STRING("XML 标识符号不匹配"); +const GString c_grsErrParserMsgFmt = TRANS_STRING("%1,错误位置 %2"); + +class GXMLParserPrivate +{ +public: + GXMLParserPrivate(GXMLParser *parent) + : q_ptr(parent), m_base(NULL), m_pos(0), m_currentNode(NULL) + , m_index(-1), m_temp(NULL), m_document(NULL) + { + } + +private: + GXMLParser * const q_ptr; + Q_DECLARE_PUBLIC(GXMLParser); + + CGLDXMLNode *m_base; + int m_pos; + CGLDXMLNode *m_currentNode; + GString m_data; + int m_index; + GString m_encoding; + GString m_version; + EnTXMLOptions m_options; + CGLDXMLNode *m_temp; + CGLDXMLDocument *m_document; +}; + +GXMLParser::GXMLParser(const GString strData, IGLDXMLNode *pBase, EnTXMLOptions vOptions) + : d_ptr(new GXMLParserPrivate(this)) +{ + Q_D(GXMLParser); + d->m_base = dynamic_cast(pBase); + d->m_options = vOptions; + d->m_currentNode = NULL; + d->m_data = strData; + d->m_encoding = "utf-8"; + d->m_version = "1.0"; +} + +GXMLParser::~GXMLParser() +{ + Q_D(GXMLParser); + d->m_base = NULL; + freePtr(d); +} + +CGLDXMLNode *GXMLParser::addOpenTag(const GString &text) +{ + Q_D(GXMLParser); + if ((d->m_currentNode == NULL) && (d->m_base != NULL)) + { + d->m_base->setXML(text); + d->m_currentNode = d->m_base; + return d->m_base; + } + else + { + d->m_temp = new CGLDXMLNode(d->m_currentNode, d->m_options, ELEMENT, d->m_document); + d->m_temp->setXML(text); + if (d->m_currentNode == NULL) + { + d->m_base = d->m_temp; + } + else + { + d->m_currentNode->childNodesObj()->add(d->m_temp); + } + d->m_currentNode = d->m_temp; + return d->m_temp; + } +} + +void GXMLParser::addCloseTag() +{ + Q_D(GXMLParser); + if (d->m_currentNode != NULL) + { + d->m_currentNode = d->m_currentNode->parentObj(); + } + else + { + xmlDocErrorInParser(TRANS_STRING("XML标识符不匹配")); + } +} + +void GXMLParser::addDataNode(const GString &data, EnXMLNodeType nodeType) +{ + Q_D(GXMLParser); + CGLDXMLNode *pNode = NULL; + if ((d->m_currentNode == NULL) && (d->m_base != NULL)) + { + xmlDocErrorInParser(TRANS_STRING("节点内容非法")); + } + else + { + pNode = new CGLDXMLNode(d->m_currentNode, d->m_options, nodeType, d->m_document); + pNode->setName(c_gdefNodeName[nodeType]); + pNode->setText(data); + if (d->m_currentNode == NULL) + { + d->m_base = pNode; + } + else + { + d->m_currentNode->childNodesObj()->add(pNode); + } + } +} + +void GXMLParser::addProcessingInstruction(const GString &data) +{ + Q_D(GXMLParser); + GString strText = data; + CGLDXMLNode *pNode = new CGLDXMLNode(NULL, d->m_options, ELEMENT, NULL); + strText.replace(1, 1, ""); + strText.replace(strText.length() - 2, 1, ""); + pNode->setXML(strText); + if (pNode->attributesObj()->indexOf("encoding") != -1) + { + d->m_encoding = "utf-8"; + } + if (pNode->attributesObj()->indexOf("version") != -1) + { + d->m_version = "1.0"; + } + freeAndNil(pNode); +} + +void GXMLParser::doParse() +{ + Q_D(GXMLParser); + int nSize = 0; + int nFind = 0; + int nEnd = 0; + int nCount = 0; + GString strTag = ""; + GString strValue = ""; + if (d->m_data.isEmpty()) + return; + else + { + nSize = d->m_data.length(); + } + d->m_index = d->m_pos; + + GString str1 = ""; + int nLenth = str1.length() + str2.length(); + + while (d->m_index < nSize) + { + if (d->m_data.at(d->m_index) == '<') + { + nEnd = d->m_data.indexOf('>', d->m_index + 1); + if (nEnd == -1) + { + xmlDocErrorInParser(TRANS_STRING("XML标识符号不匹配")); + break; + } + nCount = nEnd - d->m_index + 1; + if (nCount <= 2) + { + xmlDocErrorInParser(TRANS_STRING("XML节点内容不能为空")); + break; + } + + /* + *因为类似于下面的标签 + * + * BraceSpanCount >= 0其实是一个表达式,因为没有转译,所以造成解析错误,为了容错处理,增加判断(标签)内 + *‘"’的数量,来作为'>'是否是标签关键符号。否子继续找下一个'>' + *by huy-a.2014-09-23 + */ + while(true) + { + int nStrCount = 0; + GStringRef str = d->m_data.midRef(d->m_index, nEnd - d->m_index + 1); + nStrCount = str.count(QChar('\"')); + if (nStrCount % 2 == 0) + { + break; + } + else + { + //将>符号替换掉 + d->m_data[nEnd] = QChar('&'); + d->m_data.insert(nEnd + 1,"gt;"); + nEnd = d->m_data.indexOf('>', nEnd + 1); + nCount = nEnd - d->m_index + 1; + } + } + + if (d->m_data.at(d->m_index + 1) == '/') + { + addCloseTag(); + } + else if (d->m_data.at(d->m_index + 1) == '?') + { + strTag = d->m_data.mid(d->m_index, nCount); + addProcessingInstruction(strTag); + } + else if (d->m_data.at(d->m_index + 1) != '!') + { + strTag = d->m_data.mid(d->m_index, nCount); + addOpenTag(strTag); + if (d->m_data.at(nEnd - 1) == '/') + { + addCloseTag(); + } + } + else if ((nCount >= nLenth) + && (d->m_data.at(d->m_index + 2) == '-') + && (d->m_data.at(d->m_index + 3) == '-')) + { + if ((d->m_data.at(nEnd - 2) == '-') && (d->m_data.at(nEnd - 1) == '-')) + { + nFind = nEnd - 2; + } + else + { + nFind = posXMLString(str2, d->m_data, d->m_index + 4); + } + if (nFind == 0) + { + xmlDocErrorInParser(TRANS_STRING("XML标识符号不匹配")); + break; + } + nCount = nFind - d->m_index - 4; + strTag = d->m_data.mid(d->m_index + 4 , nCount); + if (!contains(d->m_options, XO_IGNORE_COMMENT)) + { + addDataNode(strTag, COMMENT); + } + nEnd = nFind + 2; + } + else if ((nCount >= c_gconCDataMinLength) && (d->m_data.at(d->m_index + 2) == '[') + && (d->m_data.at(d->m_index + 3) == 'C') && (d->m_data.at(d->m_index + 4) == 'D') + && (d->m_data.at(d->m_index + 5) == 'A') && (d->m_data.at(d->m_index + 6) == 'T') + && (d->m_data.at(d->m_index + 7) == 'A') && (d->m_data.at(d->m_index + 2) == '[')) + { + if ((d->m_data[nEnd - 2] == ']') && (d->m_data[nEnd - 1] == ']')) + { + nFind = nEnd - 2; + } + else + { + nFind = posXMLString(c_gconCDataPosx, d->m_data, d->m_index + 9); + } + if (nFind == 0) + { + xmlDocErrorInParser(c_grsErrTagNotMatch); + break; + } + nCount = nFind - d->m_index - 9; + strTag = d->m_data.mid(d->m_index + 9, nCount); + if (!contains(d->m_options, XO_IGNORE_CDATA)) + { + addDataNode(strTag, CDATA); + } + nEnd = nFind + 2; + } + d->m_index = nEnd + 1; + } + else + { + nEnd = d->m_data.indexOf("<", d->m_index); + if (nEnd == -1) + { + nEnd = nSize; + } + nCount = nEnd - d->m_index; + strValue = d->m_data.mid(d->m_index, nCount); + if (d->m_currentNode != NULL) + { + d->m_currentNode->setText(strValue); + } + d->m_index = nEnd; + } + } +} + +void GXMLParser::xmlDocErrorInParser(const GString &msg) +{ + Q_D(GXMLParser); + xmlDocError(c_grsErrParserMsgFmt.arg(msg, intToStr(d->m_index))); +} + +CGLDXMLNode *GXMLParser::base() +{ + Q_D(GXMLParser); + return d->m_base; +} + +const CGLDXMLNode *GXMLParser::current() +{ + Q_D(GXMLParser); + return d->m_currentNode; +} + +GString GXMLParser::encoding() +{ + Q_D(GXMLParser); + return d->m_encoding; +} + +GString GXMLParser::version() +{ + Q_D(GXMLParser); + return d->m_version; +} + +void GXMLParser::setPos(int pos) +{ + Q_D(GXMLParser); + d->m_pos = pos; +} + +void GXMLParser::setDocument(CGLDXMLDocument *document) +{ + Q_D(GXMLParser); + d->m_document = document; +} + +void GXMLParser::execute(const GString &data, CGLDXMLDocument *doc, int nPos) +{ + assert(doc != NULL); + + GXMLParser *pXMLParser = new GXMLParser(data, NULL, doc->options()); + try + { + pXMLParser->setDocument(doc); + pXMLParser->setPos(nPos); + pXMLParser->doParse(); + doc->setRoot(pXMLParser->base()); + doc->setVersion(pXMLParser->version()); + doc->setEncoding(pXMLParser->encoding()); + } + catch (...) + { + freeAndNil(pXMLParser); + throw; + } + freeAndNil(pXMLParser); +} + +void GXMLParser::execute(const GString &data, CGLDXMLNode *pBase, EnTXMLOptions options) +{ + GXMLParser *pXMLParser = new GXMLParser(data, pBase, options); + try + { + pXMLParser->doParse(); + } + catch (...) + { + freeAndNil(pXMLParser); + throw; + } + freeAndNil(pXMLParser); +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDXMLSAXUtils.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDXMLSAXUtils.cpp new file mode 100644 index 00000000..39edaee7 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDXMLSAXUtils.cpp @@ -0,0 +1,299 @@ +#include "GLDXMLSAXUtils.h" + +#include "GLDStrUtils.h" +#include "GLDException.h" +#include "GLDXML_Global.h" +#include + +class GLDXMLSAXReaderPrivate +{ +public: + GLDXMLSAXReaderPrivate(GLDXMLSAXReader *parent) + : q_ptr(parent), m_file(NULL) + { + } + +private: + GLDXMLSAXReader * const q_ptr; + Q_DECLARE_PUBLIC(GLDXMLSAXReader); + + GFileStream *m_file; + QXmlStreamReader m_reader; +}; + +GLDXMLSAXReader::GLDXMLSAXReader(): d_ptr(new GLDXMLSAXReaderPrivate(this)) +{ +} + +GLDXMLSAXReader::GLDXMLSAXReader(const GString &fileName): d_ptr(new GLDXMLSAXReaderPrivate(this)) +{ + setFilename(fileName); +} + +GLDXMLSAXReader::GLDXMLSAXReader(QIODevice *device): d_ptr(new GLDXMLSAXReaderPrivate(this)) +{ + setDevice(device); +} + +GLDXMLSAXReader::~GLDXMLSAXReader() +{ + Q_D(GLDXMLSAXReader); + closeFile(); + freePtr(d); +} + +GString GLDXMLSAXReader::readAttribute(const GString &attributeName) const +{ + Q_D(const GLDXMLSAXReader); + if (d->m_reader.isStartElement()) + { + QXmlStreamAttributes attributes = d->m_reader.attributes(); + return attributes.value(attributeName).toString(); + } + return GString(); +} + +bool GLDXMLSAXReader::hasAttribute(const GString &attribute) const +{ + Q_D(const GLDXMLSAXReader); + if (!d->m_reader.atEnd()) + { + QXmlStreamAttributes attributes = d->m_reader.attributes(); + return !attributes.value(attribute).isEmpty(); + } + return false; +} + +QXmlStreamAttributes GLDXMLSAXReader::attributes() const +{ + Q_D(const GLDXMLSAXReader); + return d->m_reader.attributes(); +} + +GString GLDXMLSAXReader::readElementText(QXmlStreamReader::ReadElementTextBehaviour behaviour) +{ + Q_D(GLDXMLSAXReader); + return d->m_reader.readElementText(behaviour); +} + +GStringRef GLDXMLSAXReader::text() const +{ + Q_D(const GLDXMLSAXReader); + if (!d->m_reader.atEnd()) + { + d->m_reader.text(); + } + return GStringRef(); +} + +GString GLDXMLSAXReader::name() const +{ + Q_D(const GLDXMLSAXReader); + GString name = d->m_reader.name().toString(); + if (d->m_reader.prefix().length() > 0) + { + return d->m_reader.prefix().toString() + ":" + name; + } + return name; +} + +GStringRef GLDXMLSAXReader::nameRef() const +{ + Q_D(const GLDXMLSAXReader); + return d->m_reader.name(); +} + +bool GLDXMLSAXReader::atEnd() const +{ + Q_D(const GLDXMLSAXReader); + return d->m_reader.atEnd(); +} + +bool GLDXMLSAXReader::isEndElement() const +{ + Q_D(const GLDXMLSAXReader); + return d->m_reader.isEndElement(); +} + +bool GLDXMLSAXReader::isEndDocument() const +{ + Q_D(const GLDXMLSAXReader); + return d->m_reader.isEndDocument() || d->m_reader.atEnd(); +} + +bool GLDXMLSAXReader::isStartElement() const +{ + Q_D(const GLDXMLSAXReader); + return d->m_reader.isStartElement(); +} + +bool GLDXMLSAXReader::isStartDocument() const +{ + Q_D(const GLDXMLSAXReader); + return d->m_reader.isStartDocument(); +} + +bool GLDXMLSAXReader::isCharacters() const +{ + Q_D(const GLDXMLSAXReader); + return d->m_reader.isCharacters(); +} + +bool GLDXMLSAXReader::isWhitespace() const +{ + Q_D(const GLDXMLSAXReader); + return d->m_reader.isWhitespace(); +} + +bool GLDXMLSAXReader::isCDATA() const +{ + Q_D(const GLDXMLSAXReader); + return d->m_reader.isCDATA(); +} + +bool GLDXMLSAXReader::isComment() const +{ + Q_D(const GLDXMLSAXReader); + return d->m_reader.isComment(); +} + +bool GLDXMLSAXReader::isDTD() const +{ + Q_D(const GLDXMLSAXReader); + return d->m_reader.isDTD(); +} + +bool GLDXMLSAXReader::isEntityReference() const +{ + Q_D(const GLDXMLSAXReader); + return d->m_reader.isEntityReference(); +} + +bool GLDXMLSAXReader::isProcessingInstruction() const +{ + Q_D(const GLDXMLSAXReader); + return d->m_reader.isProcessingInstruction(); +} + +void GLDXMLSAXReader::skipCurrentElement() +{ + Q_D(GLDXMLSAXReader); + return d->m_reader.skipCurrentElement(); +} + +GString GLDXMLSAXReader::tr(const char *sourceText, const char *disambiguation, int n) +{ + return QCoreApplication::translate("GLDXMLSAXReader", sourceText, disambiguation, n); +} + +void GLDXMLSAXReader::setDevice(QIODevice *device) +{ + assert(device); + Q_D(GLDXMLSAXReader); + d->m_reader.setDevice(device); + d->m_reader.setNamespaceProcessing(false); + QXmlStreamReader::TokenType type = d->m_reader.readNext(); + if (type == QXmlStreamReader::StartDocument) + { + d->m_reader.readNext(); + } +} + +void GLDXMLSAXReader::setFilename(const GString &fileName) +{ + Q_D(GLDXMLSAXReader); + freeAndNil(d->m_file); + d->m_file = new GFileStream(); + d->m_file->setFileName(fileName); + if (d->m_file->open(QIODevice::ReadOnly)) + { + setDevice(d->m_file); + } + else + { + gldError(tr("File not exist"));//TRANS_STRING("文件不存在")); + } +} + +void GLDXMLSAXReader::closeFile() +{ + Q_D(GLDXMLSAXReader); + if (d->m_file) + { + d->m_file->close(); + freeAndNil(d->m_file); + } + else + { + // do nothing + } +} + +void GLDXMLSAXReader::reset() +{ + Q_D(GLDXMLSAXReader); + if (d->m_file) + { + GString fileName = d->m_file->fileName(); + d->m_reader.clear(); + closeFile(); + setFilename(fileName); + } + else + { + QIODevice *device = d->m_reader.device(); + device->seek(0); + d->m_reader.clear(); + setDevice(device); + } +} + +GString GLDXMLSAXReader::readNextNode(const GString &nodeName) +{ + Q_D(GLDXMLSAXReader); + while (!d->m_reader.isEndDocument()) + { + d->m_reader.readNextStartElement(); + GString name = d->m_reader.name().toString(); + if (d->m_reader.prefix().length() > 0) + { + name = GString(d->m_reader.prefix().toString()).append(":").append(name); + } + if (nodeName.isEmpty()) + return name; + else + { + if (0 == name.compare(nodeName, Qt::CaseInsensitive)) + return name; + else + { + //针对没有数据块,但为了读取数据块又指定了nodeName的情形 + QXmlStreamReader::TokenType tokey = d->m_reader.tokenType(); + if (QXmlStreamReader::Invalid == tokey || QXmlStreamReader::NoToken == tokey) + return name; + } + } + } + return GString(); +} + +GStringRef GLDXMLSAXReader::readNextNodeNameRef(const GLatin1String &nodeName) +{ + GStringRef result = GStringRef(); + while (!sameText(result, nodeName)) + { + result = readNextNodeNameRef(); + } + return result; +} + +GStringRef GLDXMLSAXReader::readNextNodeNameRef() +{ + Q_D(GLDXMLSAXReader); + while (!d->m_reader.isEndDocument()) + { + d->m_reader.readNextStartElement(); + return d->m_reader.name(); + } + return GStringRef(); +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDXMLUtils.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDXMLUtils.cpp new file mode 100644 index 00000000..0d2844d8 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDXMLUtils.cpp @@ -0,0 +1,759 @@ +#include "GLDXMLUtils.h" + +#include "GLDFile.h" +#include "GLDTextStream.h" +#include "GLDGlobal.h" +#include "GLDStrUtils.h" +#include "GLDMathUtils.h" +#include "GLDException.h" +#include "GLDXMLDoc.h" + +#define DEFXMLUTF8HEADER_LENGTH 3 +const GString c_defXMLDataHeader = "= 'a') && (ch <= 'z')) + { + return true; + } + else if ((ch >= 'A') && (ch <= 'Z')) + { + return true; + } + return false; +} + +bool ucstricmp(const QChar *a, int length_a, const QChar *b, int ) +{ + if (a == b) + { + return true; + } + for (int i = 0; i < length_a; ++i) + { + QChar qchar1 = a[i]; + QChar qchar2 = b[i]; + if ((isChar(qchar1)) && (isChar(qchar2))) + { + char char1 = qchar1.toLatin1(); + char char2 = qchar2.toLatin1(); + if ((char1 == char2) || (char1 == char2 + 32) || (char2 == char1 + 32)) + { + continue; + } + else + { + return false; + } + } + else + { + if (qchar1 == qchar2) + { + continue; + } + else + { + return false; + } + } + } + return true; +} + +bool innerSameText(const GString &s1, const GString &s2) +{ + int nLength1 = s1.length(); + int nLength2 = s2.length(); + if ((nLength1 != nLength2) || (nLength2 == 0) || (nLength1 == 0)) + { + return false; + } + return ucstricmp(s1.data(), nLength1, s2.data(), nLength2); +} + +GXMLNode firstChildNode(const GXMLNode &node, const GString &tagName) +{ + return node.firstChildElement(tagName); +} + +GXMLNode findChildNode(const GXMLNode &node, const GString &nodeName) +{ + GXMLNode child = node.firstChildElement(); + while (!child.isNull()) + { + if (innerSameText(child.nodeName(), nodeName)) + { + return child; + } + child = child.nextSiblingElement(); + } + return child; +} + +GXMLNode addChild(GXMLNode &node, const GString &nodeName) +{ + GXMLNode child = node.ownerDocument().createElement(nodeName); + node.appendChild(child); + return child; +} + +GString readStrFromXML(const GXMLNode &node, const GString &nodeName, const GString &defVal) +{ + GXMLNode child = findChildNode(node, nodeName); + if (!child.isNull()) + return child.text(); + else + return defVal; +} + +bool readBoolFromXML(const GXMLNode &node, const GString &nodeName, bool defVal) +{ + GXMLNode child = findChildNode(node, nodeName); + if (!child.isNull()) + return sameText(child.text(), "True"); + else + return defVal; +} + +int readIntFromXML(const GXMLNode &node, const GString &nodeName, int defVal) +{ + GXMLNode child = findChildNode(node, nodeName); + if (!child.isNull()) + return strToIntDef(child.text(), 0); + else + return defVal; +} + +long long readInt64FromXML(const GXMLNode &node, const GString &nodeName, long long defVal) +{ + GXMLNode child = findChildNode(node, nodeName); + if (!child.isNull()) + return strToInt64Def(child.text(), defVal); + else + return defVal; +} + +guint64 readUInt64FromXML(const GXMLNode &node, const GString &nodeName, guint64 defVal) +{ + GXMLNode child = findChildNode(node, nodeName); + if (!child.isNull()) + return strToUInt64Def(child.text(), defVal); + else + return defVal; +} + +double readFloatFromXML(const GXMLNode &node, const GString &nodeName, double defVal) +{ + GXMLNode child = findChildNode(node, nodeName); + if (!child.isNull()) + return strToFloatDef(child.text(), defVal); + else + return defVal; +} + +GString readStrFromXMLAttr(const GXMLNode &node, const GString &attrName, const GString &defVal) +{ + if (node.hasAttribute(attrName)) + return node.attribute(attrName); + else + return defVal; +} + +bool readBoolFromXMLAttr(const GXMLNode &node, const GString &attrName, bool defVal) +{ + if (node.hasAttribute(attrName)) + return sameText(node.attribute(attrName), "True"); + else + return defVal; +} + +int readIntFromXMLAttr(const GXMLNode &node, const GString &attrName, int defVal) +{ + if (node.hasAttribute(attrName)) + return strToIntDef(node.attribute(attrName), defVal); + else + return defVal; +} + +gint64 readInt64FromXMLAttr(const GXMLNode &node, const GString &attrName, gint64 defVal) +{ + if (node.hasAttribute(attrName)) + return strToInt64Def(node.attribute(attrName), defVal); + else + return defVal; +} + +guint64 readUInt64FromXMLAttr(const GXMLNode &node, const GString &attrName, guint64 defVal) +{ + if (node.hasAttribute(attrName)) + return strToUInt64Def(node.attribute(attrName), defVal); + else + return defVal; +} + +double readFloatFromXMLAttr(const GXMLNode &node, const GString &attrName, double defVal) +{ + if (node.hasAttribute(attrName)) + return strToFloatDef(node.attribute(attrName), defVal); + else + return defVal; +} + +void writeStrToXML(GXMLNode &node, const GString &nodeName, const GString &value, const GString &defVal) +{ + if ((value == defVal) && findChildNode(node, nodeName).isNull()) + return; + + GXMLNode child = addChild(node, nodeName); +#ifdef GLD_XML + child.setAsString(value); +#else + GDomText text = node.ownerDocument().createTextNode(value); + child.appendChild(text); +#endif +} + +void writeBoolToXML(GXMLNode &node, const GString &nodeName, bool value, bool defVal) +{ + if ((value == defVal) && findChildNode(node, nodeName).isNull()) + return; + + if (value) + writeStrToXML(node, nodeName, "True"); + else + writeStrToXML(node, nodeName, "False"); + +} + +void writeIntToXML(GXMLNode &node, const GString &nodeName, int value, int defVal) +{ + if ((value == defVal) && findChildNode(node, nodeName).isNull()) + return; + + writeStrToXML(node, nodeName, intToStr(value)); +} + +void writeInt64ToXML(GXMLNode &node, const GString &nodeName, long long value, long long defVal) +{ + if ((value == defVal) && findChildNode(node, nodeName).isNull()) + return; + + writeStrToXML(node, nodeName, int64ToStr(value)); +} + +void writeUInt64ToXML(GXMLNode &node, const GString &nodeName, guint64 value, guint64 defVal) +{ + if ((value == defVal) && findChildNode(node, nodeName).isNull()) + return; + + writeStrToXML(node, nodeName, uint64ToStr(value)); +} + +void writeFloatToXML(GXMLNode &node, const GString &nodeName, double value, double defVal) +{ + if (sameValue(value, defVal) && findChildNode(node, nodeName).isNull()) + return; + + writeStrToXML(node, nodeName, floatToStr(value)); +} + +void writeStrToXMLAttr(GXMLNode &node, const GString &attrName, const GString &value, const GString &defVal) +{ + if ((value == defVal) && (!node.hasAttribute(attrName))) + return; + + node.setAttribute(attrName, value); +} + +void writeBoolToXMLAttr(GXMLNode &node, const GString &attrName, bool value, bool defVal) +{ + if ((value == defVal) && (!node.hasAttribute(attrName))) + return; + + if (value) + writeStrToXMLAttr(node, attrName, "True"); + else + writeStrToXMLAttr(node, attrName, "False"); +} + +void writeIntToXMLAttr(GXMLNode &node, const GString &attrName, int value, int defVal) +{ + if ((value == defVal) && (!node.hasAttribute(attrName))) + return; + + node.setAttribute(attrName, value); +} + +void writeUIntToXMLAttr(GXMLNode &node, const GString &attrName, uint value, uint defVal) +{ + if ((value == defVal) && (!node.hasAttribute(attrName))) + return; + + node.setAttribute(attrName, value); +} + +void writeFloatToXMLAttr(GXMLNode &node, const GString &attrName, double value, double defVal) +{ + if (sameValue(value, defVal) && (!node.hasAttribute(attrName))) + return; + + node.setAttribute(attrName, floatToStr(value)); +} + +GLDXMLNode firstChildNode(const GLDXMLNode &node, const GString &tagName) +{ + return node.firstChildElement(tagName); +} + +GLDXMLNode findChildNode(const GLDXMLNode &node, const GString &nodeName) +{ +// GDomNode result = node.namedItem(nodeName); +// if (result.isNull()) +// return GLDXMLNode(); +// else +// return result.toElement(); + GLDXMLNode child = node.firstChildElement(); + while (!child.isNull()) + { + if (sameText(child.nodeName(), nodeName)) + { + return child; + } + child = child.nextSiblingElement(); + } + return child; +} + +GLDXMLNode addChild(GLDXMLNode &node, const GString &nodeName) +{ + GLDXMLNode child = node.ownerDocument().createElement(nodeName); + node.appendChild(child); + return child; +} + +GString readStrFromXML(const GLDXMLNode &node, const GString &nodeName, const GString &defVal) +{ + GLDXMLNode child = findChildNode(node, nodeName); + if (!child.isNull()) + return child.text(); + else + return defVal; +} + +bool readBoolFromXML(const GLDXMLNode &node, const GString &nodeName, bool defVal) +{ + GLDXMLNode child = findChildNode(node, nodeName); + if (!child.isNull()) + return sameText(child.text(), "True"); + else + return defVal; +} + +int readIntFromXML(const GLDXMLNode &node, const GString &nodeName, int defVal) +{ + GLDXMLNode child = findChildNode(node, nodeName); + if (!child.isNull()) + return strToIntDef(child.text(), 0); + else + return defVal; +} + +long long readInt64FromXML(const GLDXMLNode &node, const GString &nodeName, long long defVal) +{ + GLDXMLNode child = findChildNode(node, nodeName); + if (!child.isNull()) + return strToInt64Def(child.text(), defVal); + else + return defVal; +} + +guint64 readUInt64FromXML(const GLDXMLNode &node, const GString &nodeName, guint64 defVal) +{ + GLDXMLNode child = findChildNode(node, nodeName); + if (!child.isNull()) + return strToUInt64Def(child.text(), defVal); + else + return defVal; +} + +double readFloatFromXML(const GLDXMLNode &node, const GString &nodeName, double defVal) +{ + GLDXMLNode child = findChildNode(node, nodeName); + if (!child.isNull()) + return strToFloatDef(child.text(), defVal); + else + return defVal; +} + +GString readStrFromXMLAttr(const GLDXMLNode &node, const GString &attrName, const GString &defVal) +{ + if (node.hasAttribute(attrName)) + return node.attribute(attrName); + else + return defVal; +} + +bool readBoolFromXMLAttr(const GLDXMLNode &node, const GString &attrName, bool defVal) +{ + if (node.hasAttribute(attrName)) + return sameText(node.attribute(attrName), "True"); + else + return defVal; +} + +int readIntFromXMLAttr(const GLDXMLNode &node, const GString &attrName, int defVal) +{ + if (node.hasAttribute(attrName)) + return strToIntDef(node.attribute(attrName), defVal); + else + return defVal; +} + +gint64 readInt64FromXMLAttr(const GLDXMLNode &node, const GString &attrName, gint64 defVal) +{ + if (node.hasAttribute(attrName)) + return strToInt64Def(node.attribute(attrName), defVal); + else + return defVal; +} + +guint64 readUInt64FromXMLAttr(const GLDXMLNode &node, const GString &attrName, guint64 defVal) +{ + if (node.hasAttribute(attrName)) + return strToUInt64Def(node.attribute(attrName), defVal); + else + return defVal; +} + +double readFloatFromXMLAttr(const GLDXMLNode &node, const GString &attrName, double defVal) +{ + if (node.hasAttribute(attrName)) + return strToFloatDef(node.attribute(attrName), defVal); + else + return defVal; +} + +void writeStrToXML(GLDXMLNode &node, const GString &nodeName, const GString &value, const GString &defVal) +{ + if ((value == defVal) && findChildNode(node, nodeName).isNull()) + return; + + GLDXMLNode child = addChild(node, nodeName); + child.setAsString(value); +} + +void writeBoolToXML(GLDXMLNode &node, const GString &nodeName, bool value, bool defVal) +{ + if ((value == defVal) && findChildNode(node, nodeName).isNull()) + return; + + if (value) + writeStrToXML(node, nodeName, "True"); + else + writeStrToXML(node, nodeName, "False"); + +} + +void writeIntToXML(GLDXMLNode &node, const GString &nodeName, int value, int defVal) +{ + if ((value == defVal) && findChildNode(node, nodeName).isNull()) + return; + + writeStrToXML(node, nodeName, intToStr(value)); +} + +void writeInt64ToXML(GLDXMLNode &node, const GString &nodeName, long long value, long long defVal) +{ + if ((value == defVal) && findChildNode(node, nodeName).isNull()) + return; + + writeStrToXML(node, nodeName, int64ToStr(value)); +} + +void writeUInt64ToXML(GLDXMLNode &node, const GString &nodeName, guint64 value, guint64 defVal) +{ + if ((value == defVal) && findChildNode(node, nodeName).isNull()) + return; + + writeStrToXML(node, nodeName, uint64ToStr(value)); +} + +void writeFloatToXML(GLDXMLNode &node, const GString &nodeName, double value, double defVal) +{ + if (sameValue(value, defVal) && findChildNode(node, nodeName).isNull()) + return; + + writeStrToXML(node, nodeName, floatToStr(value)); +} + +void writeStrToXMLAttr(GLDXMLNode &node, const GString &attrName, const GString &value, const GString &defVal) +{ + if ((value == defVal) && (!node.hasAttribute(attrName))) + return; + + node.setAttribute(attrName, value); +} + +void writeBoolToXMLAttr(GLDXMLNode &node, const GString &attrName, bool value, bool defVal) +{ + if ((value == defVal) && (!node.hasAttribute(attrName))) + return; + + if (value) + writeStrToXMLAttr(node, attrName, "True"); + else + writeStrToXMLAttr(node, attrName, "False"); +} + +void writeIntToXMLAttr(GLDXMLNode &node, const GString &attrName, int value, int defVal) +{ + if ((value == defVal) && (!node.hasAttribute(attrName))) + return; + + node.setAttribute(attrName, value); +} + +void writeUIntToXMLAttr(GLDXMLNode &node, const GString &attrName, uint value, uint defVal) +{ + if ((value == defVal) && (!node.hasAttribute(attrName))) + return; + + node.setAttribute(attrName, value); +} + +void writeFloatToXMLAttr(GLDXMLNode &node, const GString &attrName, double value, double defVal) +{ + if (sameValue(value, defVal) && (!node.hasAttribute(attrName))) + return; + + node.setAttribute(attrName, floatToStr(value)); +} + +GXMLDocument createXMLDocument(bool aIncludeHeader, bool autoIndent) +{ +#ifdef GLD_XML + +#else + G_UNUSED(aIncludeHeader); + G_UNUSED(autoIndent); + GXMLDocument doc; + GDomProcessingInstruction instruction = doc.createProcessingInstruction( + "xml", "version=\"1.0\" encoding=\"utf-8\""); + doc.appendChild(instruction); + return doc; +#endif +} + +GXMLDocument loadXMLDocument(const GString &fileName) +{ + GFileStream file(fileName); + if (!file.open(GStream::ReadOnly)) + return GXMLDocument(); + GXMLDocument result; + QString errorMsg; + int nRow = 0; + int nColumn = 0; + if (!result.setContent(&file, &errorMsg, &nRow, &nColumn)) + { + //qWarning() << "load xml error: " << errorMsg << ", Row: " << nRow << ", Column: " << nColumn; + file.close(); + return GXMLDocument(); + } + else + { + file.close(); + return result; + } +} + +GXMLDocument loadXMLDocument(GStream *stream) +{ + GXMLDocument result; + if (!result.setContent(stream)) + return GXMLDocument(); + else + return result; +} + +void saveXMLDocument(GXMLDocument &doc, const GString &fileName) +{ + GFileStream file(fileName); + if (!file.open(GStream::WriteOnly)) + { + return; + } + if (!doc.firstChild().isProcessingInstruction()) + { + GDomProcessingInstruction xmlInfoNode = doc.createProcessingInstruction( + "xml", "version=\"1.0\" encoding=\"utf-8\" "); + doc.insertBefore(xmlInfoNode, doc.documentElement()); + } + GTextStream oStream(&file); + doc.save(oStream, 1); + file.close(); +} + +void saveXMLDocument(GXMLDocument &doc, GStream *stream) +{ + if (!doc.firstChild().isProcessingInstruction()) + { + GDomProcessingInstruction xmlInfoNode = doc.createProcessingInstruction( + "xml", "version=\"1.0\" encoding=\"utf-8\" "); + doc.insertBefore(xmlInfoNode, doc.documentElement()); + } + GTextStream oStream(stream); + doc.save(oStream, 1); +} + +//设计:Linc 2004.12.13 +//功能:判断一个流是否 XML 流 +bool isXMLStream(GStream *stream) +{ + char cBuffer; + assert(stream != NULL); + bool result = false; + int nPos = 0; + try + { + nPos = stream->pos(); + int nSize = DEFXMLUTF8HEADER_LENGTH; + GByteArray byteArray = stream->read(nSize); + int nRead = byteArray.length(); + // 跳过 XML UTF-8 的 BOM 标记 + if ((nRead != nSize) || (0 != compareText(byteArray, GByteArray(c_defXMLUtf8Header, DEFXMLUTF8HEADER_LENGTH)))) + { + stream->seek(nPos); + } + do + { + nRead = stream->read(&cBuffer, sizeof(char)); + } while ((nRead != 0) + && ((cBuffer == 10) || (cBuffer == 13) || (cBuffer == 9) || (cBuffer == ' ')));//跳过空白行 + stream->seek(stream->pos() - 1); + nSize = length(c_defXMLDataHeader); + + GString strHeader = utf8ToUnicode(stream->read(nSize).constData(), nSize); + nRead = length(strHeader); + result = (nRead == nSize) && (strHeader == c_defXMLDataHeader); + } + catch(...) + { + stream->seek(nPos); + throw; + } + stream->seek(nPos); + return result; +} + +void clearNodes(GXMLNode &node) +{ + GXMLNode child = node.firstChildElement(); + while (!child.isNull()) + { + node.removeChild(child); + child = child.nextSiblingElement(); + } +} + +int posXMLString(GString strSub, GString strValue, int nStart) +{ + int nLen1 = strSub.length(); + int nLen2 = strValue.length(); + int result = -1; + if (nLen1 == 0 || (nStart + nLen1 > nLen2 + 1)) + { + return result; + } + int nIndex = nStart; + int nPos = 0; + while (nIndex < nLen2) + { + nPos = 0; + while (nPos < nLen1 && (strSub.at(nPos) == strValue.at(nIndex))) + { + ++nPos; + ++nIndex; + } + if (nPos == nLen1) + { + result = nIndex - nLen1; + break; + } + else + { + ++nIndex; + } + } + + return result; +} + + +void xmlDocError(const GString &msg) +{ + throw GLDException(msg); +} + +void xmlDocError(const GString &msg, const GVariantList &variantList) +{ + throw GLDException(format(msg, variantList)); +} + + +GLDXMLDocument loadGLDXMLDocument(const GString &fileName) +{ + GFileStream file(fileName); + if (!file.open(GStream::ReadOnly)) + return GLDXMLDocument(); + GLDXMLDocument result; + if (!result.setContent(&file)) + { + file.close(); + return GLDXMLDocument(); + } + else + { + file.close(); + return result; + } +} + + +GLDXMLDocument createGLDXMLDocument(bool aIncludeHeader, bool autoIndent) +{ + CGLDXMLDocument *xmlDocument = new CGLDXMLDocument(); + xmlDocument->setAutoIndent(autoIndent); + xmlDocument->setIncludeHeader(aIncludeHeader); + return xmlDocument; +} + + +GLDXMLDocument loadGLDXMLDocument(GStream *stream) +{ + GLDXMLDocument result; + if (!result.setContent(stream)) + return GLDXMLDocument(); + else + return result; +} + + +void saveGLDXMLDocument(GLDXMLDocument &doc, const GString &fileName) +{ + GFileStream file(fileName); + if (!file.open(GStream::WriteOnly)) + { + return; + } + doc.saveToStream(&file); + file.close(); +} + + +void saveGLDXMLDocument(GLDXMLDocument &doc, GStream *stream) +{ + doc.saveToStream(stream); +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDXMLWriter.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDXMLWriter.cpp new file mode 100644 index 00000000..db52e7cb --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDXMLWriter.cpp @@ -0,0 +1,473 @@ +#include "GLDXMLWriter.h" + +#include "GLDGlobal.h" +#include "GLDStrUtils.h" +#include "GLDException.h" +#include "GLDStreamUtils.h" +#include "GLDStrings.h" + +// "不支持类型为 %d 的可变数据类型" +const char *g_rsErrUnsupportVariantType = QT_TRANSLATE_NOOP("GLD", "Does not support the type of variable data type %d");// "不支持类型为 %d 的可变数据类型"); +#define GrandXMLWriter_rsErrUnsupportVariantType System::loadResourceString(&_rsErrUnsupportVariantType) + +#ifdef WIN32 +static const GLatin1String g_LineBreak("\r\n"); +#else +static const GLatin1String g_LineBreak("\r"); +#endif + +const GString c_defUtf8Encoding = "utf-8"; + +void xmlWriterError(const GString &msg, int errorCode) +{ + throw GLDException(msg, errorCode); +} + +class CGrandXMLNodeStackPrivate +{ +public: + CGrandXMLNodeStackPrivate(CGrandXMLNodeStack *parent) + : q_ptr(parent) + { + } + +private: + CGrandXMLNodeStack * const q_ptr; + Q_DECLARE_PUBLIC(CGrandXMLNodeStack) + + // 这里采用std::vector, 因QVector跟QLatin1String有兼容问题 zhangjq 2015.09.29 + std::vector m_list; + bool m_isEmptyElement; +}; + +/*CGrandXMLNodeStack*/ +CGrandXMLNodeStack::CGrandXMLNodeStack() : d_ptr(new CGrandXMLNodeStackPrivate(this)) +{ + Q_D(CGrandXMLNodeStack); + d->m_isEmptyElement = false; +} + +CGrandXMLNodeStack::~CGrandXMLNodeStack() +{ + Q_D(CGrandXMLNodeStack); + d->m_list.clear(); + freePtr(d); +} + +int CGrandXMLNodeStack::count() +{ + Q_D(CGrandXMLNodeStack); + return d->m_list.size(); +} + +bool CGrandXMLNodeStack::isEmptyElement() const +{ + Q_D(const CGrandXMLNodeStack); + return d->m_isEmptyElement; +} + +void CGrandXMLNodeStack::setIsEmptyElement(const bool value) +{ + Q_D(CGrandXMLNodeStack); + d->m_isEmptyElement = value; +} + +GLatin1String CGrandXMLNodeStack::push(const GLatin1String &s) +{ + Q_D(CGrandXMLNodeStack); + d->m_list.push_back(s); + d->m_isEmptyElement = true; + return s; +} + +GLatin1String CGrandXMLNodeStack::pop() +{ + Q_D(CGrandXMLNodeStack); + GLatin1String result = peek(); + d->m_list.erase(d->m_list.cbegin() + count() - 1); + d->m_isEmptyElement = false; + return result; +} + +GLatin1String CGrandXMLNodeStack::peek() +{ + Q_D(CGrandXMLNodeStack); + return d->m_list[count() - 1]; +} + +class GLDXMLWriterPrivate +{ +public: + GLDXMLWriterPrivate(GLDXMLWriter *parent) + : q_ptr(parent) + { + } + +private: + GLDXMLWriter * const q_ptr; + Q_DECLARE_PUBLIC(GLDXMLWriter) + + CXMLEncode m_encoding; + GStream *m_stream; + CGrandXMLNodeStack m_nodeStack; + bool m_bAutoIndent; + int m_currentLevel; +}; + +/*CGrandXMLWriter*/ + +GLDXMLWriter::GLDXMLWriter(GStream *stream, bool autoIndent):d_ptr(new GLDXMLWriterPrivate(this)) +{ + Q_D(GLDXMLWriter); + d->m_encoding = xeUtf8; + d->m_stream = stream; + d->m_bAutoIndent = autoIndent; + d->m_currentLevel = 0; + + assert(stream != NULL); +} + +GLDXMLWriter::~GLDXMLWriter() +{ + Q_D(GLDXMLWriter); + freePtr(d); +} + +void GLDXMLWriter::createProcessingInstruction(const GString &version, const GString &Encoding, + const GString &standalone) +{ + Q_D(GLDXMLWriter); + GString strTemp = ""; + + if (version.length() == 0) + { + strTemp.append("version=\"1.0\" "); + } + else + { + strTemp.append(format("version=\"%s\" ", version)); + } + + if (Encoding.length() == 0) + { + strTemp.append("encoding=\"utf-8\" "); + } + else + { + strTemp.append(format("encoding=\"%s\" ", Encoding)); + } + + if (standalone != "") + { + strTemp.append(format("standalone=\"%s\" ", standalone)); + } + + writeLn(GString("")); + d->m_encoding = getEncoding(Encoding); +} + +void GLDXMLWriter::beginNode(const GLatin1String &name, GLDVector *attNames, + GLDVector *attValues) +{ + assert(attNames->count() == attValues->count()); + beginNode(name); + + for (int i = 0; i != attNames->count(); i++) + { + addAttr(attNames->at(i), attValues->at(i)); + } +} + +void GLDXMLWriter::beginNode(const GLatin1String &name) +{ + Q_D(GLDXMLWriter); + assert(name.size() > 0); + + if ((d->m_nodeStack.count() > 0) && d->m_nodeStack.isEmptyElement()) + { + writeLn(GLatin1String(">")); + } + + writeIndent(0); + write(GLatin1String("<")); + write(name); + d->m_nodeStack.push(name); + d->m_currentLevel++; +} + +void GLDXMLWriter::endNode(bool indent) +{ + Q_D(GLDXMLWriter); + if (d->m_nodeStack.isEmptyElement()) + { + d->m_nodeStack.pop(); + writeLn(GLatin1String("/>")); + } + else + { + GLatin1String strTemp = d->m_nodeStack.pop(); + + if (indent) + { + writeIndent(-1); + } + write(GLatin1String("")); + if (d->m_bAutoIndent) + { + write(g_LineBreak); + } + } + + --d->m_currentLevel; +} + +void GLDXMLWriter::addAttr(const GString &name, bool value) +{ + GString strName = boolToXMLString(value); + addAttr(name, strName); +} + +void GLDXMLWriter::addAttr(const GString &name, double value) +{ + GString strName = floatToXMLString(value); + addAttr(name, strName); +} + +void GLDXMLWriter::addAttr(const GString &name, long long value) +{ + GString strTemp = int64ToStr(value); + addAttr(name, strTemp); +} + +void GLDXMLWriter::addAttr(const GString &name, unsigned long long value) +{ + GString strName = uint64ToStr(value); + addAttr(name, strName); +} + +void GLDXMLWriter::addAttr(const GString &name, int value) +{ + GString strName = intToStr(value); + addAttr(name, strName); +} + +void GLDXMLWriter::addAttr(const GString &name, GVariant *value) +{ + GByteArray strName = base64Encode(value->toByteArray()); + addAttr(name, (GString)strName); +} + +void GLDXMLWriter::addAttr(const GString &name, const GString &value) +{ + assert(name != ""); + GString strValue = encodeXMLString(value, false); + write(GString(' ').append(GString(name)).append("=\"").append(strValue).append('\"')); +} + +void GLDXMLWriter::createFullNode(const GLatin1String &name, const GString &text, + GLDVector *attNames, GLDVector *attValues) +{ + Q_D(GLDXMLWriter); + beginNode(name, attNames, attValues); + + if (text.length() > 0) + { + d->m_nodeStack.setIsEmptyElement(false); + GString strText = encodeXMLString(text, false); + write(GLatin1String(">")); + write(strText); + } + + endNode(false); +} + +void GLDXMLWriter::createFullNode(const GLatin1String &name, GLDVector *attNames, + GLDVector *attValues) +{ + Q_D(GLDXMLWriter); + beginNode(name, attNames, attValues); + d->m_nodeStack.setIsEmptyElement(true); + endNode(); +} + +void GLDXMLWriter::createFullNode(const GLatin1String &name, const GString &text) +{ + Q_D(GLDXMLWriter); + beginNode(name); + + if (text.length() > 0) + { + d->m_nodeStack.setIsEmptyElement(false); + GString strText = encodeXMLString(text, false); + write(GLatin1String(">")); + write(strText); + } + + endNode(false); +} + +GStream *GLDXMLWriter::stream() +{ + Q_D(GLDXMLWriter); + return d->m_stream; +} + +CXMLEncode GLDXMLWriter::encoding() +{ + Q_D(GLDXMLWriter); + return d->m_encoding; +} + +void GLDXMLWriter::setIsEmptyElement(bool value) +{ + Q_D(GLDXMLWriter); + if (d->m_nodeStack.isEmptyElement() == value) + { + return; + } + + if (!value) + { + d->m_nodeStack.setIsEmptyElement(value); + write(GLatin1String(">")); + } +} + +void GLDXMLWriter::addAttrVarRec(const GString &name, const GVariant &v) +{ + GString strAttr; + + switch (v.type()) + { + case GVariant::Int: + strAttr = intToStr(v.toInt()); + break; + + case GVariant::Bool: + strAttr = boolToXMLString(v.toBool()); + break; + + case GVariant::Char: + strAttr = GString(v.toChar()); + break; + + case GVariant::Double: + strAttr = floatToXMLString(v.toDouble()); + break; + + case GVariant::String: + strAttr = v.toString(); + break; + + //todo Lipl + // case vtPointer: + // assert(false); + // break; + case GVariant::UInt: + strAttr = v.toUInt(); + break; + + // case vtObject: + // assert(false); + // break; + // case vtAnsiString: + // strTemp = string(VAnsiString); + // break; + // case vtCurrency: + // strTemp = currToStr((*VCurrency)); + // break; + case GVariant::Invalid: + assert(false); + break; + + // case vtWideString: + // strTemp = wideString(VWideString); + // break; + case GVariant::LongLong: + strAttr = int64ToStr(v.toLongLong()); + break; + + case GVariant::ULongLong: + strAttr = uint64ToStr(v.toULongLong()); + break; + + default: + xmlWriterError(getGLDi18nStr(g_rsErrUnsupportVariantType), v.type()); + } + + G_UNUSED(name) +} + +void GLDXMLWriter::write(const GString &s) +{ + Q_D(GLDXMLWriter); + GByteArray data = s.toUtf8(); + d->m_stream->write(data.constData(), data.size()); +} + +void GLDXMLWriter::write(const GLatin1String &s) +{ + Q_D(GLDXMLWriter); + d->m_stream->write(s.data(), s.size()); +} + +void GLDXMLWriter::writeLn(const GString &s) +{ + Q_D(GLDXMLWriter); + write(s); + if (d->m_bAutoIndent) + { + write(g_LineBreak); + } +} + +void GLDXMLWriter::writeLn(const GLatin1String &s) +{ + Q_D(GLDXMLWriter); + write(s); + if (d->m_bAutoIndent) + { + write(g_LineBreak); + } +} + +void GLDXMLWriter::writeIndent(int offset) +{ + Q_D(GLDXMLWriter); + if (d->m_bAutoIndent) + { + int nLength = (d->m_currentLevel + offset) * 4; + const int nMaxLength = 1024; + if (nLength >= nMaxLength) + { + char *szTemp = new char[nLength + 1]; + memset(szTemp, ' ', nLength); + szTemp[nLength] = '\0'; + write(QLatin1String(szTemp, nLength)); + delete[] szTemp; + } + else + { + char szTemp[nMaxLength] = {' '}; + memset(szTemp, ' ', nMaxLength); + szTemp[nLength] = '\0'; + write(QLatin1String(szTemp, nLength)); + } + } +} + +CXMLEncode GLDXMLWriter::getEncoding(const GString &encode) +{ + if (encode.length() == 0) + { + return xeUtf8; + } + else if (sameText(encode, c_defUtf8Encoding)) + { + return xeUtf8; + } + + return xeUtf8; +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDZipEnc.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDZipEnc.cpp new file mode 100644 index 00000000..dd95a4a8 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDZipEnc.cpp @@ -0,0 +1,568 @@ +#include "GLDZipEnc.h" + +#include "GLDMathUtils.h" + +const unsigned long c_defStateInit1 = 0x12345678; /* 305419896 */ +const unsigned long c_defStateInit2 = 0x23456789; /* 591751049 */ +const unsigned long c_defStateInit3 = 0x34567890; /* 878082192 */ +const unsigned long c_defMagicNumber = 0x08088405; /* 134775813 */ + +const unsigned long c_CrcTable[256] = +{ + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, + 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, + 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, + 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, + 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, + 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, + 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, + 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, + 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, + 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, + 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, + 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, + 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, + 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, + 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, + 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, + 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, + 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, + 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, + 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, + 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, + 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, + 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, + 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, + 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, + 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, + 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, + 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, + 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, + 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, + 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, + 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, + 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D +}; + +unsigned long zipCRC32(GByteArray &data) +{ + unsigned long result = 0xffffffffL; + unsigned long uC; + for (int i = 0; i < data.length(); i++) + { + uC = 0x000000ffL & (unsigned long)data.at(i); + result = (result >> 8) ^ c_CrcTable[(result ^ uC) & 0xff]; + } + return ~result; +} + +unsigned long zipCRC32(GStream *stream) +{ + unsigned long result = 0xffffffffL; + unsigned long uC; + const int c_defBufferSize = 32768; + + int nCount = stream->size() / c_defBufferSize; + GByteArray data; + stream->seek(0); + + for (int j = 0; j < nCount; j++) + { + data.clear(); + data = stream->read(c_defBufferSize); + + for (int i = 0; i < data.length(); i++) + { + uC = 0x000000ffL & (unsigned long)data.at(i); + result = (result >> 8) ^ c_CrcTable[(result ^ uC) & 0xff]; + } + } + + data.clear(); + data = stream->read(stream->size() % c_defBufferSize); + + for (int i = 0; i < data.length(); i++) + { + uC = 0x000000ffL & (unsigned long)data.at(i); + result = (result >> 8) ^ c_CrcTable[(result ^ uC) & 0xff]; + } + return ~result; +} + +unsigned long zipUpdateCRC32(unsigned char curByte, unsigned long curCrc) +{ + unsigned long uc = 0x000000ffL & curByte; + return c_CrcTable[(uc ^ curCrc) & 0x000000ff] ^ ((curCrc >> 8) & 0x00ffffff); +} + +GLDZipDecryptEngine::GLDZipDecryptEngine() +{ + m_ready = false; +} + +GLDZipDecryptEngine::~GLDZipDecryptEngine() +{ +} + +unsigned char GLDZipDecryptEngine::decode(unsigned char ch) +{ + long lTemp; + unsigned char result; + //check for programming error + assert(m_ready); + + /*calculate the decoded byte (uses inlined decrypt_byte)*/ + lTemp = (m_state[2] & 0xffff) | 2; + result = ch ^ ((lTemp * (lTemp ^ 1)) >> 8); + + /*mix the decoded byte into the state (uses inlined update_keys)*/ + m_state[0] = zipUpdateCRC32(result, m_state[0]); + m_state[1] = m_state[1] + (m_state[0] & 0xff); + m_state[1] = (m_state[1] * c_defMagicNumber) + 1; + m_state[2] = zipUpdateCRC32(m_state[1] >> 24, m_state[2]); + return result; +} + +void GLDZipDecryptEngine::decodeBuffer(char *buffer, int count) +{ + long lTemp; + char* cBuffer; + long workState[3]; + + //check for programming error + assert(m_ready); + + //move the state to a local variable--for better speed + workState[0] = m_state[0]; + workState[1] = m_state[1]; + workState[2] = m_state[2]; + + //reference the buffer as a PChar--easier arithmetic + cBuffer = buffer; + + //for each byte in the buffer... + for (int i = 0; i < count; i++) + { + //calculate the next decoded byte (uses inlined decrypt_byte) + lTemp = (workState[2] & 0xffff) | 2; + *cBuffer = char((*cBuffer) ^ (lTemp * (lTemp ^ 1)) >> 8); + //mix the decoded byte into the state (uses inlined update_keys) + workState[0] = zipUpdateCRC32(*cBuffer, workState[0]); + workState[1] = workState[1] + (workState[0] & 0xFF); + workState[1] = (workState[1] * c_defMagicNumber) + 1; + workState[2] = zipUpdateCRC32((unsigned char)(workState[1] >> 24), workState[2]); + cBuffer++; + } + + //save the state + m_state[0] = workState[0]; + m_state[1] = workState[1]; + m_state[2] = workState[2]; +} + +bool GLDZipDecryptEngine::verifyHeader(const unsigned char header[], const GString &passPhrase, long checkValue) +{ + long lTemp; + unsigned char workheader[12];; + + //check for programming errors + assert(passPhrase != ""); + + //initialize the decryption state} + zdeInitState(passPhrase); + + //decrypt the bytes in the header} + for (int i = 0; i < 12; i++) + { + //calculate the next decoded byte (uses inlined decrypt_byte) + lTemp = (m_state[2] & 0xffff) | 2; + workheader[i] = header[i] ^ ((lTemp * (lTemp ^ 1)) >> 8); + //mix the decoded byte into the state (uses inlined update_keys) + m_state[0] = zipUpdateCRC32(workheader[i], m_state[0]); + m_state[1] = m_state[1] + (m_state[0] & 0xff); + m_state[1] = (m_state[1] * c_defMagicNumber) + 1; + m_state[2] = zipUpdateCRC32(m_state[1] >> 24, m_state[2]); + } + + //the header is valid if the twelfth byte of the decrypted header + // equals the fourth byte of the check value} + bool result = (workheader[11] == ((checkValue & 0xff000000) >> 24)); + + // {note: zips created with PKZIP prior to version 2.0 also checked + // that the tenth byte of the decrypted header equals the third + // byte of the check value} + m_ready = result; + return result; +} + +void GLDZipDecryptEngine::zdeInitState(const GString &passPhras) +{ + m_state[0] = c_defStateInit1; + m_state[1] = c_defStateInit2; + m_state[2] = c_defStateInit3; + + //mix in the passphrase to the state (uses inlined update_keys) + for (int i = 0; i < passPhras.length(); i++) + { + m_state[0] = zipUpdateCRC32(passPhras.at(i).unicode(), m_state[0]); + m_state[1] = m_state[1] + (m_state[0] & 0xFF); + m_state[1] = (m_state[1] * c_defMagicNumber) + 1; + m_state[2] = zipUpdateCRC32(m_state[1] >> 24, m_state[2]); + } +} + +GLDZipDecryptStream::GLDZipDecryptStream(GStream *stream, long checkValue, const GString passPhrase) +{ + m_stream = stream; + m_checkValue = checkValue; + m_passPhrase = passPhrase; + m_Engine = new GLDZipDecryptEngine(); + open(GStream::ReadWrite); +} + +GLDZipDecryptStream::~GLDZipDecryptStream() +{ + freeAndNil(m_Engine); +} + +bool GLDZipDecryptStream::isValid() +{ + unsigned char header[12] = {'\0'}; + + //Read the header from the stream + m_stream->read((char *)header, sizeof(header)); + + //check to see if the decryption engine agrees it's valid} + bool result = m_Engine->verifyHeader(header, m_passPhrase, m_checkValue); + + //if it isn't valid, reposition the stream, ready for the next try} + if (!result) + { + int nPosition = m_stream->pos(); + m_stream->seek(nPosition - sizeof(header)); + m_Ready = false; + } + else + m_Ready = true; + return result; +} + +long GLDZipDecryptStream::seek(long offset, GSeekOrigin origin) +{ + switch (origin) + { + case soBeginning: + return m_stream->seek(offset); + case soEnd: + return m_stream->seek(size() + offset); + default: + return m_stream->seek(pos() + offset); + } +} + +gint64 GLDZipDecryptStream::size() const +{ + return m_stream->size(); +} + +gint64 GLDZipDecryptStream::pos() const +{ + return m_stream->pos(); +} + +bool GLDZipDecryptStream::seek(gint64 off) +{ + GStream::seek(off); + return m_stream->seek(off); +} + +gint64 GLDZipDecryptStream::readData(char *data, gint64 maxlen) +{ + if ((maxlen = min(maxlen, gint64(size() - pos()))) <= 0) + { + return gint64(0); + } + assert(m_Ready); + long result = m_stream->read(data, maxlen); + m_Engine->decodeBuffer(data, result); + return result; +} + +gint64 GLDZipDecryptStream::writeData(const char *data, gint64 len) +{ + G_UNUSED(data); + G_UNUSED(len); + assert(false); + return 0; +} + +GLDZipEncryptEngine::GLDZipEncryptEngine() +{ + m_ready = false; +} + +GLDZipEncryptEngine::~GLDZipEncryptEngine() +{ +} + +unsigned char GLDZipEncryptEngine::encode(unsigned char ch) +{ + long lTemp; + unsigned char result; + assert(m_ready); + //check for programming error} + + //calculate the encoded byte (uses inlined decrypt_byte)} + lTemp = (m_state[2] & 0xffff) | 2; + result = ch ^ ((lTemp * (lTemp ^ 1)) >> 8); + + //mix the unencoded byte into the state (uses inlined update_keys)} + m_state[0] = zipUpdateCRC32(ch, m_state[0]); + m_state[1] = m_state[1] + (m_state[0] & 0xFF); + m_state[1] = (m_state[1] * c_defMagicNumber) + 1; + m_state[2] = zipUpdateCRC32(m_state[1] >> 24, m_state[2]); + return result; +} + +void GLDZipEncryptEngine::encodeBuffer(char *buffer, int count) +{ + unsigned char uch; + long lTemp; + char *cBuffer; + long workState[3]; + //check for programming error} + assert(m_ready); + //move the state to a local variable--for better speed} + workState[0] = m_state[0]; + workState[1] = m_state[1]; + workState[2] = m_state[2]; + + //reference the buffer as a PChar--easier arithmetic} + cBuffer = (char *)buffer; + + //for each byte in the buffer...} + for (int i = 0; i < count; i++) + { + //calculate the next encoded byte (uses inlined decrypt_byte) + lTemp = (workState[2] & 0xffff) | 2; + uch = (*cBuffer) & 0xff; + *cBuffer = uch ^ ((lTemp * (lTemp ^ 1)) >> 8); + //mix the decoded byte into the state (uses inlined update_keys) + workState[0] = zipUpdateCRC32(uch, workState[0]); + workState[1] = workState[1] + (workState[0] & 0xFF); + workState[1] = (workState[1] * c_defMagicNumber) + 1; + workState[2] = zipUpdateCRC32(workState[1] >> 24, workState[2]); + //move onto the next byte + cBuffer++; + } + //save the state} + m_state[0] = workState[0]; + m_state[1] = workState[1]; + m_state[2] = workState[2]; +} + +void GLDZipEncryptEngine::createheader(unsigned char *header, const GString passphrase, long checkValue) +{ + unsigned char uch; + long lTemp; + unsigned char workheader[12]; + //check for programming errors} + assert(passphrase != ""); + + //set the first ten bytes of the header with random values (in fact, + //we use a random value for each byte and mix it in with the state)} + + //initialize the decryption state} + zeeInitState(passphrase); + + //for the first ten bytes...} + for (int i = 0; i < 10; i++) + { + uch = rand(); + //calculate the XOR encoding byte (uses inlined decrypt_byte) + lTemp = (m_state[2] & 0xffff) | 2; + lTemp = (lTemp * (lTemp ^ 1)) >> 8; + //mix the unencoded byte into the state (uses inlined update_keys) + m_state[0] = zipUpdateCRC32(uch, m_state[0]); + m_state[1] = m_state[1] + (m_state[0] & 0xFF); + m_state[1] = (m_state[1] * c_defMagicNumber) + 1; + m_state[2] = zipUpdateCRC32(m_state[1] >> 24, m_state[2]); + //set the current byte of the header + workheader[i] = uch ^ lTemp; + } + //now encrypt the first ten bytes of the header (this merely sets up + //the state so that we can encrypt the last two bytes)} + + //reinitialize the decryption state} + zeeInitState(passphrase); + + //for the first ten bytes...} + for (int i = 0; i < 10; i++) + { + //calculate the XOR encoding byte (uses inlined decrypt_byte) + lTemp = (m_state[2] & 0xffff) | 2; + lTemp = (lTemp * (lTemp ^ 1)) >> 8; + //mix the unencoded byte into the state (uses inlined update_keys) + + m_state[0] = zipUpdateCRC32(workheader[i], m_state[0]); + m_state[1] = m_state[1] + (m_state[0] & 0xFF); + m_state[1] = (m_state[1] * c_defMagicNumber) + 1; + m_state[2] = zipUpdateCRC32(m_state[1] >> 24, m_state[2]); + //set the current byte of the header + workheader[i] = workheader[i] ^ lTemp; + } + + //now initialize byte 10 of the header, and encrypt it} + uch = (checkValue & 0x00ff0000) >> 16; + lTemp = (m_state[2] & 0xffff) | 2; + lTemp = (lTemp * (lTemp ^ 1)) >> 8; + m_state[0] = zipUpdateCRC32(uch, m_state[0]); + m_state[1] = m_state[1] + (m_state[0] & 0xFF); + m_state[1] = (m_state[1] * c_defMagicNumber) + 1; + m_state[2] = zipUpdateCRC32(m_state[1] >> 24, m_state[2]); + workheader[10] = uch ^ lTemp; + + //now initialize byte 11 of the header, and encrypt it} + uch = (unsigned char)((checkValue & 0xff000000) >> 24); + lTemp = (m_state[2] & 0xFFFF) | 2; + lTemp = (lTemp * (lTemp ^ 1)) >> 8; + m_state[0] = zipUpdateCRC32(uch, m_state[0]); + m_state[1] = m_state[1] + (m_state[0] & 0xFF); + m_state[1] = (m_state[1] * c_defMagicNumber) + 1; + m_state[2] = zipUpdateCRC32(m_state[1] >> 24, m_state[2]); + workheader[11] = uch ^ lTemp; + + //{we're now ready to encrypt} + m_ready = true; + + // {return the header} + for (int i = 0; i < 12; i++) + { + *(header + i) = workheader[i]; + } +} + +void GLDZipEncryptEngine::zeeInitState(const GString passPhrase) +{ + //{initialize the decryption state} + m_state[0] = c_defStateInit1; + m_state[1] = c_defStateInit2; + m_state[2] = c_defStateInit3; + + //{mix in the passphrase to the state (uses inlined update_keys)} + for (int i = 0; i < passPhrase.length(); i++) + { + m_state[0] = zipUpdateCRC32(passPhrase.at(i).unicode(), m_state[0]); + m_state[1] = m_state[1] + (m_state[0] & 0xFF); + m_state[1] = (m_state[1] * c_defMagicNumber) + 1; + m_state[2] = zipUpdateCRC32(m_state[1] >> 24, m_state[2]); + } +} + +GLDZipEncryptStream::GLDZipEncryptStream(GStream *stream, long checkValue, const GString passPhrase) +{ + m_stream = stream; + m_Engine = new GLDZipEncryptEngine(); + unsigned char header[12]; + m_Engine->createheader(header, passPhrase, checkValue); + stream->write((char*)&header, sizeof(header)); + m_buffer = NULL; + m_bufSize = 0; + open(GStream::ReadWrite); +} + +GLDZipEncryptStream::~GLDZipEncryptStream() +{ + if (m_buffer != NULL) + freeAndNil(m_buffer); + freeAndNil(m_Engine); +} + +long GLDZipEncryptStream::seek(long offset, GSeekOrigin origin) +{ + switch (origin) + { + case soBeginning: + return m_stream->seek(offset); + case soEnd: + return m_stream->seek(size() + offset); + default: + return m_stream->seek(pos() + offset); + } +} + +gint64 GLDZipEncryptStream::size() const +{ + return m_stream->size(); +} + +gint64 GLDZipEncryptStream::pos() const +{ + return m_stream->pos(); +} + +bool GLDZipEncryptStream::seek(gint64 off) +{ + GStream::seek(off); + return m_stream->seek(off); +} + +gint64 GLDZipEncryptStream::readData(char *data, gint64 maxlen) +{ + G_UNUSED(data); + G_UNUSED(maxlen); + return 0; +} + +gint64 GLDZipEncryptStream::writeData(const char *data, gint64 len) +{ + long result = 0; + if (m_bufSize < len) + { + if (m_buffer != NULL) + freeAndNil(m_buffer); + m_buffer = new char[len + 1]; + m_bufSize = len; + } + for (int i = 0; i < len; i++) + { + m_buffer[i] = *data++; + } +// m_buffer[len] = '\0'; + + m_Engine->encodeBuffer(m_buffer, len); + result = m_stream->write(m_buffer, len); + return result; +} + diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDZipFile.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDZipFile.cpp new file mode 100644 index 00000000..b3e7f1a4 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDZipFile.cpp @@ -0,0 +1,3682 @@ +#include "GLDZipFile.h" + +#include "GLDZlib.h" +#include "GLDObject.h" +#include "GLDZipEnc.h" +#include "GLDStrings.h" +#include "GLDStrUtils.h" +#include "GLDSysUtils.h" +#include "GLDMathUtils.h" +#include "GLDException.h" +#include "GLDStreamUtils.h" +#ifdef WIN32 +#include "LzmaLib.h" +#endif + +interface IGLDZipPersistent; + +#pragma pack(push, 1) +struct GLDCommonFileHeader +{ + unsigned short VersionNeededToExtract; // 2 bytes + unsigned short GeneralPurposeBitFlag; // 2 bytes + unsigned short CompressionMethod; // 2 bytes + unsigned int LastModFileTimeDate; // 4 bytes + unsigned int CRC32; // 4 bytes + unsigned int CompressedSize; // 4 bytes + unsigned int UncompressedSize; // 4 bytes + unsigned short FilenameLength; // 2 bytes + unsigned short ExtraFieldLength; // 2 bytes +}; + +#pragma pack(pop) + +#pragma pack(push, 1) +struct GLDCentralFileHeader +{ + unsigned int CentralFileHeaderSignature; // 4 bytes (0x02014b50, 'PK'12) + unsigned short VersionMadeBy; // 2 bytes + GLDCommonFileHeader CommonFileHeader; // + unsigned short FileCommentLength; // 2 bytes + unsigned short DiskNumberStart; // 2 bytes + unsigned short InternalFileAttributes; // 2 bytes + unsigned int ExternalFileAttributes; // 4 bytes + unsigned int RelativeOffsetOfLocalHeader; // 4 bytes +}; + +#pragma pack(pop) + +#pragma pack(push, 1) +struct GLDEndOfCentralDirectory +{ + unsigned int EndOfCentralDirSignature; // 4 bytes (0x06054b50, 'PK'56) + unsigned short NumberOfThisDisk; // 2 bytes + unsigned short NumberOfTheDiskWithTheStart; // 2 bytes + unsigned short TotalNumberOfEntriesOnThisDisk; // 2 bytes + unsigned short TotalNumberOfEntries; // 2 bytes + unsigned int SizeOfTheCentralDirectory; // 4 bytes + unsigned int OffsetOfStartOfCentralDirectory; // 4 bytes + unsigned short ZipfileCommentLength; // 2 bytes +}; + +#pragma pack(pop) + +#pragma pack(push, 1) +struct GLDZipDataDescriptor +{ + unsigned int DataDescSignature; // 4 bytes (0x08074B50, 'PK'78) + unsigned int CRC32; // 4 bytes + unsigned int CompressedSize; // 4 bytes + unsigned int UncompressedSize; // 4 bytes +}; + +#pragma pack(pop) + +#pragma pack(push, 1) +struct GLDZipFileCompressedData +{ + GStream *stream; // 4 bytes (0x08074B50, 'PK'78) + long CRC32; // 4 bytes + long CompressedSize; // 4 bytes + long UncompressedSize; // 4 bytes +}; + +#pragma pack(pop) + +DEFINE_IID(IGLDZipPersistent, "{5090E978-509E-43F6-8C97-32B9A49B6E3B}"); +DECLARE_INTERFACE_(IGLDZipPersistent, IUnknown) +{ + GLDMETHOD(void, loadCentralDirectory)(GStream *stream) PURE; + GLDMETHOD(void, loadDataDescriptor)(GStream *stream) PURE; + GLDMETHOD(void, loadLocalFileHeader)(GStream *stream) PURE; + GLDMETHOD(void, saveCentralDirectory)(GStream *stream) PURE; + GLDMETHOD(void, saveDataDescriptor)(GStream *stream) PURE; + GLDMETHOD(void, saveLocalFileHeader)(GStream *stream) PURE; +}; + +class CGLDZipFile; + +class CGLDZipFileEntry: public GInterfaceObject, public IGLDZipFileEntry, public IGLDZipPersistent +{ +public: + CGLDZipFileEntry(CGLDZipFile *zipFile, const GString &name = "", unsigned int AttriBute = 0, double timeStamp = 0, const GString &dirname = "", unsigned short CompressionMethod = 8); //c_mDeflated = 8 + virtual ~CGLDZipFileEntry(); +public: + DECLARE_IUNKNOWN + int GLDMETHODCALLTYPE attriButes(); + unsigned long GLDMETHODCALLTYPE compressedSize(); + unsigned short compressionMethod(); + unsigned long GLDMETHODCALLTYPE crc32(); + + // 该接口会有GByteArray溢出情况,因此废弃该接口,请使用GStream *data() + // GByteArray GLDMETHODCALLTYPE data(); + GStream *GLDMETHODCALLTYPE data(); + + double GLDMETHODCALLTYPE dateTime(); + GByteArray extrafield(); + GString fileComment(); + unsigned short internalAttributes(); + bool GLDMETHODCALLTYPE isEncrypted(); + GLDZipCompressionLevel level(); + GString GLDMETHODCALLTYPE name(); + IGLDZipFile* GLDMETHODCALLTYPE owner(); + unsigned long GLDMETHODCALLTYPE uncompressedSize(); + + void GLDMETHODCALLTYPE setAttriButes(const int value); + + // 该接口会有GByteArray溢出情况,建议使用setData(GStream *value) + void GLDMETHODCALLTYPE setData(GByteArray value); + void GLDMETHODCALLTYPE setData(GStream *value); + + void GLDMETHODCALLTYPE setDateTime(const double value); + + void GLDMETHODCALLTYPE loadFromFile(const GString file); + void GLDMETHODCALLTYPE saveToFile(const GString file); + void GLDMETHODCALLTYPE loadFromStream(GStream *stream); + void GLDMETHODCALLTYPE saveToStream(GStream *stream); + void GLDMETHODCALLTYPE compressFromFile(const GString file); + void GLDMETHODCALLTYPE decompressToFile(const GString file); + + /*IZipPersistent */ + void GLDMETHODCALLTYPE loadCentralDirectory(GStream *stream); + void GLDMETHODCALLTYPE loadDataDescriptor(GStream *stream); + void GLDMETHODCALLTYPE loadLocalFileHeader(GStream *stream); + void GLDMETHODCALLTYPE saveCentralDirectory(GStream *stream); + void GLDMETHODCALLTYPE saveDataDescriptor(GStream *stream); + void GLDMETHODCALLTYPE saveLocalFileHeader(GStream *stream); + +protected: + HRESULT STDMETHODCALLTYPE _QueryInterface(REFIID riid, void **ppvObject); + +public: + unsigned short versionMadeBy(); + void setExtrafield(const GByteArray &value); + void setFileComment(const GString &value); + void setLevel(const GLDZipCompressionLevel Value); + +protected: + IGLDZipFileEntry *intf(); + bool hasPassWord(); + +private: + bool buildDecryptStream(GStream *stream, GLDZipDecryptStream **decrypter); + bool buildEncryptStream(GStream *stream, GLDZipEncryptStream **encrypter); + + bool decryptZipData(GStream *data, GBlockMemoryStream *result); + bool encryptZipData(GStream *data, GBlockMemoryStream *result); + bool decompressZLibData(GStream *data, int size, GBlockMemoryStream *result); +#ifdef WIN32 + bool compress7ZData(GStream *result, GStream *data); +#endif + bool compressZLibData(GStream *data, GStream *result); + bool decompressZLibFile(GStream *data, const GString &file); + bool compressZLibFile(const GString &file, GLDZipFileCompressedData *data); + + GStream *bZip2Data(); + GStream *storedData(); + GStream *zLibData(); + GByteArray zLibStreamHeader(); + + void parseEntry(); + void setBZip2Data(GStream *data); + void setStoredData(GStream *data); + void setZLibData(GStream *data); +#ifdef WIN32 + void set7zData(GStream *data); +#endif + CGLDZipFileEntry *intfObj(); + + // add + unsigned long zipUpdateCRC32FromStream(GStream *stream); + bool encryptZipStream(GStream *stream); +// void bZip2Stream(GStream *streamRult); + void storedStream(GStream *streamResult); + void zLibStream(GStream *streamRult); +#ifdef WIN32 + void store7zStream(GStream *streamRult); +#endif + bool decompressToStream(GStream *instream, GStream *outStream); +#ifdef WIN32 + bool decompressTo7zStream(GStream *instream, GStream *outStream); +#endif + bool decryptZipStream(GStream *streamResult); + +private: + CGLDZipFile *m_zipFile; + GString m_fileName; + GString m_dirName; + GLDCentralFileHeader m_centralDirectory; + GLDCommonFileHeader m_commonFileHeader; + //GByteArray存在开辟失败问题 +// GByteArray m_compressedData; + GStream *m_compressedData; + + GByteArray m_extrafield; + GString m_fileComment; + GStream *m_memStream; + GLDZipCompressionLevel m_level; +}; + +typedef GInterfaceObjectList GLDZipFileEntryList; + +class CGLDZipList +{ +public: + CGLDZipList(); + ~CGLDZipList(); +public: + int add(CGLDZipFileEntry *item); + CGLDZipFileEntry* find(const GString &name); + int indexOf(CGLDZipFileEntry *item); + int indexOf(const GString &name); + GString fileSuffixToLower(const GString &name); + int remove(CGLDZipFileEntry *item); + void clear(); + void deleteItem(int index); + void insert(int index, CGLDZipFileEntry *item); + int count(); + void setItem(int index, CGLDZipFileEntry *value); + CGLDZipFileEntry* item(int index); +private: + GLDZipFileEntryList m_list; +}; + +class CGLDZipFile: public GInterfaceObject, public IGLDZipFile +{ +public: + CGLDZipFile(); + ~CGLDZipFile(); +public: + DECLARE_IUNKNOWN + /*IZipFile */ + int GLDMETHODCALLTYPE count(); + GByteArray GLDMETHODCALLTYPE customFileHeader(); + GString GLDMETHODCALLTYPE fileComment(); + IGLDZipFileEntry* GLDMETHODCALLTYPE items(int index); + GLDZipCompressionLevel GLDMETHODCALLTYPE level(); + GString GLDMETHODCALLTYPE password(); + void GLDMETHODCALLTYPE setCustomFileHeader(GByteArray value); + void GLDMETHODCALLTYPE setFileComment(const GString value); + void GLDMETHODCALLTYPE setLevel(const GLDZipCompressionLevel value); + void GLDMETHODCALLTYPE setPassword(const GString value); + IGLDZipFileEntry* GLDMETHODCALLTYPE add(const GString name) /*overload */; + IGLDZipFileEntry* GLDMETHODCALLTYPE add(const GString name, unsigned int attriBute, double timeStamp) /*overload */; + int GLDMETHODCALLTYPE addFiles(const GString folder, const GString base = "", bool recursion = true, + const GString fileMask = "", int searchAttr = 0); + IGLDZipFileEntry* GLDMETHODCALLTYPE addFromBuffer(const GString &name, void *buffer, int count); + IGLDZipFileEntry* GLDMETHODCALLTYPE addFromFile(const GString &name, const GString &file); + IGLDZipFileEntry* GLDMETHODCALLTYPE addFromStream(const GString &name, GStream *stream); + int GLDMETHODCALLTYPE indexOf(const GString name); + IGLDZipFileEntry* GLDMETHODCALLTYPE find(const GString name); + void GLDMETHODCALLTYPE clear(); + void GLDMETHODCALLTYPE deleteItem(int index); + void GLDMETHODCALLTYPE extractFiles(const GString folder, const GString nameMask = ""); + void GLDMETHODCALLTYPE extractToBuffer(const GString name, int *buffer, int count); + void GLDMETHODCALLTYPE extractToStream(const GString &name, GStream *stream); + void GLDMETHODCALLTYPE extractToString(const GString name, GByteArray *text); + void GLDMETHODCALLTYPE loadFromFile(const GString file); + void GLDMETHODCALLTYPE saveToFile(const GString file); + void GLDMETHODCALLTYPE loadFromStream(GStream *stream); + void GLDMETHODCALLTYPE saveToStream(GStream *stream); + IGLDZipGetPassWordEvent* GLDMETHODCALLTYPE getOnGetPassword(); + void GLDMETHODCALLTYPE setOnGetPassword(IGLDZipGetPassWordEvent *value); +protected: + HRESULT STDMETHODCALLTYPE _QueryInterface(REFIID riid, void **ppvObject); +public: + CGLDZipFileEntry* itemObjs(int index); + CGLDZipFileEntry* findObj(const GString &name); + CGLDZipFileEntry* addObj(const GString &name); + CGLDZipFileEntry* addObj(const GString &name, unsigned int attriBute, double timeStamp); + CGLDZipFileEntry* addObj(const GString &name, const GString &dirname); + CGLDZipFileEntry* addObj(const GString &name, unsigned int attriBute, double timeStamp, const GString &dirname); + CGLDZipFileEntry* addFromBufferObj(const GString &name, void *buffer, int count); + CGLDZipFileEntry* addFromFileObj(const GString &name, const GString &file); + CGLDZipFileEntry* addFromStreamObj(const GString &name, GStream *stream); + GString findPassWord(CGLDZipFileEntry *entry); +private: + void loadEndOfCentralDirectory(GStream *stream); + void saveEndOfCentralDirectory(GStream *stream, long centralDirectoryOffset); + + bool findSignature(GStream *stream, long signature, long endSignature = 0); + bool findCustomFileHeader(GStream *stream); + bool findCustomFileHeaderBySignature(GStream *stream); +private: + CGLDZipList *m_files; + GLDZipCompressionLevel m_level; + GString m_fileComment, m_PassWord; + GLDEndOfCentralDirectory m_endOfCentralDir; + GByteArray m_customFileHeader; + IGLDZipGetPassWordEvent *m_onGetPassword; +}; + +class CGLDBufferedStreamReader: public GStream +{ +public: + CGLDBufferedStreamReader(GStream *stream, int bufferSize = 1024); + virtual ~CGLDBufferedStreamReader(); +public: + long read(long &buffer, long count); + long write(const long buffer, long count); + long seek(long offset, long origin); +private: + void updateBufferFromPosition(int startPos); +private: + GStream *m_stream; + int m_streamSize; + GByteArray m_buffer; + int m_bufferSize; + int m_bufferStartPosition; + int m_virtualPosition; +}; + +//class CGLDBufferedFileReader: public CGLDBufferedStreamReader +//{ +//public: +// CGLDBufferedFileReader(const GString &fileName); +// ~CGLDBufferedFileReader(); +//}; + +//i18n +const char *rsErrEncryptedFile = QT_TRANSLATE_NOOP("GLD", "Can`t handle the compressed file");//"文件被加密,无法处理"); +const char *rsErrEncryptedZipData = QT_TRANSLATE_NOOP("GLD", "Compressed data errors");//"压缩数据出错"); +const char *rsErrFileCrc32 = QT_TRANSLATE_NOOP("GLD", "File %s CRC32 check error");//"文件 %s CRC32 检验出错"); +const char *rsErrFilePassWord = QT_TRANSLATE_NOOP("GLD", "File password is incorrect");//"文件密码不正确"); +const char *rsErrFolderNotExist = QT_TRANSLATE_NOOP("GLD", "The directory %s does not exist");//"目录 %s 不存在"); +const char *rsErrIndexOutOfBand = QT_TRANSLATE_NOOP("GLD", "Access index out of bounds");//"访问索引越界"); +const char *rsErrUnSupportMethod = QT_TRANSLATE_NOOP("GLD", "Unknown compression method %d");//"未知的压缩方法 %d"); + +const char *rsErrCompressFromFile = QT_TRANSLATE_NOOP("GLD", "Algorithm can only be the ZLIB, and can not be"\ + "encrypted, and is mainly used for the compression of large"\ + "files, and save memory"); +//"压缩算法只能是 ZLIB,而且不能加密,主要用于超大文件的压缩,节省内存"); + +const char *rsErrDecompressFile = QT_TRANSLATE_NOOP("GLD", "Decompress algorithm only is the ZLIB and can not"\ + "be encrypted, and is mainly used for the compression of "\ + "large files, and save memory"); +//"解压缩算法只能是 ZLIB,而且不能加密,主要用于超大文件的压缩,节省内存"); + +const char *rsErrDecompressToFile = QT_TRANSLATE_NOOP("GLD", "Extracting data to a file error");//"解压数据到文件出错"); + +const char *rsErrFileHeader = QT_TRANSLATE_NOOP("GLD", "Compressed file formats are illegal."\ + "We can not read file header information"); + //"压缩文件格式非法,无法读取文件头信息"); + +const char *rsErrExtractPassWord = QT_TRANSLATE_NOOP("GLD", "Incorrect extraction password");//"解压密码不正确"); +const char *rsErrMaxLenPassWord = QT_TRANSLATE_NOOP("GLD", "Compression password longer than 80 characters");//"压缩密码长度超过 80 字符"); + +const GString c_defZipFileName = "=^0^="; + +const int c_defFileIsEncrypted = 0x0001; +const int c_defHasDataDescriptor = 0x0008; +const long c_CentralFileHeaderSignature = 0x02014b50; +const long c_LocalFileHeaderSignature = 0x04034B50; +const long c_EndOfCentralDirSignature = 0x06054B50; +const long c_DataDescSignature = 0x08074B50; + +const long c_FileHeaderSignature = 0x20444C47; +const int c_defMaxFileHeaderSize = 64; +const int c_defMaxPassWordLen = 80; + +const int c_mStored = 0; +//const int c_mShrunk = 1; +//const int c_mReduced1 = 2; +//const int c_mReduced2 = 3; +//const int c_mReduced3 = 4; +//const int c_mReduced4 = 5; +//const int c_mImploded = 6; +//const int c_mTokenizingReserved = 7; +const int c_mDeflated = 8; +//const int c_mDeflated64 = 9; +//const int c_mDCLImploding = 10; +//const int c_mPKWAREReserved = 11; +const int c_mBZip2 = 12; +const int c_7Zip = 15; +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.05.10 +//功能: 创建一个压缩文件子对象 +//参数: +//////////////////////////////////////////////////////////////////////////////// +IGLDZipFileEntry* createZipFileEntry(IGLDZipFile *zipFile, const GString &zipFileName) +{ + CGLDZipFileEntry *result = new CGLDZipFileEntry(dynamic_cast(zipFile), zipFileName); + return result; +} +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2006.01.29 +//功能: 创建一个压缩文件对象 +//参数: +//////////////////////////////////////////////////////////////////////////////// +IGLDZipFile* createZipFile(const GString &passWord) +{ + CGLDZipFile *result = new CGLDZipFile(); + result->setPassword(passWord); + if (result) + result->AddRef(); + return result; +} + +GLDZipFile createZipFileSPtr(const GString &password) +{ + CGLDZipFile *result = new CGLDZipFile(); + result->setPassword(password); + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2006.01.29 +//功能: 由文件加载对象 +//参数: +//////////////////////////////////////////////////////////////////////////////// +IGLDZipFile* loadZipFile(const GString &file, const GString &passWord) +{ + IGLDZipFile *result = createZipFile(passWord); + result->loadFromFile(file); + return result; +} + +GLDZipFile loadZipFileSPtr(const GString &file, const GString &password) +{ + GLDZipFile result = createZipFileSPtr(password); + result.loadFromFile(file); + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2006.01.29 +//功能: 由内存流加载对象 +//参数: +//////////////////////////////////////////////////////////////////////////////// +IGLDZipFile* loadZipFile(GStream *stream, const GString &passWord) +{ + assert(stream != NULL); + IGLDZipFile* result = createZipFile(passWord); + result->loadFromStream(stream); + return result; +} + +GLDZipFile loadZipFileSPtr(GStream *stream, const GString &password) +{ + assert(NULL != stream); + GLDZipFile result = createZipFileSPtr(password); + result.loadFromStream(stream); + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计:Linc 2009.05.13 +//功能:压缩文件 +//参数: +//////////////////////////////////////////////////////////////////////////////// +int compressZipFiles(const GString &file, const GString &folder, const GString &nameMask) +{ + int result = 0; + GLDZipFile oZip = createZipFileSPtr(""); + try + { + oZip.addFiles(folder, "", true, nameMask); + oZip.saveToFile(file); + result = oZip.count(); + } + catch (...) + { + result = 0; + } + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计:Linc 2009.05.12 +//功能:解压文件 +//参数: +//////////////////////////////////////////////////////////////////////////////// +int extractZipFiles(const GString &file, const GString &folder, const GString &nameMask) +{ + int result = 0; + try + { + GLDZipFile oZip = loadZipFileSPtr(file, ""); + oZip.extractFiles(folder, nameMask); + result = oZip.count(); + } + catch(...) + { + result = 0; + } + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2006.01.30 +//功能: 转换文件路径 +//参数: +//////////////////////////////////////////////////////////////////////////////// +GString fileNameToZipName(const GString &name) +{ + GString result = stringReplace(name, "\\", "/"); + int nIndex = result.indexOf(":/"); + if (nIndex >= 0) + { + result = result.mid(nIndex); + } + nIndex = result.indexOf("//"); + if (nIndex >= 0) + { + result = result.mid(nIndex); + nIndex = result.indexOf("/"); + if (nIndex >= 0) + { + result = result.mid(nIndex); + nIndex = result.indexOf("/"); + if (nIndex >= 0) + result = result.mid(nIndex); + } + } + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计:Linc 2010.03.01 +//功能:在缓冲区中查找指定内容 +//参数: +//注意:偷懒,直接借助 Pos 的实现,多了一个开辟内存的动作 +//////////////////////////////////////////////////////////////////////////////// +int posData(int data, int len, const GByteArray &s) +{ + GByteArray strData = GByteArray(); + strData = strData.append((char *)&data, len); + GString res = GString(s); + GString des = GString(strData); + return res.indexOf(des); +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2006.01.30 +//功能: 转换文件路径 +//参数: +//////////////////////////////////////////////////////////////////////////////// +GString zipNameToFileName(const GString &name) +{ + return stringReplace(name, "/", "\\"); +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2004.08.22 +//功能: 判断一个文件是否为压缩文件 +//参数: +//////////////////////////////////////////////////////////////////////////////// +bool isZipFile(const GString &file) +{ + bool result = false; + + GFileStream fileStream(file); + try + { + if (!fileStream.open(GFileStream::ReadOnly)) + { + fileStream.close(); + return false; + } + fileStream.seek(0); + result = isZipStream(&fileStream); + } + catch(...) + { + fileStream.close(); + throw; + } + fileStream.close(); + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2004.08.22 +//功能: 判断一个流是否为 ZIP 压缩流 +//参数: +//注意:可能需要跳过存在的自定义数据头 +// 如果非标准的自定义头,默认只判断开始的 64 字节内容 defMaxFileHeaderSize +// 读流时避免再多读头 4 个字节一次 +// 返回 True 时 Position 会定位到 conLocalFileHeaderSignature 之后的位置 +//////////////////////////////////////////////////////////////////////////////// +bool isZipStream(GStream *stream) +{ + bool bresult = false; + int nLen(0); + int nPos(0); + int nPosition(0); + unsigned long uSignature; + assert(stream != NULL); + try + { + stream->read((char *)&uSignature, sizeof(uSignature)); + if (uSignature == (unsigned long)c_LocalFileHeaderSignature) + bresult = true; + else if (uSignature == (unsigned long)c_FileHeaderSignature) + { + stream->read((char *)&nLen, sizeof(unsigned long)); + nPosition = stream->pos(); + stream->seek(nPosition + nLen); + stream->read((char *)&uSignature, sizeof(unsigned long)); + bresult = (uSignature == (unsigned long)c_LocalFileHeaderSignature); + } + else + { + GByteArray strBuffer; + strBuffer.resize(c_defMaxFileHeaderSize); + strBuffer.append((char *)&uSignature, sizeof(unsigned long)); + nLen = stream->read(strBuffer.data() + sizeof(unsigned long), strBuffer.length() - sizeof(unsigned long)); + nLen += sizeof(unsigned long); + strBuffer.resize(nLen); + nPos = posData(c_LocalFileHeaderSignature, sizeof(unsigned long), strBuffer); + bresult = nPos > 0; + if (bresult) + { + nPosition = stream->pos(); + stream->seek(nPosition + nPos - nLen + sizeof(unsigned long) - 1); + } + } + } + catch (...) + { + bresult = false; + } + return bresult; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计:Linc 2009.06.23 +//功能:判断文件是否加密 +//参数: +//////////////////////////////////////////////////////////////////////////////// +bool isEncryptedZipFile(const GString &file) +{ + bool result = false; + GFileStream *stream = new GFileStream(file); + try + { + stream->open(GFileStream::ReadOnly); + stream->seek(0); + result = isEncryptedZipStream(stream); + } + catch (...) + { + stream->close(); + freeAndNil(stream); + throw; + } + stream->close(); + freeAndNil(stream); + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计:Linc 2009.06.23 +//功能:判断 ZIP 数据流是否加密 +//参数: +//////////////////////////////////////////////////////////////////////////////// +bool isEncryptedZipStream(GStream *stream) +{ + bool result = isZipStream(stream); + if (result) + { + try + { + unsigned short uValue; + // read 2 bytes for VersionNeededToExtractSize + stream->read((char *)&uValue, sizeof(unsigned short)); + // read 2 bytes for GeneralPurposeBitFlagSize + stream->read((char *)&uValue, sizeof(unsigned short)); + // check the encryption flag + result = ((uValue & c_defFileIsEncrypted) != 0); + } + catch (...) + { + result = false; + } + } + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2004.08.18 +//功能: 压缩字串 +//参数: +//////////////////////////////////////////////////////////////////////////////// +GStream *zipText(const GByteArray &s) +{ + GBlockMemoryStream *pResultStream = new GBlockMemoryStream(GStream::ReadWrite); + GBlockMemoryStream *pStreamTemp = new GBlockMemoryStream(GStream::ReadWrite); + + try + { + GLDZipFile cZipFile = createZipFileSPtr(); + + GBlockMemoryStream *pData = new GBlockMemoryStream(GStream::ReadWrite); + pData->write(s); + + cZipFile.add(c_defZipFileName).setData(pData); + cZipFile.saveToStream(pStreamTemp); + pStreamTemp->seek(0); + pResultStream->loadFromStream(pStreamTemp); + } + catch (...) + { + freeAndNil(pStreamTemp); + throw; + } + freeAndNil(pStreamTemp); + return pResultStream; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2004.08.18 +//功能: 解压缩字串 +//参数: +//////////////////////////////////////////////////////////////////////////////// +GStream *unzipText(const GByteArray &s) +{ + GBlockMemoryStream *pResult = new GBlockMemoryStream(GStream::ReadWrite); + GLDZipFile cZipFile; + GBlockMemoryStream *pStream = new GBlockMemoryStream(GStream::ReadWrite); + try + { + pStream->write(s.data(), s.length()); + pStream->seek(0); + cZipFile = loadZipFile(pStream); + if (cZipFile.count() > 0) + { + pResult->loadFromStream(cZipFile.items(0).data()); + } + else + { + pResult->clearData(); + } + } + catch (...) + { + freeAndNil(pStream); + throw; + } + freeAndNil(pStream); + return pResult; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2004.08.25 +//功能: 压缩流 +//参数: +//注意:不能直接压缩 TFileStream,改函数会把处理的结果回写到 Stream 中 +//////////////////////////////////////////////////////////////////////////////// +bool zipStream(GStream *stream, const GString &passWord) +{ + GBlockMemoryStream *pStreamData = new GBlockMemoryStream(GStream::ReadWrite); + + assert(stream != NULL); + stream->seek(0); + GLDZipFile oZipFile = createZipFileSPtr(passWord); + try + { + int nSize = stream->size(); + if (nSize == 0) + { + pStreamData->clearData(); + } + else + { + stream->seek(0); + pStreamData->loadFromStream(stream); + } + pStreamData->seek(0); + oZipFile.add(c_defZipFileName).setData(pStreamData); + + stream->reset(); + oZipFile.saveToStream(stream); + } + catch (...) + { + freeAndNil(pStreamData); + return false; + } + freeAndNil(pStreamData); + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2004.08.25 +//功能: 解压压缩流 +//参数: +//注意:不能直接压缩 TFileStream,改函数会把处理的结果回写到 Stream 中 +//////////////////////////////////////////////////////////////////////////////// +bool unZipStream(GStream *stream, const GString &passWord) +{ + GBlockMemoryStream *pStreamData = new GBlockMemoryStream(GStream::ReadWrite); + + assert(stream != NULL); + stream->seek(0); + + GLDZipFile cZipFile = loadZipFileSPtr(stream, passWord); + try + { + pStreamData->loadFromStream(cZipFile.items(0).data()); + stream->reset(); + stream->write(pStreamData->readAll(), pStreamData->size()); + } + catch(...) + { + freeAndNil(pStreamData); + return false; + } + freeAndNil(pStreamData); + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2004.11.20 +//功能: 压缩流 +//参数: +//////////////////////////////////////////////////////////////////////////////// +bool zipStream(GStream *srcStream, GStream *desStream, const GString &passWord) +{ + GBlockMemoryStream *pStreamData = new GBlockMemoryStream(GStream::ReadWrite); + + assert(srcStream != NULL); + assert(desStream != NULL); + int nSize = srcStream->size(); + if (nSize == 0) + { + pStreamData->clearData(); + } + else + { + srcStream->seek(0); + pStreamData->loadFromStream(srcStream); + } + + GLDZipFile cZipFile = createZipFileSPtr(passWord); + try + { + cZipFile.add(c_defZipFileName); + pStreamData->seek(0); + cZipFile.items(0).setData(pStreamData); + desStream->reset(); + cZipFile.saveToStream(desStream); + } + catch(...) + { + freeAndNil(pStreamData); + return false; + } + freeAndNil(pStreamData); + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2004.11.21 +//功能: 解压缩流 +//参数: +//////////////////////////////////////////////////////////////////////////////// +bool unZipStream(GStream *srcStream, GStream *desStream, const GString &passWord) +{ +// GByteArray strData; + assert(srcStream != NULL); + assert(desStream != NULL); + GLDZipFile oZipFile = createZipFileSPtr(passWord); + try + { + srcStream->seek(0); + oZipFile.loadFromStream(srcStream); + desStream->seek(0); + oZipFile.items(0).saveToStream(desStream); +// strData = oZipFile.items(0).data(); +// desStream->reset(); +// desStream->write(strData.data(), strData.length()); + } + catch(...) + { + return false; + } + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2004.08.28 +//功能: 抛出 ZIP 异常 +//参数: +//////////////////////////////////////////////////////////////////////////////// +void zipFileError(const GString Msg) +{ + throw GLDException(Msg); +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2004.08.28 +//功能: 抛出 ZIP 异常 +//参数: +//////////////////////////////////////////////////////////////////////////////// +//void zipFileError(const GString Msg, const TVarRec *Args, int Args_size) /*overload */ +//{ +// throw EZipFileException createFmt(Msg, Args); +//} + +/*TBufferedStreamReader */ +CGLDBufferedStreamReader::CGLDBufferedStreamReader(GStream *stream, int bufferSize) +{ + m_stream = stream; + m_streamSize = stream->size(); + m_bufferSize = bufferSize; + m_buffer.resize(bufferSize); + m_bufferStartPosition = -m_bufferSize; /*out of any useful range */ + m_virtualPosition = 0; +} + +CGLDBufferedStreamReader::~CGLDBufferedStreamReader() +{ +} + +long CGLDBufferedStreamReader::read(long &Buffer, long Count) +{ + long result = 0; + char *Buf; + int nBytesLeft; + int nFirstBufferRead; + int nStreamDirectRead; + + if ((m_virtualPosition >= 0) && (Count >= 0)) + { + result = m_stream->size() - m_virtualPosition; + if (result > 0) + { + if (result > Count) + result = Count; + Buf = (char *)&Buffer; + nBytesLeft = result; + + nFirstBufferRead = m_bufferStartPosition + m_bufferSize - m_virtualPosition; + if ((nFirstBufferRead < 0) || (nFirstBufferRead > m_bufferSize)) + nFirstBufferRead = 0; + nFirstBufferRead = nFirstBufferRead > result?result:nFirstBufferRead; + if (nFirstBufferRead > 0) + { + for (int i = 0; i < nFirstBufferRead; ++i) + { + *(Buf++) = m_buffer.at(m_virtualPosition - m_bufferStartPosition + i); + } + nBytesLeft -= nFirstBufferRead; + } + + if (nBytesLeft > 0) + { + nStreamDirectRead = (nBytesLeft / m_bufferSize) * m_bufferSize; + m_stream->seek(m_virtualPosition + nFirstBufferRead); + m_stream->read(Buf + nFirstBufferRead, nStreamDirectRead); + nBytesLeft -= nStreamDirectRead; + + if (nBytesLeft > 0) + { + updateBufferFromPosition(m_stream->pos()); + for (int i = 0; i < nBytesLeft; ++i) + { + *(Buf + nFirstBufferRead + nStreamDirectRead + i) = m_buffer.at(i); + } + } + } + m_virtualPosition += result; + return result; + } + } + return 0; +} + +long CGLDBufferedStreamReader::seek(long Offset, long Origin) +{ + switch (Origin) + { + case soBeginning: + m_virtualPosition = Offset; + break; + case soCurrent: + m_virtualPosition += Offset; + break; + case soEnd: + m_virtualPosition = m_streamSize + Offset; + break; + default: + assert(false); + } + return m_virtualPosition; +} + +void CGLDBufferedStreamReader::updateBufferFromPosition(int startPos) +{ + try + { + m_stream->seek(startPos); + m_stream->read(m_buffer.data(), m_bufferSize); + m_bufferStartPosition = startPos; + } + catch(...) + { + m_bufferStartPosition -= m_bufferSize; + throw; /*out of any useful range */ + } +} + +long CGLDBufferedStreamReader::write(const long buffer, long count) +{ + zipFileError(getGLDi18nStr("Internal Error: class can not write.")); + G_UNUSED(buffer); + G_UNUSED(count); + return 0; +} + +/*TBufferedFileReader */ +//////////////////////////////////////////////////////////////////////////////// +//设计:Linc 2010.03.01 +//功能: +//参数: +//注意:不支持大于 2G 的文件,且只支持文件读 +//////////////////////////////////////////////////////////////////////////////// +//CGLDBufferedFileReader::CGLDBufferedFileReader(const GString &fileName) +// : CGLDBufferedStreamReader(new GFileStream(fileName)) +//{ +//} + +//CGLDBufferedFileReader::~CGLDBufferedFileReader() +//{ +// // todo check: inherited::destroy(); +// // freeAndNil(m_stream); +//} + +/*CGLDZipFileEntry */ +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2006.02.01 +//功能: 返回一个解压数据对象 +//参数: +//////////////////////////////////////////////////////////////////////////////// +bool CGLDZipFileEntry::buildDecryptStream(GStream *stream, GLDZipDecryptStream **decrypter) +{ + bool result = false; + unsigned long lEncCRC; + assert(stream != NULL); + if ((m_commonFileHeader.GeneralPurposeBitFlag & c_defHasDataDescriptor) != 0) + lEncCRC = m_commonFileHeader.LastModFileTimeDate << 0x10; + else + lEncCRC = m_commonFileHeader.CRC32; + + GString strPassword = m_zipFile->findPassWord(this); + if (strPassword.length() == 0) + zipFileError(getGLDi18nStr(rsErrExtractPassWord)); + *decrypter = new GLDZipDecryptStream(stream, lEncCRC, strPassword); + try + { + result = (*decrypter)->isValid(); + } + catch (...) + { + if (!result) + freeAndNil(*decrypter); + throw; + } + if (!result) + freeAndNil(*decrypter); + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2006.02.01 +//功能: 返回一个压缩数据处理对象 +//参数: +//////////////////////////////////////////////////////////////////////////////// +bool CGLDZipFileEntry::buildEncryptStream(GStream *stream, GLDZipEncryptStream **encrypter) +{ + bool result; + unsigned long lEncCRC; + assert(stream != NULL); + if ((m_commonFileHeader.GeneralPurposeBitFlag & c_defHasDataDescriptor) != 0) + lEncCRC = m_commonFileHeader.LastModFileTimeDate << 0x10; + else + lEncCRC = m_commonFileHeader.CRC32; + try + { + *encrypter = new GLDZipEncryptStream(stream, lEncCRC, m_zipFile->password()); + result = true; + } + catch (...) + { + result = false; + } + if (!result) + freeAndNil(encrypter); + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计:Linc 2009.02.17 +//功能:直接使用 ZLIB 算法由文件压缩数据 +//参数: +//注意:压缩算法只能是 ZLIB,而且不能加密,主要用于超大文件的压缩,节省内存 +//////////////////////////////////////////////////////////////////////////////// +void CGLDZipFileEntry::compressFromFile(const GString file) +{ + GLDZipFileCompressedData oData; + oData.stream = m_memStream; + + if (hasPassWord() || (m_commonFileHeader.CompressionMethod != c_mDeflated)) + zipFileError(getGLDi18nStr(rsErrCompressFromFile)); + + if (!compressZLibFile(GString(file), &oData)) + zipFileError(getGLDi18nStr(rsErrEncryptedZipData)); + + m_commonFileHeader.CRC32 = oData.CRC32; + m_commonFileHeader.UncompressedSize = oData.UncompressedSize; +// m_compressedData = oData.CompressedData.toLocal8Bit(); +// m_memStream->loadFromFile(file); +// m_memStream->seek(0); +// m_memStream->write(oData.CompressedData.toLocal8Bit()); +// m_memStream->loadFromStream(oData.CompressedData.toLocal8Bit()) + m_commonFileHeader.CompressedSize = oData.CompressedSize; + m_centralDirectory.CommonFileHeader = m_commonFileHeader; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.05.29 +//功能: 使用 7Z 算法压缩数据 +//参数:streamResult 输出流指针,存放压缩后数据 +// data 存放输入数据指针 +//////////////////////////////////////////////////////////////////////////////// +#ifdef WIN32 +bool CGLDZipFileEntry::compress7ZData(GStream *streamResult, GStream *data) +{ + size_t nDestLen = FRAGMENT_LENGTH_7Z*2; + size_t nSizeProp = 5; //LzmaCompress参数aucProp的长度 + int ret; + unsigned char aucProp[5] = {0}; + GByteArray srcRead; + unsigned char aucLzma[FRAGMENT_LENGTH_7Z*2] ; + + data->seek(0); + int nCount = (data->size() + FRAGMENT_LENGTH_7Z - 1) / FRAGMENT_LENGTH_7Z; //计算分片次数,不足一次算一次 + for (int i = 0; i < nCount; ++i) + { + srcRead = data->read(FRAGMENT_LENGTH_7Z); + nDestLen = FRAGMENT_LENGTH_7Z*2; + + memset(aucProp,0,sizeof(aucProp)); + + if (SZ_OK != (ret = LzmaCompress(aucLzma, &nDestLen, (const uchar *)srcRead.data(), srcRead.size(), aucProp, + &nSizeProp, 9, (1 << 24), 3, 0, 2, 32, 2))) + { + return false; + } + + streamResult->write((const char *)&nDestLen, sizeof(nDestLen)); + streamResult->write((const char *)aucLzma, nDestLen); + } + + return true; +} +#endif + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2006.02.01 +//功能: 使用 ZLIB 算法压缩数据 +//参数: +//////////////////////////////////////////////////////////////////////////////// +bool CGLDZipFileEntry::compressZLibData(GStream *data, GStream *result) +{ + bool bResult ; + try + { + bResult = CGLDZlib::compress(data, result); + } + catch (...) + { + throw; + return false; + } + return bResult; +} +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2008.02.17 +//功能: 使用 ZLIB 算法压缩文件 +//参数: +//////////////////////////////////////////////////////////////////////////////// +bool CGLDZipFileEntry::compressZLibFile(const GString &file, GLDZipFileCompressedData *data) +{ + bool result = false; + + GFileStream *fileStream = new GFileStream(file); + try + { + fileStream->open(GFileStream::ReadOnly); + + if (!compressZLibData(fileStream, data->stream)) + { + zipFileError(getGLDi18nStr(rsErrEncryptedZipData)); + } + + data->CRC32 = zipCRC32(fileStream); + data->CompressedSize = data->stream->size(); + data->UncompressedSize = fileStream->size(); + result = true; + } + catch (...) + { + fileStream->close(); + freeAndNil(fileStream); + throw; + } + fileStream->close(); + freeAndNil(fileStream); + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2006.02.01 +//功能: 初始化 +//参数: +//////////////////////////////////////////////////////////////////////////////// +CGLDZipFileEntry::CGLDZipFileEntry(CGLDZipFile *zipFile, const GString &name, unsigned int AttriBute, double timeStamp, const GString &dirname, unsigned short CompressionMethod) +{ + //double nTimeStamp; + m_zipFile = zipFile; + +// if (timeStamp == 0) +// nTimeStamp = dateTimeToDouble(GDateTime::currentDateTime()); +// else +// nTimeStamp = timeStamp; + + if (zipFile != NULL) + m_level = zipFile->level(); + else + m_level = ctDefault; + + m_fileName = fileNameToZipName(name); + m_dirName = dirname; + + GStreamStrategy GStreamStrategyTemp(name, dirname); + m_memStream = GStreamStrategyTemp.stream(); + + m_compressedData = m_memStream; + + m_extrafield = GByteArray(); + m_commonFileHeader.VersionNeededToExtract = 20; + m_commonFileHeader.GeneralPurposeBitFlag = 0; + + m_commonFileHeader.CompressionMethod = CompressionMethod; + m_commonFileHeader.LastModFileTimeDate = DateTimeToFileDate(timeStamp); + m_commonFileHeader.CRC32 = 0; + m_commonFileHeader.CompressedSize = 0; + m_commonFileHeader.UncompressedSize = 0; + m_commonFileHeader.FilenameLength = m_fileName.toLocal8Bit().length(); + m_commonFileHeader.ExtraFieldLength = m_extrafield.length(); + + m_centralDirectory.CentralFileHeaderSignature = c_CentralFileHeaderSignature; + m_centralDirectory.VersionMadeBy = 20; + m_centralDirectory.CommonFileHeader = m_commonFileHeader; + m_centralDirectory.FileCommentLength = 0; + m_centralDirectory.DiskNumberStart = 0; + m_centralDirectory.InternalFileAttributes = 0; + m_centralDirectory.ExternalFileAttributes = AttriBute; + m_centralDirectory.RelativeOffsetOfLocalHeader = 0; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计:Linc 2009.02.17 +//功能:直接使用 ZLIB 算法解压数据到文件 +//参数: +//注意:压缩算法只能是 ZLIB,而且不能加密,主要用于超大文件的压缩,节省内存 +//////////////////////////////////////////////////////////////////////////////// +void CGLDZipFileEntry::decompressToFile(const GString file) +{ + if (isEncrypted() || (m_commonFileHeader.CompressionMethod != c_mDeflated)) + zipFileError(getGLDi18nStr(rsErrDecompressFile)); + if (!decompressZLibFile(m_memStream, file)) + zipFileError(getGLDi18nStr(rsErrDecompressToFile)); +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2006.02.01 +//功能: 解压缩 ZLIB 压缩数据 +//参数: +//////////////////////////////////////////////////////////////////////////////// +bool CGLDZipFileEntry::decompressZLibData(GStream *data, int size, GBlockMemoryStream *result) +{ + bool bResult = false; + + result->clearData(); + try + { + bResult = CGLDZlib::unCompress(data, result, zLibStreamHeader()); + if (result->size() != 0) + { + try + { + bResult = (result->size() == size); + if (!bResult) + result->clearData(); + } + catch (...) + { + throw; + } + } + } + catch (...) + { + throw; + } + + return bResult; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2008.02.17 +//功能: 使用 ZLIB 算法解压缩文件 +//参数: +//////////////////////////////////////////////////////////////////////////////// +bool CGLDZipFileEntry::decompressZLibFile(GStream *data, const GString &file) +{ + bool bResult = false; + GFileStream* fileStream = new GFileStream(file); + + try + { + fileStream->open(GFileStream::ReadWrite); + try + { + bResult = CGLDZlib::unCompress(data, fileStream, zLibStreamHeader()); + } + catch (...) + { + fileStream->close(); + freeAndNil(fileStream); + throw; + } + } + catch (...) + { + fileStream->close(); + freeAndNil(fileStream); + throw; + } + + fileStream->close(); + freeAndNil(fileStream); + return bResult; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2006.02.01 +//功能: 解密 PKZIP 数据 +//参数: +//////////////////////////////////////////////////////////////////////////////// +bool CGLDZipFileEntry::decryptZipData(GStream *data, GBlockMemoryStream *result) +{ + bool bResult = false; + int nSize = data->size(); + + result->loadFromStream(data); + GLDZipDecryptStream *decrypter = NULL; + try + { + data->seek(0); + if (buildDecryptStream(data, &decrypter)) + { + try + { + nSize = nSize - sizeof(BYTE[12]); + result->seek(nSize); + decrypter->seek(0); + result->loadFromStream(decrypter, nSize); + bResult = true; + } + catch (...) + { + freeAndNil(decrypter); + throw; + } + freeAndNil(decrypter); + } + else + zipFileError(getGLDi18nStr(rsErrExtractPassWord)); + } + catch (...) + { + throw; + } + return bResult; +} + +CGLDZipFileEntry::~CGLDZipFileEntry() +{ + if ((NULL != m_memStream)) + { + freeAndNil(m_memStream); + } + // todo check: inherited::destroy(); +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2006.02.01 +//功能: 使用 PKZIP 加密算法处理数据 +//参数: +//////////////////////////////////////////////////////////////////////////////// +bool CGLDZipFileEntry::encryptZipData(GStream *data, GBlockMemoryStream *result) +{ + bool bResult = false; + int nSize; + const int c_defBufferSize = 32768; + result->loadFromStream(data); + + GLDZipEncryptStream *encrypter = NULL; + GBlockMemoryStream *pStream = new GBlockMemoryStream(GStream::ReadWrite); + try + { + if (buildEncryptStream(pStream, &encrypter)) + { + try + { + nSize = data->size(); + int nCopySize = 0; + int nCount = nSize / c_defBufferSize; + for (int i = 0; i < nCount; ++i) + { + nCopySize += encrypter->write(data->read(c_defBufferSize)); + } + nCopySize += encrypter->write(data->read(nSize % c_defBufferSize)); + + bResult = (nCopySize == nSize); + } + catch (...) + { + freeAndNil(encrypter); + throw; + } + freeAndNil(encrypter); + } + if (bResult) + { + result->seek(pStream->size()); + } + pStream->seek(0); + result->loadFromStream(pStream); + } + catch (...) + { + freeAndNil(pStream); + throw; + } + freeAndNil(pStream); + return bResult; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2006.01.29 +//功能: 保存的文件属性 +//参数: +//////////////////////////////////////////////////////////////////////////////// +int CGLDZipFileEntry::attriButes() +{ + return m_centralDirectory.ExternalFileAttributes; +} + +/*CGLDZipFileEntryBZip2Processor */ +GStream *CGLDZipFileEntry::bZip2Data() +{ + assert(false); + return new GBlockMemoryStream();//todo +} + +unsigned long CGLDZipFileEntry::compressedSize() +{ + return m_commonFileHeader.CompressedSize; +} + +unsigned short CGLDZipFileEntry::compressionMethod() +{ + return m_commonFileHeader.CompressionMethod; +} + +unsigned long CGLDZipFileEntry::crc32() +{ + return m_commonFileHeader.CRC32; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2006.01.30 +//功能: 解压数据 +//参数: +//////////////////////////////////////////////////////////////////////////////// +GStream *CGLDZipFileEntry::data() +{ + GStream *result = NULL; + long lCrc32; + switch (m_commonFileHeader.CompressionMethod) + { + case c_mStored: + { + result = storedData(); + break; + } + case c_mDeflated: + { + result = zLibData(); + break; + } + case c_mBZip2: + { + result = bZip2Data(); + break; + } + default: + zipFileError(getGLDi18nStr(rsErrUnSupportMethod)); + break; + } + if (!isEncrypted()) + { + lCrc32 = zipCRC32(result); + if ((unsigned int)lCrc32 != m_commonFileHeader.CRC32) + zipFileError(getGLDi18nStr(rsErrFileCrc32)); + } + result->seek(0); + return result; +} + +double CGLDZipFileEntry::dateTime() +{ + return fileDateToDateTime(m_commonFileHeader.LastModFileTimeDate); +} + +GByteArray CGLDZipFileEntry::extrafield() +{ + return m_extrafield; +} + +GString CGLDZipFileEntry::fileComment() +{ + return m_fileComment; +} + +bool CGLDZipFileEntry::hasPassWord() +{ + return m_zipFile->password() != ""; +} + +unsigned short CGLDZipFileEntry::internalAttributes() +{ + return m_centralDirectory.InternalFileAttributes; +} + +IGLDZipFileEntry *CGLDZipFileEntry::intf() +{ + CGLDZipFileEntry *result = intfObj(); + if (result) + result->AddRef(); + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2006.01.29 +//功能: 返回是否加密标志位 +//参数: +//////////////////////////////////////////////////////////////////////////////// +bool CGLDZipFileEntry::isEncrypted() +{ + return ((m_commonFileHeader.GeneralPurposeBitFlag & c_defFileIsEncrypted) != 0); +} + +GLDZipCompressionLevel CGLDZipFileEntry::level() +{ + return m_level; +} + +GString CGLDZipFileEntry::name() +{ + return m_fileName; +} + +IGLDZipFile* CGLDZipFileEntry::owner() +{ + if (m_zipFile) + m_zipFile->AddRef(); + return m_zipFile; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2006.02.01 +//功能: 获取直接存储的数据 +//参数: +//////////////////////////////////////////////////////////////////////////////// +GStream* CGLDZipFileEntry::storedData() +{ + GBlockMemoryStream *pResultStream = new GBlockMemoryStream(GStream::ReadWrite); + if (m_commonFileHeader.CompressionMethod != c_mStored) + return pResultStream; + if (!isEncrypted()) + return m_compressedData; + else + { + if (!decryptZipData(m_compressedData, pResultStream)) + { + zipFileError(getGLDi18nStr(rsErrFilePassWord)); + } + } + return pResultStream; +} + +unsigned long CGLDZipFileEntry::uncompressedSize() +{ + return m_commonFileHeader.UncompressedSize; +} + +unsigned short CGLDZipFileEntry::versionMadeBy() +{ + return m_centralDirectory.VersionMadeBy; +} + +/*CGLDZipFileEntryZLibProcessor */ + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2006.01.31 +//功能: 解压 ZLIB 数据块 +//参数: +//////////////////////////////////////////////////////////////////////////////// +GStream *CGLDZipFileEntry::zLibData() +{ + GBlockMemoryStream *pResultStream = new GBlockMemoryStream(GStream::ReadWrite); + GBlockMemoryStream *pStreamData = new GBlockMemoryStream(GStream::ReadWrite); + pResultStream->clearData(); + + if (m_commonFileHeader.CompressionMethod != c_mDeflated) + return pResultStream; + if (!(isEncrypted())) + { + m_compressedData->seek(0); + pStreamData->loadFromStream(m_compressedData); + } + else + { + m_compressedData->seek(0); + if (!decryptZipData(m_compressedData, pStreamData)) + { + zipFileError(getGLDi18nStr(rsErrFilePassWord)); + freeAndNil(pStreamData); + return pResultStream; + } + } + pStreamData->seek(0); + decompressZLibData(pStreamData, m_commonFileHeader.UncompressedSize, pResultStream); + + freeAndNil(pStreamData); + return pResultStream; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2006.01.31 +//功能: 生成压缩流数据头 +//参数: +//注意:manufacture a 2 byte header for zlib; 4 byte footer is not required. +// Result := chr(120) + chr(156); +//////////////////////////////////////////////////////////////////////////////// +GByteArray CGLDZipFileEntry::zLibStreamHeader() +/* + TZLibStreamHeader = packed record + CMF : Byte; + m_lG : Byte; + end; +*/ +/* +const + ZL_DEF_COMPRESSIONINFO = $7; // 32k window for Deflate + ZL_DEF_COMPRESSIONMETHOD = $8; // Deflate + + ZL_FASTEST_COMPRESSION = $0; + ZL_FAST_COMPRESSION = $1; + ZL_DEFAULT_COMPRESSION = $2; + ZL_MAXIMUM_COMPRESSION = $3; + + ZL_PRESET_DICT = $20; + + ZL_FCHECK_MASK = $1F; +var + nCMF, nFLG, + nCompress: Byte; + nZLH: Word; +*/ +{ + GByteArray result = GByteArray(); + result.append(char(0x78)); + switch (m_commonFileHeader.GeneralPurposeBitFlag & 6) + { + case 0: + result.append(char(0x9c)); + break; + case 2: + result.append(char(0xda)); + break; + case 4: + result.append(char(0x5e)); + break; + case 6: + result.append(char(0x01)); + break; + default: + result.append(char(0x9c)); + break; + } + return result; + /* +// case m_commonFileHeader.generalPurposeBitFlag() and 6 of +// 0: +// nCompress := ZL_DEFAULT_COMPRESSION; +// 2: +// nCompress := ZL_MAXIMUM_COMPRESSION; +// 4: +// nCompress := ZL_FAST_COMPRESSION; +// 6: +// nCompress := ZL_FASTEST_COMPRESSION; +// else +// nCompress := ZL_DEFAULT_COMPRESSION; +// end; +// nCMF := ZL_DEF_COMPRESSIONINFO shl 4; +// nCMF := nCMF or ZL_DEF_COMPRESSIONMETHOD; +// nFLG := 0; +// nFLG := nFLG or(nCompress shl 6); +// nFLG := nFLG and not ZL_PRESET_DICT; +// nFLG := nFLG and not ZL_FCHECK_MASK; +// nZLH :=(nCMF *256) + nFLG; +// inc(nFLG, 31 -(nZLH mod 31)); +// setLength(Result, 2 *sizeOf(Byte)); +// Result[1] := chr(nCMF); +// Result[2] := chr(nFLG); +//*/ + /* +// case CompMode of +// 0, 7, 8, 9: Result := $DA78; +// 1, 2: Result := $0178; +// 3, 4: Result := $5E78; +// 5, 6: Result := $9C78; +// else +// Result := 0; +// end; +//*/ + // return result; +} + +void CGLDZipFileEntry::loadCentralDirectory(GStream *stream) +{ + GByteArray strFileName; + GByteArray strFileComment; + assert(stream != NULL); + int nPosition; + nPosition = stream->pos(); + stream->seek(nPosition - sizeof(c_CentralFileHeaderSignature)); + stream->read((char *)&m_centralDirectory, sizeof(m_centralDirectory)); + + strFileName.resize(m_centralDirectory.CommonFileHeader.FilenameLength); + stream->read(strFileName.data(), m_centralDirectory.CommonFileHeader.FilenameLength); + m_fileName = GString::fromLocal8Bit(strFileName); + m_extrafield.resize(m_centralDirectory.CommonFileHeader.ExtraFieldLength); + strFileComment.resize(m_centralDirectory.FileCommentLength); + stream->read(strFileComment.data(), m_centralDirectory.FileCommentLength); + m_fileComment = GString::fromLocal8Bit(strFileComment); +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2006.01.31 +//功能: 加载加密数据描述信息 +//参数: +//////////////////////////////////////////////////////////////////////////////// +void CGLDZipFileEntry::loadDataDescriptor(GStream *stream) +{ + GLDZipDataDescriptor cData; + assert(stream != NULL); + + if ((m_commonFileHeader.GeneralPurposeBitFlag & c_defHasDataDescriptor) > 0) + { + stream->read((char *)&cData, sizeof(cData)); + if (cData.DataDescSignature != (unsigned int)c_DataDescSignature) + { + int nPos = stream->pos(); + stream->seek(nPos - sizeof(cData)); + } + } +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2004.08.18 +//功能: 由文件加载 +//参数: +//////////////////////////////////////////////////////////////////////////////// +void CGLDZipFileEntry::loadFromFile(const GString file) +{ + GFileStream *stream = new GFileStream(file); + try + { + stream->open(GFileStream::ReadOnly); + loadFromStream(stream); + } + catch(...) + { + stream->close(); + freeAndNil(stream); + throw; + } + + stream->close(); + freeAndNil(stream); +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: LSUPER 2006.01.29 +//功能: 由数据流加载 +//参数: +//////////////////////////////////////////////////////////////////////////////// +void CGLDZipFileEntry::loadFromStream(GStream *stream) +{ + assert(stream != NULL); + setData(stream); +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: LSUPER 2006.01.29 +//功能: 由数据流初始化内容 +//参数: +//////////////////////////////////////////////////////////////////////////////// +void CGLDZipFileEntry::loadLocalFileHeader(GStream *stream) +{ + const int c_defBufferSize = 32768; + GByteArray strFileName; + assert(stream != NULL); + stream->read((char *)&m_commonFileHeader, sizeof(m_commonFileHeader)); + strFileName.resize(m_commonFileHeader.FilenameLength); + strFileName = stream->read(m_commonFileHeader.FilenameLength); + m_fileName = GString::fromLocal8Bit(strFileName); + m_extrafield.resize(m_commonFileHeader.ExtraFieldLength); + m_extrafield = stream->read(m_commonFileHeader.ExtraFieldLength); + + if (NULL == m_memStream) + { + GStreamStrategy GStreamStrategyTemp(m_fileName, m_commonFileHeader.CompressedSize); + m_memStream = GStreamStrategyTemp.stream(); + } + + m_memStream->seek(0); + //m_memStream->write(zLibStreamHeader()); + + GStreamStrategy::copyStreamByFragment(m_memStream, stream, c_defBufferSize, m_commonFileHeader.CompressedSize); + + parseEntry(); +} +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2006.01.31 +//功能: 初始化存储信息 +//参数: +//////////////////////////////////////////////////////////////////////////////// +void CGLDZipFileEntry::parseEntry() +{ + m_level = ctUnknown; + //* + // if bit 3 is set, then the data descriptor record is appended + // to the compressed data + //*/ + if (m_commonFileHeader.CompressionMethod == (unsigned short)c_mDeflated) + { + switch (m_commonFileHeader.GeneralPurposeBitFlag & 6) + { + case 0: + m_level = ctDefault; + break; + case 2: + m_level = ctMax; + break; + case 4: + m_level = ctFastest; + break; + case 6: + m_level = ctFastest; + break; + default: + break; + } + } +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2004.08.18 +//功能: 由文件流加载数据 +//参数: +//////////////////////////////////////////////////////////////////////////////// +void CGLDZipFileEntry::saveCentralDirectory(GStream *stream) +{ + GByteArray strFileName = m_fileName.toLocal8Bit(); + GByteArray strFileComment = m_fileComment.toLocal8Bit(); + stream->write((char *)&m_centralDirectory, sizeof(m_centralDirectory)); + stream->write(strFileName.data(), strFileName.length()); + stream->write(m_extrafield.data(), m_extrafield.length()); + stream->write(strFileComment.data(), strFileComment.length()); +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2006.01.31 +//功能: 保存加密数据描述信息 +//参数: +//////////////////////////////////////////////////////////////////////////////// +void CGLDZipFileEntry::saveDataDescriptor(GStream *stream) +{ + GLDZipDataDescriptor cData; + assert(stream != NULL); + if ((m_commonFileHeader.CompressionMethod == c_mDeflated) + && ((m_commonFileHeader.GeneralPurposeBitFlag & c_defHasDataDescriptor) > 0)) + { + //fillChar(cData, sizeof(cData), #0); + cData.DataDescSignature = c_DataDescSignature; + cData.CRC32 = m_commonFileHeader.CRC32; + cData.CompressedSize = m_commonFileHeader.CompressedSize; + cData.UncompressedSize = m_commonFileHeader.UncompressedSize; + stream->write((char *)&cData, sizeof(cData)); + } +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: LSUPER 2006.01.29 +//功能: 向数据流保存内容 +//参数: +//////////////////////////////////////////////////////////////////////////////// +void CGLDZipFileEntry::saveLocalFileHeader(GStream *stream) +{ + unsigned long uSignature; + unsigned short uFlag; + GByteArray strFileName; + const int c_defBufferSize = 32768; + + uSignature = c_LocalFileHeaderSignature; + assert(stream != NULL); + if (hasPassWord()) + { + uFlag = m_commonFileHeader.GeneralPurposeBitFlag | c_defFileIsEncrypted; + m_commonFileHeader.GeneralPurposeBitFlag = uFlag; + } + m_centralDirectory.CommonFileHeader = m_commonFileHeader; + m_centralDirectory.RelativeOffsetOfLocalHeader = stream->pos(); + + stream->write((char *)&uSignature, sizeof(uSignature)); + stream->write((char *)&m_commonFileHeader, sizeof(m_commonFileHeader)); + strFileName = m_fileName.toLocal8Bit(); + stream->write(strFileName.data(), m_commonFileHeader.FilenameLength); + stream->write(m_extrafield.data(), m_commonFileHeader.ExtraFieldLength); + // stream->write(m_compressedData.data(), m_commonFileHeader.CompressedSize); + + + if (NULL != m_memStream && m_memStream->size() > 0) + { + m_memStream->open(GStream::ReadWrite); + //m_memStream->seek(ZLIB_HEADER_LENGTH); + //GStreamStrategy::copyStreamByFragment(m_memStream, stream, c_defBufferSize, m_memStream->size() - ZLIB_HEADER_LENGTH); + m_memStream->seek(0); + GStreamStrategy::copyStreamByFragment(stream, m_memStream, c_defBufferSize, m_memStream->size()); + } + + return; +} + +HRESULT CGLDZipFileEntry::_QueryInterface(const IID &riid, void **ppvObject) +{ + if (riid == __uuidof(IGLDZipFileEntry)) + { + this->AddRef(); + *ppvObject = static_cast(this); + return NOERROR; + } + else if (riid == __uuidof(IGLDZipPersistent)) + { + this->AddRef(); + *ppvObject = static_cast (this); + return NOERROR; + } + else + return GInterfaceObject::_QueryInterface(riid, ppvObject); +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2004.08.18 +//功能: 向文件保存 +//参数: +//////////////////////////////////////////////////////////////////////////////// +void CGLDZipFileEntry::saveToFile(const GString file) +{ + GFileStream *stream = new GFileStream(file); + try + { + stream->open(GFileStream::ReadWrite | GFileStream::Truncate); + saveToStream(stream); + } + catch(...) + { + stream->close(); + freeAndNil(stream); + throw; + } + stream->close(); + freeAndNil(stream); +} +//////////////////////////////////////////////////////////////////////////////// +//设计: LSUPER 2006.01.29 +//功能: 数据解压到流 +//参数: +//////////////////////////////////////////////////////////////////////////////// +void CGLDZipFileEntry::saveToStream(GStream *stream) +{ + //assert(stream != NULL); + //GByteArray array = data(); + //stream->write(array.data(), array.length()); + + unsigned long lCrc32; + switch (m_commonFileHeader.CompressionMethod) + { + case c_mStored: + { + storedStream(stream); + break; + } + case c_mDeflated: + { + zLibStream(stream); + break; + } + case c_mBZip2: + { +// bZip2Stream(resultStream); + break; + } + case c_7Zip: + { +#ifdef WIN32 + store7zStream(stream); +#else + assert(false); +#endif + break; + } + default: + zipFileError(getGLDi18nStr(rsErrUnSupportMethod)); + break; + } + if (!isEncrypted()) + { + lCrc32 = zipUpdateCRC32FromStream(stream); + if ((unsigned int)lCrc32 != m_commonFileHeader.CRC32) + zipFileError(getGLDi18nStr(rsErrFileCrc32)); + }; +} + +void CGLDZipFileEntry::setAttriButes(const int value) +{ + m_centralDirectory.ExternalFileAttributes = value; +} + +void CGLDZipFileEntry::setBZip2Data(GStream *data) +{ + G_UNUSED(data); + //todo +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2004.08.18 +//功能: 保存数据 +//参数: +//注意:需要更新数据域信息 +//////////////////////////////////////////////////////////////////////////////// +void CGLDZipFileEntry::setData(GStream *value) +{ + //将value分块读 + m_commonFileHeader.CRC32 = zipCRC32(value); + m_commonFileHeader.UncompressedSize = value->size(); + + switch (m_commonFileHeader.CompressionMethod) + { + case c_mStored: + setStoredData(value); + break; + case c_mDeflated: + setZLibData(value); + break; + case c_mBZip2: + setBZip2Data(value); + break; + case c_7Zip: +#ifdef WIN32 + set7zData(value); +#else + assert(false); +#endif + break; + default: + zipFileError(getGLDi18nStr(rsErrUnSupportMethod)); + } + + //存入zip的头信息里的压缩长度字段需要去掉2字节zlib头,不然解压不出来 + //m_commonFileHeader.CompressedSize = m_memStream->size() - ZLIB_HEADER_LENGTH; + m_commonFileHeader.CompressedSize = m_memStream->size(); + m_centralDirectory.CommonFileHeader = m_commonFileHeader; +} + +void CGLDZipFileEntry::setData(GByteArray value) +{ + GBlockMemoryStream *pBlockStream = new GBlockMemoryStream(GStream::ReadWrite); + pBlockStream->write(value); + pBlockStream->seek(0); + + m_commonFileHeader.CRC32 = zipCRC32(pBlockStream); + m_commonFileHeader.UncompressedSize = pBlockStream->size(); + + switch (m_commonFileHeader.CompressionMethod) + { + case c_mStored: + setStoredData(pBlockStream); + break; + case c_mDeflated: + setZLibData(pBlockStream); + break; + case c_mBZip2: + setBZip2Data(pBlockStream); + break; + default: + zipFileError(getGLDi18nStr(rsErrUnSupportMethod)); + } + + m_commonFileHeader.CompressedSize = m_memStream->size(); + m_centralDirectory.CommonFileHeader = m_commonFileHeader; + + freeAndNil(pBlockStream); +} + +void CGLDZipFileEntry::setDateTime(const double value) +{ + m_commonFileHeader.LastModFileTimeDate = DateTimeToFileDate(value); +} + +void CGLDZipFileEntry::setExtrafield(const GByteArray &value) +{ + m_extrafield = value; + m_commonFileHeader.ExtraFieldLength = m_extrafield.length(); +} + +void CGLDZipFileEntry::setFileComment(const GString &value) +{ + GByteArray strFileComment; + m_fileComment = value; + strFileComment = m_fileComment.toLocal8Bit(); + m_centralDirectory.FileCommentLength = strFileComment.length(); +} + +void CGLDZipFileEntry::setLevel(const GLDZipCompressionLevel Value) +{ + m_level = Value; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2006.02.01 +//功能: 设置存储数据 +//参数: +//////////////////////////////////////////////////////////////////////////////// +void CGLDZipFileEntry::setStoredData(GStream *data) +{ + if (NULL == m_memStream) + { + GStreamStrategy GStreamStrategyTemp(m_fileName, data->size()); + m_memStream = GStreamStrategyTemp.stream(); + } + + if (m_commonFileHeader.CompressionMethod != c_mStored) + return; + if (!hasPassWord()) + { + m_memStream->seek(0); + //m_compressedData = data; + data->seek(0); + m_memStream->write(data->read(data->size())); + } + else + { + if (!encryptZipStream(m_memStream)) + zipFileError(getGLDi18nStr(rsErrEncryptedZipData)); + } +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2006.02.01 +//功能: 设置压缩数据 +//参数: +//////////////////////////////////////////////////////////////////////////////// +void CGLDZipFileEntry::setZLibData(GStream *data) +{ + if (m_commonFileHeader.CompressionMethod != c_mDeflated) + return; + + if (NULL == m_memStream) + { + GStreamStrategy GStreamStrategyTemp(m_fileName, data->size()); + m_memStream = GStreamStrategyTemp.stream(); + } + + m_memStream->open(GFileStream::ReadWrite); + + if (!compressZLibData(data, m_memStream)) + { + zipFileError(getGLDi18nStr(rsErrEncryptedZipData)); + } + else if (!hasPassWord()) + { + return; + } + else if (!encryptZipStream(m_memStream)) + { + zipFileError(getGLDi18nStr(rsErrEncryptedZipData)); + } +} +//////////////////////////////////////////////////////////////////////////////// +//设计: lijb 2015.05.29 +//功能: 设置压缩数据 +//参数: data 输入的数据流指针 +//////////////////////////////////////////////////////////////////////////////// +#ifdef WIN32 +void CGLDZipFileEntry::set7zData(GStream *data) +{ + if (m_commonFileHeader.CompressionMethod != c_7Zip) + return; + + if (NULL == m_memStream) + { + GStreamStrategy GStreamStrategyTemp(m_fileName, data->size()); + m_memStream = GStreamStrategyTemp.stream(); + } + + m_memStream->open(GFileStream::ReadWrite); + + if (!compress7ZData(data, m_memStream)) + { + zipFileError(getGLDi18nStr(rsErrEncryptedZipData)); + } + else if (!hasPassWord()) + { + return; + } + else if (!encryptZipStream(m_memStream)) + { + zipFileError(getGLDi18nStr(rsErrEncryptedZipData)); + } +} +#endif + +CGLDZipFileEntry *CGLDZipFileEntry::intfObj() +{ + return this; +} + +/*CGLDZipList */ +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2005.07.28 +//功能: 添加一项 +//参数: +//////////////////////////////////////////////////////////////////////////////// +int CGLDZipList::add(CGLDZipFileEntry *item) +{ + m_list.push_back(item); + return m_list.count() - 1; +} + +void CGLDZipList::clear() +{ + m_list.clear(); +} + +CGLDZipList::CGLDZipList() +{ + // +} + +void CGLDZipList::deleteItem(int index) +{ + if ((index >= 0) && (index < count())) + { + m_list.Delete(index); + } +} + +CGLDZipList::~CGLDZipList() +{ + m_list.clear(); +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2006.01.30 +//功能: 查找项 +//参数: +//////////////////////////////////////////////////////////////////////////////// +CGLDZipFileEntry* CGLDZipList::find(const GString &name) +{ + CGLDZipFileEntry *result; + int nIndex = indexOf(name); + if (nIndex == -1) + result = NULL; + else + result = m_list.at(nIndex); + return result; +} + +int CGLDZipList::count() +{ + return m_list.count(); +} + +CGLDZipFileEntry* CGLDZipList::item(int index) +{ + CGLDZipFileEntry *result; + if ((index >= 0) && (index < m_list.count())) + result = m_list.at(index); + else + { + zipFileError(getGLDi18nStr(rsErrIndexOutOfBand)); + return NULL; + } + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2006.01.30 +//功能: 检索 +//参数: +//////////////////////////////////////////////////////////////////////////////// +int CGLDZipList::indexOf(const GString &name) +{ + int result = m_list.count() - 1; + while (result >= 0) + { + if (fileSuffixToLower(m_list.at(result)->name()) == + fileSuffixToLower(name)) + break; + else + result--; + } + return result; +} + +GString CGLDZipList::fileSuffixToLower(const GString &name) +{ + GStringList list = name.split('.'); + GString suffixName = ""; + if (list.count() > 0) + { + suffixName = "." + list.value(list.count() - 1).toLower(); + } + else + { + return name; + } + + GString strName = ""; + for (int i = 0; i < list.count() - 1; i++) + { + strName += list.at(i); + } + + return strName + suffixName; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2005.07.28 +//功能: 按指针检索项 +//参数: +//////////////////////////////////////////////////////////////////////////////// +int CGLDZipList::indexOf(CGLDZipFileEntry *item) +{ + return m_list.indexOf(item); +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2005.07.28 +//功能: 插入新项 +//参数: +//////////////////////////////////////////////////////////////////////////////// +void CGLDZipList::insert(int index, CGLDZipFileEntry *item) +{ + m_list.insert(index, item); +} + +int CGLDZipList::remove(CGLDZipFileEntry *item) +{ + int result = m_list.indexOf(item); + if (result > -1) + m_list.removeOne(item); + return result; +} + +void CGLDZipList::setItem(int index, CGLDZipFileEntry *value) +{ + if ((index >= 0) && (index < m_list.count())) + m_list.replace(index, value); + else + zipFileError(getGLDi18nStr(rsErrIndexOutOfBand)); +} + +/*CGLDZipFile */ + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2004.08.18 +//功能: 添加一个记录 +//参数: +//////////////////////////////////////////////////////////////////////////////// +IGLDZipFileEntry* CGLDZipFile::add(const GString name) +{ + CGLDZipFileEntry *result = addObj(name); + if (result) + result->AddRef(); + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2006.02.08 +//功能: 添加一个记录 +//参数: +//////////////////////////////////////////////////////////////////////////////// +IGLDZipFileEntry* CGLDZipFile::add(const GString name, unsigned int AttriBute, double timeStamp) +{ + CGLDZipFileEntry *result = addObj(name, AttriBute, timeStamp); + if (result) + result->AddRef(); + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2006.01.31 +//功能: 递归添加文件 +//参数: +//////////////////////////////////////////////////////////////////////////////// +int CGLDZipFile::addFiles(const GString folder, const GString base, bool recursion, const GString fileMask, + int searchAttr) +{ + int result = 0; + GString strName; + GString strBase; + GString strFile; +// int nSearchAttr; + if (!GDir(folder).exists()) + { + zipFileError(format(getGLDi18nStr(rsErrFolderNotExist), folder)); + return 0; + } + if (base.length() == 0) + strBase = includeTrailingPathDelimiter(folder); + else + strBase = includeTrailingPathDelimiter(base); + +// if (fileMask.length() == 0) +// strMask = "*.*"; +// else +// strMask = fileMask; +// if (searchAttr == 0) +// nSearchAttr = GDir::Hidden | GDir::System | GDir::Dirs | GDir::Files | GDir::Readable; +// else +// nSearchAttr = searchAttr; + GString strPath = includeTrailingPathDelimiter(folder); + GDir *dir = new GDir(strPath); + try + { + if (fileMask != "") + dir->setNameFilters(fileMask.split("|"));//todo + dir->setFilter(GDir::Hidden | GDir::System | GDir::Dirs | GDir::Files);//todo + GFileInfoList list = dir->entryInfoList(); + for (int i = 0; i < list.count(); ++i) + { + strName = ((GFileInfo)(list.at(i))).fileName(); + if (strName == GString("..") || (strName == GString("."))) + continue; + if (GDir(strPath + strName).exists()) + { + strFile = strPath + strName + "/"; + GDir dirBuff(strBase); + strFile = dirBuff.relativeFilePath(strFile); + addObj(strFile, 16, dateTimeToDouble(GDateTime::currentDateTime()));//todo, 16为添加文件夹的选项 + result++; + if (recursion) + result += addFiles(strPath + strName, strBase, recursion, fileMask, searchAttr); + else + continue; + } + else + { + strFile = strPath + strName; + GDir dirbuff(strBase); + strName = dirbuff.relativeFilePath(strFile); + addObj(strName, strBase)->loadFromFile(strFile); + result++; + } + } + } + catch (...) + { + freeAndNil(dir); + throw; + } + freeAndNil(dir); + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2006.02.23 +//功能: 由缓冲区直接加载 +//参数: +//////////////////////////////////////////////////////////////////////////////// +IGLDZipFileEntry* CGLDZipFile::addFromBuffer(const GString &name, void *buffer, int count) +{ + CGLDZipFileEntry *result = addFromBufferObj(name, buffer, count); + if (result) + result->AddRef(); + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2006.01.29 +//功能: 由文件添加 +//参数: +//////////////////////////////////////////////////////////////////////////////// +IGLDZipFileEntry* CGLDZipFile::addFromFile(const GString &name, const GString &file) +{ + CGLDZipFileEntry *result = addFromFileObj(name, file); +// if (result) +// result->AddRef(); + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: LSUPER 2006.01.29 +//功能: 添加流内容 +//参数: +//////////////////////////////////////////////////////////////////////////////// +IGLDZipFileEntry* CGLDZipFile::addFromStream(const GString &name, GStream *stream) +{ + CGLDZipFileEntry *result = addFromStreamObj(name, stream); + if (result) + result->AddRef(); + return result; +} + +void CGLDZipFile::clear() +{ + m_files->clear(); +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2006.01.29 +//功能: 初始化、析构 +//参数: +//////////////////////////////////////////////////////////////////////////////// +CGLDZipFile::CGLDZipFile() +{ + m_files = new CGLDZipList(); + // setmem((void*) m_endOfCentralDir, sizeof(m_endOfCentralDir), '\x00') /*todo #include */; + m_level = ctDefault; + m_onGetPassword = NULL; +} + +void CGLDZipFile::deleteItem(int index) +{ + m_files->deleteItem(index); +} + +CGLDZipFile::~CGLDZipFile() +{ + freeAndNil(m_files); + // todo check: inherited::destroy(); +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2006.02.20 +//功能: 解压缩所有文件到文件夹 +//参数:nameMask为需要压缩的文件类型,默认为空,即全部压缩。 +// 1.过滤一种文件,可书写方式为:"GSP" "*.GSP" 不区分大小写 +// 2.过滤多种文件,用;分开:"GSP;ini" "*.ini;gsp" +// 3.不过滤,可以不写参数,或者"*" "*.*" +//////////////////////////////////////////////////////////////////////////////// +void CGLDZipFile::extractFiles(const GString folder, const GString nameMask) +{ + GString strDir; + GString strPath; + GString strMask; + GDir dir; + bool bFilterAll = false;//全部压缩 + QMap suffixMap; + + strMask = nameMask.trimmed(); + strMask.replace(" ", ""); + QStringList strMaskList; + + if(strMask.isEmpty()) + { + bFilterAll = true; + } + else + { + strMaskList = strMask.split(";"); + for(int i = 0; i < strMaskList.size(); ++i) + { + QString strSuffix = strMaskList[i]; + int nPos = strSuffix.lastIndexOf("."); + strSuffix = strSuffix.right(strSuffix.length() - nPos - 1); + if(strSuffix == "*") + { + bFilterAll = true; + break; + } + suffixMap.insert(strSuffix.toUpper(), true); + } + } + + GString strFolder = excludeTrailingPathDelimiter(folder); + for (int i = 0; i < m_files->count(); ++i) + { + strPath = zipNameToFileName(m_files->item(i)->name()); + if (copy(strPath, 1, 1) == GString("\\")) + strPath = strFolder + strPath; + else + strPath = includeTrailingPathDelimiter(strFolder) + strPath; + if (m_files->item(i)->attriButes() == 16) + GDir().mkpath(strPath); + else + { + strDir = GFileInfo(strPath).absolutePath(); + dir = GFileInfo(strPath).dir(); + if (!dir.exists()) + GDir().mkpath(strDir); + //添加后缀过滤 + if (bFilterAll) + { + m_files->item(i)->saveToFile(strPath); + } + else + { + int nPos = strPath.lastIndexOf("."); + GString strSuffix = strPath.right(strPath.length() - nPos - 1); + if(suffixMap.value(strSuffix.toUpper())) + { + m_files->item(i)->saveToFile(strPath); + } + } + } + } +} + +void CGLDZipFile::extractToBuffer(const GString name, int *buffer, int count) +{ + CGLDZipFileEntry *cEntry; + GBlockMemoryStream *pStream = new GBlockMemoryStream(GStream::ReadWrite); + int nSize; + char* pBuf = (char *)buffer; + + cEntry = findObj(name); + if (cEntry) + { + pStream->loadFromStream(cEntry->data()); + nSize = count > pStream->size() ? pStream->size() : count; + for (int i = 0; i < count; ++i) + { + *(buffer++) = 0; + } + for (int i = 0; i < nSize; ++i) + { + pStream->seek(i); + *(pBuf++) = pStream->read(1).at(0); + } + } + freeAndNil(pStream); +} + +void CGLDZipFile::extractToStream(const GString &name, GStream *stream) +{ + CGLDZipFileEntry *cEntry; + cEntry = findObj(name); + if (cEntry != NULL) + cEntry->saveToStream(stream); +} + +void CGLDZipFile::extractToString(const GString name, GByteArray *text) +{ + CGLDZipFileEntry *cEntry = findObj(name); + if (cEntry != NULL) + *text = cEntry->data()->readAll(); + else + *text = GByteArray(); +} + +IGLDZipFileEntry* CGLDZipFile::find(const GString name) +{ + CGLDZipFileEntry *result = findObj(name); + if (result) + result->AddRef(); + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计:Linc 2009.12.09 +//功能:获取设置的密码 +//参数: +//////////////////////////////////////////////////////////////////////////////// +GString CGLDZipFile::findPassWord(CGLDZipFileEntry *entry) +{ + GString result = m_PassWord; + if (m_onGetPassword != NULL) + m_onGetPassword->getPasswordEvent(entry, &result); + if (result.length() > c_defMaxPassWordLen) + zipFileError(getGLDi18nStr(rsErrMaxLenPassWord)); + return result; +} + +int CGLDZipFile::count() +{ + return m_files->count(); +} + +GByteArray CGLDZipFile::customFileHeader() +{ + return m_customFileHeader; +} + +GString CGLDZipFile::fileComment() +{ + return m_fileComment; +} + +IGLDZipFileEntry* CGLDZipFile::items(int index) +{ + CGLDZipFileEntry *result = itemObjs(index); + if (result) + result->AddRef(); + return result; +} + +GLDZipCompressionLevel CGLDZipFile::level() +{ + return m_level; +} + +GString CGLDZipFile::password() +{ + return m_PassWord; +} + +int CGLDZipFile::indexOf(const GString name) +{ + CGLDZipFileEntry *fileEntry = m_files->find(name); + return m_files->indexOf(fileEntry); +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: LSUPER 2006.01.29 +//功能: 加载文件信息 +//参数: +//////////////////////////////////////////////////////////////////////////////// +void CGLDZipFile::loadEndOfCentralDirectory(GStream *stream) +{ + GByteArray strFileComment; + assert(stream != NULL); + int nPosition = stream->pos(); + stream->seek(nPosition - sizeof(c_EndOfCentralDirSignature)); + stream->read((char *)&m_endOfCentralDir, sizeof(m_endOfCentralDir)); + strFileComment.resize(m_endOfCentralDir.ZipfileCommentLength); + stream->read(strFileComment.data(), m_endOfCentralDir.ZipfileCommentLength); + m_fileComment = GString::fromLocal8Bit(strFileComment); +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2004.08.18 +//功能: 由文件加载 +//参数: +//////////////////////////////////////////////////////////////////////////////// +void CGLDZipFile::loadFromFile(const GString file) +{ + GFileStream *stream = new GFileStream(file); + try + { + stream->open(GFileStream::ReadOnly); + loadFromStream(stream); + } + catch (...) + { + stream->close(); + freeAndNil(stream); + throw; + } + stream->close(); + freeAndNil(stream); +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2004.08.18 +//功能: 由文件流加载数据 +//参数: +//注意:读取 CustomFileHeader 时同时做 conFileHeaderSignature 和 +//////////////////////////////////////////////////////////////////////////////// +void CGLDZipFile::loadFromStream(GStream *stream) +{ + int nIndex; + CGLDZipFileEntry *cEntity; + IGLDZipPersistent *cPersistent; + assert(stream != NULL); + m_files->clear(); + m_customFileHeader.clear(); + if ((!findCustomFileHeader(stream)) && (!findCustomFileHeaderBySignature(stream))) + zipFileError(getGLDi18nStr(rsErrFileHeader)); + while (findSignature(stream, c_LocalFileHeaderSignature, c_CentralFileHeaderSignature)) + { + cEntity = new CGLDZipFileEntry(this); + cPersistent = (IGLDZipPersistent *)cEntity; + cPersistent->loadLocalFileHeader(stream); + cPersistent->loadDataDescriptor(stream); + m_files->add(cEntity); + } + nIndex = 0; + while (findSignature(stream, c_CentralFileHeaderSignature, c_EndOfCentralDirSignature)) + { + cEntity = m_files->item(nIndex); + cPersistent = (IGLDZipPersistent *)cEntity; + cPersistent->loadCentralDirectory(stream); + nIndex++; + } + if (findSignature(stream, c_EndOfCentralDirSignature)) + { + loadEndOfCentralDirectory(stream); + } +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: LSUPER 2006.01.29 +//功能: 保存文件信息 +//参数: +//////////////////////////////////////////////////////////////////////////////// +void CGLDZipFile::saveEndOfCentralDirectory(GStream *stream, long centralDirectoryOffset) +{ + GByteArray strFileComment; + assert(stream != NULL); + strFileComment = m_fileComment.toLocal8Bit(); + + m_endOfCentralDir.EndOfCentralDirSignature = c_EndOfCentralDirSignature; + m_endOfCentralDir.NumberOfThisDisk = 0; + m_endOfCentralDir.NumberOfTheDiskWithTheStart = 0; + m_endOfCentralDir.TotalNumberOfEntriesOnThisDisk = m_files->count(); + m_endOfCentralDir.TotalNumberOfEntries = m_files->count(); + m_endOfCentralDir.SizeOfTheCentralDirectory = stream->pos() - centralDirectoryOffset; + m_endOfCentralDir.OffsetOfStartOfCentralDirectory = centralDirectoryOffset; + m_endOfCentralDir.ZipfileCommentLength = strFileComment.length(); + + stream->write((char *)&m_endOfCentralDir, sizeof(m_endOfCentralDir)); + stream->write(strFileComment.data(), strFileComment.length()); +} + +bool CGLDZipFile::findSignature(GStream *stream, long signature, long endSignature) +{ + bool bResult; + int nReaded; + int nPosition; + unsigned long uSignature; + bool bMatch; + do + { + uSignature = 0; + nReaded = stream->read((char *)&uSignature, sizeof(uSignature)); + if (nReaded < (int)sizeof(uSignature)) + return false; + if (endSignature == 0) + bMatch = (uSignature == (unsigned long)signature); + else + bMatch = ((uSignature == (unsigned long)signature) || (uSignature == (unsigned long)endSignature)); + if (!bMatch) + { + nPosition = stream->pos(); + stream->seek(nPosition - 3); + } + } while (!bMatch); + bResult = (uSignature == (unsigned long)signature); + if ((endSignature != 0) && (!bResult)) + { + nPosition = stream->pos(); + stream->seek(nPosition - sizeof(uSignature)); + } + return bResult; +} + +bool CGLDZipFile::findCustomFileHeader(GStream *stream) +{ + int nLen(0); + unsigned long uSignature; + bool bResult = false; + + int nPos = stream->pos(); + int nReaded = stream->read((char *)&uSignature, sizeof(uSignature)); + if (nReaded < (int)sizeof(uSignature)) + return false; + if (uSignature != (unsigned long)c_FileHeaderSignature) + { + int nPosition = stream->pos(); + stream->seek(nPosition - sizeof(uSignature)); + bResult = false; + return bResult; + } + try + { + nReaded = stream->read((char *)&nLen, sizeof(nLen)); + if ((nReaded < (int)sizeof(nLen)) || (stream->pos() + nLen >= stream->size())) + return bResult; + m_customFileHeader.resize(nLen); + stream->read(m_customFileHeader.data(), nLen); + bResult = true; + } + catch (...) + { + if (!bResult) + stream->seek(nPos); + throw; + } + if (!bResult) + stream->seek(nPos); + return bResult; +} + +bool CGLDZipFile::findCustomFileHeaderBySignature(GStream *stream) +{ + int nPos = (int)stream->pos(); + bool bResult; + bResult = findSignature(stream, c_LocalFileHeaderSignature); + if (!bResult) + return bResult; + int nReaded = (int)stream->pos() - nPos - sizeof(int); + stream->seek(nPos); + m_customFileHeader.resize(nReaded); + stream->read(m_customFileHeader.data(), nReaded); + return bResult; +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2004.08.18 +//功能: 向文件保存 +//参数: +//////////////////////////////////////////////////////////////////////////////// +void CGLDZipFile::saveToFile(const GString file) +{ + GFileStream *stream = new GFileStream(file); + try + { + if (stream->open(GFileStream::WriteOnly | GFileStream::Truncate)) + { + saveToStream(stream); + } + } + catch (...) + { + stream->close(); + freeAndNil(stream); + throw; + } + stream->close(); + freeAndNil(stream); +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2004.08.18 +//功能: 向文件流保存 +//参数: +//////////////////////////////////////////////////////////////////////////////// +void CGLDZipFile::saveToStream(GStream *stream) +{ + unsigned long uOffset; + int nLen; + IGLDZipPersistent *cPersistent; + assert(stream != NULL); + if (m_customFileHeader != GByteArray()) + { + stream->write((char *)&c_FileHeaderSignature, sizeof(c_FileHeaderSignature)); + nLen = m_customFileHeader.length(); + stream->write((char *)&nLen, sizeof(nLen)); + stream->write(m_customFileHeader.data(), nLen); + } + for (int i = 0; i < m_files->count(); ++i) + { + cPersistent = (IGLDZipPersistent *)(m_files->item(i)); + cPersistent->saveLocalFileHeader(stream); + cPersistent->saveDataDescriptor(stream); + } + uOffset = stream->pos(); + for (int i = 0; i < m_files->count(); ++i) + { + cPersistent = (IGLDZipPersistent *)(m_files->item(i)); + cPersistent->saveCentralDirectory(stream); + } + saveEndOfCentralDirectory(stream, uOffset); +} + +IGLDZipGetPassWordEvent *CGLDZipFile::getOnGetPassword() +{ + return m_onGetPassword; +} + +void CGLDZipFile::setOnGetPassword(IGLDZipGetPassWordEvent *value) +{ + m_onGetPassword = value; +} + +CGLDZipFileEntry *CGLDZipFile::itemObjs(int index) +{ + if ((index >= 0) && (index < m_files->count())) + return m_files->item(index); + else + { + zipFileError(getGLDi18nStr(rsErrIndexOutOfBand)); + return NULL; + } +} + +CGLDZipFileEntry *CGLDZipFile::findObj(const GString &name) +{ + return m_files->find(name); +} + +CGLDZipFileEntry *CGLDZipFile::addObj(const GString &name) +{ + CGLDZipFileEntry *result = new CGLDZipFileEntry(this, name); + m_files->add(result); + return result; +} + +CGLDZipFileEntry *CGLDZipFile::addObj(const GString &name, unsigned int attriBute, double timeStamp) +{ + CGLDZipFileEntry *result = new CGLDZipFileEntry(this, name, attriBute, timeStamp); + m_files->add(result); + return result; +} +CGLDZipFileEntry *CGLDZipFile::addObj(const GString &name, const GString &dirname) +{ + CGLDZipFileEntry *result = new CGLDZipFileEntry(this, name, 0, 0, dirname); + m_files->add(result); + return result; +} + +CGLDZipFileEntry *CGLDZipFile::addObj(const GString &name, unsigned int attriBute, double timeStamp, const GString &dirname) +{ + CGLDZipFileEntry *result = new CGLDZipFileEntry(this, name, attriBute, timeStamp, dirname); + m_files->add(result); + return result; +} + +CGLDZipFileEntry *CGLDZipFile::addFromBufferObj(const GString &name, void *buffer, int count) +{ + GBlockMemoryStream *pStrMemory = new GBlockMemoryStream(GStream::ReadWrite); + CGLDZipFileEntry *result = addObj(name); + if (count != 0) + { + pStrMemory->write((char *)buffer, count); + pStrMemory->seek(0); + dynamic_cast(result->data())->loadFromStream(pStrMemory); + } + freeAndNil(pStrMemory); + return result; +} + +CGLDZipFileEntry *CGLDZipFile::addFromFileObj(const GString &name, const GString &file) +{ + CGLDZipFileEntry *result = NULL; + if (!GFileStream::exists(file)) + return NULL; + double dLastModifyTime; + GFileInfo *info = new GFileInfo(file); + try + { + dLastModifyTime = dateTimeToDouble(info->lastModified()); + } + catch (...) + { + freeAndNil(info); + throw; + } + freeAndNil(info); + result = addObj(name, 0, dLastModifyTime); + result->loadFromFile(file); + return result;//todo +} + +CGLDZipFileEntry *CGLDZipFile::addFromStreamObj(const GString &name, GStream *stream) +{ + CGLDZipFileEntry *result; + //GByteArray byteArray = GByteArray(); + //assert(stream != NULL); + //if (stream->size() > 0) + //{ + // stream->seek(0); + // byteArray.resize(stream->size()); + // stream->read(byteArray.data(), stream->size()); + //} + result = addObj(name); +// result->setData(byteArray); + result->loadFromStream(stream); + return result; +} + +HRESULT CGLDZipFile::_QueryInterface(const IID &riid, void **ppvObject) +{ + if (riid == __uuidof(IGLDZipFile)) + { + this->AddRef(); + *ppvObject = static_cast(this); + return NOERROR; + } + else + return GInterfaceObject::_QueryInterface(riid, ppvObject); +} + +void CGLDZipFile::setCustomFileHeader(GByteArray value) +{ + m_customFileHeader = value; +} + +void CGLDZipFile::setFileComment(const GString value) +{ + m_fileComment = value; +} + +void CGLDZipFile::setLevel(const GLDZipCompressionLevel value) +{ + m_level = value; +} + +void CGLDZipFile::setPassword(const GString value) +{ + if (value.length() > c_defMaxPassWordLen) + zipFileError(getGLDi18nStr(rsErrMaxLenPassWord)); + m_PassWord = value; +} + +/*GLDZipGetPassWordEvent*/ +void GLDZipGetPassWordEvent::getPasswordEvent(GLDZipFileEntry entry, GString *password) +{ + p->getPasswordEvent(entry, password); +} + +/*GLDZipFileEntry*/ +int GLDZipFileEntry::attriButes() +{ + return p->attriButes(); +} + +unsigned long GLDZipFileEntry::compressedSize() +{ + return p->compressedSize(); +} + +unsigned long GLDZipFileEntry::crc32() +{ + return p->crc32(); +} + +GStream *GLDZipFileEntry::data() +{ + return p->data(); +} + +double GLDZipFileEntry::dateTime() +{ + return p->dateTime(); +} + +bool GLDZipFileEntry::isEncrypted() +{ + return p->isEncrypted(); +} + +GString GLDZipFileEntry::name() +{ + return p->name(); +} + +GLDZipFile GLDZipFileEntry::owner() +{ + return GLDZipFile(p->owner(), false); +} + +unsigned long GLDZipFileEntry::uncompressedSize() +{ + return p->uncompressedSize(); +} + +void GLDZipFileEntry::setAttriButes(const int value) +{ + p->setAttriButes(value); +} + +void GLDZipFileEntry::setData(GStream *value) +{ + p->setData(value); +} + +void GLDZipFileEntry::setData(GByteArray &value) +{ + p->setData(value); +} + +void GLDZipFileEntry::setDateTime(const double value) +{ + p->setDateTime(value); +} + +void GLDZipFileEntry::loadFromFile(const GString &file) +{ + p->loadFromFile(file); +} + +void GLDZipFileEntry::saveToFile(const GString &file) +{ + p->saveToFile(file); +} + +void GLDZipFileEntry::loadFromStream(GStream *stream) +{ + p->loadFromStream(stream); +} + +void GLDZipFileEntry::saveToStream(GStream *stream) +{ + p->saveToStream(stream); +} + +void GLDZipFileEntry::compressFromFile(const GString &file) +{ + p->compressFromFile(file); +} + +void GLDZipFileEntry::decompressToFile(const GString &file) +{ + p->decompressToFile(file); +} + +/*GLDZipFile*/ +int GLDZipFile::count() +{ + return p->count(); +} + +GByteArray GLDZipFile::customFileHeader() +{ + return p->customFileHeader(); +} + +GString GLDZipFile::fileComment() +{ + return p->fileComment(); +} + +GLDZipFileEntry GLDZipFile::items(int index) +{ + return GLDZipFileEntry(p->items(index), false); +} + +GLDZipCompressionLevel GLDZipFile::level() +{ + return p->level(); +} + +GString GLDZipFile::password() +{ + return p->password(); +} + +void GLDZipFile::setCustomFileHeader(const GByteArray &value) +{ + p->setCustomFileHeader(value); +} + +void GLDZipFile::setFileComment(const GString &value) +{ + p->setFileComment(value); +} + +void GLDZipFile::setLevel(const GLDZipCompressionLevel &value) +{ + p->setLevel(value); +} + +void GLDZipFile::setPassword(const GString &value) +{ + p->setPassword(value); +} + +GLDZipFileEntry GLDZipFile::add(const GString &name) +{ + return GLDZipFileEntry(p->add(name), false); +} + +int GLDZipFile::addFiles(const GString &folder, const GString &base, const bool recursion, const GString &fileMask, + const int searchAttr) +{ + return p->addFiles(folder, base, recursion, fileMask, searchAttr); +} + +GLDZipFileEntry GLDZipFile::addFromBuffer(const GString &name, void *buffer, const int count) +{ + return GLDZipFileEntry(p->addFromBuffer(name, buffer, count), false); +} + +GLDZipFileEntry GLDZipFile::addFromFile(const GString &name, const GString &file) +{ + return GLDZipFileEntry(p->addFromFile(name, file)); +} + +GLDZipFileEntry GLDZipFile::addFromStream(const GString &name, GStream *stream) +{ + return GLDZipFileEntry(p->addFromStream(name, stream), false); +} + +int GLDZipFile::indexOf(const GString &name) +{ + return p->indexOf(name); +} + +void GLDZipFile::clear() +{ + p->clear(); +} + +void GLDZipFile::deleteItem(const int index) +{ + p->deleteItem(index); +} + +void GLDZipFile::extractFiles(const GString &folder, const GString &nameMask) +{ + p->extractFiles(folder, nameMask); +} + +void GLDZipFile::extractToBuffer(const GString &name, int *buffer, const int count) +{ + p->extractToBuffer(name, buffer, count); +} + +void GLDZipFile::extractToStream(const GString &name, GStream *stream) +{ + p->extractToStream(name, stream); +} + +void GLDZipFile::extractToString(const GString &name, GByteArray *text) +{ + p->extractToString(name, text); +} + +void GLDZipFile::loadFromFile(const GString &file) +{ + p->loadFromFile(file); +} + +void GLDZipFile::saveToFile(const GString &file) +{ + p->saveToFile(file); +} + +void GLDZipFile::loadFromStream(GStream *stream) +{ + p->loadFromStream(stream); +} + +void GLDZipFile::saveToStream(GStream *stream) +{ + p->saveToStream(stream); +} + +GLDZipGetPassWordEvent GLDZipFile::getOnGetPassword() +{ + return GLDZipGetPassWordEvent(p->getOnGetPassword(), false); +} + +void GLDZipFile::setOnGetPassword(GLDZipGetPassWordEvent &value) +{ + p->setOnGetPassword(value); +} + +unsigned long CGLDZipFileEntry::zipUpdateCRC32FromStream(GStream *stream) +{ + const int c_defBufferSize = 32768; + GByteArray strBuffer; + unsigned long uCrc = 0xffffffff; + stream->seek(0); + do + { + strBuffer = stream->read(c_defBufferSize); + for (int i = 0; i < strBuffer.size(); ++i) + { + uCrc = zipUpdateCRC32(strBuffer.at(i), uCrc); + } + } while (!stream->atEnd()); + uCrc = uCrc ^ 0xffffffff; + return uCrc; +} + +bool CGLDZipFileEntry::encryptZipStream(GStream *inStream) +{ + const int c_defBufferSize = 32768; + bool bResult = false; + GLDZipEncryptStream *encrypter = NULL; + + GStreamStrategy GStreamStrategyTemp(this->m_fileName, inStream->size(), "_encry"); + GStream *encryptOutStream = GStreamStrategyTemp.stream(); + try + { + if (buildEncryptStream(encryptOutStream, &encrypter)) + { + try + { + //偏移掉zlib两个字节头不加密,否则存入zip文件后(需要去掉zlib头),第三方工具解密会失败 + //inStream->seek(ZLIB_HEADER_LENGTH); + //GStreamStrategy::copyStreamByFragment(inStream, encrypter, c_defBufferSize, inStream->size() - ZLIB_HEADER_LENGTH); + inStream->seek(0); + GStreamStrategy::copyStreamByFragment(encrypter, inStream, c_defBufferSize, inStream->size()); + bResult = true; + } + catch (...) + { + freeAndNil(encrypter); + throw; + } + freeAndNil(encrypter); + } + encryptOutStream->seek(0); + + //将加密数据存到zlib头后 + //m_memStream->seek(ZLIB_HEADER_LENGTH); + m_memStream->seek(0); + GStreamStrategy::copyStreamByFragment(m_memStream, encryptOutStream, c_defBufferSize, encryptOutStream->size()); + } + catch (...) + { + throw; + } + + return bResult; +} + +void CGLDZipFileEntry::storedStream(GStream * streamResult) +{ + if (m_commonFileHeader.CompressionMethod != c_mStored) + return; + if (!isEncrypted()) + { + m_memStream->seek(0); + GStreamStrategy::copyStreamByFragment(streamResult, m_memStream, 3800, m_memStream->size()); + } + else + { + if (!decryptZipStream(streamResult)) + zipFileError(getGLDi18nStr(rsErrFilePassWord)); + } +} +//////////////////////////////////////////////////////////////////////////////// +//设计: Linc 2006.01.31 +//功能: 解压 ZLIB 数据块 +//参数: +//////////////////////////////////////////////////////////////////////////////// +void CGLDZipFileEntry::zLibStream(GStream *streamRuslt) +{ + GBlockMemoryStream streamData(GStream::ReadWrite); // 可能用不上 + GStream *pStreamData = NULL; + try + { + if (m_commonFileHeader.CompressionMethod != c_mDeflated) + return; + + if (!m_memStream->isOpen()) + { + m_memStream->open(GFileStream::ReadWrite); + } + + if (!(isEncrypted())) + { + m_memStream->seek(0); + pStreamData = m_memStream; + } + else + { + pStreamData = &streamData; + if (!decryptZipStream(pStreamData)) + { + zipFileError(getGLDi18nStr(rsErrFilePassWord)); + return; + } + } + + pStreamData->seek(0); + decompressToStream(pStreamData, streamRuslt); + } + catch (...) + { + throw; + } +} +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.05.21 +//功能: 解压 7Z 数据块 +//参数: +//////////////////////////////////////////////////////////////////////////////// +#ifdef WIN32 +void CGLDZipFileEntry::store7zStream(GStream *streamRuslt) +{ + GBlockMemoryStream streamData(GStream::ReadWrite); // 可能用不上 + GStream *pStreamData = NULL; + try + { + if (m_commonFileHeader.CompressionMethod != c_7Zip) + return; + + if ( !m_memStream->isOpen()) + { + m_memStream->open(GFileStream::ReadWrite); + } + + if (!(isEncrypted())) + { + m_memStream->seek(0); + pStreamData = m_memStream; + } + else + { + pStreamData = &streamData; + if (!decryptZipStream(pStreamData)) + { + zipFileError(getGLDi18nStr(rsErrFilePassWord)); + return; + } + } + + pStreamData->seek(0); + decompressTo7zStream(pStreamData, streamRuslt); + } + catch (...) + { + throw; + } +} +#endif + +//////////////////////////////////////////////////////////////////////////////// +//设计: Lijb 2015.05.21 +//功能: 解压输入流中的7Z压缩数据块到输出流 +//参数:instream 输入数据流 +// outStream 输出数据流 +//////////////////////////////////////////////////////////////////////////////// +#ifdef WIN32 +bool CGLDZipFileEntry::decompressTo7zStream(GStream *instream, GStream *outStream) +{ + try + { + uint nDestLen ; + size_t ndead = FRAGMENT_LENGTH_7Z*2; + size_t nRead; + int ret; + GByteArray srcRead; + + unsigned char aucDecomress[FRAGMENT_LENGTH_7Z*2]; //解压缓存 + unsigned char prop[5] = {93,0,0,0,1}; //lzma解压缺省参数,这个需要与压缩时的输出proc参数值一致,否则解压会失败 + + instream->seek(0); + nRead = instream->read((char *)&nDestLen, sizeof(nDestLen)); + while(nRead > 0) + { + srcRead = instream->read(nDestLen); + nRead = srcRead.size(); + + if (SZ_OK != (ret = LzmaUncompress(aucDecomress, &ndead, (const uchar *)srcRead.data(), &nRead, prop, 5))) + { + printf("LzmaUncompress error %d\n",ret); + // return - 1; + } + + //规避LzmaUncompress接口在解压最后一个分片,在后边多添加一个0的问题,这里需要截断多余字符,否则外层函数校验crc会失败 + if ((outStream->size() + ndead) >= m_commonFileHeader.UncompressedSize) + { + ndead = m_commonFileHeader.UncompressedSize - outStream->size(); + outStream->write((const char *)aucDecomress, ndead); + break; + } + outStream->write((const char *)aucDecomress, ndead); + nRead = instream->read((char *)&nDestLen, sizeof(nDestLen)); + } + } + catch (...) + { + instream->close(); + throw; + } + + instream->close(); + return true; +} +#endif + +bool CGLDZipFileEntry::decompressToStream(GStream *instream, GStream *outStream) +{ + try + { + m_memStream->seek(0); + CGLDZlib::unCompress(instream, outStream, zLibStreamHeader()); + } + catch (...) + { + instream->close(); + throw; + } + instream->close(); + return true; +} + +bool CGLDZipFileEntry::decryptZipStream(GStream *streamResult) +{ + bool bResult = false; + const int c_defBufferSize = 65535; + + GStreamStrategy GStreamStrategyTemp(this->m_fileName, m_memStream->size(), "decrypt"); + GStream *decryptOutstream = GStreamStrategyTemp.stream(); + try + { + GLDZipDecryptStream *decrypter = NULL; + + //m_memStream->seek(ZLIB_HEADER_LENGTH); + //GStreamStrategy::copyStreamByFragment(m_memStream, DecryptOutstream, c_defBufferSize, m_memStream->size() - ZLIB_HEADER_LENGTH); + m_memStream->seek(0); + GStreamStrategy::copyStreamByFragment(decryptOutstream, m_memStream, c_defBufferSize, m_memStream->size()); + + //m_memStream->seek(ZLIB_HEADER_LENGTH); + m_memStream->seek(0); + decryptOutstream->seek(0); + + if (buildDecryptStream(decryptOutstream, &decrypter)) + { + try + { + gint64 nLen = decrypter->size() - decrypter->pos(); + GStreamStrategy::copyStreamByFragment(streamResult, decrypter, c_defBufferSize, nLen); + bResult = true; + } + catch (...) + { + freeAndNil(decrypter); + throw; + } + freeAndNil(decrypter); + } + else + zipFileError(getGLDi18nStr(rsErrExtractPassWord)); + } + catch (...) + { + freeAndNil(decryptOutstream); + throw; + } + + freeAndNil(decryptOutstream); + + return bResult; +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/GLDZlib.cpp b/GCR/trunk/Glodon/src/GLD/Base/GLDZlib.cpp new file mode 100644 index 00000000..5ebe7baa --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/GLDZlib.cpp @@ -0,0 +1,574 @@ +#include "GLDZlib.h" + +#include +#include +#ifndef WIN32 +# undef FAR +# define FAR +#endif +#include "zlib.h" +#include "GLDStream.h" +#include "GLDSysUtils.h" +#include "GLDException.h" +#include "GLDStreamUtils.h" + +const int c_fragment_length_7z = 0x100000; //7z压缩解压缩的分片大小 + +//////////////////////////////////////////////////////////////////////////////// +//设计:创建一个策略类,根据用户传入参数,用工厂方法动态创建对象,屏蔽差异,用户不感知,方便扩展 +//功能:根据用户传入的参数(文件名/文件大小),创建文件流(缺省当文件大小大于16M时)或者内存流 +//参数:strFileName 输入文件名 +// strDirName 输入目录名 +// strFileName 输入文件后缀 +// nFragSize 分片大小,当超过此大小的文件分配文件流,此参数在bUseFileStreamFlag生效后起作用 +// bUseFileStreamFlag 是否启动临时文件缓存机制 +//////////////////////////////////////////////////////////////////////////////// +GStreamStrategy::GStreamStrategy(const GString &strFileName, const GString &strDirName, const GString &strSuffix, bool bUseFileStreamFlag, gint64 nFragSize) //16M +{ + if (false == bUseFileStreamFlag) + { + m_stream = new GBlockMemoryStream(GStream::ReadWrite); + m_stream->open(GStream::ReadWrite); + return; + } + + setStreamFragmentSize(nFragSize); + + GFileStream fileStream(strDirName + strFileName); + if (fileStream.exists()) + { + fileStream.open(GFileStream::ReadOnly); + } + + gint64 nStreamSize = fileStream.size(); + + if (nStreamSize == 0) + { + m_stream = NULL; + } + else if (nStreamSize <= streamFragmentSize()) + { + m_stream = new GBlockMemoryStream(GStream::ReadWrite); + m_stream->open(GStream::ReadWrite); + } + else + { + //在系统临时目录创建临时文件 + this->createFileInDir(strFileName + strSuffix); + } +} +//////////////////////////////////////////////////////////////////////////////// +//设计:创建一个策略类,根据用户传入参数,用工厂方法动态创建对象,屏蔽差异,用户不感知,方便扩展 +//功能:根据用户传入的参数(文件名/文件大小),创建文件流(当文件大小大于16M时)或者内存流 +//参数:strFileName 输入文件名 +// nStreamSize 输入文件大小 +// strSuffix 输入文件后缀 +// nFragSize 分片大小,当超过此大小的文件分配文件流,此参数在bUseFileStreamFlag生效后起作用 +// bUseFileStreamFlag 是否启动临时文件缓存机制 +//////////////////////////////////////////////////////////////////////////////// +GStreamStrategy::GStreamStrategy(const GString &strFileName, gint64 nStreamSize, const GString &strSuffix, bool bUseFileStreamFlag, gint64 nFragSize) +{ + if (false == bUseFileStreamFlag) + { + m_stream = new GBlockMemoryStream(GStream::ReadWrite); + m_stream->open(GStream::ReadWrite); + return; + } + + setStreamFragmentSize(nFragSize); + + if (nStreamSize <= streamFragmentSize()) + { + m_stream = new GBlockMemoryStream(GStream::ReadWrite); + } + else + { + this->createFileInDir(strFileName + strSuffix); + } +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: 根据用户指定的分片大小,分片拷贝流 +//功能: 根据用户指定的分片大小,分片拷贝输入流的指定大小数据到输出流中 +//参数: inStream 输入流 +// OutStream 输出流 +// nFragmentLength 分片长度 +// nCopySize 拷贝的长度 +//////////////////////////////////////////////////////////////////////////////// +void GStreamStrategy::copyStreamByFragment(GStream *outStream, GStream *inStream, uint nFragmentLength, gint64 nCopySize) +{ + assert(nFragmentLength != 0); + + uint nCount = nCopySize / nFragmentLength; + + for (uint i = 0; i < nCount; ++i) + { + outStream->write(inStream->read(nFragmentLength)); + } + outStream->write(inStream->read(nCopySize % nFragmentLength)); +} + +//////////////////////////////////////////////////////////////////////////////// +//设计:根据指定路径创建文件(如果不存在的话) +//功能:根据指定路径创建文件(如果不存在的话),目前两个参数暂时不用,留作扩展,比如指定目录 +// 生成指定名字文件 +//参数:strFileName 文件名 +//////////////////////////////////////////////////////////////////////////////// +void GStreamStrategy::createFileInDir(const GString &strFileName) +{ + try + { + QTemporaryFile *tempFile = new QTemporaryFile("compressXXXXXX.tmp"); + m_stream = tempFile; + m_stream->open(GFileStream::ReadWrite); + tempFile->setAutoRemove(true); + } + + catch (...) + { + throw GLDException("Internal Error: create file:" + strFileName + "failed!"); + } +} + +/* CGLDZlib */ +CGLDZlib::CGLDZlib() +{ + +} + +CGLDZlib::~CGLDZlib() +{ +} + +//////////////////////////////////////////////////////////////////////////////// +//设计: 压缩函数,根据用户输入的hasZlibHeaderFlag判断输出带(值为1)或不带zlib压缩头的压缩输出流outStream +//功能: 压缩用户输如的原始数据,输出压缩后的数据,压缩后的数据包含zlib压缩头, +//参数:inStream 输入的原始数据 +// outStream 输出的原始数据 +// hasZlibHeaderFlag 为true时,输出流包含zlib压缩头; false时输出流不包含压缩头 +//////////////////////////////////////////////////////////////////////////////// +int CGLDZlib::newCompress(GStream *inStream, GStream *outStream, bool hasZlibHeaderFlag) +{ + int nRet = -1; + int nnflush = -1; + bool zlibHeaderFlag = hasZlibHeaderFlag; + z_stream zcpr; + const int c_DefMaxBufSize = 0x10000; + Bytef *compressPtr = (Bytef *)malloc(sizeof(c_DefMaxBufSize) * (c_DefMaxBufSize + 1)); + unsigned long ninputSize = inStream->size(); + inStream->seek(0); + /* allocate deflate state */ + zcpr.zalloc = Z_NULL; + zcpr.zfree = Z_NULL; + zcpr.opaque = Z_NULL; + nRet = deflateInit(&zcpr, Z_DEFAULT_COMPRESSION); + zcpr.next_out = compressPtr; + if (nRet != Z_OK) + return nRet; + + while (ninputSize != 0) + { + int ntmpSize = 0; + if (ninputSize > c_DefMaxBufSize) + { + ntmpSize = c_DefMaxBufSize; + ninputSize = ninputSize - c_DefMaxBufSize; + nnflush = Z_NO_FLUSH; + } + else + { + ntmpSize = ninputSize; + nnflush = Z_FINISH; + ninputSize = 0; + } + + GByteArray in = inStream->read(ntmpSize); + + zcpr.next_in = (Bytef *)(in.data()); + long lToDo = ntmpSize; + long lReadBefore = 0; + long lReadOutBefore = 0; + do + { + lReadBefore = zcpr.total_in; + lReadOutBefore = zcpr.total_out; + zcpr.avail_in = lToDo > c_DefMaxBufSize? c_DefMaxBufSize : lToDo; + zcpr.avail_out = c_DefMaxBufSize; + nRet = deflate(&zcpr, nnflush); + if (zlibHeaderFlag) + { + outStream->write((const char *)compressPtr, zcpr.total_out - lReadOutBefore); + } + else + { + outStream->write((const char *)compressPtr + ZLIB_HEADER_LENGTH, zcpr.total_out - lReadOutBefore - ZLIB_HEADER_LENGTH); + zlibHeaderFlag = true ; + } + + lToDo -= (zcpr.total_in - lReadBefore); + zcpr.next_out = compressPtr; + + } while (nRet == Z_OK); + } + if (nRet >= 0) + { + deflateEnd(&zcpr); + } + freeAndNil(compressPtr); + return nRet; +} +//////////////////////////////////////////////////////////////////////////////// +//设计: 解压缩函数,根据用户输入的zlibHeader对输入流inStream添加或不添加zlib压缩头 +//功能: 解压用户输入的压缩数据,输出解压缩数据给用户 +//参数:inStream 用户输入的压缩数据 +// outStream 输出的解压缩数据 +// zlibHeader zlib压缩头,输入的inStream已包含压缩头时,该参数填空串 +//////////////////////////////////////////////////////////////////////////////// +bool CGLDZlib::unCompress(GStream *inStream, GStream *outStream, GByteArray zlibHeader) +{ + bool bResult = false; + bool zlibHeaderFlag = false; + int zlibHeaderLen = ZLIB_HEADER_LENGTH; + + if (inStream == NULL) + return bResult; + + const uint c_DefMaxBufSize = 0xf000; + const uint c_DefMaxInBufSize = 65536; + z_stream zcpr; + memset(&zcpr, 0, sizeof(z_stream)); + // 初始化 + inflateInit(&zcpr); + Bytef *unCompressPtr = (Bytef *)malloc(sizeof(c_DefMaxBufSize) * (c_DefMaxBufSize + 1)); + + if (zlibHeader.isEmpty()) + { + zlibHeaderFlag = true; + zlibHeaderLen = 0; + } + + GByteArray oTempArray(zlibHeader); + zcpr.next_out = unCompressPtr; + + int nRet = Z_OK; + ULONG lInStreamSize = inStream->size() + zlibHeaderLen; + ULONG lTempLength = 0; + + // 当输入的流没有读完,则一直循环读取 + // 这里最好不要seek 0 + inStream->seek(0); + ULONG lReadBefore = 0; + ULONG lReadOutBefore = 0; + int i = 0; + int j = 0; + while (lInStreamSize > 0) + { + i++; + if (lInStreamSize > c_DefMaxBufSize) + { + lTempLength = c_DefMaxBufSize; + lInStreamSize = lInStreamSize - c_DefMaxBufSize; + nRet = Z_NO_FLUSH; + } + else + { + lTempLength = lInStreamSize; + lInStreamSize = 0; + nRet = Z_FINISH; + } + + // 一段一段读取,防止GByteArray溢出 + if (zlibHeaderFlag) + { + oTempArray.clear(); + oTempArray = inStream->read(lTempLength); + } + else + { + oTempArray.append(inStream->read(lTempLength - zlibHeaderLen)); + zlibHeaderFlag = true ; + } + + zcpr.next_in = (Bytef *)(oTempArray.data()); + + long lToDo = lTempLength; + do + { + j++; + zcpr.avail_out = c_DefMaxBufSize; + nRet = Z_OK; + + // 上一轮处理到的长度 + lReadBefore = zcpr.total_in; + lReadOutBefore = zcpr.total_out; + + int nPreOutOfTemp = 0; + int nPreInOfTemp = 0; + int nCurOutOfTemp = 0; + while ((zcpr.avail_out > 0) && (nRet != Z_STREAM_END)) + { + // 第一进到循环中,可用空间肯定是0,需要分配空间,方便后面处理 + // 但是如果已经处理完,也应该是0,因此需要加上判断 + if (0 == zcpr.avail_in) + { + zcpr.avail_in = + lToDo > long(c_DefMaxInBufSize) ? c_DefMaxInBufSize : lToDo; + } + // 处理完,直接Break + if (0 == zcpr.avail_in) + { + break; + } + + // 已经处理的长度 + nPreInOfTemp = zcpr.total_in - lReadBefore; + // 已经输出的长度 + nPreOutOfTemp = zcpr.total_out - lReadOutBefore; + // 当轮处理的长度初始化为0 + nCurOutOfTemp = 0; + + // 解压缩处理 + nRet = inflate(&zcpr, Z_NO_FLUSH); + + if (nRet < 0) + break; + + lToDo = lToDo - (zcpr.total_in - lReadBefore); + nCurOutOfTemp = zcpr.total_out - lReadOutBefore - nPreOutOfTemp; + zcpr.next_in = (Bytef *)(oTempArray.data() + (lTempLength - lToDo)); + } + + zcpr.next_out = unCompressPtr; + outStream->write((const char *)unCompressPtr, nCurOutOfTemp); + + } while (zcpr.total_out - lReadOutBefore == c_DefMaxBufSize); + } + + if (nRet >= 0) + { + inflateEnd(&zcpr); + bResult = true; + } + freeAndNilByGFree(unCompressPtr); + + return bResult; +} +//////////////////////////////////////////////////////////////////////////////// +//设计: 对外解压缩函数,用户输入流inStream已包含zlib压缩头 +//功能: 解压用户输入流中的压缩数据,输出解压缩数据给用户 +//参数:inStream 输入的压缩数据流指针 +// bUseFileStreamFlag 是否启用文件缓存方式,当启动此方式否,如果输入文件大于分片大小 +// (缺省16M),则将分配文件流存储解压缩后的数据,返回给用户 +//////////////////////////////////////////////////////////////////////////////// +GStream* CGLDZlib::unCompress(GStream *inStream, bool bUseFileStreamFlag) +{ + if (inStream == NULL) + { + return false; + } + + GStreamStrategy StreamStrategyTemp("_temp", inStream->size(), "_temp_unzip", bUseFileStreamFlag); + GStream *outStream = StreamStrategyTemp.stream(); + + //用户输入流inStream已包含zlib压缩头,第三个参数填空串 + unCompress(inStream, outStream, ""); + if (outStream) + { + outStream->seek(0); + } + return outStream; +} +//////////////////////////////////////////////////////////////////////////////// +//设计: 内部压缩函数,压缩输出流outStream不包含zlib头 +//功能: 压缩用户输如的原始数据,输出压缩后的数据,压缩后的数据不包含zlib压缩头,主要给zipfile类用, +// winzip等第三方工具加压时,如果压缩数据包含了zilb头,会解压失败 +//参数:inStream 输入的原始数据 +// outStream 输出的原始数据 +//////////////////////////////////////////////////////////////////////////////// +bool CGLDZlib::compress(GStream *inStream, GStream *outStream) +{ + if (inStream == NULL) + { + return false; + } + + //输出流outStream不需要包含zlib压缩头,第三个参数填false + newCompress(inStream, outStream, false); + if (outStream) + { + outStream->seek(0); + } + return true; +} +//////////////////////////////////////////////////////////////////////////////// +//设计:对外压缩函数,返回参数输出流包含zlib压缩头 +//功能: 压缩用户输如的原始数据,输出压缩后的数据,压缩后的数据包含zlib压缩头, +//参数:inStream 输入的原始数据 +// bUseFileStreamFlag 是否启用文件缓存方式,当启动此方式否,如果输入文件大于分片大小 +// (缺省16M),则将分配文件流存储压缩后的数据,返回给用户 +//////////////////////////////////////////////////////////////////////////////// +GStream* CGLDZlib::compress(GStream *inStream, bool bUseFileStreamFlag) +{ + if (inStream == NULL) + { + return false; + } + + GStreamStrategy StreamStrategyTemp("_temp", inStream->size(), "_temp_zip", bUseFileStreamFlag); + GStream *outStream = StreamStrategyTemp.stream(); + + //对外压缩函数,返回参数outStream输出流包含zlib压缩头 + newCompress(inStream, outStream, true); + if (outStream) + { + outStream->seek(0); + } + return outStream; +} + +#ifdef WIN32 +#include "LzmaLib.h" +/* CGLD7Zip */ +bool CGLD7Zip::unCompress(GStream *instream, GStream *outStream, int unCompressedSize) +{ + int nOldPos = outStream->pos(); + try + { + const unsigned char prop[5] = {93, 0, 0, 0, 1}; //lzma解压缺省参数,这个需要与压缩时的输出proc参数值一致,否则解压会失败 + + int nSrcSize = readIntFromStream(instream); + int nDestLen = -1; + size_t nRead = instream->read((char *)&nDestLen, sizeof(int)); + while(nRead > 0) + { + GByteArray srcRead = instream->read(nDestLen); + nRead = srcRead.size(); + + size_t ndead = nSrcSize; +// size_t ndead = nRead * 2; + unsigned char *aucDecomress = (unsigned char *)malloc(ndead); + int ret = -1; + if (SZ_OK != (ret = LzmaUncompress(aucDecomress, &ndead, (const uchar *)srcRead.data(), &nRead, prop, 5))) + { + //申请空间不足 + aucDecomress = (unsigned char *)realloc(aucDecomress, ndead); + memset(aucDecomress, '\0', ndead); + if (SZ_OK != (ret = LzmaUncompress(aucDecomress, &ndead, (const uchar *)srcRead.data(), &nRead, prop, 5))) + { + qWarning() << "LzmaUncompress error:" << ret; + } + } + //规避LzmaUncompress接口在解压最后一个分片,在后边多添加一个0的问题,这里需要截断多余字符,否则外层函数校验crc会失败 + if ((outStream->size() + ndead) >= unCompressedSize) + { + ndead = unCompressedSize - outStream->size(); + outStream->write((const char *)aucDecomress, ndead); + break; + } + outStream->write((const char *)aucDecomress, ndead); + nSrcSize = readIntFromStream(instream); + nRead = instream->read((char *)&nDestLen, sizeof(int)); + free(aucDecomress); + aucDecomress = NULL; + } + } + catch (...) + { + throw; + } + outStream->seek(nOldPos); + return true; +} + +GStream *CGLD7Zip::unCompress(GStream *inStream, int unCompressedSize) +{ + GBlockMemoryStream *result = new GBlockMemoryStream; + unCompress(inStream, result, unCompressedSize); + return result; +} + +bool CGLD7Zip::compress(GStream *instream, GStream *outStream) +{ + size_t nDestLen = c_fragment_length_7z * 2; + size_t nSizeProp = 5; //LzmaCompress参数aucProp的长度 + int ret; + unsigned char aucProp[5] = {0}; + GByteArray srcRead; + unsigned char *aucLzma = new unsigned char[c_fragment_length_7z * 2] ; + + int nOldPos = outStream->pos(); + int nCount = (instream->size() - instream->pos() + c_fragment_length_7z - 1) / c_fragment_length_7z; //计算分片次数,不足一次算一次 + for (int i = 0; i < nCount; ++i) + { + srcRead = instream->read(c_fragment_length_7z); + nDestLen = c_fragment_length_7z * 2; + + memset(aucProp, 0, sizeof(aucProp)); + + int nSrcSize = srcRead.size(); + if (SZ_OK != (ret = LzmaCompress(aucLzma, &nDestLen, (const uchar *)srcRead.data(), nSrcSize, + aucProp, &nSizeProp, 0, (1 << 24), 3, 0, 2, 32, 2))) + { + outStream->seek(nOldPos); + return false; + } + + writeIntToStream(outStream, nSrcSize); + writeIntToStream(outStream, nDestLen); + outStream->write((const char *)aucLzma, nDestLen); + } + outStream->seek(nOldPos); + delete(aucLzma); + return true; +} + +GStream *CGLD7Zip::compress(GStream *inStream) +{ + GBlockMemoryStream *result = new GBlockMemoryStream; + compress(inStream, result); + return result; +} +#endif + +/* CGLDAutoCompress */ +GStream *CGLDAutoCompress::unCompress(GStream *inStream) +{ + return CGLDZlib::unCompress(inStream); + + int nOldPos = inStream->pos(); + char szLength = readByteFromStream(inStream); + inStream->seek(nOldPos); + if (szLength == strlen("_7zip_")) + { + GString id = readStrFromStream(inStream); + if (sameText(id, "_7zip_")) + { +#ifdef WIN32 + return CGLD7Zip::unCompress(inStream, readIntFromStream(inStream)); +#else + assert(false); +#endif + } + inStream->seek(nOldPos); + } + return CGLDZlib::unCompress(inStream); +} + +GStream *CGLDAutoCompress::compress(GStream *inStream) +{ + return CGLDZlib::compress(inStream); + +#ifdef WIN32 + GBlockMemoryStream *result = new GBlockMemoryStream; + + writeStrToStream(result, "_7zip_"); + writeIntToStream(result, inStream->size() - inStream->pos()); + + CGLD7Zip::compress(inStream, result); + + result->seek(0); + return result; +#else + return CGLDZlib::compress(inStream); +#endif +} diff --git a/GCR/trunk/Glodon/src/GLD/Base/version.h b/GCR/trunk/Glodon/src/GLD/Base/version.h new file mode 100644 index 00000000..f89db35f --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Base/version.h @@ -0,0 +1,11 @@ +#define GLDVERSION L"2.4RC2" +#define GLDFILE_VERSION 5,0,0,8000 +#define GLDPRODUCT_VERSION 5,0,0,8000 +#define GLDVERSION_COPYRIGHT "Copyright (C) 2014 Glodon Corp Ltd." +#define GLDCOMPANY_NAME "广联达软件股份有限公司" +#define GLDFILE_DESCRIPTION +#define GLDORIGINAL_FILENAME +#define GLDPRODUCT_NAME + + + diff --git a/GCR/trunk/Glodon/src/GLD/GLD.ini b/GCR/trunk/Glodon/src/GLD/GLD.ini new file mode 100644 index 00000000..20334594 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/GLD.ini @@ -0,0 +1,5 @@ +[VERSION_GlodonCommon] +MajorVersion = 1 +MinorVersion=1 +svnversion=1937 +buildversion=386 \ No newline at end of file diff --git a/GCR/trunk/Glodon/src/GLD/GLDAll.pro b/GCR/trunk/Glodon/src/GLD/GLDAll.pro new file mode 100644 index 00000000..c20ce4de --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/GLDAll.pro @@ -0,0 +1,22 @@ +#------------------------------------------------- +# +# Project Group created by Zhangsk 2012-04-25 +# +#------------------------------------------------- +TEMPLATE = subdirs + +SUBDIRS += \ + GLDCommon.pro \ + GLDCrypt.pro \ + GLDZip.pro \ + GLDXML.pro \ + GLDWidget.pro \ + GLDTableView.pro \ + GLDMask.pro + +GLDCrypt.depends = GLDCommon +GLDZip.depends = GLDCommon +GLDXML.depends = GLDCommon +GLDWidget.depends = GLDCommon +GLDTableView.depends = GLDCommon GLDWidget GLDXML + diff --git a/GCR/trunk/Glodon/src/GLD/GLDCommon.pro b/GCR/trunk/Glodon/src/GLD/GLDCommon.pro new file mode 100644 index 00000000..31e13135 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/GLDCommon.pro @@ -0,0 +1,152 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2012-09-21T09:14:54 +# +#------------------------------------------------- +greaterThan(QT_MAJOR_VERSION, 4): QT += core-private widgets xml + +TARGET = GLDCommon +TEMPLATE = lib + +CONFIG += debug_and_release + +unix:QMAKE_CXXFLAGS += -std=c++11 + +CONFIG(debug, debug|release){ + contains(QMAKE_HOST.arch, x86_64) { + DESTDIR = ../../bin/Debug/X64 + } else { + DESTDIR = ../../bin/Debug/X86 + } + unix:TARGET=$$join(TARGET,,,_debug) + win32:TARGET=$$join(TARGET,,,d) +} + +CONFIG(release, debug|release){ + contains(QMAKE_HOST.arch, x86_64) { + DESTDIR = ../../bin/Release/X64 + } else { + DESTDIR = ../../bin/Release/X86 + } +} + +QMAKE_CXXFLAGS_RELEASE += /Zi +QMAKE_LFLAGS_RELEASE += /DEBUG + +greaterThan(QT_MAJOR_VERSION, 4): DEFINES += NOMINMAX + +DEFINES += GLODONCOMMON_LIBRARY \ + QUAZIP_STATIC \ + INITGUID \ + GDP_QT \ + GLD_LIBRARY \ + GLDCOMMON_LIBRARY + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003|win32-msvc2005|win32-msvc2008|win32-msvc2010|win32-msvc2012|win32-msvc2013 { + LIBS += -loleaut32 -lole32 -lShell32 +} + +INCLUDEPATH += ../../include/GLD + +HEADERS += \ + ../../include/GLD/GLDNameSpace.h \ + ../../include/GLD/GLDWinErrorDef.h \ + ../../include/GLD/GLDChar.h \ + ../../include/GLD/GLDString.h \ + ../../include/GLD/GLDDateTime.h \ + ../../include/GLD/GLDUuid.h \ + ../../include/GLD/GLDByteArray.h \ + ../../include/GLD/GLDVariant.h \ + ../../include/GLD/GLDIntList.h \ + ../../include/GLD/GLDVariantList.h \ + ../../include/GLD/GLDStringList.h \ + ../../include/GLD/GLDSystem.h \ + ../../include/GLD/GLDEnum.h \ + ../../include/GLD/GLDResourceDef.h \ + ../../include/GLD/GLDIODevice.h \ + ../../include/GLD/GLDBuffer.h \ + ../../include/GLD/GLDFile.h \ + ../../include/GLD/GLDFileInfo.h \ + ../../include/GLD/GLDThread.h \ + ../../include/GLD/GLDMutex.h \ + ../../include/GLD/GLDRunnable.h \ + ../../include/GLD/GLDDir.h \ + ../../include/GLD/GLDSettings.h \ + ../../include/GLD/GLDTextStream.h \ + ../../include/GLD/GLDTypes.h \ + ../../include/GLD/GLDStream.h \ + ../../include/GLD/GLDEvent.h \ + ../../include/GLD/GLDGlobal.h \ + ../../include/GLD/GLDSysUtils.h \ + ../../include/GLD/GLDStrUtils.h \ + ../../include/GLD/GLDStreamUtils.h \ + ../../include/GLD/GLDFileUtils.h \ + ../../include/GLD/GLDMathUtils.h \ + ../../include/GLD/GLDObjBase.h \ + ../../include/GLD/GLDObject.h \ + ../../include/GLD/GLDObjectList.h \ + ../../include/GLD/GLDVector.h \ + ../../include/GLD/GLDList.h \ + ../../include/GLD/GLDMap.h \ + ../../include/GLD/GLDStack.h \ + ../../include/GLD/GLDHash.h \ + ../../include/GLD/GLDGuidDef.h \ + ../../include/GLD/GLDUnknwn.h \ + ../../include/GLD/GLDComptr.h \ + ../../include/GLD/GLDComObject.h \ + ../../include/GLD/GLDComLoaderIntf.h \ + ../../include/GLD/GLDComHelper.h \ + ../../include/GLD/GLDComDLLMain.h \ + ../../include/GLD/GLDMacroUtils.h \ + ../../include/GLD/GLDInterfaceObject.h \ + ../../include/GLD/GLDClassFactory.h \ + ../../include/GLD/GLDException.h \ + ../../include/GLD/GLDRBTree.h \ + ../../include/GLD/GLDStringObjectList.h \ + ../../include/GLD/GLDSortUtils.h \ + ../../include/GLD/GLDIniFiles.h \ + ../../include/GLD/GLDSingleInstance.h \ + ../../include/GLD/GLDStrings.h \ + ../../include/GLD/GLDFloatFormating.h \ + ../../include/GLD/GLDJSONTypes.h \ + ../../include/GLD/GLDJSONUtils.h \ + ../../include/GLD/GLDAbstractItemModel_p.h \ + ../../include/GLD/GLDAbstractItemModel.h \ + ../../include/GLD/GLDGroupModel.h \ + ../../include/GLD/GLDFooterModel.h \ + ../../include/GLD/GLDCommon_Global.h \ + ../../include/GLD/GLDUIUtils.h \ + ../../include/GLD/GLDXMLTypes.h \ + ../../include/GLD/GLDTranslations.h \ + +SOURCES += \ + Base/GLDEvent.cpp \ + Base/GLDGlobal.cpp \ + Base/GLDObject.cpp \ + Base/GLDStringObjectList.cpp \ + Base/GLDStream.cpp \ + Base/GLDIniFiles.cpp \ + Base/GLDSysUtils.cpp \ + Base/GLDStrUtils.cpp \ + Base/GLDMathUtils.cpp \ + Base/GLDFileUtils.cpp \ + Base/GLDStreamUtils.cpp \ + Base/GLDSortUtils.cpp \ + Base/GLDSingleInstance.cpp \ + Base/GLDStrings.cpp \ + Base/GLDFloatFormating.cpp \ + Qt/Components/GLDAbstractItemModel.cpp \ + Base/GLDJSONUtils.cpp \ + Qt/Components/GLDFooterModel.cpp \ + Qt/Components/GLDGroupModel.cpp \ + Base/GLDUIUtils.cpp \ + Base/GLDTranslations.cpp + +RESOURCES += \ + Res/ico/GLDIcons.qrc \ + Res/ini/GLDInis.qrc \ + Res/qss/GLDQsses.qrc + +TRANSLATIONS += GLD_zh_CN.ts + +RC_FILE = Res/rc/GLDCommon.rc diff --git a/GCR/trunk/Glodon/src/GLD/GLDCrypt.pro b/GCR/trunk/Glodon/src/GLD/GLDCrypt.pro new file mode 100644 index 00000000..34532bd0 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/GLDCrypt.pro @@ -0,0 +1,72 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2012-09-21T09:14:54 +# +#------------------------------------------------- + +TARGET = GLDCrypt +TEMPLATE = lib + +CONFIG += debug_and_release + +unix:QMAKE_CXXFLAGS += -std=c++11 + +CONFIG(debug, debug|release){ + contains(QMAKE_HOST.arch, x86_64) { + DESTDIR = ../../bin/Debug/X64 + } else { + DESTDIR = ../../bin/Debug/X86 + } + unix:TARGET=$$join(TARGET,,,_debug) + win32:TARGET=$$join(TARGET,,,d) +} + +CONFIG(release, debug|release){ + contains(QMAKE_HOST.arch, x86_64) { + DESTDIR = ../../bin/Release/X64 + } else { + DESTDIR = ../../bin/Release/X86 + } +} + +QMAKE_CXXFLAGS_RELEASE += /Zi +QMAKE_LFLAGS_RELEASE += /DEBUG + +greaterThan(QT_MAJOR_VERSION, 4): DEFINES += NOMINMAX + +DEFINES += GLODONCOMMON_LIBRARY \ + QUAZIP_STATIC \ + INITGUID \ + GDP_QT \ + GLDCRYPT_LIBRARY + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003|win32-msvc2005|win32-msvc2008|win32-msvc2010|win32-msvc2012|win32-msvc2013 { + + include($(GLDRS)/Glodon/shared/GLDCommon.pri) + include($(GLDRS)/Glodon/shared/Cryptopp.pri) +} + +INCLUDEPATH += \ + ../../include/GLD + +HEADERS += \ + ../../include/GLD/GLDMD5.h \ + ../../include/GLD/GLDSHA1.h \ + ../../include/GLD/GLDDes.h \ + ../../include/GLD/GLDCrypt.h \ + ../../include/GLD/GLDCrypt_Global.h + +SOURCES += \ + Base/GLDMD5.cpp \ + Base/GLDSHA1.cpp \ + Base/GLDDes.cpp \ + Base/GLDCrypt.cpp + +RESOURCES += \ + Res/ico/GLDIcons.qrc \ + Res/ini/GLDInis.qrc \ + Res/qss/GLDQsses.qrc + +TRANSLATIONS += GLD_zh_CN.ts + +RC_FILE = Res/rc/GLDCrypt.rc diff --git a/GCR/trunk/Glodon/src/GLD/GLDMask.pro b/GCR/trunk/Glodon/src/GLD/GLDMask.pro new file mode 100644 index 00000000..ce54bb0c --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/GLDMask.pro @@ -0,0 +1,58 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2015-12-02T20:26:51 +# +#------------------------------------------------- +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = GLDMask +TEMPLATE = lib + +CONFIG += debug_and_release + +unix:QMAKE_CXXFLAGS += -std=c++11 + +CONFIG(debug, debug|release){ + contains(QMAKE_HOST.arch, x86_64) { + DESTDIR = ../../bin/Debug/X64 + } else { + DESTDIR = ../../bin/Debug/X86 + } + unix:TARGET=$$join(TARGET,,,_debug) + win32:TARGET=$$join(TARGET,,,d) +} + +CONFIG(release, debug|release){ + contains(QMAKE_HOST.arch, x86_64) { + DESTDIR = ../../bin/Release/X64 + } else { + DESTDIR = ../../bin/Release/X86 + } +} + +QMAKE_CXXFLAGS_RELEASE += /Zi +QMAKE_LFLAGS_RELEASE += /DEBUG + +greaterThan(QT_MAJOR_VERSION, 4): DEFINES += NOMINMAX + +DEFINES += GLDMASK_LIBRARY + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003|win32-msvc2005|win32-msvc2008|win32-msvc2010|win32-msvc2012|win32-msvc2013 { + LIBS += -loleaut32 -lole32 +} + +INCLUDEPATH += ../../include/GLD + +HEADERS += \ + ../../include/GLD/GLDMaskBox.h \ + ../../include/GLD/GLDMask_Global.h \ + ../../include/GLD/GLDIrregularForm.h \ + ../../include/GLD/GLDCustomButton.h + +SOURCES += \ + Qt/Widgets/GLDMaskBox.cpp \ + Qt/Widgets/GLDIrregularForm.cpp \ + Qt/Widgets/GLDCustomButton.cpp + + + diff --git a/GCR/trunk/Glodon/src/GLD/GLDStaticLib.pro b/GCR/trunk/Glodon/src/GLD/GLDStaticLib.pro new file mode 100644 index 00000000..ab0e06dc --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/GLDStaticLib.pro @@ -0,0 +1,379 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2012-09-21T09:14:54 +# +#------------------------------------------------- +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets core-private widgets-private + +TARGET = GLDStaticLib +TEMPLATE = lib + +CONFIG += staticlib debug_and_release + +CONFIG(debug, debug|release){ + contains(QMAKE_HOST.arch, x86_64) { + DESTDIR = ../../bin/Debug/X64 + } else { + DESTDIR = ../../bin/Debug/X86 + } + unix:TARGET=$$join(TARGET,,,_debug) + win32:TARGET=$$join(TARGET,,,d) +} + +CONFIG(release, debug|release){ + contains(QMAKE_HOST.arch, x86_64) { + DESTDIR = ../../bin/Release/X64 + } else { + DESTDIR = ../../bin/Release/X86 + } +} + +greaterThan(QT_MAJOR_VERSION, 4): DEFINES += NOMINMAX + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003|win32-msvc2005|win32-msvc2008|win32-msvc2010|win32-msvc2012|win32-msvc2013 { + DEFINES += ZLIB_WINAPI +} + +DEFINES += \ + QUAZIP_STATIC \ + _UNICODE \ + INITGUID \ + GDP_QT \ + GLD_FULLSOURCE + +INCLUDEPATH += $(GLDRS)/ThirdPart/zlib \ + $(GLDRS)/ThirdPart/quazip \ + $(GLDRS)/ThirdPart/RichText/include \ + $(GLDRS)/ThirdPart/libxl/include_cpp \ + $(GLDRS)/ThirdPart/lzma/C \ + $(GLDRS)/ThirdPart/cryptopp/Include \ + ../../include/GLD \ + ../../include/GLD/GLDDockPanel + +HEADERS += \ + ../../include/GLD/GLDCommon_Global.h \ + ../../include/GLD/GLDWidget_Global.h \ + ../../include/GLD/GLDTableView_Global.h \ + ../../include/GLD/GLDXML_GLobal.h \ + ../../include/GLD/GLDCrypt_Global.h \ + ../../include/GLD/GLDZip_Global.h \ + ../../include/GLD/GLDNameSpace.h \ + ../../include/GLD/GLDWinErrorDef.h \ + ../../include/GLD/GLDChar.h \ + ../../include/GLD/GLDString.h \ + ../../include/GLD/GLDDateTime.h \ + ../../include/GLD/GLDUuid.h \ + ../../include/GLD/GLDByteArray.h \ + ../../include/GLD/GLDVariant.h \ + ../../include/GLD/GLDIntList.h \ + ../../include/GLD/GLDVariantList.h \ + ../../include/GLD/GLDStringList.h \ + ../../include/GLD/GLDSystem.h \ + ../../include/GLD/GLDEnum.h \ + ../../include/GLD/GLDResourceDef.h \ + ../../include/GLD/GLDIODevice.h \ + ../../include/GLD/GLDBuffer.h \ + ../../include/GLD/GLDFile.h \ + ../../include/GLD/GLDFileInfo.h \ + ../../include/GLD/GLDThread.h \ + ../../include/GLD/GLDMutex.h \ + ../../include/GLD/GLDRunnable.h \ + ../../include/GLD/GLDDir.h \ + ../../include/GLD/GLDSettings.h \ + ../../include/GLD/GLDTextStream.h \ + ../../include/GLD/GLDTypes.h \ + ../../include/GLD/GLDXMLTypes.h \ + ../../include/GLD/GLDUITypes.h \ + ../../include/GLD/GLDStream.h \ + ../../include/GLD/GLDEvent.h \ + ../../include/GLD/GLDAbstractItemModel_p.h \ + ../../include/GLD/GLDAbstractItemModel.h \ + ../../include/GLD/GLDTreeModel.h \ + ../../include/GLD/GLDGroupModel.h \ + ../../include/GLD/GLDFooterModel.h \ + ../../include/GLD/GLDTreeDrawInfo.h \ + ../../include/GLD/GLDGlobal.h \ + ../../include/GLD/GLDSysUtils.h \ + ../../include/GLD/GLDStrUtils.h \ + ../../include/GLD/GLDStreamUtils.h \ + ../../include/GLD/GLDXMLUtils.h \ + ../../include/GLD/GLDFileUtils.h \ + ../../include/GLD/GLDMathUtils.h \ + ../../include/GLD/GLDUIUtils.h \ + ../../include/GLD/GLDObjBase.h \ + ../../include/GLD/GLDObject.h \ + ../../include/GLD/GLDObjectList.h \ + ../../include/GLD/GLDVector.h \ + ../../include/GLD/GLDList.h \ + ../../include/GLD/GLDMap.h \ + ../../include/GLD/GLDStack.h \ + ../../include/GLD/GLDHash.h \ + ../../include/GLD/GLDGuidDef.h \ + ../../include/GLD/GLDUnknwn.h \ + ../../include/GLD/GLDComptr.h \ + ../../include/GLD/GLDComObject.h \ + ../../include/GLD/GLDComLoaderIntf.h \ + ../../include/GLD/GLDComHelper.h \ + ../../include/GLD/GLDComDLLMain.h \ + ../../include/GLD/GLDMacroUtils.h \ + ../../include/GLD/GLDInterfaceObject.h \ + ../../include/GLD/GLDApplication.h \ + ../../include/GLD/GLDTreeView.h \ + ../../include/GLD/GLDTreeWidget.h \ + ../../include/GLD/GLDAbstractItemView.h \ + ../../include/GLD/GLDAbstractItemView_p.h \ + ../../include/GLD/GLDHeaderView.h \ + ../../include/GLD/GLDHeaderView_p.h \ + ../../include/GLD/GLDMultiHeaderView.h \ + ../../include/GLD/GLDMultiHeaderView_p.h \ + ../../include/GLD/GLDGroupHeaderView.h \ + ../../include/GLD/GLDGroupHeaderView_p.h \ + ../../include/GLD/GLDTableView.h \ + ../../include/GLD/GLDTableViewBasic.h \ + ../../include/GLD/GLDTableView_p.h \ + ../../include/GLD/GLDTableViewBasic_p.h \ + ../../include/GLD/GLDFilterView.h \ + ../../include/GLD/GLDFilterView_p.h \ + ../../include/GLD/GLDFilterTableView.h \ + ../../include/GLD/GLDFilterTableView_p.h \ + ../../include/GLD/GLDFooterView.h \ + ../../include/GLD/GLDFooterView_p.h \ + ../../include/GLD/GLDFooterTableView.h \ + ../../include/GLD/GLDFooterTableView_p.h \ + ../../include/GLD/GLDDefaultItemDelegate.h \ + ../../include/GLD/GLDImageEditor.h \ + ../../include/GLD/GLDColorList.h \ + ../../include/GLD/GLDClassFactory.h \ + ../../include/GLD/GLDEllipsis.h \ + ../../include/GLD/GLDGridSetting.h \ + ../../include/GLD/GLDGridSettingXMLBuilder.h \ + ../../include/GLD/GLDException.h \ + ../../include/GLD/GLDExtPropDefs.h \ + ../../include/GLD/GLDRBTree.h \ + ../../include/GLD/GLDStringObjectList.h \ + ../../include/GLD/GLDSortUtils.h \ + ../../include/GLD/GLDMD5.h \ + ../../include/GLD/GLDSHA1.h \ + ../../include/GLD/GLDDes.h \ + ../../include/GLD/GLDZlib.h \ + ../../include/GLD/GLDZipFile.h \ + ../../include/GLD/GLDZipEnc.h \ + ../../include/GLD/GLDXMLWriter.h \ + ../../include/GLD/GLDXMLSAXUtils.h \ + ../../include/GLD/GLDIniFiles.h \ + ../../include/GLD/GLDFontList.h \ + ../../include/GLD/GLDStylePaintUtils.h \ + ../../include/GLD/GLDWindowComboBox.h \ + ../../include/GLD/GLDDockContainer.h \ + ../../include/GLD/GLDSpinBox.h \ + ../../include/GLD/GLDToolBox.h \ + ../../include/GLD/GLDShellWidgets.h \ + ../../include/GLD/GLDFileSystemModel.h \ + ../../include/GLD/GLDAbstractBtnEdit.h \ + ../../include/GLD/GLDListView.h \ + ../../include/GLD/GLDPaperTableView.h \ + ../../include/GLD/GLDPaperTableView_p.h \ + ../../include/GLD/GLDDocView.h \ + ../../include/GLD/GLDPaperWidgetModel.h \ + ../../include/GLD/GLDComboBox.h \ + ../../include/GLD/GLDNetScapeSplitter.h \ + ../../include/GLD/GLDXLS.h \ + ../../include/GLD/GLDXLSModel.h \ + ../../include/GLD/GLDExcelGridIterator.h \ + ../../include/GLD/GLDExcelGridIntf.h \ + ../../include/GLD/GLDExcelIteratorTableView.h \ + ../../include/GLD/GLDDateTimeEdit.h \ + ../../include/GLD/GLDTextEdit.h \ + ../../include/GLD/GLDTableViewExport.h \ + ../../include/GLD/GLDSingleInstance.h \ + ../../include/GLD/GLDWAbstractspinbox_p.h \ + ../../include/GLD/GLDWAbstractspinbox.h \ + ../../include/GLD/GLDDrawSymbol.h \ + ../../include/GLD/GLDFilterWidget.h \ + ../../include/GLD/GLDStrings.h \ + ../../include/GLD/GLDClassicsOutLookBar.h \ + ../../include/GLD/GLDTranslations.h \ + ../../include/GLD/GLD360MainWindow.h \ + ../../include/GLD/GLDCommentFrame.h \ + ../../include/GLD/GLDFloatFormating.h \ + ../../include/GLD/GLDJSONTypes.h \ + ../../include/GLD/GLDJSONUtils.h \ + ../../include/GLD/GLDSplitter.h \ + ../../include/GLD/GLDSplitter_p.h \ + ../../include/GLD/GLDSplitterHandle.h \ + ../../include/GLD/GLDNetScapeSplitterEx.h \ + ../../include/GLD/GLDNetScapeSplitterHandle.h \ + ../../include/GLD/GLDCommentFrameEx.h \ + ../../include/GLD/GLDCustomWaitingBox.h \ + ../../include/GLD/GLDDockWidget.h \ + ../../include/GLD/GLDXMLBuilder.h \ + ../../include/GLD/GLDXMLCore.h \ + ../../include/GLD/GLDXMLDoc.h \ + ../../include/GLD/GLDXMLInterface.h \ + ../../include/GLD/GLDXMLParser.h \ + ../../include/GLD/GLDTabDockContainer.h \ + ../../include/GLD/GLDScrollStyle.h \ + ../../include/GLD/GLDShadow.h \ + ../../include/GLD/GLDWindowComboBoxEx.h \ + ../../include/GLD/GLDLineWidthComboBoxEx.h \ + ../../include/GLD/GLDFontListEx.h \ + ../../include/GLD/GLDColorListEx.h \ + ../../include/GLD/GLDDefaultItemDelegateFactory.h \ + ../../include/GLD/GLDPaperWidget.h \ + ../../include/GLD/GLDWebLogin.h \ + ../../include/GLD/GLDKeyboardInput.h \ + ../../include/GLD/GLDKeyboardButton.h \ + ../../include/GLD/GLDShellComboBoxEx.h \ + ../../include/GLD/GLDDateTimeEditEx.h \ + ../../include/GLD/GLDTreeViewEx.h \ + ../../include/GLD/GLDShellTreeViewEx.h \ + ../../include/GLD/GLDSearchEdit.h \ + ../../include/GLD/GLDCalendarWidget.h\ + ../../include/GLD/GLDProgressBar.h \ + ../../include/GLD/GLDProgressBarEvent.h \ + Qt/Widgets/GLDDockPanel/GLDDockTabWidget.h \ + Qt/Widgets/GLDDockPanel/GLDDockTabBar.h \ + Qt/Widgets/GLDDockPanel/GLDDockPanelComponents.h \ + Qt/Widgets/GLDDockPanel/GLDDockPanel.h \ + Qt/Widgets/GLDDockPanel/GLDDockNode.h \ + Qt/Widgets/GLDDockPanel/GLDDockMaskWidget.h \ + Qt/Widgets/GLDDockPanel/GLDDockDataBuilder.h \ + Qt/Widgets/GLDDockPanel/GLDDockArrows.h \ + ../../include/GLD/GLDDockPanel/GLDDockManager.h \ + ../../include/GLD/GLDDockPanel/GLDDockFrame.h \ + ../../include/GLD/GLDDockPanel/GLDDockCommon.h \ + ../../include/GLD/GLDTableCornerButton.h \ + ../../include/GLD/GLDCrypt.h \ + ../../include/GLD/GLDCustomCommentFrame.h + +SOURCES += \ + Base/GLDEvent.cpp \ + Base/GLDGlobal.cpp \ + Base/GLDObject.cpp \ + Base/GLDStringObjectList.cpp \ + Base/GLDStream.cpp \ + Base/GLDMD5.cpp \ + Base/GLDSHA1.cpp \ + Base/GLDDes.cpp \ + Base/GLDZlib.cpp \ + Base/GLDZipFile.cpp \ + Base/GLDZipEnc.cpp \ + Base/GLDIniFiles.cpp \ + Base/GLDExtPropDefs.cpp \ + Base/GLDGridSetting.cpp \ + Base/GLDGridSettingXMLBuilder.cpp \ + Base/GLDSysUtils.cpp \ + Base/GLDStrUtils.cpp \ + Base/GLDMathUtils.cpp \ + Base/GLDFileUtils.cpp \ + Base/GLDStreamUtils.cpp \ + Base/GLDSortUtils.cpp \ + Base/GLDXMLWriter.cpp \ + Base/GLDXMLUtils.cpp \ + Base/GLDXMLSAXUtils.cpp \ + Base/GLDUIUtils.cpp \ + Base/GLDXLS.cpp \ + Base/GLDExcelGridIterator.cpp \ + Base/GLDExcelIteratorTableView.cpp \ + Base/GLDTranslations.cpp \ + Base/GLDCrypt.cpp \ + Qt/Components/GLDAbstractItemModel.cpp \ + Qt/Components/GLDFooterModel.cpp \ + Qt/Components/GLDTreeModel.cpp \ + Qt/Components/GLDGroupModel.cpp \ + Qt/Components/GLDXLSModel.cpp \ + Qt/Widgets/GLDApplication.cpp \ + Qt/Widgets/GLDTreeDrawInfo.cpp \ + Qt/Widgets/GLDTreeView.cpp \ + Qt/Widgets/GLDAbstractItemView.cpp \ + Qt/Widgets/GLDHeaderView.cpp \ + Qt/Widgets/GLDMultiHeaderView.cpp \ + Qt/Widgets/GLDGroupHeaderView.cpp \ + Qt/Widgets/GLDTableView.cpp \ + Qt/Widgets/GLDTableViewBasic.cpp \ + Qt/Widgets/GLDFilterView.cpp \ + Qt/Widgets/GLDFilterTableView.cpp \ + Qt/Widgets/GLDFooterView.cpp \ + Qt/Widgets/GLDFooterTableView.cpp \ + Qt/Widgets/GLDDefaultItemDelegate.cpp \ + Qt/Widgets/GLDImageEditor.cpp \ + Qt/Widgets/GLDFontList.cpp \ + Qt/Widgets/GLDColorList.cpp \ + Qt/Widgets/GLDEllipsis.cpp \ + Qt/Widgets/GLDStylePaintUtils.cpp \ + Qt/Widgets/GLDWindowComboBox.cpp \ + Qt/Widgets/GLDSpinBox.cpp \ + Qt/Widgets/GLDToolBox.cpp \ + Qt/Widgets/GLDShellWidgets.cpp \ + Qt/Widgets/GLDFileSystemModel.cpp \ + Qt/Widgets/GLDAbstractBtnEdit.cpp \ + Qt/Widgets/GLDListView.cpp \ + Qt/Widgets/GLDDocView.cpp \ + Qt/Widgets/GLDPaperWidgetModel.cpp \ + Qt/Widgets/GLDComboBox.cpp \ + Qt/Widgets/GLDNetScapeSplitter.cpp \ + Qt/Widgets/GLDNetScapeSplitterHandle.cpp \ + Qt/Widgets/GLDDockContainer.cpp \ + Qt/Widgets/GLDDateTimeEdit.cpp \ + Qt/Widgets/GLDTextEdit.cpp \ + Qt/Widgets/GLDWAbstractspinbox.cpp \ + Qt/Widgets/GLDFilterWidget.cpp \ + Qt/Widgets/GLD360MainWindow.cpp \ + Qt/Widgets/GLDClassicsOutLookBar.cpp \ + Qt/Widgets/GLDCommentFrame.cpp \ + Qt/Widgets/GLDSplitter.cpp \ + Qt/Widgets/GLDSplitterHandle.cpp \ + Qt/Widgets/GLDNetScapeSplitterEx.cpp \ + Qt/Widgets/GLDCommentFrameEx.cpp \ + Qt/Widgets/GLDCustomCommentFrame.cpp \ + Base/GLDTableViewExport.cpp \ + Base/GLDSingleInstance.cpp \ + Base/GLDDrawSymbol.cpp \ + Base/GLDStrings.cpp \ + Base/GLDFloatFormating.cpp \ + Base/GLDJSONUtils.cpp \ + Qt/Widgets/GLDCustomWaitingBox.cpp \ + Qt/Widgets/GLDDockWidget.cpp \ + Base/GLDXMLBuilder.cpp \ + Base/GLDXMLCore.cpp \ + Base/GLDXMLDoc.cpp \ + Base/GLDXMLParser.cpp \ + Qt/Widgets/GLDTabDockContainer.cpp \ + Qt/Widgets/GLDScrollStyle.cpp \ + Qt/Widgets/GLDShadow.cpp \ + Qt/Widgets/GLDWindowComboBoxEx.cpp \ + Qt/Widgets/GLDLineWidthComboBoxEx.cpp \ + Qt/Widgets/GLDFontListEx.cpp \ + Qt/Widgets/GLDColorListEx.cpp \ + Qt/Widgets/GLDDefaultItemDelegateFactory.cpp \ + Qt/Widgets/GLDPaperWidget.cpp \ + Qt/Widgets/GLDWebLogin.cpp \ + Qt/Widgets/GLDKeyboardInput.cpp \ + Qt/Widgets/GLDKeyboardButton.cpp \ + Qt/Widgets/GLDShellComboBoxEx.cpp \ + Qt/Widgets/GLDDateTimeEditEx.cpp \ + Qt/Widgets/GLDTreeViewEx.cpp \ + Qt/Widgets/GLDShellTreeViewEx.cpp \ + Qt/Widgets/GLDSearchEdit.cpp \ + Qt/Widgets/GLDCalendarWidget.cpp\ + Qt/Widgets/GLDProgressBar.cpp \ + Qt/Widgets/GLDProgressBarEvent.cpp \ + Qt/Widgets/GLDDockPanel/GLDDockTabWidget.cpp \ + Qt/Widgets/GLDDockPanel/GLDDockTabBar.cpp \ + Qt/Widgets/GLDDockPanel/GLDDockPanelComponents.cpp \ + Qt/Widgets/GLDDockPanel/GLDDockPanel.cpp \ + Qt/Widgets/GLDDockPanel/GLDDockNode.cpp \ + Qt/Widgets/GLDDockPanel/GLDDockMaskWidget.cpp \ + Qt/Widgets/GLDDockPanel/GLDDockManager.cpp \ + Qt/Widgets/GLDDockPanel/GLDDockFrame.cpp \ + Qt/Widgets/GLDDockPanel/GLDDockDataBuilder.cpp \ + Qt/Widgets/GLDDockPanel/GLDDockArrows.cpp \ + Qt/Widgets/GLDTableCornerButton.cpp \ + Qt/Widgets/GLDPaperTableView.cpp + +RESOURCES += \ + Res/ico/GLDIcons.qrc \ + Res/ini/GLDInis.qrc \ + Res/qss/GLDQsses.qrc + +TRANSLATIONS += GLD_zh_CN.ts diff --git a/GCR/trunk/Glodon/src/GLD/GLDTableView.pro b/GCR/trunk/Glodon/src/GLD/GLDTableView.pro new file mode 100644 index 00000000..051ffa32 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/GLDTableView.pro @@ -0,0 +1,143 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2012-09-21T09:14:54 +# +#------------------------------------------------- +QT += xml +QT += printsupport core +greaterThan(QT_MAJOR_VERSION, 4): QT += core-private widgets-private + +TARGET = GLDTableView +TEMPLATE = lib + +CONFIG += debug_and_release + +unix:QMAKE_CXXFLAGS += -std=c++11 + +CONFIG(debug, debug|release){ + contains(QMAKE_HOST.arch, x86_64) { + DESTDIR = ../../bin/Debug/X64 + } else { + DESTDIR = ../../bin/Debug/X86 + } + unix:TARGET=$$join(TARGET,,,_debug) + win32:TARGET=$$join(TARGET,,,d) +} + +CONFIG(release, debug|release){ + contains(QMAKE_HOST.arch, x86_64) { + DESTDIR = ../../bin/Release/X64 + } else { + DESTDIR = ../../bin/Release/X86 + } +} + +QMAKE_CXXFLAGS_RELEASE += /Zi +QMAKE_LFLAGS_RELEASE += /DEBUG + +greaterThan(QT_MAJOR_VERSION, 4): DEFINES += NOMINMAX + +DEFINES += GLODONCOMMON_LIBRARY \ + QUAZIP_STATIC \ + INITGUID \ + GDP_QT \ + GLDTABLEVIEW_LIBRARY + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003|win32-msvc2005|win32-msvc2008|win32-msvc2010|win32-msvc2012|win32-msvc2013 { + include($(GLDRS)/Glodon/shared/GLDCommon.pri) + include($(GLDRS)/Glodon/shared/GLDXLS.pri) + include($(GLDRS)/Glodon/shared/GLDXML.pri) + include($(GLDRS)/Glodon/shared/GLDWidget.pri) +} + +INCLUDEPATH += $(GLDRS)/ThirdPart/quazip \ + $(GLDRS)/ThirdPart/RichText/include \ + $(GLDRS)/ThirdPart/libxl/include_cpp \ + ../../include/GLD + +HEADERS += \ + ../../include/GLD/GLDTreeModel.h \ + ../../include/GLD/GLDCommentFrameEx.h \ + ../../include/GLD/GLDCustomCommentFrame.h \ + ../../include/GLD/GLDTreeView.h \ + ../../include/GLD/GLDTreeWidget.h \ + ../../include/GLD/GLDAbstractItemView.h \ + ../../include/GLD/GLDAbstractItemView_p.h \ + ../../include/GLD/GLDHeaderView.h \ + ../../include/GLD/GLDHeaderView_p.h \ + ../../include/GLD/GLDMultiHeaderView.h \ + ../../include/GLD/GLDMultiHeaderView_p.h \ + ../../include/GLD/GLDGroupHeaderView.h \ + ../../include/GLD/GLDGroupHeaderView_p.h \ + ../../include/GLD/GLDTableView.h \ + ../../include/GLD/GLDTableViewBasic.h \ + ../../include/GLD/GLDTableView_p.h \ + ../../include/GLD/GLDTableViewBasic_p.h \ + ../../include/GLD/GLDFilterView.h \ + ../../include/GLD/GLDFilterView_p.h \ + ../../include/GLD/GLDFilterTableView.h \ + ../../include/GLD/GLDFilterTableView_p.h \ + ../../include/GLD/GLDFooterView.h \ + ../../include/GLD/GLDFooterView_p.h \ + ../../include/GLD/GLDFooterTableView.h \ + ../../include/GLD/GLDFooterTableView_p.h \ + ../../include/GLD/GLDDefaultItemDelegate.h \ + ../../include/GLD/GLDGridSetting.h \ + ../../include/GLD/GLDGridSettingXMLBuilder.h \ + ../../include/GLD/GLDExtPropDefs.h \ + ../../include/GLD/GLDDocView.h \ + ../../include/GLD/GLDDrawSymbol.h \ + ../../include/GLD/GLDExcelGridIterator.h \ + ../../include/GLD/GLDExcelGridIntf.h \ + ../../include/GLD/GLDExcelIteratorTableView.h \ + ../../include/GLD/GLDTableViewExport.h \ + ../../include/GLD/GLDDefaultItemDelegateFactory.h \ + ../../include/GLD/GLDPaperWidget.h \ + ../../include/GLD/GLDPaperTableView.h \ + ../../include/GLD/GLDPaperWidgetModel.h \ + ../../include/GLD/GLDTreeViewEx.h \ + ../../include/GLD/GLDTableView_Global.h \ + ../../include/GLD/GLDXLSModel.h \ + ../../include/GLD/GLDXLS.h + +SOURCES += \ + Qt/Components/GLDTreeModel.cpp \ + Qt/Widgets/GLDAbstractItemView.cpp \ + Qt/Widgets/GLDCommentFrameEx.cpp \ + Qt/Widgets/GLDCustomCommentFrame.cpp \ + Qt/Widgets/GLDDefaultItemDelegate.cpp \ + Qt/Widgets/GLDDefaultItemDelegateFactory.cpp \ + Qt/Widgets/GLDDocView.cpp \ + Qt/Widgets/GLDFilterTableView.cpp \ + Qt/Widgets/GLDFilterView.cpp \ + Qt/Widgets/GLDFooterTableView.cpp \ + Qt/Widgets/GLDFooterView.cpp \ + Qt/Widgets/GLDGroupHeaderView.cpp \ + Qt/Widgets/GLDHeaderView.cpp \ + Qt/Widgets/GLDMultiHeaderView.cpp \ + Qt/Widgets/GLDPaperWidget.cpp \ + Qt/Widgets/GLDPaperTableView.cpp \ + Qt/Widgets/GLDPaperWidgetModel.cpp \ + Qt/Widgets/GLDTableView.cpp \ + Qt/Widgets/GLDTableViewBasic.cpp \ + Qt/Widgets/GLDTreeDrawInfo.cpp \ + Qt/Widgets/GLDTreeView.cpp \ + Qt/Widgets/GLDTreeViewEx.cpp \ + Base/GLDDrawSymbol.cpp \ + Base/GLDExcelGridIterator.cpp \ + Base/GLDExcelIteratorTableView.cpp \ + Base/GLDExtPropDefs.cpp \ + Base/GLDGridSetting.cpp \ + Base/GLDGridSettingXMLBuilder.cpp \ + Base/GLDTableViewExport.cpp \ + Base/GLDXLS.cpp \ + Qt/Components/GLDXLSModel.cpp + +RESOURCES += \ + Res/ico/GLDIcons.qrc \ + Res/ini/GLDInis.qrc \ + Res/qss/GLDQsses.qrc + +TRANSLATIONS += GLD_zh_CN.ts + +RC_FILE = Res/rc/GLDTableView.rc diff --git a/GCR/trunk/Glodon/src/GLD/GLDWidget.pro b/GCR/trunk/Glodon/src/GLD/GLDWidget.pro new file mode 100644 index 00000000..d115aab2 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/GLDWidget.pro @@ -0,0 +1,196 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2012-09-21T09:14:54 +# +#------------------------------------------------- +#QT += gui //去掉也能编译过 +QT += core +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets core-private widgets-private + +TARGET = GLDWidget +TEMPLATE = lib + +CONFIG += debug_and_release + +unix:QMAKE_CXXFLAGS += -std=c++11 + +CONFIG(debug, debug|release){ + contains(QMAKE_HOST.arch, x86_64) { + DESTDIR = ../../bin/Debug/X64 + } else { + DESTDIR = ../../bin/Debug/X86 + } + unix:TARGET=$$join(TARGET,,,_debug) + win32:TARGET=$$join(TARGET,,,d) +} + +CONFIG(release, debug|release){ + contains(QMAKE_HOST.arch, x86_64) { + DESTDIR = ../../bin/Release/X64 + } else { + DESTDIR = ../../bin/Release/X86 + } +} + +QMAKE_CXXFLAGS_RELEASE += /Zi +QMAKE_LFLAGS_RELEASE += /DEBUG + +greaterThan(QT_MAJOR_VERSION, 4): DEFINES += NOMINMAX + +DEFINES += GLODONCOMMON_LIBRARY \ + QUAZIP_STATIC \ + INITGUID \ + GDP_QT \ + GLDWIDGET_LIBRARY + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003|win32-msvc2005|win32-msvc2008|win32-msvc2010|win32-msvc2012|win32-msvc2013 { + include($(GLDRS)/Glodon/shared/GLDCommon.pri) + LIBS += user32.lib +} + +INCLUDEPATH += $(GLDRS)/ThirdPart/quazip \ + $(GLDRS)/ThirdPart/RichText/include \ + $(GLDRS)/ThirdPart/libxl/include_cpp \ + ../../include/GLD \ + ../../include/GLD/GLDDockPanel + +HEADERS += \ + ../../include/GLD/GLDApplication.h \ + ../../include/GLD/GLDImageEditor.h \ + ../../include/GLD/GLDApplication.h \ + ../../include/GLD/GLDColorList.h \ + ../../include/GLD/GLDClassFactory.h \ + ../../include/GLD/GLDEllipsis.h \ + ../../include/GLD/GLDException.h \ + ../../include/GLD/GLDRBTree.h \ + ../../include/GLD/GLDIniFiles.h \ + ../../include/GLD/GLDFontList.h \ + ../../include/GLD/GLDStylePaintUtils.h \ + ../../include/GLD/GLDWindowComboBox.h \ + ../../include/GLD/GLDDockContainer.h \ + ../../include/GLD/GLDSpinBox.h \ + ../../include/GLD/GLDToolBox.h \ + ../../include/GLD/GLDShellWidgets.h \ + ../../include/GLD/GLDFileSystemModel.h \ + ../../include/GLD/GLDAbstractBtnEdit.h \ + ../../include/GLD/GLDListView.h \ + ../../include/GLD/GLDComboBox.h \ + ../../include/GLD/GLDNetScapeSplitter.h \ + ../../include/GLD/GLDDateTimeEdit.h \ + ../../include/GLD/GLDTextEdit.h \ + ../../include/GLD/GLDWAbstractspinbox_p.h \ + ../../include/GLD/GLDWAbstractspinbox.h \ + ../../include/GLD/GLDFilterWidget.h \ + ../../include/GLD/GLDClassicsOutLookBar.h \ + ../../include/GLD/GLD360MainWindow.h \ + ../../include/GLD/GLDCommentFrame.h \ + ../../include/GLD/GLDSplitter.h \ + ../../include/GLD/GLDSplitter_p.h \ + ../../include/GLD/GLDSplitterHandle.h \ + ../../include/GLD/GLDNetScapeSplitterEx.h \ + ../../include/GLD/GLDNetScapeSplitterHandle.h \ + ../../include/GLD/GLDCustomWaitingBox.h \ + ../../include/GLD/GLDDockWidget.h \ + ../../include/GLD/GLDTabDockContainer.h \ + ../../include/GLD/GLDScrollStyle.h \ + ../../include/GLD/GLDShadow.h \ + ../../include/GLD/GLDWindowComboBoxEx.h \ + ../../include/GLD/GLDLineWidthComboBoxEx.h \ + ../../include/GLD/GLDFontListEx.h \ + ../../include/GLD/GLDColorListEx.h \ + ../../include/GLD/GLDWebLogin.h \ + ../../include/GLD/GLDKeyboardInput.h \ + ../../include/GLD/GLDKeyboardButton.h \ + ../../include/GLD/GLDShellComboBoxEx.h \ + ../../include/GLD/GLDDateTimeEditEx.h \ + ../../include/GLD/GLDShellTreeViewEx.h \ + ../../include/GLD/GLDSearchEdit.h \ + #../../include/GLD/GLDFileDialog.h \ + #../../include/GLD/GLDMutilFileModel.h \ + ../../include/GLD/GLDCalendarWidget.h\ + ../../include/GLD/GLDProgressBar.h \ + ../../include/GLD/GLDProgressBarEvent.h \ + Qt/Widgets/GLDDockPanel/GLDDockTabWidget.h \ + Qt/Widgets/GLDDockPanel/GLDDockTabBar.h \ + Qt/Widgets/GLDDockPanel/GLDDockPanelComponents.h \ + Qt/Widgets/GLDDockPanel/GLDDockPanel.h \ + Qt/Widgets/GLDDockPanel/GLDDockNode.h \ + Qt/Widgets/GLDDockPanel/GLDDockMaskWidget.h \ + Qt/Widgets/GLDDockPanel/GLDDockDataBuilder.h \ + Qt/Widgets/GLDDockPanel/GLDDockArrows.h \ + ../../include/GLD/GLDDockPanel/GLDDockManager.h \ + ../../include/GLD/GLDDockPanel/GLDDockFrame.h \ + ../../include/GLD/GLDDockPanel/GLDDockCommon.h \ + ../../include/GLD/GLDTableCornerButton.h \ + ../../include/GLD/GLDWidget_Global.h + +SOURCES += \ + #Qt/Components/GLDMutilFileModel.cpp \ + Qt/Widgets/GLDApplication.cpp \ + Qt/Widgets/GLDImageEditor.cpp \ + Qt/Widgets/GLDApplication.cpp \ + Qt/Widgets/GLDFontList.cpp \ + Qt/Widgets/GLDColorList.cpp \ + Qt/Widgets/GLDEllipsis.cpp \ + Qt/Widgets/GLDStylePaintUtils.cpp \ + Qt/Widgets/GLDWindowComboBox.cpp \ + Qt/Widgets/GLDSpinBox.cpp \ + Qt/Widgets/GLDToolBox.cpp \ + Qt/Widgets/GLDShellWidgets.cpp \ + Qt/Widgets/GLDFileSystemModel.cpp \ + Qt/Widgets/GLDAbstractBtnEdit.cpp \ + Qt/Widgets/GLDListView.cpp \ + Qt/Widgets/GLDComboBox.cpp \ + Qt/Widgets/GLDNetScapeSplitter.cpp \ + Qt/Widgets/GLDNetScapeSplitterHandle.cpp \ + Qt/Widgets/GLDDockContainer.cpp \ + Qt/Widgets/GLDDateTimeEdit.cpp \ + Qt/Widgets/GLDTextEdit.cpp \ + Qt/Widgets/GLDWAbstractspinbox.cpp \ + Qt/Widgets/GLDFilterWidget.cpp \ + Qt/Widgets/GLD360MainWindow.cpp \ + Qt/Widgets/GLDClassicsOutLookBar.cpp \ + Qt/Widgets/GLDCommentFrame.cpp \ + Qt/Widgets/GLDSplitter.cpp \ + Qt/Widgets/GLDSplitterHandle.cpp \ + Qt/Widgets/GLDNetScapeSplitterEx.cpp \ + Qt/Widgets/GLDCustomWaitingBox.cpp \ + Qt/Widgets/GLDDockWidget.cpp \ + Qt/Widgets/GLDTabDockContainer.cpp \ + Qt/Widgets/GLDScrollStyle.cpp \ + Qt/Widgets/GLDShadow.cpp \ + Qt/Widgets/GLDWindowComboBoxEx.cpp \ + Qt/Widgets/GLDLineWidthComboBoxEx.cpp \ + Qt/Widgets/GLDFontListEx.cpp \ + Qt/Widgets/GLDColorListEx.cpp \ + Qt/Widgets/GLDWebLogin.cpp \ + Qt/Widgets/GLDKeyboardInput.cpp \ + Qt/Widgets/GLDKeyboardButton.cpp \ + Qt/Widgets/GLDShellComboBoxEx.cpp \ + Qt/Widgets/GLDDateTimeEditEx.cpp \ + Qt/Widgets/GLDShellTreeViewEx.cpp \ + Qt/Widgets/GLDSearchEdit.cpp \ + #Qt/Widgets/GLDFileDialog.cpp \ + Qt/Widgets/GLDCalendarWidget.cpp\ + Qt/Widgets/GLDProgressBar.cpp \ + Qt/Widgets/GLDProgressBarEvent.cpp \ + Qt/Widgets/GLDDockPanel/GLDDockTabWidget.cpp \ + Qt/Widgets/GLDDockPanel/GLDDockTabBar.cpp \ + Qt/Widgets/GLDDockPanel/GLDDockPanelComponents.cpp \ + Qt/Widgets/GLDDockPanel/GLDDockPanel.cpp \ + Qt/Widgets/GLDDockPanel/GLDDockNode.cpp \ + Qt/Widgets/GLDDockPanel/GLDDockMaskWidget.cpp \ + Qt/Widgets/GLDDockPanel/GLDDockManager.cpp \ + Qt/Widgets/GLDDockPanel/GLDDockFrame.cpp \ + Qt/Widgets/GLDDockPanel/GLDDockDataBuilder.cpp \ + Qt/Widgets/GLDDockPanel/GLDDockArrows.cpp \ + Qt/Widgets/GLDTableCornerButton.cpp + +RESOURCES += \ + Res/ico/GLDIcons.qrc \ + Res/ini/GLDInis.qrc \ + Res/qss/GLDQsses.qrc + +TRANSLATIONS += GLD_zh_CN.ts + +RC_FILE = Res/rc/GLDWidget.rc diff --git a/GCR/trunk/Glodon/src/GLD/GLDXML.pro b/GCR/trunk/Glodon/src/GLD/GLDXML.pro new file mode 100644 index 00000000..2e02c11e --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/GLDXML.pro @@ -0,0 +1,82 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2012-09-21T09:14:54 +# +#------------------------------------------------- +QT += xml +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets core-private + + +TARGET = GLDXML +TEMPLATE = lib + +CONFIG += debug_and_release + +unix:QMAKE_CXXFLAGS += -std=c++11 + +CONFIG(debug, debug|release){ + contains(QMAKE_HOST.arch, x86_64) { + DESTDIR = ../../bin/Debug/X64 + } else { + DESTDIR = ../../bin/Debug/X86 + } + unix:TARGET=$$join(TARGET,,,_debug) + win32:TARGET=$$join(TARGET,,,d) +} + +CONFIG(release, debug|release){ + contains(QMAKE_HOST.arch, x86_64) { + DESTDIR = ../../bin/Release/X64 + } else { + DESTDIR = ../../bin/Release/X86 + } +} + +greaterThan(QT_MAJOR_VERSION, 4): DEFINES += NOMINMAX + +QMAKE_CXXFLAGS_RELEASE += /Zi +QMAKE_LFLAGS_RELEASE += /DEBUG + +DEFINES += GLODONCOMMON_LIBRARY \ + QUAZIP_STATIC \ + INITGUID \ + GDP_QT \ + GLDXML_LIBRARY + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003|win32-msvc2005|win32-msvc2008|win32-msvc2010|win32-msvc2012|win32-msvc2013 { + LIBS += -loleaut32 -lole32 + include($(GLDRS)/Glodon/shared/GLDCommon.pri) +} + +INCLUDEPATH += $(GLDRS)/ThirdPart/RichText/include \ + $(GLDRS)/ThirdPart/libxl/include_cpp \ + ../../include/GLD \ + +HEADERS += \ + ../../include/GLD/GLDXMLUtils.h \ + ../../include/GLD/GLDXMLWriter.h \ + ../../include/GLD/GLDXMLSAXUtils.h \ + ../../include/GLD/GLDXMLBuilder.h \ + ../../include/GLD/GLDXMLCore.h \ + ../../include/GLD/GLDXMLDoc.h \ + ../../include/GLD/GLDXMLInterface.h \ + ../../include/GLD/GLDXMLParser.h \ + ../../include/GLD/GLDXML_Global.h + +SOURCES += \ + Base/GLDXMLWriter.cpp \ + Base/GLDXMLUtils.cpp \ + Base/GLDXMLSAXUtils.cpp \ + Base/GLDXMLBuilder.cpp \ + Base/GLDXMLCore.cpp \ + Base/GLDXMLDoc.cpp \ + Base/GLDXMLParser.cpp + +RESOURCES += \ + Res/ico/GLDIcons.qrc \ + Res/ini/GLDInis.qrc \ + Res/qss/GLDQsses.qrc + +TRANSLATIONS += GLD_zh_CN.ts + +RC_FILE = Res/rc/GLDXML.rc diff --git a/GCR/trunk/Glodon/src/GLD/GLDZip.pro b/GCR/trunk/Glodon/src/GLD/GLDZip.pro new file mode 100644 index 00000000..2f82a428 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/GLDZip.pro @@ -0,0 +1,72 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2012-09-21T09:14:54 +# +#------------------------------------------------- +greaterThan(QT_MAJOR_VERSION, 4): QT += core-private + +TARGET = GLDZip +TEMPLATE = lib + +CONFIG += debug_and_release + +unix:QMAKE_CXXFLAGS += -std=c++11 + +CONFIG(debug, debug|release){ + contains(QMAKE_HOST.arch, x86_64) { + DESTDIR = ../../bin/Debug/X64 + } else { + DESTDIR = ../../bin/Debug/X86 + } + unix:TARGET=$$join(TARGET,,,_debug) + win32:TARGET=$$join(TARGET,,,d) +} + +CONFIG(release, debug|release){ + contains(QMAKE_HOST.arch, x86_64) { + DESTDIR = ../../bin/Release/X64 + } else { + DESTDIR = ../../bin/Release/X86 + } +} + +QMAKE_CXXFLAGS_RELEASE += /Zi +QMAKE_LFLAGS_RELEASE += /DEBUG + +greaterThan(QT_MAJOR_VERSION, 4): DEFINES += NOMINMAX + +DEFINES += GLODONCOMMON_LIBRARY \ + QUAZIP_STATIC \ + INITGUID \ + GDP_QT \ + GLDZIP_LIBRARY + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003|win32-msvc2005|win32-msvc2008|win32-msvc2010|win32-msvc2012|win32-msvc2013 { + include($(GLDRS)/ThirdPart/zlib/zlib.pri) + include($(GLDRS)/ThirdPart/lzma/C/lzma.pri) + include($(GLDRS)/Glodon/shared/GLDCommon.pri) +} + +INCLUDEPATH += \ + ../../include/GLD \ + $(GLDRS)/ThirdPart/zlib + +HEADERS += \ + ../../include/GLD/GLDZipFile.h \ + ../../include/GLD/GLDZipEnc.h \ + ../../include/GLD/GLDZlib.h \ + ../../include/GLD/GLDZip_Global.h + +SOURCES += \ + Base/GLDZipFile.cpp \ + Base/GLDZipEnc.cpp \ + Base/GLDZlib.cpp + +RESOURCES += \ + Res/ico/GLDIcons.qrc \ + Res/ini/GLDInis.qrc \ + Res/qss/GLDQsses.qrc + +TRANSLATIONS += GLD_zh_CN.ts + +RC_FILE = Res/rc/GLDZip.rc diff --git a/GCR/trunk/Glodon/src/GLD/GLD_zh_CN.qm b/GCR/trunk/Glodon/src/GLD/GLD_zh_CN.qm new file mode 100644 index 00000000..96564113 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/GLD_zh_CN.qm differ diff --git a/GCR/trunk/Glodon/src/GLD/GLD_zh_CN.ts b/GCR/trunk/Glodon/src/GLD/GLD_zh_CN.ts new file mode 100644 index 00000000..deefac45 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/GLD_zh_CN.ts @@ -0,0 +1,1019 @@ + + + + + GColorList + + + more... + 鏇村... + + + + GColorListEx + + + + More Color(w)... + 鏇村棰滆壊锛坵锛... + + + + + More Color + 鏇村棰滆壊 + + + + + theme color + 涓婚鑹 + + + + + commonly used color + 甯哥敤鑹 + + + + GEGExcelModel + + + + Unrecognized + 鏈瘑鍒 + + + + GLD + + + Current rule not exist + 褰撳墠Rule涓嶅瓨鍦 + + + + No actived Sheet + 娌℃湁婵娲荤殑Sheet + + + + Getting merge cell failed + 鑾峰緱鍚堝苟鏍煎け璐 + + + + hide all identified rows + 闅愯棌宸茶瘑鍒 + + + + display all rows + 鏄剧ず鎵鏈夎 + + + + select all + 鍏ㄩ儴閫夋嫨 + + + + cancel all + 鍏ㄩ儴鍙栨秷 + + + + mark as + 璇嗗埆涓 + + + + clear all matched records of types + 娓呴櫎宸插尮閰嶇殑璁板綍绫诲瀷 + + + + This Operation Can Only Be Used in Design Status + 璇ユ搷浣滃彧鑳藉湪璁捐鐘舵佷笅浣跨敤 + + + + Table[%s] has a valide written field name[%s] + Invalid Write Field Name[%1] of Table[%2] + 琛╗%s]闈炴硶鍐欏叆瀛楁鍚峓%s] + + + + Table [%s] has a invalid header row expression [%s] + Invalid Header Row Expression [%1] of Table [%2] + 琛╗%s]闈炴硶甯﹀尯鏍囬琛岃〃杈惧紡[%s] + + + + ! invalid value + !闈炴硶鍊 + + + + String list does not allow duplicates + 瀛楃涓插垪琛ㄤ笉鍏佽閲嶅 + + + + Operation not allowed on sorted list + 璇ユ搷浣滀笉鍏佽鍦ㄦ湁搴忓垪琛ㄤ笂 + + + + List index out of bounds (%d) + 鍒楄〃涓嬫爣瓒婄晫 (%d) + + + + Invalid integer [%s] + 闈炴硶鏁存暟鍊糩%s] + + + + Illegal floating number [%s] + 闈炴硶娴偣鏁癧%s] + + + + Invalid GUID[%s] + 闈炴硶GUID鍊糩%s] + + + + Types dosn`t match + 绫诲瀷涓嶅尮閰 + + + + Invalid Base64 Data + 瀛楃涓茬紪鐮佹牸寮忛潪娉 + + + + '%1'is not a valid date and time + '%1'涓嶆槸鏈夋晥鐨勬椂闂/鏃ユ湡 + + + + Extended attribute code cannot be null + 鎵╁睍灞炴т唬鐮佷笉鑳戒负绌 + + + + Extended attribute code[%1] is repeated + 鎵╁睍灞炴т唬鐮乕%s]閲嶅 + + + + Invalid Edit Field Name[%1] of Table[%2] + 琛╗%s]闈炴硶缂栬緫瀛楁鍚峓%s] + + + + This Operation Can Only Be Used in Running Status + 璇ユ搷浣滃彧鑳藉湪杩愯鐘舵佷笅浣跨敤 + + + + Table [%1] has illegal field name [%2] + 琛╗%s]闈炴硶瀛楁鍚嶇О[%s]锛孿"&\"鍚庡繀椤讳负鏋氫妇瀛楁銆佽〃杈惧紡瀛楁銆佹椂闂存棩鏈熷瓧娈 + + + + select image + 閫夋嫨鍥剧墖 + + + + Index + 搴忓彿 + + + + Select + 閫夋嫨 + + + + Symbol + 鏍囪瘑 + + + + Month + + + + + Year + + + + + Day + + + + + Mon + + + + + Tue + + + + + Wed + + + + + Thu + + + + + Fri + + + + + Sat + + + + + Sun + + + + + FontEffect + 瀛椾綋鏁堟灉 + + + + Effect + 鏁堟灉 + + + + NoLine + + + + + OtherLine(w)... + 鍏朵粬绾挎潯锛坵锛... + + + + Pounds + + + + + AutoHide + 鑷姩闅愯棌 + + + + Locked + 閿佸畾 + + + + Simsun + 瀹嬩綋 + + + + Account: + 璐﹀彿锛 + + + + Password: + 瀵嗙爜锛 + + + + Login + 鐧 褰 + + + + RegisterAccount + 娉ㄥ唽璐﹀彿 + + + + GetBackPassword + 鎵惧洖瀵嗙爜 + + + + RemeberPassword + 璁颁綇瀵嗙爜 + + + + AutoLogin + 鑷姩鐧诲綍 + + + + OpenVirtualKeyboard + 鎵撳紑杞敭鐩 + + + + The username or password is error, please enter again! + 鐢ㄦ埛鍚嶆垨瀵嗙爜閿欒锛岃閲嶆柊杈撳叆锛 + + + + Login failed, please try again later! + 鐧诲綍澶辫触锛岃绋嶅悗閲嶈瘯锛 + + + + Network connection error, please check your network! + 缃戠粶杩炴帴閿欒锛岃浣犳鏌ヤ綘鐨勭綉缁滐紒 + + + + Prompt + 鎻愮ず + + + + Confirm + 纭 + + + + Error + 閿欒 + + + + Warning + 璀﹀憡 + + + + OK + 纭畾 + + + + + Cancel + 鍙栨秷 + + + + Can`t handle the compressed file + 鏂囦欢琚姞瀵嗭紝鏃犳硶澶勭悊 + + + + Compressed data errors + 鍘嬬缉鏁版嵁鍑洪敊 + + + + File %s CRC32 check error + 鏂囦欢 %s CRC32 妫楠屽嚭閿 + + + + File password is incorrect + 鏂囦欢瀵嗙爜涓嶆纭 + + + + The directory %s does not exist + 鐩綍 %s 涓嶅瓨鍦 + + + + Access index out of bounds + 鏍煎紡鍖栨棩鏈熸椂闂磋緭鍑 + + + + Unknown compression method %d + 鏈煡鐨勫帇缂╂柟娉 %d + + + + Algorithm can only be the ZLIB, and can not beencrypted, and is mainly used for the compression of largefiles, and save memory + 鍘嬬缉绠楁硶鍙兘鏄 ZLIB锛岃屼笖涓嶈兘鍔犲瘑锛屼富瑕佺敤浜庤秴澶ф枃浠剁殑鍘嬬缉锛岃妭鐪佸唴瀛 + + + + Decompress algorithm only is the ZLIB and can notbe encrypted, and is mainly used for the compression of large files, and save memory + 瑙e帇缂╃畻娉曞彧鑳芥槸 ZLIB锛岃屼笖涓嶈兘鍔犲瘑锛屼富瑕佺敤浜庤秴澶ф枃浠剁殑鍘嬬缉锛岃妭鐪佸唴瀛 + + + + Extracting data to a file error + 瑙e帇鏁版嵁鍒版枃浠跺嚭閿 + + + + Compressed file formats are illegal.We can not read file header information + 鍘嬬缉鏂囦欢鏍煎紡闈炴硶锛屾棤娉曡鍙栨枃浠跺ご淇℃伅 + + + + Incorrect extraction password + 瑙e帇瀵嗙爜涓嶆纭 + + + + Compression password longer than 80 characters + 鍘嬬缉瀵嗙爜闀垮害瓒呰繃 80 瀛楃 + + + + Does not support the type of variable data type %d + 涓嶆敮鎸佸彉閲忔暟鎹被鍨%d + + + + two + + + + + three + + + + + GLDDateTimeEditEx + + + HINT + 鎻愮ず + + + + The selecting dateTime is before the minimum date + 鎮ㄦ墍閫夋嫨鐨勬棩鏈熷皬浜庢渶灏忔棩鏈 + + + + The selecting dateTime is after the maximum date + 鎮ㄦ墍閫夋嫨鐨勬棩鏈熷ぇ浜庢渶澶ф棩鏈 + + + + The datetime can not include letters + 鏃ユ湡涓嶈兘鍖呭惈瀛楁瘝 + + + + You have input a wrong datetime, please input it again + 鎮ㄧ殑鏃ユ湡杈撳叆鏂瑰紡鏈夎锛岃閲嶆柊杈撳叆 + + + + GLD_Year + + + + + GLD_Month + + + + + GLD_Day + + + + + GLDDockWidget + + + &Lock + 閿佸畾锛&L锛 + + + + &Float + 娴姩锛&F锛 + + + + &Close + 鍏抽棴锛&C锛 + + + + GLDFileDialog + + + Can't find%1.Please check the spelling and try again. + 鎵句笉鍒%1銆傝妫鏌ユ嫾鍐欏苟閲嶈瘯銆 + + + + + + New Folder + 鏂板缓鏂囦欢澶 + + + + Confirm Delete + + + + + Are you sure Delete? + + + + + + GPS_InvalidFileName %1 + + + + + Back To + + + + + Forward To + + + + + Refresh + 鍒锋柊 + + + + ViewMode + 鏌ョ湅 + + + + Change Your View Mode + + + + + Delete + 鍒犻櫎 + + + + Rename + 閲嶅懡鍚 + + + + Small Icon + 灏忓浘鏍 + + + + Detail List + 璇︾粏淇℃伅 + + + + Mid Icon + 涓瓑鍥炬爣 + + + + GLDFileSortModel + + + + + + desktop + 妗岄潰 + + + + Size + 澶у皬 + + + + GLDFileSystemModel + + + desktop + 妗岄潰 + + + + Name + 鍚嶇О + + + + Size + 澶у皬 + + + + Kind + Match OS X Finder + 绫诲瀷 + + + + Type + All other platforms + 绫诲瀷 + + + + Date Modified + 淇敼鏃ユ湡 + + + + GLDFilterWidget + + + Clear text + 娓呯┖ + + + + GLDLineWidthComboBox + + + pixel:%1 + 鍍忕礌:%1 + + + + GLDListView + + + List + 鍒楄〃 + + + + Icon + 鍥炬爣 + + + + Small Icon + 灏忓浘鏍 + + + + Report + 鎶ヨ〃 + + + + Error + 閿欒 + + + + GLDMutilFileModel + + + Name + 鍚嶇О + + + + Type + 绫诲瀷 + + + + Update DateTime + 淇敼鏃ユ湡 + + + + Create DateTime + 鍒涘缓鏃ユ湡 + + + + Size + 澶у皬 + + + + GLDOpenFileDialog + + + Not found File %1 + + + + + + Open + 鎵撳紑 + + + + File Name(N): + 鏂囦欢鍚嶏紙N锛夛細 + + + + Cancel + 鍙栨秷 + + + + GLDSaveAsDialog + + + Save As + 鍙﹀瓨涓 + + + + Save Location: + 淇濆瓨鍦細 + + + + File Name(N): + 鏂囦欢鍚嶏紙N锛夛細 + + + + Save Type(T): + 淇濆瓨绫诲瀷锛圱锛夛細 + + + + + + Save + 淇濆瓨 + + + + + Open + 鎵撳紑 + + + + + Overwrite the original file? + + + + + Cancel + 鍙栨秷 + + + + GLDTableView + + + width: + 瀹: + + + + height: + 楂: + + + + pixel( + 鍍忕礌锛 + + + + millimetre) + 姣背锛 + + + + GLDToolBoxHeader + + + Custom widget classes should not invode this function + 鑷畾涔墂idget涓嶈兘璋冪敤姝ゆ柟娉 + + + + GLDWAbstractSpinBox + + + &Select All + 閫夋嫨鍏ㄩ儴锛&S锛 + + + + &Step up + 澧炲姞锛&S锛 + + + + Step &down + 鍑忓皯锛&D锛 + + + + GLDXMLSAXReader + + + File not exist + 鏂囦欢涓嶅瓨鍦 + + + + GSP + + + No Non Fixed Column to Display + 娌℃湁鍙樉绀虹殑闈炲浐瀹氬垪 + + + + Invalid configuration file + 閰嶇疆鏂囦欢闈炴硶 + + + + XML Node field cannot be null + XML鑺傜偣涓嶈兘涓虹┖ + + + + GlodonTableViewToExcel + + + success export to excel + 瀵煎嚭excel鎴愬姛 + + + + can't open file for writing + 鏂囦欢鍙兘琚崰鐢紝鏃犳硶鎵撳紑鏂囦欢鍐欏叆 + + + + error on saving + 淇濆瓨鍑洪敊 + + + + current tag page existing + 褰撳墠鏍囩椤靛凡缁忓瓨鍦 + + + + QColorDialog + + + Hu&e: + 鑹茶皟锛&E锛夛細 + + + + &Sat: + 楗卞拰搴︼紙&S锛夛細 + + + + &Val: + 浜害锛&V锛夛細 + + + + &Red: + 绾㈣壊锛&R锛夛細 + + + + &Green: + 缁胯壊锛&G锛夛細 + + + + Bl&ue: + 钃濊壊锛&U锛夛細 + + + + A&lpha channel: + Alpha閫氶亾锛&A锛夛細 + + + + Select Color + 閫夋嫨棰滆壊 + + + + &Basic colors + 鍩烘湰棰滆壊锛&B锛 + + + + &Custom colors + 鑷畾涔夐鑹诧紙&C锛 + + + + &Add to Custom Colors + 娣诲姞鍒拌嚜瀹氫箟棰滆壊锛&A锛 + + + + Pick Screen Color + 鎷惧彇灞忓箷棰滆壊 + + + + QDialogButtonBox + + + &Cancel + 鍙栨秷锛&C锛 + + + + &OK + 纭畾(&O) + + + + QFileDialog + + + My Computer + 鎴戠殑鐢佃剳 + + + + QFileSystemModel + + + %1 TB + %1 TB + + + + %1 GB + %1 GB + + + + %1 MB + %1 MB + + + + %1 KB + %1 KB + + + + %1 byte(s) + %1 byte(s) + + + + QObject + + + + desktop + 妗岄潰 + + + diff --git a/GCR/trunk/Glodon/src/GLD/GenVcxproj.bat b/GCR/trunk/Glodon/src/GLD/GenVcxproj.bat new file mode 100644 index 00000000..f610f9a5 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/GenVcxproj.bat @@ -0,0 +1,2 @@ +qmake -spec win32-msvc2010 -r -tp vc GLDAll.pro +GLDAll.sln \ No newline at end of file diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Components/GLDAbstractItemModel.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Components/GLDAbstractItemModel.cpp new file mode 100644 index 00000000..8efc17d4 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Components/GLDAbstractItemModel.cpp @@ -0,0 +1,290 @@ +#include "GLDAbstractItemModel.h" +#include "GLDAbstractItemModel_p.h" + +GlodonAbstractItemModel::GlodonAbstractItemModel(QObject *parent) + : QAbstractItemModel(*new GlodonAbstractItemModelPrivate, parent) +{ +} + +GlodonAbstractItemModel::~GlodonAbstractItemModel() +{ +} + +QVariant GlodonAbstractItemModel::data(const QModelIndex &index, int role) const +{ + Q_D(const GlodonAbstractItemModel); + + if (d->m_showCheckbox) + { + if (Qt::CheckStateRole == role) + { + if (d->m_checkedIndexes.contains(index) && !d->m_partiallyCheckedIndexes.contains(index) && !d->m_forbiddenCheckedIndexes.contains(index)) + { + return Qt::Checked; + } + + if (d->m_forbiddenCheckedIndexes.contains(index)) + { + return Qt::Unchecked; // 为了使不可点击的视觉效果明显 + } + + if (d->m_partiallyCheckedIndexes.contains(index)) + { + return Qt::PartiallyChecked; + } + + return Qt::Unchecked; + } + else if (gidrCheckUnEnableRole == role) + { + return d->m_forbiddenCheckedIndexes.contains(index) ? true : false; + } + } + + return GVariant(); +} + +bool GlodonAbstractItemModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + Q_D(GlodonAbstractItemModel); + + if (! d->indexValid(index)) + { + return false; + } + + if (Qt::CheckStateRole == role) + { + bool result = true; + + if (Qt::Checked == value) + { + d->m_checkedIndexes.insert(index); + } + else + { + d->m_checkedIndexes.remove(index); + } + + d->m_partiallyCheckedIndexes.remove(index); + emit dataChanged(index, index); + + if (d->m_recursiveCheck && hasChildren(index)) + { + result &= recursiveCheck(index, value); + } + + if (d->m_isTristate) + { + result &= recursiveCheckParent(index, value); + } + + return result; + } + else if (gidrAddUnEnableRole == role) + { + d->m_forbiddenCheckedIndexes.insert(index); + d->m_partiallyCheckedIndexes.remove(index); + d->m_checkedIndexes.remove(index); + return true; + } + else if (gidrRemoveUnEnableRole == role) + { + d->m_forbiddenCheckedIndexes.remove(index); + return true; + } + + return false; +} + +Qt::ItemFlags GlodonAbstractItemModel::flags(const QModelIndex &index) const +{ + Q_D(const GlodonAbstractItemModel); + + if (!d->indexValid(index)) + { + return 0; + } + + Qt::ItemFlags oFlags = QAbstractItemModel::flags(index); + + if (d->m_showCheckbox) + { + oFlags |= Qt::ItemIsUserCheckable; + } + + if (d->m_isTristate) + { + oFlags |= Qt::ItemIsTristate; + } + + return oFlags | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; +} + +bool GlodonAbstractItemModel::showCheckBox() +{ + Q_D(GlodonAbstractItemModel); + return d->m_showCheckbox; +} + +void GlodonAbstractItemModel::setShowCheckBox(const bool &value) +{ + Q_D(GlodonAbstractItemModel); + d->m_showCheckbox = value; +} + +bool GlodonAbstractItemModel::isItemIsTristate() +{ + Q_D(GlodonAbstractItemModel); + return d->m_isTristate; +} + +void GlodonAbstractItemModel::setIsTristate(const bool &value) +{ + Q_D(GlodonAbstractItemModel); + d->m_isTristate = value; +} + +bool GlodonAbstractItemModel::isRecursiveCheck() +{ + Q_D(GlodonAbstractItemModel); + return d->m_showCheckbox; +} + +void GlodonAbstractItemModel::setRecursiveCheck(const bool &value) +{ + Q_D(GlodonAbstractItemModel); + d->m_recursiveCheck = value; +} + +void GlodonAbstractItemModel::afterCurrentChanged(const QModelIndex &index) +{ + Q_UNUSED(index); +} + +/*! + \internal +*/ +GlodonAbstractItemModel::GlodonAbstractItemModel(GlodonAbstractItemModelPrivate &dd, QObject *parent) + : QAbstractItemModel(dd, parent) +{ +} + +bool GlodonAbstractItemModel::recursiveCheck(const QModelIndex &index, const GVariant &value) +{ + int nChildCount = rowCount(index); + QModelIndex child; + bool result = true; + + for (int i = 0; i < nChildCount; i++) + { + child = this->index(i, 0, index); + result &= setData(child, value, Qt::CheckStateRole); + } + + return result; +} + +bool GlodonAbstractItemModel::recursiveCheckParent(const QModelIndex &index, const GVariant &value) +{ + Q_D(GlodonAbstractItemModel); + QModelIndex oParentIndex = index.parent(); + + if (! oParentIndex.isValid()) + { + return false; + } + + int nChildCount = rowCount(oParentIndex); + QModelIndex oChild; + Qt::CheckState oState = (Qt::CheckState)value.toInt(); + bool bSameCheck = true; + + if (Qt::PartiallyChecked == oState) + { + recursiveCheckParentPartCheck(oParentIndex); + return true; + } + else if (Qt::Checked == oState) + { + for (int i = 0; i < nChildCount; i++) + { + oChild = this->index(i, 0, oParentIndex); + + if (!d->m_checkedIndexes.contains(oChild)) + { + recursiveCheckParentPartCheck(oParentIndex); + bSameCheck = false; + break; + } + } + } + else + { + for (int i = 0; i < nChildCount; i++) + { + oChild = this->index(i, 0, oParentIndex); + + if (d->m_checkedIndexes.contains(oChild)) + { + recursiveCheckParentPartCheck(oParentIndex); + bSameCheck = false; + break; + } + if(d->m_partiallyCheckedIndexes.contains(oChild)) + { + bSameCheck = false; + break; + } + } + } + + if (bSameCheck) + { + if (Qt::Checked == oState) + { + d->m_checkedIndexes.insert(oParentIndex); + } + else + { + d->m_checkedIndexes.remove(oParentIndex); + } + + d->m_partiallyCheckedIndexes.remove(oParentIndex); + emit dataChanged(oParentIndex, oParentIndex); + recursiveCheckParent(oParentIndex, oState); + } + + return true; +} + +void GlodonAbstractItemModel::recursiveCheckParentPartCheck(const QModelIndex &index) +{ + if (! index.isValid()) + { + return; + } + + Q_D(GlodonAbstractItemModel); + QModelIndex oIndex = index; + + while (oIndex.isValid()) + { + d->m_partiallyCheckedIndexes.insert(oIndex); + d->m_checkedIndexes.remove(oIndex); + emit dataChanged(oIndex, oIndex); + oIndex = oIndex.parent(); + } +} + +/* GlodonAbstractItemModelPrivate */ + +GlodonAbstractItemModelPrivate::GlodonAbstractItemModelPrivate() + : QAbstractItemModelPrivate() , m_showCheckbox(false), m_recursiveCheck(false), + m_isTristate(false) +{ +} + +GlodonAbstractItemModelPrivate::~GlodonAbstractItemModelPrivate() +{ +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Components/GLDFooterModel.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Components/GLDFooterModel.cpp new file mode 100644 index 00000000..997230ff --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Components/GLDFooterModel.cpp @@ -0,0 +1,292 @@ +#include "GLDFooterModel.h" +#include "GLDGlobal.h" +#include "GLDStringList.h" + +class QModelIndexHack +{ +public: + int r, c; + quintptr i; + QAbstractItemModel *m; +}; + +/* GlodonFooterModel */ + +GlodonFooterModel::GlodonFooterModel(QAbstractItemModel *pModel, QObject *parent) : + GlodonAbstractItemModel(parent), m_model(pModel), m_footerRowCount(1) +{ + connect(m_model, SIGNAL(modelReset()), this, SLOT(onResetModel())); + connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector)), + this, SLOT(onDataChange(QModelIndex,QModelIndex,QVector))); +} + +QModelIndex GlodonFooterModel::index(const QModelIndex &dataIndex) const +{ + return index(dataIndex.row(), dataIndex.column(), dataIndex.parent()); +} + +QModelIndex GlodonFooterModel::index(int row, int column, const QModelIndex &parent) const +{ + QModelIndex oIndex = m_model->index(row + m_model->rowCount() - m_footerRowCount, column, parent); + return createIndex(row, column, oIndex.internalPointer()); +} + +QModelIndex GlodonFooterModel::parent(const QModelIndex &child) const +{ + return QModelIndex(); + Q_UNUSED(child) +} + +int GlodonFooterModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + else + return m_footerRowCount; +} + +int GlodonFooterModel::columnCount(const QModelIndex &parent) const +{ + return m_model->columnCount(dataIndex(parent)); +} + +bool GlodonFooterModel::hasChildren(const QModelIndex &parent) const +{ + return false; + Q_UNUSED(parent) +} + +QVariant GlodonFooterModel::data(const QModelIndex &index, int role) const +{ + return m_model->data(dataIndex(index), role); +} + +bool GlodonFooterModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + return m_model->setData(dataIndex(index), value, role); +} + +QModelIndex GlodonFooterModel::dataIndex(const QModelIndex &footerIndex) const +{ + if (footerIndex.isValid()) + { + int nRow = m_model->rowCount() - m_footerRowCount; + return m_model->index(nRow + footerIndex.row(), footerIndex.column(), footerIndex.parent()); + } + else + { + return QModelIndex(); + } +} + +QModelIndex GlodonFooterModel::footerIndex(const QModelIndex &dataIndex) const +{ + if (!dataIndex.isValid()) + return QModelIndex(); + QModelIndex parent = dataIndex.parent(); + if (!parent.isValid()) + { + int nRowCount = m_model->rowCount(parent); + return index(dataIndex.row() - (nRowCount - m_footerRowCount), + dataIndex.column(), dataIndex.parent()); + } + else + return QModelIndex(); +} + +void GlodonFooterModel::onDataChange(const QModelIndex &topLeft, const QModelIndex &bottomRight, + const QVector &roles) +{ + emit dataChanged(footerIndex(topLeft), footerIndex(bottomRight), roles); +} + +void GlodonFooterModel::onResetModel() +{ + beginResetModel(); + endResetModel(); +} + +/*GlodonFooterBodyModel*/ + +GlodonFooterBodyModel::GlodonFooterBodyModel(QAbstractItemModel *model, QObject *parent) : + GlodonAbstractItemModel(parent), m_model(model), m_footerRowCount(1) +{ + connect(m_model, SIGNAL(rowsInserted(const QModelIndex &,int,int)), this, + SLOT(onRowInserted(const QModelIndex &,int,int))); + connect(m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(onRowRemoved(QModelIndex,int,int))); + connect(m_model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), + this, SLOT(onRowMoved(QModelIndex,int,int,QModelIndex,int))); + connect(m_model, SIGNAL(modelReset()), this, SLOT(onResetModel())); + connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector)), + this, SLOT(onDataChange(QModelIndex,QModelIndex,QVector))); +} + +QModelIndex GlodonFooterBodyModel::index(const QModelIndex &dataIndex) const +{ + return createIndex(dataIndex.row(), dataIndex.column(), dataIndex.internalPointer()); +} + +QModelIndex GlodonFooterBodyModel::index(int row, int column, const QModelIndex &parent) const +{ + QModelIndex oIndex = m_model->index(row, column, dataIndex(parent)); + if (!oIndex.isValid()) + { + return QModelIndex(); + } + return createIndex(oIndex.row(), oIndex.column(), oIndex.internalPointer()); +} + +QModelIndex GlodonFooterBodyModel::parent(const QModelIndex &child) const +{ + if (!child.isValid()) + return QModelIndex(); + return footerBodyIndex(m_model->parent(dataIndex(child))); +} + +int GlodonFooterBodyModel::rowCount(const QModelIndex &parent) const +{ + QModelIndex oParentDataIndex = dataIndex(parent); + int nRowCount = m_model->rowCount(oParentDataIndex); + if (parent.isValid()) + { + return nRowCount; + } + else + { + if (nRowCount > 0) + return nRowCount - m_footerRowCount; + else + return 0; + } +} + +int GlodonFooterBodyModel::columnCount(const QModelIndex &parent) const +{ + return m_model->columnCount(dataIndex(parent)); +} + +bool GlodonFooterBodyModel::hasChildren(const QModelIndex &parent) const +{ + return m_model->hasChildren(dataIndex(parent)); +} + +QVariant GlodonFooterBodyModel::data(const QModelIndex &index, int role) const +{ + return m_model->data(dataIndex(index), role); +} + +bool GlodonFooterBodyModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + return m_model->setData(dataIndex(index), value, role); +} + +QVariant GlodonFooterBodyModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + return m_model->headerData(section, orientation, role); +} + +bool GlodonFooterBodyModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role) +{ + return m_model->setHeaderData(section, orientation, value, role); +} + +void GlodonFooterBodyModel::sort(int column, Qt::SortOrder order) +{ + emit layoutAboutToBeChanged(); + + m_model->sort(column, order); + + emit layoutChanged(); +} + +Qt::ItemFlags GlodonFooterBodyModel::flags(const QModelIndex &index) const +{ + return m_model->flags(dataIndex(index)); +} + +QStringList GlodonFooterBodyModel::mimeTypes() const +{ + return m_model->mimeTypes(); +} + +QMimeData *GlodonFooterBodyModel::mimeData(const QModelIndexList &indexes) const +{ + QModelIndexList dataIndexes; + for (int i = 0; i < indexes.count(); ++i) + { + dataIndexes.append(dataIndex(indexes.at(i))); + } + return m_model->mimeData(dataIndexes); +} + +bool GlodonFooterBodyModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, + const QModelIndex &parent) const +{ + return m_model->canDropMimeData(data, action, row, column, dataIndex(parent)); +} + +bool GlodonFooterBodyModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, + const QModelIndex &parent) +{ + return m_model->dropMimeData(data, action, row, column, dataIndex(parent)); +} + +QModelIndex GlodonFooterBodyModel::dataIndex(const QModelIndex &footerIndex) const +{ + if (footerIndex.isValid()) + { + QModelIndex result = footerIndex; + reinterpret_cast(&result)->m = m_model; + return result; + } + else + { + return QModelIndex(); + } +} + +QModelIndex GlodonFooterBodyModel::footerBodyIndex(const QModelIndex &dataIndex) const +{ + if (!dataIndex.isValid()) + { + return QModelIndex(); + } + return createIndex(dataIndex.row(), dataIndex.column(), dataIndex.internalPointer()); +} + +void GlodonFooterBodyModel::onRowRemoved(const QModelIndex &parent, int first, int last) +{ + beginRemoveRows(dataIndex(parent), first, last); + endRemoveRows(); +} + +void GlodonFooterBodyModel::onRowInserted(const QModelIndex &parent, int first, int last) +{ + beginInsertRows(dataIndex(parent), first, last); + endInsertRows(); +} + +void GlodonFooterBodyModel::onRowMoved(const QModelIndex &parent, int start, int end, const QModelIndex &destination, + int row) +{ + beginMoveRows(dataIndex(parent), start, end, dataIndex(destination), row); + endMoveRows(); +} + +void GlodonFooterBodyModel::onUpdate(QModelIndex &topLeft) +{ + topLeft = index(topLeft); +} + +void GlodonFooterBodyModel::onResetModel() +{ + beginResetModel(); + m_footerRowCount = m_model->data(QModelIndex(), gidrFooterRowCount).toInt(); + endResetModel(); +} + +void GlodonFooterBodyModel::onDataChange(const QModelIndex &topLeft, const QModelIndex &bottomRight, + const QVector &roles) +{ + emit dataChanged(index(topLeft), index(bottomRight), roles); +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Components/GLDGroupModel.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Components/GLDGroupModel.cpp new file mode 100644 index 00000000..ac0a33ae --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Components/GLDGroupModel.cpp @@ -0,0 +1,448 @@ +#include "GLDGroupModel.h" +#include "GLDGlobal.h" + +#include + +GlodonGroupModel::GlodonGroupModel(QAbstractItemModel *pModel, QObject *parent) : + QAbstractItemModel(parent) +{ + m_model = pModel; + m_root = new GlodonGroupModelGroupItem(); + m_treeCol = MaxInt; + buildModel(); + connect(pModel, SIGNAL(modelReset()), this, SLOT(onResetModel())); +} + +GlodonGroupModel::~GlodonGroupModel() +{ + delete m_root; +} + +QModelIndex GlodonGroupModel::index(int row, int column, const QModelIndex &parent) const +{ + if (!parent.isValid()) + { + if (row < 0 || column < 0 || row > m_model->rowCount() - 1 || column > m_model->columnCount() - 1) + { + return QModelIndex(); + } + + return createIndex(row, column, m_root->child.at(row)); + } + + if (GlodonGroupModelAbstractItem * parentItem + = static_cast(parent.internalPointer())) + { + if (row < 0 || column < 0) + { + return QModelIndex(); + } + else + { + return createIndex(row, column, parentItem->child.at(row)); + } + } + else + { + return QModelIndex(); + } +} + +QModelIndex GlodonGroupModel::parent(const QModelIndex &child) const +{ + if (!child.isValid()) + { + return QModelIndex(); + } + + if (GlodonGroupModelAbstractItem *item = static_cast(child.internalPointer())) + { + if (item->parent == m_root) + { + return QModelIndex(); + } + + GlodonGroupModelAbstractItem *parentItem = item->parent->parent; + int row = 0; + + for (row = 0; row < parentItem->child.count(); row++) + { + if (parentItem->child.indexOf(item) >= 0) + { + return createIndex(row, 0, item->parent); + } + } + } + + return QModelIndex(); +} + +int GlodonGroupModel::rowCount(const QModelIndex &parent) const +{ + if (!parent.isValid()) + { + return m_root->child.count(); + } + + if (GlodonGroupModelAbstractItem *item = static_cast(parent.internalPointer())) + { + return item->child.count(); + } + + return 0; +} + +int GlodonGroupModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return m_model->columnCount(); +} + +QVariant GlodonGroupModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + { + return QVariant(); + } + + GlodonGroupModelAbstractItem *item = static_cast(index.internalPointer()); + + if (item == NULL) + { + return QVariant(); + } + + if (item->type() == GlodonGroupModelAbstractItem::CXGroup) + { + return groupData(index, role, item); + } + else + { + return itemData(index, role, item); + } + + return QVariant(); +} + +bool GlodonGroupModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (!index.isValid()) + { + return false; + } + + if (GlodonGroupModelAbstractItem *item = static_cast(index.internalPointer())) + { + if (item->type() == GlodonGroupModelAbstractItem::CXGroup) + { + return false; + } + else + { + GlodonGroupModelDataItem *dataItem = dynamic_cast(item); + QModelIndex indexForData = m_model->index(dataItem->index(), index.column(), dataItem->parentIndex()); + return m_model->setData(indexForData, value, role); + } + } + + return false; +} + +QVariant GlodonGroupModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + return m_model->headerData(section, orientation, role); +} + +bool GlodonGroupModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role) +{ + return m_model->setHeaderData(section, orientation, value, role); +} + +Qt::ItemFlags GlodonGroupModel::flags(const QModelIndex &index) const +{ + if (GlodonGroupModelAbstractItem *item = static_cast(index.internalPointer())) + { + if (item->type() == GlodonGroupModelAbstractItem::CXData) + { + GlodonGroupModelDataItem *dataItem = dynamic_cast(item); + QModelIndex indexForData = m_model->index(dataItem->index(), index.column(), dataItem->parentIndex()); + return m_model->flags(indexForData); + } + else + { + return Qt::ItemIsSelectable | Qt::ItemIsEnabled; + } + } + + return Qt::NoItemFlags; +} + +void GlodonGroupModel::buildModel(bool reset) +{ + if (reset) + { + resetModel(); + } + + //QTime startBuildModel = QTime::currentTime(); + + m_root->child.clear(); + + if (m_groupCols.count() == 0) + { + for (int i = 0; i < m_model->rowCount(); i++) + { + GlodonGroupModelDataItem *item; + QModelIndex index = m_model->index(i, 0); + item = new GlodonGroupModelDataItem(index.parent(), m_root); + item->setIndex(i); + LoadChildModelIndex(item, index); + m_root->child.append(item); + } + } + else + { + int nCurrCol = m_groupCols[0]; + ValueRowInfo valueInfo; + + //QTime start = QTime::currentTime(); + + for (int i = 0; i < m_model->rowCount(); i++) + { + QString strValue = m_model->data(m_model->index(i, nCurrCol)).toString(); + valueInfo.insertMulti(strValue, i); + } + + QList keys = valueInfo.uniqueKeys(); + + for (int i = 0; i < keys.count(); i++) + { + GlodonGroupModelGroupItem *item = new GlodonGroupModelGroupItem(m_root); + QList value = valueInfo.values(keys[i]); + item->setData(m_model->headerData(nCurrCol, Qt::Horizontal).toString() + ": " + keys[i]); + loadChildItems(1, value, item); + m_root->child.append(item); + } + } + + emit modelRebuild(); +} + +QAbstractItemModel *GlodonGroupModel::model() const +{ + return m_model; +} + +void GlodonGroupModel::setModel(QAbstractItemModel *model) +{ + if (model == m_model) + { + return; + } + + m_model = model; + buildModel(true); +} + +QModelIndex GlodonGroupModel::dataIndex(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return QModelIndex(); + } + + if (GlodonGroupModelAbstractItem *item = static_cast(index.internalPointer())) + { + if (item->type() == GlodonGroupModelAbstractItem::CXGroup) + { + return QModelIndex(); + } + else + { + GlodonGroupModelDataItem *dataItem = dynamic_cast(item); + QModelIndex indexForData = m_model->index(dataItem->index(), index.column(), dataItem->parentIndex()); + return indexForData; + } + } + + return QModelIndex(); +} + +QModelIndex GlodonGroupModel::groupIndex(const QModelIndex &index) const +{ + Q_UNUSED(index); + return QModelIndex(); +} + +void GlodonGroupModel::groupChanged(QVector newGroup) +{ + m_groupCols.clear(); + m_groupCols = newGroup; + m_treeCol = 0; + + // 得到当前的树形所在的列 + for (int nCol = 0; nCol < model()->columnCount(); ++nCol) + { + for (int nGroup = 0; nGroup < m_groupCols.size(); ++nGroup) + { + if (nCol == m_groupCols.at(nGroup) && nCol <= m_treeCol) + { + m_treeCol++; + break; + } + } + } + + buildModel(); +} + +void GlodonGroupModel::onResetModel() +{ + buildModel(true); +} + +void GlodonGroupModel::resetModel() +{ + m_groupCols.clear(); + m_valueInfo.clear(); +} + +void GlodonGroupModel::loadChildItems(int index, const QList &rows, GlodonGroupModelAbstractItem *parent) +{ + if (index == m_groupCols.count()) + { + for (int i = 0; i < rows.count(); i++) + { + int nRow = rows[i]; + QModelIndex dataIndex = m_model->index(nRow, 0); + GlodonGroupModelDataItem *item = new GlodonGroupModelDataItem(dataIndex.parent(), parent); + item->setIndex(nRow); + + if (m_model->hasChildren(dataIndex)) + { + LoadChildModelIndex(item, dataIndex); + } + + parent->child.append(item); + } + } + else + { + int nCurrCol = m_groupCols[index]; + + ValueRowInfo valueInfo; + + //QTime start = QTime::currentTime(); + for (int i = 0; i < rows.count(); i++) + { + QString strValue = m_model->data(m_model->index(rows[i], nCurrCol)).toString(); + valueInfo.insertMulti(strValue, rows[i]); + } + + QList keys = valueInfo.uniqueKeys(); + + for (int i = 0; i < keys.count(); i++) + { + GlodonGroupModelGroupItem *item = new GlodonGroupModelGroupItem(parent); + QList value = valueInfo.values(keys[i]); + item->setData(m_model->headerData(nCurrCol, Qt::Horizontal).toString() + ": " + keys[i]); + loadChildItems(index + 1, value, item); + parent->child.append(item); + } + } +} + +void GlodonGroupModel::LoadChildModelIndex(GlodonGroupModelAbstractItem *parentItem, QModelIndex parentIndex) +{ + for (int nRow = 0; nRow < m_model->rowCount(parentIndex); nRow++) + { + QModelIndex dataIndex = m_model->index(nRow, 0, parentIndex); + GlodonGroupModelDataItem *item = new GlodonGroupModelDataItem(parentIndex, parentItem); + item->setIndex(nRow); + + if (m_model->hasChildren(dataIndex)) + { + LoadChildModelIndex(item, dataIndex); + } + + parentItem->child.append(item); + } +} + +void GlodonGroupModel::initColumnValueInfo(int col) +{ + ValueRowInfo rowInfo = m_valueInfo.value(col); + + for (int row = 0; row < m_model->rowCount(); row++) + { + QModelIndex index = m_model->index(row, col); + QString strData = m_model->data(index).toString(); + rowInfo.insertMulti(strData, row); + } + + m_valueInfo.insert(col, rowInfo); +} + +QVariant GlodonGroupModel::groupData(const QModelIndex &index, int role, GlodonGroupModelAbstractItem *item) const +{ + if (index.column() <= m_treeCol || role == Qt::BackgroundColorRole) + { + switch (role) + { + case Qt::TextAlignmentRole: + { + return Qt::AlignVCenter; + } + + case Qt::DisplayRole: + { + return static_cast(item)->data(); + } + + case Qt::BackgroundColorRole: + { +#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) + // todo qt5 + return QColor(Qt::gray); +#else + return Qt::gray; +#endif + } + } + } + + return QVariant(); +} + +QVariant GlodonGroupModel::itemData(const QModelIndex &index, int role, GlodonGroupModelAbstractItem *item) const +{ + if (role == 91) + { + return item->type(); + } + + GlodonGroupModelDataItem *dataItem = dynamic_cast(item); + QModelIndex indexForData = m_model->index(dataItem->index(), index.column(), dataItem->parentIndex()); + return indexForData.data(role); +} + +GlodonGroupModelAbstractItem::GlodonGroupModelAbstractItem(GlodonGroupModelAbstractItem *parentItem) +{ + parent = parentItem; +} + +GlodonGroupModelAbstractItem::~GlodonGroupModelAbstractItem() +{ + child.clear(); +} + +GlodonGroupModelDataItem::GlodonGroupModelDataItem(QModelIndex parentIndex, GlodonGroupModelAbstractItem *parentItem) + : GlodonGroupModelAbstractItem(parentItem) +{ + m_index = parentIndex; +} + +GlodonGroupModelGroupItem::GlodonGroupModelGroupItem(GlodonGroupModelAbstractItem *parentItem) + : GlodonGroupModelAbstractItem(parentItem) +{ +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Components/GLDTreeModel.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Components/GLDTreeModel.cpp new file mode 100644 index 00000000..3756407d --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Components/GLDTreeModel.cpp @@ -0,0 +1,371 @@ +#include "GLDTreeModel.h" + +#include "GLDAbstractItemModel.h" + +GlodonTreeModel::GlodonTreeModel(QAbstractItemModel *pModel, QObject *parent) : + GlodonAbstractItemModel(parent) +{ + model = pModel; + + connect(pModel, SIGNAL(rowsInserted(QModelIndex, int, int)), + this, SLOT(onRowInserted(QModelIndex, int, int))); + connect(pModel, SIGNAL(rowsRemoved(QModelIndex, int, int)), + this, SLOT(onRowRemoved(QModelIndex, int, int))); + connect(pModel, SIGNAL(rowsMoved(QModelIndex, int, int, QModelIndex, int)), + this, SLOT(onRowMoved(QModelIndex, int, int, QModelIndex, int))); + connect(pModel, SIGNAL(modelReset()), + this, SLOT(onResetModel())); + connect(pModel, SIGNAL(dataChanged(QModelIndex, QModelIndex, QVector)), + this, SLOT(onUpdate(QModelIndex, QModelIndex, QVector))); + + root = QModelIndex(); +} + +QModelIndex GlodonTreeModel::index(int row, int column, const QModelIndex &parent) const +{ + Q_UNUSED(parent); + + if (row < drawInfo->m_viewItems.count()) + { + return createIndex(row, column); + } + else + { + return QModelIndex(); + } +} + +QModelIndex GlodonTreeModel::parent(const QModelIndex &child) const +{ + Q_UNUSED(child); + return QModelIndex(); +} + +int GlodonTreeModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return drawInfo->m_viewItems.count(); +} + +int GlodonTreeModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return model->columnCount(); +} + +QVariant GlodonTreeModel::data(const QModelIndex &index, int role) const +{ + QModelIndex data = dataIndex(index); + return model->data(data, role); +} + +bool GlodonTreeModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + QModelIndex data = dataIndex(index); + return model->setData(data, value, role); +} + +QMap GlodonTreeModel::itemData(const QModelIndex &index) const +{ + QModelIndex data = dataIndex(index); + return model->itemData(data); +} + +bool GlodonTreeModel::setItemData(const QModelIndex &index, const QMap &roles) +{ + QModelIndex data = dataIndex(index); + return model->setItemData(data, roles); +} + +QVariant GlodonTreeModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (orientation == Qt::Horizontal) + { + return model->headerData(section, orientation, role); + } + else + { + QModelIndex oIndex = dataIndex(index(section, 0)); + + switch (role) + { + case Qt::TextAlignmentRole: + { + return model->data(oIndex, gidrHeaderTextAlignmentRole); + } + + case Qt::DisplayRole: + { + if (oIndex.parent().isValid()) + { + return model->data(oIndex, gidrRowHeaderData); + } + else + { + return model->headerData(oIndex.row(), orientation, role); + } + } + + case Qt::DecorationRole: + { + return model->data(oIndex, gidrHeaderDecorationRole); + } + + case Qt::FontRole: + { + return model->data(oIndex, gidrHeaderFontRole); + } + + case Qt::DecorationPropertyRole: + { + return model->data(oIndex, Qt::DecorationPropertyRole); + } + + default: + { + return model->headerData(oIndex.row(), orientation, role); + } + } + } +} + +bool GlodonTreeModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role) +{ + return model->setHeaderData(section, orientation, value, role); +} + +Qt::ItemFlags GlodonTreeModel::flags(const QModelIndex &index) const +{ + return model->flags(dataIndex(index)); +} + +QStringList GlodonTreeModel::mimeTypes() const +{ + return model->mimeTypes(); +} + +QMimeData *GlodonTreeModel::mimeData(const QModelIndexList &indexes) const +{ + QModelIndexList dataIndexes; + + for (int i = 0; i < indexes.count(); ++i) + { + dataIndexes.append(dataIndex(indexes.at(i))); + } + + return model->mimeData(dataIndexes); +} + +bool GlodonTreeModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, + int column, const QModelIndex &parent) +{ + return model->dropMimeData(data, action, row, column, dataIndex(parent)); +} + +bool GlodonTreeModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, + const QModelIndex &parent) const +{ + return model->canDropMimeData(data, action, row, column, dataIndex(parent)); +} + +QModelIndex GlodonTreeModel::dataIndex(int row, int column) const +{ + if (row < 0 || column < 0 || row >= drawInfo->m_viewItems.count()) + { + return QModelIndex(); + } + + int nParentItem = drawInfo->m_viewItems[row].parentIndex; + + if (nParentItem == -1) + { + return model->index(drawInfo->m_viewItems[row].modelIndex.row(), + column); + } + else + { + return model->index(drawInfo->m_viewItems[row].modelIndex.row(), + column, + drawInfo->m_viewItems[nParentItem].modelIndex); + } +} + +QModelIndex GlodonTreeModel::dataIndex(const QModelIndex &index) const +{ + if (index.isValid()) + { + return dataIndex(index.row(), index.column()); + } + else + { + return QModelIndex(); + } +} + +void GlodonTreeModel::onRowRemoved(const QModelIndex &parent, int first, int last) +{ + int nRow = drawInfo->rowNo(parent); + + if (nRow < -1) + { + return; + } + + int nStart = visualRowNo(parent, first); + int nEnd = visualRowNo(parent, last); + + int nLastDelRow = nEnd + drawInfo->m_viewItems[nEnd].childCount; + + for (int i = nEnd; i >= nStart; i--) + { + if (nRow == drawInfo->m_viewItems.at(i).parentIndex) + { + drawInfo->removeViewItem(i); + } + } + + beginRemoveRows(root, nStart, nLastDelRow); + endRemoveRows(); +// onResetModel(); +} + +void GlodonTreeModel::onRowInserted(const QModelIndex &parent, int first, int last) +{ + int row = drawInfo->rowNo(parent); + + if (row < -1) + { + return; + } + + QVector insertedRows; + + for (int i = first; i <= last; i++) + { + QModelIndex dataIndex = model->index(i, 0, parent); + int nCurr = drawInfo->insertViewItem(row, dataIndex); + + if (model->hasChildren(dataIndex)) + { + onRowInserted(dataIndex, 0, model->rowCount(dataIndex) - 1); + } + + if (nCurr >= 0) + { + insertedRows.append(nCurr); + } + } + + int nIndex = 0; + + while (nIndex < insertedRows.count()) + { + int ninsertedFirst = insertedRows.at(nIndex); + int ncount = 1; + + while (true) + { + if (insertedRows.last() == ninsertedFirst + ncount - 1) + { + beginInsertRows(root, ninsertedFirst, ninsertedFirst + ncount - 1); + endInsertRows(); + return; + } + + if (insertedRows.at(nIndex) == insertedRows.at(nIndex + 1) - 1) + { + nIndex++; + ncount++; + } + else + { + beginInsertRows(root, ninsertedFirst, ninsertedFirst + ncount - 1); + endInsertRows(); + nIndex++; + break; + } + } + } +} + +void GlodonTreeModel::onRowMoved(const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row) +{ + Q_UNUSED(parent); + Q_UNUSED(start); + Q_UNUSED(end); + Q_UNUSED(destination); + Q_UNUSED(row); + + onResetModel(); +} + +void GlodonTreeModel::onUpdate(const QModelIndex &topLeft, + const QModelIndex &bottomRight, + const QVector &roles) +{ + int ntopRowNo = visualRowNo(topLeft.parent(), topLeft.row()); + int nbottomRowNo = visualRowNo(bottomRight.parent(), bottomRight.row()); + + if (ntopRowNo > nbottomRowNo) + { + int ntemp = ntopRowNo; + ntopRowNo = nbottomRowNo; + nbottomRowNo = ntemp; + } + + emit dataChanged(index(ntopRowNo, topLeft.column()), + index(nbottomRowNo, bottomRight.column()), + roles); +} + +void GlodonTreeModel::onResetModel() +{ + drawInfo->reset(); + + beginResetModel(); + endResetModel(); +} + +int GlodonTreeModel::visualRowNo(const QModelIndex &parent, int row) const +{ + int nParentRow = drawInfo->rowNo(parent); + + int nIndex = nParentRow + 1; + + while (row != 0) + { + if (nIndex < 0) + { + break; + } + + if (nIndex >= drawInfo->m_viewItems.count()) + { + break; + } + + nIndex += (drawInfo->m_viewItems[nIndex].childCount + 1); + row--; + } + + return nIndex; +} + +QModelIndex GlodonTreeModel::treeIndex(const QModelIndex &dataIndex) const +{ + if (!dataIndex.isValid()) + { + return QModelIndex(); + } + + Q_ASSERT(dataIndex.model() == model); + + int row = visualRowNo(dataIndex.parent(), dataIndex.row()); + + return index(row, dataIndex.column()); +} + +void GlodonTreeModel::sort(int column, Qt::SortOrder order) +{ + model->sort(column, order); +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Components/GLDXLSModel.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Components/GLDXLSModel.cpp new file mode 100644 index 00000000..c4448dea --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Components/GLDXLSModel.cpp @@ -0,0 +1,500 @@ +#include "GLDXLSModel.h" +#include "GLDGlobal.h" +#include "GLDStrUtils.h" +#include +#include +#include +#include "GLDFileInfo.h" +#include "GLDXLS.h" + +using namespace libxl; + +/* GlodonXLSModel */ + +GlodonXLSModel::GlodonXLSModel(QObject *parent) : GlodonAbstractItemModel(parent), + m_book(NULL), m_bakBook(NULL), m_sheet(NULL), m_editable(false) +{ +} + +GlodonXLSModel::~GlodonXLSModel() +{ + while(m_listBook.count() != NULL) + { + libxl::Book *listBook = m_listBook.takeFirst(); + if (listBook != NULL) + { + listBook->release(); + } + } +} + +bool GlodonXLSModel::load(const GString &fileName) +{ + GFileInfo fi(fileName); + + if (fi.suffix() == "xls") + { + m_book = createXLSBook(true); + + if (!m_listBook.contains(m_book)) + { + m_listBook.append(m_book); + } + } + else + { + m_book = createXLSBook(false); + } + + m_book->setRgbMode(true); + + m_bakBook = createXLSBook(true); + + if (!m_listBook.contains(m_bakBook)) + { + m_listBook.append(m_bakBook); + } + + m_bakBook->setRgbMode(true); + return m_book->load((const wchar_t *)fileName.constData()); +} + +bool GlodonXLSModel::save(const GString &fileName) +{ + return m_book->save((const wchar_t *)fileName.constData()); +} + +bool GlodonXLSModel::setSheetIndex(int index) +{ + if (m_book && (m_book->sheetCount() > 0) && (index >= 0) && (index < m_book->sheetCount())) + { + m_sheet = m_book->getSheet(index); + return m_sheet != NULL; + } + + return false; +} + +void GlodonXLSModel::setXlsBook(Book *oBook) +{ + m_book = oBook; + +// if (NULL == m_bakBook) +// { +// m_bakBook = createXLSBook(true); +// m_bakBook->setRgbMode(true); +// } +} + +void GlodonXLSModel::setXlsBakBook(Book *oBakBook) +{ + m_bakBook = oBakBook; +} + +GString GlodonXLSModel::getSheetName() const +{ + if (NULL != m_sheet) + { + return GString::fromWCharArray(m_sheet->name()); + } + + return GString(""); +} + +QModelIndex GlodonXLSModel::index(int row, int column, const QModelIndex &) const +{ + return createIndex(row, column); +} + +QModelIndex GlodonXLSModel::parent(const QModelIndex &) const +{ + return QModelIndex(); +} + +int GlodonXLSModel::rowCount(const QModelIndex &parent) const +{ + if (!m_sheet) + { + return 0; + } + + if (parent.isValid()) + { + return 0; + } + else if (m_sheet->lastRow() >= 0) + { + return m_sheet->lastRow(); + } + else + { + return 0; + } +} + +int GlodonXLSModel::columnCount(const QModelIndex &parent) const +{ + if (!m_sheet) + { + return 0; + } + + if (parent.isValid()) + { + return 0; + } + else + { + return m_sheet->lastCol(); + } +} + +bool GlodonXLSModel::hasChildren(const QModelIndex &parent) const +{ + if (!m_sheet) + { + return false; + } + + if (parent.isValid()) + { + return false; + } + else + { + return m_sheet->lastRow() >= 0; + } +} + +QVariant GlodonXLSModel::data(const QModelIndex &index, int role) const +{ + if (!m_sheet) + { + return QVariant(); + } + + if (!index.isValid()) + { + return QVariant(); + } + +// switch (m_sheet->cellType(index.row(), index.column())) +// { +// case CELLTYPE_EMPTY: +// case CELLTYPE_BLANK: +// case CELLTYPE_ERROR: +// return QVariant(); + +// default: +// break; +// } + + switch (role) + { + case Qt::DisplayRole: + return displayData(index.row(), index.column()); + + case Qt::EditRole: + return editData(index.row(), index.column()); + + case gidrCommentRole: + return QString((const QChar *)m_sheet->readComment(index.row(), index.column())); + + case gidrRowExpandedRole: + return true; + + case gidrRowHeightRole: + return m_sheet->rowHeight(index.row()); + + case gidrColWidthRole: + { + // 微软官方说:一般取的时标准字体宽度值 8.43 + return m_sheet->colWidth(index.column()) * 8.5; + } + + case gidrRowHeaderData: + return QVariant(); + + case gidrMergeIDRole: + { + int nrowFirst = -1; + int nrowLast = -1; + int ncolFirst = -1; + int ncolLast = -1; + m_sheet->getMerge(index.row(), index.column(), &nrowFirst, &nrowLast, &ncolFirst, &ncolLast); + + if (nrowFirst >= 0 && ncolFirst >= 0) + { + return nrowFirst * 1000 + ncolFirst + 1; + } + else + { + return 0; + } + } + + default: + break; + } + + Format *format = NULL; + + switch (role) + { + case Qt::FontRole: + case Qt::TextAlignmentRole: + case Qt::BackgroundColorRole: + case Qt::ForegroundRole: + format = m_sheet->cellFormat(index.row(), index.column()); + + default: + break; + } + + if (!format) + { + return QVariant(); + } + + switch (role) + { + case Qt::FontRole: + { + Font *pFont = format->font(); + + if (!pFont) + { + return QVariant(); + } + + QFont result(QString((const QChar *)pFont->name()), pFont->size(), + -1, pFont->italic()); + result.setStrikeOut(pFont->strikeOut()); + result.setBold(pFont->bold()); + result.setUnderline(UNDERLINE_NONE != pFont->underline()); + return result; + } + + case Qt::TextAlignmentRole: + { + int result = XLSAlignmentToQtAlignment(format->alignH(), format->alignV()); + return result; + } + + case Qt::BackgroundColorRole: + { + Color color = format->patternForegroundColor(); + + //修改导入excel颜色不正确的bug + if (color >= COLOR_DEFAULT_FOREGROUND || color == Color(-1)) + { + return QColor(255, 255, 255); + } + + int nRed = 255; + int nGreen = 255; + int nBlue = 255; + m_bakBook->colorUnpack(color, &nRed, &nGreen, &nBlue); + return QColor(nRed, nGreen, nBlue); + } + + case Qt::ForegroundRole: + { + Font *pFont = format->font(); + + if (!pFont) + { + return QVariant(); + } + + Color color = pFont->color(); + + if (color == Color(-1)) + { + color = COLOR_BLACK; + } + + if (color >= COLOR_DEFAULT_FOREGROUND) + { + return QVariant(); + } + + int nRed = 0; + int nGreen = 0; + int nBlue = 0; + m_bakBook->colorUnpack(color, &nRed, &nGreen, &nBlue); + return QColor(nRed, nGreen, nBlue); + } + + default: + return QVariant(); + } +} + +bool GlodonXLSModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (!m_sheet) + { + return false; + } + + if (!m_editable) + { + return false; + } + + switch (role) + { + case Qt::EditRole: + return doSetEditData(index.row(), index.column(), value); + break; + + default: + break; + } + + return false; +} + +QVariant GlodonXLSModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (!m_sheet) + { + return QVariant(); + } + + switch (role) + { + case Qt::DisplayRole: + case Qt::EditRole: + { + if (orientation == Qt::Vertical) + { + return section + 1; + } + else + { + return QChar(QLatin1Char('A' + section)); + } + } + + default: + return QVariant(); + } +} + +bool GlodonXLSModel::setHeaderData(int, Qt::Orientation, const QVariant &, int) +{ + return false; +} + +Qt::ItemFlags GlodonXLSModel::flags(const QModelIndex &index) const +{ + if (!m_sheet) + { + return inherited::flags(index); + } + + if (!index.isValid()) + { + return 0; + } + + Qt::ItemFlags result = Qt::ItemIsSelectable | Qt::ItemIsEnabled; + + if (m_editable) + { + result |= Qt::ItemIsEditable; + } + + return result; +} + +QVariant GlodonXLSModel::displayData(int row, int col) const +{ + switch (m_sheet->cellType(row, col)) + { + case CELLTYPE_EMPTY: + return QString(); + + case CELLTYPE_NUMBER: + return m_sheet->readNum(row, col); + + case CELLTYPE_STRING: + { + return QString((const QChar *)m_sheet->readStr(row, col)); + } + + case CELLTYPE_BOOLEAN: + return m_sheet->readBool(row, col); + + case CELLTYPE_BLANK: + return QString(); + + case CELLTYPE_ERROR: + default: + return QVariant(); + } +} + +QVariant GlodonXLSModel::editData(int row, int col) const +{ + if (m_sheet->isFormula(row, col)) + { + return QString("=") + QString((const QChar *)m_sheet->readFormula(row, col)); + } + else + { + return displayData(row, col); + } +} + +bool GlodonXLSModel::doSetEditData(int row, int col, const QVariant &value) +{ + if (value.type() == QVariant::String) + { + const wchar_t *pWChar = (const wchar_t *)value.toString().constData(); + + if (!value.isNull() && (pWChar[0] == L'=')) + { + pWChar++; + m_sheet->writeFormula(row, col, pWChar); + } + else + { + m_sheet->writeStr(row, col, pWChar); + } + + return true; + } + else if (variantTypeIsNumeric(value.type())) + { + m_sheet->writeNum(row, col, value.toDouble()); + return true; + } + else if (value == QVariant())//字符串长度为0的情况 + { + return true; + } + + return false; +} + +Book *loadxlsFile(const GString &fileName) +{ + GFileInfo fi(fileName); + libxl::Book *oBook; + + if (fi.suffix() == "xls") + { + oBook = createXLSBook(true); + } + else + { + oBook = createXLSBook(false); + } + + oBook->setRgbMode(true); + oBook->load((const wchar_t *)fileName.constData()); + return oBook; +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Plugins/GLDWidgets.ini b/GCR/trunk/Glodon/src/GLD/Qt/Plugins/GLDWidgets.ini new file mode 100644 index 00000000..53a18444 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Plugins/GLDWidgets.ini @@ -0,0 +1,5 @@ +[VERSION_GlodonCommon] +MajorVersion = 1 +MinorVersion=1 +svnversion=0 +buildversion=386 \ No newline at end of file diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Plugins/GLDWidgets.pro b/GCR/trunk/Glodon/src/GLD/Qt/Plugins/GLDWidgets.pro new file mode 100644 index 00000000..d8b04c96 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Plugins/GLDWidgets.pro @@ -0,0 +1,50 @@ +CONFIG += designer plugin debug_and_release +TARGET = $$qtLibraryTarget(GLDWidgets) +TEMPLATE = lib + +greaterThan(QT_MAJOR_VERSION, 4): QT += core-private widgets-private + +CONFIG += debug_and_release + +CONFIG(debug, debug|release){ + contains(QMAKE_HOST.arch, x86_64) { + DESTDIR = ../../../../bin/Debug/X64 + } else { + DESTDIR = ../../../../bin/Debug/X86 + } + unix:TARGET=$$join(TARGET,,,_debug) + win32:TARGET=$$join(TARGET,,,d) +} + +CONFIG(release, debug|release){ + contains(QMAKE_HOST.arch, x86_64) { + DESTDIR = ../../../../bin/Release/X64 + } else { + DESTDIR = ../../../../bin/Release/X86 + } +} + +win32-msvc|win32-msvc.net|win32-msvc2002|win32-msvc2003|win32-msvc2005|win32-msvc2008|win32-msvc2010|win32-msvc2012|win32-msvc2013 { + LIBS += -lUser32 +} + +include(../../../../shared/GLD.pri) + +INCLUDEPATH += include + +RESOURCES = ../../Res/ico/GLDIcons.qrc \ + +target.path = $$[QT_INSTALL_PLUGINS]/designer +INSTALLS += target + +SOURCES += \ + src/GLDWidgets.cpp \ + src/GLDTableViewPlugin.cpp \ + src/GLDFilterTableViewPlugin.cpp + +HEADERS += \ + include/GLDWidgets.h \ + include/GLDTableViewPlugin.h \ + include/GLDFilterTableViewPlugin.h \ + ../../../../include/GLD/GLDTableView.h \ + ../../../../include/GLD/GLDFilterTableView.h diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Plugins/include/GLDFilterTableViewPlugin.h b/GCR/trunk/Glodon/src/GLD/Qt/Plugins/include/GLDFilterTableViewPlugin.h new file mode 100644 index 00000000..0b45fd55 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Plugins/include/GLDFilterTableViewPlugin.h @@ -0,0 +1,30 @@ +#ifndef GLODONFILTERTABLEVIEWPLUGIN_H +#define GLODONFILTERTABLEVIEWPLUGIN_H + +#include + +class GlodonFilterTableViewPlugin : public QObject, public QDesignerCustomWidgetInterface +{ + Q_OBJECT + Q_INTERFACES(QDesignerCustomWidgetInterface) + +public: + GlodonFilterTableViewPlugin(QObject *parent = 0); + + bool isContainer() const; + bool isInitialized() const; + QIcon icon() const; + QString domXml() const; + QString group() const; + QString includeFile() const; + QString name() const; + QString toolTip() const; + QString whatsThis() const; + QWidget *createWidget(QWidget *parent); + void initialize(QDesignerFormEditorInterface *core); + +private: + bool m_initialized; +}; + +#endif diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Plugins/include/GLDTableViewPlugin.h b/GCR/trunk/Glodon/src/GLD/Qt/Plugins/include/GLDTableViewPlugin.h new file mode 100644 index 00000000..6ee9a913 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Plugins/include/GLDTableViewPlugin.h @@ -0,0 +1,30 @@ +#ifndef GLDTABLEVIEWPLUGIN_H +#define GLDTABLEVIEWPLUGIN_H + +#include + +class GlodonTableViewPlugin : public QObject, public QDesignerCustomWidgetInterface +{ + Q_OBJECT + Q_INTERFACES(QDesignerCustomWidgetInterface) + +public: + GlodonTableViewPlugin(QObject *parent = 0); + + bool isContainer() const; + bool isInitialized() const; + QIcon icon() const; + QString domXml() const; + QString group() const; + QString includeFile() const; + QString name() const; + QString toolTip() const; + QString whatsThis() const; + QWidget *createWidget(QWidget *parent); + void initialize(QDesignerFormEditorInterface *core); + +private: + bool m_initialized; +}; + +#endif // GLDTABLEVIEWPLUGIN_H diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Plugins/include/GLDWidgets.h b/GCR/trunk/Glodon/src/GLD/Qt/Plugins/include/GLDWidgets.h new file mode 100644 index 00000000..342ff5cd --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Plugins/include/GLDWidgets.h @@ -0,0 +1,24 @@ +#ifndef GLODONWIDGETS_H +#define GLODONWIDGETS_H + +#include +#include + +class GlodonWidgets : public QObject, public QDesignerCustomWidgetCollectionInterface +{ + Q_OBJECT + Q_INTERFACES(QDesignerCustomWidgetCollectionInterface) +#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) + Q_PLUGIN_METADATA(IID "org.devmachines.Qt.QDesignerCustomWidgetCollectionInterface") +#endif + +public: + explicit GlodonWidgets(QObject *parent = 0); + + virtual QList customWidgets() const; + +private: + QList m_widgets; +}; + +#endif diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Plugins/src/GLDFilterTableViewPlugin.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Plugins/src/GLDFilterTableViewPlugin.cpp new file mode 100644 index 00000000..8cb677da --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Plugins/src/GLDFilterTableViewPlugin.cpp @@ -0,0 +1,71 @@ +#include "GLDFilterTableView.h" +#include "GLDFilterTableViewPlugin.h" + +#include + +GlodonFilterTableViewPlugin::GlodonFilterTableViewPlugin(QObject *parent) + : QObject(parent) +{ + m_initialized = false; +} + +void GlodonFilterTableViewPlugin::initialize(QDesignerFormEditorInterface * /* core */) +{ + if (m_initialized) + return; + + // Add extension registrations, etc. here + + m_initialized = true; +} + +bool GlodonFilterTableViewPlugin::isInitialized() const +{ + return m_initialized; +} + +QWidget *GlodonFilterTableViewPlugin::createWidget(QWidget *parent) +{ + return new GlodonFilterTableView(parent); +} + +QString GlodonFilterTableViewPlugin::name() const +{ + return QLatin1String("GLDFilterTableView"); +} + +QString GlodonFilterTableViewPlugin::group() const +{ + return QLatin1String("Glodon"); +} + +QIcon GlodonFilterTableViewPlugin::icon() const +{ + return QIcon(QLatin1String(":/ico/GlodonFilterTableView.ico")); +} + +QString GlodonFilterTableViewPlugin::toolTip() const +{ + return QLatin1String("GLDFilterTableView"); +} + +QString GlodonFilterTableViewPlugin::whatsThis() const +{ + return QLatin1String("GLDFilterTableView"); +} + +bool GlodonFilterTableViewPlugin::isContainer() const +{ + return false; +} + +QString GlodonFilterTableViewPlugin::domXml() const +{ + return QLatin1String("\n\n"); +} + +QString GlodonFilterTableViewPlugin::includeFile() const +{ + return QLatin1String("GLDFilterTableView.h"); +} + diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Plugins/src/GLDTableViewPlugin.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Plugins/src/GLDTableViewPlugin.cpp new file mode 100644 index 00000000..5524b898 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Plugins/src/GLDTableViewPlugin.cpp @@ -0,0 +1,71 @@ +#include "GLDTableView.h" +#include "GLDTableViewPlugin.h" + +#include + +GlodonTableViewPlugin::GlodonTableViewPlugin(QObject *parent) + : QObject(parent) +{ + m_initialized = false; +} + +void GlodonTableViewPlugin::initialize(QDesignerFormEditorInterface * /* core */) +{ + if (m_initialized) + return; + + // Add extension registrations, etc. here + + m_initialized = true; +} + +bool GlodonTableViewPlugin::isInitialized() const +{ + return m_initialized; +} + +QWidget *GlodonTableViewPlugin::createWidget(QWidget *parent) +{ + return new GlodonTableView(parent); +} + +QString GlodonTableViewPlugin::name() const +{ + return QLatin1String("GLDTableView"); +} + +QString GlodonTableViewPlugin::group() const +{ + return QLatin1String("Glodon"); +} + +QIcon GlodonTableViewPlugin::icon() const +{ + return QIcon(QLatin1String(":/ico/GlodonTableView.ico")); +} + +QString GlodonTableViewPlugin::toolTip() const +{ + return QLatin1String("GLDTableView"); +} + +QString GlodonTableViewPlugin::whatsThis() const +{ + return QLatin1String("GLDTableView"); +} + +bool GlodonTableViewPlugin::isContainer() const +{ + return false; +} + +QString GlodonTableViewPlugin::domXml() const +{ + return QLatin1String("\n\n"); +} + +QString GlodonTableViewPlugin::includeFile() const +{ + return QLatin1String("GLDTableView.h"); +} + diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Plugins/src/GLDWidgets.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Plugins/src/GLDWidgets.cpp new file mode 100644 index 00000000..b942fe8b --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Plugins/src/GLDWidgets.cpp @@ -0,0 +1,20 @@ +#include "GLDTableViewPlugin.h" +#include "GLDFilterTableViewPlugin.h" +#include "GLDWidgets.h" + +GlodonWidgets::GlodonWidgets(QObject *parent) + : QObject(parent) +{ + m_widgets.append(new GlodonTableViewPlugin(this)); + m_widgets.append(new GlodonFilterTableViewPlugin(this)); + +} + +QList GlodonWidgets::customWidgets() const +{ + return m_widgets; +} + +#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0)) +Q_EXPORT_PLUGIN2(glodonwidgets, GlodonWidgets) +#endif diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLD360MainWindow.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLD360MainWindow.cpp new file mode 100644 index 00000000..cf45551e --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLD360MainWindow.cpp @@ -0,0 +1,485 @@ +#include "GLD360MainWindow.h" + +#include +#include +#include +#include +#include +#include + +const int c_titleHeight = 30; +const int c_toolBarHeight = 100; + +/* GLD360PushButton */ +GLD360PushButton::GLD360PushButton(QWidget *parent) : QPushButton(parent), + m_status(NORMAL), m_btnWidth(0), m_btnHeight(0), m_mousePress(false) +{ + +} + +GLD360PushButton::~GLD360PushButton() +{ + +} + +void GLD360PushButton::loadPixmap(const QString &picName) +{ + m_pixmap.load(picName); + m_btnWidth = m_pixmap.width() / 4; + m_btnHeight = m_pixmap.height(); + setFixedSize(m_btnWidth, m_btnHeight); +} + +void GLD360PushButton::enterEvent(QEvent *) +{ + m_status = ENTER; + update(); +} + +void GLD360PushButton::leaveEvent(QEvent *) +{ + m_status = NORMAL; + update(); +} + +void GLD360PushButton::mousePressEvent(QMouseEvent *event) +{ + // 若点击鼠标左键 + if (event->button() == Qt::LeftButton) + { + m_mousePress = true; + m_status = PRESS; + update(); + } +} + +void GLD360PushButton::mouseReleaseEvent(QMouseEvent *) +{ + // 若点击鼠标左键 + if (m_mousePress) + { + m_mousePress = false; + m_status = ENTER; + update(); + emit clicked(); + } +} + +void GLD360PushButton::paintEvent(QPaintEvent *) +{ + QPainter painter(this); + painter.drawPixmap(rect(), m_pixmap.copy(m_btnWidth * m_status, 0, m_btnWidth, m_btnHeight)); +} + +/* GLD360ToolButton */ +GLD360ToolButton::GLD360ToolButton(const GString &text, const GString &picName, QWidget *parent) : QToolButton(parent), + m_mouseOver(false), m_mousePress(false) +{ + setCheckable(true); + setText(text); + //设置文本颜色 + QPalette text_palette = palette(); + text_palette.setColor(QPalette::ButtonText, QColor(230, 230, 230)); + setPalette(text_palette); + + //设置文本粗体 + QFont &text_font = const_cast(font()); + text_font.setWeight(QFont::Bold); + + setToolButtonStyle(Qt::ToolButtonTextUnderIcon); + + //设置图标 + QPixmap pixmap(picName); + setIcon(pixmap); + setIconSize(pixmap.size()); + + //设置大小 + setFixedSize(pixmap.width() + 25, pixmap.height() + 27); + setAutoRaise(true); + + setStyleSheet("background:transparent;"); +} + +GLD360ToolButton::~GLD360ToolButton() +{ + +} + +void GLD360ToolButton::setMousePress(bool mousePress) +{ + m_mousePress = mousePress; + update(); +} + +void GLD360ToolButton::enterEvent(QEvent *) +{ + m_mouseOver = true; +} + +void GLD360ToolButton::leaveEvent(QEvent *) +{ + m_mouseOver = false; +} + +void GLD360ToolButton::mousePressEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) + { + emit clicked(); + } +} + +void GLD360ToolButton::paintEvent(QPaintEvent *event) +{ + if (m_mouseOver || isChecked()) + { + //绘制鼠标移到按钮上的按钮效果 + painterInfo(0, 100, 150); + } + + QToolButton::paintEvent(event); +} + +void GLD360ToolButton::painterInfo(int topColor, int middleColor, int bottomColor) +{ + QPainter painter(this); + QPen pen(Qt::NoBrush, 1); + painter.setPen(pen); + QLinearGradient linear(rect().topLeft(), rect().bottomLeft()); + linear.setColorAt(0, QColor(230, 230, 230, topColor)); + linear.setColorAt(0.5, QColor(230, 230, 230, middleColor)); + linear.setColorAt(1, QColor(230, 230, 230, bottomColor)); + painter.setBrush(linear); + painter.drawRect(rect()); +} + +/* GLD360WindowTile */ +GLD360WindowTile::GLD360WindowTile(QWidget *parent): QWidget(parent), m_isMove(false) +{ + m_versionTitle = new QLabel(); + m_skinButton = new GLD360PushButton(); + m_mainMenuButton = new GLD360PushButton(); + m_minButton = new GLD360PushButton(); + m_maxButton = new GLD360PushButton(); + m_closeButton = new GLD360PushButton(); + m_versionTitle->setAlignment(Qt::AlignVCenter); + m_versionTitle->setStyleSheet("color:white;"); + m_versionTitle->setText(parent->windowTitle()); + //设置图片 + m_skinButton->loadPixmap(":/icons/360skin/sysbutton/skin_button"); + m_mainMenuButton->loadPixmap(":/icons/360skin/sysbutton/main_menu.png"); + m_minButton->loadPixmap(":/icons/360skin/sysbutton/min_button.png"); + m_maxButton->loadPixmap(":/icons/360skin/sysbutton/max_button.png"); + m_closeButton->loadPixmap(":/icons/360skin/sysbutton/close_button"); + + connect(m_skinButton, SIGNAL(clicked()), this, SIGNAL(showSkin())); + connect(m_mainMenuButton, SIGNAL(clicked()), this, SIGNAL(showMainMenu())); + connect(m_minButton, SIGNAL(clicked()), this, SIGNAL(showMin())); + connect(m_maxButton, SIGNAL(clicked()), this, SIGNAL(showMax())); + connect(m_closeButton, SIGNAL(clicked()), this, SIGNAL(closeWidget())); + + QHBoxLayout *title_layout = new QHBoxLayout(); + title_layout->addWidget(m_versionTitle, 0, Qt::AlignVCenter); + title_layout->addStretch(); + title_layout->addWidget(m_skinButton, 0, Qt::AlignTop); + title_layout->addWidget(m_mainMenuButton, 0, Qt::AlignTop); + title_layout->addWidget(m_minButton, 0, Qt::AlignTop); + title_layout->addWidget(m_maxButton, 0, Qt::AlignTop); + title_layout->addWidget(m_closeButton, 0, Qt::AlignTop); + title_layout->setSpacing(0); + title_layout->setContentsMargins(0, 0, 5, 0); + m_versionTitle->setContentsMargins(15, 0, 0, 0); + m_skinButton->setContentsMargins(0, 0, 10, 0); + + setLayout(title_layout); + setFixedHeight(c_titleHeight); +} + +GLD360WindowTile::~GLD360WindowTile() +{ + +} + +void GLD360WindowTile::mousePressEvent(QMouseEvent *e) +{ + m_pressPoint = e->pos(); + m_isMove = true; +} + +void GLD360WindowTile::mouseMoveEvent(QMouseEvent *e) +{ + if ((e->buttons() == Qt::LeftButton) && m_isMove) + { + static QWidget *parent_widget = this->parentWidget(); + QPoint parent_point = parent_widget->pos(); + parent_point.setX(parent_point.x() + e->x() - m_pressPoint.x()); + parent_point.setY(parent_point.y() + e->y() - m_pressPoint.y()); + parent_widget->move(parent_point); + } +} + +void GLD360WindowTile::mouseReleaseEvent(QMouseEvent *) +{ + if (m_isMove) + { + m_isMove = false; + } +} + +void GLD360WindowTile::mouseDoubleClickEvent(QMouseEvent *) +{ + emit showMax(); +} + +/* GLD360MainToolBar */ +GLD360MainToolBar::GLD360MainToolBar(QWidget *parent): QWidget(parent), m_isMove(false) +{ + m_buttonLayout = new QHBoxLayout(); + m_signalMapper = new QSignalMapper(this); + connect(m_signalMapper, SIGNAL(mapped(QString)), this, SLOT(turnPage(const QString &))); + + m_logoLabel = new QLabel(); + m_logoLabel->setCursor(Qt::PointingHandCursor); + + QHBoxLayout *mainLayout = new QHBoxLayout(); + mainLayout->addLayout(m_buttonLayout); + mainLayout->addStretch(); + mainLayout->addWidget(m_logoLabel); + mainLayout->setSpacing(8); + mainLayout->setContentsMargins(15, 0, 0, 0); + + setLayout(mainLayout); + setFixedHeight(c_toolBarHeight); +} + +GLD360MainToolBar::~GLD360MainToolBar() +{ + m_buttonList.clear(); +} + +void GLD360MainToolBar::add360Action(const GString &text, const GString &picName) +{ + GLD360ToolButton *tool_button = new GLD360ToolButton(text, picName); + m_buttonList.push_back(tool_button); + connect(tool_button, SIGNAL(clicked()), m_signalMapper, SLOT(map())); + m_signalMapper->setMapping(tool_button, QString::number(m_buttonList.count() - 1, 10)); + m_buttonLayout->addWidget(tool_button, 0, Qt::AlignBottom); +} + +void GLD360MainToolBar::setLogo(const GString &picName) +{ + QPixmap pixmap(picName); + m_logoLabel->setPixmap(pixmap); + m_logoLabel->setFixedSize(pixmap.size()); +} + +void GLD360MainToolBar::setCurrentPage(const QString ¤tPage) +{ + turnPage(currentPage); +} + +void GLD360MainToolBar::turnPage(const QString ¤tPage) +{ + bool ok = false; + int current_index = currentPage.toInt(&ok, 10); + + for (int i = 0; i < m_buttonList.count(); i++) + { + GLD360ToolButton *toolButton = m_buttonList.at(i); + + if (current_index == i) + { + toolButton->setMousePress(true); + toolButton->setChecked(true); + } + else + { + toolButton->setMousePress(false); + toolButton->setChecked(false); + } + } +} + +void GLD360MainToolBar::mousePressEvent(QMouseEvent *e) +{ + m_pressPoint = e->pos(); + m_isMove = true; +} + +void GLD360MainToolBar::mouseMoveEvent(QMouseEvent *e) +{ + if ((e->buttons() == Qt::LeftButton) && m_isMove) + { + static QWidget *parent_widget = this->parentWidget(); + QPoint parent_point = parent_widget->pos(); + parent_point.setX(parent_point.x() + e->x() - m_pressPoint.x()); + parent_point.setY(parent_point.y() + e->y() - m_pressPoint.y()); + parent_widget->move(parent_point); + } +} + +void GLD360MainToolBar::mouseReleaseEvent(QMouseEvent *) +{ + if (m_isMove) + { + m_isMove = false; + } +} + +void GLD360MainToolBar::mouseDoubleClickEvent(QMouseEvent *) +{ + emit showMax(); +} + +/* GLD360MainWindow */ +GLD360MainWindow::GLD360MainWindow(QWidget *parent): QWidget(parent), m_mainMenu(NULL), m_isCloseWhenMinimized(true), + m_allowMax(false) +{ + +} + +GLD360MainWindow::~GLD360MainWindow() +{ + +} + +void GLD360MainWindow::initialize() +{ + // do nothing +} + +void GLD360MainWindow::init() +{ + setMinimumSize(900, 600); + setWindowFlags(Qt::FramelessWindowHint); + + m_skinName = QString(":/icons/360skin/skin/17_big.jpg"); + + m_titleWidget = new GLD360WindowTile(this); + m_mainToolBar = new GLD360MainToolBar(this); + + QWidget *wgt = new QWidget(); + m_mainLayOut = new QHBoxLayout(); + m_mainLayOut->setSpacing(0); + m_mainLayOut->setContentsMargins(0, 0, 0, 0); + wgt->setLayout(m_mainLayOut); + + QVBoxLayout *main_layout = new QVBoxLayout(); + main_layout->addWidget(m_titleWidget); + main_layout->addWidget(m_mainToolBar); + main_layout->addWidget(wgt); + main_layout->setSpacing(0); + main_layout->setContentsMargins(0, 0, 0, 0); + + setLayout(main_layout); + + initialize(); + + connect(m_titleWidget, SIGNAL(showSkin()), this, SIGNAL(showSkin())); + connect(m_titleWidget, SIGNAL(showMainMenu()), this, SLOT(showMainMenu())); + connect(m_titleWidget, SIGNAL(showMax()), this, SLOT(showMax())); + connect(m_titleWidget, SIGNAL(showMin()), this, SLOT(showMinimized())); + connect(m_titleWidget, SIGNAL(closeWidget()), this, SLOT(close())); +} + +void GLD360MainWindow::showWidget() +{ + m_contentWidgetList.clear(); +} + +void GLD360MainWindow::paintEvent(QPaintEvent *) +{ + QPainter painter(this); + painter.drawPixmap(rect(), QPixmap(m_skinName)); + + QPainter painter2(this); + painter2.setPen(Qt::gray); + static const QPointF points[4] = {QPointF(0, 100), QPointF(0, this->height() - 1), QPointF(this->width() - 1, this->height() - 1), QPointF(this->width() - 1, 100)}; + painter2.drawPolyline(points, 4); +} + +void GLD360MainWindow::showMax() +{ + // todo 要恢复原始大小 + if (m_allowMax) + { + showMaximized(); + } +} + +void GLD360MainWindow::showMainMenu() +{ + if (m_mainMenu == NULL) + { + return; + } + + // 设置主菜单出现的位置 + QPoint p = rect().topRight(); + p.setX(p.x() - 150); + p.setY(p.y() + 22); + m_mainMenu->exec(this->mapToGlobal(p)); +} + +void GLD360MainWindow::changeSkin(const QString &skinName) +{ + m_skinName = skinName; + update(); +} + +GLD360WindowTile *GLD360MainWindow::titleWidget() const +{ + return m_titleWidget; +} + +void GLD360MainWindow::setTitleWidget(GLD360WindowTile *titleWidget) +{ + m_titleWidget = titleWidget; +} + +GLD360MainToolBar *GLD360MainWindow::mainToolBar() const +{ + return m_mainToolBar; +} + +void GLD360MainWindow::setMainToolBar(GLD360MainToolBar *mainToolBar) +{ + m_mainToolBar = mainToolBar; +} + +bool GLD360MainWindow::allowMax() const +{ + return m_allowMax; +} + +void GLD360MainWindow::setAllowMax(bool allowMax) +{ + m_allowMax = allowMax; +} + +bool GLD360MainWindow::isCloseWhenMinimized() const +{ + return m_isCloseWhenMinimized; +} + +void GLD360MainWindow::setIsCloseWhenMinimized(bool isCloseWhenMinimized) +{ + m_isCloseWhenMinimized = isCloseWhenMinimized; + + if (m_isCloseWhenMinimized) + { + disconnect(m_titleWidget, SIGNAL(closeWidget()), this, SLOT(hide())); + connect(m_titleWidget, SIGNAL(closeWidget()), this, SLOT(close())); + } + else + { + disconnect(m_titleWidget, SIGNAL(closeWidget()), this, SLOT(close())); + connect(m_titleWidget, SIGNAL(closeWidget()), this, SLOT(hide())); + } +} + +void GLD360MainWindow::setSkinName(const QString &skinName) +{ + changeSkin(skinName); +} + diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDAbstractBtnEdit.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDAbstractBtnEdit.cpp new file mode 100644 index 00000000..46929335 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDAbstractBtnEdit.cpp @@ -0,0 +1,261 @@ +#include "GLDAbstractBtnEdit.h" +#include "GLDGlobal.h" +#include +#include +#include +#include +#include +#include + +const int c_MinButtonEditBtnWidth = 18; + +GLDAbstractBtnEdit::GLDAbstractBtnEdit(QWidget *parent) : + QWidget(parent), m_btnIconSize(m_maxBtnCount,QSize(0,0)), + m_btnUsingIcon(m_maxBtnCount, 0), m_btns(NULL), m_associateData(NULL) +{ + init(); +} + +GLDAbstractBtnEdit::~GLDAbstractBtnEdit() +{ + if (!m_btns->parent()) + { + freeAndNil(m_btns); + } +} + +bool GLDAbstractBtnEdit::setButtonsCount(int nBtnCount) +{ + if (nBtnCount <= m_maxBtnCount && m_btns) + { + for (int i = 0; iaddButton(new QPushButton(QString(" ..."), this), i); + } + QObject::connect(m_btns, SIGNAL(buttonClicked(int)), this, SLOT(onEllipsisButtonClicked(int))); + return true; + } + else + return false; +} + +int GLDAbstractBtnEdit::buttonsCount() const +{ + int ncount = 0; + if (m_btns) + ncount = m_btns->buttons().count(); + return ncount; +} + +int GLDAbstractBtnEdit::maximumButtonsCount() const +{ + return m_maxBtnCount; +} + +bool GLDAbstractBtnEdit::eventFilter(QObject *obj, QEvent *event) +{ + QWidget *editor = dynamic_cast(obj); + QAbstractButton *btn = dynamic_cast(obj); + if (!editor) + return false; + if (event->type() == QEvent::KeyPress) + { + QKeyEvent* keyEvent = static_cast(event); + if (keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return) + { + if (keyEvent->modifiers() == Qt::CTRL) + { + ellipsisButtonClicked(btn); + return true; + } + else if (keyEvent->modifiers() == Qt::ALT) + { + cursorPosInsertANewLine(); + return true; + } + else + { + QCoreApplication::sendEvent(this, event); + return true; + } + } + else if (keyEvent->key() == Qt::Key_Up || keyEvent->key() == Qt::Key_Down) + { + if (keyEvent->modifiers() == Qt::ALT) + { + ellipsisButtonClicked(btn); + return true; + } + else + { + QCoreApplication::sendEvent(this, event); + return true; + } + } + else if (keyEvent->key() == Qt::Key_Tab) + { + QCoreApplication::sendEvent(this, event); + return true; + } + } + return QWidget::eventFilter(obj, event); +} + +bool GLDAbstractBtnEdit::setBtnText(QString &text, int btnIndex) +{ + QAbstractButton *btn = m_btns->button(btnIndex); + if (btn) + { + btn->setText(text); + return true; + } + return false; +} + +bool GLDAbstractBtnEdit::setButtonIcon(QIcon &icon, int btnIndex) +{ + if (btnIndex >= 0 && btnIndex < buttonsCount()) + { + m_btns->button(btnIndex)->setText(""); + m_btns->button(btnIndex)->setIcon(icon); + m_btnIconSize[btnIndex] = m_btns->button(btnIndex)->iconSize(); + m_btnUsingIcon[btnIndex] = 1; + return true; + } + else + return false; +} + +void GLDAbstractBtnEdit::onEllipsisButtonClicked(int clickedBtnIndex) +{ + emit ellipsisButtonClicked(clickedBtnIndex); + QAbstractButton *btn = m_btns->button(clickedBtnIndex); + if (btn) + emit ellipsisButtonClicked(btn); +} + +void GLDAbstractBtnEdit::onEllipsisButtonClicked(QAbstractButton *clickedBtn) +{ + if (m_btns && clickedBtn && buttonsCount() > 0) + { + int nbtnIndex = 0; + QList btns = m_btns->buttons(); + for (QList::Iterator it = btns.begin(); it != btns.end(); ++it, ++nbtnIndex) + { + if (clickedBtn == *it) + { + emit ellipsisButtonClicked(nbtnIndex); + emit ellipsisButtonClicked(clickedBtn); + } + } + } +} + +void GLDAbstractBtnEdit::init() +{ + m_btns = new QButtonGroup(this); +} + +GLDBtnsLineEdit::GLDBtnsLineEdit(int btnCount, QWidget *parent):GLDAbstractBtnEdit(parent), + m_edit(NULL) +{ + init(btnCount); + m_edit->installEventFilter(this); + + if (btnCount > 0) + { + int ntargetBtnWidth = qMax(c_MinButtonEditBtnWidth, m_btns->button(0)->fontMetrics().width(" ...")); + int nbtnWidth = btnCount * ntargetBtnWidth + 2; + int nlineEditWidth = width() - nbtnWidth; + + m_edit->setGeometry(0, 0, nlineEditWidth, height()); + } + else + { + m_edit->setGeometry(0, 0, width() - 1, height()); + } + this->setFocusProxy(m_edit); +} + +GLDBtnsLineEdit::~GLDBtnsLineEdit() +{ + +} + +QString GLDBtnsLineEdit::text() const +{ + if (m_edit) + return m_edit->text(); + else + return QString(""); +} + +void GLDBtnsLineEdit::setText(QString text) +{ + m_edit->setText(text); + m_edit->selectAll(); +} + +void GLDBtnsLineEdit::paintEvent(QPaintEvent *) +{ + int nk(0); + int nl(0); + for (nk = 0, nl = 1; nk < 100; ++nk) + { + nl = nk + 2; + } + int ntargetBtnWidth = 0; + int nbtnNums = buttonsCount(); + if (nbtnNums > 0) + ntargetBtnWidth = qMax(c_MinButtonEditBtnWidth, m_btns->button(0)->fontMetrics().width(" ...")); +// m_edit->setGeometry(0 ,0, width() - btnNums * targetBtnWidth + 2 + btnNums - 1, height()); + int nbtnsWidth = 0; + for (int i = nbtnNums - 1; i >= 0; --i) + { + QAbstractButton *m_button = m_btns->button(i); + bool busingIcon = (0 != m_btnUsingIcon[i]); + int nbtnOriginalHeight = -1; + if (busingIcon) + { + m_button->resize(m_btnIconSize[i]); + nbtnsWidth += m_btnIconSize[i].width(); + nbtnOriginalHeight += (height() - m_btnIconSize[i].height()) / 2.0; + m_button->setStyleSheet("border-radius:16px;"); + } + else + { + m_button->resize(ntargetBtnWidth + 1, height() + 2); + nbtnsWidth += m_button->width(); + nbtnOriginalHeight += (height() - m_button->height()) / 2.0; + } + m_button->move(width() - nbtnsWidth + 1, nbtnOriginalHeight); + } + m_edit->setGeometry(0,0,width() - nbtnsWidth + 2,height()); +} + +void GLDBtnsLineEdit::selectAll() +{ + if (m_edit) + m_edit->selectAll(); +} + +void GLDBtnsLineEdit::cursorPosInsertANewLine() +{ + return cursorToEnd(); +} + +void GLDBtnsLineEdit::cursorToEnd() +{ + if (m_edit && m_edit->isEnabled() && m_edit->hasFocus()) + { + bool bselectText = false; + m_edit->end(bselectText); + } +} + +void GLDBtnsLineEdit::init(int btnCount) +{ + freeAndNil(m_edit); + m_edit = new QLineEdit(this); + setButtonsCount(btnCount); +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDAbstractItemView.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDAbstractItemView.cpp new file mode 100644 index 00000000..8a7b0c51 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDAbstractItemView.cpp @@ -0,0 +1,5503 @@ +#include "GLDAbstractItemView.h" +#include "GLDAbstractItemView_p.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef QT_NO_ACCESSIBILITY +#include +#endif +//#include +#include +#include +#include + +#include "GLDString.h" +#include "GLDGlobal.h" +#include "GLDAbstractItemModel.h" +#include "GLDEvent.h" +#include "GLDStrUtils.h" +#include "GLDWindowComboBox.h" +#include "GLDWindowComboBoxEx.h" +#include "GLDEllipsis.h" +#include "GLDHeaderView.h" + +GlodonAbstractItemViewPrivate::GlodonAbstractItemViewPrivate() + : m_model(QAbstractItemModelPrivate::staticEmptyModel()), + m_dataModel(0), + m_itemDelegate(0), + m_selectionModel(0), + m_ctrlDragSelectionFlag(QItemSelectionModel::NoUpdate), + m_noSelectionOnMousePress(false), + m_selectionMode(GlodonAbstractItemView::ExtendedSelection), + m_selectionBehavior(GlodonAbstractItemView::SelectItems), + m_pCurCommittingEditor(0), + m_pressedModifiers(Qt::NoModifier), + m_pressedPosition(QPoint(-1, -1)), + m_pressedAlreadySelected(false), + m_viewportEnteredNeeded(false), + m_state(GlodonAbstractItemView::NoState), + m_stateBeforeAnimation(GlodonAbstractItemView::NoState), + m_editTriggers(GlodonAbstractItemView::DoubleClicked | GlodonAbstractItemView::EditKeyPressed), + m_lastTrigger(GlodonAbstractItemView::NoEditTriggers), + m_bTabKeyNavigation(false), +#ifndef QT_NO_DRAGANDDROP + m_bShowDropIndicator(true), + m_bDragEnabled(false), + m_dragDropMode(GlodonAbstractItemView::NoDragDrop), + m_bDragDropOverwrite(false), + m_dropIndicatorPosition(GlodonAbstractItemView::OnItem), + m_defaultDropAction(Qt::IgnoreAction), +#endif +#ifdef QT_SOFTKEYS_ENABLED + doneSoftKey(0), +#endif + m_bAutoScroll(true), + m_nAutoScrollMargin(16), + m_autoScrollCount(0), + m_shouldScrollToCurrentOnShow(false), + m_shouldClearStatusTip(false), + m_bAlternatingColors(true), + m_textElideMode(Qt::ElideRight), + m_nDelayedHintTime(1000), + m_verticalScrollMode(GlodonAbstractItemView::ScrollPerItem), + m_horizontalScrollMode(GlodonAbstractItemView::ScrollPerItem), + m_bCurrentIndexSet(false), + m_bWrapItemText(false), + m_delayedPendingLayout(true), + m_moveCursorUpdatedView(false), + m_bGridTextIncludeLeading(true), + m_bScrollBarTracking(true), + m_bAllowSelectAll(true), + m_isSearchModel(false), + m_bMouseMoveRefresh(false), + m_oGridColor(QColor()), + m_pToolTipFrame(NULL), + m_bShowIndexContent(false), + m_ignoreActiveWindowFocusReason(false), + m_alwaysShowEditorPro(false), + m_currentEditor(NULL), + m_bIsInMultiSelect(false) +{ + m_keyboardInputTime.invalidate(); +} + +GlodonAbstractItemViewPrivate::~GlodonAbstractItemViewPrivate() +{ + freeAndNil(m_pToolTipFrame); +} + +void GlodonAbstractItemViewPrivate::init() +{ + Q_Q(GlodonAbstractItemView); + q->setItemDelegate(new GlodonDefaultItemDelegate(q)); + + vbar->setRange(0, 0); + hbar->setRange(0, 0); + + QObject::connect(vbar, SIGNAL(actionTriggered(int)), + q, SLOT(verticalScrollbarAction(int))); + QObject::connect(hbar, SIGNAL(actionTriggered(int)), + q, SLOT(horizontalScrollbarAction(int))); + QObject::connect(vbar, SIGNAL(valueChanged(int)), + q, SLOT(verticalScrollbarValueChanged(int))); + QObject::connect(hbar, SIGNAL(valueChanged(int)), + q, SLOT(horizontalScrollbarValueChanged(int))); + + viewport->setBackgroundRole(QPalette::Base); + + q->setAttribute(Qt::WA_InputMethodEnabled); + +#ifdef QT_SOFTKEYS_ENABLED + doneSoftKey = QSoftKeyManager::createKeyedAction(QSoftKeyManager::DoneSoftKey, Qt::Key_Back, q); +#endif +} + +void GlodonAbstractItemViewPrivate::setHoverIndex(const QPersistentModelIndex &index) +{ + Q_Q(GlodonAbstractItemView); + + if (m_hover == index) + { + return; + } + + if (m_bMouseMoveRefresh) + { + if (m_selectionBehavior != GlodonAbstractItemView::SelectRows) + { + q->update(m_hover); //update the old one + q->update(index); //update the new one + } + else + { + QRect oldHoverRect = q->visualRect(m_hover); + QRect newHoverRect = q->visualRect(index); + viewport->update(QRect(0, newHoverRect.y(), viewport->width(), newHoverRect.height())); + viewport->update(QRect(0, oldHoverRect.y(), viewport->width(), oldHoverRect.height())); + } + } + + m_hover = index; +} + +void GlodonAbstractItemViewPrivate::checkMouseMove(const QPersistentModelIndex &index) +{ + //we take a persistent model index because the model might change by emitting signals + Q_Q(GlodonAbstractItemView); + setHoverIndex(index); + + if (m_viewportEnteredNeeded || m_enteredIndex != index) + { + m_viewportEnteredNeeded = false; + + if (index.isValid()) + { + emit q->entered(index); +#ifndef QT_NO_STATUSTIP + QString statustip = m_model->data(index, Qt::StatusTipRole).toString(); + + if (parent && (m_shouldClearStatusTip || !statustip.isEmpty())) + { + QStatusTipEvent tip(statustip); + QApplication::sendEvent(parent, &tip); + m_shouldClearStatusTip = !statustip.isEmpty(); + } + +#endif + } + else + { +#ifndef QT_NO_STATUSTIP + + if (parent && m_shouldClearStatusTip) + { + QString emptyString; + QStatusTipEvent tip(emptyString); + QApplication::sendEvent(parent, &tip); + } + +#endif + emit q->viewportEntered(); + } + + m_enteredIndex = index; + } +} + +QItemSelectionModel::SelectionFlags GlodonAbstractItemViewPrivate::selectionBehaviorFlags() const +{ + switch (m_selectionBehavior) + { + case GlodonAbstractItemView::SelectRows: + return QItemSelectionModel::Rows; + + case GlodonAbstractItemView::SelectColumns: + return QItemSelectionModel::Columns; + + case GlodonAbstractItemView::SelectItems: + default: + return QItemSelectionModel::NoUpdate; + } +} + +GlodonAbstractItemView::GlodonAbstractItemView(QWidget *parent) + : QAbstractScrollArea(*(new GlodonAbstractItemViewPrivate), parent) +{ + setMouseTracking(true); + d_func()->init(); +} + +GlodonAbstractItemView::GlodonAbstractItemView(GlodonAbstractItemViewPrivate &dd, QWidget *parent) + : QAbstractScrollArea(dd, parent) +{ + setMouseTracking(true); + d_func()->init(); +} + +GlodonAbstractItemView::~GlodonAbstractItemView() +{ + Q_D(GlodonAbstractItemView); + freeAndNil(d->m_pToolTipFrame); + // stop these timers here before ~QObject + d->m_delayedReset.stop(); + d->m_updateTimer.stop(); + d->m_delayedAutoScroll.stop(); + d->m_autoScrollTimer.stop(); + d->m_delayedLayout.stop(); + d->m_fetchMoreTimer.stop(); + d->m_delayedShowToolTip.stop(); +} + +QWidget *GlodonAbstractItemView::initCustomComment(const QModelIndex &, GString &) +{ + return NULL; +} + +void GlodonAbstractItemView::setModel(QAbstractItemModel *model) +{ + Q_D(GlodonAbstractItemView); + + if (model == d->m_model) + { + return; + } + + if (d->m_model && d->m_model != QAbstractItemModelPrivate::staticEmptyModel()) + { + disconnect(d->m_model, SIGNAL(destroyed()), + this, SLOT(_q_modelDestroyed())); + disconnect(d->m_model, SIGNAL(dataChanged(QModelIndex, QModelIndex, QVector)), + this, SLOT(dataChanged(QModelIndex, QModelIndex, QVector))); + disconnect(d->m_model, SIGNAL(headerDataChanged(Qt::Orientation, int, int)), + this, SLOT(_q_headerDataChanged())); + disconnect(d->m_model, SIGNAL(rowsInserted(QModelIndex, int, int)), + this, SLOT(rowsInserted(QModelIndex, int, int))); + disconnect(d->m_model, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)), + this, SLOT(rowsAboutToBeRemoved(QModelIndex, int, int))); + disconnect(d->m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), + this, SLOT(_q_rowsRemoved(QModelIndex, int, int))); + disconnect(d->m_model, SIGNAL(rowsInserted(QModelIndex, int, int)), + this, SLOT(_q_rowsInserted(QModelIndex, int, int))); + disconnect(d->m_model, SIGNAL(columnsAboutToBeRemoved(QModelIndex, int, int)), + this, SLOT(_q_columnsAboutToBeRemoved(QModelIndex, int, int))); + disconnect(d->m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)), + this, SLOT(_q_columnsRemoved(QModelIndex, int, int))); + disconnect(d->m_model, SIGNAL(columnsInserted(QModelIndex, int, int)), + this, SLOT(_q_columnsInserted(QModelIndex, int, int))); + + disconnect(d->m_model, SIGNAL(modelReset()), this, SLOT(reset())); + disconnect(d->m_model, SIGNAL(layoutChanged()), this, SLOT(_q_layoutChanged())); + } + + d->m_model = (model ? model : QAbstractItemModelPrivate::staticEmptyModel()); + + //These asserts do basic sanity checking of the model + Q_ASSERT_X(d->m_model->index(0, 0) == d->m_model->index(0, 0), + "GlodonAbstractItemView::setModel", + "A model should return the exact same index " + "(including its internal id/pointer) when asked for it twice in a row."); + Q_ASSERT_X(!d->m_model->index(0, 0).parent().isValid(), + "GlodonAbstractItemView::setModel", + "The parent of a top level index should be invalid"); + + if (d->m_model != QAbstractItemModelPrivate::staticEmptyModel()) + { + connect(d->m_model, SIGNAL(destroyed()), + this, SLOT(_q_modelDestroyed())); + connect(d->m_model, SIGNAL(dataChanged(QModelIndex, QModelIndex, QVector)), + this, SLOT(dataChanged(QModelIndex, QModelIndex, QVector))); + connect(d->m_model, SIGNAL(headerDataChanged(Qt::Orientation, int, int)), + this, SLOT(_q_headerDataChanged())); + connect(d->m_model, SIGNAL(rowsInserted(QModelIndex, int, int)), + this, SLOT(rowsInserted(QModelIndex, int, int))); + connect(d->m_model, SIGNAL(rowsInserted(QModelIndex, int, int)), + this, SLOT(_q_rowsInserted(QModelIndex, int, int))); + connect(d->m_model, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)), + this, SLOT(rowsAboutToBeRemoved(QModelIndex, int, int))); + connect(d->m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), + this, SLOT(_q_rowsRemoved(QModelIndex, int, int))); + connect(d->m_model, SIGNAL(columnsAboutToBeRemoved(QModelIndex, int, int)), + this, SLOT(_q_columnsAboutToBeRemoved(QModelIndex, int, int))); + connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)), + this, SLOT(_q_columnsRemoved(QModelIndex, int, int))); + connect(d->m_model, SIGNAL(columnsInserted(QModelIndex, int, int)), + this, SLOT(_q_columnsInserted(QModelIndex, int, int))); + + connect(d->m_model, SIGNAL(modelReset()), this, SLOT(reset())); + connect(d->m_model, SIGNAL(layoutChanged()), this, SLOT(_q_layoutChanged())); + } + + QItemSelectionModel *selection_model = new QItemSelectionModel(d->m_model, this); + connect(d->m_model, SIGNAL(destroyed()), selection_model, SLOT(deleteLater())); + setSelectionModel(selection_model); + + reset(); // kill editors, set new root and do layout +} + +QAbstractItemModel *GlodonAbstractItemView::model() const +{ + Q_D(const GlodonAbstractItemView); + return (d->m_model == QAbstractItemModelPrivate::staticEmptyModel() ? 0 : d->m_model); +} + +void GlodonAbstractItemView::setDataModel(QAbstractItemModel *dataModel) +{ + Q_D(GlodonAbstractItemView); + d->m_dataModel = dataModel; +} + +QAbstractItemModel *GlodonAbstractItemView::dataModel() const +{ + Q_D(const GlodonAbstractItemView); + return d->m_dataModel; +} + +void GlodonAbstractItemView::setSelectionModel(QItemSelectionModel *selectionModel) +{ + // ### if the given model is null, we should use the original selection model + Q_ASSERT(selectionModel); + Q_D(GlodonAbstractItemView); + + if (selectionModel->model() != d->m_model) + { + qWarning("GlodonAbstractItemView::setSelectionModel() failed: " + "Trying to set a selection model, which works on " + "a different model than the view."); + return; + } + + if (d->m_selectionModel) + { + disconnect(d->m_selectionModel, SIGNAL(selectionChanged(QItemSelection, QItemSelection)), + this, SLOT(selectionChanged(QItemSelection, QItemSelection))); + disconnect(d->m_selectionModel, SIGNAL(currentChanged(QModelIndex, QModelIndex)), + this, SLOT(currentChanged(QModelIndex, QModelIndex))); + } + + d->m_selectionModel = selectionModel; + + if (d->m_selectionModel) + { + connect(d->m_selectionModel, SIGNAL(selectionChanged(QItemSelection, QItemSelection)), + this, SLOT(selectionChanged(QItemSelection, QItemSelection))); + connect(d->m_selectionModel, SIGNAL(currentChanged(QModelIndex, QModelIndex)), + this, SLOT(currentChanged(QModelIndex, QModelIndex))); + } +} + +QItemSelectionModel *GlodonAbstractItemView::selectionModel() const +{ + Q_D(const GlodonAbstractItemView); + return d->m_selectionModel; +} + +bool GlodonAbstractItemView::canStartDrag(QModelIndexList indexes) +{ + Q_UNUSED(indexes); + return true; +} + +void GlodonAbstractItemView::setItemDelegate(GlodonDefaultItemDelegate *pNewItemDelegate) +{ + Q_D(GlodonAbstractItemView); + + if (pNewItemDelegate == d->m_itemDelegate) + { + return; + } + + GlodonDefaultItemDelegate *pOldItemDelegate = d->m_itemDelegate.data(); + + if (pOldItemDelegate != NULL && d->delegateRefCount(pOldItemDelegate) == 1) + { + disconnect(pOldItemDelegate, &GlodonDefaultItemDelegate::closeEditor, + this, &GlodonAbstractItemView::closeEditor); + disconnect(pOldItemDelegate, SIGNAL(sizeHintChanged(QModelIndex)), this, SLOT(doItemsLayout())); + + disconnect(pOldItemDelegate, SIGNAL(commitData(QWidget *, bool &)), + this, SLOT(commitData(QWidget *, bool &))); + disconnect(pOldItemDelegate, + SIGNAL(onQueryImageAspectRatioMode(QModelIndex, GlodonDefaultItemDelegate::GAspectRatioMode &)), + this, SIGNAL(onQueryImageRatioMode(QModelIndex, GlodonDefaultItemDelegate::GAspectRatioMode &))); + disconnect(pOldItemDelegate, SIGNAL(onQueryFloatOrDoubleViewFormat(QModelIndex, QString &)), + this, SIGNAL(onQueryFloatOrDoubleViewFormat(QModelIndex, QString &))); + disconnect(pOldItemDelegate, + SIGNAL(onQueryIndexDataType(QModelIndex, GlodonDefaultItemDelegate::GDataType &)), + this, SIGNAL(onQueryIndexDataType(QModelIndex, GlodonDefaultItemDelegate::GDataType &))); + disconnect(pOldItemDelegate, + SIGNAL(onCommitDataAndCloseEditor()), this, SLOT(commitDataAndCloseEditor())); + } + + if (pNewItemDelegate != NULL) + { + if (d->delegateRefCount(pNewItemDelegate) == 0) + { + connect(pNewItemDelegate, &GlodonDefaultItemDelegate::closeEditor, + this, &GlodonAbstractItemView::closeEditor); + qRegisterMetaType("QModelIndex"); + connect(pNewItemDelegate, SIGNAL(sizeHintChanged(QModelIndex)), this, SLOT(doItemsLayout()), Qt::QueuedConnection); + + connect(pNewItemDelegate, SIGNAL(commitData(QWidget *, bool &)), + this, SLOT(commitData(QWidget *, bool &))); + connect(pNewItemDelegate, + SIGNAL(onQueryImageAspectRatioMode(QModelIndex, GlodonDefaultItemDelegate::GAspectRatioMode &)), + this, SIGNAL(onQueryImageRatioMode(QModelIndex, GlodonDefaultItemDelegate::GAspectRatioMode &))); + connect(pNewItemDelegate, SIGNAL(onQueryFloatOrDoubleViewFormat(QModelIndex, QString &)), + this, SIGNAL(onQueryFloatOrDoubleViewFormat(QModelIndex, QString &))); + connect(pNewItemDelegate, + SIGNAL(onQueryIndexDataType(const QModelIndex &, GlodonDefaultItemDelegate::GDataType &)), + this, SIGNAL(onQueryIndexDataType(const QModelIndex &, GlodonDefaultItemDelegate::GDataType &))); + connect(pNewItemDelegate, + SIGNAL(onCommitDataAndCloseEditor()), this, SLOT(commitDataAndCloseEditor())); + } + + syncStateToDelegate(pNewItemDelegate); + + pNewItemDelegate->m_pTable = this; + } + + d->m_itemDelegate = pNewItemDelegate; + viewport()->update(); +} + +GlodonDefaultItemDelegate *GlodonAbstractItemView::itemDelegate() const +{ + return d_func()->m_itemDelegate; +} + +QVariant GlodonAbstractItemView::inputMethodQuery(Qt::InputMethodQuery query) const +{ + const QModelIndex c_oCurrentIndex = currentIndex(); + + if (!c_oCurrentIndex.isValid() || query != Qt::ImMicroFocus) + { + return QAbstractScrollArea::inputMethodQuery(query); + } + + return visualRect(c_oCurrentIndex); +} + +bool GlodonAbstractItemView::inLinkCell(const QPoint& pos) +{ + QModelIndex index = indexAt(pos); + GlodonDefaultItemDelegate::GDataType type = GlodonDefaultItemDelegate::GTypeNormal; + emit onQueryIndexDataType(index, type); + return (type == GlodonDefaultItemDelegate::GTypeHTML); +} + +bool GlodonAbstractItemView::alwaysShowEditorPro() +{ + Q_D(GlodonAbstractItemView); + return d->m_alwaysShowEditorPro; +} + +void GlodonAbstractItemView::setAlwaysShowEditorPro(bool value) +{ + Q_D(GlodonAbstractItemView); + + if (d->m_alwaysShowEditorPro == value) + { + return; + } + else + { + d->m_alwaysShowEditorPro = value; + + if (value) + { + for (int row = 0; row < d->m_model->rowCount(); ++row) + { + for (int column = 0; column < d->m_model->columnCount(); ++column) + { + QModelIndex index = d->m_model->index(row, column); + edit(index); + + if (NULL != d->m_currentEditor) + { + setIndexWidget(index, d->m_currentEditor); + d->m_currentEditor = NULL; + } + } + } + } + else + { + foreach(const GEditorInfo & info, d->m_indexEditorHash) + { + if (info.widget) + { + d->releaseEditor(info.widget.data()); + } + } + d->m_editorIndexHash.clear(); + d->m_indexEditorHash.clear(); + d->m_persistent.clear(); + } + } +} + +bool GlodonAbstractItemView::isLegalData() +{ + return false; +} + +void GlodonAbstractItemView::setLegalData(bool value) +{ + G_UNUSED(value); +} + +QModelIndex GlodonAbstractItemView::editorModelIndex() +{ + Q_D(GlodonAbstractItemView); + return d->m_oEditorIndex; +} + +bool GlodonAbstractItemView::gridTextIncludeLeading() const +{ + Q_D(const GlodonAbstractItemView); + return d->m_bGridTextIncludeLeading; +} + +void GlodonAbstractItemView::setGridTextIncludeLeading(bool value) +{ + Q_D(GlodonAbstractItemView); + + if (d->m_bGridTextIncludeLeading != value) + { + d->m_itemDelegate.data()->setIncludeLeading(value); + d->m_bGridTextIncludeLeading = value; + } +} + +bool GlodonAbstractItemView::allowSelectAll() const +{ + Q_D(const GlodonAbstractItemView); + return d->m_bAllowSelectAll; +} + +bool GlodonAbstractItemView::scrollBarTracking() const +{ + Q_D(const GlodonAbstractItemView); + return d->m_bScrollBarTracking; +} + +void GlodonAbstractItemView::setScrollBarTracking(bool value) +{ + Q_D(GlodonAbstractItemView); + + if (d->m_bScrollBarTracking != value) + { + d->m_bScrollBarTracking = value; + + if (d->vbar) + { + d->vbar->setTracking(value); + } + + if (d->hbar) + { + d->hbar->setTracking(value); + } + } +} + +void GlodonAbstractItemView::setAllowSelectAll(bool value) +{ + Q_D(GlodonAbstractItemView); + d->m_bAllowSelectAll = value; +} + +QColor GlodonAbstractItemView::gridColor() const +{ + Q_D(const GlodonAbstractItemView); + + return d->m_oGridColor; +} + +void GlodonAbstractItemView::setGridColor(QColor value) +{ + Q_D(GlodonAbstractItemView); + + if (value == QColor(5, 0, 0)) //对应delphi的clWindow,使用默认颜色 + { + return; + } + + if (d->m_oGridColor != value) + { + d->m_oGridColor = value; + //设置Grid背景色 + const_cast(palette()).setColor(QPalette::Window, d->m_oGridColor); + const_cast(d->viewport->palette()).setColor(QPalette::Window, d->m_oGridColor); + + d->viewport->setBackgroundRole(QPalette::Window); + d->viewport->update(); + } +} + +void GlodonAbstractItemView::setIsShowHint(bool value, bool showIndexContent) +{ + Q_D(GlodonAbstractItemView); + + if (value) + { + if (!(d->m_pToolTipFrame)) + { + d->m_pToolTipFrame = new GToolTipFrame(NULL);//保证frame可以在控件顶层 + } + + connect(this, SIGNAL(entered(QModelIndex)), this, SLOT(showToolTip(QModelIndex))); + d->m_bShowIndexContent = showIndexContent; + } + else + { + disconnect(this, SIGNAL(entered(QModelIndex)), this, SLOT(showToolTip(QModelIndex))); + } +} + +void GlodonAbstractItemView::setShowHintDelay(int time) +{ + Q_D(GlodonAbstractItemView); + d->m_nDelayedHintTime = time; +} + +int GlodonAbstractItemView::verticalScrollbarValue() +{ + Q_D(GlodonAbstractItemView); + return d->vbar->value(); +} + +void GlodonAbstractItemView::setVerticalScrollBarValue(int value) +{ + Q_D(GlodonAbstractItemView); + d->vbar->setValue(value); +} + +int GlodonAbstractItemView::horizontalScrollbarValue() +{ + Q_D(GlodonAbstractItemView); + return d->hbar->value(); +} + +void GlodonAbstractItemView::setHorizontalScrollbarValue(int value) +{ + Q_D(GlodonAbstractItemView); + d->hbar->setValue(value); +} + +void GlodonAbstractItemView::setIsSearchModel(bool value) +{ + Q_D(GlodonAbstractItemView); + d->m_isSearchModel = value; +} + +bool GlodonAbstractItemView::isSearchModel() +{ + Q_D(GlodonAbstractItemView); + return d->m_isSearchModel; +} + +void GlodonAbstractItemView::setAllowRangeMoving(bool value) +{ + G_UNUSED(value); +} + +bool GlodonAbstractItemView::allowRangeMoving() const +{ + return false; +} + +void GlodonAbstractItemView::setItemDelegateForRow(int row, GlodonDefaultItemDelegate *delegate) +{ + Q_D(GlodonAbstractItemView); + + if (GlodonDefaultItemDelegate *rowDelegate = d->m_rowDelegates.value(row, 0)) + { + if (d->delegateRefCount(rowDelegate) == 1) + { + disconnect(rowDelegate, &GlodonDefaultItemDelegate::closeEditor, + this, &GlodonAbstractItemView::closeEditor); + disconnect(rowDelegate, + SIGNAL(commitData(QWidget *, bool &)), this, SLOT(commitData(QWidget *, bool &))); + + disconnect(rowDelegate, + SIGNAL(onQueryImageAspectRatioMode(QModelIndex, GlodonDefaultItemDelegate::GAspectRatioMode &)), + this, SIGNAL(onQueryImageRatioMode(QModelIndex, GlodonDefaultItemDelegate::GAspectRatioMode &))); + disconnect(rowDelegate, SIGNAL(onQueryFloatOrDoubleViewFormat(QModelIndex, QString &)), + this, SIGNAL(onQueryFloatOrDoubleViewFormat(QModelIndex, QString &))); + disconnect(rowDelegate, + SIGNAL(onQueryIndexDataType(QModelIndex, GlodonDefaultItemDelegate::GDataType &)), + this, SIGNAL(onQueryIndexDataType(QModelIndex, GlodonDefaultItemDelegate::GDataType &))); + } + + d->m_rowDelegates.remove(row); + } + + if (delegate != NULL) + { + if (d->delegateRefCount(delegate) == 0) + { + connect(delegate, &GlodonDefaultItemDelegate::closeEditor, + this, &GlodonAbstractItemView::closeEditor); + connect(delegate, SIGNAL(commitData(QWidget *, bool &)), this, SLOT(commitData(QWidget *, bool &))); + + connect(delegate, + SIGNAL(onQueryImageAspectRatioMode(QModelIndex, GlodonDefaultItemDelegate::GAspectRatioMode &)), + this, SIGNAL(onQueryImageRatioMode(QModelIndex, GlodonDefaultItemDelegate::GAspectRatioMode &))); + connect(delegate, SIGNAL(onQueryFloatOrDoubleViewFormat(QModelIndex, QString &)), + this, SIGNAL(onQueryFloatOrDoubleViewFormat(QModelIndex, QString &))); + connect(delegate, SIGNAL(onQueryIndexDataType(QModelIndex, GlodonDefaultItemDelegate::GDataType &)), + this, SIGNAL(onQueryIndexDataType(QModelIndex, GlodonDefaultItemDelegate::GDataType &))); + } + + syncStateToDelegate(delegate); + d->m_rowDelegates.insert(row, delegate); + } + + viewport()->update(); +} + +GlodonDefaultItemDelegate *GlodonAbstractItemView::itemDelegateForRow(int row) const +{ + Q_D(const GlodonAbstractItemView); + return d->m_rowDelegates.value(row, 0); +} + +void GlodonAbstractItemView::setItemDelegateForColumn(int column, GlodonDefaultItemDelegate *delegate) +{ + Q_D(GlodonAbstractItemView); + + if (GlodonDefaultItemDelegate *columnDelegate = d->m_columnDelegates.value(column, 0)) + { + if (d->delegateRefCount(columnDelegate) == 1) + { + disconnect(columnDelegate, SIGNAL(closeEditor(QWidget *, bool &, GlodonDefaultItemDelegate::EndEditHint)), + this, SLOT(closeEditor(QWidget *, bool &, GlodonDefaultItemDelegate::EndEditHint))); + disconnect(columnDelegate, SIGNAL(commitData(QWidget *, bool &)), + this, SLOT(commitData(QWidget *, bool &))); + + disconnect(columnDelegate, + SIGNAL(onQueryImageAspectRatioMode(QModelIndex, GlodonDefaultItemDelegate::GAspectRatioMode &)), + this, SIGNAL(onQueryImageRatioMode(QModelIndex, GlodonDefaultItemDelegate::GAspectRatioMode &))); + disconnect(columnDelegate, SIGNAL(onQueryFloatOrDoubleViewFormat(QModelIndex, QString &)), + this, SIGNAL(onQueryFloatOrDoubleViewFormat(QModelIndex, QString &))); + disconnect(columnDelegate, + SIGNAL(onQueryIndexDataType(QModelIndex, GlodonDefaultItemDelegate::GDataType &)), + this, SIGNAL(onQueryIndexDataType(QModelIndex, GlodonDefaultItemDelegate::GDataType &))); + } + + d->m_columnDelegates.remove(column); + } + + if (delegate != NULL) + { + if (d->delegateRefCount(delegate) == 0) + { + connect(delegate, SIGNAL(closeEditor(QWidget *, bool &, GlodonDefaultItemDelegate::EndEditHint)), + this, SLOT(closeEditor(QWidget *, bool &, GlodonDefaultItemDelegate::EndEditHint))); + connect(delegate, SIGNAL(commitData(QWidget *, bool &)), this, SLOT(commitData(QWidget *, bool &))); + + connect(delegate, + SIGNAL(onQueryImageAspectRatioMode(QModelIndex, GlodonDefaultItemDelegate::GAspectRatioMode &)), + this, SIGNAL(onQueryImageRatioMode(QModelIndex, GlodonDefaultItemDelegate::GAspectRatioMode &))); + connect(delegate, SIGNAL(onQueryFloatOrDoubleViewFormat(QModelIndex, QString &)), + this, SIGNAL(onQueryFloatOrDoubleViewFormat(QModelIndex, QString &))); + connect(delegate, SIGNAL(onQueryIndexDataType(QModelIndex, GlodonDefaultItemDelegate::GDataType &)), + this, SIGNAL(onQueryIndexDataType(QModelIndex, GlodonDefaultItemDelegate::GDataType &))); + } + + syncStateToDelegate(delegate); + d->m_columnDelegates.insert(column, delegate); + } + + viewport()->update(); +} + +GlodonDefaultItemDelegate *GlodonAbstractItemView::itemDelegateForColumn(int column) const +{ + Q_D(const GlodonAbstractItemView); + return d->m_columnDelegates.value(column, 0); +} + +GlodonDefaultItemDelegate *GlodonAbstractItemView::itemDelegate(const QModelIndex &index) const +{ + Q_D(const GlodonAbstractItemView); + return d->delegateForIndex(index); +} + +void GlodonAbstractItemView::setSelectionMode(SelectionMode mode) +{ + Q_D(GlodonAbstractItemView); + d->m_selectionMode = mode; +} + +GlodonAbstractItemView::SelectionMode GlodonAbstractItemView::selectionMode() const +{ + Q_D(const GlodonAbstractItemView); + return d->m_selectionMode; +} + +void GlodonAbstractItemView::setSelectionBehavior(GlodonAbstractItemView::SelectionBehavior behavior) +{ + Q_D(GlodonAbstractItemView); + d->m_selectionBehavior = behavior; +} + +GlodonAbstractItemView::SelectionBehavior GlodonAbstractItemView::selectionBehavior() const +{ + Q_D(const GlodonAbstractItemView); + return d->m_selectionBehavior; +} + +void GlodonAbstractItemView::setCurrentIndex(const QModelIndex &index) +{ + Q_D(GlodonAbstractItemView); + + if (d->m_selectionModel && (!index.isValid() || d->isIndexEnabled(index))) + { + QItemSelectionModel::SelectionFlags command = selectionCommand(index, 0); + moveCurrent(currentIndex(), index, command, mrProgram); + d->m_bCurrentIndexSet = true; + + if ((command & QItemSelectionModel::Current) == 0) + { + d->m_pressedPosition = visualRect(currentIndex()).center() + d->offset(); + } + } +} + +QModelIndex GlodonAbstractItemView::currentIndex() const +{ + Q_D(const GlodonAbstractItemView); + return d->m_selectionModel ? d->m_selectionModel->currentIndex() : QModelIndex(); +} + +void GlodonAbstractItemView::reset() +{ + beforeReset(); + doReset(); + afterReset(); +} + +void GlodonAbstractItemView::beforeReset() +{ + +} + +void GlodonAbstractItemView::doReset() +{ + Q_D(GlodonAbstractItemView); + + d->m_delayedReset.stop(); //make sure we stop the timer + + foreach(const GEditorInfo & info, d->m_indexEditorHash) + { + if (info.widget) + { + d->releaseEditor(info.widget.data()); + } + } + + d->m_editorIndexHash.clear(); + d->m_indexEditorHash.clear(); + d->m_persistent.clear(); + d->m_bCurrentIndexSet = false; + d->m_oEditorIndex = QModelIndex(); + + setState(NoState); + setRootIndex(QModelIndex()); + + if (d->m_selectionModel) + { + d->m_selectionModel->reset(); + } + + //通过插入数据的方式,结束编辑状态,应该把delegate的状态重置 + if (itemDelegate() != NULL) + { + itemDelegate()->setCurEditor(NULL); + } + +#ifndef QT_NO_ACCESSIBILITY +#ifdef Q_WS_X11 + + if (QAccessible::isActive()) + { + QAccessible::queryAccessibleInterface(this)->table2Interface()->modelReset(); + QAccessible::updateAccessibility(this, 0, QAccessible::TableModelChanged); + } + +#endif +#endif +} + +void GlodonAbstractItemView::afterReset() +{ + +} + +void GlodonAbstractItemView::setRootIndex(const QModelIndex &index) +{ + Q_D(GlodonAbstractItemView); + + if (index.isValid() && index.model() != d->m_model) + { + qWarning("GlodonAbstractItemView::setRootIndex failed : index must be from the currently set model"); + return; + } + + d->m_root = index; + d->doDelayedItemsLayout(); +} + +QModelIndex GlodonAbstractItemView::rootIndex() const +{ + return QModelIndex(d_func()->m_root); +} + +void GlodonAbstractItemView::selectAll() +{ + Q_D(GlodonAbstractItemView); + + if (!d->m_bAllowSelectAll) + { + return; + } + + SelectionMode mode = d->m_selectionMode; + if (mode == MultiSelection || mode == ExtendedSelection) + { + d->selectAll(QItemSelectionModel::ClearAndSelect + | d->selectionBehaviorFlags()); + } + else if (mode != SingleSelection) + { + d->selectAll(selectionCommand(d->m_model->index(0, 0, d->m_root))); + } +} + +void GlodonAbstractItemView::edit(const QModelIndex &index) +{ + Q_D(GlodonAbstractItemView); + + if (!d->isIndexValid(index)) + { + qWarning("edit: index was invalid"); + } + + if (!edit(index, AllEditTriggers, 0)) + { + qWarning("edit: editing failed"); + } +} + +void GlodonAbstractItemView::doCommitDataAndCloseEditor(bool &canCloseEditor) +{ + Q_D(GlodonAbstractItemView); + + QModelIndex index = currentIndex(); + + if (!d->isIndexValid(index) || (d->m_state != EditingState && !d->m_alwaysShowEditorPro)) + return; + + QWidget *pEditor = d->editorForIndex(index).widget.data(); + + if (NULL == pEditor) + return; + + GlodonDefaultItemDelegate * pGlodonDelegate = d->delegateForIndex(index); + try + { + commitData(pEditor, canCloseEditor); + + if (canCloseEditor) + { + closeEditor(pEditor, canCloseEditor, GlodonDefaultItemDelegate::NoHint); + } + + if (canCloseEditor) + { + d->m_state = NoState; + } + else + { + //提交非法内容,被拒绝的时候,控件中的文字内容全选 + if (NULL != pGlodonDelegate) + { + pGlodonDelegate->setTextAllSelected(pEditor); + } + d->m_state = EditingState; + } + } + catch (...) + { + if (NULL != pGlodonDelegate) + { + pGlodonDelegate->setTextAllSelected(pEditor); + } + d->m_state = EditingState; + + throw; + } +} + +void GlodonAbstractItemView::setModelData(GlodonDefaultItemDelegate *pDelegate, QWidget * editor, + const QModelIndex & index, bool & canCloseEditor) +{ + Q_D(GlodonAbstractItemView); + + try + { + pDelegate->setModelData(editor, d->m_model, index); + } + catch (...) + { + d->m_pCurCommittingEditor = NULL; + setLegalData(false); + canCloseEditor = false; + editor->setFocus(); + throw; + } +} + +void GlodonAbstractItemView::setLegitimacyOfData(GlodonDefaultItemDelegate *pDelegate, bool &canCloseEditor) +{ + Q_D(GlodonAbstractItemView); + + canCloseEditor = pDelegate->checkSetModelData(); + + if (canCloseEditor) + { + setLegalData(true); + d->m_oEditorIndex = QModelIndex(); + } + else + { + setLegalData(false); + } +} + +void GlodonAbstractItemView::clearSelection() +{ + Q_D(GlodonAbstractItemView); + + if (d->m_selectionModel) + { + d->m_selectionModel->clearSelection(); + } +} + +void GlodonAbstractItemView::doItemsLayout() +{ + Q_D(GlodonAbstractItemView); + d->interruptDelayedItemsLayout(); + updateGeometries(); + d->viewport->update(); +} + +void GlodonAbstractItemView::setEditTriggers(EditTriggers actions) +{ + Q_D(GlodonAbstractItemView); + d->m_editTriggers = actions; +} + +GlodonAbstractItemView::EditTriggers GlodonAbstractItemView::editTriggers() const +{ + Q_D(const GlodonAbstractItemView); + return d->m_editTriggers; +} + +void GlodonAbstractItemView::setVerticalScrollMode(ScrollMode mode) +{ + Q_D(GlodonAbstractItemView); + + if (mode == d->m_verticalScrollMode) + { + return; + } + + QModelIndex topLeft = indexAt(QPoint(0, 0)); + d->m_verticalScrollMode = mode; + updateGeometries(); // update the scroll bars + scrollTo(topLeft, GlodonAbstractItemView::PositionAtTop); +} + +GlodonAbstractItemView::ScrollMode GlodonAbstractItemView::verticalScrollMode() const +{ + Q_D(const GlodonAbstractItemView); + return d->m_verticalScrollMode; +} + +void GlodonAbstractItemView::setHorizontalScrollMode(ScrollMode mode) +{ + Q_D(GlodonAbstractItemView); + d->m_horizontalScrollMode = mode; + updateGeometries(); // update the scroll bars +} + +GlodonAbstractItemView::ScrollMode GlodonAbstractItemView::horizontalScrollMode() const +{ + Q_D(const GlodonAbstractItemView); + return d->m_horizontalScrollMode; +} + +#ifndef QT_NO_DRAGANDDROP + +void GlodonAbstractItemView::setDragDropOverwriteMode(bool overwrite) +{ + Q_D(GlodonAbstractItemView); + d->m_bDragDropOverwrite = overwrite; +} + +bool GlodonAbstractItemView::dragDropOverwriteMode() const +{ + Q_D(const GlodonAbstractItemView); + return d->m_bDragDropOverwrite; +} + +#endif + +void GlodonAbstractItemView::setAutoScroll(bool enable) +{ + Q_D(GlodonAbstractItemView); + d->m_bAutoScroll = enable; +} + +bool GlodonAbstractItemView::hasAutoScroll() const +{ + Q_D(const GlodonAbstractItemView); + return d->m_bAutoScroll; +} + +void GlodonAbstractItemView::setAutoScrollMargin(int margin) +{ + Q_D(GlodonAbstractItemView); + d->m_nAutoScrollMargin = margin; +} + +int GlodonAbstractItemView::autoScrollMargin() const +{ + Q_D(const GlodonAbstractItemView); + return d->m_nAutoScrollMargin; +} + +void GlodonAbstractItemView::setToolTipFrameHide() +{ + Q_D(GlodonAbstractItemView); + if (d->m_pToolTipFrame) + { + d->m_pToolTipFrame->hide(); + d->m_delayedShowToolTip.stop(); + } +} + +void GlodonAbstractItemView::setTabKeyNavigation(bool enable) +{ + Q_D(GlodonAbstractItemView); + d->m_bTabKeyNavigation = enable; +} + +bool GlodonAbstractItemView::tabKeyNavigation() const +{ + Q_D(const GlodonAbstractItemView); + return d->m_bTabKeyNavigation; +} + +#ifndef QT_NO_DRAGANDDROP + +void GlodonAbstractItemView::setDropIndicatorShown(bool enable) +{ + Q_D(GlodonAbstractItemView); + d->m_bShowDropIndicator = enable; +} + +bool GlodonAbstractItemView::showDropIndicator() const +{ + Q_D(const GlodonAbstractItemView); + return d->m_bShowDropIndicator; +} + +void GlodonAbstractItemView::setDragEnabled(bool enable) +{ + Q_D(GlodonAbstractItemView); + d->m_bDragEnabled = enable; +} + +bool GlodonAbstractItemView::dragEnabled() const +{ + Q_D(const GlodonAbstractItemView); + return d->m_bDragEnabled; +} + +void GlodonAbstractItemView::setDragDropMode(DragDropMode behavior) +{ + Q_D(GlodonAbstractItemView); + d->m_dragDropMode = behavior; + setDragEnabled(behavior == DragOnly || behavior == DragDrop || behavior == InternalMove); + setAcceptDrops(behavior == DropOnly || behavior == DragDrop || behavior == InternalMove); +} + +GlodonAbstractItemView::DragDropMode GlodonAbstractItemView::dragDropMode() const +{ + Q_D(const GlodonAbstractItemView); + DragDropMode setBehavior = d->m_dragDropMode; + + if (!dragEnabled() && !acceptDrops()) + { + return NoDragDrop; + } + + if (dragEnabled() && !acceptDrops()) + { + return DragOnly; + } + + if (!dragEnabled() && acceptDrops()) + { + return DropOnly; + } + + if (dragEnabled() && acceptDrops()) + { + if (setBehavior == InternalMove) + { + return setBehavior; + } + else + { + return DragDrop; + } + } + + return NoDragDrop; +} + +void GlodonAbstractItemView::setDefaultDropAction(Qt::DropAction dropAction) +{ + Q_D(GlodonAbstractItemView); + d->m_defaultDropAction = dropAction; +} + +Qt::DropAction GlodonAbstractItemView::defaultDropAction() const +{ + Q_D(const GlodonAbstractItemView); + return d->m_defaultDropAction; +} + +#endif // QT_NO_DRAGANDDROP + +void GlodonAbstractItemView::setAlternatingRowColors(bool enable) +{ + Q_D(GlodonAbstractItemView); + + if (d->m_bAlternatingColors == enable) + { + return; + } + + d->m_bAlternatingColors = enable; + if (isVisible()) + { + d->viewport->update(); + } +} + +bool GlodonAbstractItemView::alternatingRowColors() const +{ + Q_D(const GlodonAbstractItemView); + return d->m_bAlternatingColors; +} + +void GlodonAbstractItemView::setIconSize(const QSize &size) +{ + Q_D(GlodonAbstractItemView); + + if (size == d->m_oIconSize) + { + return; + } + + d->m_oIconSize = size; + d->doDelayedItemsLayout(); +} + +QSize GlodonAbstractItemView::iconSize() const +{ + Q_D(const GlodonAbstractItemView); + return d->m_oIconSize; +} + +void GlodonAbstractItemView::setTextElideMode(Qt::TextElideMode mode) +{ + Q_D(GlodonAbstractItemView); + d->m_textElideMode = mode; +} + +Qt::TextElideMode GlodonAbstractItemView::textElideMode() const +{ + return d_func()->m_textElideMode; +} + +bool GlodonAbstractItemView::focusNextPrevChild(bool next) +{ +// Q_D(GlodonAbstractItemView); +// if (d->m_tabKeyNavigation && isEnabled() && d->viewport->isEnabled()) { +// QKeyEvent event(QEvent::KeyPress, next ? Qt::Key_Tab : Qt::Key_Backtab, Qt::NoModifier); +// keyPressEvent(&event); +// if (event.isAccepted()) +// return true; +// } +// return QAbstractScrollArea::focusNextPrevChild(next); + //此处不需要QWdiget的focusNextPrevChild处理,返回false,直接调用keyPressEvent自己控制焦点方向 + Q_UNUSED(next); + return false; +} + +bool GlodonAbstractItemView::event(QEvent *event) +{ + Q_D(GlodonAbstractItemView); + GLDEvent *gldEvent = dynamic_cast(event); + + if (gldEvent) + { + switch (gldEvent->type()) + { + case GM_FIRST: + { + doGMFirst(gldEvent); + break; + } + + case GM_QUERYFIRST: + { + doGMQueryFirst(gldEvent); + break; + } + + case GM_PREV: + { + doGMPrev(gldEvent); + break; + } + + case GM_QUERYPREV: + { + doGMQueryPrev(gldEvent); + break; + } + + case GM_NEXT: + { + doGMNext(gldEvent); + break; + } + + case GM_QUERYNEXT: + { + doGMQueryNext(gldEvent); + break; + } + + case GM_Last: + { + doGMLast(gldEvent); + break; + } + + case GM_QUERYLAST: + { + doGMQueryLast(gldEvent); + break; + } + + case GM_SETSEL: + { + doGMSetSel(gldEvent); + break; + } + + case GM_QUERYSETSEL: + { + doGMQuerySetSel(gldEvent); + break; + } + + case GM_SETCOLROW: + { + doGMSetColRow(gldEvent); + break; + } + + case GM_SetScrollBarStep: + { + switch ((GLDScrollBarType)(gldEvent->wParam())) + { + case gsbtVertical: // Vertical + d->vbar->setEnabled(gldEvent->lParam()); + break; + + case gsbtHorizon: // Horizon: + d->hbar->setEnabled(gldEvent->lParam()); + break; + + case gsbtAll: + d->vbar->setEnabled(gldEvent->lParam()); + d->hbar->setEnabled(gldEvent->lParam()); + break; + + default: + break; + } + + return true; + } + + default: + break; + } + } + else + { + switch (event->type()) + { + case QEvent::Paint: + //we call this here because the scrollbars' visibility might be altered + //so this can't be done in the paintEvent method + d->executePostedLayout(); //make sure we set the layout properly + break; + + case QEvent::Show: + d->executePostedLayout(); //make sure we set the layout properly + + if (d->m_shouldScrollToCurrentOnShow) + { + d->m_shouldScrollToCurrentOnShow = false; + const QModelIndex c_oCurrentIndex = currentIndex(); + if (c_oCurrentIndex.isValid() && (d->m_state == GlodonAbstractItemView::EditingState || d->m_bAutoScroll)) + { + scrollTo(c_oCurrentIndex); + } + } + + break; + + case QEvent::LocaleChange: + viewport()->update(); + break; + + case QEvent::LayoutDirectionChange: + case QEvent::ApplicationLayoutDirectionChange: + updateGeometries(); + break; + + case QEvent::StyleChange: + doItemsLayout(); + break; + + case QEvent::FocusOut: + d->checkPersistentEditorFocus(); + break; + + case QEvent::FontChange: + d->doDelayedItemsLayout(); // the size of the items will change + break; +#ifdef QT_SOFTKEYS_ENABLED + + case QEvent::LanguageChange: + d->doneSoftKey->setText(QSoftKeyManager::standardSoftKeyText(QSoftKeyManager::DoneSoftKey)); + break; +#endif + + default: + break; + } + } + + return QAbstractScrollArea::event(event); +} + +bool GlodonAbstractItemView::viewportEvent(QEvent *event) +{ + Q_D(GlodonAbstractItemView); + + switch (event->type()) + { + case QEvent::HoverMove: + case QEvent::HoverEnter: + d->setHoverIndex(indexAt(static_cast(event)->pos())); + break; + + case QEvent::HoverLeave: + d->setHoverIndex(QModelIndex()); + break; + + case QEvent::Enter: + d->m_viewportEnteredNeeded = true; + break; + + case QEvent::Leave: +#ifndef QT_NO_STATUSTIP + if (d->m_shouldClearStatusTip && d->parent) + { + QString empty; + QStatusTipEvent tip(empty); + QApplication::sendEvent(d->parent, &tip); + d->m_shouldClearStatusTip = false; + } + +#endif + d->m_enteredIndex = QModelIndex(); + break; + case QEvent::ToolTip: + case QEvent::QueryWhatsThis: + case QEvent::WhatsThis: + { + QHelpEvent *he = static_cast(event); + const QModelIndex c_index = indexAt(he->pos()); + + QStyleOptionViewItem option = d->viewOptionsV4(); + option.rect = visualRect(c_index); + option.state |= (c_index == currentIndex() ? QStyle::State_HasFocus : QStyle::State_None); + + bool bRetval = false; + // ### Qt 5: make this a normal function call to a virtual function + QMetaObject::invokeMethod(d->delegateForIndex(c_index), "helpEvent", + Q_RETURN_ARG(bool, bRetval), + Q_ARG(QHelpEvent *, he), + Q_ARG(GlodonAbstractItemView *, this), + Q_ARG(QStyleOptionViewItem, option), + Q_ARG(QModelIndex, c_index)); + return bRetval; + } + + case QEvent::FontChange: + d->doDelayedItemsLayout(); // the size of the items will change + break; + + case QEvent::WindowActivate: + case QEvent::WindowDeactivate: + d->viewport->update(); + break; + + case QEvent::Wheel: + //数据非法会出现两次弹窗 +// setFocus(Qt::MouseFocusReason); + return QAbstractScrollArea::viewportEvent(event); + + default: + break; + } + + return QAbstractScrollArea::viewportEvent(event); +} + +void GlodonAbstractItemView::mousePressEvent(QMouseEvent *event) +{ + Q_D(GlodonAbstractItemView); + d->m_delayedAutoScroll.stop(); //any interaction with the view cancel the auto scrolling + + QPoint pos = event->pos(); + QPersistentModelIndex index = indexAt(pos); + //如果点击的是格线之外的区域,不做任何操作,保持和Delphi版一致 + if (!index.isValid()) + { + d->m_noSelectionOnMousePress = true; + return; + } + + // wangdd-a,后面的判断觉得不是特别正确,进入编辑状态后,TableView应该接不到鼠标消息了 + // 但是Qt里面也是这么写的,先不做修改 + if (!d->m_selectionModel || (d->m_state == EditingState && d->hasEditor(index))) + { + return; + } + + dealWithSelectionAndAutoScroll(index, event); +} + +void GlodonAbstractItemView::mouseMoveEvent(QMouseEvent *event) +{ + Q_D(GlodonAbstractItemView); + + QPoint oPrePoint; + QPoint oCurPoint = event->pos(); + QPersistentModelIndex oCurIndex = indexAt(oCurPoint); + + switch (state()) + { + case ExpandingState: + case CollapsingState: + { + return; + } + +#ifndef QT_NO_DRAGANDDROP + case DraggingState: + { + if (canStartDrag(d->selectedDraggableIndexes())) + { + oPrePoint = d->m_pressedPosition - d->offset(); + + if ((oPrePoint - oCurPoint).manhattanLength() > QApplication::startDragDistance()) + { + d->m_pressedIndex = QModelIndex(); + startDrag(d->m_model->supportedDragActions()); + setState(NoState); // the startDrag will return when the dnd operation is done + stopAutoScroll(); + } + + return; + } + } +#endif // QT_NO_DRAGANDDROP + + case EditingState: + { + QModelIndex buddy = d->m_model->buddy(d->m_pressedIndex); + + if (d->hasEditor(buddy)) + { + // todo liurx huy-a 在Revision: 5161 修改 always edit 模式状态下支持 ToolTip(施工需求) + if (d->m_alwaysShowEditorPro) + { + d->checkMouseMove(oCurIndex); + } + + return; + } + } + default: + break; + } + + // 同上 + if (d->m_oEditorIndex.isValid()) + { + if (d->m_alwaysShowEditorPro) + { + d->checkMouseMove(oCurIndex); + } + + return; + } + + if (d->m_selectionMode != SingleSelection) + { + oPrePoint = d->m_pressedPosition - d->offset(); + } + else + { + oPrePoint = oCurPoint; + } + + d->checkMouseMove(oCurIndex); + +#ifndef QT_NO_DRAGANDDROP + + if (d->m_pressedIndex.isValid() + && d->m_bDragEnabled + && (state() != DragSelectingState) + && (event->buttons() != Qt::NoButton) + && !d->selectedDraggableIndexes().isEmpty()) + { + setState(DraggingState); + return; + } + +#endif + + setSelectionAndScrollToOnMouseMove(oCurIndex, event, oPrePoint, oCurPoint); +} + +void GlodonAbstractItemView::leaveEvent(QEvent *event) +{ + G_UNUSED(event); + Q_D(GlodonAbstractItemView); + + if (NULL != d->m_pToolTipFrame) + { + d->m_pToolTipFrame->hide(); + } +} + +void GlodonAbstractItemView::mouseReleaseEvent(QMouseEvent *event) +{ + Q_D(GlodonAbstractItemView); + + QPoint pos = event->pos(); + QPersistentModelIndex index = indexAt(pos); + + if (state() == EditingState) + { + if (d->isIndexValid(index) + && d->isIndexEnabled(index) + && d->sendDelegateEvent(index, event)) + { + update(index); + } + + return; + } + + bool bClick = (index == d->m_pressedIndex && index.isValid()); + bool bSelectedClicked = bClick && (Qt::LeftButton == (event->button() & Qt::LeftButton)) + && d->m_pressedAlreadySelected; + EditTrigger trigger = (bSelectedClicked ? SelectedClicked : NoEditTriggers); + const bool c_edited = edit(index, trigger, event); + + d->m_ctrlDragSelectionFlag = QItemSelectionModel::NoUpdate; + + if (d->m_selectionModel && d->m_noSelectionOnMousePress) + { + d->m_noSelectionOnMousePress = false; +// d->selectionModel->select(index, selectionCommand(index, event)); + QRect rect(d->m_pressedPosition - d->offset(), pos); + setSelection(rect, selectionCommand(index, event)); + } + + if (!c_edited) + { + setState(NoState); + } + + if (bClick) + { + if (Qt::LeftButton == event->button()) + { + emit clicked(index); + } + + if (c_edited) + { + return; + } + + QStyleOptionViewItem option = d->viewOptionsV4(); + + if (d->m_pressedAlreadySelected) + { + option.state |= QStyle::State_Selected; + } + + if (0 != style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, &option, this)) + { + emit activated(index); + } + } +} + +void GlodonAbstractItemView::mouseDoubleClickEvent(QMouseEvent *event) +{ + Q_D(GlodonAbstractItemView); + + QModelIndex index = indexAt(event->pos()); + + if (!index.isValid() + || !d->isIndexEnabled(index) + || (d->m_pressedIndex != index)) + { + QMouseEvent me(QEvent::MouseButtonPress, + event->pos(), event->button(), + event->buttons(), event->modifiers()); + mousePressEvent(&me); + return; + } + + // signal handlers may change the model + QPersistentModelIndex persistent = index; + emit doubleClicked(persistent); + + if ((Qt::LeftButton == (event->button() & Qt::LeftButton)) && cursor().shape() == Qt::ArrowCursor) + if (!edit(persistent, DoubleClicked, event) + && 0 == style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, 0, this)) + { + emit activated(persistent); + } +} + +#ifndef QT_NO_DRAGANDDROP + +void GlodonAbstractItemView::dragEnterEvent(QDragEnterEvent *event) +{ + if (dragDropMode() == InternalMove + && (event->source() != this || !(event->possibleActions() & Qt::MoveAction))) + { + return; + } + + if (d_func()->canDecode(event)) + { + event->accept(); + setState(DraggingState); + } + else + { + event->ignore(); + } +} + +void GlodonAbstractItemView::dragMoveEvent(QDragMoveEvent *event) +{ + Q_D(GlodonAbstractItemView); + + if (dragDropMode() == InternalMove + && (event->source() != this || !(event->possibleActions() & Qt::MoveAction))) + { + return; + } + + // ignore by default + event->ignore(); + + QModelIndex dropIndex; + int col = -1; + int row = -1; + if (d->dropOn(event, &row, &col, &dropIndex)) + { + if (!d->m_model->canDropMimeData( + event->mimeData(), + dragDropMode() == InternalMove ? Qt::MoveAction : event->dropAction(), row, col, dropIndex)) + { + return; + } + } + + QModelIndex index = indexAt(event->pos()); + d->m_hover = index; + if (!d->droppingOnItself(event, index) + && d->canDecode(event)) + { + if (index.isValid() && d->m_bShowDropIndicator) + { + QRect rect = visualRect(index); + d->m_dropIndicatorPosition = d->position(event->pos(), rect, index); + switch (d->m_dropIndicatorPosition) + { + case AboveItem: + if (d->isIndexDropEnabled(index.parent())) + { + d->m_dropIndicatorRect = QRect(rect.left(), rect.top(), rect.width(), 0); + event->accept(); + } + else + { + d->m_dropIndicatorRect = QRect(); + } + break; + case BelowItem: + if (d->isIndexDropEnabled(index.parent())) + { + d->m_dropIndicatorRect = QRect(rect.left(), rect.bottom(), rect.width(), 0); + event->accept(); + } + else + { + d->m_dropIndicatorRect = QRect(); + } + break; + case OnItem: + if (d->isIndexDropEnabled(index)) + { + d->m_dropIndicatorRect = rect; + event->accept(); + } + else + { + d->m_dropIndicatorRect = QRect(); + } + break; + case OnViewport: + d->m_dropIndicatorRect = QRect(); + + if (d->isIndexDropEnabled(rootIndex())) + { + event->accept(); // allow dropping in empty areas + } + break; + } + } + else + { + d->m_dropIndicatorRect = QRect(); + d->m_dropIndicatorPosition = OnViewport; + if (d->isIndexDropEnabled(rootIndex())) + { + event->accept(); // allow dropping in empty areas + } + } + + d->viewport->update(); + } // can decode + + if (d->shouldAutoScroll(event->pos())) + { + startAutoScroll(); + } +} + +bool GlodonAbstractItemViewPrivate::droppingOnItself(QDropEvent *event, const QModelIndex &index) +{ + Q_Q(GlodonAbstractItemView); + Qt::DropAction dropAction = event->dropAction(); + + if (q->dragDropMode() == GlodonAbstractItemView::InternalMove) + { + dropAction = Qt::MoveAction; + } + + if (event->source() == q + && (Qt::MoveAction == (event->possibleActions() & Qt::MoveAction)) + && dropAction == Qt::MoveAction) + { + QModelIndexList selectedIndexes = q->selectedIndexes(); + QModelIndex child = index; + + while (child.isValid() && child != m_root) + { + if (selectedIndexes.contains(child)) + { + return true; + } + + child = child.parent(); + } + } + + return false; +} + +void GlodonAbstractItemView::dragLeaveEvent(QDragLeaveEvent *) +{ + Q_D(GlodonAbstractItemView); + stopAutoScroll(); + setState(NoState); + d->m_hover = QModelIndex(); + d->viewport->update(); +} + +void GlodonAbstractItemView::dropEvent(QDropEvent *event) +{ + Q_D(GlodonAbstractItemView); + + if (dragDropMode() == InternalMove) + { + if (event->source() != this || !(event->possibleActions() & Qt::MoveAction)) + { + return; + } + } + + QModelIndex index; + int col = -1; + int row = -1; + + if (d->dropOn(event, &row, &col, &index)) + { + if (d->m_model->dropMimeData(event->mimeData(), + dragDropMode() == InternalMove ? Qt::MoveAction : event->dropAction(), + row, col, index)) + { + if (dragDropMode() == InternalMove) + { + event->setDropAction(Qt::MoveAction); + } + + event->accept(); + } + } + + stopAutoScroll(); + setState(NoState); + d->viewport->update(); +} + +bool GlodonAbstractItemViewPrivate::dropOn(QDropEvent *event, int *dropRow, int *dropCol, QModelIndex *dropIndex) +{ + Q_Q(GlodonAbstractItemView); + + if (event->isAccepted()) + { + return false; + } + + QModelIndex index; + // rootIndex() (i.e. the viewport) might be a valid index + if (viewport->rect().contains(event->pos())) + { + index = q->indexAt(event->pos()); + if (!index.isValid() || !q->visualRect(index).contains(event->pos())) + { + index = m_root; + } + } + + // If we are allowed to do the drop + if (0 != (m_model->supportedDropActions() & event->dropAction())) + { + int row = -1; + int col = -1; + if (index != m_root) + { + m_dropIndicatorPosition = position(event->pos(), q->visualRect(index), index); + + switch (m_dropIndicatorPosition) + { + case GlodonAbstractItemView::AboveItem: + row = index.row(); + col = index.column(); + index = index.parent(); + break; + + case GlodonAbstractItemView::BelowItem: + row = index.row() + 1; + col = index.column(); + index = index.parent(); + break; + + case GlodonAbstractItemView::OnItem: + case GlodonAbstractItemView::OnViewport: + break; + } + } + else + { + m_dropIndicatorPosition = GlodonAbstractItemView::OnViewport; + } + + *dropIndex = index; + *dropRow = row; + *dropCol = col; + + if (!droppingOnItself(event, index)) + { + return true; + } + } + + return false; +} + +GlodonAbstractItemView::DropIndicatorPosition +GlodonAbstractItemViewPrivate::position(const QPoint &pos, const QRect &rect, const QModelIndex &index) const +{ + GlodonAbstractItemView::DropIndicatorPosition dropPosition = GlodonAbstractItemView::OnViewport; + + if (!m_bDragDropOverwrite) + { + const int c_margin = 2; + + if (pos.y() - rect.top() < c_margin) + { + dropPosition = GlodonAbstractItemView::AboveItem; + } + else if (rect.bottom() - pos.y() < c_margin) + { + dropPosition = GlodonAbstractItemView::BelowItem; + } + else if (rect.contains(pos, true)) + { + dropPosition = GlodonAbstractItemView::OnItem; + } + } + else + { + QRect touchingRect = rect; + touchingRect.adjust(-1, -1, 1, 1); + + if (touchingRect.contains(pos, false)) + { + dropPosition = GlodonAbstractItemView::OnItem; + } + } + + if (dropPosition == GlodonAbstractItemView::OnItem && (!(m_model->flags(index) & Qt::ItemIsDropEnabled))) + dropPosition + = pos.y() < rect.center().y() ? GlodonAbstractItemView::AboveItem : GlodonAbstractItemView::BelowItem; + + return dropPosition; +} + +bool GlodonAbstractItemViewPrivate::canDecode(QDropEvent *e) const +{ + QStringList modelTypes = m_model->mimeTypes(); + const QMimeData *mime = e->mimeData(); + + for (int i = 0; i < modelTypes.count(); ++i) + { + if (mime->hasFormat(modelTypes.at(i)) + && (Qt::IgnoreAction != (e->dropAction() & m_model->supportedDropActions()))) + { + return true; + } + } + + return false; +} + +void GlodonAbstractItemViewPrivate::paintDropIndicator(QPainter *painter) +{ + if (m_bShowDropIndicator && m_state == GlodonAbstractItemView::DraggingState + #ifndef QT_NO_CURSOR + && viewport->cursor().shape() != Qt::ForbiddenCursor + #endif + ) + { + QStyleOption opt; + opt.init(q_func()); + opt.rect = m_dropIndicatorRect; + q_func()->style()->drawPrimitive(QStyle::PE_IndicatorItemViewItemDrop, &opt, painter, q_func()); + } +} + +#endif // QT_NO_DRAGANDDROP + +void GlodonAbstractItemView::focusInEvent(QFocusEvent *event) +{ + Q_D(GlodonAbstractItemView); + QAbstractScrollArea::focusInEvent(event); + + const QItemSelectionModel *pSelectionModel = selectionModel(); + const bool c_bCurrentIndexValid = currentIndex().isValid(); + + // 第一次Show之前没有设置CurrentIndex时 + if (pSelectionModel && !d->m_bCurrentIndexSet && !c_bCurrentIndexValid) + { + bool bAutoScroll = d->m_bAutoScroll; + d->m_bAutoScroll = false; + + QModelIndex index = moveCursor(MoveNext, Qt::NoModifier); // first visible index + if (index.isValid() && d->isIndexEnabled(index) && event->reason() != Qt::MouseFocusReason) + { + selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate); + } + + d->m_bAutoScroll = bAutoScroll; + } + + if (pSelectionModel && c_bCurrentIndexValid) + { + if (currentIndex().flags() != Qt::ItemIsEditable) + { + setAttribute(Qt::WA_InputMethodEnabled, false); + } + else + { + setAttribute(Qt::WA_InputMethodEnabled); + } + } + + if (!c_bCurrentIndexValid) + { + setAttribute(Qt::WA_InputMethodEnabled, false); + } + + d->viewport->update(); +} + +void GlodonAbstractItemView::focusOutEvent(QFocusEvent *event) +{ + Q_D(GlodonAbstractItemView); + QAbstractScrollArea::focusOutEvent(event); + d->viewport->update(); + +#ifdef QT_SOFTKEYS_ENABLED + + if (!hasEditFocus()) + { + removeAction(d->doneSoftKey); + } + +#endif +} + +void GlodonAbstractItemView::keyPressEvent(QKeyEvent *event) +{ + Q_D(GlodonAbstractItemView); + d->m_delayedAutoScroll.stop(); //any interaction with the view cancel the auto scrolling + +#ifdef QT_KEYPAD_NAVIGATION + dealWithKeyPadNavigation(event); +#endif + +#if !defined(QT_NO_CLIPBOARD) && !defined(QT_NO_SHORTCUT) + // TODO wangdd-a这里之前是处理复制粘贴的,我们为了自己控制是否允许复制粘贴,先不在这里处理复制粘贴了 + // 后面需要看看复制粘贴是不是有必要重新实现 +#endif + + d->m_moveCursorUpdatedView = false; + + QPersistentModelIndex oNewCurrent = getNewCurrentAccordingToKeyPressOperation(event); + if (setNewCurrentSelection(event, oNewCurrent)) + return; + + dealWithEventAcception(event); +} + +void GlodonAbstractItemView::resizeEvent(QResizeEvent *event) +{ + QAbstractScrollArea::resizeEvent(event); + updateGeometries(); +} + +/*! + This function is called with the given \a event when a timer event is sent + to the widget. + + \sa QObject::timerEvent() +*/ +void GlodonAbstractItemView::timerEvent(QTimerEvent *event) +{ + Q_D(GlodonAbstractItemView); + + if (event->timerId() == d->m_fetchMoreTimer.timerId()) + { + d->fetchMore(); + } + else if (event->timerId() == d->m_delayedReset.timerId()) + { + reset(); + } + else if (event->timerId() == d->m_autoScrollTimer.timerId()) + { + doAutoScroll(); + } + else if (event->timerId() == d->m_updateTimer.timerId()) + { + d->updateDirtyRegion(); + } + else if (d->m_delayedShowToolTip.timerId() == event->timerId()) + { + showCurIndexToolTip(); + d->m_delayedShowToolTip.stop(); + } + else if (event->timerId() == d->m_delayedLayout.timerId()) + { + d->m_delayedLayout.stop(); + doLayoutAndScroll(); + } + else if (event->timerId() == d->m_delayedAutoScroll.timerId()) + { + d->m_delayedAutoScroll.stop(); + + //end of the timer: if the current item is still the same as the one when the mouse press occurred + //we only get here if there was no double click + if (d->m_pressedIndex.isValid() && d->m_pressedIndex == currentIndex()) + { + scrollTo(d->m_pressedIndex); + } + } +} + +void GlodonAbstractItemView::inputMethodEvent(QInputMethodEvent *event) +{ + if (event->commitString().isEmpty() && event->preeditString().isEmpty()) + { + event->ignore(); + return; + } + + if (!edit(currentIndex(), AnyKeyPressed, event)) + { + if (!event->commitString().isEmpty()) + { + keyboardSearch(event->commitString()); + } + + event->ignore(); + } +} + +#ifndef QT_NO_DRAGANDDROP + +GlodonAbstractItemView::DropIndicatorPosition GlodonAbstractItemView::dropIndicatorPosition() const +{ + Q_D(const GlodonAbstractItemView); + return d->m_dropIndicatorPosition; +} + +#endif + +void GlodonAbstractItemView::doGMFirst(GLDEvent *event) +{ + moveCursor(MoveHome, Qt::ControlModifier); + G_UNUSED(event); +} + +void GlodonAbstractItemView::doGMQueryFirst(GLDEvent *event) +{ + event->setResult(currentIndex().row() != 0); + G_UNUSED(event); +} + +void GlodonAbstractItemView::doGMPrev(GLDEvent *event) +{ + moveCursor(MoveUp, Qt::NoModifier); + G_UNUSED(event); +} + +void GlodonAbstractItemView::doGMQueryPrev(GLDEvent *event) +{ + doGMQueryFirst(event); + G_UNUSED(event); +} + +void GlodonAbstractItemView::doGMNext(GLDEvent *event) +{ + moveCursor(MoveDown, Qt::NoModifier); + G_UNUSED(event); +} + +void GlodonAbstractItemView::doGMQueryNext(GLDEvent *event) +{ + doGMQueryLast(event); + G_UNUSED(event); +} + +void GlodonAbstractItemView::doGMLast(GLDEvent *event) +{ + moveCursor(MoveEnd, Qt::ControlModifier); + G_UNUSED(event); +} + +void GlodonAbstractItemView::doGMQueryLast(GLDEvent *event) +{ + Q_D(GlodonAbstractItemView); + event->setResult(currentIndex().row() != d->m_model->rowCount(d->m_root) - 1); + G_UNUSED(event); +} + +void GlodonAbstractItemView::doGMSetSel(GLDEvent *event) +{ + selectAll(); + G_UNUSED(event); +} + +void GlodonAbstractItemView::doGMQuerySetSel(GLDEvent *event) +{ + Q_D(GlodonAbstractItemView); + event->setResult(d->m_bAllowSelectAll); + G_UNUSED(event); +} + +void GlodonAbstractItemView::doGMSetColRow(GLDEvent *event) +{ + Q_D(GlodonAbstractItemView); + int col = event->lParam(); + int row = event->wParam(); + QModelIndex index = d->m_model->index(row, col, d->m_root); + setCurrentIndex(index); + G_UNUSED(event); +} + +// 控制Editor的通用Actions,例如:对Edior的复制,粘贴,剪切,删除等操作的Action +void GlodonAbstractItemView::controlEditorNormalActions(const QModelIndex &index) +{ + Q_D(GlodonAbstractItemView); + + GlodonDefaultItemDelegate *pGlodonDelegate = d->delegateForIndex(index); + if (pGlodonDelegate == NULL) + { + return; + } + + bool bReadOnly = false; + GEditStyle edtStyle = pGlodonDelegate->editStyle(pGlodonDelegate->dataIndex(index), bReadOnly); + QWidget *pEditor = pGlodonDelegate->curEditor(); + if (NULL != pEditor + && !(edtStyle == esVectorGraph + || edtStyle == esBool + || edtStyle == esLineWidthList + || edtStyle == esFontList + || edtStyle == esColorList + || edtStyle == esImage + || edtStyle == esNone)) + { + setEditorActSignals(pEditor); + resetActAvailable(pEditor); + } +} + +void GlodonAbstractItemView::setEditorActSignals(QWidget *editor) +{ + if (connectEditorSignal(editor, "copyAvailable(bool)", + this, "doEditorCopyAvailable(bool)")) + { + doNothingMacro(); + } + else + { + if (connectEditorSignal(editor, "cursorPositionChanged()", + this, "doCursorPositionChanged()")) + { + doNothingMacro(); + } + else if (connectEditorSignal(editor, "cursorPositionChanged(int, int)", + this, "doCursorPositionChanged(int, int)")) + { + doNothingMacro(); + } + + if (connectEditorSignal(editor, "selectionChanged()", + this, "doSelectionChanged()")) + { + doNothingMacro(); + } + } + + if (connectEditorSignal(this, "onEditorCopy()", + editor, "copy()")) + { + doNothingMacro(); + } + + if (connectEditorSignal(this, "onEditorCut()", + editor, "cut()")) + { + doNothingMacro(); + } + + if (connectEditorSignal(this, "onEditorPaste()", + editor, "paste()")) + { + doNothingMacro(); + } + + if (connectEditorSignal(this, "onEditorDelete()", + editor, "deleteSelectedText()")) + { + doNothingMacro(); + } +} + +bool GlodonAbstractItemView::connectEditorSignal(QWidget *sender, const char *signalName, + QWidget *receiver, const char *slotName) +{ + int nSignalIndex = sender->metaObject()->indexOfSignal(signalName); + int nSlotIndex = receiver->metaObject()->indexOfSlot(slotName); + + if (nSignalIndex != -1 && nSlotIndex != -1) + { + this->metaObject()->connect(sender, nSignalIndex, receiver, nSlotIndex); + return true; + } + + return false; +} + +bool GlodonAbstractItemView::editorHasSelText(QWidget *editor) +{ + int nPropertyIndex = editor->metaObject()->indexOfProperty("hasSelectedText"); + + if (nPropertyIndex != -1) + { + QMetaProperty meta = editor->metaObject()->property(nPropertyIndex); + return meta.read(editor).toBool(); + } + + return false; +} + +bool GlodonAbstractItemView::editorReadOnly(QWidget *editor) +{ + int nReadOnlyIndex = editor->metaObject()->indexOfProperty("readOnly"); + + if (nReadOnlyIndex != -1) + { + QMetaProperty meta = editor->metaObject()->property(nReadOnlyIndex); + return meta.read(editor).toBool(); + } + + return false; +} + +void GlodonAbstractItemView::resetActAvailable(QWidget *editor) +{ + if (editor == NULL) + { + return; + } + + bool bHasSelText = editorHasSelText(editor); + emit onEditorCanCopy(bHasSelText); + + bool bIsROnly = editorReadOnly(editor); + emit onEditorCanDelete(!bIsROnly); + emit onEditorCanCut(bHasSelText && !bIsROnly); + + bool bHasClip = qApp->clipboard()->text().isEmpty(); + emit onEditorCanPaste(!bIsROnly && !bHasClip); +} + +void GlodonAbstractItemView::disableEditorActions() +{ + emit onEditorCanCopy(false); + emit onEditorCanDelete(false); + emit onEditorCanCut(false); + emit onEditorCanPaste(false); +} + +bool GlodonAbstractItemView::isComment(const QPersistentModelIndex &index) +{ + GString commentText = model()->data(index, gidrCommentRole).toString(); + return !commentText.isEmpty(); +} + +/*! + This convenience function returns a list of all selected and + non-hidden item indexes in the view. The list contains no + duplicates, and is not sorted. + + \sa QItemSelectionModel::selectedIndexes() +*/ +QModelIndexList GlodonAbstractItemView::selectedIndexes() const +{ + Q_D(const GlodonAbstractItemView); + QModelIndexList indexes; + + if (d->m_selectionModel) + { + indexes = d->m_selectionModel->selectedIndexes(); + QList::iterator it = indexes.begin(); + + while (it != indexes.end()) + { + if (isIndexHidden(*it)) + { + it = indexes.erase(it); + } + else + { + ++it; + } + } + } + + return indexes; +} + +bool GlodonAbstractItemView::edit(const QModelIndex &index, EditTrigger trigger, QEvent *event) +{ + Q_D(GlodonAbstractItemView); + + if (!d->isIndexValid(index)) + { + return false; + } + + QWidget *pIndexWidget = (d->m_persistent.isEmpty() ? static_cast(0) : d->editorForIndex(index).widget.data()); + + if (pIndexWidget != NULL) + { + if (pIndexWidget->focusPolicy() == Qt::NoFocus) + { + return false; + } + + pIndexWidget->setFocus(); + + return true; + } + + if (trigger == DoubleClicked) + { + d->m_delayedAutoScroll.stop(); + } + + if (d->sendDelegateEvent(index, event)) + { + update(index); + return true; + } + + // save the previous trigger before updating + EditTriggers lastTrigger = d->m_lastTrigger; + d->m_lastTrigger = trigger; + + if (!d->shouldEdit(trigger, d->m_model->buddy(index))) + { + return false; + } + + // we will receive a mouseButtonReleaseEvent after a + // mouseDoubleClickEvent, so we need to check the previous trigger + if (lastTrigger == DoubleClicked && trigger == SelectedClicked) + { + return false; + } + + // we may get a double click event later + if (trigger == SelectedClicked) + { + edit(index); + return true; + } + else + { + if (d->openEditor(index, d->shouldForwardEvent(trigger, event) ? event : 0)) + { + emit isInEditing(true); + controlEditorNormalActions(index); + return true; + } + } + + return false; +} + +void GlodonAbstractItemView::updateEditorData() +{ + Q_D(GlodonAbstractItemView); + d->updateEditorData(QModelIndex(), QModelIndex()); +} + +/*! + \internal + Updates the geometry of the open editor widgets in the view. +*/ +void GlodonAbstractItemView::updateEditorGeometries() +{ + Q_D(GlodonAbstractItemView); + + if (d->m_editorIndexHash.isEmpty()) + { + return; + } + + QStyleOptionViewItem option = d->viewOptionsV4(); + GEditorIndexHash::iterator it = d->m_editorIndexHash.begin(); + QWidgetList oEditorToReleaseList; + QWidgetList oEditorToHideList; + + while (it != d->m_editorIndexHash.end()) + { + QModelIndex oIndex = it.value(); + QWidget *pEditor = it.key(); + if (oIndex.isValid() && pEditor) + { + option.rect = visualRect(oIndex); + if (option.rect.isValid()) + { + pEditor->show(); + GlodonDefaultItemDelegate *pIndexDelegate = d->delegateForIndex(oIndex); + if (pIndexDelegate) + { + pIndexDelegate->updateEditorGeometry(pEditor, option, oIndex); + } + } + else + { + oEditorToHideList << pEditor; + } + ++it; + } + else + { + d->m_indexEditorHash.remove(it.value()); + it = d->m_editorIndexHash.erase(it); + oEditorToReleaseList << pEditor; + } + } + + //we hide and release the editor outside of the loop because it might change the focus and try + //to change the editors hashes. + for (int i = 0; i < oEditorToHideList.count(); ++i) + { + oEditorToHideList.at(i)->hide(); + } + + for (int i = 0; i < oEditorToReleaseList.count(); ++i) + { + d->releaseEditor(oEditorToReleaseList.at(i)); + } +} + +void GlodonAbstractItemView::updateGeometries() +{ + updateEditorGeometries(); + d_func()->m_fetchMoreTimer.start(0, this); //fetch more later +} + +void GlodonAbstractItemView::verticalScrollbarValueChanged(int value) +{ + Q_D(GlodonAbstractItemView); + + if (verticalScrollBar()->maximum() == value && d->m_model->canFetchMore(d->m_root)) + { + d->m_model->fetchMore(d->m_root); + } + + QPoint posInVp = viewport()->mapFromGlobal(QCursor::pos()); + + if (viewport()->rect().contains(posInVp)) + { + d->checkMouseMove(posInVp); + } +} + +void GlodonAbstractItemView::syncStateToDelegate(GlodonDefaultItemDelegate *delegate) +{ + Q_D(GlodonAbstractItemView); + delegate->setIncludeLeading(d->m_bGridTextIncludeLeading); +} + +void GlodonAbstractItemView::installEventFilterWidthEdit(QWidget *widget, GlodonDefaultItemDelegate *delegate) +{ + if (QAbstractScrollArea *pScrollArea = dynamic_cast(widget)) + { + pScrollArea->viewport()->installEventFilter(delegate); + } + else if (GLDWindowComboBox *pComboBox = dynamic_cast(widget)) + { + if (pComboBox && pComboBox->getLineEdit()) + { + pComboBox->getLineEdit()->installEventFilter(delegate); + } + } + else if (GLDWindowComboBoxEx *pComboBox = dynamic_cast(widget)) + { + if (pComboBox && pComboBox->getLineEdit()) + { + pComboBox->getLineEdit()->viewport()->installEventFilter(delegate); + } + } + else if (GLDCustomComboBox *pComboBox = dynamic_cast(widget)) + { + if (pComboBox && (pComboBox->lineEdit() != NULL)) + { + pComboBox->lineEdit()->installEventFilter(delegate); + } + } +} + +void GlodonAbstractItemView::dealWithSelectionAndAutoScroll(QModelIndex index, QMouseEvent *event) +{ + Q_D(GlodonAbstractItemView); + + QPoint pos = event->pos(); + + // 以下都在处理SelectionModel,并将可选中的Index滚出来 + d->m_pressedAlreadySelected = d->m_selectionModel->isSelected(index); + d->m_pressedIndex = index; + d->m_pressedModifiers = event->modifiers(); + + QItemSelectionModel::SelectionFlags command = selectionCommand(index, event); + if (command == QItemSelectionModel::NoUpdate) + { + d->m_noSelectionOnMousePress = true; + } + else + { + d->m_noSelectionOnMousePress = false; + } + + QPoint offset = d->offset(); + + // 如果index即将被设置为Current,需要更新pressedPosition + if ((command & QItemSelectionModel::Current) == 0) + { + d->m_pressedPosition = pos + offset; + } + // 下面这个分支不知道啥时候会进来,看样子是下面的意思: + // 如果index不会即将被设置为Current + // 但是由于滚动之类的,导致通过m_pressedPosition获取的Index无效了,则需要重新设置 + else if (!indexAt(d->m_pressedPosition - offset).isValid()) + { + d->m_pressedPosition = visualRect(currentIndex()).center() + offset; + } + + if (d->isIndexEnabled(index) + && (cursor().shape() == Qt::ArrowCursor + || cursor().shape() == Qt::PointingHandCursor)) + { + if (command.testFlag(QItemSelectionModel::Toggle)) + { + command &= ~QItemSelectionModel::Toggle; + d->m_ctrlDragSelectionFlag = d->m_selectionModel->isSelected(index) ? QItemSelectionModel::Deselect : QItemSelectionModel::Select; + command |= d->m_ctrlDragSelectionFlag; + + if ((d->m_selectionMode != SingleSelection) || (d->m_selectionMode != NoSelection)) + { + d->m_bIsInMultiSelect = true; + } + } + else + { + d->m_bIsInMultiSelect = false; + } + + // we disable scrollTo for mouse press so the item doesn't change position + // when the user is interacting with it (ie. clicking on it) + bool bAutoScroll = d->m_bAutoScroll; + d->m_bAutoScroll = false; + // 给外部判断时机,决定是否可以改变焦点格子 + bool bShouldSelect = moveCurrent(currentIndex(), index, command, mrMouse); + d->m_bAutoScroll = bAutoScroll; + + if (bShouldSelect) + { + QRect rect(d->m_pressedPosition - offset, pos); + setSelection(rect, command); + } + + // signal handlers may change the model + emit pressed(index); + + if (d->m_bAutoScroll) + { + //we delay the autoscrolling to filter out double click event + //100 is to be sure that there won't be a double-click misinterpreted as a 2 single clicks + d->m_delayedAutoScroll.start(QApplication::doubleClickInterval() + 100, this); + } + } + else + { + // Forces a finalize() even if mouse is pressed, but not on a item + d->m_selectionModel->select(QModelIndex(), QItemSelectionModel::Select); + } +} + +#ifdef QT_KEYPAD_NAVIGATION +void GlodonAbstractItemView::dealWithKeyPadNavigation(QKeyEvent *event) +{ + Q_D(GlodonAbstractItemView); + switch (event->key()) + { + case Qt::Key_Select: + if (QApplication::keypadNavigationEnabled()) + { + if (!hasEditFocus()) + { + setEditFocus(true); + return; + } + } + break; + case Qt::Key_Back: + if (QApplication::keypadNavigationEnabled() && hasEditFocus()) + { + setEditFocus(false); + } + else + { + event->ignore(); + } + return; + case Qt::Key_Down: + case Qt::Key_Up: + // Let's ignore vertical navigation events, only if there is no other widget + // what can take the focus in vertical direction. This means widget can handle navigation events + // even the widget don't have edit focus, and there is no other widget in requested direction. + if (QApplication::keypadNavigationEnabled() && !hasEditFocus() + && QWidgetPrivate::canKeypadNavigate(Qt::Vertical)) + { + event->ignore(); + return; + } + break; + case Qt::Key_Left: + case Qt::Key_Right: + // Similar logic as in up and down events + if (QApplication::keypadNavigationEnabled() && !hasEditFocus() + && (QWidgetPrivate::canKeypadNavigate(Qt::Horizontal) || QWidgetPrivate::inTabWidget(this))) + { + event->ignore(); + return; + } + break; + default: + if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) + { + event->ignore(); + return; + } + } +} +#endif + +QPersistentModelIndex GlodonAbstractItemView::getNewCurrentAccordingToKeyPressOperation(QKeyEvent *event) +{ + Q_D(GlodonAbstractItemView); + + QPersistentModelIndex oNewCurrent; + switch (event->key()) + { + case Qt::Key_Down: + { + oNewCurrent = moveCursor(MoveDown, event->modifiers()); + break; + } + case Qt::Key_Up: + { + oNewCurrent = moveCursor(MoveUp, event->modifiers()); + break; + } + case Qt::Key_Left: + { + oNewCurrent = moveCursor(MoveLeft, event->modifiers()); + break; + } + case Qt::Key_Right: + { + oNewCurrent = moveCursor(MoveRight, event->modifiers()); + break; + } + case Qt::Key_Home: + { + oNewCurrent = moveCursor(MoveHome, event->modifiers()); + break; + } + case Qt::Key_End: + { + oNewCurrent = moveCursor(MoveEnd, event->modifiers()); + break; + } + case Qt::Key_PageUp: + { + oNewCurrent = moveCursor(MovePageUp, event->modifiers()); + scrollToNewCurrent(event, oNewCurrent); + break; + } + case Qt::Key_PageDown: + { + oNewCurrent = moveCursor(MovePageDown, event->modifiers()); + scrollToNewCurrent(event, oNewCurrent); + break; + } + case Qt::Key_Tab: + { + if (d->m_bTabKeyNavigation) + { + oNewCurrent = moveCursor(MoveNext, event->modifiers()); + } + break; + } + case Qt::Key_Backtab: + { + if (d->m_bTabKeyNavigation) + { + oNewCurrent = moveCursor(MovePrevious, event->modifiers()); + } + break; + } + } + return oNewCurrent; +} + +bool GlodonAbstractItemView::setNewCurrentSelection(QKeyEvent *event, QPersistentModelIndex oNewCurrent) +{ + Q_D(GlodonAbstractItemView); + + QPersistentModelIndex oOldCurrent = currentIndex(); + + if (!oNewCurrent.isValid() || oNewCurrent == oOldCurrent || !d->isIndexEnabled(oNewCurrent)) + return false; + + // TODO liurx 以下代码比较诡异,需要详细测试决定是否需要 +// // 如果编辑方式是Ellipsis的时候,focusWidget永远都是QlineEdit,indexWidget(oldCurrent)是GLDLineButtonEdit +// // 在此只应该判断newCurrent与oldCurrent是否是一个 +// if (!hasFocus()) +// { +// commitData(indexWidget(oOldCurrent)); + +// if (isLegalData()) +// { +// setFocus(); +// } +// else +// { +// return; +// } +// } + + QItemSelectionModel::SelectionFlags command = selectionCommand(oNewCurrent, event); + + if (command == QItemSelectionModel::NoUpdate + && 0 == style()->styleHint(QStyle::SH_ItemView_MovementWithoutUpdatingSelection, 0, this)) + return false; + + // note that we don't check if the new current index is enabled because moveCursor() makes sure it is + if (command & QItemSelectionModel::Current) + { + bool bShouldSelect = moveCurrent(currentIndex(), oNewCurrent, command, mrKey); + + if (!indexAt(d->m_pressedPosition - d->offset()).isValid()) + { + d->m_pressedPosition = visualRect(oOldCurrent).center() + d->offset(); + } + + if (bShouldSelect) + { + QRect rect(d->m_pressedPosition - d->offset(), visualRect(oNewCurrent).center()); + setSelection(rect, command); + } + } + else + { + //当按着Control键时,如有选择区域的改变,则也会重新设置选择区域 + if (event->modifiers() & Qt::ControlModifier) + { + command |= QItemSelectionModel::ClearAndSelect; + } + + bool bShouldSelect = moveCurrent(currentIndex(), oNewCurrent, command, mrKey); + d->m_pressedPosition = visualRect(oNewCurrent).center() + d->offset(); + + if (oNewCurrent.isValid() && bShouldSelect) + { + // We copy the same behaviour as for mousePressEvent(). + QRect rect(d->m_pressedPosition - d->offset(), QSize(1, 1)); + setSelection(rect, command); + } + } + + event->accept(); + return true; +} + +void GlodonAbstractItemView::scrollToNewCurrent(QKeyEvent *event, QPersistentModelIndex &oNewCurrent) +{ + if (Qt::ControlModifier == (event->modifiers() & Qt::ControlModifier)) + { + scrollTo(oNewCurrent, EnsureVisible); + } + else + { + scrollTo(oNewCurrent, PositionAtBottom); + } +} + +void GlodonAbstractItemView::dealWithEventAcception(QKeyEvent *event) +{ + Q_D(GlodonAbstractItemView); + + switch (event->key()) + { + // ignored keys + case Qt::Key_Down: + case Qt::Key_Up: +#ifdef QT_KEYPAD_NAVIGATION + if (QApplication::keypadNavigationEnabled() && QWidgetPrivate::canKeypadNavigate(Qt::Vertical)) + { + event->accept(); // don't change focus + break; + } + +#endif + case Qt::Key_Left: + case Qt::Key_Right: +#ifdef QT_KEYPAD_NAVIGATION + if (QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional + && (QWidgetPrivate::canKeypadNavigate(Qt::Horizontal) + || (QWidgetPrivate::inTabWidget(this) && d->model->columnCount(d->root) > 1))) + { + event->accept(); // don't change focus + break; + } +#endif // QT_KEYPAD_NAVIGATION + case Qt::Key_Home: + case Qt::Key_End: + case Qt::Key_PageUp: + case Qt::Key_PageDown: + case Qt::Key_Escape: + case Qt::Key_Shift: + case Qt::Key_Control: + case Qt::Key_Delete: + case Qt::Key_Backspace: + event->ignore(); + break; + case Qt::Key_Space: + case Qt::Key_Select: + if (!edit(currentIndex(), AnyKeyPressed, event) && d->m_selectionModel) + { + d->m_selectionModel->select(currentIndex(), selectionCommand(currentIndex(), event)); + } +#ifdef QT_KEYPAD_NAVIGATION + if (event->key() == Qt::Key_Select) + { + // Also do Key_Enter action. + if (currentIndex().isValid()) + { + if (state() != EditingState) + { + emit activated(currentIndex()); + } + } + else + { + event->ignore(); + } + } +#endif + break; +#ifdef Q_WS_MAC + case Qt::Key_Enter: + case Qt::Key_Return: + // Propagate the enter if you couldn't edit the item and there are no + // current editors (if there are editors, the event was most likely propagated from it). + if (!edit(currentIndex(), EditKeyPressed, event) && d->editorIndexHash.isEmpty()) + { + event->ignore(); + } + break; +#else + case Qt::Key_F2: + if (edit(currentIndex(), EditKeyPressed, event)) + { + QWidget *editor = dynamic_cast(d->editorForIndex(currentIndex()).widget.data()); + if (editor && editor->hasFocus()) + { + QCoreApplication::sendEvent(editor, event); + } + } + else + { + event->ignore(); + } + break; + case Qt::Key_Enter: + case Qt::Key_Return: + // ### we can't open the editor on enter, becuse + // some widgets will forward the enter event back + // to the viewport, starting an endless loop + if (state() != EditingState || hasFocus()) + { + if (currentIndex().isValid()) + { + emit activated(currentIndex()); + } + event->ignore(); + } + break; +#endif + case Qt::Key_A: + if (event->modifiers() & Qt::ControlModifier) + { + selectAll(); + break; + } + default: + { +#ifdef Q_WS_MAC + if (event->key() == Qt::Key_O && event->modifiers() & Qt::ControlModifier && currentIndex().isValid()) + { + emit activated(currentIndex()); + break; + } +#endif + bool bModified = event->modifiers() & (Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier); + if (!event->text().isEmpty() && !bModified && !edit(currentIndex(), AnyKeyPressed, event) && d->m_isSearchModel) + { + keyboardSearch(event->text()); + event->accept(); + } + else + { + event->ignore(); + } + break; + } + } + + if (d->m_moveCursorUpdatedView) + { + event->accept(); + } +} + +void GlodonAbstractItemView::setSelectionAndScrollToOnMouseMove( + const QModelIndex &oCurIndex, QMouseEvent *event, const QPoint &oPrePoint, const QPoint &oCurPoint) +{ + Q_D(GlodonAbstractItemView); + + if (event->buttons() & Qt::LeftButton && d->selectionAllowed(oCurIndex) && d->m_selectionModel) + { + setState(DragSelectingState); + QItemSelectionModel::SelectionFlags command = selectionCommand(oCurIndex, event); + + if (d->m_ctrlDragSelectionFlag != QItemSelectionModel::NoUpdate + && command.testFlag(QItemSelectionModel::Toggle)) + { + command &= ~QItemSelectionModel::Toggle; + command |= d->m_ctrlDragSelectionFlag; + } + + // Do the normalize ourselves, since QRect::normalized() is flawed + QRect selectionRect = QRect(oPrePoint, oCurPoint); + setSelection(selectionRect, command); + + // set at the end because it might scroll the view + if (oCurIndex.isValid() + && (oCurIndex != d->m_selectionModel->currentIndex()) + && d->isIndexEnabled(oCurIndex)) + { + //不改变当前选择区域的焦点,且能使滚动条在适当的时机滚动 + if (!d->m_autoScrollTimer.isActive()) + { + if (d->m_bAutoScroll) + { + // 最后一列和一行是需要滚出来的,固定行列是需要滚动的 + scrollTo(oCurIndex); + } + + update(oCurIndex); + + // 乐观预计,可能支持懒加载。。。。 + if (oCurIndex.row() == (d->m_model->rowCount(d->m_root) - 1)) + { + d->fetchMore(); + } + } + } + } +} + +void GlodonAbstractItemView::showCurIndexToolTip() +{ + Q_D(GlodonAbstractItemView); + + QPoint oCurLocalPos = d->viewport->mapFromGlobal(QCursor::pos()); + //QPoint localPt = QCursor::pos(); + QPersistentModelIndex oCurIndex = indexAt(oCurLocalPos); + + // TODO wangdd-a,批注框和ToolTip是互斥的 + // 修改批注框的时候,仔细看一下,基类不应该关心子类的功能,看能不能移到子类 + if (isComment(oCurIndex) || !d->m_pToolTipFrame) + { + return; + } + + oCurLocalPos = d->viewport->mapToGlobal(oCurLocalPos); + //frame本来应该在自己的位置显示,通过外部来调节,但由于目前其他代码可能用到,没办法更改了。 + //现在frame在移动的时候,x增加35,y增加45,所以这里通过外部重新计算frame的合适位置 + int nCurPosY = oCurLocalPos.y() - 45; + QWidget *pCurWidget = QApplication::widgetAt(QCursor::pos()); + + //当刚刚获得焦点的时候,可能获得不到widget. + if (pCurWidget == NULL) + { + return; + } + + Qt::CursorShape cursorShpae = pCurWidget->cursor().shape(); + + // TODO wangdd-a,不知道这些数字是啥。。。 + if (cursorShpae == Qt::IBeamCursor) + { + nCurPosY += 10; + } + else + { + nCurPosY += 20; + } + + oCurLocalPos.setX(oCurLocalPos.x() - 35); + oCurLocalPos.setY(nCurPosY); + d->m_pToolTipFrame->move(oCurLocalPos); + QCoreApplication::processEvents(); + + QVariant hintContent = oCurIndex.data(Qt::ToolTipRole); + d->m_pToolTipFrame->setHintText(hintContent.isNull() && d->m_bShowIndexContent ? + oCurIndex.data().toString() : hintContent.toString()); +} + +void GlodonAbstractItemView::doLayoutAndScroll() +{ + Q_D(GlodonAbstractItemView); + + if (!isVisible()) + { + return; + } + + d->interruptDelayedItemsLayout(); + doItemsLayout(); + const QModelIndex c_current = currentIndex(); + + if (c_current.isValid() && d->m_state == GlodonAbstractItemView::EditingState) + { + scrollTo(c_current); + } +} + +void GlodonAbstractItemView::scrollVerticalScrollBar(int nVerticalValue, QScrollBar *verticalScroll) +{ + Q_D(GlodonAbstractItemView); + + int nMargin = d->m_nAutoScrollMargin; + QRect oClipRect = static_cast(d->viewport)->d_func()->clipRect(); + QPoint oCurGlobalPos = d->viewport->mapFromGlobal(QCursor::pos()); + + if (oCurGlobalPos.y() - oClipRect.top() < nMargin) + { + verticalScroll->setValue(nVerticalValue - d->m_autoScrollCount); + } + else if (oClipRect.bottom() - oCurGlobalPos.y() < nMargin) + { + verticalScroll->setValue(nVerticalValue + d->m_autoScrollCount); + } +} + +void GlodonAbstractItemView::scrollHorizontalScrollBar(int nHorizontalValue, QScrollBar *horizontalScroll) +{ + Q_D(GlodonAbstractItemView); + + int nMargin = d->m_nAutoScrollMargin; + QRect oClipRect = static_cast(d->viewport)->d_func()->clipRect(); + QPoint oCurGlobalPos = d->viewport->mapFromGlobal(QCursor::pos()); + + if (oCurGlobalPos.x() - oClipRect.left() < nMargin) + { + horizontalScroll->setValue(nHorizontalValue - d->m_autoScrollCount); + } + else if (oClipRect.right() - oCurGlobalPos.x() < nMargin) + { + horizontalScroll->setValue(nHorizontalValue + d->m_autoScrollCount); + } +} + +void GlodonAbstractItemView::removeNonPersistentEditor(QWidget *editor) +{ + Q_D(GlodonAbstractItemView); + + bool bPersistent = d->m_persistent.contains(editor); + if (bPersistent) + { + return; + } + + setState(NoState); + QModelIndex oEditorIndex = d->indexForEditor(editor); + editor->removeEventFilter(d->delegateForIndex(oEditorIndex)); + d->removeEditor(editor); + d->m_oEditorIndex = QModelIndex(); +} + +void GlodonAbstractItemView::setEditorFocus(QWidget *editor) +{ + Q_D(GlodonAbstractItemView); + + bool bHadFocus = editor->hasFocus(); + + if (bHadFocus) + { + setFocus(); // this will send a focusLost event to the editor + } + else + { + d->checkPersistentEditorFocus(); + } + + QPointer ed = editor; + QApplication::sendPostedEvents(editor, 0); + editor = ed; + + bool bPersistent = d->m_persistent.contains(editor); + + if (!bPersistent && editor) + { + d->releaseEditor(editor); + } +} + +void GlodonAbstractItemView::dealWithEndEditHint(GlodonDefaultItemDelegate::EndEditHint hint) +{ + Q_D(GlodonAbstractItemView); + + QItemSelectionModel::SelectionFlags flags = QItemSelectionModel::ClearAndSelect + | d->selectionBehaviorFlags(); + + switch (hint) + { + case GlodonDefaultItemDelegate::EditNextItem: + { + QModelIndex index = moveCursor(MoveNext, Qt::NoModifier); + + if (index.isValid()) + { + QPersistentModelIndex persistent(index); + moveCurrent(currentIndex(), persistent, flags, mrProgram); + } + + break; + } + + case GlodonDefaultItemDelegate::EditPreviousItem: + { + QModelIndex index = moveCursor(MovePrevious, Qt::NoModifier); + + if (index.isValid()) + { + QPersistentModelIndex persistent(index); + moveCurrent(currentIndex(), persistent, flags, mrProgram); + } + + break; + } + + case GlodonDefaultItemDelegate::SubmitModelCache: + { + d->m_model->submit(); + break; + } + + case GlodonDefaultItemDelegate::RevertModelCache: + { + d->m_model->revert(); + break; + } + + default: + break; + } +} + +void GlodonAbstractItemView::resetEditorFocus() +{ + Q_D(GlodonAbstractItemView); + + QWidget *widget = d->delegateForIndex(d->m_oEditorIndex)->curEditor(); + + if (widget && widget->isVisible()) + { + widget->setFocus(); + } +} + +void GlodonAbstractItemView::_q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end) +{ + d_func()->_q_columnsAboutToBeRemoved(parent, start, end); +} + +void GlodonAbstractItemView::_q_columnsRemoved(const QModelIndex &index, int start, int end) +{ + d_func()->_q_columnsRemoved(index, start, end); +} + +void GlodonAbstractItemView::_q_columnsInserted(const QModelIndex &index, int start, int end) +{ + d_func()->_q_columnsInserted(index, start, end); +} + +void GlodonAbstractItemView::_q_rowsInserted(const QModelIndex &index, int start, int end) +{ + d_func()->_q_rowsInserted(index, start, end); +} + +void GlodonAbstractItemView::_q_rowsRemoved(const QModelIndex &index, int start, int end) +{ + d_func()->_q_rowsRemoved(index, start, end); +} + +void GlodonAbstractItemView::_q_modelDestroyed() +{ + d_func()->_q_modelDestroyed(); +} + +void GlodonAbstractItemView::_q_layoutChanged() +{ + d_func()->_q_layoutChanged(); +} + +void GlodonAbstractItemView::_q_headerDataChanged() +{ + d_func()->_q_headerDataChanged(); +} + +void GlodonAbstractItemView::horizontalScrollbarValueChanged(int value) +{ + Q_D(GlodonAbstractItemView); + + if (horizontalScrollBar()->maximum() == value && d->m_model->canFetchMore(d->m_root)) + { + d->m_model->fetchMore(d->m_root); + } + + QPoint posInVp = viewport()->mapFromGlobal(QCursor::pos()); + + if (viewport()->rect().contains(posInVp)) + { + d->checkMouseMove(posInVp); + } +} + +void GlodonAbstractItemView::verticalScrollbarAction(int) +{ + //do nothing +} + +void GlodonAbstractItemView::horizontalScrollbarAction(int) +{ + //do nothing +} + +void GlodonAbstractItemView::closeEditor(QWidget *editor, bool &canCloseEditor, GlodonDefaultItemDelegate::EndEditHint hint) +{ + Q_UNUSED(canCloseEditor) + + Q_D(GlodonAbstractItemView); + + // TODO wangdd-a,觉得可以去掉 + // 使所有Editor的操作都变成disable + disableEditorActions(); + + // Close the editor + if (editor) + { + QModelIndex oEditorIndex = d->indexForEditor(editor); + + if (!oEditorIndex.isValid()) + { + return; // the editor was not registered + } + + removeNonPersistentEditor(editor); + setEditorFocus(editor); + emit isInEditing(false); + } + + // The EndEditHint part + dealWithEndEditHint(hint); +} + +void GlodonAbstractItemView::commitData(QWidget *editor, bool &canCloseEditor) +{ + Q_D(GlodonAbstractItemView); + + if (!editor || !d->m_itemDelegate || d->m_pCurCommittingEditor) + { + return; + } + + QModelIndex pEditorIndex = d->indexForEditor(editor); + + if(!pEditorIndex.isValid()) + { + return; + } + + GlodonDefaultItemDelegate *pDelegate = d->delegateForIndex(pEditorIndex); + editor->removeEventFilter(pDelegate); + + try + { + setModelData(pDelegate, editor, pEditorIndex, canCloseEditor); + setLegitimacyOfData(pDelegate, canCloseEditor); + } + catch(...) + { + editor->installEventFilter(pDelegate); + d->m_pCurCommittingEditor = NULL; + throw; + } + + editor->installEventFilter(pDelegate); + d->m_pCurCommittingEditor = NULL; +} + +void GlodonAbstractItemView::editorDestroyed(QObject *editor) +{ + Q_D(GlodonAbstractItemView); + QWidget *widgt = dynamic_cast(editor); + d->removeEditor(widgt); + d->m_persistent.remove(widgt); + + if (state() == EditingState) + { + setState(NoState); + } +} + +void GlodonAbstractItemView::doSelectionChanged() +{ + QWidget *editor = (QWidget *)this->sender(); + resetActAvailable(editor); +} + +void GlodonAbstractItemView::doEditorCopyAvailable(bool canCopy) +{ + QWidget *editor = (QWidget *)this->sender(); + + emit onEditorCanCopy(canCopy); + + bool breadOnly = editorReadOnly(editor); + emit onEditorCanCut(canCopy && !breadOnly); + emit onEditorCanDelete(canCopy && !breadOnly); + + bool bhasClip = qApp->clipboard()->text().isEmpty(); + emit onEditorCanPaste(!breadOnly && !bhasClip); +} + +void GlodonAbstractItemView::doCursorPositionChanged() +{ + QWidget *editor = (QWidget *)this->sender(); + resetActAvailable(editor); +} + +void GlodonAbstractItemView::doCursorPositionChanged(int, int) +{ + QWidget *editor = (QWidget *)this->sender(); + resetActAvailable(editor); +} + +void GlodonAbstractItemView::setHorizontalStepsPerItem(int steps) +{ + Q_UNUSED(steps) + // do nothing +} + +int GlodonAbstractItemView::horizontalStepsPerItem() const +{ + return 1; +} + +void GlodonAbstractItemView::setVerticalStepsPerItem(int steps) +{ + Q_UNUSED(steps) + // do nothing +} + +int GlodonAbstractItemView::verticalStepsPerItem() const +{ + return 1; +} + +bool GlodonAbstractItemView::moveCurrent(const QModelIndex &oldIndex, const QModelIndex &newIndex, + QItemSelectionModel::SelectionFlags command, + MoveReason moveReason) +{ + bool bCanMove = true; + beforeMoveCurrent(oldIndex, newIndex, command, moveReason, bCanMove); + + if (!bCanMove) + { + return bCanMove; + } + + doMoveCurrent(oldIndex, newIndex, command, moveReason); + afterMoveCurrent(oldIndex, newIndex, command, moveReason); + return bCanMove; +} + +void GlodonAbstractItemView::beforeMoveCurrent(const QModelIndex &oldIndex, const QModelIndex &newIndex, + QItemSelectionModel::SelectionFlags command, + MoveReason moveReason, bool &canMove) +{ + emit onbeforeMoveCurrent(oldIndex, newIndex, command, moveReason, canMove); +} + +void GlodonAbstractItemView::doMoveCurrent(const QModelIndex &oldIndex, const QModelIndex &newIndex, + QItemSelectionModel::SelectionFlags command, MoveReason moveReason) +{ + Q_D(GlodonAbstractItemView); + d->m_selectionModel->setCurrentIndex(newIndex, command); + + G_UNUSED(oldIndex); + G_UNUSED(moveReason); +} + +void GlodonAbstractItemView::afterMoveCurrent(const QModelIndex &oldIndex, const QModelIndex &newIndex, + QItemSelectionModel::SelectionFlags command, MoveReason moveReason) +{ + emit onAfterMoveCurrent(oldIndex, newIndex, command, moveReason); +} + +void GlodonAbstractItemView::keyboardSearch(const QString &search) +{ + Q_D(GlodonAbstractItemView); + + if (0 == d->m_model->rowCount(d->m_root) || 0 == d->m_model->columnCount(d->m_root)) + { + return; + } + + QModelIndex oStartIndex = currentIndex().isValid() ? currentIndex() + : d->m_model->index(0, 0, d->m_root); + bool bSkipRow = false; + bool bKeyboardTimeWasValid = d->m_keyboardInputTime.isValid(); + gint64 nKeyboardInputTimeElapsed = d->m_keyboardInputTime.restart(); + if (search.isEmpty() || !bKeyboardTimeWasValid + || nKeyboardInputTimeElapsed > QApplication::keyboardInputInterval()) + { + d->m_keyboardInput = search; + bSkipRow = currentIndex().isValid(); //if it is not valid we should really start at QModelIndex(0,0) + } + else + { + d->m_keyboardInput += search; + } + + // special case for searches with same key like 'aaaaa' + bool bsameKey = false; + if (d->m_keyboardInput.length() > 1) + { + int nCount = d->m_keyboardInput.count(d->m_keyboardInput.at(d->m_keyboardInput.length() - 1)); + bsameKey = (nCount == d->m_keyboardInput.length()); + if (bsameKey) + { + bSkipRow = true; + } + } + + // skip if we are searching for the same key or a new search started + if (bSkipRow) + { + QModelIndex parent = oStartIndex.parent(); + int newRow = (oStartIndex.row() < d->m_model->rowCount(parent) - 1) ? oStartIndex.row() + 1 : 0; + oStartIndex = d->m_model->index(newRow, oStartIndex.column(), parent); + } + + // search from start with wraparound + const QString c_strSearchString = bsameKey ? QString(d->m_keyboardInput.at(0)) : d->m_keyboardInput; + QModelIndex oCurrentIndex = oStartIndex; + QModelIndexList oMatchIndexList; + QModelIndex oFirstMatchIndex; + QModelIndex oStartMatchIndex; + QModelIndexList oPreviousIndexList; + + do + { + oMatchIndexList = d->m_model->match(oCurrentIndex, Qt::DisplayRole, c_strSearchString); + + if (oMatchIndexList == oPreviousIndexList) + { + break; + } + + oFirstMatchIndex = oMatchIndexList.value(0); + oPreviousIndexList = oMatchIndexList; + if (oFirstMatchIndex.isValid()) + { + if (d->isIndexEnabled(oFirstMatchIndex)) + { + setCurrentIndex(oFirstMatchIndex); + break; + } + + int row = oFirstMatchIndex.row() + 1; + if (row >= d->m_model->rowCount(oFirstMatchIndex.parent())) + { + row = 0; + } + + oCurrentIndex = oFirstMatchIndex.sibling(row, oFirstMatchIndex.column()); + //avoid infinite loop if all the matching items are disabled. + if (!oStartMatchIndex.isValid()) + { + oStartMatchIndex = oFirstMatchIndex; + } + else if (oStartMatchIndex == oFirstMatchIndex) + { + break; + } + } + } + while (oCurrentIndex != oStartIndex && oFirstMatchIndex.isValid()); +} + +QSize GlodonAbstractItemView::sizeHintForIndex(const QModelIndex &index) const +{ + Q_D(const GlodonAbstractItemView); + + if (!d->isIndexValid(index) || !d->m_itemDelegate) + { + return QSize(); + } + + return d->delegateForIndex(index)->sizeHint(d->viewOptionsV4(), index); +} + +int GlodonAbstractItemView::sizeHintForRow(int row) const +{ + Q_D(const GlodonAbstractItemView); + + if (row < 0 || row >= d->m_model->rowCount(d->m_root)) + { + return -1; + } + + ensurePolished(); + + int nHeight = 0; + + QModelIndex index; + + int nColCount = d->m_model->columnCount(d->m_root); + + for (int i = 0; i < nColCount; ++i) + { + index = d->m_model->index(row, i, d->m_root); + + if (QWidget *editor = d->editorForIndex(index).widget.data()) + { + nHeight = qMax(nHeight, editor->height()); + } + + int nHint = d->delegateForIndex(index)->sizeHint(d->viewOptionsV4(), index).height(); + nHeight = qMax(nHeight, nHint); + } + + return nHeight; +} + +int GlodonAbstractItemView::sizeHintForColumn(int column) const +{ + Q_D(const GlodonAbstractItemView); + + if (column < 0 || column >= d->m_model->columnCount(d->m_root)) + { + return -1; + } + + ensurePolished(); + + QStyleOptionViewItem option = d->viewOptionsV4(); + int nWidth = 0; + int nRows = d->m_model->rowCount(d->m_root); + QModelIndex index; + + for (int i = 0; i < nRows; ++i) + { + index = d->m_model->index(i, column, d->m_root); + + if (QWidget *editor = d->editorForIndex(index).widget.data()) + { + nWidth = qMax(nWidth, editor->sizeHint().width()); + } + + int nHint = d->delegateForIndex(index)->sizeHint(option, index).width(); + nWidth = qMax(nWidth, nHint); + } + + return nWidth; +} + +void GlodonAbstractItemView::openPersistentEditor(const QModelIndex &index) +{ + Q_D(GlodonAbstractItemView); + + QStyleOptionViewItem options = d->viewOptionsV4(); + options.rect = visualRect(index); + options.state |= (index == currentIndex() ? QStyle::State_HasFocus : QStyle::State_None); + + QWidget *editor = d->editor(index, options); + + if (editor) + { + editor->show(); + d->m_persistent.insert(editor); + } +} + +void GlodonAbstractItemView::closePersistentEditor(const QModelIndex &index) +{ + Q_D(GlodonAbstractItemView); + + if (QWidget *editor = d->editorForIndex(index).widget.data()) + { + if (index == selectionModel()->currentIndex()) + { + bool bCanCloseEditor = true; + closeEditor(editor, bCanCloseEditor, GlodonDefaultItemDelegate::RevertModelCache); + } + + d->m_persistent.remove(editor); + d->removeEditor(editor); + d->releaseEditor(editor); + } +} + +void GlodonAbstractItemView::setIndexWidget(const QModelIndex &index, QWidget *widget) +{ + Q_D(GlodonAbstractItemView); + + if (!d->isIndexValid(index)) + { + return; + } + + if (QWidget *oldWidget = indexWidget(index)) + { + d->m_persistent.remove(oldWidget); + d->removeEditor(oldWidget); + oldWidget->deleteLater(); + } + + if (widget) + { + widget->setParent(viewport()); + d->m_persistent.insert(widget); + d->addEditor(index, widget, true); + widget->show(); + dataChanged(index, index); // update the geometry + + if (!d->m_delayedPendingLayout) + { + widget->setGeometry(visualRect(index)); + } + } +} + +QWidget *GlodonAbstractItemView::indexWidget(const QModelIndex &index) const +{ + Q_D(const GlodonAbstractItemView); + + if (d->isIndexValid(index)) + { + if (QWidget *editor = d->editorForIndex(index).widget.data()) + { + return editor; + } + } + + return 0; +} + +void GlodonAbstractItemView::scrollToTop() +{ + verticalScrollBar()->setValue(verticalScrollBar()->minimum()); +} + +void GlodonAbstractItemView::scrollToBottom() +{ + Q_D(GlodonAbstractItemView); + + if (d->m_delayedPendingLayout) + { + d->executePostedLayout(); + updateGeometries(); + } + + verticalScrollBar()->setValue(verticalScrollBar()->maximum()); +} + +void GlodonAbstractItemView::update(const QModelIndex &index) +{ + Q_D(GlodonAbstractItemView); + + if (index.isValid()) + { + const QRect c_rect = visualRect(index); + + //this test is important for peformance reason + //For example in dataChanged we simply update all the cells without checking + //it can be a major bottleneck to update rects that aren't even part of the viewport + if (d->viewport->rect().intersects(c_rect)) + { + d->viewport->update(c_rect); + } + } +} + +bool GlodonAbstractItemView::commitDataAndCloseEditor() +{ + bool bCanCloseEditor = true; + doCommitDataAndCloseEditor(bCanCloseEditor); + + if (!bCanCloseEditor) + { + resetEditorFocus(); + } + + return bCanCloseEditor; +} + +void GlodonAbstractItemView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, + const QVector &roles) +{ + // Single item changed + G_UNUSED(roles); + Q_D(GlodonAbstractItemView); + + if (topLeft == bottomRight && topLeft.isValid()) + { + d->updateNoStaticEditorData(topLeft); + + if (isVisible() && !d->m_delayedPendingLayout) + { + // otherwise the items will be update later anyway + update(topLeft); + } + + return; + } + + d->updateEditorData(topLeft, bottomRight); + + if (!isVisible() || d->m_delayedPendingLayout) + { + return; // no need to update + } + + d->viewport->update(); +} + +void GlodonAbstractItemView::rowsInserted(const QModelIndex &, int, int) +{ + if (!isVisible()) + { + d_func()->m_fetchMoreTimer.start(0, this); //fetch more later + } + else + { + updateEditorGeometries(); + } +} + +void GlodonAbstractItemView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) +{ + Q_D(GlodonAbstractItemView); + + setState(CollapsingState); + + // Ensure one selected item in single selection mode. + QModelIndex current = currentIndex(); + + if (d->m_selectionMode == SingleSelection + && current.isValid() + && current.row() >= start + && current.row() <= end + && current.parent() == parent) + { + int nTotalToRemove = end - start + 1; + + if (d->m_model->rowCount(parent) <= nTotalToRemove) + { + // no more children + QModelIndex index = parent; + + while (index != d->m_root && !d->isIndexEnabled(index)) + { + index = index.parent(); + } + + if (index != d->m_root) + { + setCurrentIndex(index); + } + } + else + { + int row = end + 1; + QModelIndex next; + + do + { + // find the next visible and enabled item + next = d->m_model->index(row++, current.column(), current.parent()); + } + while (next.isValid() && (isIndexHidden(next) || !d->isIndexEnabled(next))); + + if (row > d->m_model->rowCount(parent)) + { + row = start - 1; + + do + { + // find the previous visible and enabled item + next = d->m_model->index(row--, current.column(), current.parent()); + } + while (next.isValid() && (isIndexHidden(next) || !d->isIndexEnabled(next))); + } + + setCurrentIndex(next); + } + } + + // Remove all affected editors; this is more efficient than waiting + // for updateGeometries() to clean out editors for invalid indexes + GEditorIndexHash::iterator iter = d->m_editorIndexHash.begin(); + + while (iter != d->m_editorIndexHash.end()) + { + const QModelIndex c_index = iter.value(); + + if (c_index.row() >= start && c_index.row() <= end && d->m_model->parent(c_index) == parent) + { + QWidget *editor = iter.key(); + GEditorInfo info = d->m_indexEditorHash.take(c_index); + iter = d->m_editorIndexHash.erase(iter); + + if (info.widget) + { + d->releaseEditor(editor); + } + } + else + { + ++iter; + } + } +} + +void GlodonAbstractItemViewPrivate::_q_rowsRemoved(const QModelIndex &index, int start, int end) +{ + Q_UNUSED(index) + Q_UNUSED(start) + Q_UNUSED(end) + + Q_Q(GlodonAbstractItemView); + + if (q->isVisible()) + { + q->updateEditorGeometries(); + } + + q->setState(GlodonAbstractItemView::NoState); +#ifndef QT_NO_ACCESSIBILITY +#ifdef Q_WS_X11 + + if (QAccessible::isActive()) + { + QAccessible::queryAccessibleInterface(q)->table2Interface()->rowsRemoved(index, start, end); + QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged); + } + +#endif +#endif +} + +void GlodonAbstractItemViewPrivate::_q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end) +{ + Q_Q(GlodonAbstractItemView); + + q->setState(GlodonAbstractItemView::CollapsingState); + + // Ensure one selected item in single selection mode. + QModelIndex current = q->currentIndex(); + + if (current.isValid() + && m_selectionMode == GlodonAbstractItemView::SingleSelection + && current.column() >= start + && current.column() <= end) + { + int nTotalToRemove = end - start + 1; + + if (m_model->columnCount(parent) < nTotalToRemove) + { + // no more columns + QModelIndex index = parent; + + while (index.isValid() && !isIndexEnabled(index)) + { + index = index.parent(); + } + + if (index.isValid()) + { + q->setCurrentIndex(index); + } + } + else + { + int nColumn = end; + QModelIndex next; + + do + { + // find the next visible and enabled item + next = m_model->index(current.row(), nColumn++, current.parent()); + } + while (next.isValid() && (q->isIndexHidden(next) || !isIndexEnabled(next))); + + q->setCurrentIndex(next); + } + } + + // Remove all affected editors; this is more efficient than waiting + // for updateGeometries() to clean out editors for invalid indexes + GEditorIndexHash::iterator it = m_editorIndexHash.begin(); + + while (it != m_editorIndexHash.end()) + { + QModelIndex index = it.value(); + + if (index.column() <= start && index.column() >= end && m_model->parent(index) == parent) + { + QWidget *editor = it.key(); + GEditorInfo info = m_indexEditorHash.take(it.value()); + it = m_editorIndexHash.erase(it); + + if (info.widget) + { + releaseEditor(editor); + } + } + else + { + ++it; + } + } + +} + +void GlodonAbstractItemViewPrivate::_q_columnsRemoved(const QModelIndex &index, int start, int end) +{ + Q_UNUSED(index) + Q_UNUSED(start) + Q_UNUSED(end) + + Q_Q(GlodonAbstractItemView); + + if (q->isVisible()) + { + q->updateEditorGeometries(); + } + + q->setState(GlodonAbstractItemView::NoState); +#ifndef QT_NO_ACCESSIBILITY +#ifdef Q_WS_X11 + + if (QAccessible::isActive()) + { + QAccessible::queryAccessibleInterface(q)->table2Interface()->columnsRemoved(index, start, end); + QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged); + } + +#endif +#endif +} + +void GlodonAbstractItemViewPrivate::_q_rowsInserted(const QModelIndex &index, int start, int end) +{ + Q_UNUSED(index) + Q_UNUSED(start) + Q_UNUSED(end) + +#ifndef QT_NO_ACCESSIBILITY +#ifdef Q_WS_X11 + Q_Q(GlodonAbstractItemView); + + if (QAccessible::isActive()) + { + QAccessible::queryAccessibleInterface(q)->table2Interface()->rowsInserted(index, start, end); + QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged); + } + +#endif +#endif +} + +void GlodonAbstractItemViewPrivate::_q_columnsInserted(const QModelIndex &index, int start, int end) +{ + Q_UNUSED(index) + Q_UNUSED(start) + Q_UNUSED(end) + + Q_Q(GlodonAbstractItemView); + + if (q->isVisible()) + { + q->updateEditorGeometries(); + } + +#ifndef QT_NO_ACCESSIBILITY +#ifdef Q_WS_X11 + + if (QAccessible::isActive()) + { + QAccessible::queryAccessibleInterface(q)->table2Interface()->columnsInserted(index, start, end); + QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged); + } + +#endif +#endif +} + +void GlodonAbstractItemViewPrivate::_q_modelDestroyed() +{ + m_model = QAbstractItemModelPrivate::staticEmptyModel(); + doDelayedReset(); +} + +void GlodonAbstractItemViewPrivate::_q_layoutChanged() +{ + doDelayedItemsLayout(); +#ifndef QT_NO_ACCESSIBILITY +#ifdef Q_WS_X11 + Q_Q(GlodonAbstractItemView); + + if (QAccessible::isActive()) + { + QAccessible::queryAccessibleInterface(q)->table2Interface()->modelReset(); + QAccessible::updateAccessibility(q, 0, QAccessible::TableModelChanged); + } + +#endif +#endif +} + +void GlodonAbstractItemView::selectionChanged(const QItemSelection &selected, + const QItemSelection &deselected) +{ + Q_D(GlodonAbstractItemView); + + if (isVisible() && updatesEnabled()) + { + d->viewport->update(visualRegionForSelection(deselected) | visualRegionForSelection(selected)); + } +} + +void GlodonAbstractItemView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) +{ + Q_D(GlodonAbstractItemView); + Q_ASSERT(d->m_model); + + if (previous.isValid()) + { + QModelIndex oBuddyIndex = d->m_model->buddy(previous); + QWidget *pEditor = d->editorForIndex(oBuddyIndex).widget.data(); + + if (pEditor && !d->m_persistent.contains(pEditor)) + { + bool bCanCloseEditor = true; + commitData(pEditor, bCanCloseEditor); + + if (bCanCloseEditor) + { + if (current.row() == previous.row()) + { + closeEditor(pEditor, bCanCloseEditor, GlodonDefaultItemDelegate::NoHint); + } + else + { + closeEditor(pEditor, bCanCloseEditor, GlodonDefaultItemDelegate::SubmitModelCache); + } + } + } + + if (isVisible()) + { + update(previous); + } + } + + if (current.isValid() && !d->m_autoScrollTimer.isActive()) + { + if (isVisible()) + { + if (d->m_bAutoScroll) + { + scrollTo(current); + } + + update(current); + edit(current, CurrentChanged, 0); + + if (current.row() == (d->m_model->rowCount(d->m_root) - 1)) + { + d->fetchMore(); + } + } + else + { + d->m_shouldScrollToCurrentOnShow = d->m_bAutoScroll; + } + } +} + +#ifndef QT_NO_DRAGANDDROP + +void GlodonAbstractItemView::startDrag(Qt::DropActions supportedActions) +{ + Q_D(GlodonAbstractItemView); + QModelIndexList indexes = d->selectedDraggableIndexes(); + + if (indexes.count() <= 0) + { + return; + } + + QMimeData *data = d->m_model->mimeData(indexes); + + if (!data) + { + return; + } + + QRect rect; + QPixmap pixmap = d->renderToPixmap(indexes, &rect); + rect.adjust(horizontalOffset(), verticalOffset(), 0, 0); + QDrag *drag = new QDrag(this); + drag->setPixmap(pixmap); + drag->setMimeData(data); + drag->setHotSpot(d->m_pressedPosition - rect.topLeft()); + Qt::DropAction defaultDropAction = Qt::IgnoreAction; + + if (d->m_defaultDropAction != Qt::IgnoreAction + && (supportedActions & d->m_defaultDropAction)) + { + defaultDropAction = d->m_defaultDropAction; + } + else if (supportedActions & Qt::CopyAction + && dragDropMode() != GlodonAbstractItemView::InternalMove) + { + defaultDropAction = Qt::CopyAction; + } + + if (drag->exec(supportedActions, defaultDropAction) == Qt::MoveAction) + { + d->clearOrRemove(); + } +} + +#endif // QT_NO_DRAGANDDROP + +QStyleOptionViewItem GlodonAbstractItemView::viewOptions() const +{ + Q_D(const GlodonAbstractItemView); + + QStyleOptionViewItem option; + option.init(this); + option.state &= ~QStyle::State_MouseOver; + option.font = font(); + +#ifndef Q_WS_MAC + + // On mac the focus appearance follows window activation + // not widget activation + if (!hasFocus()) + { + option.state &= ~QStyle::State_Active; + } + +#endif + + option.state &= ~QStyle::State_HasFocus; + + if (d->m_oIconSize.isValid()) + { + option.decorationSize = d->m_oIconSize; + } + else + { + int nPm = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this); + option.decorationSize = QSize(nPm, nPm); + } + + option.decorationPosition = QStyleOptionViewItem::Left; + option.decorationAlignment = Qt::AlignCenter; + option.displayAlignment = Qt::AlignLeft | Qt::AlignVCenter; + option.textElideMode = d->m_textElideMode; + option.rect = QRect(); + option.showDecorationSelected = (0 != style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, 0, this)); + return option; +} + +QStyleOptionViewItem GlodonAbstractItemViewPrivate::viewOptionsV4() const +{ + Q_Q(const GlodonAbstractItemView); + + QStyleOptionViewItem option = q->viewOptions(); + + if (m_bWrapItemText) + { + option.features = QStyleOptionViewItem::WrapText; + } + + option.locale = q->locale(); + option.locale.setNumberOptions(QLocale::OmitGroupSeparator); + option.widget = q; + + return option; +} + +void GlodonAbstractItemViewPrivate::doDelayedReset() +{ + //we delay the reset of the timer because some views (QTableView) + //with headers can't handle the fact that the model has been destroyed + //all _q_modelDestroyed slots must have been called + if (!m_delayedReset.isActive()) + { + m_delayedReset.start(0, q_func()); + } +} + +bool GlodonAbstractItemViewPrivate::mouseMoveEventFlag( + Qt::KeyboardModifiers &modifiers, const QEvent *event, QItemSelectionModel::SelectionFlags &selectionFlags) const +{ + modifiers = static_cast(event)->modifiers(); + + if (Qt::ControlModifier == (modifiers & Qt::ControlModifier)) + { + selectionFlags = QItemSelectionModel::ToggleCurrent | selectionBehaviorFlags(); + return true; + } + return false; +} + +bool GlodonAbstractItemViewPrivate::mouseButtonPressEventFlag( + Qt::KeyboardModifiers &modifiers, const QModelIndex &index, const QEvent *event, QItemSelectionModel::SelectionFlags &selectionFlags) const +{ + modifiers = static_cast(event)->modifiers(); + const Qt::MouseButton c_button = static_cast(event)->button(); + const bool c_rightButtonPressed = (Qt::RightButton == (c_button & Qt::RightButton)); + const bool c_shiftKeyPressed = (Qt::ShiftModifier == (modifiers & Qt::ShiftModifier)); + const bool c_controlKeyPressed = (Qt::ControlModifier == (modifiers & Qt::ControlModifier)); + const bool c_indexIsSelected = m_selectionModel->isSelected(index); + + if ((c_shiftKeyPressed || c_controlKeyPressed) && c_rightButtonPressed) + { + selectionFlags = QItemSelectionModel::NoUpdate; + return true; + } + + if (!c_shiftKeyPressed && !c_controlKeyPressed && c_indexIsSelected) + { + selectionFlags = QItemSelectionModel::NoUpdate; + return true; + } + + if (!index.isValid() && !c_rightButtonPressed && !c_shiftKeyPressed && !c_controlKeyPressed) + { + selectionFlags = QItemSelectionModel::Clear; + return true; + } + + if (!index.isValid()) + { + selectionFlags = QItemSelectionModel::NoUpdate; + return true; + } + + return false; +} + +QItemSelectionModel::SelectionFlags GlodonAbstractItemViewPrivate::mouseButtonReleaseEventFlag( + Qt::KeyboardModifiers &modifiers, const QModelIndex &index, const QEvent *event) const +{ + if (isNewSelect(modifiers, index, event)) + { + return QItemSelectionModel::ClearAndSelect | selectionBehaviorFlags(); + } + + return QItemSelectionModel::NoUpdate; +} + +bool GlodonAbstractItemViewPrivate::keyPressEventFlag( + Qt::KeyboardModifiers &modifiers, const QEvent *event, QItemSelectionModel::SelectionFlags &selectionFlags) const +{ + modifiers = static_cast(event)->modifiers(); + + switch (static_cast(event)->key()) + { + case Qt::Key_Backtab: + modifiers = modifiers & ~Qt::ShiftModifier; // special case for backtab + + case Qt::Key_Down: + case Qt::Key_Up: + case Qt::Key_Left: + case Qt::Key_Right: + case Qt::Key_Home: + case Qt::Key_End: + case Qt::Key_PageUp: + case Qt::Key_PageDown: + case Qt::Key_Tab: + if ((modifiers & Qt::ControlModifier) +#ifdef QT_KEYPAD_NAVIGATION + // Preserve historical tab order navigation behavior + || QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder +#endif + ) + { + selectionFlags = QItemSelectionModel::NoUpdate; + return true; + } + + break; + + case Qt::Key_Select: + { + selectionFlags = QItemSelectionModel::Toggle | selectionBehaviorFlags(); + return true; + } + + case Qt::Key_Space:// Toggle on Ctrl-Qt::Key_Space, Select on Space + { + if (modifiers & Qt::ControlModifier) + { + selectionFlags = QItemSelectionModel::Toggle | selectionBehaviorFlags(); + return true; + } + selectionFlags = QItemSelectionModel::Select | selectionBehaviorFlags(); + return true; + } + + default: + break; + } + + return false; +} + +bool GlodonAbstractItemViewPrivate::isNewSelect(Qt::KeyboardModifiers &modifiers, const QModelIndex &index, const QEvent *event) const +{ + modifiers = static_cast(event)->modifiers(); + const Qt::MouseButton c_button = static_cast(event)->button(); + const bool c_rightButtonPressed = (Qt::RightButton == (c_button & Qt::RightButton)); + const bool c_shiftKeyPressed = (Qt::ShiftModifier == (modifiers & Qt::ShiftModifier)); + const bool c_controlKeyPressed = (Qt::ControlModifier == (modifiers & Qt::ControlModifier)); + + return !c_shiftKeyPressed + && !c_controlKeyPressed + && (!c_rightButtonPressed || !index.isValid()) + &&(!index.isValid() || (index == m_pressedIndex && m_selectionModel->isSelected(index))) + && m_state != GlodonAbstractItemView::DragSelectingState ; +} + +void GlodonAbstractItemViewPrivate::updateNoStaticEditorData(const QModelIndex &editorIndex) +{ + const GEditorInfo &editorInfo = editorForIndex(editorIndex); + + //we don't update the edit data if it is static + if (!editorInfo.isStatic && editorInfo.widget) + { + GlodonDefaultItemDelegate *delegate = delegateForIndex(editorIndex); + + if (delegate) + { + delegate->setEditorData(editorInfo.widget.data(), editorIndex); + } + } +} + +GlodonAbstractItemView::State GlodonAbstractItemView::state() const +{ + Q_D(const GlodonAbstractItemView); + return d->m_state; +} + +void GlodonAbstractItemView::setState(State state) +{ + Q_D(GlodonAbstractItemView); + d->m_state = state; +} + +void GlodonAbstractItemView::showToolTip(const QModelIndex &index) +{ + Q_D(GlodonAbstractItemView); + + if (d->m_pToolTipFrame) + { + d->m_pToolTipFrame->hide(); + } + + if (!index.isValid()) + { + return; + } + + if (d->m_pToolTipFrame) + { + d->m_delayedShowToolTip.stop(); + d->m_delayedShowToolTip.start(d->m_nDelayedHintTime, this); + } +} + +void GlodonAbstractItemView::editorCopy() +{ + Q_D(GlodonAbstractItemView); + + emit onEditorCopy(); + resetActAvailable(d->delegateForIndex(currentIndex())->curEditor()); +} + +void GlodonAbstractItemView::editorCut() +{ + emit onEditorCut(); +} + +void GlodonAbstractItemView::editorPaste() +{ + emit onEditorPaste(); +} + +void GlodonAbstractItemView::editorDelete() +{ + emit onEditorDelete(); +} + +QStyleOptionViewItem GlodonAbstractItemView::StyleOptionViewItem() +{ + Q_D(GlodonAbstractItemView); + return d->viewOptionsV4(); +} + +void GlodonAbstractItemView::scheduleDelayedItemsLayout() +{ + Q_D(GlodonAbstractItemView); + d->doDelayedItemsLayout(); +} + +void GlodonAbstractItemView::executeDelayedItemsLayout() +{ + Q_D(GlodonAbstractItemView); + d->executePostedLayout(); +} + +void GlodonAbstractItemView::setDirtyRegion(const QRegion ®ion) +{ + Q_D(GlodonAbstractItemView); + d->setDirtyRegion(region); +} + +void GlodonAbstractItemView::scrollDirtyRegion(int dx, int dy) +{ + Q_D(GlodonAbstractItemView); + d->scrollDirtyRegion(dx, dy); +} + +void GlodonAbstractItemView::startAutoScroll() +{ + d_func()->startAutoScroll(); +} + +void GlodonAbstractItemView::stopAutoScroll() +{ + d_func()->stopAutoScroll(); +} + +void GlodonAbstractItemView::doAutoScroll() +{ + // find how much we should scroll with + Q_D(GlodonAbstractItemView); + + QScrollBar *pVerticalScroll = verticalScrollBar(); + QScrollBar *pHorizontalScroll = horizontalScrollBar(); + + GlodonHeaderView *pHeaderView = qobject_cast(this); + if (pHeaderView) + { + QAbstractScrollArea *pParent = qobject_cast(parentWidget()); + if (pHeaderView->orientation() == Qt::Horizontal) + { + if (!pHeaderView->horizontalScrollBar() + || !pHeaderView->horizontalScrollBar()->isVisible()) + { + pHorizontalScroll = pParent->horizontalScrollBar(); + } + } + else + { + if (!pHeaderView->verticalScrollBar() + || !pHeaderView->verticalScrollBar()->isVisible()) + { + pHorizontalScroll = pParent->horizontalScrollBar(); + } + } + } + + int nVerticalStep = pVerticalScroll->pageStep(); + int nHorizontalStep = pHorizontalScroll->pageStep(); + if (d->m_autoScrollCount < qMax(nVerticalStep, nHorizontalStep)) + { + ++d->m_autoScrollCount; + } + + int nVerticalValue = pVerticalScroll->value(); + int nHorizontalValue = pHorizontalScroll->value(); + + // do the scrolling if we are in the scroll margins + scrollVerticalScrollBar(nVerticalValue, pVerticalScroll); + scrollHorizontalScrollBar(nHorizontalValue, pHorizontalScroll); + + // if nothing changed, stop scrolling + bool bVerticalUnchanged = (nVerticalValue == pVerticalScroll->value()); + bool bHorizontalUnchanged = (nHorizontalValue == pHorizontalScroll->value()); + + if (bVerticalUnchanged && bHorizontalUnchanged) + { + stopAutoScroll(); + } + else + { +#ifndef QT_NO_DRAGANDDROP + d->m_dropIndicatorRect = QRect(); + d->m_dropIndicatorPosition = GlodonAbstractItemView::OnViewport; +#endif + d->viewport->update(); + } +} + +QItemSelectionModel::SelectionFlags GlodonAbstractItemView::selectionCommand(const QModelIndex &index, + const QEvent *event) const +{ + Q_D(const GlodonAbstractItemView); + + switch (d->m_selectionMode) + { + case NoSelection: // Never update selection model + return QItemSelectionModel::NoUpdate; + + case SingleSelection: // ClearAndSelect on valid index otherwise NoUpdate + if (event && event->type() == QEvent::MouseButtonRelease) + { + return QItemSelectionModel::NoUpdate; + } + + return QItemSelectionModel::ClearAndSelect | d->selectionBehaviorFlags(); + + case MultiSelection: + return d->multiSelectionCommand(index, event); + + case ExtendedSelection: + return d->extendedSelectionCommand(index, event); + + case ContiguousSelection: + return d->contiguousSelectionCommand(index, event); + } + + return QItemSelectionModel::NoUpdate; +} + +QItemSelectionModel::SelectionFlags GlodonAbstractItemViewPrivate::multiSelectionCommand( + const QModelIndex &index, const QEvent *event) const +{ + Q_UNUSED(index) + + if (event) + { + switch (event->type()) + { + case QEvent::KeyPress: + if (static_cast(event)->key() == Qt::Key_Space + || static_cast(event)->key() == Qt::Key_Select) + { + return QItemSelectionModel::Toggle | selectionBehaviorFlags(); + } + + break; + + case QEvent::MouseButtonPress: + if (static_cast(event)->button() == Qt::LeftButton) + { + return QItemSelectionModel::Toggle | selectionBehaviorFlags(); // toggle + } + + break; + + case QEvent::MouseButtonRelease: + if (static_cast(event)->button() == Qt::LeftButton) + { + return QItemSelectionModel::NoUpdate | selectionBehaviorFlags(); // finalize + } + + break; + + case QEvent::MouseMove: + if (Qt::LeftButton == (static_cast(event)->buttons() & Qt::LeftButton)) + { + return QItemSelectionModel::ToggleCurrent | selectionBehaviorFlags(); // toggle drag select + } + + default: + break; + } + + return QItemSelectionModel::NoUpdate; + } + + return QItemSelectionModel::Toggle | selectionBehaviorFlags(); +} + +QItemSelectionModel::SelectionFlags GlodonAbstractItemViewPrivate::extendedSelectionCommand( + const QModelIndex &index, const QEvent *event) const +{ + Qt::KeyboardModifiers modifiers = QApplication::keyboardModifiers(); + QItemSelectionModel::SelectionFlags selectionFlags; + + if (event) + { + switch (event->type()) + { + case QEvent::MouseMove: + { + // Toggle on MouseMove + if (mouseMoveEventFlag(modifiers, event, selectionFlags)) + { + return selectionFlags; + } + break; + } + case QEvent::MouseButtonPress: + { + if (mouseButtonPressEventFlag(modifiers, index, event, selectionFlags)) + { + return selectionFlags; + } + break; + } + case QEvent::MouseButtonRelease: + { + // ClearAndSelect on MouseButtonRelease if MouseButtonPress on selected item or empty area + return mouseButtonReleaseEventFlag(modifiers, index, event); + } + case QEvent::KeyPress: + { + // NoUpdate on Key movement and Ctrl + if (keyPressEventFlag(modifiers, event, selectionFlags)) + { + return selectionFlags; + } + break; + } + default: + break; + } + } + + if (Qt::ShiftModifier == (modifiers & Qt::ShiftModifier)) + { + return QItemSelectionModel::SelectCurrent | selectionBehaviorFlags(); + } + + if (Qt::ControlModifier == (modifiers & Qt::ControlModifier)) + { + if (event) + { + return QItemSelectionModel::Toggle | selectionBehaviorFlags(); + } + return QItemSelectionModel::ClearAndSelect | selectionBehaviorFlags(); + } + + if (m_state == GlodonAbstractItemView::DragSelectingState) + { + //when drag-selecting we need to clear any previous selection and select the current one + return QItemSelectionModel::Clear | QItemSelectionModel::SelectCurrent | selectionBehaviorFlags(); + } + + return QItemSelectionModel::ClearAndSelect | selectionBehaviorFlags(); +} + +QItemSelectionModel::SelectionFlags +GlodonAbstractItemViewPrivate::contiguousSelectionCommand(const QModelIndex &index, + const QEvent *event) const +{ + QItemSelectionModel::SelectionFlags flags = extendedSelectionCommand(index, event); + const int c_Mask = QItemSelectionModel::Clear | QItemSelectionModel::Select + | QItemSelectionModel::Deselect | QItemSelectionModel::Toggle + | QItemSelectionModel::Current; + + switch (flags & c_Mask) + { + case QItemSelectionModel::Clear: + case QItemSelectionModel::ClearAndSelect: + case QItemSelectionModel::SelectCurrent: + return flags; + + case QItemSelectionModel::NoUpdate: + if (event + && (event->type() == QEvent::MouseButtonPress + || event->type() == QEvent::MouseButtonRelease)) + { + return flags; + } + + return QItemSelectionModel::ClearAndSelect | selectionBehaviorFlags(); + + default: + return QItemSelectionModel::SelectCurrent | selectionBehaviorFlags(); + } +} + +void GlodonAbstractItemViewPrivate::fetchMore() +{ + m_fetchMoreTimer.stop(); + + if (!m_model->canFetchMore(m_root)) + { + return; + } + + int nlast = m_model->rowCount(m_root) - 1; + + if (nlast < 0) + { + m_model->fetchMore(m_root); + return; + } + + QModelIndex index = m_model->index(nlast, 0, m_root); + QRect rect = q_func()->visualRect(index); + + if (viewport->rect().intersects(rect)) + { + m_model->fetchMore(m_root); + } +} + +bool GlodonAbstractItemViewPrivate::shouldEdit( + GlodonAbstractItemView::EditTrigger trigger, const QModelIndex &index) const +{ + if (!index.isValid()) + { + return false; + } + + Qt::ItemFlags flags = m_model->flags(index); + + if (((flags & Qt::ItemIsEditable) == 0) || ((flags & Qt::ItemIsEnabled) == 0)) + { + return false; + } + + if (m_state == GlodonAbstractItemView::EditingState && !m_alwaysShowEditorPro) + { + return false; + } + + if (hasEditor(index)) + { + return false; + } + + if (trigger == GlodonAbstractItemView::AllEditTriggers) // force editing + { + return true; + } + + if ((trigger & m_editTriggers) == GlodonAbstractItemView::SelectedClicked + && !m_selectionModel->isSelected(index)) + { + return false; + } + + return trigger & m_editTriggers; +} + +bool GlodonAbstractItemViewPrivate::shouldForwardEvent( + GlodonAbstractItemView::EditTrigger trigger, const QEvent *event) const +{ + if (!event || (trigger & m_editTriggers) != GlodonAbstractItemView::AnyKeyPressed) + { + return false; + } + + switch (event->type()) + { + case QEvent::KeyPress: + case QEvent::MouseButtonDblClick: + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseMove: + return true; + + default: + break; + }; + + return false; +} + +bool GlodonAbstractItemViewPrivate::shouldAutoScroll(const QPoint &pos) const +{ + if (!m_bAutoScroll) + { + return false; + } + + QRect area = static_cast(viewport)->d_func()->clipRect(); + // access QWidget private by bending C++ rules + return (pos.y() - area.top() < m_nAutoScrollMargin) + || (area.bottom() - pos.y() < m_nAutoScrollMargin) + || (pos.x() - area.left() < m_nAutoScrollMargin) + || (area.right() - pos.x() < m_nAutoScrollMargin); +} + +void GlodonAbstractItemViewPrivate::doDelayedItemsLayout(int delay) +{ + if (!m_delayedPendingLayout) + { + m_delayedPendingLayout = true; + m_delayedLayout.start(delay, q_func()); + } +} + +void GlodonAbstractItemViewPrivate::doWheel() +{ +} + +void GlodonAbstractItemViewPrivate::interruptDelayedItemsLayout() const +{ + m_delayedLayout.stop(); + m_delayedPendingLayout = false; +} + +QWidget *GlodonAbstractItemViewPrivate::editor(const QModelIndex &index, + const QStyleOptionViewItem &options) +{ + Q_Q(GlodonAbstractItemView); + QWidget *widgt = editorForIndex(index).widget.data(); + + if (!widgt) + { + GlodonDefaultItemDelegate *delegate = delegateForIndex(index); + + if (!delegate) + { + return 0; + } + + widgt = delegate->createEditor(viewport, options, index); + + if (widgt) + { + delegate->setCurEditor(widgt); + + m_state = GlodonAbstractItemView::EditingState; + widgt->installEventFilter(delegate); + q->installEventFilterWidthEdit(widgt, delegate); + QObject::connect(widgt, SIGNAL(destroyed(QObject *)), q, SLOT(editorDestroyed(QObject *))); + //options.showDecorationSelected = true; + delegate->updateEditorGeometry(widgt, options, index); + delegate->setEditorData(widgt, index); + + if (!m_alwaysShowEditorPro) + { + addEditor(index, widgt, false); + } + + if (widgt->parent() == viewport) + { + QWidget::setTabOrder(q, widgt); + } + + // Special cases for some editors containing QLineEdit + QWidget *focusWidget = widgt; + + while (QWidget *fp = focusWidget->focusProxy()) + { + focusWidget = fp; + } + + m_currentEditor = widgt; + } + } + + return widgt; +} + +void GlodonAbstractItemViewPrivate::updateEditorData(const QModelIndex &tl, const QModelIndex &br) +{ + // we are counting on having relatively few editors + const bool c_checkIndexes = tl.isValid() && br.isValid(); + const QModelIndex c_parent = tl.parent(); + GIndexEditorHash::const_iterator it = m_indexEditorHash.constBegin(); + + for (; it != m_indexEditorHash.constEnd(); ++it) + { + QWidget *editor = it.value().widget.data(); + const QModelIndex c_index = it.key(); + + if (it.value().isStatic || !editor || !c_index.isValid() + || (c_checkIndexes + && (c_index.row() < tl.row() || c_index.row() > br.row() + || c_index.column() < tl.column() || c_index.column() > br.column() + || c_index.parent() != c_parent))) + { + continue; + } + + GlodonDefaultItemDelegate *delegate = delegateForIndex(c_index); + + if (delegate) + { + delegate->setEditorData(editor, c_index); + } + } +} + +void GlodonAbstractItemViewPrivate::clearOrRemove() +{ +#ifndef QT_NO_DRAGANDDROP + const QItemSelection c_selection = m_selectionModel->selection(); + QList::const_iterator it = c_selection.constBegin(); + + if (!m_bDragDropOverwrite) + { + for (; it != c_selection.constEnd(); ++it) + { + QModelIndex parent = (*it).parent(); + + if ((*it).left() != 0) + { + continue; + } + + if ((*it).right() != (m_model->columnCount(parent) - 1)) + { + continue; + } + + int ncount = (*it).bottom() - (*it).top() + 1; + m_model->removeRows((*it).top(), ncount, parent); + } + } + else + { + // we can't remove the rows so reset the items (i.e. the view is like a table) + QModelIndexList list = c_selection.indexes(); + + for (int i = 0; i < list.size(); ++i) + { + QModelIndex index = list.at(i); + QMap roles = m_model->itemData(index); + + for (QMap::Iterator it = roles.begin(); it != roles.end(); ++it) + { + it.value() = QVariant(); + } + + m_model->setItemData(index, roles); + } + } + +#endif +} + +void GlodonAbstractItemViewPrivate::checkPersistentEditorFocus() +{ + Q_Q(GlodonAbstractItemView); + + if (QWidget *widget = QApplication::focusWidget()) + { + if (m_persistent.contains(widget)) + { + //a persistent editor has gained the focus + QModelIndex index = indexForEditor(widget); + + if (m_selectionModel->currentIndex() != index) + { + q->setCurrentIndex(index); + } + } + } +} + +const GEditorInfo &GlodonAbstractItemViewPrivate::editorForIndex(const QModelIndex &index) const +{ + static GEditorInfo s_nullInfo; + + GIndexEditorHash::const_iterator it = m_indexEditorHash.find(index); + + if (it == m_indexEditorHash.end()) + { + return s_nullInfo; + } + + return it.value(); +} + +QModelIndex GlodonAbstractItemViewPrivate::indexForEditor(QWidget *editor) const +{ + GEditorIndexHash::const_iterator it = m_editorIndexHash.find(editor); + + if (it == m_editorIndexHash.end()) + { + return QModelIndex(); + } + + return it.value(); +} + +void GlodonAbstractItemViewPrivate::removeEditor(QWidget *editor) +{ + GEditorIndexHash::iterator it = m_editorIndexHash.find(editor); + + if (it != m_editorIndexHash.end()) + { + m_indexEditorHash.remove(it.value()); + m_editorIndexHash.erase(it); + } +} + +int GlodonAbstractItemViewPrivate::delegateRefCount(const GlodonDefaultItemDelegate *delegate) const +{ + int nRef = 0; + + if (m_itemDelegate == delegate) + { + ++nRef; + } + + typedef QMap > DelegateMap; + + for (int nMaps = 0; nMaps < 2; ++nMaps) + { + const DelegateMap *delegates = (0 != nMaps) ? &m_columnDelegates : &m_rowDelegates; + + DelegateMap::const_iterator it = delegates->begin(); + DelegateMap::const_iterator end = delegates->end(); + + for (; it != end; ++it) + { + if (it.value() == delegate) + { + ++nRef; + + // optimization, we are only interested in the ref count values 0, 1 or >=2 + if (nRef >= 2) + { + return nRef; + } + } + } + } + + return nRef; +} + +bool GlodonAbstractItemViewPrivate::isPersistent(const QModelIndex &index) const +{ + GAbstractItemModel *temp = static_cast(m_model); + QAbstractItemModelPrivate *pPrivate = static_cast(temp->d_ptr.data()); + return pPrivate->persistent.indexes.contains(index); +} + +void GlodonAbstractItemViewPrivate::addEditor(const QModelIndex &index, QWidget *editor, bool isStatic) +{ + m_editorIndexHash.insert(editor, index); + m_indexEditorHash.insert(index, GEditorInfo(editor, isStatic)); +} + +bool GlodonAbstractItemViewPrivate::sendDelegateEvent(const QModelIndex &index, QEvent *event) const +{ + Q_Q(const GlodonAbstractItemView); + + QModelIndex buddy = m_model->buddy(index); + + QStyleOptionViewItem options = viewOptionsV4(); + options.rect = q->visualRect(buddy); + options.state |= (buddy == q->currentIndex() ? QStyle::State_HasFocus : QStyle::State_None); + GlodonDefaultItemDelegate *delegate = delegateForIndex(index); + + return (event && delegate && delegate->editorEvent(event, m_model, options, buddy)); +} + +bool GlodonAbstractItemViewPrivate::openEditor(const QModelIndex &index, QEvent *event) +{ + Q_Q(GlodonAbstractItemView); + + QModelIndex buddy = m_model->buddy(index); + m_oEditorIndex = buddy; + QStyleOptionViewItem options = viewOptionsV4(); + options.rect = q->visualRect(buddy); + options.state |= (buddy == q->currentIndex() ? QStyle::State_HasFocus : QStyle::State_None); + + QWidget *pCurEditor = editor(buddy, options); + if (!pCurEditor) + { + m_oEditorIndex = QModelIndex(); + return false; + } + + q->setState(GlodonAbstractItemView::EditingState); + pCurEditor->show(); + + // TODO wangdd-a,后面考虑重新实现,并且移到子类 + if (!q->alwaysShowEditorPro()) + { + pCurEditor->setFocus(); + } + + if (event) + { +#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) + if (event->type() == QEvent::KeyPress) // todo qt5 && inputContext()) +#else + if (event->type() == QEvent::KeyPress && inputContext()) +#endif + QApplication::sendEvent(pCurEditor->focusProxy() ? pCurEditor->focusProxy() : pCurEditor, event); + } + + return true; +} + +GItemViewPaintPairs GlodonAbstractItemViewPrivate::draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const +{ + Q_ASSERT(r); + Q_Q(const GlodonAbstractItemView); + QRect &rect = *r; + const QRect c_viewportRect = viewport->rect(); + GItemViewPaintPairs ret; + + for (int i = 0; i < indexes.count(); ++i) + { + const QModelIndex &index = indexes.at(i); + const QRect c_current = q->visualRect(index); + + if (c_current.intersects(c_viewportRect)) + { + ret += qMakePair(c_current, index); + rect |= c_current; + } + } + + rect &= c_viewportRect; + return ret; +} + +void GlodonAbstractItemViewPrivate::releaseEditor(QWidget *editor) const +{ + if (editor) + { + QObject::disconnect(editor, SIGNAL(destroyed(QObject *)), + q_func(), SLOT(editorDestroyed(QObject *))); + editor->removeEventFilter(m_itemDelegate); + editor->hide(); + editor->deleteLater(); + } +} + +QPixmap GlodonAbstractItemViewPrivate::renderToPixmap(const QModelIndexList &indexes, QRect *r) const +{ + Q_ASSERT(r); + GItemViewPaintPairs paintPairs = draggablePaintPairs(indexes, r); + + if (paintPairs.isEmpty()) + { + return QPixmap(); + } + + QPixmap pixmap(r->size()); + pixmap.fill(Qt::transparent); + QPainter painter(&pixmap); + + QStyleOptionViewItem option = viewOptionsV4(); + option.state |= QStyle::State_Selected; + + for (int j = 0; j < paintPairs.count(); ++j) + { + option.rect = paintPairs.at(j).first.translated(-r->topLeft()); + const QModelIndex ¤t = paintPairs.at(j).second; + adjustViewOptionsForIndex(&option, current); + delegateForIndex(current)->paint(&painter, option, current); + } + + return pixmap; +} + +void GlodonAbstractItemViewPrivate::selectAll(QItemSelectionModel::SelectionFlags command) +{ + if (!m_selectionModel) + { + return; + } + + QItemSelection selection; + QModelIndex oTopLeftIndex = m_model->index(0, 0, m_root); + QModelIndex oBottomRightIndex = + m_model->index(m_model->rowCount(m_root) - 1, m_model->columnCount(m_root) - 1, m_root); + + selection.append(QItemSelectionRange(oTopLeftIndex, oBottomRightIndex)); + m_selectionModel->select(selection, command); +} + +QModelIndexList GlodonAbstractItemViewPrivate::selectedDraggableIndexes() const +{ + Q_Q(const GlodonAbstractItemView); + QModelIndexList indexes = q->selectedIndexes(); + + for (int i = indexes.count() - 1; i >= 0; --i) + { + if (!isIndexDragEnabled(indexes.at(i))) + { + indexes.removeAt(i); + } + } + + return indexes; +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDApplication.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDApplication.cpp new file mode 100644 index 00000000..4c2bb42a --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDApplication.cpp @@ -0,0 +1,191 @@ +#include "GLDApplication.h" + +#include "GLDException.h" +#include "GLDUIUtils.h" + +//#define DEBUG +#ifdef DEBUG +#include +#endif + +/* +#include + +class GLDEventDispatcherWin32 : public QEventDispatcherWin32 +{ +public: + explicit GLDEventDispatcherWin32(QObject *parent = 0); + bool processEvents(QEventLoop::ProcessEventsFlags flags); +}; + +GLDEventDispatcherWin32::GLDEventDispatcherWin32(QObject *parent) : QEventDispatcherWin32(parent) +{ +} + +bool GLDEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) +{ + try + { + return QEventDispatcherWin32::processEvents(flags); + } + catch (GLDException &e) + { + showPrompt(e.message()); + return false; + } +} +*/ + +/* GLDApplication */ + +GLDApplication::GLDApplication(int &argc, + char **argv, + int _internal) + : QApplication(argc, argv, _internal) + , useFilterInBusy(true) + , m_idleTimerID(0) +{ + // 初始化资源文件 + Q_INIT_RESOURCE(GLDIcons); + Q_INIT_RESOURCE(GLDQsses); + Q_INIT_RESOURCE(GLDInis); + + m_idleTimerID = this->startTimer(0); + m_nonBusyEventTypes.insert(QEvent::ZeroTimerEvent); + //if there is some bug, pls try to remove those code lines below + m_nonBusyEventTypes.insert(QEvent::DynamicPropertyChange); + //Leave + m_nonBusyEventTypes.insert(QEvent::Enter);//10 + m_nonBusyEventTypes.insert(QEvent::Leave);//11 + m_nonBusyEventTypes.insert(QEvent::Paint);//12 + m_nonBusyEventTypes.insert(QEvent::Resize);//14 + m_nonBusyEventTypes.insert(QEvent::Create);//15 + m_nonBusyEventTypes.insert(QEvent::Destroy);//16 + m_nonBusyEventTypes.insert(QEvent::Show);//17 + m_nonBusyEventTypes.insert(QEvent::Hide);//18 + m_nonBusyEventTypes.insert(QEvent::ParentChange);//21 + m_nonBusyEventTypes.insert(QEvent::HideToParent);//27 + m_nonBusyEventTypes.insert(QEvent::PaletteChange);//39 + m_nonBusyEventTypes.insert(QEvent::DeferredDelete);//52 + m_nonBusyEventTypes.insert(QEvent::ChildAdded);//68 + m_nonBusyEventTypes.insert(QEvent::ChildPolished);//69 + m_nonBusyEventTypes.insert(QEvent::ChildRemoved);//71 + m_nonBusyEventTypes.insert(QEvent::ActionChanged); + m_nonBusyEventTypes.insert(QEvent::PolishRequest);//74 + m_nonBusyEventTypes.insert(QEvent::Polish);//75 + m_nonBusyEventTypes.insert(QEvent::LayoutRequest);//76 + m_nonBusyEventTypes.insert(QEvent::UpdateRequest);//77 + m_nonBusyEventTypes.insert(QEvent::UpdateLater);//78 + + m_nonBusyEventTypes.insert(QEvent::LanguageChange);//89 + m_nonBusyEventTypes.insert(QEvent::FontChange);//97 + m_nonBusyEventTypes.insert(QEvent::StyleChange);//100 + m_nonBusyEventTypes.insert(QEvent::ActionRemoved);//115 + + m_nonBusyEventTypes.insert(QEvent::ToolTipChange);//184 + m_nonBusyEventTypes.insert(QEvent::LayoutRequest); + + // busy events (used in filtered in) + m_busyEventTypes.insert(QEvent::MouseButtonPress); + m_busyEventTypes.insert(QEvent::MouseButtonRelease); + m_busyEventTypes.insert(QEvent::MouseButtonDblClick); + m_busyEventTypes.insert(QEvent::MouseMove); + m_busyEventTypes.insert(QEvent::KeyPress); + m_busyEventTypes.insert(QEvent::KeyRelease); + m_busyEventTypes.insert(QEvent::TabletPress); + m_busyEventTypes.insert(QEvent::TabletRelease); + m_busyEventTypes.insert(QEvent::Wheel); + m_busyEventTypes.insert(QEvent::TabletEnterProximity); + m_busyEventTypes.insert(QEvent::TabletLeaveProximity); + m_busyEventTypes.insert(QEvent::CursorChange); + m_busyEventTypes.insert(QEvent::TouchBegin); + m_busyEventTypes.insert(QEvent::TouchUpdate); + m_busyEventTypes.insert(QEvent::TouchEnd); +#ifndef QT_NO_GESTURES + m_busyEventTypes.insert(QEvent::Gesture); + m_busyEventTypes.insert(QEvent::NativeGesture); +#endif + m_busyEventTypes.insert(QEvent::Scroll); + m_busyEventTypes.insert(QEvent::InputMethodQuery); + m_busyEventTypes.insert(QEvent::OrientationChange); + m_busyEventTypes.insert(QEvent::ThemeChange); + //m_busyEventTypes.insert(QEvent::Paint);//????? + +} + +GLDApplication::~GLDApplication() +{ + if (0!=m_idleTimerID) { + this->killTimer(m_idleTimerID); + } +} + +void GLDApplication::timerEvent( QTimerEvent *event ) +{ + if ( event->timerId() == m_idleTimerID) { + // first time switching from busy into idle + this->killTimer(m_idleTimerID); + m_idleTimerID = 0; + onIdle(); + } + +} + +bool GLDApplication::notify(QObject *receiver, QEvent *e) +{ + try + { + bool result = QApplication::notify(receiver, e); + + if (QEvent::Timer == e->type()) { + QTimerEvent* qtimerEvent = dynamic_cast(e); + if (NULL == qtimerEvent || + qtimerEvent->timerId()!=m_idleTimerID ) { + //m_busy = true; + } + } else { + bool isBusyNow = false; + if (useFilterInBusy && + m_busyEventTypes.find(e->type())!= + m_busyEventTypes.end()) { + isBusyNow = true; +#ifdef DEBUG + qDebug( "1type=%d", e->type()); +#endif + } + else if (!useFilterInBusy && m_nonBusyEventTypes.find(e->type())== + m_nonBusyEventTypes.end() && + e->type()type=%d", e->type()); +#endif + } + if (isBusyNow && 0 == m_idleTimerID) { + m_idleTimerID = this->startTimer(0); + } + + } + return result; + } + catch (GLDException &e) + { + showPrompt(e.message()); + return false; + } +} + +/* +void GLDApplication::initEventDispatcher() +{ + QCoreApplication::setEventDispatcher(new GLDEventDispatcherWin32(0)); +} +*/ + +void GLDApplication::onIdle() +{ +#ifdef DEBUG + qDebug( ":emit idle()"); +#endif + emit idle(); +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDCalendarWidget.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDCalendarWidget.cpp new file mode 100644 index 00000000..2a7ee1ad --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDCalendarWidget.cpp @@ -0,0 +1,3244 @@ +#include "GLDCalendarWidget.h" +#include "GLDStrings.h" + +#include +#include +#include + +#ifndef QT_NO_CALENDARWIDGET + +QT_BEGIN_NAMESPACE + +// 日历变量 +const int c_MaxYear = 7999; +const int c_MaxMonth = 12; +const int c_MaxDay = 31; +const int c_MinYear = 1752; +const int c_daysPerMonth = 31; +const int c_monthsPerYear = 12; +const int c_daysPerWeek = 7; + +// 布局变量 +const int c_navBarWidth = 251; +const int c_navBarHeight = 28; +const int c_monthComboBoxWidth = 48; +const int c_monthComboBoxHeight = 20; +const int c_monthComboBoxViewHeight = 226; +const int c_yearEditWidth = 48; +const int c_yearEditHeight = 20; +const int c_yearEditHeightErr = 4; +const int c_yearTextWidthErr = 2; +const int c_yearTextHeightErr = -4; +const int c_monthComboBoxWidthErr = 2; +const int c_monthComboBoxHeightErr = 4; +const int c_calendarWidgetWidth = 251; +const int c_calendarWidgetHeight = 266; +const int c_calendarBodyWidth = 245; +const int c_calendarBodyHeight = 233; +const int c_calendarBodyLayoutMargin = 8; +const int c_calendarHeadWidth = 226; +const int c_calendarHeadHeight = 28; +const int c_calendarHearBtnWidth = 33; +const int c_calendarHearBtnHeight = 30; + +QString GLDCalendarDateSectionValidator::highlightString(const QString &str, int pos) const +{ + if (pos == 0) + { + return QLatin1String("") + str + QLatin1String(""); + } + int startPos = str.length() - pos; + return str.mid(0, startPos) + QLatin1String("") + str.mid(startPos, pos) + QLatin1String(""); +} + +GLDCalendarDayValidator::GLDCalendarDayValidator(): + GLDCalendarDateSectionValidator(), + m_pos(0), + m_day(1), + m_oldDay(1) +{ + +} + +GLDCalendarDateSectionValidator::Section GLDCalendarDayValidator::handleKey(int key) +{ + if (key == Qt::Key_Right || key == Qt::Key_Left) + { + m_pos = 0; + return GLDCalendarDateSectionValidator::ThisSection; + } + else if (key == Qt::Key_Up) + { + m_pos = 0; + ++m_day; + if (m_day > c_daysPerMonth) + { + m_day = 1; + } + return GLDCalendarDateSectionValidator::ThisSection; + } + else if (key == Qt::Key_Down) + { + m_pos = 0; + --m_day; + if (m_day < 1) + { + m_day = c_daysPerMonth; + } + return GLDCalendarDateSectionValidator::ThisSection; + } + else if (key == Qt::Key_Back || key == Qt::Key_Backspace) + { + --m_pos; + if (m_pos < 0) + { + m_pos = 1; + } + + if (m_pos == 0) + { + m_day = m_oldDay; + } + else + { + m_day = m_day / 10; + //m_day = m_oldDay / 10 * 10 + m_day / 10; + } + + if (m_pos == 0) + { + return GLDCalendarDateSectionValidator::PrevSection; + } + return GLDCalendarDateSectionValidator::ThisSection; + } + if (key < Qt::Key_0 || key > Qt::Key_9) + { + return GLDCalendarDateSectionValidator::ThisSection; + } + int pressedKey = key - Qt::Key_0; + if (m_pos == 0) + { + m_day = pressedKey; + } + else + { + m_day = m_day % 10 * 10 + pressedKey; + } + if (m_day > c_daysPerMonth) + { + m_day = c_daysPerMonth; + } + ++m_pos; + if (m_pos > 1) + { + m_pos = 0; + return GLDCalendarDateSectionValidator::NextSection; + } + return GLDCalendarDateSectionValidator::ThisSection; +} + +QDate GLDCalendarDayValidator::applyToDate(const QDate &date) const +{ + int day = m_day; + if (day < 1) + { + day = 1; + } + else if (day > c_daysPerMonth) + { + day = c_daysPerMonth; + } + if (day > date.daysInMonth()) + { + day = date.daysInMonth(); + } + return QDate(date.year(), date.month(), day); +} + +void GLDCalendarDayValidator::setDate(const QDate &date) +{ + m_day = m_oldDay = date.day(); + m_pos = 0; +} + +QString GLDCalendarDayValidator::text() const +{ + QString str; + if (m_day / 10 == 0) + { + str += QLatin1Char('0'); + } + str += QString::number(m_day); + return highlightString(str, m_pos); +} + +QString GLDCalendarDayValidator::text(const QDate &date, int repeat) const +{ + if (repeat <= 1) + { + return QString::number(date.day()); + } + else if (repeat == 2) + { + QString str; + if (date.day() / 10 == 0) + { + str += QLatin1Char('0'); + } + return str + QString::number(date.day()); + } + else if (repeat == 3) + { + return m_locale.dayName(date.dayOfWeek(), QLocale::ShortFormat); + } + else if (repeat >= 4) + { + return m_locale.dayName(date.dayOfWeek(), QLocale::LongFormat); + } + return QString(); +} + +GLDCalendarMonthValidator::GLDCalendarMonthValidator() : + GLDCalendarDateSectionValidator(), + m_pos(0), + m_month(1), + m_oldMonth(1) +{ + +} + +GLDCalendarDateSectionValidator::Section GLDCalendarMonthValidator::handleKey(int key) +{ + if (key == Qt::Key_Right || key == Qt::Key_Left) + { + m_pos = 0; + return GLDCalendarDateSectionValidator::ThisSection; + } else if (key == Qt::Key_Up) + { + m_pos = 0; + ++m_month; + if (m_month > c_monthsPerYear) + { + m_month = 1; + } + return GLDCalendarDateSectionValidator::ThisSection; + } + else if (key == Qt::Key_Down) + { + m_pos = 0; + --m_month; + if (m_month < 1) + { + m_month = c_monthsPerYear; + } + return GLDCalendarDateSectionValidator::ThisSection; + } + else if (key == Qt::Key_Back || key == Qt::Key_Backspace) + { + --m_pos; + if (m_pos < 0) + { + m_pos = 1; + } + + if (m_pos == 0) + { + m_month = m_oldMonth; + } + else + { + m_month = m_month / 10; + //m_month = m_oldMonth / 10 * 10 + m_month / 10; + } + + if (m_pos == 0) + { + return GLDCalendarDateSectionValidator::PrevSection; + } + return GLDCalendarDateSectionValidator::ThisSection; + } + if (key < Qt::Key_0 || key > Qt::Key_9) + { + return GLDCalendarDateSectionValidator::ThisSection; + } + int pressedKey = key - Qt::Key_0; + if (m_pos == 0) + { + m_month = pressedKey; + } + else + { + m_month = m_month % 10 * 10 + pressedKey; + } + if (m_month > c_monthsPerYear) + { + m_month = c_monthsPerYear; + } + ++m_pos; + if (m_pos > 1) + { + m_pos = 0; + return GLDCalendarDateSectionValidator::NextSection; + } + return GLDCalendarDateSectionValidator::ThisSection; +} + +QDate GLDCalendarMonthValidator::applyToDate(const QDate &date) const +{ + int month = m_month; + if (month < 1) + { + month = 1; + } + else if (month > c_monthsPerYear) + { + month = c_monthsPerYear; + } + QDate newDate(date.year(), m_month, 1); + int day = date.day(); + if (day > newDate.daysInMonth()) + { + day = newDate.daysInMonth(); + } + return QDate(date.year(), month, day); +} + +void GLDCalendarMonthValidator::setDate(const QDate &date) +{ + m_month = m_oldMonth = date.month(); + m_pos = 0; +} + +QString GLDCalendarMonthValidator::text() const +{ + QString str; + if (m_month / 10 == 0) + { + str += QLatin1Char('0'); + } + str += QString::number(m_month); + return highlightString(str, m_pos); +} + +QString GLDCalendarMonthValidator::text(const QDate &date, int repeat) const +{ + if (repeat <= 1) + { + return QString::number(date.month()); + } + else if (repeat == 2) + { + QString str; + if (date.month() / 10 == 0) + { + str += QLatin1Char('0'); + } + return str + QString::number(date.month()); + } + else if (repeat == 3) + { + return m_locale.standaloneMonthName(date.month(), QLocale::ShortFormat); + } + else /*if (repeat >= 4)*/ + { + return m_locale.standaloneMonthName(date.month(), QLocale::LongFormat); + } +} + +GLDCalendarYearValidator::GLDCalendarYearValidator() : + GLDCalendarDateSectionValidator(), + m_pos(0), + m_year(2000), + m_oldYear(2000) +{ + +} + +int GLDCalendarYearValidator::pow10(int n) +{ + int power = 1; + for (int i = 0; i < n; i++) + { + power *= 10; + } + return power; +} + +GLDCalendarDateSectionValidator::Section GLDCalendarYearValidator::handleKey(int key) +{ + if (key == Qt::Key_Right || key == Qt::Key_Left) + { + m_pos = 0; + return GLDCalendarDateSectionValidator::ThisSection; + } + else if (key == Qt::Key_Up) + { + m_pos = 0; + ++m_year; + return GLDCalendarDateSectionValidator::ThisSection; + } + else if (key == Qt::Key_Down) + { + m_pos = 0; + --m_year; + return GLDCalendarDateSectionValidator::ThisSection; + } + else if (key == Qt::Key_Back || key == Qt::Key_Backspace) + { + --m_pos; + if (m_pos < 0) + { + m_pos = 3; + } + + int pow = pow10(m_pos); + m_year = m_oldYear / pow * pow + m_year % (pow * 10) / 10; + + if (m_pos == 0) + { + return GLDCalendarDateSectionValidator::PrevSection; + } + return GLDCalendarDateSectionValidator::ThisSection; + } + if (key < Qt::Key_0 || key > Qt::Key_9) + { + return GLDCalendarDateSectionValidator::ThisSection; + } + int pressedKey = key - Qt::Key_0; + int pow = pow10(m_pos); + m_year = m_year / (pow * 10) * (pow * 10) + m_year % pow * 10 + pressedKey; + ++m_pos; + if (m_pos > 3) + { + m_pos = 0; + return GLDCalendarDateSectionValidator::NextSection; + } + return GLDCalendarDateSectionValidator::ThisSection; +} + +QDate GLDCalendarYearValidator::applyToDate(const QDate &date) const +{ + int year = m_year; + if (year < 1) + { + year = 1; + } + QDate newDate(year, date.month(), 1); + int day = date.day(); + if (day > newDate.daysInMonth()) + { + day = newDate.daysInMonth(); + } + return QDate(year, date.month(), day); +} + +void GLDCalendarYearValidator::setDate(const QDate &date) +{ + m_year = m_oldYear = date.year(); + m_pos = 0; +} + +QString GLDCalendarYearValidator::text() const +{ + QString str; + int pow = 10; + for (int i = 0; i < 3; i++) + { + if (m_year / pow == 0) + { + str += QLatin1Char('0'); + } + pow *= 10; + } + str += QString::number(m_year); + return highlightString(str, m_pos); +} + +QString GLDCalendarYearValidator::text(const QDate &date, int repeat) const +{ + if (repeat < 4) + { + QString str; + int year = date.year() % 100; + if (year / 10 == 0) + { + str = QLatin1Char('0'); + } + return str + QString::number(year); + } + return QString::number(date.year()); +} + +GLDCalendarDateValidator::GLDCalendarDateValidator() : + m_currentToken(0), + m_lastSectionMove(GLDCalendarDateSectionValidator::ThisSection) +{ + m_initialDate = m_currentDate = QDate::currentDate(); + m_yearValidator = new GLDCalendarYearValidator(); + m_monthValidator = new GLDCalendarMonthValidator(); + m_dayValidator = new GLDCalendarDayValidator(); +} + +void GLDCalendarDateValidator::setLocale(const QLocale &locale) +{ + m_yearValidator->m_locale = locale; + m_monthValidator->m_locale = locale; + m_dayValidator->m_locale = locale; +} + +GLDCalendarDateValidator::~GLDCalendarDateValidator() +{ + delete m_yearValidator; + delete m_monthValidator; + delete m_dayValidator; + clear(); +} + +// from qdatetime.cpp +int GLDCalendarDateValidator::countRepeat(const QString &str, int index) const +{ + Q_ASSERT(index >= 0 && index < str.size()); + int count = 1; + const QChar ch = str.at(index); + while (index + count < str.size() && str.at(index + count) == ch) + { + ++count; + } + return count; +} + +void GLDCalendarDateValidator::setInitialDate(const QDate &date) +{ + m_yearValidator->setDate(date); + m_monthValidator->setDate(date); + m_dayValidator->setDate(date); + m_initialDate = date; + m_currentDate = date; + m_lastSectionMove = GLDCalendarDateSectionValidator::ThisSection; +} + +QString GLDCalendarDateValidator::currentText() const +{ + QString str; + QStringListIterator itSep(m_separators); + QListIterator itTok(m_tokens); + while (itSep.hasNext()) + { + str += itSep.next(); + if (itTok.hasNext()) + { + SectionToken *token = itTok.next(); + GLDCalendarDateSectionValidator *validator = token->validator; + if (m_currentToken == token) + { + str += validator->text(); + } + else + { + str += validator->text(m_currentDate, token->repeat); + } + } + } + return str; +} + +void GLDCalendarDateValidator::clear() +{ + QListIterator it(m_tokens); + while (it.hasNext()) + { + delete it.next(); + } + + m_tokens.clear(); + m_separators.clear(); + + m_currentToken = 0; +} + +void GLDCalendarDateValidator::setFormat(const QString &format) +{ + clear(); + + int pos = 0; + const QLatin1Char quote('\''); + bool quoting = false; + QString separator; + while (pos < format.size()) + { + QString mid = format.mid(pos); + int offset = 1; + + if (mid.startsWith(quote)) + { + quoting = !quoting; + } + else + { + const QChar nextChar = format.at(pos); + if (quoting) + { + separator += nextChar; + } + else + { + SectionToken *token = 0; + if (nextChar == QLatin1Char('d')) + { + offset = qMin(4, countRepeat(format, pos)); + token = new SectionToken(m_dayValidator, offset); + } + else if (nextChar == QLatin1Char('M')) + { + offset = qMin(4, countRepeat(format, pos)); + token = new SectionToken(m_monthValidator, offset); + } + else if (nextChar == QLatin1Char('y')) + { + offset = qMin(4, countRepeat(format, pos)); + token = new SectionToken(m_yearValidator, offset); + } + else + { + separator += nextChar; + } + if (token) + { + m_tokens.append(token); + m_separators.append(separator); + separator = QString(); + if (!m_currentToken) + { + m_currentToken = token; + } + + } + } + } + pos += offset; + } + m_separators += separator; +} + +void GLDCalendarDateValidator::applyToDate() +{ + m_currentDate = m_yearValidator->applyToDate(m_currentDate); + m_currentDate = m_monthValidator->applyToDate(m_currentDate); + m_currentDate = m_dayValidator->applyToDate(m_currentDate); +} + +void GLDCalendarDateValidator::toNextToken() +{ + const int idx = m_tokens.indexOf(m_currentToken); + if (idx == -1) + { + return; + } + if (idx + 1 >= m_tokens.count()) + { + m_currentToken = m_tokens.first(); + } + else + { + m_currentToken = m_tokens.at(idx + 1); + } +} + +void GLDCalendarDateValidator::toPreviousToken() +{ + const int idx = m_tokens.indexOf(m_currentToken); + if (idx == -1) + { + return; + } + + if (idx - 1 < 0) + { + m_currentToken = m_tokens.last(); + } + else + { + m_currentToken = m_tokens.at(idx - 1); + } +} + +void GLDCalendarDateValidator::handleKeyEvent(QKeyEvent *keyEvent) +{ + if (!m_currentToken) + { + return; + } + + int key = keyEvent->key(); + if (m_lastSectionMove == GLDCalendarDateSectionValidator::NextSection) + { + if (key == Qt::Key_Back || key == Qt::Key_Backspace) + { + toPreviousToken(); + } + } + + if (key == Qt::Key_Right) + { + toNextToken(); + } + else if (key == Qt::Key_Left) + { + toPreviousToken(); + } + + m_lastSectionMove = m_currentToken->validator->handleKey(key); + + applyToDate(); + if (m_lastSectionMove == GLDCalendarDateSectionValidator::NextSection) + { + toNextToken(); + } + else if (m_lastSectionMove == GLDCalendarDateSectionValidator::PrevSection) + { + toPreviousToken(); + } +} + +QWidget *GLDCalendarTextNavigator::widget() const +{ + return m_widget; +} + +void GLDCalendarTextNavigator::setWidget(QWidget *widget) +{ + m_widget = widget; +} + +QDate GLDCalendarTextNavigator::date() const +{ + return m_date; +} + +void GLDCalendarTextNavigator::setDate(const QDate &date) +{ + m_date = date; +} + +void GLDCalendarTextNavigator::updateDateLabel() +{ + if (!m_widget) + { + return; + } + + m_acceptTimer.start(m_editDelay, this); + + m_dateText->setText(m_dateValidator->currentText()); + + QSize s = m_dateFrame->sizeHint(); + QRect r = m_widget->geometry(); // later, just the table section + QRect newRect((r.width() - s.width()) / 2, (r.height() - s.height()) / 2, s.width(), s.height()); + m_dateFrame->setGeometry(newRect); + // need to set palette after geometry update as phonestyle sets transparency + // effect in move event. + QPalette p = m_dateFrame->palette(); + p.setBrush(QPalette::Window, m_dateFrame->window()->palette().brush(QPalette::Window)); + m_dateFrame->setPalette(p); + + m_dateFrame->raise(); + m_dateFrame->show(); +} + +void GLDCalendarTextNavigator::applyDate() +{ + QDate date = m_dateValidator->currentDate(); + if (m_date == date) + { + return; + } + + m_date = date; + emit dateChanged(date); +} + +void GLDCalendarTextNavigator::createDateLabel() +{ + if (m_dateFrame) + { + return; + } + m_dateFrame = new QFrame(m_widget); + QVBoxLayout *vl = new QVBoxLayout; + m_dateText = new QLabel; + vl->addWidget(m_dateText); + m_dateFrame->setLayout(vl); + m_dateFrame->setFrameShadow(QFrame::Plain); + m_dateFrame->setFrameShape(QFrame::Box); + m_dateValidator = new GLDCalendarDateValidator(); + m_dateValidator->setLocale(m_widget->locale()); + m_dateValidator->setFormat(m_widget->locale().dateFormat(QLocale::ShortFormat)); + m_dateValidator->setInitialDate(m_date); + + m_dateFrame->setAutoFillBackground(true); + m_dateFrame->setBackgroundRole(QPalette::Window); +} + +void GLDCalendarTextNavigator::removeDateLabel() +{ + if (!m_dateFrame) + { + return; + } + + m_acceptTimer.stop(); + m_dateFrame->hide(); + m_dateFrame->deleteLater(); + delete m_dateValidator; + m_dateFrame = 0; + m_dateText = 0; + m_dateValidator = 0; +} + +bool GLDCalendarTextNavigator::eventFilter(QObject *o, QEvent *e) +{ + if (m_widget) + { + if (e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease) + { + QKeyEvent* ke = (QKeyEvent*)e; + if ((ke->text().length() > 0 && ke->text()[0].isPrint()) || m_dateFrame) + { + if (ke->key() == Qt::Key_Return || ke->key() == Qt::Key_Enter || ke->key() == Qt::Key_Select) + { + applyDate(); + emit editingFinished(); + removeDateLabel(); + } + else if (ke->key() == Qt::Key_Escape) + { + removeDateLabel(); + } + else if (e->type() == QEvent::KeyPress) + { + createDateLabel(); + m_dateValidator->handleKeyEvent(ke); + updateDateLabel(); + } + ke->accept(); + return true; + } + // If we are navigating let the user finish his date in old locate. + // If we change our mind and want it to update immediately simply uncomment below + /* + } else if (e->type() == QEvent::LocaleChange) { + if (m_dateValidator) { + m_dateValidator->setLocale(m_widget->locale()); + m_dateValidator->setFormat(m_widget->locale().dateFormat(QLocale::ShortFormat)); + updateDateLabel(); + } + */ + } + } + return QObject::eventFilter(o,e); +} + +void GLDCalendarTextNavigator::timerEvent(QTimerEvent *e) +{ + if (e->timerId() == m_acceptTimer.timerId()) + { + applyDate(); + removeDateLabel(); + } +} + +int GLDCalendarTextNavigator::dateEditAcceptDelay() const +{ + return m_editDelay; +} + +void GLDCalendarTextNavigator::setDateEditAcceptDelay(int delay) +{ + m_editDelay = delay; +} + +GLDCalendarModel::GLDCalendarModel(const QDate &date, QObject *parent) : QAbstractTableModel(parent) +{ + m_date = date; + m_minimumDate = QDate::fromJulianDay(1); // 当前日历能表示的最小日期 + m_maximumDate = QDate(c_MaxYear, c_MaxMonth, c_MaxDay); // 当前日历能表示的最大日期 + m_shownYear = m_date.year(); + m_shownMonth = m_date.month(); + m_firstDay = QLocale().firstDayOfWeek(); + m_horizontalHeaderFormat = GLDCalendarWidget::ShortDayNames; + m_weekNumbersShown = true; + m_firstColumn = 1; + m_firstRow = 1; + m_view = 0; +} + +Qt::DayOfWeek GLDCalendarModel::dayOfWeekForColumn(int column) const +{ + int col = column - m_firstColumn; + if (col < 0 || col > c_daysPerWeek - 1) + { + return Qt::Sunday; + } + int day = m_firstDay + col; + if (day > c_daysPerWeek) + { + day -= c_daysPerWeek; + } + return Qt::DayOfWeek(day); +} + +int GLDCalendarModel::columnForDayOfWeek(Qt::DayOfWeek day) const +{ + if (day < 1 || day > c_daysPerWeek) + { + return -1; + } + int column = (int)day - (int)m_firstDay; + if (column < 0) + { + column += c_daysPerWeek; + } + return column + m_firstColumn; +} + +/* +This simple algorithm tries to generate a valid date from the month shown. +Some months don't contain a first day (e.g. Jan of -4713 year, +so QDate (-4713, 1, 1) would be invalid). In that case we try to generate +another valid date for that month. Later, returned date's day is the number of cells +calendar widget will reserve for days before referenceDate. (E.g. if returned date's +day is 16, that day will be placed in 3rd or 4th row, not in the 1st or 2nd row). +Depending on referenceData we can change behaviour of Oct 1582. If referenceDate is 1st +of Oct we render 1 Oct in 1st or 2nd row. If referenceDate is 17 of Oct we show always 16 +dates before 17 of Oct, and since this month contains the hole 5-14 Oct, the first of Oct +will be rendered in 2nd or 3rd row, showing more dates from previous month. +*/ +QDate GLDCalendarModel::referenceDate() const +{ + int refDay = 1; + while (refDay <= c_daysPerMonth) + { + QDate refDate(m_shownYear, m_shownMonth, refDay); + if (refDate.isValid()) + { + return refDate; + } + refDay += 1; + } + return QDate(); +} + +int GLDCalendarModel::columnForFirstOfMonth(const QDate &date) const +{ + return (columnForDayOfWeek(static_cast(date.dayOfWeek())) - (date.day() % c_daysPerWeek) + (c_daysPerWeek + 1)) % c_daysPerWeek; +} + +QDate GLDCalendarModel::dateForCell(int row, int column) const +{ + if (row < m_firstRow || row > m_firstRow + RowCount - 1 || + column < m_firstColumn || column > m_firstColumn + ColumnCount - 1) + { + return QDate(); + } + const QDate refDate = referenceDate(); + if (!refDate.isValid()) + { + return QDate(); + } + + const int columnForFirstOfShownMonth = columnForFirstOfMonth(refDate); + if (columnForFirstOfShownMonth - m_firstColumn < MinimumDayOffset) + { + row -= 1; + } + + const int requestedDay = c_daysPerWeek * (row - m_firstRow) + column - columnForFirstOfShownMonth - refDate.day() + 1; + return refDate.addDays(requestedDay); +} + +void GLDCalendarModel::cellForDate(const QDate &date, int *row, int *column) const +{ + if (!row && !column) + { + return; + } + + if (row) + { + *row = -1; + } + if (column) + { + *column = -1; + } + + const QDate refDate = referenceDate(); + if (!refDate.isValid()) + { + return; + } + + const int columnForFirstOfShownMonth = columnForFirstOfMonth(refDate); + const int requestedPosition = refDate.daysTo(date) - m_firstColumn + columnForFirstOfShownMonth + refDate.day() - 1; + + int c = requestedPosition % c_daysPerWeek; + int r = requestedPosition / c_daysPerWeek; + if (c < 0) + { + c += c_daysPerWeek; + r -= 1; + } + + if (columnForFirstOfShownMonth - m_firstColumn < MinimumDayOffset) + { + r += 1; + } + + if (r < 0 || r > RowCount - 1 || c < 0 || c > ColumnCount - 1) + { + return; + } + + if (row) + { + *row = r + m_firstRow; + } + if (column) + { + *column = c + m_firstColumn; + } +} + +QString GLDCalendarModel::dayName(Qt::DayOfWeek day) const +{ + switch (m_horizontalHeaderFormat) + { + case GLDCalendarWidget::SingleLetterDayNames: + { + QString standaloneDayName = m_view->locale().standaloneDayName(day, QLocale::NarrowFormat); + if (standaloneDayName == m_view->locale().dayName(day, QLocale::NarrowFormat)) + { + return standaloneDayName.at(1); + } + return standaloneDayName; + } + case GLDCalendarWidget::ShortDayNames: + return m_view->locale().dayName(day, QLocale::ShortFormat); + case GLDCalendarWidget::LongDayNames: + return m_view->locale().dayName(day, QLocale::LongFormat); + default: + break; + } + return QString(); +} + +QTextCharFormat GLDCalendarModel::formatForCell(int row, int col) const +{ + QPalette pal; + QPalette::ColorGroup cg = QPalette::Active; + if (m_view) + { + pal = m_view->palette(); + if (!m_view->isEnabled()) + { + cg = QPalette::Disabled; + } + else if (!m_view->isActiveWindow()) + { + cg = QPalette::Inactive; + } + } + + QTextCharFormat format; + format.setFont(m_view->font()); + bool header = (m_weekNumbersShown && col == HeaderColumn) + || (m_horizontalHeaderFormat != GLDCalendarWidget::NoHorizontalHeader && row == HeaderRow); + format.setBackground(pal.brush(cg, header ? QPalette::AlternateBase : QPalette::Base)); + format.setForeground(pal.brush(cg, QPalette::Text)); + if (header) + { + format.merge(m_headerFormat); + } + + if (col >= m_firstColumn && col < m_firstColumn + ColumnCount) + { + Qt::DayOfWeek dayOfWeek = dayOfWeekForColumn(col); + if (m_dayFormats.contains(dayOfWeek)) + { + format.merge(m_dayFormats.value(dayOfWeek)); + } + } + + if (!header) + { + QDate date = dateForCell(row, col); + format.merge(m_dateFormats.value(date)); + if(date < m_minimumDate || date > m_maximumDate) + { + format.setBackground(pal.brush(cg, QPalette::Window)); + } + if (m_shownMonth != date.month()) + { + format.setForeground(pal.brush(QPalette::Disabled, QPalette::Text)); + } + } + return format; +} + +QVariant GLDCalendarModel::data(const QModelIndex &index, int role) const +{ + if (role == Qt::TextAlignmentRole) + { + return (int) Qt::AlignCenter; + } + + int row = index.row(); + int column = index.column(); + + if(role == Qt::DisplayRole) + { + if (m_weekNumbersShown && column == HeaderColumn + && row >= m_firstRow && row < m_firstRow + RowCount) + { + QDate date = dateForCell(row, columnForDayOfWeek(Qt::Monday)); + if (date.isValid()) + { + return date.weekNumber(); + } + } + if (m_horizontalHeaderFormat != GLDCalendarWidget::NoHorizontalHeader && row == HeaderRow + && column >= m_firstColumn && column < m_firstColumn + ColumnCount) + { + return dayName(dayOfWeekForColumn(column)); + } + QDate date = dateForCell(row, column); + if (date.isValid()) + { + return date.day(); + } + return QString(); + } + + QTextCharFormat fmt = formatForCell(row, column); + if (role == Qt::BackgroundColorRole) + { + return fmt.background().color(); + } + if (role == Qt::TextColorRole) + { + return fmt.foreground().color(); + } + if (role == Qt::FontRole) + { + return fmt.font(); + } + if (role == Qt::ToolTipRole) + { + return fmt.toolTip(); + } + return QVariant(); +} + +Qt::ItemFlags GLDCalendarModel::flags(const QModelIndex &index) const +{ + QDate date = dateForCell(index.row(), index.column()); + if (!date.isValid()) + { + return QAbstractTableModel::flags(index); + } + if (date < m_minimumDate) + { + return 0; + } + if (date > m_maximumDate) + { + return 0; + } + return QAbstractTableModel::flags(index); +} + +void GLDCalendarModel::setDate(const QDate &d) +{ + m_date = d; + if (m_date < m_minimumDate) + { + m_date = m_minimumDate; + } + else if (m_date > m_maximumDate) + { + m_date = m_maximumDate; + } +} + +void GLDCalendarModel::showMonth(int year, int month) +{ + if (m_shownYear == year && m_shownMonth == month) + { + return; + } + + m_shownYear = year; + m_shownMonth = month; + + internalUpdate(); +} + +void GLDCalendarModel::setMinimumDate(const QDate &d) +{ + if (!d.isValid() || d == m_minimumDate) + { + return; + } + + m_minimumDate = d; + if (m_maximumDate < m_minimumDate) + { + m_maximumDate = m_minimumDate; + } + if (m_date < m_minimumDate) + { + m_date = m_minimumDate; + } + internalUpdate(); +} + +void GLDCalendarModel::setMaximumDate(const QDate &d) +{ + if (!d.isValid() || d == m_maximumDate) + { + return; + } + + m_maximumDate = d; + if (m_minimumDate > m_maximumDate) + { + m_minimumDate = m_maximumDate; + } + if (m_date > m_maximumDate) + { + m_date = m_maximumDate; + } + internalUpdate(); +} + +void GLDCalendarModel::setRange(const QDate &min, const QDate &max) +{ + m_minimumDate = min; + m_maximumDate = max; + if (m_minimumDate > m_maximumDate) + { + qSwap(m_minimumDate, m_maximumDate); + } + if (m_date < m_minimumDate) + { + m_date = m_minimumDate; + } + if (m_date > m_maximumDate) + { + m_date = m_maximumDate; + } + internalUpdate(); +} + +void GLDCalendarModel::internalUpdate() +{ + QModelIndex begin = index(0, 0); + QModelIndex end = index(m_firstRow + RowCount - 1, m_firstColumn + ColumnCount - 1); + emit dataChanged(begin, end); + emit headerDataChanged(Qt::Vertical, 0, m_firstRow + RowCount - 1); + emit headerDataChanged(Qt::Horizontal, 0, m_firstColumn + ColumnCount - 1); +} + +void GLDCalendarModel::setHorizontalHeaderFormat(GLDCalendarWidget::HorizontalHeaderFormat format) +{ + if (m_horizontalHeaderFormat == format) + { + return; + } + + int oldFormat = m_horizontalHeaderFormat; + m_horizontalHeaderFormat = format; + if (oldFormat == GLDCalendarWidget::NoHorizontalHeader) + { + m_firstRow = 1; + insertRow(0); + } + else if (m_horizontalHeaderFormat == GLDCalendarWidget::NoHorizontalHeader) + { + m_firstRow = 0; + removeRow(0); + } + internalUpdate(); +} + +void GLDCalendarModel::setFirstColumnDay(Qt::DayOfWeek dayOfWeek) +{ + if (m_firstDay == dayOfWeek) + { + return; + } + + m_firstDay = dayOfWeek; + internalUpdate(); +} + +Qt::DayOfWeek GLDCalendarModel::firstColumnDay() const +{ + return m_firstDay; +} + +bool GLDCalendarModel::weekNumbersShown() const +{ + return m_weekNumbersShown; +} + +void GLDCalendarModel::setWeekNumbersShown(bool show) +{ + if (m_weekNumbersShown == show) + { + return; + } + + m_weekNumbersShown = show; + if (show) + { + m_firstColumn = 1; + insertColumn(0); + } + else + { + m_firstColumn = 0; + removeColumn(0); + } + internalUpdate(); +} + +GLDCalendarView::GLDCalendarView(QWidget *parent) + : QTableView(parent), + m_readOnly(false), + m_validDateClicked(false) +{ + setTabKeyNavigation(false); + setShowGrid(false); + verticalHeader()->setVisible(false); + horizontalHeader()->setVisible(false); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); +} + +QModelIndex GLDCalendarView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers) +{ + GLDCalendarModel *calendarModel = qobject_cast(model()); + if (!calendarModel) + { + return QTableView::moveCursor(cursorAction, modifiers); + } + + if (m_readOnly) + { + return currentIndex(); + } + + QModelIndex index = currentIndex(); + QDate currentDate = static_cast(model())->dateForCell(index.row(), index.column()); + switch (cursorAction) + { + case QAbstractItemView::MoveUp: + currentDate = currentDate.addDays(- c_daysPerWeek); + break; + case QAbstractItemView::MoveDown: + currentDate = currentDate.addDays(c_daysPerWeek); + break; + case QAbstractItemView::MoveLeft: + currentDate = currentDate.addDays(isRightToLeft() ? 1 : -1); + break; + case QAbstractItemView::MoveRight: + currentDate = currentDate.addDays(isRightToLeft() ? -1 : 1); + break; + case QAbstractItemView::MoveHome: + currentDate = QDate(currentDate.year(), currentDate.month(), 1); + break; + case QAbstractItemView::MoveEnd: + currentDate = QDate(currentDate.year(), currentDate.month(), currentDate.daysInMonth()); + break; + case QAbstractItemView::MovePageUp: + currentDate = currentDate.addMonths(-1); + break; + case QAbstractItemView::MovePageDown: + currentDate = currentDate.addMonths(1); + break; + case QAbstractItemView::MoveNext: + case QAbstractItemView::MovePrevious: + return currentIndex(); + default: + break; + } + emit changeDate(currentDate, true); + return currentIndex(); +} + +void GLDCalendarView::keyPressEvent(QKeyEvent *event) +{ +#ifdef QT_KEYPAD_NAVIGATION + if (event->key() == Qt::Key_Select) + { + if (QApplication::keypadNavigationEnabled()) + { + if (!hasEditFocus()) + { + setEditFocus(true); + return; + } + } + } + else if (event->key() == Qt::Key_Back) + { + if (QApplication::keypadNavigationEnabled() && hasEditFocus()) + { + if (qobject_cast(model())) + { + emit changeDate(origDate, true); //changes selection back to origDate, but doesn't activate + setEditFocus(false); + return; + } + } + } +#endif + + if (!m_readOnly) + { + switch (event->key()) + { + case Qt::Key_Return: + case Qt::Key_Enter: + case Qt::Key_Select: + emit editingFinished(); + return; + default: + break; + } + } + QTableView::keyPressEvent(event); +} + +#ifndef QT_NO_WHEELEVENT +void GLDCalendarView::wheelEvent(QWheelEvent *event) +{ + const int numDegrees = event->delta() / 8; + const int numSteps = numDegrees / 15; + const QModelIndex index = currentIndex(); + QDate currentDate = static_cast(model())->dateForCell(index.row(), index.column()); + currentDate = currentDate.addMonths(-numSteps); + emit showDate(currentDate); +} +#endif + +bool GLDCalendarView::event(QEvent *event) +{ +#ifdef QT_KEYPAD_NAVIGATION + if (event->type() == QEvent::FocusIn) + { + if (GLDCalendarModel *calendarModel = qobject_cast(model())) + { + origDate = calendarModel->m_date; + } + } +#endif + + return QTableView::event(event); +} + +QDate GLDCalendarView::handleMouseEvent(QMouseEvent *event) +{ + GLDCalendarModel *calendarModel = qobject_cast(model()); + if (!calendarModel) + { + return QDate(); + } + + QPoint pos = event->pos(); + QModelIndex index = indexAt(pos); + QDate date = calendarModel->dateForCell(index.row(), index.column()); + if (date.isValid() && date >= calendarModel->m_minimumDate + && date <= calendarModel->m_maximumDate) + { + return date; + } + return QDate(); +} + +void GLDCalendarView::mouseDoubleClickEvent(QMouseEvent *event) +{ + GLDCalendarModel *calendarModel = qobject_cast(model()); + if (!calendarModel) + { + QTableView::mouseDoubleClickEvent(event); + return; + } + + if (m_readOnly) + { + return; + } + + QDate date = handleMouseEvent(event); + m_validDateClicked = false; + if (date == calendarModel->m_date && !style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick)) + { + emit editingFinished(); + } +} + +void GLDCalendarView::mousePressEvent(QMouseEvent *event) +{ + GLDCalendarModel *calendarModel = qobject_cast(model()); + if (!calendarModel) + { + QTableView::mousePressEvent(event); + return; + } + + if (m_readOnly) + { + return; + } + + if (event->button() != Qt::LeftButton) + { + return; + } + + QDate date = handleMouseEvent(event); + if (date.isValid()) + { + m_validDateClicked = true; + int row = -1, col = -1; + static_cast(model())->cellForDate(date, &row, &col); + if (row != -1 && col != -1) + { + selectionModel()->setCurrentIndex(model()->index(row, col), QItemSelectionModel::NoUpdate); + } + } + else + { + m_validDateClicked = false; + event->ignore(); + } +} + +void GLDCalendarView::mouseMoveEvent(QMouseEvent *event) +{ + GLDCalendarModel *calendarModel = qobject_cast(model()); + if (!calendarModel) + { + QTableView::mouseMoveEvent(event); + return; + } + + if (m_readOnly) + { + return; + } + + if (m_validDateClicked) + { + QDate date = handleMouseEvent(event); + if (date.isValid()) + { + int row = -1, col = -1; + static_cast(model())->cellForDate(date, &row, &col); + if (row != -1 && col != -1) + { + selectionModel()->setCurrentIndex(model()->index(row, col), QItemSelectionModel::NoUpdate); + } + } + } + else + { + event->ignore(); + } +} + +void GLDCalendarView::mouseReleaseEvent(QMouseEvent *event) +{ + GLDCalendarModel *calendarModel = qobject_cast(model()); + if (!calendarModel) + { + QTableView::mouseReleaseEvent(event); + return; + } + + if (event->button() != Qt::LeftButton) + { + return; + } + + if (m_readOnly) + { + return; + } + + if (m_validDateClicked) + { + QDate date = handleMouseEvent(event); + if (date.isValid()) + { + emit changeDate(date, true); + emit clicked(date); + if (style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick)) + { + emit editingFinished(); + } + } + m_validDateClicked = false; + } + else + { + event->ignore(); + } +} + +void GLDCalendarDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + QDate date = calendarWidgetPrivate->m_model->dateForCell(index.row(), index.column()); + if (date.isValid()) + { + storedOption = option; + QRect rect = option.rect; + calendarWidgetPrivate->paintCell(painter, rect, date); + } + else + { + QItemDelegate::paint(painter, option, index); + } +} + +void GLDCalendarDelegate::paintCell(QPainter *painter, const QRect &rect, const QDate &date) const +{ + storedOption.rect = rect; + int row = -1; + int col = -1; + calendarWidgetPrivate->m_model->cellForDate(date, &row, &col); + QModelIndex idx = calendarWidgetPrivate->m_model->index(row, col); + QItemDelegate::paint(painter, storedOption, idx); +} + +GLDCalendarWidgetPrivate::GLDCalendarWidgetPrivate() + : QWidgetPrivate() +{ + m_model = 0; + m_view = 0; + m_delegate = 0; + m_selection = 0; + m_navigator = 0; + m_dateEditEnabled = false; + m_navBarVisible = true; + m_oldFocusPolicy = Qt::StrongFocus; +} + +void GLDCalendarWidgetPrivate::setNavigatorEnabled(bool enable) +{ + Q_Q(GLDCalendarWidget); + + bool navigatorEnabled = (m_navigator->widget() != 0); + if (enable == navigatorEnabled) + { + return; + } + + if (enable) + { + m_navigator->setWidget(q); + q->connect(m_navigator, SIGNAL(dateChanged(QDate)), + q, SLOT(_q_slotChangeDate(QDate))); + q->connect(m_navigator, SIGNAL(editingFinished()), + q, SLOT(_q_editingFinished())); + m_view->installEventFilter(m_navigator); + } + else + { + m_navigator->setWidget(0); + q->disconnect(m_navigator, SIGNAL(dateChanged(QDate)), + q, SLOT(_q_slotChangeDate(QDate))); + q->disconnect(m_navigator, SIGNAL(editingFinished()), + q, SLOT(_q_editingFinished())); + m_view->removeEventFilter(m_navigator); + } +} + +void GLDCalendarWidgetPrivate::createNavigationBar(QWidget *widget) +{ + Q_Q(GLDCalendarWidget); + m_navBarBackground = new QWidget(widget); + m_navBarBackground->setProperty("GLDNavBackground", true); + m_navBarBackground->setFixedSize(c_navBarWidth, c_navBarHeight); + m_navBarBackground->setObjectName(QLatin1String("qt_calendar_navigationbar")); + m_navBarBackground->setAutoFillBackground(true); + + m_prevMonth = new QPushButton(m_navBarBackground); + m_nextMonth = new QPushButton(m_navBarBackground); + updateButtonIcons(); + m_prevMonth->setAutoRepeat(true); + m_nextMonth->setAutoRepeat(true); + m_prevMonth->setFlat(true); + m_nextMonth->setFlat(true); + + m_monthComboBox = new QComboBox(m_navBarBackground); + m_monthComboBox->setView(new QListView()); + m_monthComboBox->setFixedSize(QSize(c_monthComboBoxWidth, c_monthComboBoxHeight)); + m_monthComboBox->view()->setFixedHeight(c_monthComboBoxViewHeight); + for (int i = 1; i <= c_monthsPerYear; i++) + { + QString monthName(QString("%1").arg(i) + getGLDi18nStr((g_rsMonth))); + m_monthComboBox->addItem(monthName); + } + m_yearButton = new GLDCalToolButton(m_navBarBackground); + m_yearButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum); + m_yearButton->setAutoRaise(true); + m_yearEdit = new QSpinBox(m_navBarBackground); + m_yearText = new QLabel(m_navBarBackground); + m_yearText->setText(getGLDi18nStr(g_rsYear)); + + m_yearButton->setProperty("GLDYearToolBtn", true); + m_yearEdit->setProperty("GLDYearSpinBox", true); + m_monthComboBox->setProperty("GLDMonthComboBox", true); + + QFont font = q->font(); + font.setBold(true); + m_yearButton->setFont(font); + m_yearEdit->setFrame(false); + m_yearEdit->setFixedSize(c_yearEditWidth, c_yearEditHeight); + m_yearEdit->setMinimum(m_model->m_minimumDate.year()); + m_yearEdit->setMaximum(m_model->m_maximumDate.year()); + m_yearEdit->hide(); + m_yearText->setFont(font); + m_spaceHolder = new QSpacerItem(0,0); + + QHBoxLayout *pheaderLayout = new QHBoxLayout; + pheaderLayout->setMargin(0); + pheaderLayout->setSpacing(0); + pheaderLayout->addWidget(m_prevMonth); + pheaderLayout->insertStretch(pheaderLayout->count()); + pheaderLayout->addWidget(m_yearButton); + pheaderLayout->addWidget(m_yearText); + pheaderLayout->addItem(m_spaceHolder); + pheaderLayout->addWidget(m_monthComboBox); + pheaderLayout->insertStretch(pheaderLayout->count()); + pheaderLayout->addWidget(m_nextMonth); + m_navBarBackground->setLayout(pheaderLayout); + + m_yearEdit->setFocusPolicy(Qt::StrongFocus); + m_prevMonth->setFocusPolicy(Qt::NoFocus); + m_nextMonth->setFocusPolicy(Qt::NoFocus); + m_yearButton->setFocusPolicy(Qt::NoFocus); + m_monthComboBox->setFocusPolicy(Qt::NoFocus); + m_yearText->setFocusPolicy(Qt::NoFocus); + + //set names for the header controls. + m_prevMonth->setObjectName(QLatin1String("qt_calendar_prevmonth")); + m_nextMonth->setObjectName(QLatin1String("qt_calendar_nextmonth")); + m_monthComboBox->setObjectName(QLatin1String("qt_calendar_monthComboBox")); + m_yearButton->setObjectName(QLatin1String("qt_calendar_yearbutton")); + m_yearEdit->setObjectName(QLatin1String("qt_calendar_yearedit")); + m_yearText->setObjectName(QLatin1String("qt_calendar_yearText")); + + showMonth(m_model->m_date.year(), m_model->m_date.month()); +} + +void GLDCalendarWidgetPrivate::updateButtonIcons() +{ + m_prevMonth->setIcon(QIcon(":/icons/arrowleft.png")); + m_nextMonth->setIcon(QIcon(":/icons/arrowright.png")); +} + +void GLDCalendarWidgetPrivate::updateMonthMenu() +{ + int beg = 1, end = c_monthsPerYear; + bool prevEnabled = true; + bool nextEnabled = true; + if (m_model->m_shownYear == m_model->m_minimumDate.year()) + { + beg = m_model->m_minimumDate.month(); + if (m_model->m_shownMonth == m_model->m_minimumDate.month()) + { + prevEnabled = false; + } + } + if (m_model->m_shownYear == m_model->m_maximumDate.year()) + { + end = m_model->m_maximumDate.month(); + if (m_model->m_shownMonth == m_model->m_maximumDate.month()) + { + nextEnabled = false; + } + } + m_prevMonth->setEnabled(prevEnabled); + m_nextMonth->setEnabled(nextEnabled); +} + +void GLDCalendarWidgetPrivate::updateCurrentPage(const QDate &date) +{ + Q_Q(GLDCalendarWidget); + + QDate newDate = date; + QDate minDate = q->minimumDate(); + QDate maxDate = q->maximumDate(); + if (minDate.isValid()&& minDate.daysTo(newDate) < 0) + { + newDate = minDate; + } + if (maxDate.isValid()&& maxDate.daysTo(newDate) > 0) + { + newDate = maxDate; + } + showMonth(newDate.year(), newDate.month()); + int row = -1, col = -1; + m_model->cellForDate(newDate, &row, &col); + if (row != -1 && col != -1) + { + m_view->selectionModel()->setCurrentIndex(m_model->index(row, col), + QItemSelectionModel::NoUpdate); + } +} + +void GLDCalendarWidgetPrivate::_q_monthChanged(int monthNum) +{ + QDate currentDate = getCurrentDate(); + QDate newDate = currentDate.addMonths(monthNum - currentDate.month() + 1); + updateCurrentPage(newDate); +} + +QDate GLDCalendarWidgetPrivate::getCurrentDate() +{ + QModelIndex index = m_view->currentIndex(); + return m_model->dateForCell(index.row(), index.column()); +} + +void GLDCalendarWidgetPrivate::_q_prevMonthClicked() +{ + QDate currentDate = getCurrentDate().addMonths(-1); + updateCurrentPage(currentDate); +} + +void GLDCalendarWidgetPrivate::_q_nextMonthClicked() +{ + QDate currentDate = getCurrentDate().addMonths(1); + updateCurrentPage(currentDate); +} + +void GLDCalendarWidgetPrivate::_q_yearEditingFinished() +{ + Q_Q(GLDCalendarWidget); + int nYear = m_yearEdit->text().toInt(); + + if (nYear < c_MinYear || nYear > c_MaxYear) + { + nYear = m_model->m_shownYear; + } + m_yearEdit->setValue(nYear); + m_yearButton->setText(QString("%1").arg(nYear)); + m_yearEdit->hide(); + q->setFocusPolicy(m_oldFocusPolicy); + qApp->removeEventFilter(q); + m_spaceHolder->changeSize(0, 0); + m_yearButton->show(); + QDate currentDate = getCurrentDate(); + currentDate = currentDate.addYears(nYear - currentDate.year()); + updateCurrentPage(currentDate); + q->setFocus(); +} + +void GLDCalendarWidgetPrivate::_q_yearClicked() +{ + Q_Q(GLDCalendarWidget); + //show the spinbox on top of the button + // 4为yearEdit的y坐标偏移量 + m_yearEdit->setGeometry(m_yearButton->x(), m_yearButton->y() + c_yearEditHeightErr, + m_yearEdit->sizeHint().width(), m_yearButton->height()); + m_spaceHolder->changeSize(m_yearButton->width(), 0); + m_yearButton->hide(); + m_oldFocusPolicy = q->focusPolicy(); + q->setFocusPolicy(Qt::NoFocus); + m_yearEdit->show(); + qApp->installEventFilter(q); + m_yearEdit->raise(); + m_yearEdit->selectAll(); + m_yearEdit->setFocus(Qt::MouseFocusReason); + + // yearText的横坐标偏移量为2, 纵坐标偏移量为-4 + m_yearText->setGeometry(m_yearEdit->x() + m_yearEdit->width() + c_yearTextWidthErr, + m_yearEdit->y() + c_yearTextHeightErr, m_yearText->sizeHint().width(), m_yearText->height()); + // monthComboBox的横坐标偏移量为2, 纵坐标偏移量为4 + m_monthComboBox->setGeometry(m_yearText->x() + m_yearText->width() + c_monthComboBoxWidthErr, + m_yearText->y() + c_monthComboBoxHeightErr, m_monthComboBox->sizeHint().width(), + m_monthComboBox->height()); +} + +void GLDCalendarWidgetPrivate::showMonth(int year, int month) +{ + if (m_model->m_shownYear == year && m_model->m_shownMonth == month) + { + return; + } + Q_Q(GLDCalendarWidget); + m_model->showMonth(year, month); + updateNavigationBar(); + emit q->currentPageChanged(year, month); + m_view->internalUpdate(); + m_cachedSizeHint = QSize(); + update(); + updateMonthMenu(); +} + +void GLDCalendarWidgetPrivate::updateNavigationBar() +{ + m_monthComboBox->setCurrentIndex(m_model->m_shownMonth - 1); + m_yearButton->setText(QString::number(m_model->m_shownYear)); + m_yearEdit->setValue(m_model->m_shownYear); +} + +void GLDCalendarWidgetPrivate::update() +{ + QDate currentDate = m_model->m_date; + int row, column; + m_model->cellForDate(currentDate, &row, &column); + QModelIndex idx; + m_selection->clear(); + if (row != -1 && column != -1) + { + idx = m_model->index(row, column); + m_selection->setCurrentIndex(idx, QItemSelectionModel::SelectCurrent); + } +} + +void GLDCalendarWidgetPrivate::paintCell(QPainter *painter, const QRect &rect, const QDate &date) const +{ + Q_Q(const GLDCalendarWidget); + q->paintCell(painter, rect, date); +} + +void GLDCalendarWidgetPrivate::_q_slotShowDate(const QDate &date) +{ + updateCurrentPage(date); +} + +void GLDCalendarWidgetPrivate::_q_slotChangeDate(const QDate &date) +{ + _q_slotChangeDate(date, true); +} + +void GLDCalendarWidgetPrivate::_q_slotChangeDate(const QDate &date, bool changeMonth) +{ + QDate oldDate = m_model->m_date; + m_model->setDate(date); + QDate newDate = m_model->m_date; + if (changeMonth) + { + showMonth(newDate.year(), newDate.month()); + } + if (oldDate != newDate) + { + update(); + Q_Q(GLDCalendarWidget); + m_navigator->setDate(newDate); + emit q->selectionChanged(); + } +} + +void GLDCalendarWidgetPrivate::_q_slotPassDateToEdit(const QDate &date, bool changeMonth) +{ + Q_Q(GLDCalendarWidget); + emit q->passDateToEdit(date); + Q_UNUSED(changeMonth); +} + +void GLDCalendarWidgetPrivate::_q_editingFinished() +{ + Q_Q(GLDCalendarWidget); + emit q->activated(m_model->m_date); +} + +/*! + \class QCalendarWidget + \brief The QCalendarWidget class provides a monthly based + calendar widget allowing the user to select a date. + \since 4.2 + + \ingroup advanced + \inmodule QtWidgets + + \image fusion-calendarwidget.png + + The widget is initialized with the current month and year, but + QCalendarWidget provides several public slots to change the year + and month that is shown. + + By default, today's date is selected, and the user can select a + date using both mouse and keyboard. The currently selected date + can be retrieved using the selectedDate() function. It is + possible to constrain the user selection to a given date range by + setting the minimumDate and maximumDate properties. + Alternatively, both properties can be set in one go using the + setDateRange() convenience slot. Set the \l selectionMode + property to NoSelection to prohibit the user from selecting at + all. Note that a date also can be selected programmatically using + the setSelectedDate() slot. + + The currently displayed month and year can be retrieved using the + monthShown() and yearShown() functions, respectively. + + A newly created calendar widget uses abbreviated day names, and + both Saturdays and Sundays are marked in red. The calendar grid is + not visible. The week numbers are displayed, and the first column + day is the first day of the week for the calendar's locale. + + The notation of the days can be altered to a single letter + abbreviations ("M" for "Monday") by setting the + horizontalHeaderFormat property to + QCalendarWidget::SingleLetterDayNames. Setting the same property + to QCalendarWidget::LongDayNames makes the header display the + complete day names. The week numbers can be removed by setting + the verticalHeaderFormat property to + QCalendarWidget::NoVerticalHeader. The calendar grid can be + turned on by setting the gridVisible property to true using the + setGridVisible() function: + + \table + \row \li + \image qcalendarwidget-grid.png + \row \li + \snippet code/src_gui_widgets_qcalendarwidget.cpp 0 + \endtable + + Finally, the day in the first column can be altered using the + setFirstDayOfWeek() function. + + The QCalendarWidget class also provides three signals, + selectionChanged(), activated() and currentPageChanged() making it + possible to respond to user interaction. + + The rendering of the headers, weekdays or single days can be + largely customized by setting QTextCharFormat's for some special + weekday, a special date or for the rendering of the headers. + + Only a subset of the properties in QTextCharFormat are used by the + calendar widget. Currently, the foreground, background and font + properties are used to determine the rendering of individual cells + in the widget. + + \sa QDate, QDateEdit, QTextCharFormat +*/ + +/*! + \enum QCalendarWidget::SelectionMode + + This enum describes the types of selection offered to the user for + selecting dates in the calendar. + + \value NoSelection Dates cannot be selected. + \value SingleSelection Single dates can be selected. + + \sa selectionMode +*/ + +/*! + Constructs a calendar widget with the given \a parent. + + The widget is initialized with the current month and year, and the + currently selected date is today. + + \sa setCurrentPage() +*/ +GLDCalendarWidget::GLDCalendarWidget(QDateTime &dt, QWidget *parent) : + QWidget(*new GLDCalendarWidgetPrivate(), parent, 0), + m_dateTime(dt) +{ + Q_D(GLDCalendarWidget); + setFixedSize(c_calendarWidgetWidth, c_calendarWidgetHeight); + setAutoFillBackground(true); + setBackgroundRole(QPalette::Window); + + QVBoxLayout *layoutV = new QVBoxLayout(this); + layoutV->setMargin(0); + d->m_model = new GLDCalendarModel(dt.date(), this); + QTextCharFormat fmt; + fmt.setForeground(QBrush(Qt::red)); + d->m_model->m_dayFormats.insert(Qt::Saturday, fmt); + d->m_model->m_dayFormats.insert(Qt::Sunday, fmt); + d->m_view = new GLDCalendarView(this); + d->m_view->setObjectName(QLatin1String("qt_calendar_calendarview")); + d->m_view->setModel(d->m_model); + d->m_model->setView(d->m_view); + d->m_view->setSelectionBehavior(QAbstractItemView::SelectItems); + d->m_view->setSelectionMode(QAbstractItemView::SingleSelection); + d->m_view->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + d->m_view->horizontalHeader()->setSectionsClickable(false); + d->m_view->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch); + d->m_view->verticalHeader()->setSectionsClickable(false); + d->m_selection = d->m_view->selectionModel(); + d->createNavigationBar(this); + d->m_view->setFrameStyle(QFrame::NoFrame); + d->m_delegate = new GLDCalendarDelegate(d, this); + d->m_view->setItemDelegate(d->m_delegate); + d->update(); + d->updateNavigationBar(); + setFocusPolicy(Qt::StrongFocus); + setFocusProxy(d->m_view); + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + setGridVisible(true); + setVerticalHeaderFormat(GLDCalendarWidget::NoVerticalHeader); + setHorizontalHeaderFormat(GLDCalendarWidget::NoHorizontalHeader); + + setWeekdayTextColor(); + setWeekendTextColor(); + + QTextCharFormat headFormat; + QFont font; + font.setBold(true); + headFormat.setFont(font); + headFormat.setForeground(QBrush(QColor("#000000"))); + setHeaderTextFormat(headFormat); + + layoutV->setMargin(0); + layoutV->setSpacing(0); + layoutV->addWidget(d->m_navBarBackground); + // 除了导航栏,下面的部分 + QWidget *pCalendarWidget = new QWidget(this); + pCalendarWidget->setProperty("GLDCalendarWidget", true); + pCalendarWidget->setFixedSize(c_calendarWidgetWidth, c_calendarWidgetHeight - 30); // 30为出去导航栏后下面的日历部分 + layoutV->addWidget(pCalendarWidget); + + QHBoxLayout *pCalendarLayout = new QHBoxLayout(pCalendarWidget); + pCalendarLayout->setContentsMargins(0, 0, 0, 0); + // 主要是为了实现圆角 + QWidget *pCalendarBody = new QWidget(this); + pCalendarBody->setFixedSize(c_calendarBodyWidth, c_calendarBodyHeight); + pCalendarBody->setProperty("GLDCalendarBody", true); + pCalendarLayout->addWidget(pCalendarBody); + + QVBoxLayout *pCalendarBodyLayout = new QVBoxLayout(pCalendarBody); + pCalendarBodyLayout->setContentsMargins(c_calendarBodyLayoutMargin, 0, c_calendarBodyLayoutMargin, c_calendarBodyLayoutMargin); + // 日历头,包含了星期一~星期日 + addCalendarHead(); + pCalendarBodyLayout->addWidget(m_calendarHead); + pCalendarBodyLayout->addWidget(d->m_view); + + d->m_navigator = new GLDCalendarTextNavigator(this); + setDateEditEnabled(true); + setSelectedDate(m_dateTime.date()); + + connect(d->m_view, SIGNAL(showDate(QDate)), + this, SLOT(_q_slotShowDate(QDate))); + connect(d->m_view, SIGNAL(changeDate(QDate, bool)), + this, SLOT(_q_slotChangeDate(QDate, bool))); + connect(d->m_view, SIGNAL(changeDate(QDate, bool)), + this, SLOT(_q_slotPassDateToEdit(QDate, bool))); + connect(d->m_view, SIGNAL(clicked(QDate)), + this, SIGNAL(clicked(QDate))); + connect(d->m_view, SIGNAL(editingFinished()), + this, SLOT(_q_editingFinished())); + + connect(d->m_prevMonth, SIGNAL(clicked(bool)), + this, SLOT(_q_prevMonthClicked())); + connect(d->m_nextMonth, SIGNAL(clicked(bool)), + this, SLOT(_q_nextMonthClicked())); + connect(d->m_yearButton, SIGNAL(clicked(bool)), + this, SLOT(_q_yearClicked())); + connect(d->m_monthComboBox, SIGNAL(activated(int)), + this, SLOT(_q_monthChanged(int))); + connect(d->m_yearEdit, SIGNAL(editingFinished()), + this, SLOT(_q_yearEditingFinished())); +} + +/*! + Destroys the calendar widget. +*/ +GLDCalendarWidget::~GLDCalendarWidget() +{ + +} + +/*! + \reimp +*/ +QSize GLDCalendarWidget::sizeHint() const +{ + return minimumSizeHint(); +} + +/*! + \reimp +*/ +QSize GLDCalendarWidget::minimumSizeHint() const +{ + Q_D(const GLDCalendarWidget); + if (d->m_cachedSizeHint.isValid()) + { + return d->m_cachedSizeHint; + } + + ensurePolished(); + + int w = 0; + int h = 0; + + int end = 53; + int rows = RowCount + 1; + int cols = ColumnCount + 1; + + const int marginH = (style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1) * 2; + + if (horizontalHeaderFormat() == GLDCalendarWidget::NoHorizontalHeader) + { + rows = RowCount; + } + else + { + for (int i = 1; i <= ColumnCount; i++) + { + QFontMetrics fm(d->m_model->formatForCell(0, i).font()); + w = qMax(w, fm.width(d->m_model->dayName(d->m_model->dayOfWeekForColumn(i))) + marginH); + h = qMax(h, fm.height()); + } + } + + if (verticalHeaderFormat() == GLDCalendarWidget::NoVerticalHeader) + { + cols = ColumnCount; + } + else + { + for (int i = 1; i <= RowCount; i++) + { + QFontMetrics fm(d->m_model->formatForCell(i, 0).font()); + for (int j = 1; j < end; j++) + { + w = qMax(w, fm.width(QString::number(j)) + marginH); + } + h = qMax(h, fm.height()); + } + } + + QFontMetrics fm(d->m_model->formatForCell(1, 1).font()); + for (int i = 1; i <= end; i++) + { + w = qMax(w, fm.width(QString::number(i)) + marginH); + h = qMax(h, fm.height()); + } + + if (d->m_view->showGrid()) + { + // hardcoded in tableview + w += 1; + h += 1; + } + + w += 1; // default column span + + h = qMax(h, d->m_view->verticalHeader()->minimumSectionSize()); + w = qMax(w, d->m_view->horizontalHeader()->minimumSectionSize()); + + //add the size of the header. + QSize headerSize(0, 0); + if (d->m_navBarVisible) + { + int headerH = d->m_navBarBackground->sizeHint().height(); + int headerW = 0; + + headerW += d->m_prevMonth->sizeHint().width(); + headerW += d->m_nextMonth->sizeHint().width(); + + QFontMetrics fm = d->m_monthComboBox->fontMetrics(); + int monthW = 0; + for (int i = 1; i < c_monthsPerYear; i++) + { + QString monthName = QString("%1").arg(i) + getGLDi18nStr(g_rsMonth);//locale().standaloneMonthName(i, QLocale::LongFormat); + monthW = qMax(monthW, fm.boundingRect(monthName).width()); + } + headerW += monthW; + + fm = d->m_yearButton->fontMetrics(); + headerW += fm.boundingRect(QLatin1String("5555")).width()/* + buttonDecoMargin*/; + + headerSize = QSize(headerW, headerH); + } + w *= cols; + w = qMax(headerSize.width(), w); + h = (h * rows) + headerSize.height(); + d->m_cachedSizeHint = QSize(w, h); + return d->m_cachedSizeHint; +} + +/*! + Paints the cell specified by the given \a date, using the given \a painter and \a rect. +*/ + +void GLDCalendarWidget::paintCell(QPainter *painter, const QRect &rect, const QDate &date) const +{ + Q_D(const GLDCalendarWidget); + d->m_delegate->paintCell(painter, rect, date); +} + +/*! + \property GLDCalendarWidget::selectedDate + \brief the currently selected date. + + The selected date must be within the date range specified by the + minimumDate and maximumDate properties. By default, the selected + date is the current date. + + \sa setDateRange() +*/ + +QDate GLDCalendarWidget::selectedDate() const +{ + Q_D(const GLDCalendarWidget); + return d->m_model->m_date; +} + +void GLDCalendarWidget::setSelectedDate(const QDate &date) +{ + Q_D(GLDCalendarWidget); + if (d->m_model->m_date == date && date == d->getCurrentDate()) + { + return; + } + + if (!date.isValid()) + { + return; + } + + d->m_model->setDate(date); + d->update(); + QDate newDate = d->m_model->m_date; + d->showMonth(newDate.year(), newDate.month()); + emit selectionChanged(); +} + +/*! + Returns the year of the currently displayed month. Months are + numbered from 1 to 12. + + \sa monthShown(), setCurrentPage() +*/ + +int GLDCalendarWidget::yearShown() const +{ + Q_D(const GLDCalendarWidget); + return d->m_model->m_shownYear; +} + +/*! + Returns the currently displayed month. Months are numbered from 1 to + 12. + + \sa yearShown(), setCurrentPage() +*/ + +int GLDCalendarWidget::monthShown() const +{ + Q_D(const GLDCalendarWidget); + return d->m_model->m_shownMonth; +} + +/*! + Displays the given \a month of the given \a year without changing + the selected date. Use the setSelectedDate() function to alter the + selected date. + + The currently displayed month and year can be retrieved using the + monthShown() and yearShown() functions respectively. + + \sa yearShown(), monthShown(), showPreviousMonth(), showNextMonth(), + showPreviousYear(), showNextYear() +*/ + +void GLDCalendarWidget::setCurrentPage(int year, int month) +{ + Q_D(GLDCalendarWidget); + QDate currentDate = d->getCurrentDate(); + int day = currentDate.day(); + int daysInMonths = QDate(year, month, 1).daysInMonth(); + if (day > daysInMonths) + { + day = daysInMonths; + } + + d->showMonth(year, month); + + QDate newDate(year, month, day); + int row = -1, col = -1; + d->m_model->cellForDate(newDate, &row, &col); + if (row != -1 && col != -1) + { + d->m_view->selectionModel()->setCurrentIndex(d->m_model->index(row, col), + QItemSelectionModel::NoUpdate); + } +} + +/*! + Shows the next month relative to the currently displayed + month. Note that the selected date is not changed. + + \sa showPreviousMonth(), setCurrentPage(), setSelectedDate() +*/ + +void GLDCalendarWidget::showNextMonth() +{ + int year = yearShown(); + int month = monthShown(); + if (month == c_monthsPerYear) + { + ++year; + month = 1; + } + else + { + ++month; + } + setCurrentPage(year, month); +} + +/*! + Shows the previous month relative to the currently displayed + month. Note that the selected date is not changed. + + \sa showNextMonth(), setCurrentPage(), setSelectedDate() +*/ +void GLDCalendarWidget::showPreviousMonth() +{ + int year = yearShown(); + int month = monthShown(); + if (month == 1) + { + --year; + month = c_monthsPerYear; + } + else + { + --month; + } + setCurrentPage(year, month); +} + +/*! + Shows the currently displayed month in the \e next year relative + to the currently displayed year. Note that the selected date is + not changed. + + \sa showPreviousYear(), setCurrentPage(), setSelectedDate() +*/ +void GLDCalendarWidget::showNextYear() +{ + int year = yearShown(); + int month = monthShown(); + ++year; + setCurrentPage(year, month); +} + +/*! + Shows the currently displayed month in the \e previous year + relative to the currently displayed year. Note that the selected + date is not changed. + + \sa showNextYear(), setCurrentPage(), setSelectedDate() +*/ +void GLDCalendarWidget::showPreviousYear() +{ + int year = yearShown(); + int month = monthShown(); + --year; + setCurrentPage(year, month); +} + +/*! + Shows the month of the selected date. + + \sa selectedDate(), setCurrentPage() +*/ +void GLDCalendarWidget::showSelectedDate() +{ + QDate currentDate = selectedDate(); + setCurrentPage(currentDate.year(), currentDate.month()); +} + +/*! + Shows the month of the today's date. + + \sa selectedDate(), setCurrentPage() +*/ +void GLDCalendarWidget::showToday() +{ + QDate currentDate = QDate::currentDate(); + setCurrentPage(currentDate.year(), currentDate.month()); +} + +void GLDCalendarWidget::dateTimeChanged(const QDateTime &dateTime) +{ + setSelectedDate(QDate(dateTime.date().year(), dateTime.date().month(), dateTime.date().day())); +} + +/*! + \property GLDCalendarWidget::minimumDate + \brief the minimum date of the currently specified date range. + + The user will not be able to select a date that is before the + currently set minimum date. + + \table + \row + \li \image qcalendarwidget-minimum.png + \row + \li + \snippet code/src_gui_widgets_qcalendarwidget.cpp 1 + \endtable + + By default, the minimum date is the earliest date that the QDate + class can handle. + + When setting a minimum date, the maximumDate and selectedDate + properties are adjusted if the selection range becomes invalid. If + the provided date is not a valid QDate object, the + setMinimumDate() function does nothing. + + \sa setDateRange() +*/ +QDate GLDCalendarWidget::minimumDate() const +{ + Q_D(const GLDCalendarWidget); + return d->m_model->m_minimumDate; +} + +void GLDCalendarWidget::setMinimumDate(const QDate &date) +{ + Q_D(GLDCalendarWidget); + if (!date.isValid() || d->m_model->m_minimumDate == date) + { + return; + } + + QDate oldDate = d->m_model->m_date; + d->m_model->setMinimumDate(date); + d->m_yearEdit->setMinimum(d->m_model->m_minimumDate.year()); + d->updateMonthMenu(); + QDate newDate = d->m_model->m_date; + if (oldDate != newDate) + { + d->update(); + d->showMonth(newDate.year(), newDate.month()); + d->m_navigator->setDate(newDate); + emit selectionChanged(); + } +} + +/*! + \property GLDCalendarWidget::maximumDate + \brief the maximum date of the currently specified date range. + + The user will not be able to select a date which is after the + currently set maximum date. + + \table + \row + \li \image qcalendarwidget-maximum.png + \row + \li + \snippet code/src_gui_widgets_qcalendarwidget.cpp 2 + \endtable + + By default, the maximum date is the last day the QDate class can + handle. + + When setting a maximum date, the minimumDate and selectedDate + properties are adjusted if the selection range becomes invalid. If + the provided date is not a valid QDate object, the + setMaximumDate() function does nothing. + + \sa setDateRange() +*/ +QDate GLDCalendarWidget::maximumDate() const +{ + Q_D(const GLDCalendarWidget); + return d->m_model->m_maximumDate; +} + +void GLDCalendarWidget::setMaximumDate(const QDate &date) +{ + Q_D(GLDCalendarWidget); + if (!date.isValid() || d->m_model->m_maximumDate == date) + { + return; + } + + QDate oldDate = d->m_model->m_date; + d->m_model->setMaximumDate(date); + d->m_yearEdit->setMaximum(d->m_model->m_maximumDate.year()); + d->updateMonthMenu(); + QDate newDate = d->m_model->m_date; + if (oldDate != newDate) + { + d->update(); + d->showMonth(newDate.year(), newDate.month()); + d->m_navigator->setDate(newDate); + emit selectionChanged(); + } +} + +/*! + Defines a date range by setting the minimumDate and maximumDate + properties. + + The date range restricts the user selection, i.e. the user can + only select dates within the specified date range. Note that + + \snippet code/src_gui_widgets_qcalendarwidget.cpp 3 + + is analogous to + + \snippet code/src_gui_widgets_qcalendarwidget.cpp 4 + + If either the \a min or \a max parameters are not valid QDate + objects, this function does nothing. + + \sa setMinimumDate(), setMaximumDate() +*/ +void GLDCalendarWidget::setDateRange(const QDate &min, const QDate &max) +{ + Q_D(GLDCalendarWidget); + if (d->m_model->m_minimumDate == min && d->m_model->m_maximumDate == max) + { + return; + } + if (!min.isValid() || !max.isValid()) + { + return; + } + + QDate oldDate = d->m_model->m_date; + d->m_model->setRange(min, max); + d->m_yearEdit->setMinimum(d->m_model->m_minimumDate.year()); + d->m_yearEdit->setMaximum(d->m_model->m_maximumDate.year()); + d->updateMonthMenu(); + QDate newDate = d->m_model->m_date; + if (oldDate != newDate) + { + d->update(); + d->showMonth(newDate.year(), newDate.month()); + d->m_navigator->setDate(newDate); + emit selectionChanged(); + } +} + +/*! \enum GLDCalendarWidget::HorizontalHeaderFormat + + This enum type defines the various formats the horizontal header can display. + + \value SingleLetterDayNames The header displays a single letter abbreviation for day names (e.g. M for Monday). + \value ShortDayNames The header displays a short abbreviation for day names (e.g. Mon for Monday). + \value LongDayNames The header displays complete day names (e.g. Monday). + \value NoHorizontalHeader The header is hidden. + + \sa horizontalHeaderFormat(), VerticalHeaderFormat +*/ + +/*! + \property GLDCalendarWidget::horizontalHeaderFormat + \brief the format of the horizontal header. + + The default value is GLDCalendarWidget::ShortDayNames. +*/ + +void GLDCalendarWidget::setHorizontalHeaderFormat(GLDCalendarWidget::HorizontalHeaderFormat format) +{ + Q_D(GLDCalendarWidget); + if (d->m_model->m_horizontalHeaderFormat == format) + { + return; + } + + d->m_model->setHorizontalHeaderFormat(format); + d->m_cachedSizeHint = QSize(); + d->m_view->viewport()->update(); + d->m_view->updateGeometry(); +} + +GLDCalendarWidget::HorizontalHeaderFormat GLDCalendarWidget::horizontalHeaderFormat() const +{ + Q_D(const GLDCalendarWidget); + return d->m_model->m_horizontalHeaderFormat; +} + +/*! + \enum GLDCalendarWidget::VerticalHeaderFormat + + This enum type defines the various formats the vertical header can display. + + \value ISOWeekNumbers The header displays ISO week numbers as described by \l QDate::weekNumber(). + \value NoVerticalHeader The header is hidden. + + \sa verticalHeaderFormat(), HorizontalHeaderFormat +*/ + +/*! + \property GLDCalendarWidget::verticalHeaderFormat + \brief the format of the vertical header. + + The default value is GLDCalendarWidget::ISOWeekNumber. +*/ + +GLDCalendarWidget::VerticalHeaderFormat GLDCalendarWidget::verticalHeaderFormat() const +{ + Q_D(const GLDCalendarWidget); + bool shown = d->m_model->weekNumbersShown(); + if (shown) + { + return GLDCalendarWidget::ISOWeekNumbers; + } + return GLDCalendarWidget::NoVerticalHeader; +} + +void GLDCalendarWidget::setVerticalHeaderFormat(GLDCalendarWidget::VerticalHeaderFormat format) +{ + Q_D(GLDCalendarWidget); + bool show = false; + if (format == GLDCalendarWidget::ISOWeekNumbers) + { + show = true; + } + if (d->m_model->weekNumbersShown() == show) + { + return; + } + d->m_model->setWeekNumbersShown(show); + d->m_cachedSizeHint = QSize(); + d->m_view->viewport()->update(); + d->m_view->updateGeometry(); +} + +/*! + \property GLDCalendarWidget::gridVisible + \brief whether the table grid is displayed. + + \table + \row + \li \inlineimage qcalendarwidget-grid.png + \row + \li + \snippet code/src_gui_widgets_qcalendarwidget.cpp 5 + \endtable + + The default value is false. +*/ + +bool GLDCalendarWidget::isGridVisible() const +{ + Q_D(const GLDCalendarWidget); + return d->m_view->showGrid(); +} + +void GLDCalendarWidget::setGridVisible(bool show) +{ + Q_D(GLDCalendarWidget); + d->m_view->setShowGrid(show); + d->m_cachedSizeHint = QSize(); + d->m_view->viewport()->update(); + d->m_view->updateGeometry(); +} + +/*! + \property GLDCalendarWidget::selectionMode + \brief the type of selection the user can make in the calendar + + When this property is set to SingleSelection, the user can select a date + within the minimum and maximum allowed dates, using either the mouse or + the keyboard. + + When the property is set to NoSelection, the user will be unable to select + dates, but they can still be selected programmatically. Note that the date + that is selected when the property is set to NoSelection will still be + the selected date of the calendar. + + The default value is SingleSelection. +*/ +GLDCalendarWidget::SelectionMode GLDCalendarWidget::selectionMode() const +{ + Q_D(const GLDCalendarWidget); + return d->m_view->m_readOnly ? GLDCalendarWidget::NoSelection : GLDCalendarWidget::SingleSelection; +} + +void GLDCalendarWidget::setSelectionMode(SelectionMode mode) +{ + Q_D(GLDCalendarWidget); + d->m_view->m_readOnly = (mode == GLDCalendarWidget::NoSelection); + d->setNavigatorEnabled(isDateEditEnabled() && (selectionMode() != GLDCalendarWidget::NoSelection)); + d->update(); +} + +/*! + \property GLDCalendarWidget::firstDayOfWeek + \brief a value identifying the day displayed in the first column. + + By default, the day displayed in the first column + is the first day of the week for the calendar's locale. +*/ +void GLDCalendarWidget::setFirstDayOfWeek(Qt::DayOfWeek dayOfWeek) +{ + Q_D(GLDCalendarWidget); + if ((Qt::DayOfWeek)d->m_model->firstColumnDay() == dayOfWeek) + { + return; + } + + d->m_model->setFirstColumnDay(dayOfWeek); + d->update(); +} + +Qt::DayOfWeek GLDCalendarWidget::firstDayOfWeek() const +{ + Q_D(const GLDCalendarWidget); + return (Qt::DayOfWeek)d->m_model->firstColumnDay(); +} + +/*! + Returns the text char format for rendering the header. +*/ +QTextCharFormat GLDCalendarWidget::headerTextFormat() const +{ + Q_D(const GLDCalendarWidget); + return d->m_model->m_headerFormat; +} + +/*! + Sets the text char format for rendering the header to \a format. + If you also set a weekday text format, this format's foreground and + background color will take precedence over the header's format. + The other formatting information will still be decided by + the header's format. +*/ +void GLDCalendarWidget::setHeaderTextFormat(const QTextCharFormat &format) +{ + Q_D(GLDCalendarWidget); + d->m_model->m_headerFormat = format; + d->m_cachedSizeHint = QSize(); + d->m_view->viewport()->update(); + d->m_view->updateGeometry(); +} + +/*! + Returns the text char format for rendering of day in the week \a dayOfWeek. + + \sa headerTextFormat() +*/ +QTextCharFormat GLDCalendarWidget::weekdayTextFormat(Qt::DayOfWeek dayOfWeek) const +{ + Q_D(const GLDCalendarWidget); + return d->m_model->m_dayFormats.value(dayOfWeek); +} + +/*! + Sets the text char format for rendering of day in the week \a dayOfWeek to \a format. + The format will take precedence over the header format in case of foreground + and background color. Other text formatting information is taken from the headers format. + + \sa setHeaderTextFormat() +*/ +void GLDCalendarWidget::setWeekdayTextFormat(Qt::DayOfWeek dayOfWeek, const QTextCharFormat &format) +{ + Q_D(GLDCalendarWidget); + d->m_model->m_dayFormats[dayOfWeek] = format; + d->m_cachedSizeHint = QSize(); + d->m_view->viewport()->update(); + d->m_view->updateGeometry(); +} + +/*! + Returns a QMap from QDate to QTextCharFormat showing all dates + that use a special format that alters their rendering. +*/ +QMap GLDCalendarWidget::dateTextFormat() const +{ + Q_D(const GLDCalendarWidget); + return d->m_model->m_dateFormats; +} + +/*! + Returns a QTextCharFormat for \a date. The char format can be be + empty if the date is not renderd specially. +*/ +QTextCharFormat GLDCalendarWidget::dateTextFormat(const QDate &date) const +{ + Q_D(const GLDCalendarWidget); + return d->m_model->m_dateFormats.value(date); +} + +/*! + Sets the format used to render the given \a date to that specified by \a format. + + If \a date is null, all date formats are cleared. +*/ +void GLDCalendarWidget::setDateTextFormat(const QDate &date, const QTextCharFormat &format) +{ + Q_D(GLDCalendarWidget); + if (date.isNull()) + { + d->m_model->m_dateFormats.clear(); + } + else + { + d->m_model->m_dateFormats[date] = format; + } + d->m_view->viewport()->update(); + d->m_view->updateGeometry(); +} + +/*! + \property GLDCalendarWidget::dateEditEnabled + \brief whether the date edit popup is enabled + \since 4.3 + + If this property is enabled, pressing a non-modifier key will cause a + date edit to popup if the calendar widget has focus, allowing the user + to specify a date in the form specified by the current locale. + + By default, this property is enabled. + + The date edit is simpler in appearance than QDateEdit, but allows the + user to navigate between fields using the left and right cursor keys, + increment and decrement individual fields using the up and down cursor + keys, and enter values directly using the number keys. + + \sa GLDCalendarWidget::dateEditAcceptDelay +*/ +bool GLDCalendarWidget::isDateEditEnabled() const +{ + Q_D(const GLDCalendarWidget); + return d->m_dateEditEnabled; +} + +void GLDCalendarWidget::setDateEditEnabled(bool enable) +{ + Q_D(GLDCalendarWidget); + if (isDateEditEnabled() == enable) + { + return; + } + + d->m_dateEditEnabled = enable; + + d->setNavigatorEnabled(enable && (selectionMode() != GLDCalendarWidget::NoSelection)); +} + +/*! + \property GLDCalendarWidget::dateEditAcceptDelay + \brief the time an inactive date edit is shown before its contents are accepted + \since 4.3 + + If the calendar widget's \l{dateEditEnabled}{date edit is enabled}, this + property specifies the amount of time (in millseconds) that the date edit + remains open after the most recent user input. Once this time has elapsed, + the date specified in the date edit is accepted and the popup is closed. + + By default, the delay is defined to be 1500 milliseconds (1.5 seconds). +*/ +int GLDCalendarWidget::dateEditAcceptDelay() const +{ + Q_D(const GLDCalendarWidget); + return d->m_navigator->dateEditAcceptDelay(); +} + +void GLDCalendarWidget::setDateEditAcceptDelay(int delay) +{ + Q_D(GLDCalendarWidget); + d->m_navigator->setDateEditAcceptDelay(delay); +} + +void GLDCalendarWidget::addCalendarHead() +{ + m_calendarHead = new QWidget(this); + m_calendarHead->setFixedSize(QSize(c_calendarHeadWidth, c_calendarHeadHeight)); + m_calendarHead->setProperty("GLDCalendarHead", true); + + QHBoxLayout *pHeadLayout = new QHBoxLayout(m_calendarHead); + pHeadLayout->setSpacing(0); + pHeadLayout->setContentsMargins(0, 0, 0, 0); + m_calendarHead->setLayout(pHeadLayout); + + QStringList weekdaysList; + if (locale().firstDayOfWeek() == Qt::Sunday) + { + weekdaysList << getGLDi18nStr(g_rsSunDay) << getGLDi18nStr(g_rsMonDay) + << getGLDi18nStr(g_rsTueDay) << getGLDi18nStr(g_rsWedDay) + << getGLDi18nStr(g_rsThuDay) << getGLDi18nStr(g_rsFriDay) + << getGLDi18nStr(g_rsSatDay); + } + else if (locale().firstDayOfWeek() == Qt::Monday) + { + weekdaysList << getGLDi18nStr(g_rsMonDay) << getGLDi18nStr(g_rsTueDay) + << getGLDi18nStr(g_rsWedDay) << getGLDi18nStr(g_rsThuDay) + << getGLDi18nStr(g_rsFriDay) << getGLDi18nStr(g_rsSatDay) + << getGLDi18nStr(g_rsSunDay) ; + } + + foreach (QString weedday, weekdaysList) + { + addButtonToHeader(weedday, pHeadLayout); + } +} + +void GLDCalendarWidget::addButtonToHeader(QString weekday, QHBoxLayout *headLayout) +{ + QPushButton *pWeekdayBtn = new QPushButton(weekday); + pWeekdayBtn->setDisabled(true); + pWeekdayBtn->setProperty("GLDHeadBtn", true); + pWeekdayBtn->setFixedSize(QSize(c_calendarHearBtnWidth, c_calendarHearBtnHeight)); + pWeekdayBtn->setFlat(true); + headLayout->addWidget(pWeekdayBtn); +} + +void GLDCalendarWidget::setWeekdayTextColor(const QColor &foreColor, const QColor &backColor) +{ + QTextCharFormat weekdayFormat; + weekdayFormat.setForeground(QBrush(foreColor)); + weekdayFormat.setBackground(QBrush(backColor)); + + setWeekdayTextFormat(Qt::Monday, weekdayFormat); + setWeekdayTextFormat(Qt::Tuesday, weekdayFormat); + setWeekdayTextFormat(Qt::Wednesday, weekdayFormat); + setWeekdayTextFormat(Qt::Thursday, weekdayFormat); + setWeekdayTextFormat(Qt::Friday, weekdayFormat); +} + +void GLDCalendarWidget::setWeekendTextColor(const QColor &foreColor, const QColor &backColor) +{ + QTextCharFormat weekendFormat; + weekendFormat.setForeground(QBrush(foreColor)); + weekendFormat.setBackground(QBrush(backColor)); + + setWeekdayTextFormat(Qt::Saturday, weekendFormat); + setWeekdayTextFormat(Qt::Sunday, weekendFormat); +} + +/*! + \since 4.4 + + Updates the cell specified by the given \a date unless updates + are disabled or the cell is hidden. + + \sa updateCells(), yearShown(), monthShown() +*/ +void GLDCalendarWidget::updateCell(const QDate &date) +{ + if (!date.isValid()) + { + qWarning("GLDCalendarWidget::updateCell: Invalid date"); + return; + } + + if (!isVisible()) + return; + + Q_D(GLDCalendarWidget); + int row, column; + d->m_model->cellForDate(date, &row, &column); + if (row == -1 || column == -1) + { + return; + } + + QModelIndex modelIndex = d->m_model->index(row, column); + if (!modelIndex.isValid()) + return; + + d->m_view->viewport()->update(d->m_view->visualRect(modelIndex)); +} + +/*! + \since 4.4 + + Updates all visible cells unless updates are disabled. + + \sa updateCell() +*/ +void GLDCalendarWidget::updateCells() +{ + Q_D(GLDCalendarWidget); + if (isVisible()) + { + d->m_view->viewport()->update(); + } +} + +/*! + \fn void GLDCalendarWidget::selectionChanged() + + This signal is emitted when the currently selected date is + changed. + + The currently selected date can be changed by the user using the + mouse or keyboard, or by the programmer using setSelectedDate(). + + \sa selectedDate() +*/ + +/*! + \fn void GLDCalendarWidget::currentPageChanged(int year, int month) + + This signal is emitted when the currently shown month is changed. + The new \a year and \a month are passed as parameters. + + \sa setCurrentPage() +*/ + +/*! + \fn void GLDCalendarWidget::activated(const QDate &date) + + This signal is emitted whenever the user presses the Return or + Enter key or double-clicks a \a date in the calendar + widget. +*/ + +/*! + \fn void GLDCalendarWidget::clicked(const QDate &date) + + This signal is emitted when a mouse button is clicked. The date + the mouse was clicked on is specified by \a date. The signal is + only emitted when clicked on a valid date, e.g., dates are not + outside the minimumDate() and maximumDate(). If the selection mode + is NoSelection, this signal will not be emitted. + +*/ + +/*! + \property GLDCalendarWidget::navigationBarVisible + \brief whether the navigation bar is shown or not + + \since 4.3 + + When this property is \c true (the default), the next month, + previous month, month selection, year selection controls are + shown on top. + + When the property is set to false, these controls are hidden. +*/ +bool GLDCalendarWidget::isNavigationBarVisible() const +{ + Q_D(const GLDCalendarWidget); + return d->m_navBarVisible; +} + + +void GLDCalendarWidget::setNavigationBarVisible(bool visible) +{ + Q_D(GLDCalendarWidget); + d->m_navBarVisible = visible; + d->m_cachedSizeHint = QSize(); + d->m_navBarBackground->setVisible(visible); + updateGeometry(); +} + +/*! + \reimp +*/ +bool GLDCalendarWidget::event(QEvent *event) +{ + Q_D(GLDCalendarWidget); + switch (event->type()) + { + case QEvent::LayoutDirectionChange: + d->updateButtonIcons(); + case QEvent::LocaleChange: + d->m_model->setFirstColumnDay(locale().firstDayOfWeek()); + d->m_cachedSizeHint = QSize(); + d->updateNavigationBar(); + d->m_view->updateGeometry(); + break; + case QEvent::FontChange: + case QEvent::ApplicationFontChange: + d->m_cachedSizeHint = QSize(); + d->m_view->updateGeometry(); + break; + case QEvent::StyleChange: + d->m_cachedSizeHint = QSize(); + d->m_view->updateGeometry(); + default: + break; + } + return QWidget::event(event); +} + +/*! + \reimp +*/ +bool GLDCalendarWidget::eventFilter(QObject *watched, QEvent *event) +{ + Q_D(GLDCalendarWidget); + if (event->type() == QEvent::MouseButtonPress && d->m_yearEdit->hasFocus()) + { + QWidget *tlw = window(); + QWidget *widget = static_cast(watched); + //as we have a event filter on the whole application we first make sure that the top level widget + //of both this and the watched widget are the same to decide if we should finish the year edition. + if (widget->window() == tlw) + { + QPoint mousePos = widget->mapTo(tlw, static_cast(event)->pos()); + QRect geom = QRect(d->m_yearEdit->mapTo(tlw, QPoint(0, 0)), d->m_yearEdit->size()); + if (!geom.contains(mousePos)) + { + event->accept(); + d->_q_yearEditingFinished(); + setFocus(); + return true; + } + } + } + return QWidget::eventFilter(watched, event); +} + +/*! + \reimp +*/ +void GLDCalendarWidget::mousePressEvent(QMouseEvent *event) +{ + setAttribute(Qt::WA_NoMouseReplay); + QWidget::mousePressEvent(event); + setFocus(); +} + +/*! + \reimp +*/ +void GLDCalendarWidget::resizeEvent(QResizeEvent * event) +{ + Q_D(GLDCalendarWidget); + + // XXX Should really use a QWidgetStack for yearEdit and yearButton, + // XXX here we hide the year edit when the layout is likely to break + // XXX the manual positioning of the yearEdit over the yearButton. + if(d->m_yearEdit->isVisible() && event->size().width() != event->oldSize().width()) + { + d->_q_yearEditingFinished(); + } + + QWidget::resizeEvent(event); +} + +/*! + \reimp +*/ +void GLDCalendarWidget::keyPressEvent(QKeyEvent * event) +{ + Q_D(GLDCalendarWidget); + if(d->m_yearEdit->isVisible()&& event->key() == Qt::Key_Escape) + { + d->m_yearEdit->setValue(yearShown()); + d->_q_yearEditingFinished(); + return; + } + QWidget::keyPressEvent(event); +} + +QT_END_NAMESPACE + +#endif //QT_NO_CALENDARWIDGET diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDClassicsOutLookBar.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDClassicsOutLookBar.cpp new file mode 100644 index 00000000..530e9e5d --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDClassicsOutLookBar.cpp @@ -0,0 +1,718 @@ +#include "GLDClassicsOutLookBar.h" + +#include +#include +#include +#include "GLDWidget_Global.h" +#include "GLDFileUtils.h" + +const int c_maxToolButtonShow = 3; + +// 导航项目 +static const int conNavigationItemHeight = 34; + +const GString c_sOutLookBarQssFile = ":qsses/outLookBar.qss"; + +/* GLDOutLookBar */ +GLDClassicsOutLookBar::GLDClassicsOutLookBar(QWidget *parent) : + QScrollArea(parent), m_curAction(NULL), m_curView(NULL) +{ + m_splitter = new GLDNavigationSplitter(Qt::Vertical, this); + connect(m_splitter, SIGNAL(splitterChanged(bool)), + this, SLOT(splitterChanged(bool))); + + m_outLookView = new GLDOutLookView(m_splitter); + m_outLookNavigBar = new GLDOutLookNavigationBar(m_splitter); + m_thumbnailButtons = new GLDThumbnailBar(this); + initLayout(); + + this->setStyleSheet(loadQssFile(c_sOutLookBarQssFile)); +} + +GLDClassicsOutLookBar::~GLDClassicsOutLookBar() +{ + for (int i = 0; i < m_actions.count(); ++i) + { + GLDOutLookBarAction *action = m_actions.at(i); + freeAndNil(action); + } + + m_actions.clear(); + + m_curAction = NULL; + m_curView = NULL; +} + +GLDNavigationItem *GLDClassicsOutLookBar::addBarItem(QWidget *view, const GString &text, const QIcon &icon) +{ + GLDOutLookBarAction *action = new GLDOutLookBarAction(text, icon, this); + m_actions.append(action); + + GLDNavigationItem *item = m_outLookNavigBar->addItem(text, icon); + item->addOutLookBarAction(action); + m_outLookView->addView(view); + view->hide(); + m_itemViews.insert(action->uuid(), view); + connect(action, SIGNAL(clicked(GString)), this, SLOT(itemClick(GString))); + return item; +} + +QAction *GLDClassicsOutLookBar::addThumbnailButton(QWidget *view, const GString &text, const QIcon &icon) +{ + GLDOutLookBarAction *action = new GLDOutLookBarAction(text, icon, this); + m_actions.append(action); + + m_thumbnailButtons->addLeftAction(action); + m_outLookView->addView(view); + view->hide(); + m_itemViews.insert(action->uuid(), view); + connect(action, SIGNAL(clicked(GString)), this, SLOT(itemClick(GString))); + return action->action(); +} + +void GLDClassicsOutLookBar::setTitleHeight(int nHeight) +{ + m_outLookView->setTitleHeight(nHeight); +} + +int GLDClassicsOutLookBar::currentIndex() const +{ + return findActionIndex(m_curAction->uuid()); +} + +void GLDClassicsOutLookBar::setCurrentIndex(int nIndex) +{ + if (m_actions.count() == 0) + { + return; + } + + if ((nIndex < 0) || (nIndex >= m_actions.count())) + { + nIndex = 0; + } + + itemClick(m_actions[nIndex]->uuid()); +} + +QWidget *GLDClassicsOutLookBar::currentWidget() const +{ + return m_itemViews.value(m_curAction->uuid()); +} + +QWidget *GLDClassicsOutLookBar::widget(int nIndex) const +{ + if ((nIndex < 0) || (nIndex >= m_actions.count())) + { + return NULL; + } + + return m_itemViews.value(m_actions[nIndex]->uuid()); +} + +void GLDClassicsOutLookBar::setCurrentWidget(QWidget *widget) +{ + GString uuid = m_curAction->uuid(); + QWidget *preWidget = m_itemViews[uuid]; + + if (preWidget != widget) + { + m_outLookView->removeView(preWidget); + freeAndNil(preWidget); + m_itemViews[uuid] = widget; + m_outLookView->addView(widget); + } + + widget->show(); + m_curView = widget; +} + +GString GLDClassicsOutLookBar::currentText() const +{ + return m_curAction->text(); +} + +void GLDClassicsOutLookBar::setToolButtonStyle(Qt::ToolButtonStyle style) +{ + m_thumbnailButtons->setToolButtonStyle(style); +} + +void GLDClassicsOutLookBar::clearItems() +{ + m_outLookNavigBar->clearItems(); + m_thumbnailButtons->clear(); + + if (NULL != m_curView) + { + m_curView->hide(); + m_curView = NULL; + } + + m_outLookView->setTitle(""); + m_itemViews.clear(); + m_curAction = NULL; + + for (int i = 0; i < m_actions.count(); ++i) + { + GLDOutLookBarAction *action = m_actions.at(i); + freeAndNil(action); + } + + m_actions.clear(); +} + +//隐藏ThumbnailButton的接口. +void GLDClassicsOutLookBar::setIsHideThumbnailButton(bool isHide) +{ + if (isHide) + { + m_thumbnailButtons->hide(); + m_outLookNavigBar->hide(); + } + else + { + m_thumbnailButtons->show(); + m_outLookNavigBar->show(); + } +} + +void GLDClassicsOutLookBar::itemClick(const GString &itemID) +{ + QHash::const_iterator it = m_itemViews.find(itemID); + + if (it != m_itemViews.end()) + { + GLDOutLookBarAction *act = this->findAction(itemID); + + if (m_curAction == act) + { + return; + } + + if (NULL != m_curView) + { + m_curView->hide(); + } + + if (NULL != m_curAction) + { + setItemCheck(m_curAction->uuid(), false); + } + + QWidget *widget = it.value(); + widget->show(); + m_outLookView->setTitle(act->text()); + act->setChecked(true); + setItemCheck(act->uuid(), true); + m_curAction = act; + m_curView = widget; + emit currentChanged(findActionIndex(itemID)); + } +} + +void GLDClassicsOutLookBar::splitterChanged(bool downward) +{ + if (downward) + { + if (m_outLookNavigBar->itemCount() == 0) + { + return; + } + + m_outLookNavigBar->removeLastAction(); + int nCount = m_outLookNavigBar->itemCount(); + GLDOutLookBarAction *action = m_actions.at(nCount); + m_thumbnailButtons->addLeftAction(action); + } + else + { + if (m_outLookNavigBar->itemCount() == m_actions.count()) + { + return; + } + + GLDOutLookBarAction *action = m_actions.at(m_outLookNavigBar->itemCount()); + GLDNavigationItem *item = m_outLookNavigBar->addItem(action->text(), action->icon()); + item->addOutLookBarAction(action); + m_thumbnailButtons->removeAction(action); + } +} + +void GLDClassicsOutLookBar::initLayout() +{ + QHBoxLayout *layout = new QHBoxLayout(this); + layout->setSpacing(0); + layout->setContentsMargins(0, 0, 0, 0); + this->setLayout(layout); + + QSplitter *splitter = new QSplitter(); + layout->addWidget(splitter); + + QWidget *navigation = new QWidget(splitter); + + QVBoxLayout *navigatLayout = new QVBoxLayout(splitter); + navigatLayout->setSpacing(0); + navigatLayout->setContentsMargins(0, 0, 0, 0); + + navigation->setLayout(navigatLayout); + + navigatLayout->addWidget(m_splitter); + navigatLayout->addWidget(m_thumbnailButtons); +} + +GLDOutLookBarAction *GLDClassicsOutLookBar::findAction(const GString &uID) +{ + for (int i = 0; i < m_actions.count(); ++i) + { + GLDOutLookBarAction *olAct = m_actions.at(i); + + if (olAct->uuid() == uID) + { + return olAct; + } + } + + return NULL; +} + +int GLDClassicsOutLookBar::findActionIndex(const GString &itemID) const +{ + for (int i = 0; i < m_actions.count(); ++i) + { + GLDOutLookBarAction *olAct = m_actions.at(i); + + if (sameText(olAct->uuid(), itemID)) + { + return i; + } + } + + return -1; +} + +void GLDClassicsOutLookBar::setItemCheck(const GString &uID, bool checked) +{ + if (! m_thumbnailButtons->hasAction(uID)) + { + m_outLookNavigBar->findByUuid(uID)->setChecked(checked); + } + + GLDOutLookBarAction *action = findAction(uID); + + if (NULL != action) + { + action->setChecked(checked); + } +} + +/* GLDOutLookNavigationBar */ +GLDOutLookNavigationBar::GLDOutLookNavigationBar(QWidget *parent) + : QWidget(parent) +{ + m_itemList = new QObjectList(); + this->setMaximumHeight(0); + this->setMinimumHeight(0); + initLayout(); +} + +GLDOutLookNavigationBar::~GLDOutLookNavigationBar() +{ + clearItems(); + freeAndNil(m_itemList); +} + +GLDNavigationItem *GLDOutLookNavigationBar::addItem(GLDNavigationItem *item) +{ + m_itemList->push_back(item); + m_itemLayout->addWidget(item); + this->setMaximumHeight(itemCount() * conNavigationItemHeight); + this->setMinimumHeight(itemCount() * conNavigationItemHeight); + return item; +} + +GLDNavigationItem *GLDOutLookNavigationBar::addItem(const GString &text) +{ + GLDNavigationItem *item = new GLDNavigationItem(this); + item->setText(text); + return addItem(item); +} + +GLDNavigationItem *GLDOutLookNavigationBar::addItem(const GString &text, const QIcon &icon) +{ + GLDNavigationItem *item = new GLDNavigationItem(text, icon, this); + item->setText(text); + item->setIcon(icon); + return addItem(item); +} + +bool GLDOutLookNavigationBar::removeItem(GLDNavigationItem *item) +{ + return m_itemList->removeOne(item); +} + +bool GLDOutLookNavigationBar::removeItem(int index) +{ + if (0 == m_itemList->count()) + { + return false; + } + + m_itemList->removeAt(index); + return true; +} + +GLDNavigationItem *GLDOutLookNavigationBar::addLastAction(GLDOutLookBarAction *action) +{ + GLDNavigationItem *item = new GLDNavigationItem(action->text(), action->icon(), this); + item->addOutLookBarAction(action); + addItem(item); + return item; +} + +GLDNavigationItem *GLDOutLookNavigationBar::findByUuid(const GString &value) +{ + for (int i = 0; i < m_itemList->count(); i++) + { + GLDNavigationItem *item = static_cast(m_itemList->at(i)); + + if (item->uuid() == value) + { + return item; + } + } + + return NULL; +} + +QAction *GLDOutLookNavigationBar::removeLastAction() +{ + if (0 == m_itemList->count()) + { + return NULL; + } + + GLDNavigationItem *item = (GLDNavigationItem *)m_itemList->last(); + QAction *action = item->actions().first(); + m_itemList->removeOne(item); + freeAndNil(item); + + this->setMaximumHeight(itemCount() * conNavigationItemHeight); + this->setMinimumHeight(itemCount() * conNavigationItemHeight); + return action; +} + +void GLDOutLookNavigationBar::clearItems() +{ + for (int i = 0; i < m_itemList->count(); ++i) + { + GLDNavigationItem *item = (GLDNavigationItem *)m_itemList->at(i); + freeAndNil(item); + } + + this->setMaximumHeight(0); + this->setMinimumHeight(0); + m_itemList->clear(); +} + +int GLDOutLookNavigationBar::needItemCount(int offset) +{ + return (this->geometry().height() - offset) / conNavigationItemHeight; +} + +int GLDOutLookNavigationBar::itemCount() +{ + return m_itemList->count(); +} + +void GLDOutLookNavigationBar::initLayout() +{ + m_itemLayout = new QVBoxLayout(this); + m_itemLayout->setSpacing(0); + m_itemLayout->setContentsMargins(0, 0, 0, 0); + this->setLayout(m_itemLayout); +} + +/*GLDNavigationItem*/ +GLDNavigationItem::GLDNavigationItem(QWidget *parent) : QPushButton(parent) +{ + init(); +} + +GLDNavigationItem::GLDNavigationItem(const GString &text, const QIcon &icon, QWidget *parent) + : QPushButton(icon, text, parent) +{ + init(); +} + +GLDNavigationItem::~GLDNavigationItem() +{ +} + +void GLDNavigationItem::addOutLookBarAction(GLDOutLookBarAction *action) +{ + setText(action->text()); + setIcon(action->icon()); + m_uuid = action->uuid(); + connect(this, SIGNAL(clicked()), action->action(), SLOT(trigger())); + setChecked(action->action()->isChecked()); + addAction(action->action()); +} + +void GLDNavigationItem::setChecked(bool checked) +{ + setCheckable(checked); + QPushButton::setChecked(checked); + QPushButton::update(); +} + +void GLDNavigationItem::init() +{ + +} + +/* GLDOutLookView */ +GLDOutLookView::GLDOutLookView(QWidget *parent, Qt::WindowFlags f) + : QFrame(parent, f) +{ + m_titleWgt = new QWidget(this); + QHBoxLayout *titleLayout = new QHBoxLayout(this); + m_titleWgt->setLayout(titleLayout); + + m_titleWgt->setFixedHeight(30); + m_titleWgt->setObjectName("titleWidget"); + m_title = new QLabel(m_titleWgt); + m_title->setAlignment(Qt::AlignLeft); + titleLayout->addWidget(m_title); + + QVBoxLayout *layout = new QVBoxLayout(this); + layout->setSpacing(0); + layout->setContentsMargins(0, 0, 0, 0); + this->setLayout(layout); + + QWidget *container = new QWidget(this); + container->setObjectName("container"); + + layout->addWidget(m_titleWgt); + layout->addWidget(container); + + m_layout = new QVBoxLayout(this); + m_layout->setSpacing(0); + m_layout->setContentsMargins(0, 0, 0, 0); + container->setLayout(m_layout); +} + +GLDOutLookView::~GLDOutLookView() +{ +} + +void GLDOutLookView::addView(QWidget *widget) +{ + widget->setParent(this);//归outLookView来管释放 + m_layout->addWidget(widget); +} + +void GLDOutLookView::setTitle(const GString &title) +{ + m_title->setText(title); +} + +void GLDOutLookView::setTitleHeight(int nHeight) +{ + m_titleWgt->setFixedHeight(nHeight); +} + +void GLDOutLookView::removeView(QWidget *widget) +{ + m_layout->removeWidget(widget); +} + +/* GLDThumbnailBar */ +GLDThumbnailBar::GLDThumbnailBar(QWidget *parent) : QToolBar(parent) +{ + m_foldAction = new QAction(QIcon(":/icons/more.png"), QString(""), this); + connect(m_foldAction, SIGNAL(triggered()), this, SLOT(showMoreAction())); + setToolButtonStyle(Qt::ToolButtonTextBesideIcon);//默认是图标加文字 +} + +GLDThumbnailBar::~GLDThumbnailBar() +{ + m_btnActions.clear(); +} + +GLDOutLookBarAction *GLDThumbnailBar::addAction(const QIcon &icon, const GString &text) +{ + GLDOutLookBarAction *action = new GLDOutLookBarAction(text, icon, this); + this->addAction(action); + return action; +} + +GLDOutLookBarAction *GLDThumbnailBar::addAction(GLDOutLookBarAction *action) +{ + this->insertAction(m_btnActions.top()->action(), action->action()); + m_btnActions.push(action); + return action; +} + +void GLDThumbnailBar::removeAction(GLDOutLookBarAction *action) +{ + if (m_btnActions.count() > c_maxToolButtonShow) + { + m_btnActions.pop(); + int nIndex = m_btnActions.count() - c_maxToolButtonShow; + QToolBar::removeAction(action->action()); + QToolBar::insertAction(m_foldAction, m_btnActions.at(nIndex)->action()); + + if (m_btnActions.count() == c_maxToolButtonShow) + { + QToolBar::removeAction(m_foldAction); + } + } + else + { + m_btnActions.pop(); + QToolBar::removeAction(action->action()); + } +} + +void GLDThumbnailBar::addLeftAction(GLDOutLookBarAction *action) +{ + if (m_btnActions.empty()) + { + QToolBar::insertAction(NULL, action->action()); + } + else + { + if (c_maxToolButtonShow == m_btnActions.count()) + { + GLDOutLookBarAction *oAction = static_cast(m_btnActions.at(0)); + QToolBar::removeAction(oAction->action()); + QToolBar::insertAction(NULL, m_foldAction); + QToolBar::insertAction(m_btnActions.top()->action(), action->action()); + } + else if (c_maxToolButtonShow < m_btnActions.count()) + { + int nIndex = m_btnActions.count() - c_maxToolButtonShow; + GLDOutLookBarAction *oAction = static_cast(m_btnActions.at(nIndex)); + QToolBar::removeAction(oAction->action()); + QToolBar::insertAction(m_btnActions.top()->action(), action->action()); + } + else + { + QToolBar::insertAction(m_btnActions.top()->action(), action->action()); + } + } + + m_btnActions.push(action); +} + +void GLDThumbnailBar::removeLeftAction() +{ + this->removeAction(m_btnActions.top()); +} + +bool GLDThumbnailBar::hasAction(const GString &uId) +{ + for (int i = 0; i < m_btnActions.count(); i++) + { + GLDOutLookBarAction *oAction = static_cast(m_btnActions.at(i)); + + if (oAction->uuid() == uId) + { + return true; + } + } + + return false; +} + +void GLDThumbnailBar::clearButtons() +{ + m_btnActions.clear(); +} + +void GLDThumbnailBar::showMoreAction() +{ + QMenu *menu = new QMenu(this); + + for (int i = 0; i < m_btnActions.count() - c_maxToolButtonShow; i++) + { + menu->addAction(m_btnActions.at(i)->action()); + } + + menu->popup(QCursor::pos()); +} + +/* GLDNavigationSplitter */ +GLDNavigationSplitter::GLDNavigationSplitter(Qt::Orientation orientation, + QWidget *parent): + QSplitter(orientation, parent) +{ + setChildrenCollapsible(false); + setFixedHeight(5); +} + +QSplitterHandle *GLDNavigationSplitter::createHandle() +{ + GLDNavigationSplitterHandle *handle = new GLDNavigationSplitterHandle(this->orientation(), this); + connect(handle, SIGNAL(splitterHandleChanged(bool)), + this, SLOT(splitterHandleChanged(bool))); + return handle; +} + +void GLDNavigationSplitter::splitterHandleChanged(bool downward) +{ + emit splitterChanged(downward); +} + +GLDNavigationSplitterHandle::GLDNavigationSplitterHandle(Qt::Orientation o, QSplitter *parent): + QSplitterHandle(o, parent), m_windowPosY(0) +{ + setFixedHeight(5); +} + +void GLDNavigationSplitterHandle::mouseMoveEvent(QMouseEvent *e) +{ + double pos = e->windowPos().y(); + + if (pos > m_windowPosY + conNavigationItemHeight) + { + emit splitterHandleChanged(true); + m_windowPosY = pos; + } + else if (pos < m_windowPosY - conNavigationItemHeight) + { + emit splitterHandleChanged(false); + m_windowPosY = pos; + } + + QSplitterHandle::mouseMoveEvent(e); +} + +void GLDNavigationSplitterHandle::mousePressEvent(QMouseEvent *e) +{ + m_windowPosY = e->windowPos().y(); + QSplitterHandle::mousePressEvent(e); +} + +GLDOutLookBarAction::GLDOutLookBarAction(const GString &text, const QIcon &icon, QObject *parent) +{ + m_action = new QAction(icon, text, parent); + connect(m_action, SIGNAL(triggered()), this, SLOT(triggered())); + + m_uuid = QUuid::createUuid(); +} + +GLDOutLookBarAction::~GLDOutLookBarAction() +{ +} + +void GLDOutLookBarAction::triggered() +{ + emit clicked(m_uuid.toString()); +} + +void GLDOutLookBarAction::setChecked(bool checked) +{ + m_action->setCheckable(true); + m_action->setChecked(checked); +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDColorList.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDColorList.cpp new file mode 100644 index 00000000..4b557d03 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDColorList.cpp @@ -0,0 +1,169 @@ +#include "GLDColorList.h" +#include +#include +#include +#include +#include + +static const int c_GlobalColorCount = 20; //Qt自带GlobalColor枚举的个数 + +GColorList::GColorList(QWidget *parent) : + QComboBox(parent), m_newSize(QSize()), m_userColor(QColor(Qt::white)), + m_isInInit(true), m_currentIndex(0) +{ + m_newSize = size() - QSize(ITEM_RIGHT_OFFSET, 0); + initColorList(); + connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(moreColorClicked(int))); +} + +int GColorList::findColor(QColor color) +{ + for (int i = 0; i < count() - 1; i++) + { + if (itemData(i).value() == color) + { + return i; + } + } + return -1; +} + +int GColorList::addColor(QColor color) +{ + int nIndex = findColor(color); + if (nIndex == -1) + { + nIndex = count() - 3; + + insertItem(nIndex, colorToIcon(color), "", color); + m_addColors.push_back(color); + return nIndex + 1; + } + else + { + return nIndex; + } +} + +int GColorList::setUserColor(QColor color) +{ + int nIndex = findColor(color); + if (nIndex == -1) + { + nIndex = count() - 2; + setItemIcon(nIndex, colorToIcon(color)); + setItemData(nIndex, color); + } + m_userColor = color; + setCurrentIndex(nIndex); + return nIndex; +} + +QColor GColorList::userColor() +{ + return m_userColor; +} + +QColor GColorList::currentColor() +{ + int nIndex = currentIndex(); + return qvariant_cast(itemData(nIndex)); +} + +void GColorList::selectColor(QColor color) +{ + int nIndex = findColor(color); + if (nIndex == -1) + { + setUserColor(color); + } + else + { + setCurrentIndex(nIndex); + } +} + +void GColorList::setCurrentIndex(int index) +{ + m_currentIndex = index; + QComboBox::setCurrentIndex(index); + emit colorIndexChange(index); +} + +void GColorList::resizeEvent(QResizeEvent *e) +{ + if (e->oldSize() != e->size()) + { + m_newSize = e->size() - QSize(ITEM_RIGHT_OFFSET, 0); + initColorList(); + } +} + +void GColorList::moreColorClicked(int index) +{ + if (!m_isInInit) + { + if (index == count() - 1) + { + QColor originalColor = qvariant_cast(itemData(m_currentIndex)); + if (!originalColor.isValid()) + originalColor = Qt::black; + QColor color = QColorDialog::getColor(originalColor, this); + if (color.isValid()) //防止出现已经选中某种颜色,选择more...,然后Esc,进而变黑的情形 + setUserColor(color); + else if (0 <= m_currentIndex && m_currentIndex < index) + setCurrentIndex(m_currentIndex); + } + else if (index != m_currentIndex) + { + m_currentIndex = index; + emit colorIndexChange(index); + } + } +} + +QIcon GColorList::colorToIcon(QColor color) +{ + QPixmap pix(m_newSize); + pix.fill(Qt::white); + + QPainter painter(&pix); + + painter.drawRect(2, 3, pix.width() - 15, pix.height() - 8); + painter.fillRect(QRect(3, 4, pix.width() - 16, pix.height() - 9), QColor(color)); + return QIcon(pix); +} + +void GColorList::initColorList() +{ + m_isInInit = true; + clear(); + setIconSize(m_newSize); + //遍历GlobalColor枚举,生成相应的QColor,放入到QComBox中, 取的颜色为枚举第三个开始到倒数第二个 + for (int i = 0; i < c_GlobalColorCount - 3; i++) + { + QColor color = QColor(Qt::GlobalColor(i + 2));//为了保证comboBox的index和枚举颜色相对应,所以+2 + + addItem(colorToIcon(color), NULL, color); + } + + for (int i = 0; i < m_addColors.count(); ++i) + { + QColor color = QColor(m_addColors.at(i)); + addItem(colorToIcon(color), NULL, color); + } + //添加用户自定义颜色,默认为白色 + addItem(colorToIcon(m_userColor), NULL, m_userColor); + + //添加更多选项 + QPixmap pix(m_newSize); + pix.fill(Qt::white); + + QPainter painter(&pix); + painter.drawText(QRect(3, 4, pix.width() - 16, pix.height() - 9), tr("more..."));//TRANS_STRING("更多...")); + + addItem(QIcon(pix), NULL); + m_isInInit = false; + setCurrentIndex(m_currentIndex); +} + diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDColorListEx.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDColorListEx.cpp new file mode 100644 index 00000000..4c8a7d2e --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDColorListEx.cpp @@ -0,0 +1,1097 @@ +#include "GLDColorListEx.h" + +#include "GLDWidget_Global.h" +#include "GLDShadow.h" +#include "GLDFileUtils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// GLDColorBlock 常量 +const int c_colorBlockWidth = 16; +const int c_colorBlockHeight = 16; +const int c_colorBtnWidth = 24; // 22 + 1 + 1 +const int c_colorBtnHeight = 24; // 22 + 1 + 1 + +// GLDColorRow 常量 +const int c_colorRowWidth = 242; // 5 + 22 * 9 + 4 * 8 + 5 +const int c_colorRowHeight = 26; // 16 + 8 + 2 +const int c_colorBlockSpacing = 4; // 10 - 3 - 3 +const int c_colorRowLeftMargin = 4; +const int c_colorRowRightMargin = 6; + +// 最近使用色所在的行号 +const int c_recentColorTableRow = 2; +const int c_blockColorDeviation = 50; + +// GLDColorTable 常量 +const int c_tabTitleLeftMargin = 8; +const int c_tabTitleTopMargin = 5; +const int c_tabTitleBottomMargin = 2; +const int c_tabRowSpacing = 4; +const int c_tabRowBottomMargin = 4; +const int c_tabTopMargin = 2; +const int c_tabTitleFontSize = 12; + +// GColorListEx 常量 +const int c_colorColumnCount = 9; +const int c_grayColorRowCount = 1; +const int c_standardColorRowCount = 1; +const int c_themeColorRowCount = 5; +const int c_edgeColorRowCount = 7; // 1 + 1 + 5 +const int c_listWidgetCount = 4; +const int c_listWidgetMargin = 2; +const int c_listWidgetHeight = 284; +const int c_grayTableMargin = 7; +const int c_grayTableHeight = 34; +const int c_standardTabMargin = 4; +const int c_standardTabHeight = 54; +const int c_recentColorTableHeight = 32; +const int c_themeTabHeight = 164; +const int c_moreBtnHeight = 30; +const int c_moreBtnTop = 5; +const int c_moreBtnBottom = 10; + +const int c_yStartPos = 11; +const int c_blockHeightInEdit = 4; + +const QString c_recentColorConfPath = "/GLDRes/colorTempConf.txt"; + +const char *c_hu = QT_TRANSLATE_NOOP("QColorDialog", "Hu&e:"); // 色调(&E): +const char *c_sat = QT_TRANSLATE_NOOP("QColorDialog", "&Sat:"); // 饱和度(&S): +const char *c_val = QT_TRANSLATE_NOOP("QColorDialog", "&Val:"); // 亮度(&V): +const char *c_red = QT_TRANSLATE_NOOP("QColorDialog", "&Red:"); // 红色(&R): +const char *c_green = QT_TRANSLATE_NOOP("QColorDialog", "&Green:"); // 绿色(&G): +const char *c_blue = QT_TRANSLATE_NOOP("QColorDialog", "Bl&ue:"); // 蓝色(&U): +const char *c_alphaChannel = QT_TRANSLATE_NOOP("QColorDialog", "A&lpha channel:"); // Alpha通道(&A): +const char *c_selectColor = QT_TRANSLATE_NOOP("QColorDialog", "Select Color"); // 选择颜色 +const char *c_basicColors = QT_TRANSLATE_NOOP("QColorDialog", "&Basic colors"); // 基本颜色(&B) +const char *c_customColors = QT_TRANSLATE_NOOP("QColorDialog", "&Custom colors"); // 自定义颜色(&C) +const char *c_addToCustomColors = QT_TRANSLATE_NOOP("QColorDialog", "&Add to Custom Colors"); // 添加到自定义颜色(&A) +const char *c_pickScreenColor = QT_TRANSLATE_NOOP("QColorDialog", "Pick Screen Color"); // 获取屏幕颜色 +const char *c_okBtn = QT_TRANSLATE_NOOP("QDialogButtonBox", "&OK"); // 确定 +const char *c_cancelBtn = QT_TRANSLATE_NOOP("QDialogButtonBox", "&Cancel"); // 取消 +const char *c_moreColorBtn = QT_TRANSLATE_NOOP("GColorListEx", "More Color(w)..."); // 更多颜色按键上的Text +const char *c_moreColorTitle = QT_TRANSLATE_NOOP("GColorListEx", "More Color"); // 更多颜色对话框的标题 +const char *c_themeColor = QT_TRANSLATE_NOOP("GColorListEx", "theme color"); // 主题颜色 +const char *c_commonlyUsedColor = QT_TRANSLATE_NOOP("GColorListEx", "commonly used color"); // 主题颜色 + +const GString c_sColorListQssFile = ":/qsses/GColorListEx.qss"; + +GLDColorBlock::GLDColorBlock(const QColor &color, const QColor &edgeColor, QWidget *parent) : + QPushButton(parent), + m_color(color), + m_edgeColor(edgeColor) +{ + setProperty("GLDColorBlock", true); + drawColorBlock(); +} + +void GLDColorBlock::updateColor(const QColor &color, const QColor &edgeColor) +{ + m_color = color; + m_edgeColor = edgeColor; + drawColorBlock(); +} + +void GLDColorBlock::drawColorBlock() +{ + QPixmap pixColor(c_colorBlockWidth, c_colorBlockHeight); + QPainter painter(&pixColor); + QPen pen = painter.pen(); + + pen.setColor(m_color); + pen.setWidth(c_colorBlockWidth * 2); + painter.setPen(pen); + painter.drawPoint(0, 0); + + // 处理第一个颜色块为透明,画红色线条 + if (m_color.alpha() == 0) + { + + painter.setPen(QPen(QColor(Qt::red), 1)); + painter.drawLine(c_colorBlockWidth - 1, 1, 1, c_colorBlockWidth - 1); + } + + painter.setPen(QPen(QColor(m_edgeColor), 1)); + painter.drawRect(0, 0, c_colorBlockWidth - 1, c_colorBlockWidth - 1); + + QIcon iconColor(pixColor); + setIcon(iconColor); + setIconSize(QSize(c_colorBlockWidth, c_colorBlockWidth)); + setFixedSize(c_colorBtnWidth, c_colorBtnHeight); + connect(this, &GLDColorBlock::clicked, this, &GLDColorBlock::onClick); +} + +/** + * 颜色块的点击事件 + */ +void GLDColorBlock::onClick() +{ + emit colorValue(m_color, m_edgeColor); + emit colorBlock(this); + emit commitSelectedColor(m_color, m_edgeColor); + setStyleSheet("border: 1px solid #39a9d1; border-radius: 2px; background-color: #dbf3fc;"); +} + +/** + * GColorListEx class 构造函数 + */ +GColorListEx::GColorListEx(QWidget *parent, QColor color ,bool isLoadRecentColor) : + QComboBox(parent), + m_comboBoxWidget(NULL), + m_userColor(QColor("#ffffff")), + m_curColor(color), + m_recentColorTable(NULL), + m_recentUseColorCount(0), + m_isLoadRecentColor(isLoadRecentColor), + m_isShowRGBColor(false), + m_isShowRGBStr(false), + m_iconUrlInEdit(":/icons/GColorListEx-backgroundColor.png") +{ + setObjectName("GColorListEx"); + loadColorFile(); + // 判断是否从临时配置文件中加载最近使用的颜色 + if (m_isLoadRecentColor) + { + loadSelectedMoreColor(); + } + initColorComboBox(); + setModel(m_comboBoxWidget->model()); + setView(m_comboBoxWidget); + updateCurrentColor(); + setHasBorder(true); + this->setStyleSheet(loadQssFile(":/qsses/GColorListEx.qss")); + GLDShadow *pShadow = new GLDShadow(this); + pShadow->removeShadow(); +} + +GColorListEx::~GColorListEx() +{ + freeAndNil(m_comboBoxWidget); +} + +/** + * @brief GColorListEx::setHasBorder 设置GColorListEx有无边框 + * @param flag false-无边框 true-有边框 + */ +void GColorListEx::setHasBorder(bool bHasBorder) +{ + if (bHasBorder) + { + setProperty("ComboBoxBorder", true); + } + else + { + setProperty("ComboBoxBorder", false); + } + + this->setStyleSheet(loadQssFile(c_sColorListQssFile)); +} + +GLDColorBlock *GColorListEx::findColorBlock(const QColor &color) +{ + GLDColorBlock *findResult = NULL; + + foreach (GLDColorTable *colorTable, m_colorTableList) + { + findResult = colorTable->findColorBlock(color); + + if (NULL != findResult) + { + break; + } + } + + return findResult; +} + +QColor GColorListEx::currentColor() const +{ + return m_curColor; +} + +void GColorListEx::setCurrentColor(const QColor color) +{ + m_curColor = color; + GLDColorBlock *findBlock = findColorBlock(color); + + if (NULL == findBlock) + { + m_userColor = color; + addRecentColorList(); + } + + emit colorIndexChange(color); +} + +bool GColorListEx::isLoadRecentColor() const +{ + return m_isLoadRecentColor; +} + +void GColorListEx::setIsLoadRecentColor(const bool isLoadRecentColor) +{ + if (!isLoadRecentColor) + { + removeRecentColorConfFile(); + } + + m_isLoadRecentColor = isLoadRecentColor; +} + +bool GColorListEx::isShowRGBColor() const +{ + return m_isShowRGBColor; +} + +void GColorListEx::setIsShowRGBColor(const bool isShowColorRGB) +{ + m_isShowRGBColor = isShowColorRGB; + + if (isShowColorRGB) + { + if (!m_blockColors.isEmpty()) + { + // 不显示第一个透明颜色,所以从1开始 + for (int i = 1; i < m_blockColors.size(); ++i) + { + GLDColorBlock *pColorBlock = findColorBlock(m_blockColors.at(i)); + + if (pColorBlock) + { + pColorBlock->setToolTip(m_blockColors.at(i).name()); + } + } + } + } +} + +bool GColorListEx::isShowRGBStr() const +{ + return m_isShowRGBStr; +} + +void GColorListEx::setIsShowRGBStr(bool isShowRGBStr) +{ + m_isShowRGBStr = isShowRGBStr; +} + +QString GColorListEx::iconUrlInEdit() const +{ + return m_iconUrlInEdit; +} + +void GColorListEx::setIconUrlInEdit(const QString iconUrl) +{ + m_iconUrlInEdit = iconUrl; + updateCurrentColor(); +} + +/** + * 画颜色块并显示到GColorListEx的编辑框中 + */ +void GColorListEx::drawColor(const QColor &color, const QColor &edgeColor) +{ + m_curColor = color; +// QPixmap pixColor(c_colorBlockWidth, c_colorBlockHeight); + QPixmap pixColor(m_iconUrlInEdit); + + QPainter painter(&pixColor); + QImage image(m_iconUrlInEdit); + painter.drawImage(QRect(0, 0, c_colorBlockWidth, c_colorBlockHeight), image); + + painter.fillRect(0, c_yStartPos, c_colorBlockWidth, c_blockHeightInEdit + 1, color); + //分透明色需要画红线,其他色不需要 + if (color.alpha() == 0) + { + painter.setPen(QPen(QColor(Qt::red), 1)); + painter.drawLine(c_colorBlockWidth - 1, c_yStartPos + 1, 1, c_yStartPos + 4); + } + else + { + if (m_isShowRGBColor) + { + setToolTip(color.name()); + } + } + + setCurrentColor(color); + + painter.setPen(QPen(QColor(edgeColor), 1)); + painter.drawRect(0, c_yStartPos, c_colorBlockWidth - 1, c_blockHeightInEdit); + + QIcon iconColor(pixColor); + QListWidgetItem * item = m_comboBoxWidget->item(0); + item->setIcon(iconColor); + m_comboBoxWidget->setIconSize(QSize(0, 0)); + setCurrentIndex(0); + hidePopup(); +} + +void GColorListEx::moreColor() +{ + // 更多颜色对话框汉化 + QColor originalColor = QColor(Qt::gray); + QColor color = QColorDialog::getColor(currentColor(), this, tr("More Color")); + + if (color.isValid()) + { + GLDColorBlock* selectColorBlock = findColorBlock(color); + if (NULL != selectColorBlock) + { + selectColorBlock->onClick(); + } + else + { + setCurrentColor(color); + updateRecentColorTable(); + if (m_isLoadRecentColor) + { + saveSelectedMoreColor(); + } + } + + drawColor(color, originalColor); + } + + emit colorIndexChange(color); +} + +void GColorListEx::currentSelectedBlock(GLDColorBlock *block) +{ + m_originalBlock = m_currentBlock; + m_currentBlock = block; + m_originalBlock->setStyleSheet(NULL); +} + +QColor GColorListEx::getColor(const QString sVal) +{ + if (sVal.isNull() || !QColor(sVal).isValid()) + { + return QColor(Qt::white); + } + else if (sVal.length() > 7 && sVal.endsWith("00")) + { + return QColor(255, 255, 255, 0); + } + else + { + return QColor(sVal); + } +} + +/** + * 添加GLDColorTable到listWidget + */ +void GColorListEx::addTable(GLDColorTable *table, int tableWid, int tableHeight) +{ + table->initTableLayout(); + m_colorTableList.append(table); + connect(table, &GLDColorTable::currentSelectedColor, + this, &GColorListEx::currentSelectedColor); + connect(table, &GLDColorTable::currentSelectedColor, + this, &GColorListEx::drawColor); + connect(table, &GLDColorTable::currentSelectedBlock, + this, &GColorListEx::currentSelectedBlock); + connect(table, SIGNAL(commitSelectedColor(QColor, QColor)), + this, SLOT(commitSelectedColor(QColor, QColor))); + QListWidgetItem *item = new QListWidgetItem(m_comboBoxWidget); + item->setSizeHint(QSize(tableWid, tableHeight)); + m_comboBoxWidget->setItemWidget(item, table); + m_comboBoxWidget->addItem(item); +} + +void GColorListEx::addThemeColorTable() +{ + GLDColorTable *pThemeColorTable = NULL; + + const QList blokColors = m_blockColors.mid((c_grayColorRowCount + c_standardColorRowCount)* c_colorColumnCount, c_colorColumnCount); + const QList edgeColors = m_edgeColors.mid((c_grayColorRowCount + c_standardColorRowCount) * c_colorColumnCount, c_colorColumnCount); + + pThemeColorTable = new GLDColorTable(blokColors, edgeColors, this); + pThemeColorTable->setContentsMargins(0, 0, 0, 0); + pThemeColorTable->addTitle(tr("theme color")); + + for (int i = 1; i < c_themeColorRowCount; ++i) + { + pThemeColorTable->appendColorRow( + m_blockColors.mid((c_grayColorRowCount + c_standardColorRowCount + i) * c_colorColumnCount, c_colorColumnCount), + m_edgeColors.mid((c_grayColorRowCount + c_standardColorRowCount + i) * c_colorColumnCount, c_colorColumnCount)); + } + + addTable(pThemeColorTable, c_colorRowWidth, c_themeTabHeight); +} + +void GColorListEx::addGrayColorTable() +{ + GLDColorTable *pGrayColorTable = NULL; + pGrayColorTable = new GLDColorTable(m_blockColors.mid(0, c_colorColumnCount), + m_edgeColors.mid(0, c_colorColumnCount), this); + + //初始化前一个选中颜色块和当前选中颜色块, 以增加选中效果 + m_originalBlock = pGrayColorTable->initBlock(); + m_currentBlock = pGrayColorTable->initBlock(); + m_currentBlock->setStyleSheet("border: 1px solid #39a9d1; border-radius: 2px; background-color: #dbf3fc;"); + + pGrayColorTable->setProperty("GLDGrayColorTable", true); + pGrayColorTable->setContentsMargins(0, 0, 0, c_grayTableMargin); + addTable(pGrayColorTable, c_colorRowWidth, c_grayTableHeight); +} + +void GColorListEx::addMoreButton() +{ + QPushButton *pMoreBtn = new QPushButton(this); + pMoreBtn->setText(tr("More Color(w)...")); + pMoreBtn->setProperty("moreBtn", true); + + QHBoxLayout *pBtnLayout = new QHBoxLayout(m_comboBoxWidget); + pBtnLayout->setContentsMargins(0, c_moreBtnTop, 0, c_moreBtnBottom); + + QListWidgetItem *pMoreColorItem = new QListWidgetItem(m_comboBoxWidget); + pMoreColorItem->setSizeHint(QSize(c_colorRowWidth, c_moreBtnHeight)); + + m_comboBoxWidget->setLayout(pBtnLayout); + m_comboBoxWidget->setItemWidget(pMoreColorItem, pMoreBtn); + m_comboBoxWidget->addItem(pMoreColorItem); + + connect(pMoreBtn, &QPushButton::clicked, this, &GColorListEx::moreColor); +} + +void GColorListEx::addStandardColorTable() +{ + GLDColorTable *standardColorTable = + new GLDColorTable(m_blockColors.mid(c_grayColorRowCount * c_colorColumnCount, c_colorColumnCount), + m_edgeColors.mid(c_grayColorRowCount * c_colorColumnCount, c_colorColumnCount), this); + standardColorTable->addTitle(tr("commonly used color")); + standardColorTable->setContentsMargins(0, 0, 0, c_standardTabMargin); + addTable(standardColorTable, c_colorRowWidth, c_standardTabHeight); +} + +void GColorListEx::addRecentColorTable() +{ + for (int i = 0; i < c_colorColumnCount; ++i) + { + // 从临时文件中加载,此时 m_recentUseColor 不为空, 计算颜色块的边界颜色,否则,添加默认颜色 + if (m_recentUseColor.count() > 0 && isLoadRecentColor()) + { + if (i < m_recentUseColorCount) + { + m_recentUseEdgeColor.append(getEdgeColor(m_recentUseColor.at(i))); + } + else + { + m_recentUseEdgeColor.append(QColor(Qt::white)); + } + } + else + { + m_recentUseColor.append(QColor("#ffffff")); + m_recentUseEdgeColor.append(QColor(Qt::white)); + } + } + + m_recentColorTable = new GLDColorTable(m_recentUseColor, m_recentUseEdgeColor, this); + m_recentColorTable->setContentsMargins(0, 0, 0, 0); + + // 从临时文件中加载,改变下拉框的高度,以显示最近使用色,否则隐藏最近使用色 + if (isLoadRecentColor()) + { + m_comboBoxWidget->setFixedHeight(c_listWidgetHeight + c_recentColorTableHeight); + addTable(m_recentColorTable, c_colorRowWidth , c_recentColorTableHeight); + } + else + { + addTable(m_recentColorTable, c_colorRowWidth , 0); + } +} + +QColor GColorListEx::getEdgeColor(const QColor &color) +{ + QColor result(Qt::white); + + int nRed = color.red() - c_blockColorDeviation; + if (nRed < 0) + { + nRed = 0; + } + + int nGreen = color.green() - c_blockColorDeviation; + if (nGreen < 0) + { + nGreen = 0; + } + + int nBlue = color.blue() - c_blockColorDeviation; + if (nBlue < 0) + { + nBlue = 0; + } + + result.setRgb(nRed, nGreen, nBlue); + return result; +} + +void GColorListEx::updateRecentColorTable() +{ + QListWidgetItem *item = m_comboBoxWidget->item(c_recentColorTableRow); + + if (0 == item->sizeHint().height()) + { + item->setSizeHint(QSize(c_colorRowWidth, c_recentColorTableHeight)); + m_comboBoxWidget->setFixedHeight(c_listWidgetHeight + c_recentColorTableHeight); + QWidget *parentWidget = m_comboBoxWidget->parentWidget(); + if (NULL != parentWidget) + { + m_comboBoxWidget->parentWidget()->setFixedHeight(c_listWidgetHeight + c_recentColorTableHeight); + } + } + + for (int i = 0; i < m_recentUseColorCount; ++i) + { + QColor color = m_recentUseColor.at(i); + m_recentUseEdgeColor[i] = getEdgeColor(color); + } + + m_recentColorTable->updateColorRow(0, m_recentUseColor, m_recentUseEdgeColor, + m_recentUseColorCount); +} + +/** + * 初始化GColorListEx + */ +void GColorListEx::initColorComboBox() +{ + // 设置ListWidget的样式 + initPopUpWidget(); + // 灰度颜色行 + addGrayColorTable(); + // 标准颜色行 + addStandardColorTable(); + // 最近使用颜色 + addRecentColorTable(); + // 主题颜色行 + addThemeColorTable(); + // 更多 Button + addMoreButton(); +} + +void GColorListEx::initPopUpWidget() +{ + m_comboBoxWidget = new QListWidget(this); + m_comboBoxWidget->setContentsMargins(0, 0, 0, c_listWidgetMargin); + m_comboBoxWidget->setFixedSize(c_colorRowWidth + c_listWidgetMargin, c_listWidgetHeight); + m_comboBoxWidget->setSelectionMode(QAbstractItemView::NoSelection); + m_comboBoxWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_comboBoxWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); +} + +void GColorListEx::addRecentColorList() +{ + if (!m_recentUseColor.contains(m_userColor)) + { + if (m_recentUseColorCount >= 9) + { + m_recentUseColor.removeLast(); + } + else + { + ++m_recentUseColorCount; + if (m_recentUseColor.count() >= 9) + { + m_recentUseColor.removeLast(); + } + } + } + else + { + int existIndex = m_recentUseColor.indexOf(m_userColor); + m_recentUseColor.removeAt(existIndex); + } + + m_recentUseColor.insert(0, m_userColor); +} + +void GColorListEx::loadDefaultConfigColorVal() +{ + m_blockColors << getColor("#ffffff00") << getColor("#d7d2d1") << getColor("#c2c2c2") + << getColor("#c2c2c2") << getColor("#86848c") << getColor("#707070") + << getColor("#5f5f5f") << getColor("#4f4e4e") << getColor("#000000") + + << getColor("#ff010f") << getColor("#f9865a") << getColor("#fedf7d") + << getColor("#91d151") << getColor("#37b64a") << getColor("#00b1f0") + << getColor("#0171c0") << getColor("#005c7e") << getColor("#662d91") + + << getColor("#ffffff") << getColor("#ffd5aa") << getColor("#fcfecc") + << getColor("#daffeb") << getColor("#a5e0dd") << getColor("#c9fefd") + << getColor("#c6aae0") << getColor("#f1b097") << getColor("#ffabfe") + + << getColor("#d8d8d8") << getColor("#feac54") << getColor("#ffff00") + << getColor("#d1ebb7") << getColor("#96e2dd") << getColor("#9fe0ef") + << getColor("#bd99de") << getColor("#f38871") << getColor("#b983f0") + + << getColor("#bfbfbf") << getColor("#fe8100") << getColor("#facb3a") + << getColor("#7ec377") << getColor("#16c0ba") << getColor("#4bc2e5") + << getColor("#9c7bbd") << getColor("#fb6f6b") << getColor("#8560a8") + + << getColor("#a5a5a5") << getColor("#bf6100") << getColor("#feb500") + << getColor("#54c665") << getColor("#2e9c94") << getColor("#00aeee") + << getColor("#7c589d") << getColor("#f31f17") << getColor("#6c4d8c") + + << getColor("#7f7f7f") << getColor("#7a5102") << getColor("#e9a61e") + << getColor("#2d9c48") << getColor("#00746a") << getColor("#0075ab") + << getColor("#662b90") << getColor("#9c450b") << getColor("#662d91"); + + m_edgeColors << getColor("#979797") << getColor("#c2c2c2") << getColor("#a4a4a1") + << getColor("#868d83") << getColor("#707070") << getColor("#464646") + << getColor("#262626") << getColor("#000000") << getColor("#000000") + + << getColor("#a7302f") << getColor("#c95f26") << getColor("#d5a927") + << getColor("#00b150") << getColor("#187c2f") << getColor("#0075ab") + << getColor("#005c7e") << getColor("#0c4758") << getColor("#551a83") + + << getColor("#e2e5e7") << getColor("#feac56") << getColor("#e6ea89") + << getColor("#a9e4a9") << getColor("#75ce9f") << getColor("#6ed6f4") + << getColor("#c7aade") << getColor("#dd6045") << getColor("#ff57ff") + + << getColor("#bfbfbf") << getColor("#ff8000") << getColor("#e6e873") + << getColor("#92d14f") << getColor("#00aa9d") << getColor("#01bff6") + << getColor("#8560a8") << getColor("#de5f49") << getColor("#aa58ff") + + << getColor("#a5a5a5") << getColor("#bf6001") << getColor("#ff9100") + << getColor("#37b64a") << getColor("#289f96") << getColor("#30a8d5") + << getColor("#8560a8") << getColor("#f31f19") << getColor("#8361a8") + + << getColor("#7f7f7f") << getColor("#bf6100") << getColor("#cb883c") + << getColor("#2c9e3d") << getColor("#1e9087") << getColor("#0075ab") + << getColor("#652c90") << getColor("#ec6c64") << getColor("#642c90") + + << getColor("#626262") << getColor("#803f00") << getColor("#f8b258") + << getColor("#187c2f") << getColor("#005b51") << getColor("#005c7e") + << getColor("#532f6e") << getColor("#ba1512") << getColor("#450f60"); +} + +void GColorListEx::loadSelectedMoreColor() +{ + QString tempDir = QDir::tempPath() + c_recentColorConfPath; + QFile file(tempDir); + + if (!file.open(QFile::ReadOnly)) + { + file.close(); + return; + } + + QString strSelectColor = QString::fromLatin1(file.readAll()); + QStringList selectColorList = strSelectColor.split(","); + + if (!selectColorList.empty()) + { + foreach (QString str, selectColorList) + { + if (m_recentUseColor.count() < 9) + { + if ("#ffffff" != str) + { + ++m_recentUseColorCount; + } + m_recentUseColor.append(QColor(str)); + } + } + } + + file.close(); +} + +void GColorListEx::saveSelectedMoreColor() +{ + // 获取临时文件路径 + QString tempDir = QDir::tempPath() + c_recentColorConfPath; + QFile file(tempDir); + + if (!file.exists()) + { + QDir::temp().mkdir("GLDRes"); + } + file.setFileName(tempDir); + // 以覆盖之前的记录打开 + if (!file.open(QFile::ReadWrite | QFile::Truncate)) + { + file.close(); + return; + } + + QTextStream textout(&file); + // 加载已选的更多颜色到临时文件中 + foreach (QColor recentColor, m_recentUseColor) + { + textout << recentColor.name() + ","; + } + file.close(); +} + +void GColorListEx::removeRecentColorConfFile() +{ + QString tempDir = QDir::tempPath() + c_recentColorConfPath; + if (!tempDir.isEmpty()) + { + QFile file(tempDir); + if (file.exists()) + { + QFile::remove(tempDir); + } + } +} + +void GColorListEx::updateCurrentColor() +{ + GLDColorBlock *initBlock = findColorBlock(m_curColor); + if (NULL != initBlock) + { + drawColor(initBlock->color(), initBlock->edgeColor()); + initBlock->onClick(); + } + else + { + m_userColor = m_curColor; + addRecentColorList(); + updateRecentColorTable(); + drawColor(m_curColor, getEdgeColor(m_curColor)); + } +} + +/** + * 加载GColorListEx.ini配置文件(配置了颜色板中的颜色值) + */ +void GColorListEx::loadColorFile(const QString &fileName) +{ + if (fileName.isEmpty() || !fileExists(fileName)) + { + // 加载默认颜色值 + loadDefaultConfigColorVal(); + return; + } + + QSettings *pSetting = new QSettings(fileName, QSettings::IniFormat); + if (NULL == pSetting) + { + delete pSetting; + return; + } + + for (int i = 0; i < c_edgeColorRowCount * c_colorColumnCount; ++i) + { + QString strColorkey = "blockColor/blockColor" + QString("%1").arg(i); + m_blockColors.append(getColor(pSetting->value(strColorkey).toString())); + } + + for (int i = 0; i < c_edgeColorRowCount * c_colorColumnCount; ++i) + { + QString strColorkey = "edgeColor/edgeColor" + QString("%1").arg(i); + m_edgeColors.append(getColor(pSetting->value(strColorkey).toString())); + } + + delete pSetting; +} + +void GColorListEx::commitSelectedColor(const QColor &color, const QColor &edgeColor) +{ + int index; + foreach (GLDColorTable * colorTable, m_colorTableList) + { + index = colorTable->findColorBlockIndex(color, edgeColor); + if (index != -1) + { + emit colorBlockClicked(index); + } + } +} + +GLDColorRow::GLDColorRow(const QList &colors, const QList &edgeColors, QWidget *parent) : + QWidget(parent) +{ + initColorBlocks(colors, edgeColors); + initColorBlocksLayout(); + setFixedWidth(c_colorRowWidth); + setFixedHeight(c_colorRowHeight); +} + +/** + * 设置行的背景颜色 + */ +void GLDColorRow::setBackgroundColor(QColor &color) +{ + setAutoFillBackground(true); + QPalette oPalette; + oPalette.setColor(QPalette::Background, color); + setPalette(oPalette); +} + +void GLDColorRow::updateColorBlocks(QList &colors, QList &edgeColors, + int updateColorCount) +{ + for (int i = 0; i < m_colorBlocks.count(); ++i) + { + GLDColorBlock *pColorBlock = m_colorBlocks.at(i); + // 初始设置每个块disable为false, 可以hover + pColorBlock->setDisabled(false); + pColorBlock->updateColor(colors.at(i), edgeColors.at(i)); + // 当超过更多颜色中添加颜色, 设置后面的颜色块disable + if (i >= updateColorCount) + { + pColorBlock->setDisabled(true); + } + // 设置此行(常用色第二行, 即从系统颜色框中选择的颜色)最左边的为最新选择色 + if (0 == i) + { + pColorBlock->onClick(); + } + } +} + +GLDColorBlock* GLDColorRow::initBlock() +{ + return m_colorBlocks.last(); +} + +int GLDColorRow::findColorBlockIndex(const QColor color) +{ + int index = -1; + for (int i = 0; i < m_colorBlocks.size(); i++) + { + if (color.name() == m_colorBlocks.at(i)->color().name()) + { + index = i; + break; + } + } + return index; +} + +GLDColorBlock *GLDColorRow::findColorBlock(const QColor color) +{ + GLDColorBlock *findBlock = NULL; + foreach (GLDColorBlock *colorBlock, m_colorBlocks) + { + if (color.name() == colorBlock->color().name()) + { + findBlock = colorBlock; + break; + } + } + return findBlock; +} + +/** + * 初始化颜色Row + */ +void GLDColorRow::initColorBlocks(const QList &colors, const QList &edgeColors) +{ + for (int i = 0; i < colors.count(); ++i) + { + GLDColorBlock *pColorBlock = new GLDColorBlock(colors.at(i), edgeColors.at(i), this); + + connect(pColorBlock, &GLDColorBlock::colorValue, this, + &GLDColorRow::currentSelectedColor); + connect(pColorBlock, &GLDColorBlock::colorBlock, this, + &GLDColorRow::currentSelectedBlock); + connect(pColorBlock, &GLDColorBlock::commitSelectedColor, this, + &GLDColorRow::commitSelectedColor); + pColorBlock->setProperty("colorBlock", true); + m_colorBlocks.append(pColorBlock); + } +} + +void GLDColorRow::initColorBlocksLayout() +{ + QHBoxLayout *pLayout = new QHBoxLayout; + pLayout->setSpacing(c_colorBlockSpacing); + pLayout->setAlignment(Qt::AlignTop); + pLayout->setContentsMargins(c_colorRowLeftMargin, 0, c_colorRowRightMargin, 0); + setLayout(pLayout); + foreach (GLDColorBlock *pColorBlock, m_colorBlocks) + { + pLayout->addWidget(pColorBlock); + } +} + +/** + * GLDColorTableTitle +*/ +GLDColorTableTitle::GLDColorTableTitle(QWidget *parent) : + QPushButton(parent) +{ + setProperty("GLDColorLabel", true); +} + +/** + * GLDColorTable + */ +GLDColorTable::GLDColorTable(const QList &firstRowColors, + const QList &firstRowEdgeColors, QWidget *parent) : + QWidget(parent), + m_title(NULL), + m_BackColor(Qt::white) +{ + setBackgroundColor(m_BackColor); + GLDColorRow *pFirstRow = new GLDColorRow(firstRowColors, firstRowEdgeColors, this); + m_colorRows.append(pFirstRow); + connect(pFirstRow, &GLDColorRow::currentSelectedColor, + this, &GLDColorTable::currentSelectedColor); + connect(pFirstRow, &GLDColorRow::currentSelectedBlock, + this, &GLDColorTable::currentSelectedBlock); + connect(pFirstRow, &GLDColorRow::commitSelectedColor, + this, &GLDColorTable::commitSelectedColor); +} + +GLDColorTable::~GLDColorTable() +{ + freeAndNil(m_title); +} + +/** + * 设置颜色Table的背景颜色 + */ +void GLDColorTable::setBackgroundColor(QColor &color) +{ + setAutoFillBackground(true); + QPalette oPalette; + oPalette.setColor(QPalette::Background, color); + setPalette(oPalette); +} + +GLDColorBlock* GLDColorTable::initBlock() +{ + return m_colorRows.first()->initBlock(); +} + +GLDColorBlock *GLDColorTable::findColorBlock(const QColor &color) +{ + GLDColorBlock *findResult = NULL; + foreach (GLDColorRow *colorRow, m_colorRows) + { + findResult = colorRow->findColorBlock(color); + if (NULL != findResult) + { + break; + } + } + return findResult; +} + +/** + * @brief GLDColorTable::mouseReleaseEvent 截获鼠标释放事件, + * 不然点击到button之外的地方下拉框会收起 + * @param e + */ +void GLDColorTable::mouseReleaseEvent(QMouseEvent *e) +{ + e->accept(); +} + +/** + * 对颜色Table添加标题 + */ +void GLDColorTable::addTitle(const QString &title) +{ + m_title = new GLDColorTableTitle(this); + m_title->setText(title); +} + +/** + * 向颜色Table中添加一行颜色 + */ +void GLDColorTable::appendColorRow(const QList &colors, const QList &edgeColor) +{ + GLDColorRow *pColorRow = new GLDColorRow(colors, edgeColor); + m_colorRows.append(pColorRow); + connect(pColorRow, &GLDColorRow::currentSelectedColor, + this, &GLDColorTable::currentSelectedColor); + connect(pColorRow, &GLDColorRow::currentSelectedBlock, + this, &GLDColorTable::currentSelectedBlock); + connect(pColorRow, &GLDColorRow::commitSelectedColor, + this, &GLDColorTable::commitSelectedColor); +} + +void GLDColorTable::updateColorRow(int row, QList &blockColors, + QList &blockEdgeColors, int updateColorCount) +{ + GLDColorRow *pColorRow = m_colorRows.at(row); + pColorRow->updateColorBlocks(blockColors, blockEdgeColors, updateColorCount); +} + +/** + * 对颜色Table中的title布局 + */ +void GLDColorTable::initTitleLayout(QVBoxLayout *layout) +{ + if (NULL != m_title) + { + m_title->setProperty("tabTitle", true); + QVBoxLayout *pTitleLayout = new QVBoxLayout(); + pTitleLayout->setSpacing(0); + pTitleLayout->addWidget(m_title); + pTitleLayout->setContentsMargins(c_tabTitleLeftMargin, c_tabTitleTopMargin, 0, c_tabTitleBottomMargin); + layout->addLayout(pTitleLayout); + } +} + +/** + * 对颜色Table中的一行布局 + */ +void GLDColorTable::initColorRows(QVBoxLayout *layout) +{ + QVBoxLayout *pColorRowsLayout = new QVBoxLayout(); + pColorRowsLayout->addSpacing(c_tabRowSpacing); + pColorRowsLayout->setContentsMargins(0, 0, 0, c_tabRowBottomMargin); + foreach (GLDColorRow *colorRow, m_colorRows) + { + pColorRowsLayout->addWidget(colorRow); + } + layout->addLayout(pColorRowsLayout); +} + +/** + * 对颜色Table布局 + */ +void GLDColorTable::initTableLayout() +{ + QVBoxLayout *pLayout = new QVBoxLayout(); + pLayout->setSpacing(0); + pLayout->setContentsMargins(0, c_tabTopMargin, 0, 0); + setLayout(pLayout); + + initTitleLayout(pLayout); + initColorRows(pLayout); +} + +int GLDColorTable::findColorBlockIndex(const QColor &color, const QColor &edgeColor) +{ + G_UNUSED(edgeColor); + int index = -1; + + foreach (GLDColorRow* colorRow, m_colorRows) + { + if (colorRow->findColorBlockIndex(color) != -1) + { + index = colorRow->findColorBlockIndex(color); + } + } + + return index; +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDComboBox.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDComboBox.cpp new file mode 100644 index 00000000..f5a91d01 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDComboBox.cpp @@ -0,0 +1,510 @@ +#include "GLDComboBox.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "GLDShadow.h" +#include "GLDFileUtils.h" +#include "GLDScrollStyle.h" + +const int c_maxVisibleItems = 6; + +const GString c_sCustomComBoxQssFile = ":/qsses/GLDCustomComboBoxEx.qss"; + +/* GLDCustomComboBox */ +GLDCustomComboBox::GLDCustomComboBox(QWidget *parent) : QComboBox(parent), m_isReadOnly(false) +{ + GLDComboBoxLineEdit *lineEdit = new GLDComboBoxLineEdit(this); + setLineEdit(lineEdit); + + connect(lineEdit, SIGNAL(cursorPositionChanged(int, int)), + this, SIGNAL(cursorPositionChanged())); + connect(lineEdit, SIGNAL(selectionChanged()), + this, SIGNAL(selectionChanged())); +} + +void GLDCustomComboBox::showPopup() +{ + resizeContent(); + QComboBox::showPopup(); + QTreeView *treeView = dynamic_cast(view()); + + if (NULL != treeView) + { + connect(treeView, SIGNAL(expanded(QModelIndex)), this, SLOT(onExpandOrCollapsed(QModelIndex))); + connect(treeView, SIGNAL(collapsed(QModelIndex)), this, SLOT(onExpandOrCollapsed(QModelIndex))); + } +} + +void GLDCustomComboBox::hidePopup() +{ + QComboBox::hidePopup(); + QTreeView *treeView = dynamic_cast(view()); + + if (NULL != treeView) + { + treeView->sizeHint(); + disconnect(treeView, SIGNAL(expanded(QModelIndex)), this, SLOT(onExpandOrCollapsed(QModelIndex))); + disconnect(treeView, SIGNAL(collapsed(QModelIndex)), this, SLOT(onExpandOrCollapsed(QModelIndex))); + } +} + +void GLDCustomComboBox::updateEditFieldGeometry() +{ + QStyleOptionComboBox optCombo; + optCombo.init(this); + optCombo.editable = true; + optCombo.subControls = QStyle::SC_ComboBoxFrame | QStyle::SC_ComboBoxEditField; + { + optCombo.subControls |= QStyle::SC_ComboBoxArrow; + QRect rect = style()->subControlRect(QStyle::CC_ComboBox, &optCombo, QStyle::SC_ComboBoxEditField, this); +#ifdef __APPLE__ +#else + rect = rect.adjusted(-2, -2, 2, 2); +#endif + + if (lineEdit() != NULL) + { + lineEdit()->setGeometry(rect); + } + } +} + +bool GLDCustomComboBox::isReadOnly() +{ + if (NULL != lineEdit()) + { + return lineEdit()->isReadOnly(); + } + else + { + return false; + } +} + +void GLDCustomComboBox::setReadOnly(bool value) +{ + if (value != m_isReadOnly && lineEdit() != NULL) + { + m_isReadOnly = value; + GLDComboBoxLineEdit *gldLineEdit = dynamic_cast(lineEdit()); + + if (NULL != gldLineEdit) + { + gldLineEdit->setReadOnly(value); + } + } +} + +bool GLDCustomComboBox::hasSelectedText() +{ + return lineEdit()->hasSelectedText(); +} + +bool GLDCustomComboBox::canDelete() +{ + if (m_isReadOnly) + { + GLDComboBoxLineEdit *gldLineEdit = dynamic_cast(lineEdit()); + + if (NULL != gldLineEdit) + { + return gldLineEdit->canDelete(); + } + } + + return true; +} + +void GLDCustomComboBox::setCanDelete(bool value) +{ + if (m_isReadOnly) + { + GLDComboBoxLineEdit *gldLineEdit = dynamic_cast(lineEdit()); + + if (NULL != gldLineEdit) + { + gldLineEdit->setCanDelete(value); + } + } +} + +void GLDCustomComboBox::setCurrentIndexAndEmitSignal(int index) +{ + emit onSetCurrentIndex(index); + QComboBox::setCurrentIndex(index); +} + +void GLDCustomComboBox::resizeContent() +{ + QTreeView *treeView = dynamic_cast(view()); + int nFitWidth = this->sizeHint().width(); + + if (NULL != treeView) + { + nFitWidth = qMax(nFitWidth, treeView->sizeHint().width()); + } + + int nWidth = (nFitWidth > width()) ? nFitWidth : width(); + + //修正字符为全角时,字符显示不全 + nWidth += 4; + + //如果为无边框,加上左右边框大小 + if (property("borderStyle") == "noBorder") + { + nWidth += 2; + } + + if (QWidget *popup = this->view()->window()) + { + popup->setMinimumWidth(nWidth); + // max width = 1000 + popup->setMaximumWidth(1000); + } +} + +void GLDCustomComboBox::setAlignment(Qt::Alignment align) +{ + lineEdit()->setAlignment(align); +} + +void GLDCustomComboBox::onExpandOrCollapsed(const QModelIndex &index) +{ + resizeContent(); + Q_UNUSED(index); +} + +void GLDCustomComboBox::doCursorPositionChanged(int, int) +{ + emit cursorPositionChanged(); +} + +void GLDCustomComboBox::doSelectionChanged() +{ + emit selectionChanged(); +} + +void GLDCustomComboBox::resizeEvent(QResizeEvent *e) +{ + Q_UNUSED(e) + updateEditFieldGeometry(); +} + +GLDCustomComboBoxEx::GLDCustomComboBoxEx(QWidget *parent) : + GLDCustomComboBox(parent), + m_hasBorder(true), + m_isShow(false) +{ + setView(new QListView(this)); + + // Qss整体美化 + setMaxVisibleItems(c_maxVisibleItems); + setHasBorder(true); + this->setStyleSheet(loadQssFile(c_sCustomComBoxQssFile)); + + // 移除阴影 + GLDShadow *pShadow = new GLDShadow(this); + pShadow->removeShadow(); + + // 滚动条美化 + setStyle(new GLDScrollStyle(this)); + + this->lineEdit()->installEventFilter(this); +} + +void GLDCustomComboBoxEx::setFilterPopupStyleSheet() +{ + if (NULL != completer() && NULL != completer()->popup()) + { + completer()->popup()->setStyle(new GLDScrollStyle(this)); + // 加载QSS设置过滤弹出框的样式 + completer()->popup()->setStyleSheet("\ + QAbstractItemView\ + {\ + color: #6f6f6f;\ + background-color: #fff;\ + border: 1px solid #39a9d1;\ + outline: 0px;\ + }" + ); + completer()->popup()->setItemDelegate(new FilterPopupItemDelegate(completer()->popup())); + // 根据内容自适应长度 + QTreeView *treeViewPopup = dynamic_cast(completer()->popup()); + int nHintWidth = sizeHint().width(); + + if (NULL != treeViewPopup) + { + nHintWidth = qMax(nHintWidth, treeViewPopup->sizeHint().width()); + } + + int nFitWidth = (nHintWidth > width()) ? nHintWidth : width(); + + if (QWidget *popup = completer()->popup()->window()) + { + popup->setFixedWidth(nFitWidth); + } + } +} + +void GLDCustomComboBoxEx::resizeEvent(QResizeEvent *e) +{ + QStyleOptionComboBox optCombo; + optCombo.init(this); + optCombo.editable = true; + optCombo.subControls = QStyle::SC_ComboBoxFrame | QStyle::SC_ComboBoxEditField; + { + optCombo.subControls |= QStyle::SC_ComboBoxArrow; + QRect rect = style()->subControlRect(QStyle::CC_ComboBox, &optCombo, QStyle::SC_ComboBoxEditField, this); + + if (lineEdit() != NULL) + { + lineEdit()->setGeometry(rect); + } + } + Q_UNUSED(e); +} + +bool GLDCustomComboBoxEx::eventFilter(QObject *target, QEvent *e) +{ + if (this->lineEdit() == target && (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonDblClick)) + { + QMouseEvent *event = static_cast(e); + + if (event->buttons() & Qt::LeftButton) + { + if (m_isShow) + { + hidePopup(); + m_isShow = false; + return false; + } + else + { + showPopup(); + m_isShow = true; + return true; + } + } + } + + return GLDCustomComboBox::eventFilter(target, e); +} + +void GLDCustomComboBoxEx::keyPressEvent(QKeyEvent *e) +{ + //过滤弹出框的美化 + setFilterPopupStyleSheet(); + + QComboBox::keyPressEvent(e); +} + +void GLDCustomComboBoxEx::setHasBorder(bool hasBorder) +{ + if (m_hasBorder != hasBorder) + { + m_hasBorder = hasBorder; + } + + if (!m_hasBorder) + { + setProperty("borderStyle", "noBorder"); + this->setStyleSheet(loadQssFile(c_sCustomComBoxQssFile)); + } +} + +GLDLineWidthComboBox::GLDLineWidthComboBox(QWidget *parent) : QComboBox(parent) +{ + m_parent = parent; + m_parentSize = QSize(); + m_minLineWidth = 0; + m_maxLineWidth = 3; + m_currentLineWidth = m_minLineWidth; + m_inAddItem = false; + + connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(onCurrentIndexChanged(int))); +} + +void GLDLineWidthComboBox::setMinLineWidth(int minLineWidth) +{ + if (m_minLineWidth != minLineWidth) + { + m_minLineWidth = minLineWidth; + initLineWidthIcon(); + } +} + +void GLDLineWidthComboBox::setMaxLineWidth(int maxLineWidth) +{ + if (m_maxLineWidth != maxLineWidth) + { + m_maxLineWidth = maxLineWidth; + initLineWidthIcon(); + } +} + +void GLDLineWidthComboBox::setCurrentLineWidth(int lineWidth) +{ + setCurrentIndex(lineWidth - m_minLineWidth); + m_currentLineWidth = lineWidth; +} + +void GLDLineWidthComboBox::resizeEvent(QResizeEvent *) +{ + if (m_parent->size() != m_parentSize) + { + initLineWidthIcon(); + m_parentSize = m_parent->size(); + } +} + +void GLDLineWidthComboBox::onCurrentIndexChanged(int index) +{ + if (!m_inAddItem && index != -1) + { + m_currentLineWidth = m_minLineWidth + index; + } +} + +void GLDLineWidthComboBox::initLineWidthIcon() +{ + setIconSize(QSize(width() - 70, 24)); + clear(); + m_inAddItem = true; + + for (int i = m_minLineWidth; i <= m_maxLineWidth; i++) + { + QPixmap pix(QSize(width() - 70, 24)); + pix.fill(Qt::transparent); + + QPainter painter(&pix); + + QPen pen = painter.pen(); + pen.setColor(Qt::black); + pen.setWidth(i); + painter.setPen(pen); + + if (i != 0) + { + painter.drawLine(0, pix.height() / 2, pix.width() , pix.height() / 2); + } + + addItem(QIcon(pix), tr("pixel:%1").arg(i)); //TRANS_STRING("像素:%1" ).arg(i)); + setItemData(i - m_minLineWidth, i); + } + + m_inAddItem = false; + setCurrentLineWidth(m_currentLineWidth); +} + +GLDComboBoxLineEdit::GLDComboBoxLineEdit(QWidget *parent) : + QLineEdit(parent), m_canDelete(false) +{ +} + +bool GLDComboBoxLineEdit::canDelete() +{ + if (isReadOnly()) + { + return m_canDelete; + } + else + { + return true; + } +} + +void GLDComboBoxLineEdit::setCanDelete(bool value) +{ + if (isReadOnly()) + { + m_canDelete = value; + } +} + +void GLDComboBoxLineEdit::deleteSelectedText() +{ + if (hasSelectedText()) + { + this->del(); + } +} + +void GLDComboBoxLineEdit::keyPressEvent(QKeyEvent *keyEvent) +{ + if (isReadOnly() && m_canDelete && (keyEvent->key() == Qt::Key_Backspace || keyEvent->key() == Qt::Key_Delete)) + { + clear(); + keyEvent->accept(); + } + + QLineEdit::keyPressEvent(keyEvent); +} + +void GLDCustomComboBox::cut() +{ + if(false == isReadOnly()) + { + lineEdit()->cut(); + } +} + +void GLDCustomComboBox::paste() +{ + if(false == isReadOnly()) + { + lineEdit()->paste(); + } + +} + +void GLDCustomComboBox::copy() +{ + lineEdit()->copy(); +} + +void GLDCustomComboBox::deleteSelectedText() +{ + if (hasSelectedText()) + { + lineEdit()->del(); + } +} + +FilterPopupItemDelegate::FilterPopupItemDelegate(QObject *parent) + :QStyledItemDelegate(parent) +{ + Q_UNUSED(parent) +} + +FilterPopupItemDelegate::~FilterPopupItemDelegate() +{ + +} + +void FilterPopupItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + QStyleOptionViewItem view_option(option); + + //添加鼠标滑过的背景色 + if (option.state & QStyle::State_MouseOver) + { + painter->fillRect(view_option.rect, QColor(219, 244, 252)); + view_option.palette.setColor(QPalette::HighlightedText, QColor(255, 0, 0)); + } + QStyledItemDelegate::paint(painter, option, index); +} + +QSize FilterPopupItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + QSize size = QStyledItemDelegate::sizeHint(option, index); + size.setHeight(25); + return size; +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDCommentFrame.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDCommentFrame.cpp new file mode 100644 index 00000000..c6f85ee2 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDCommentFrame.cpp @@ -0,0 +1,295 @@ +#include "GLDWidget_Global.h" +#include "GLDMathUtils.h" +#include "GLDCommentFrame.h" +#include "GLDAbstractItemModel.h" + +#define CommentFrameOffset 5 +#define CommentFrameArrowInitLineLen 100 + +GArrowFrame::GArrowFrame(QFrame *parent) : QFrame(parent), m_topLeft(QPoint()), m_bottomRight(QPoint()) +{ +} + +void GArrowFrame::setPosition(QPoint topLeft, QPoint bottomRight) +{ + m_topLeft = topLeft; + m_bottomRight = bottomRight; + this->update(); +} + +void GArrowFrame::setBottomRight(QPoint bottomRight) +{ + m_bottomRight = bottomRight; + this->update(); +} + +QPoint GArrowFrame::bottomRight() +{ + return m_bottomRight; +} + +void GArrowFrame::setTopLeft(QPoint topLeft) +{ + m_topLeft = topLeft; + this->update(); +} + +QPoint GArrowFrame::topLeft() +{ + return m_topLeft; +} + +void GArrowFrame::paintEvent(QPaintEvent *) +{ + QPainter painter(this); + QColor color = Qt::black; + QPen pen(color, 1, Qt::SolidLine); + painter.setPen(pen); + m_topLeft = this->frameRect().bottomLeft(); + m_bottomRight = this->frameRect().topRight(); + painter.drawLine(m_topLeft, m_bottomRight); + + QPoint point[3]; + point[0] = m_topLeft; + point[1] = m_topLeft + QPoint(3, -5); + point[2] = m_topLeft + QPoint(6, 0); + + QBrush brush_(color); + QBrush old = painter.brush(); + painter.setBrush(brush_); + painter.drawConvexPolygon(point, 3); + painter.setBrush(old); +} + +GCommentFrame::GCommentFrame(QWidget *parent, QPoint pt) + : QFrame(parent), + m_arrow(0), m_nMarginWidth(5 * 2), m_nWidth(160), m_nHeight(80) +{ + m_parent = parent; + m_arrow = new GArrowFrame(); + m_arrow->setFrameShape(NoFrame); + m_arrow->setWindowFlags(Qt::ToolTip); + + // 去掉Frame的外边框 + setFrameShape(Panel); + // 去掉最小化,关闭按钮 + setWindowFlags(Qt::ToolTip); + + //因为setWindowFlags(Qt::ToolTip)会导致父子对象间的updatesEnabled属性不同步, + //进而引发批注框显示不稳定的问题,所以在这里强制将批注框的updatesEnabled属性置为true。 + setUpdatesEnabled(true); + + m_label = new QLabel(); + m_label->setParent(this); + // Label内自动换行 + m_label->setWordWrap(true); + m_label->setAlignment(Qt::AlignTop); + + // 设置背景Frame和Label的背景色 + QPalette p = palette(); + p.setColor(QPalette::Window, QColor(255, 255, 225)); + + setAutoFillBackground(true); + setPalette(p); + + m_label->setAutoFillBackground(true); + m_label->setPalette(p); + + m_label->resize(m_nWidth - m_nMarginWidth, m_nHeight - m_nMarginWidth); + m_label->setMinimumSize(m_nWidth - m_nMarginWidth, m_nHeight - m_nMarginWidth); + resize(m_label->size().width() + m_nMarginWidth, m_label->size().height() + m_nMarginWidth); + m_label->move(m_nMarginWidth / 2, m_nMarginWidth / 2); + + if ((pt.x() > 0 ) && (pt.y())) + { + move(pt); + } +} + +GCommentFrame::~GCommentFrame() +{ + freeAndNil(m_arrow); + freeAndNil(m_label); +} + +void GCommentFrame::hide() +{ + QFrame::hide(); + m_arrow->hide(); +} + +void GCommentFrame::show() +{ + QFrame::show(); + m_arrow->show(); +} + +void GCommentFrame::move(int x, int y) +{ + move(QPoint(x, y)); +} + +void GCommentFrame::move(const QPoint &pt) +{ + int nOffsetX = 15; + int nOffsetY = -10; + QPoint offset(nOffsetX, nOffsetY); + + QPoint oPointGlobal = m_parent->mapToGlobal(pt); + QFrame::move(oPointGlobal + offset); + + offset.setX(0); + m_arrow->resize(nOffsetX, abs(nOffsetY)); + m_arrow->setParent(m_parent); + m_arrow->move(pt + offset); +} + +void GCommentFrame::setCommentText(const QString &str) +{ + m_label->setText(str); + m_label->adjustSize(); + resize(m_label->size().width() + m_nMarginWidth, m_label->size().height() + m_nMarginWidth); +} + +/*GInfoFrame*/ +GInfoFrame::GInfoFrame(QFrame *parent, QPoint pt) : QFrame(parent) +{ + m_label = new QLabel(this); + + // 去掉Frame的外边框 + setFrameShape(Panel); + // 去掉最小化,关闭按钮 + setWindowFlags(Qt::ToolTip); + + // 设置背景Frame和Label的背景色 + QPalette palte = palette(); + palte.setColor(QPalette::Window, QColor(255, 255, 225)); + + setAutoFillBackground(true); + setPalette(palte); + + m_label->setAutoFillBackground(true); + m_label->setPalette(palte); + + if ((pt.x() > 0 ) && 0 != (pt.y())) + { + QFrame::move(pt); + } +} + +GInfoFrame::~GInfoFrame() +{ + freeAndNil(m_label); +} + +void GInfoFrame::move(const QPoint &point) +{ + if (orientation() == Qt::Vertical) + { + QFrame::move(point + QPoint(5, 0)); + } + else + { + QFrame::move(point + QPoint(-5, 10)); + } +} + +void GInfoFrame::setText(const QString &str) +{ + m_label->setText(str); + m_label->adjustSize(); + m_label->update(); + adjustSize(); + update(); +} + +/* GHintFrame */ + +GToolTipFrame::GToolTipFrame(QFrame *parent, QPoint pt, const QString &text): + m_parent(parent), m_label(new QLabel()), m_lastShowText(""), + m_nMarginWidth(5 * 2)//, m_nWidth(160), m_nHeight(18) +{ + // 去掉Frame的外边框 + setFrameShape(Panel); + // 去掉最小化,关闭按钮 + setWindowFlags(Qt::ToolTip); + + m_label->setParent(this); + // Label内自动换行 + m_label->setWordWrap(true); + m_label->setAlignment(Qt::AlignTop); + + // 设置背景Frame和Label的背景色 + QPalette palete = palette(); + palete.setColor(QPalette::Window, QColor(255, 255, 225)); + + setAutoFillBackground(true); + setPalette(palete); + + m_label->setAutoFillBackground(true); + m_label->setPalette(palete); + resize(m_label->size().width() + m_nMarginWidth, m_label->size().height() + m_nMarginWidth); + m_label->move(m_nMarginWidth / 2, m_nMarginWidth / 2); + + if ((pt.x() > 0 ) && 0 != (pt.y())) + { + move(pt); + setHintText(text); + } +} + +GToolTipFrame::~GToolTipFrame() +{ + freeAndNil(m_label); +} + +void GToolTipFrame::hide() +{ + QFrame::hide(); +// m_lastShowText = ""; +} + +void GToolTipFrame::show() +{ + QFrame::show(); +} + +void GToolTipFrame::move(int x, int y) +{ + move(QPoint(x, y)); +} + +void GToolTipFrame::move(const QPoint &point) +{ +// QPoint parentPt = m_parent->mapFromGlobal(point); + int nXOffset = 35; + int nYOffset = 45; + QPoint pOffset(nXOffset, nYOffset); + QFrame::setParent(m_parent); + QFrame::move(point + pOffset); +} + +void GToolTipFrame::setHintText(const QString &text) +{ + if (text.isEmpty()) + { + hide(); + return; + } +// if (m_lastShowText.isEmpty()) +// { +// m_lastShowText = text; +// } +// else if (m_lastShowText == text) +// { + m_label->setText(text); + m_label->adjustSize(); + resize(m_label->size().width() + m_nMarginWidth, m_label->size().height() + m_nMarginWidth); + show(); +// m_lastShowText = text; +// } +// else +// { +// m_lastShowText = ""; +// } +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDCommentFrameEx.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDCommentFrameEx.cpp new file mode 100644 index 00000000..47b3c47a --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDCommentFrameEx.cpp @@ -0,0 +1,1428 @@ +#include +#include "GLDTextEdit.h" +#include "GLDAbstractItemView.h" +#include "GLDAbstractItemModel.h" +#include "GLDCommentFrameEx.h" + +static const int c_ncSpace = 20; +static const int c_nMinWidth = 178; +static const int c_nMinHeight = 95; +static const int c_nMinAnchorWidth = 4; +static const QMargins c_margEdit = QMargins(7, 2, 13, 7); +static const QPoint c_ptDefaultAnchor = QPoint(0, 60); + +GCustomCommentFrameEx::GCustomCommentFrameEx(QWidget *parent, QPoint pt) : + QWidget(parent) + , m_dragPoint(0, 0) + , m_initWinSize(c_nMinWidth + (4 * c_ncSpace), c_nMinHeight + (2 * c_ncSpace)) + , m_anchor(c_ptDefaultAnchor) + , m_ptAnchorFirst(0, 0) + , m_ptAnchorSecond(0, 0) + , m_rcPos(m_anchor.x() + c_ncSpace, c_ncSpace, c_nMinWidth, c_nMinHeight) + , m_mouseCurrentPos(GCustomCommentFrameEx::EMousePosNULL) + , m_bShowStretch(false) + , m_clBg(255, 255, 225) + , m_clText(0, 0, 0) + , m_clBorder(130, 130, 127) + , m_mapbl(":/icons/bottom-left.png") + , m_mapbr(":/icons/bottom-right.png") + , m_mapbc(":/icons/bottom-conter.png") + , m_maprt(":/icons/right-top.png") + , m_maprc(":/icons/right-conter.png") + , m_bWndState(false) + , m_bIsMenuShow(false) +{ + setUpUI(); + initPlaintEdit(); + + QPoint ptmove = QPoint(pt.x(), pt.y() - m_anchor.y()); + + if (!setPosByParent(QRect(ptmove.x(), ptmove.y(), m_initWinSize.width(), m_initWinSize.height()))) + { + resize(m_initWinSize); + QWidget::move(ptmove); + setWindowMask(true); + } + + setMouseTracking(true); +} + +GCustomCommentFrameEx::~GCustomCommentFrameEx() +{ +} + +void GCustomCommentFrameEx::setUpUI() +{ + if (m_rcPos.top() < 0) + { + m_rcPos.moveTo(m_rcPos.x(), c_ncSpace); + } + + setAttribute(Qt::WA_TranslucentBackground); + updatePaintPolygonDate(m_anchor, m_rcPos); +} + +QRect GCustomCommentFrameEx::getMaxRect(const QPoint &pt, const QRect &rc) const +{ + QRect rcResult(rc); + + if (rcResult.left() > pt.x()) + { + rcResult.setLeft(pt.x()); + } + + if (rcResult.right() < pt.x()) + { + rcResult.setRight(pt.x()); + } + + if (rcResult.top() > pt.y()) + { + rcResult.setTop(pt.y()); + } + + if (rcResult.bottom() < pt.y()) + { + rcResult.setBottom(pt.y()); + } + + return rcResult; +} + +void GCustomCommentFrameEx::updateWindow() +{ + QRect rcPos(m_rcPos.left() - c_ncSpace + , m_rcPos.top() - c_ncSpace + , m_rcPos.width() + (2 * c_ncSpace) + , m_rcPos.height() + (2 * c_ncSpace)); + rcPos = getMaxRect(m_anchor, rcPos); + + m_anchor -= rcPos.topLeft(); + m_rcPos.moveTo(m_rcPos.left() - rcPos.left(), m_rcPos.top() - rcPos.top()); + updatePaintPolygonDate(m_anchor, m_rcPos); + + if ((rcPos.topLeft().x() == 0) + && (rcPos.topLeft().y() == 0) + && (rcPos.width() == width()) + && (rcPos.height() == height())) + { + updateEditPos(); + update(); + } + else + { + QWidget::move(pos() + rcPos.topLeft()); + resize(rcPos.width(), rcPos.height()); + } +} + +void GCustomCommentFrameEx::drawImageOnWin(QPainter *painter) +{ + painter->drawRect(m_rcPos.left() + , m_rcPos.top() + , m_rcPos.width() + 10 + , m_rcPos.height() + 10); + + if (!m_rcPos.contains(m_anchor)) + { + QPolygon polygonLine(m_verFreamPoint); + painter->drawPolygon(polygonLine); + } + + drawFreamRect(painter, false); +} + +void GCustomCommentFrameEx::drawFreamRect(QPainter *painter, bool bPainterEvent) +{ + const int c_smallRectWidth = 7; + const int c_lineLeng = 4; + const int c_nOff = c_smallRectWidth / 2; + + QPoint ptLT(m_rcPos.left() - c_ncSpace, m_rcPos.top() - c_ncSpace); + QPoint ptRB(m_rcPos.right() + c_ncSpace, m_rcPos.bottom() + c_ncSpace); + + if (!bPainterEvent) + { + painter->drawRect(m_rcPos.left() - c_ncSpace + , m_rcPos.top() - c_ncSpace + , m_rcPos.width() + (2 * c_ncSpace) + , m_rcPos.height() + (2 * c_ncSpace)); + } + else + { + m_rectLT.setRect(ptLT.rx() + , ptLT.ry() + , c_smallRectWidth + , c_smallRectWidth); + m_rectRT.setRect(ptRB.rx() - c_smallRectWidth + , ptLT.ry() + , c_smallRectWidth + , c_smallRectWidth); + m_rectMT.setRect(ptLT.rx() + (((ptRB.rx() - ptLT.rx()) / 2) - ((c_smallRectWidth + 1) / 2)) + , ptLT.ry() + , c_smallRectWidth + , c_smallRectWidth); + m_rectMB.setRect(ptLT.rx() + (((ptRB.rx() - ptLT.rx()) / 2) - ((c_smallRectWidth + 1) / 2)) + , ptRB.ry() - c_smallRectWidth + , c_smallRectWidth + , c_smallRectWidth); + m_rectRB.setRect(ptRB.rx() - c_smallRectWidth + , ptRB.ry() - c_smallRectWidth + , c_smallRectWidth + , c_smallRectWidth); + m_rectLB.setRect(ptLT.rx() + , ptRB.ry() - c_smallRectWidth + , c_smallRectWidth + , c_smallRectWidth); + m_rectML.setRect(ptLT.rx() + , ptLT.ry() + (((ptRB.ry() - ptLT.ry()) / 2) - ((c_smallRectWidth + 1) / 2)) + , c_smallRectWidth + , c_smallRectWidth); + m_rectMR.setRect(ptRB.rx() - c_smallRectWidth + , ptLT.ry() + (((ptRB.ry() - ptLT.ry()) / 2) - ((c_smallRectWidth + 1) / 2)) + , c_smallRectWidth + , c_smallRectWidth); + + painter->drawRect(m_rectLT); + painter->drawRect(m_rectRT); + painter->drawRect(m_rectMT); + painter->drawRect(m_rectMB); + painter->drawRect(m_rectRB); + painter->drawRect(m_rectLB); + painter->drawRect(m_rectML); + painter->drawRect(m_rectMR); + + int n_index = 0; + + for (int i = ptLT.rx() + c_smallRectWidth + c_lineLeng; i < m_rectMT.left() - c_lineLeng; i += c_lineLeng) + { + ++n_index; + + if (0 == n_index % 2) + { + painter->drawLine(QPoint(i, ptLT.ry() + c_nOff), QPoint(i + c_lineLeng - 1, ptLT.ry() + c_nOff)); + painter->drawLine(QPoint(i, ptRB.ry() - c_nOff), QPoint(i + c_lineLeng - 1, ptRB.ry() - c_nOff)); + } + } + + n_index = 0; + + for (int i = m_rectMT.left() + c_smallRectWidth + c_lineLeng; i < m_rectRB.left() - c_lineLeng; i += c_lineLeng) + { + ++n_index; + + if (0 == n_index % 2) + { + painter->drawLine(QPoint(i, ptLT.ry() + c_nOff), QPoint(i + c_lineLeng - 1, ptLT.ry() + c_nOff)); + painter->drawLine(QPoint(i, ptRB.ry() - c_nOff), QPoint(i + c_lineLeng - 1, ptRB.ry() - c_nOff)); + } + } + + n_index = 0; + + for (int i = ptLT.ry() + c_smallRectWidth + c_lineLeng; i < m_rectML.top() - c_lineLeng; i += c_lineLeng) + { + ++n_index; + + if (0 == n_index % 2) + { + painter->drawLine(QPoint(ptLT.rx() + c_nOff, i), QPoint(ptLT.rx() + c_nOff, i + c_lineLeng - 1)); + painter->drawLine(QPoint(ptRB.rx() - c_nOff, i), QPoint(ptRB.rx() - c_nOff, i + c_lineLeng - 1)); + } + } + + n_index = 0; + + for (int i = m_rectML.top() + c_smallRectWidth + c_lineLeng; i < m_rectRB.top() - c_lineLeng; i += c_lineLeng) + { + ++n_index; + + if (0 == n_index % 2) + { + painter->drawLine(QPoint(ptLT.rx() + c_nOff, i), QPoint(ptLT.rx() + c_nOff, i + c_lineLeng - 1)); + painter->drawLine(QPoint(ptRB.rx() - c_nOff, i), QPoint(ptRB.rx() - c_nOff, i + c_lineLeng - 1)); + } + } + } +} + +void GCustomCommentFrameEx::paintEvent(QPaintEvent *e) +{ + Q_UNUSED(e); + QPainter painterMem(this); + + painterMem.drawPixmap(m_rcPos.left(), m_rcPos.bottom() + 1, m_mapbl); + painterMem.drawPixmap(m_rcPos.right() + 2 - 11, m_rcPos.bottom() + 2 - 11, m_mapbr); + painterMem.drawPixmap(m_rcPos.left() + m_mapbl.width() + , m_rcPos.bottom() + 1 + , m_rcPos.width() - m_mapbl.width() - 10 + , m_mapbc.height() + , m_mapbc); + painterMem.drawPixmap(m_rcPos.right() + 1, m_rcPos.top(), m_maprt); + painterMem.drawPixmap(m_rcPos.right() + 1 + , m_rcPos.top() + m_maprt.height() + , m_maprc.width() + , m_rcPos.height() - m_maprt.height() - 10 + , m_maprc); + + painterMem.setPen(QPen(m_clBorder)); + painterMem.setBrush(QBrush(GColor(255, 255, 225))); + + if (m_rcPos.contains(m_anchor)) + { + painterMem.drawRect(m_rcPos.left() + , m_rcPos.top() + , m_rcPos.width() - 1 + , m_rcPos.height() - 1);// 此处的1像素是因为通过m_verFreamPoint画出的矩形, + // 与直接通过m_rcPos画出来的矩形差一个像素需要调整一下 + } + else + { + QPolygon polygonLine(m_verFreamPoint); + painterMem.drawPolygon(polygonLine); + painterMem.setPen(QPen(m_clBorder)); + painterMem.setRenderHint(QPainter::Antialiasing, true); + painterMem.drawLine(m_anchor, m_ptAnchorFirst); + painterMem.drawLine(m_anchor, m_ptAnchorSecond); + painterMem.setRenderHint(QPainter::Antialiasing, false); + } + + if (m_bShowStretch) + { + painterMem.setPen(QPen(GColor(0, 0, 0))); + painterMem.setBrush(QBrush(GColor(255, 255, 255))); + drawFreamRect(&painterMem); + } +} + +void GCustomCommentFrameEx::resizeEvent(QResizeEvent *e) +{ + QWidget::resizeEvent(e); + updateEditPos(); +} + +void GCustomCommentFrameEx::mousePressEvent(QMouseEvent *e) +{ + QWidget::mousePressEvent(e); + + if (e->button() == Qt::LeftButton) + { + if (!m_bWndState) + { + setWindowMask(false); + update(); + m_bWndState = true; + } + + m_dragPoint = e->globalPos(); + e->accept(); + + EMousePos posmouse = getMousePos(e->pos()); + + if (posmouse == EMousePosEdit) + { + m_plainTextEdit->activateWindow(); + } + } +} + +void GCustomCommentFrameEx::mouseReleaseEvent(QMouseEvent *e) +{ + Q_UNUSED(e); + + if (m_bWndState) + { + setWindowMask(true); + update(); + m_bWndState = false; + } +} + +void GCustomCommentFrameEx::mouseMoveEvent(QMouseEvent *e) +{ + if (e->buttons() != Qt::LeftButton) + { + m_mouseCurrentPos = getMousePos(e->pos()); + } + + processMousePos(e, m_mouseCurrentPos); + + QWidget::mouseMoveEvent(e); +} + +void GCustomCommentFrameEx::enterEvent(QEvent *e) +{ + QWidget::enterEvent(e); + m_bShowStretch = true; + update(); +} + +void GCustomCommentFrameEx::leaveEvent(QEvent *e) +{ + QWidget::leaveEvent(e); + m_bShowStretch = false; + update(); +} + +bool GCustomCommentFrameEx::eventFilter(QObject *watched, QEvent *event) +{ + if (watched == m_plainTextEdit->viewport()) + { + if (event->type() == QEvent::MouseButtonPress) + { + QMouseEvent *pmouseEvent = (QMouseEvent *)event; + + if (pmouseEvent->button() == Qt::RightButton) + { + m_bIsMenuShow = true; + } + } + } + + if (watched == m_plainTextEdit) + { + if (QEvent::FocusOut == event->type()) + { + if (!m_bIsMenuShow) + { + hide(); + } + + m_bIsMenuShow = false; + } + } + + return false ; +} + +GCustomCommentFrameEx::EAnchorPos GCustomCommentFrameEx::getAnchorPos(const QPoint &pt, const QRect &rc) const +{ + if (pt.x() <= rc.left()) + { + if ((rc.left() - pt.x()) >= (rc.top() - pt.y()) && (pt.y() <= rc.top() + (rc.height() / 2))) + { + return ELeftUp; + } + else if ((pt.y() > rc.top() + (rc.height() / 2)) && (rc.left() - pt.x()) > (pt.y() - rc.bottom())) + { + return ELeftDown; + } + } + + if (pt.y() <= rc.top()) + { + if ((rc.left() - pt.x()) < (rc.top() - pt.y()) && pt.x() <= rc.left() + (rc.width() / 2)) + { + return ETopLeft; + } + else if (pt.x() > rc.left() + (rc.width() / 2) && (pt.x() - rc.right()) <= (rc.top() - pt.y())) + { + return ETopRight; + } + } + + if (pt.x() >= rc.right()) + { + if ((pt.x() - rc.right()) > (rc.top() - pt.y()) && (pt.y() <= rc.top() + (rc.height() / 2))) + { + return ERightUp; + } + else if ((pt.y() > rc.top() + (rc.height() / 2)) && (pt.x() - rc.right()) >= (pt.y() - rc.bottom())) + { + return ERightDown; + } + } + + if (pt.y() >= rc.bottom()) + { + if ((rc.left() - pt.x()) <= (pt.y() - rc.bottom()) && pt.x() <= rc.left() + (rc.width() / 2)) + { + return EBottomLeft; + } + else if (pt.x() > rc.left() + (rc.width() / 2) && (pt.x() - rc.right()) < (pt.y() - rc.bottom())) + { + return EBottomRight; + } + } + + return ECenter; +} + +GCustomCommentFrameEx::EAnchorPos GCustomCommentFrameEx::getTriangleByAnchorAndRect(const QPoint &ptAnchor + , const QRect &rcPos + , QPoint &ptFirst + , QPoint &ptSecond) const +{ + EAnchorPos pos = getAnchorPos(ptAnchor, rcPos); + const int c_nSpaceSize = 10; + const int c_nWidth = 20; + + switch (pos) + { + case ELeftUp: + { + ptFirst.setX(rcPos.left()); + ptFirst.setY(rcPos.top() + c_nSpaceSize); + ptSecond.setX(rcPos.left()); + ptSecond.setY(rcPos.top() + (c_nSpaceSize + c_nWidth)); + break; + } + + case ELeftDown: + { + ptFirst.setX(rcPos.left()); + ptFirst.setY(rcPos.bottom() - (c_nSpaceSize + c_nWidth)); + ptSecond.setX(rcPos.left()); + ptSecond.setY(rcPos.bottom() - c_nSpaceSize); + break; + } + + case ETopLeft: + { + ptFirst.setX(rcPos.left() + c_nSpaceSize); + ptFirst.setY(rcPos.top()); + ptSecond.setX(rcPos.left() + (c_nSpaceSize + c_nWidth)); + ptSecond.setY(rcPos.top()); + break; + } + + case ETopRight: + { + ptFirst.setX(rcPos.right() - (c_nSpaceSize + c_nWidth)); + ptFirst.setY(rcPos.top()); + ptSecond.setX(rcPos.right() - c_nSpaceSize); + ptSecond.setY(rcPos.top()); + break; + } + + case ERightUp: + { + ptFirst.setX(rcPos.right()); + ptFirst.setY(rcPos.top() + c_nSpaceSize); + ptSecond.setX(rcPos.right()); + ptSecond.setY(rcPos.top() + (c_nSpaceSize + c_nWidth)); + break; + } + + case ERightDown: + { + ptFirst.setX(rcPos.right()); + ptFirst.setY(rcPos.bottom() - (c_nSpaceSize + c_nWidth)); + ptSecond.setX(rcPos.right()); + ptSecond.setY(rcPos.bottom() - c_nSpaceSize); + break; + } + + case EBottomLeft: + { + ptFirst.setX(rcPos.left() + c_nSpaceSize); + ptFirst.setY(rcPos.bottom()); + ptSecond.setX(rcPos.left() + (c_nSpaceSize + c_nWidth)); + ptSecond.setY(rcPos.bottom()); + break; + } + + case EBottomRight: + { + ptFirst.setX(rcPos.right() - (c_nSpaceSize + c_nWidth)); + ptFirst.setY(rcPos.bottom()); + ptSecond.setX(rcPos.right() - c_nSpaceSize); + ptSecond.setY(rcPos.bottom()); + break; + } + + default: + { + ptFirst.setX(0); + ptFirst.setY(0); + ptSecond.setX(0); + ptSecond.setY(0); + break; + } + } + + return pos; +} + +void GCustomCommentFrameEx::updatePaintPolygonDate(const QPoint &ptAnchor, const QRect &rcPos) +{ + EAnchorPos pos = getTriangleByAnchorAndRect(ptAnchor, rcPos, m_ptAnchorFirst, m_ptAnchorSecond); + m_verFreamPoint.clear(); + + switch (pos) + { + case ELeftUp: + case ELeftDown: + { + m_verFreamPoint.append(ptAnchor); + m_verFreamPoint.append(m_ptAnchorFirst); + m_verFreamPoint.append(rcPos.topLeft()); + m_verFreamPoint.append(rcPos.topRight()); + m_verFreamPoint.append(rcPos.bottomRight()); + m_verFreamPoint.append(rcPos.bottomLeft()); + m_verFreamPoint.append(m_ptAnchorSecond); + break; + } + + case ETopLeft: + case ETopRight: + { + m_verFreamPoint.append(ptAnchor); + m_verFreamPoint.append(m_ptAnchorSecond); + m_verFreamPoint.append(rcPos.topRight()); + m_verFreamPoint.append(rcPos.bottomRight()); + m_verFreamPoint.append(rcPos.bottomLeft()); + m_verFreamPoint.append(rcPos.topLeft()); + m_verFreamPoint.append(m_ptAnchorFirst); + break; + } + + case ERightUp: + case ERightDown: + { + m_verFreamPoint.append(ptAnchor); + m_verFreamPoint.append(m_ptAnchorSecond); + m_verFreamPoint.append(rcPos.bottomRight()); + m_verFreamPoint.append(rcPos.bottomLeft()); + m_verFreamPoint.append(rcPos.topLeft()); + m_verFreamPoint.append(rcPos.topRight()); + m_verFreamPoint.append(m_ptAnchorFirst); + break; + } + + case EBottomLeft: + case EBottomRight: + { + m_verFreamPoint.append(ptAnchor); + m_verFreamPoint.append(m_ptAnchorFirst); + m_verFreamPoint.append(rcPos.bottomLeft()); + m_verFreamPoint.append(rcPos.topLeft()); + m_verFreamPoint.append(rcPos.topRight()); + m_verFreamPoint.append(rcPos.bottomRight()); + m_verFreamPoint.append(m_ptAnchorSecond); + break; + } + + default: + { + m_ptAnchorFirst.setX(0); + m_ptAnchorFirst.setY(0); + m_ptAnchorSecond.setX(0); + m_ptAnchorSecond.setY(0); + break; + } + } +} + +GCustomCommentFrameEx::EMousePos GCustomCommentFrameEx::getMousePos(const QPoint &pos) const +{ + if (m_rcPos.contains(pos)) + { + return EMousePosEdit; + } + else if (m_rectLT.contains(pos)) + { + return EStretchLeftUp; + } + else if (m_rectRT.contains(pos)) + { + return EStretchRightUp; + } + else if (m_rectMT.contains(pos)) + { + return EStretchUp; + } + else if (m_rectMB.contains(pos)) + { + return EStretchDown; + } + else if (m_rectRB.contains(pos)) + { + return EStretchRightDown; + } + else if (m_rectLB.contains(pos)) + { + return EStretchLeftDown; + } + else if (m_rectML.contains(pos)) + { + return EStretchLeft; + } + else if (m_rectMR.contains(pos)) + { + return EStretchRight; + } + else if (QRect(m_rcPos.left() - c_ncSpace + , m_rcPos.top() - c_ncSpace + , m_rcPos.width() + (2 * c_ncSpace) + , m_rcPos.height() + (2 * c_ncSpace)).contains(pos)) + { + return EMoveWindPos; + } + + return EMousePosNULL; +} + +void GCustomCommentFrameEx::processMousePos(QMouseEvent *e, GCustomCommentFrameEx::EMousePos pos) +{ + switch (pos) + { + case EMoveWindPos: + { + processMoveWindPos(e); + break; + } + + case EStretchLeft: + { + processStretchLeft(e); + break; + } + + case EStretchRight: + { + processStretchRight(e); + break; + } + + case EStretchUp: + { + processStretchUp(e); + break; + } + + case EStretchDown: + { + processStretchDown(e); + break; + } + + case EStretchLeftUp: + { + processStretchLeftUp(e); + break; + } + + case EStretchLeftDown: + { + processStretchLeftDown(e); + break; + } + + case EStretchRightUp: + { + processStretchRightUp(e); + break; + } + + case EStretchRightDown: + { + processStretchRightDown(e); + break; + } + + case EMousePosEdit: + default: + { + setCursor(Qt::ArrowCursor); + break; + } + } +} + +void GCustomCommentFrameEx::processMoveWindPos(QMouseEvent *e) +{ + setCursor(Qt::SizeAllCursor); + + if (e->buttons() == Qt::LeftButton) + { + int nwidth = e->globalPos().rx() - m_dragPoint.rx(); + int nheight = e->globalPos().ry() - m_dragPoint.ry(); + m_dragPoint = e->globalPos(); + m_rcPos.moveTo(m_rcPos.x() + nwidth, m_rcPos.y() + nheight); + updateWindow(); + } +} + +void GCustomCommentFrameEx::processStretchLeft(QMouseEvent *e) +{ + setCursor(Qt::SizeHorCursor); + + if (e->buttons() == Qt::LeftButton) + { + int nwidth = e->globalPos().rx() - m_dragPoint.rx(); + int nheight = 0; + m_dragPoint = e->globalPos(); + + bool bMinsize = false; + if (m_rcPos.width() - nwidth <= c_nMinWidth) + { + nwidth = m_rcPos.width() - c_nMinWidth; + bMinsize = true; + } + + m_rcPos.moveTo(m_rcPos.left() + nwidth, m_rcPos.top() + nheight); + m_rcPos.setRight(m_rcPos.right() - nwidth); + + updateWindow(); + if (bMinsize == true) + { + m_dragPoint.setX(mapToGlobal(QPoint(m_rcPos.left() - c_ncSpace, 0)).x()); + } + } +} + +void GCustomCommentFrameEx::processStretchRight(QMouseEvent *e) +{ + setCursor(Qt::SizeHorCursor); + + if (e->buttons() == Qt::LeftButton) + { + int nwidth = e->globalPos().rx() - m_dragPoint.rx(); + m_dragPoint = e->globalPos(); + + if (m_rcPos.width() + nwidth <= c_nMinWidth) + { + nwidth = c_nMinWidth - m_rcPos.width(); + m_dragPoint.setX(mapToGlobal(QPoint(m_rcPos.right() + nwidth + c_ncSpace, 0)).x()); + } + + m_rcPos.setRight(m_rcPos.right() + nwidth); + updateWindow(); + } +} + +void GCustomCommentFrameEx::processStretchUp(QMouseEvent *e) +{ + setCursor(Qt::SizeVerCursor); + + if (e->buttons() == Qt::LeftButton) + { + int nheight = e->globalPos().ry() - m_dragPoint.ry(); + m_dragPoint = e->globalPos(); + + bool bMinsize = false; + if (m_rcPos.height() - nheight <= c_nMinHeight) + { + nheight = m_rcPos.height() - c_nMinHeight; + bMinsize = true; + } + + m_rcPos.moveTo(m_rcPos.left(), m_rcPos.top() + nheight); + m_rcPos.setBottom(m_rcPos.bottom() - nheight); + + updateWindow(); + + if (bMinsize) + { + m_dragPoint.setY(mapToGlobal(QPoint(0, m_rcPos.top() - c_ncSpace)).y()); + } + } +} + +void GCustomCommentFrameEx::processStretchDown(QMouseEvent *e) +{ + setCursor(Qt::SizeVerCursor); + + if (e->buttons() == Qt::LeftButton) + { + int nheight = e->globalPos().ry() - m_dragPoint.ry(); + m_dragPoint = e->globalPos(); + + if (m_rcPos.height() + nheight <= c_nMinHeight) + { + nheight = c_nMinHeight - m_rcPos.height(); + m_dragPoint.setY(mapToGlobal(QPoint(0, m_rcPos.bottom() + nheight + c_ncSpace)).y()); + } + + m_rcPos.setBottom(m_rcPos.bottom() + nheight); + updateWindow(); + } +} + +void GCustomCommentFrameEx::processStretchLeftUp(QMouseEvent *e) +{ + setCursor(Qt::SizeFDiagCursor); + + if (e->buttons() == Qt::LeftButton) + { + int nwidth = e->globalPos().rx() - m_dragPoint.rx(); + int nheight = e->globalPos().ry() - m_dragPoint.ry(); + m_dragPoint = e->globalPos(); + + bool bminHeight = false; + if (m_rcPos.height() - nheight <= c_nMinHeight) + { + nheight = m_rcPos.height() - c_nMinHeight; + bminHeight = true; + } + + bool bminWidth = false; + if (m_rcPos.width() - nwidth <= c_nMinWidth) + { + nwidth = m_rcPos.width() - c_nMinWidth; + bminWidth = true; + } + + m_rcPos.moveTo(m_rcPos.left() + nwidth, m_rcPos.top() + nheight); + m_rcPos.setRight(m_rcPos.right() - nwidth); + m_rcPos.setBottom(m_rcPos.bottom() - nheight); + updateWindow(); + if (bminWidth) + { + m_dragPoint.setX(mapToGlobal(QPoint(m_rcPos.left() - c_ncSpace, 0)).x()); + } + + if (bminHeight) + { + m_dragPoint.setY(mapToGlobal(QPoint(0, m_rcPos.top() - c_ncSpace)).y()); + } + } +} + +void GCustomCommentFrameEx::processStretchLeftDown(QMouseEvent *e) +{ + setCursor(Qt::SizeBDiagCursor); + + if (e->buttons() == Qt::LeftButton) + { + int nwidth = e->globalPos().rx() - m_dragPoint.rx(); + int nheight = e->globalPos().ry() - m_dragPoint.ry(); + m_dragPoint = e->globalPos(); + + bool bminWidth = false; + if (m_rcPos.width() - nwidth <= c_nMinWidth) + { + nwidth = m_rcPos.width() - c_nMinWidth; + bminWidth = true; + } + + bool bminHeight = false; + if (m_rcPos.height() + nheight <= c_nMinHeight) + { + nheight = c_nMinHeight - m_rcPos.height(); + bminHeight = true; + } + + m_rcPos.moveTo(m_rcPos.left() + nwidth, m_rcPos.top()); + m_rcPos.setRight(m_rcPos.right() - nwidth); + m_rcPos.setBottom(m_rcPos.bottom() + nheight); + updateWindow(); + if (bminWidth) + { + m_dragPoint.setX(mapToGlobal(QPoint(m_rcPos.left() - c_ncSpace, 0)).x()); + } + + if (bminHeight) + { + m_dragPoint.setY(mapToGlobal(QPoint(0, m_rcPos.bottom() + c_ncSpace)).y()); + } + } +} + +void GCustomCommentFrameEx::processStretchRightUp(QMouseEvent *e) +{ + setCursor(Qt::SizeBDiagCursor); + + if (e->buttons() == Qt::LeftButton) + { + int nwidth = e->globalPos().rx() - m_dragPoint.rx(); + int nheight = e->globalPos().ry() - m_dragPoint.ry(); + m_dragPoint = e->globalPos(); + + bool bminHeight = false; + if (m_rcPos.height() - nheight <= c_nMinHeight) + { + nheight = m_rcPos.height() - c_nMinHeight; + bminHeight = true; + } + + bool bminWidth = false; + if (m_rcPos.width() + nwidth <= c_nMinWidth) + { + nwidth = c_nMinWidth - m_rcPos.width(); + bminWidth = true; + } + + m_rcPos.moveTo(m_rcPos.left(), m_rcPos.top() + nheight); + m_rcPos.setRight(m_rcPos.right() + nwidth); + m_rcPos.setBottom(m_rcPos.bottom() - nheight); + updateWindow(); + if (bminWidth) + { + m_dragPoint.setX(mapToGlobal(QPoint(m_rcPos.right() + c_ncSpace, 0)).x()); + } + + if (bminHeight) + { + m_dragPoint.setY(mapToGlobal(QPoint(0, m_rcPos.top() - c_ncSpace)).y()); + } + } +} + +void GCustomCommentFrameEx::processStretchRightDown(QMouseEvent *e) +{ + setCursor(Qt::SizeFDiagCursor); + + if (e->buttons() == Qt::LeftButton) + { + int nwidth = e->globalPos().rx() - m_dragPoint.rx(); + int nheight = e->globalPos().ry() - m_dragPoint.ry(); + m_dragPoint = e->globalPos(); + + bool bminWidth = false; + if (m_rcPos.width() + nwidth <= c_nMinWidth) + { + nwidth = c_nMinWidth - m_rcPos.width(); + bminWidth = true; + } + + bool bminHeight = false; + if (m_rcPos.height() + nheight <= c_nMinHeight) + { + nheight = c_nMinHeight - m_rcPos.height(); + bminHeight = true; + } + + m_rcPos.setRight(m_rcPos.right() + nwidth); + m_rcPos.setBottom(m_rcPos.bottom() + nheight); + updateWindow(); + if (bminWidth) + { + m_dragPoint.setX(mapToGlobal(QPoint(m_rcPos.right() + c_ncSpace, 0)).x()); + } + + if (bminHeight) + { + m_dragPoint.setY(mapToGlobal(QPoint(0, m_rcPos.bottom() + c_ncSpace)).y()); + } + } +} + +void GCustomCommentFrameEx::setWindowMask(bool birregularWnd) +{ + QBitmap bitMap(width(), height()); + QPainter painter(&bitMap); + painter.setPen(QPen(GColor(255, 255, 255))); + painter.setBrush(QBrush(GColor(255, 255, 255))); + painter.drawRect(0, 0, width(), height()); + painter.setPen(QPen(GColor(0, 0, 0))); + painter.setBrush(QBrush(GColor(0, 0, 0))); + + if (birregularWnd) + { + drawImageOnWin(&painter); + } + + setMask(bitMap); +} + +void GCustomCommentFrameEx::updateEditPos() +{ + m_plainTextEdit->setGeometry(m_rcPos.left() + c_margEdit.left() + , m_rcPos.top() + c_margEdit.top() + , m_rcPos.width() - c_margEdit.right() + , m_rcPos.height() - c_margEdit.bottom()); +} + +/** + * @brief 初始化编辑框的大小 + */ +void GCustomCommentFrameEx::initPlaintEdit() +{ + m_plainTextEdit = new GLDPlainTextEdit(this); + m_plainTextEdit->setFrameShape(QFrame::Panel); + m_plainTextEdit->setLineWidth(1); + m_plainTextEdit->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_plainTextEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_plainTextEdit->setWordWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); + updateEditPos(); + // 设置背景Frame和Label的背景色 + QPalette palet = palette(); + palet.setColor(QPalette::Window, m_clBg); + palet.setColor(QPalette::Disabled, QPalette::Text, GColor(m_clText)); + palet.setColor(QPalette::Disabled, QPalette::WindowText, GColor(m_clText)); + m_plainTextEdit->setAutoFillBackground(true); + m_plainTextEdit->setCenterOnScroll(true); + m_plainTextEdit->setPalette(palet); + m_plainTextEdit->viewport()->setBackgroundRole(QPalette::Window); + m_plainTextEdit->setStyleSheet("border-style:none;"); + m_plainTextEdit->ensureCursorVisible(); + m_plainTextEdit->setFocus(); + m_plainTextEdit->moveCursor(QTextCursor::End); + m_plainTextEdit->setReadOnly(true); + setFocusPolicy(Qt::WheelFocus); + setFocusProxy(m_plainTextEdit); + connect(m_plainTextEdit, SIGNAL(textChanged(GString)), this, SIGNAL(textChanged(GString))); +} + +void GCustomCommentFrameEx::setCommentText(const GString &str) +{ + m_plainTextEdit->setPlainText(str); + + if (isReadOnly()) + { + m_plainTextEdit->moveCursor(QTextCursor::Start); + } + else + { + m_plainTextEdit->moveCursor(QTextCursor::End); + } +} + +GString GCustomCommentFrameEx::commentText() +{ + return m_plainTextEdit->toPlainText(); +} + +void GCustomCommentFrameEx::hide() +{ + if (!isVisible()) + { + return; + } + + m_plainTextEdit->removeEventFilter(this); + m_plainTextEdit->viewport()->removeEventFilter(this); + setWindowMask(false); + + QWidget::hide(); + GlodonAbstractItemView *pParent = dynamic_cast(parentWidget()); + + if (pParent && !isReadOnly()) + { + pParent->model()->setData(m_curIndex, m_plainTextEdit->toPlainText(), gidrCommentRole); + } +} + +void GCustomCommentFrameEx::setFramePosition(QPoint point) +{ + move(point); +} + +void GCustomCommentFrameEx::show(bool bautohiden) +{ + if (true == bautohiden) + { + m_plainTextEdit->installEventFilter(this); + m_plainTextEdit->viewport()->installEventFilter(this); + } + else + { + m_plainTextEdit->removeEventFilter(this); + m_plainTextEdit->viewport()->removeEventFilter(this); + } + + QWidget::show(); + QApplication::setActiveWindow(this); + m_plainTextEdit->setFocus(); + QTextCursor oTextCursor = m_plainTextEdit->textCursor(); + oTextCursor.movePosition(QTextCursor::End); + m_plainTextEdit->setTextCursor(oTextCursor); +} + +void GCustomCommentFrameEx::move(int x, int y) +{ + move(QPoint(x, y)); +} + +void GCustomCommentFrameEx::move(const QPoint &pt) +{ + m_anchor = c_ptDefaultAnchor; + QPoint ptmove = QPoint(pt.x(), pt.y() - m_anchor.y()); + m_rcPos = QRect(m_anchor.x() + c_ncSpace, c_ncSpace, c_nMinWidth, c_nMinHeight); + + updatePaintPolygonDate(m_anchor, m_rcPos); + + update(); + QWidget::move(ptmove); + resize(m_initWinSize.width(), m_initWinSize.height()); + setWindowMask(true); + setPosByParent(QRect(ptmove.x(), ptmove.y(), m_initWinSize.width(), m_initWinSize.height())); + updateEditPos(); +} + +void GCustomCommentFrameEx::move(const QModelIndex &index, const GlodonAbstractItemView &instView) +{ + GlodonAbstractItemView *pParent = dynamic_cast(parentWidget()); + + if (pParent) + { + move(instView.visualRect(index).topRight() + instView.viewport()->pos()); + m_curIndex = index; + } +} + +bool GCustomCommentFrameEx::isReadOnly() const +{ + return m_plainTextEdit->isReadOnly(); +} + +void GCustomCommentFrameEx::setReadOnly(bool bReadOnly) +{ + m_plainTextEdit->setReadOnly(bReadOnly); +} + +bool GCustomCommentFrameEx::setPosByParent(const QRect &rcPos) +{ + QWidget *pParent = parentWidget(); + + if (NULL == pParent) + { + return false; + } + + if (rotationRight(rcPos)) + { + return true; + } + + if (rotationDown(rcPos)) + { + return true; + } + + if (rotationUp(rcPos)) + { + return true; + } + + if (rotationLeft(rcPos)) + { + return true; + } + + return false; +} + +bool GCustomCommentFrameEx::rotationLeft(const QRect &rcPoswind) +{ + QWidget *pParent = parentWidget(); + int nHeight = 0; + + if (rcPoswind.top() + m_rcPos.height() + c_ncSpace - pParent->height() > 0) + { + nHeight = rcPoswind.top() + m_rcPos.height() + c_ncSpace - pParent->height(); + } + + if (rcPoswind.top() - nHeight + c_ncSpace < 0) + { + nHeight += rcPoswind.top() - nHeight + c_ncSpace; + } + + int nSpace = rcPoswind.left() - m_rcPos.width() - c_ncSpace; + + if (nSpace >= 0 || nSpace + c_ncSpace < c_nMinAnchorWidth) + { + if (nSpace >= 0) + { + int nRight = rcPoswind.left() - m_anchor.x() - c_ncSpace - pParent->width(); + + if (nRight > 0) + { + nSpace = c_ncSpace + nRight; + } + else + { + nSpace = c_ncSpace; + } + } + else + { + return false; + } + } + else + { + nSpace = c_ncSpace + nSpace; + } + + m_rcPos.moveTo(c_ncSpace, c_ncSpace); + m_anchor += QPoint(m_rcPos.width() + c_ncSpace + nSpace, nHeight); + + updatePaintPolygonDate(m_anchor, m_rcPos); + QWidget::move(rcPoswind.left() - m_anchor.x(), rcPoswind.top() - nHeight); + QRect rcPos(m_rcPos.left() - c_ncSpace + , m_rcPos.top() - c_ncSpace + , m_rcPos.width() + (2 * c_ncSpace) + , m_rcPos.height() + (2 * c_ncSpace)); + rcPos = getMaxRect(m_anchor, rcPos); + resize(rcPos.width(), rcPos.height()); + + updateEditPos(); + + return true; +} + +bool GCustomCommentFrameEx::rotationRight(const QRect &rcPoswind) +{ + QWidget *pParent = parentWidget(); + int nHeight = 0; + + if (rcPoswind.top() + m_rcPos.height() + c_ncSpace - pParent->height() > 0) + { + nHeight = rcPoswind.top() + m_rcPos.height() + c_ncSpace - pParent->height(); + } + + if (rcPoswind.top() - nHeight + c_ncSpace < 0) + { + nHeight += rcPoswind.top() - nHeight + c_ncSpace; + } + + int nSpace = pParent->width() - (rcPoswind.left() + m_rcPos.width() + c_ncSpace); + + if (nSpace >= 0 || nSpace + c_ncSpace < c_nMinAnchorWidth) + { + if (nSpace >= 0) + { + if (rcPoswind.left() + m_rcPos.left() < 0) + { + nSpace = 0 - (rcPoswind.left() + m_rcPos.left()); + } + else + { + nSpace = 0; + } + } + else + { + return false; + } + } + + m_anchor.setX(m_anchor.x() - nSpace); + m_anchor.setY(m_anchor.y() + nHeight); + m_rcPos.moveTo(c_ncSpace, c_ncSpace); + updatePaintPolygonDate(m_anchor, m_rcPos); + QWidget::move(rcPoswind.left() + nSpace, rcPoswind.top() - nHeight); + QRect rcPos(m_rcPos.left() - c_ncSpace + , m_rcPos.top() - c_ncSpace + , m_rcPos.width() + (2 * c_ncSpace) + , m_rcPos.height() + (2 * c_ncSpace)); + rcPos = getMaxRect(m_anchor, rcPos); + resize(rcPos.width(), rcPos.height()); + + return true; +} + +bool GCustomCommentFrameEx::rotationUp(const QRect &rcPoswind) +{ + QWidget *pParent = parentWidget(); + int nwidth = 0; + + if (rcPoswind.left() + m_rcPos.width() + c_ncSpace - pParent->width() > 0) + { + nwidth = rcPoswind.left() + m_rcPos.width() + c_ncSpace - pParent->width(); + } + + if (rcPoswind.left() - nwidth + c_ncSpace < 0) + { + nwidth += rcPoswind.left() - nwidth + c_ncSpace; + } + + int nSpace = rcPoswind.top() + m_anchor.y() - m_rcPos.height() - c_ncSpace; + + if (nSpace >= 0 || nSpace + c_ncSpace < c_nMinAnchorWidth) + { + if (nSpace >= 0) + { + int nTop = rcPoswind.top() - rcPoswind.height() + + m_anchor.y() + + c_ncSpace + + m_rcPos.height() + - pParent->height(); + + if (nTop > 0) + { + nSpace = c_ncSpace + nTop; + } + else + { + nSpace = c_ncSpace; + } + } + else + { + return false; + } + } + else + { + nSpace = c_ncSpace + nSpace; + } + + m_rcPos.moveTo(c_ncSpace, c_ncSpace); + int nYpixs = m_anchor.y(); + m_anchor.setX(m_anchor.x() + nwidth); + m_anchor.setY(c_ncSpace + m_rcPos.height() + nSpace); + + updatePaintPolygonDate(m_anchor, m_rcPos); + QWidget::move(rcPoswind.left() - nwidth, rcPoswind.top() - (rcPoswind.height() - nYpixs) + (c_ncSpace - nSpace)); + QRect rcPos(m_rcPos.left() - c_ncSpace + , m_rcPos.top() - c_ncSpace + , m_rcPos.width() + (2 * c_ncSpace) + , m_rcPos.height() + (2 * c_ncSpace)); + rcPos = getMaxRect(m_anchor, rcPos); + resize(rcPos.width() + 1, rcPos.height()); + updateEditPos(); + return true; +} + +bool GCustomCommentFrameEx::rotationDown(const QRect &rcPoswind) +{ + QWidget *pParent = parentWidget(); + int nwidth = 0; + + if (rcPoswind.left() + m_rcPos.width() + c_ncSpace - pParent->width() > 0) + { + nwidth = rcPoswind.left() + m_rcPos.width() + c_ncSpace - pParent->width(); + } + + if (rcPoswind.left() - nwidth + c_ncSpace < 0) + { + nwidth += rcPoswind.left() - nwidth + c_ncSpace; + } + + int nSpace = pParent->height() - (rcPoswind.top() + m_anchor.y() + c_ncSpace + m_rcPos.height()); + + if (nSpace >= 0 || nSpace + c_ncSpace < c_nMinAnchorWidth) + { + if (nSpace >= 0) + { + int nTop = rcPoswind.top() + m_anchor.y() + c_ncSpace; + + if (nTop < 0) + { + nSpace = c_ncSpace - nTop; + } + else + { + nSpace = c_ncSpace; + } + } + else + { + return false; + } + } + else + { + nSpace = c_ncSpace + nSpace; + } + + int nYpixs = m_anchor.y(); + m_anchor.setX(m_anchor.x() + nwidth); + m_anchor.setY(0); + m_rcPos.moveTo(c_ncSpace, nSpace); + + updatePaintPolygonDate(m_anchor, m_rcPos); + QWidget::move(rcPoswind.left() - nwidth, rcPoswind.top() + nYpixs); + QRect rcPos(m_rcPos.left() - c_ncSpace + , m_rcPos.top() - c_ncSpace + , m_rcPos.width() + (2 * c_ncSpace) + , m_rcPos.height() + (2 * c_ncSpace)); + rcPos = getMaxRect(m_anchor, rcPos); + resize(rcPos.width() + 1, rcPos.height()); + updateEditPos(); + return true; +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDCustomButton.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDCustomButton.cpp new file mode 100644 index 00000000..406bad59 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDCustomButton.cpp @@ -0,0 +1,42 @@ +#include "GLDCustomButton.h" +#include + + +GLDCustomButton::GLDCustomButton(QWidget *parent) + : QPushButton(parent) + , m_pixmap("") +{ + +} + +GLDCustomButton::GLDCustomButton(const QString &iconPath, QWidget* parent) + : QPushButton(parent) + , m_pixmap("") +{ + QPixmap btnPixmap; + btnPixmap.load(iconPath); + setPixmap(btnPixmap); +} + +void GLDCustomButton::setPixmap(const QPixmap& pm) +{ + m_pixmap = pm; + update(); +} + +QSize GLDCustomButton::sizeHint() const +{ + if (!m_pixmap.isNull()) + { + return m_pixmap.size(); + } + + return QPushButton::sizeHint(); +} + +void GLDCustomButton::paintEvent(QPaintEvent* e) +{ + Q_UNUSED(e); + QPainter p(this); + p.drawPixmap(0, 0, m_pixmap); +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDCustomCommentFrame.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDCustomCommentFrame.cpp new file mode 100644 index 00000000..53e0c1bc --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDCustomCommentFrame.cpp @@ -0,0 +1,759 @@ +#include "GLDCustomCommentFrame.h" +#include "GLDMathUtils.h" +#include "GLDGlobal.h" +#include "GLDAbstractItemView.h" +#include "GLDAbstractItemModel.h" + +#define CommentFrameOffset 5 +#define CommentFrameArrowInitLineLen 100 + +/*GCustomCommentFrame*/ +GCustomCommentFrame::GCustomCommentFrame(QWidget *parent, QPoint pt) : QFrame(parent, Qt::Widget), + m_nMarginWidth(10), + m_nWidth(160), + m_nHeight(80), + m_state(m_EnNormal), + m_angle(0), + m_isShowCommentPersistent(false) +{ + setAttribute(Qt::WA_WState_Created); + m_parent = parent; + m_topLeft = pt; + m_bottomRight.setX(pt.rx() + CommentFrameArrowInitLineLen); + m_bottomRight.setY(pt.ry()); + m_nDefaultWidth = 160; + m_nDefaultHeight = 80; + m_isShowEllopse = true; + m_starDraw = false; + // 参考Excel中的像素为6,但是6像素的时候存在显示很诡异的情况,因此y方向改为8像素 + m_arrowPoints.append(QPoint(0, 0)); + m_arrowPoints.append(QPoint(6, -4)); + m_arrowPoints.append(QPoint(6, 4)); + + initPlaintEdit(); + + setInitStyle(); + setCommentFrameSize(); + setMouseTracking(true); + connect(m_plainTextEdit, SIGNAL(textChanged(QString)), this, SIGNAL(textChanged(QString))); +} + +GCustomCommentFrame::~GCustomCommentFrame() +{ + freeAndNil(m_plainTextEdit); +} + +void GCustomCommentFrame::setFramePosition(QPoint point) +{ + if (m_topLeft != point) + { + m_topLeft = point; + resetFramePosition(); + } +} + +/** + * @brief 初始化编辑框的大小 + */ +void GCustomCommentFrame::initPlaintEdit() +{ + m_plainTextEdit = new GLDPlainTextEdit(); + m_plainTextEdit->installEventFilter(this); + m_plainTextEdit->viewport()->installEventFilter(this); + m_plainTextEdit->setParent(this); + m_plainTextEdit->setFrameShape(QFrame::Panel); + m_plainTextEdit->setFrameShadow(QFrame::Plain); + m_plainTextEdit->setLineWidth(1); + m_plainTextEdit->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_plainTextEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_plainTextEdit->setWordWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); + m_plainTextEdit->setGeometry(m_bottomRight.rx(), m_bottomRight.ry(), m_nWidth, m_nHeight); + + // 设置背景Frame和Label的背景色 + QPalette palet = palette(); + palet.setColor(QPalette::Window, QColor(255, 255, 225)); + m_plainTextEdit->setAutoFillBackground(true); + m_plainTextEdit->setPalette(palet); + m_plainTextEdit->viewport()->setBackgroundRole(QPalette::Window); + m_plainTextEdit->setMinimumSize(m_nWidth - m_nMarginWidth, m_nHeight - m_nMarginWidth); + resetBordrect(); +} + +/** + * @brief 设置背景Frame和Label的背景色 + */ +void GCustomCommentFrame::setInitStyle() +{ + QPalette palet = palette(); + palet.setColor (QPalette::Background, Qt::color0); + palet.setColor (QPalette::Foreground, Qt::color1); + setAutoFillBackground(false); + setPalette(palet); +} + +/** + * @brief 设置frame的大小,按照父窗口的大小来创建。 + * @param parent + */ +void GCustomCommentFrame::setCommentFrameSize() +{ + setFixedSize(m_parent->width(), m_parent->height()); +} + +void GCustomCommentFrame::setCommentFrameMask() +{ + QPolygon arrowPolygon(m_arrowPoints); + QTransform transform; + transform.rotate(m_angle); + arrowPolygon = transform.map(arrowPolygon); + arrowPolygon.translate(m_topLeft); + + QRegion region(arrowPolygon); + + QVector pointLine; + pointLine.append(QPoint(m_topLeft.x() + 2, m_topLeft.y() - 2)); + pointLine.append(QPoint(m_topLeft.x() - 2, m_topLeft.y() + 2)); + pointLine.append(QPoint(m_bottomRight.x() - 2, m_bottomRight.y() + 2)); + pointLine.append(QPoint(m_bottomRight.x() + 2, m_bottomRight.y() - 2)); + + QPolygon polygonLine(pointLine); + QRegion regionLine(polygonLine); + region += regionLine; + + region += m_borderRect.adjusted(-10, -10, 10, 10); + setMask(region); +} + +/** + * @brief 设置edittext的位置 + */ +void GCustomCommentFrame::setEditTextPos() +{ + m_plainTextEdit->setGeometry(m_borderRect.left(), m_borderRect.top(), m_nWidth, m_nHeight); +} + +/** + * @brief 根据不同的情况绘制界面 + * @param event + */ +void GCustomCommentFrame::paintEvent(QPaintEvent *event) +{ + QPainter painter(this); + + if (m_isShowEllopse) + { + // 2画编辑状态 + repainAdjustRect(&painter); + } + if (m_starDraw) + { + // 3画移动状态 + repainArrowMoving(&painter); + } + repainLineAndArrow(&painter); + QFrame::paintEvent(event); +} + +/** + * @brief 当编辑框小于最小值的时候,里面的内容将看不到,所以要返回移动前的编辑框 + */ +void GCustomCommentFrame::resetBorderRect() +{ + if (Abs(m_borderRect.left() - m_borderRect.right()) < (m_nDefaultWidth - m_nMarginWidth)) + { + resetBordrect(); + } + if (Abs(m_borderRect.top() - m_borderRect.bottom()) < (m_nDefaultHeight - m_nMarginWidth)) + { + resetBordrect(); + } +} + +void GCustomCommentFrame::resetBordrect() +{ + m_borderRect.setCoords(m_plainTextEdit->geometry().left(),m_plainTextEdit->geometry().top(), + m_plainTextEdit->geometry().right(),m_plainTextEdit->geometry().bottom()); +} + +void GCustomCommentFrame::hide() +{ + m_isShowCommentPersistent = false; + if (!isVisible()) + return; + QFrame::hide(); + GlodonAbstractItemView *pParent = dynamic_cast(m_parent->parent()); + if (pParent) + { + pParent->model()->setData(m_curIndex, m_plainTextEdit->toPlainText(), gidrCommentRole); + } +} + +void GCustomCommentFrame::show(bool isPersistent) +{ + m_bottomRight.setX(m_topLeft.rx() + CommentFrameArrowInitLineLen); + m_bottomRight.setY(m_topLeft.ry()); + m_borderRect.moveTo(m_bottomRight); + resetFramePosition(); + + m_isShowCommentPersistent = isPersistent; + QFrame::show(); + QApplication::setActiveWindow(this); + m_plainTextEdit->setFocus(); + QTextCursor oTextCursor = m_plainTextEdit->textCursor(); + oTextCursor.movePosition(QTextCursor::End); + m_plainTextEdit->setTextCursor(oTextCursor); +} + +void GCustomCommentFrame::move(int x, int y) +{ + move(QPoint(x, y)); +} + +void GCustomCommentFrame::move(const QPoint &pt) +{ + QFrame::move(pt); +} + +void GCustomCommentFrame::move(QModelIndex index) +{ + GlodonAbstractItemView *pParent = dynamic_cast(m_parent->parent()); + if (pParent) + { + move(pParent->visualRect(index).topRight() + pParent->viewport()->pos()); + m_curIndex = index; + } +} + +void GCustomCommentFrame::moveTo(QPoint point) +{ + QPoint movePoint = point - m_topLeft; + move(movePoint); +} + +void GCustomCommentFrame::setCommentText(const QString &str) +{ + m_plainTextEdit->setPlainText(str); +} + +QString GCustomCommentFrame::commentText() +{ + return m_plainTextEdit->toPlainText(); +} + +void GCustomCommentFrame::repainArrowMoving(QPainter *painter) +{ + painter->save(); + QColor color = Qt::black; + QPen pen(color, 1, Qt::DotLine); + painter->setPen(pen); + painter->drawRect(m_borderRect); + painter->restore(); +} + +void GCustomCommentFrame::repainLineAndArrow(QPainter *painter) +{ + painter->save(); + painter->setRenderHint(QPainter::Antialiasing); + QColor color = Qt::black; + QPen pen(color, 1, Qt::SolidLine); + painter->setPen(pen); + painter->drawLine(m_topLeft, m_bottomRight); + repainArrow(painter); + painter->restore(); +} + +void GCustomCommentFrame::repainArrow(QPainter *painter) +{ + painter->save(); + QColor color = Qt::black; + QPen pen(color, 1, Qt::SolidLine); + painter->setPen(pen); + + // 先画出三脚,然后根据三角进行旋转。 + // 计算角度 + QBrush brush_(color); + painter->setBrush(brush_); + // 旋转角度 + QPolygon arrowPolygon(m_arrowPoints); + QTransform transform; + transform.rotate(m_angle); + arrowPolygon = transform.map(arrowPolygon); + arrowPolygon.translate(m_topLeft); + painter->setClipRegion(QRegion(arrowPolygon)); +// qDebug() << "repaintArrow;PolygonF" << QRegion(arrowPolygon); + + painter->drawPolygon(arrowPolygon); + painter->restore(); +} + +// 画八个提示鼠标移动的小矩形 +void GCustomCommentFrame::repainAdjustRect(QPainter *painter) +{ + painter->save(); + QPen pen(Qt::gray, 1, Qt::SolidLine); + painter->setPen(pen); + // 防止小框边线与编辑框边线重叠,让出1像素 + int nLeft = m_plainTextEdit->geometry().left() - 1; + int nTop = m_plainTextEdit->geometry().top() - 1; + int nRight = m_plainTextEdit->geometry().right() + 1; + int nBottom = m_plainTextEdit->geometry().bottom() + 1; + painter->drawRect(nLeft - c_AdjustWith, nTop - c_AdjustWith, c_AdjustWith, c_AdjustWith); + painter->drawRect(nLeft - c_AdjustWith, nBottom, c_AdjustWith, c_AdjustWith); + painter->drawRect(nRight, nTop - c_AdjustWith, c_AdjustWith, c_AdjustWith); + painter->drawRect(nRight, nBottom, c_AdjustWith, c_AdjustWith); + painter->drawRect(nLeft - c_AdjustWith, (nTop - c_AdjustWith + nBottom) / 2, c_AdjustWith, c_AdjustWith); // nLeft + painter->drawRect((nLeft - c_AdjustWith + nRight) / 2, nTop - c_AdjustWith, c_AdjustWith, c_AdjustWith); // nTop + painter->drawRect(nRight, (nTop - c_AdjustWith + nBottom) / 2, c_AdjustWith, c_AdjustWith); //nRight + painter->drawRect((nLeft + nRight) / 2, nBottom, c_AdjustWith, c_AdjustWith); // nBottom + painter->restore(); +} + +/** + * TODO:这个可以根据需要抽成通用函数 + * 根据反正切计算角度。 + * @brief myGArrowFrame::cacultAngle + * @return + */ +double GCustomCommentFrame::cacultAngle() +{ + if (Abs(m_topLeft.ry() - m_bottomRight.ry()) < 0.00000001) + { + if (m_topLeft.rx() > m_bottomRight.rx()) + { + return 180.0; + } + else + { + return 0.0; + } + } + + if (Abs(m_topLeft.rx() - m_bottomRight.rx()) < 0.00000001) + { + if (m_topLeft.ry() > m_bottomRight.ry()) + { + return 270.0; + } + else + { + return 90.0; + } + } + // arctan这个获取的是弧度 + double dRadian = arctan((double)(m_topLeft.ry() - m_bottomRight.ry()) + / (double)(m_topLeft.rx() - m_bottomRight.rx())); + // qDebug() << "dRadian is " << dRadian; + // 将弧度转换到角度 + double dAngle = radianToAngle(dRadian); + // qDebug() << "dRadian is " << dAngle + // << "Abs(m_topLeft.rx() - m_bottomRight.rx()) " << Abs(m_topLeft.rx() - m_bottomRight.rx()); + // arctan 的取值范围是[-PI/2, PI/2],所以需要补足 + if (m_bottomRight.rx() - m_topLeft.rx() < 0.00000001) + { + dAngle += 180.0; + } + return dAngle; +} + +void GCustomCommentFrame::mousePressEvent(QMouseEvent *e) +{ + m_mousePos = e->globalPos(); + if (m_borderRect.contains(e->pos())) + { + m_isShowEllopse = true; + } + else + { + if (m_state == m_EnNormal) + { + m_isShowEllopse = false; + } + } + if (m_state != m_EnNormal) + { + m_isShowEllopse = true; + m_starDraw = true; + } + this->repaint(); +} + +void GCustomCommentFrame::onMouseMoveEvent(QMouseEvent *e) +{ + int nPosX = e->pos().rx(); + int nPosY = e->pos().ry(); + + int commentFrameLeft; + int commentFrameBottom; + int commentFrameTop; + int commentFrameRight; + + QRect rect = m_parent->rect(); + commentFrameLeft = rect.left(); + commentFrameBottom = rect.bottom(); + commentFrameTop = rect.top(); + commentFrameRight = rect.right(); + + if (m_state == m_EnMoving) + { + int nMoveX = e->globalPos().rx() - m_mousePos.rx(); + int nMoveY = e->globalPos().ry() - m_mousePos.ry(); + + m_borderRect.setCoords(m_borderRect.left() + nMoveX, m_borderRect.top() + nMoveY, + m_borderRect.right() + nMoveX, m_borderRect.bottom() + nMoveY); + + QRect rect = m_parent->rect(); + + // 横向 + if (m_borderRect.left() <= rect.left()) + { + m_borderRect.setLeft(rect.left()); + m_borderRect.setRight(rect.left() + m_nWidth); + } + + if (m_borderRect.right() >= rect.right()) + { + m_borderRect.setRight(rect.right()); + m_borderRect.setLeft(m_borderRect.right() - m_nWidth); + } + + // 纵向 + if (m_borderRect.top() <= rect.top()) + { + m_borderRect.setTop(rect.top()); + m_borderRect.setBottom(m_borderRect.top() + m_nHeight); + } + + if (m_borderRect.bottom() >= rect.bottom()) + { + m_borderRect.setBottom(rect.bottom()); + m_borderRect.setTop(m_borderRect.bottom() - m_nHeight); + } + + m_borderRect.setCoords(m_borderRect.left() + nMoveX, m_borderRect.top() + nMoveY, + m_borderRect.right() + nMoveX, m_borderRect.bottom() + nMoveY); + m_mousePos = e->globalPos(); + clearMask(); + } + else if (m_state == m_EnUP) + { + if (nPosY > commentFrameTop) + { + m_borderRect.setCoords(m_borderRect.left(), nPosY, m_borderRect.right(), m_borderRect.bottom()); + } + else + { + m_borderRect.setCoords(m_borderRect.left(), commentFrameTop + 2, m_borderRect.right(), m_borderRect.bottom()); + } + } + else if (m_state == m_EnDown) + { + if (nPosY < commentFrameBottom) + { + m_borderRect.setCoords(m_borderRect.left(), m_borderRect.top(), m_borderRect.right(), nPosY); + } + else + { + m_borderRect.setCoords(m_borderRect.left(), m_borderRect.top(), m_borderRect.right(), commentFrameBottom - 2); + } + } + else if (m_state == m_EnLeft) + { + if (nPosX > commentFrameLeft) + { + m_borderRect.setCoords(nPosX, m_borderRect.top(), m_borderRect.right(), m_borderRect.bottom()); + } + else + { + m_borderRect.setCoords(commentFrameLeft + 2, m_borderRect.top(), m_borderRect.right(), m_borderRect.bottom()); + } + } + else if (m_state == m_EnRiht) + { + if (nPosX < commentFrameRight) + { + m_borderRect.setCoords(m_borderRect.left(), m_borderRect.top(),nPosX , m_borderRect.bottom()); + } + else + { + m_borderRect.setCoords(m_borderRect.left(), m_borderRect.top(),commentFrameRight - 2 , m_borderRect.bottom()); + } + } + else if (m_state == m_EnLeftUp) + { + if (nPosY > commentFrameTop && nPosX > commentFrameLeft) + { + m_borderRect.setCoords(nPosX, nPosY, m_borderRect.right(), m_borderRect.bottom()); + } + else if (nPosY <= commentFrameTop) + { + m_borderRect.setCoords(m_borderRect.left(), commentFrameTop + 2, m_borderRect.right(), m_borderRect.bottom()); + } + else if (nPosX <= commentFrameLeft) + { + m_borderRect.setCoords(commentFrameLeft + 2, m_borderRect.top(), m_borderRect.right(), m_borderRect.bottom()); + } + } + else if (m_state == m_EnbottomLeft) + { + if (nPosX > commentFrameLeft && nPosY < commentFrameBottom) + { + m_borderRect.setCoords(nPosX, m_borderRect.top(), m_borderRect.right(), nPosY); + } + else if (nPosX <= commentFrameLeft) + { + m_borderRect.setCoords(commentFrameLeft + 2, m_borderRect.top(), m_borderRect.right(), m_borderRect.bottom()); + } + else if (nPosY >= commentFrameBottom) + { + m_borderRect.setCoords(m_borderRect.left(), m_borderRect.top(), m_borderRect.right(), commentFrameBottom - 2); + } + } + else if (m_state == m_EnRightUp) + { + if (nPosY > commentFrameTop && nPosX < commentFrameRight) + { + m_borderRect.setCoords(m_borderRect.left(), nPosY, nPosX, m_borderRect.bottom()); + } + else if (nPosY <= commentFrameTop) + { + m_borderRect.setCoords(m_borderRect.left(), commentFrameTop + 2, m_borderRect.right(), m_borderRect.bottom()); + } + else if (nPosX >= commentFrameRight) + { + m_borderRect.setCoords(m_borderRect.left(), m_borderRect.top(),commentFrameRight - 2 , m_borderRect.bottom()); + } + } + else if (m_state == m_EnRightDown) + { + if (nPosY < commentFrameBottom && nPosX < commentFrameRight) + { + m_borderRect.setCoords(m_borderRect.left(), m_borderRect.top(), nPosX, nPosY); + } + else if (nPosY >= commentFrameBottom) + { + m_borderRect.setCoords(m_borderRect.left(), m_borderRect.top(), m_borderRect.right(), commentFrameBottom - 2); + } + else if (nPosX >= commentFrameRight) + { + m_borderRect.setCoords(m_borderRect.left(), m_borderRect.top(),commentFrameRight - 2 , m_borderRect.bottom()); + } + } + else + { + QFrame::mouseMoveEvent(e); + } +} + +void GCustomCommentFrame::mouseMoveEvent(QMouseEvent *e) +{ + // 在选择编辑状态下,需要绘制箭头样式 + if (m_isShowEllopse) + { + inMoveRange(e->pos()); + } + + if (!m_starDraw) + { + QFrame::mouseMoveEvent(e); + return; + } + + onMouseMoveEvent(e); + + this->update(); +} + +void GCustomCommentFrame::mouseReleaseEvent(QMouseEvent *e) +{ + // 1画非编辑状态。 + if (m_state != m_EnNormal) + { + m_state = m_EnNormal; + + resetBorderRect(); + // 获取距离框架x距离最近的点作为x + int nPointX = Abs(m_borderRect.left() - m_topLeft.rx()) < Abs(m_borderRect.right() - m_topLeft.rx()) ? + m_borderRect.left() : m_borderRect.right(); + // 获取距离框架y距离最近的点作为y + int nPointY = Abs(m_borderRect.top() - m_topLeft.ry()) < Abs(m_borderRect.bottom() - m_topLeft.ry()) ? + m_borderRect.top() : m_borderRect.bottom(); + m_bottomRight.setX(nPointX); + m_bottomRight.setY(nPointY); + m_nWidth = Abs(m_borderRect.left() - m_borderRect.right()); + m_nHeight = Abs(m_borderRect.top() - m_borderRect.bottom()); + m_starDraw = false; + setCursor(Qt::ArrowCursor); + resetFramePosition(); + } + + QFrame::mouseReleaseEvent(e); +} + +bool GCustomCommentFrame::eventFilter(QObject *object, QEvent *event) +{ + QWidget *pWidget = dynamic_cast(object); + if (NULL == pWidget) + { + return false; + } + else + { + QAbstractScrollArea *pScrollArea = dynamic_cast(pWidget); + GLDPlainTextEdit *pPlainTextEdit = dynamic_cast(pWidget); + if (NULL != pScrollArea || NULL != pPlainTextEdit) + { + if (event->type() == QEvent::FocusIn) + { + m_isShowEllopse = true; + } + else if ((event->type() == QEvent::FocusOut && !containPos(m_parent->mapFromGlobal(QCursor::pos()), m_borderRect.adjusted(-10, -10, 10, 10))) + && m_isShowEllopse == true + && m_starDraw == false) + { + emit editFocusOut(); + if (!m_isShowCommentPersistent) + { + hide(); + } + m_isShowEllopse = false; + } + } + } + return QFrame::eventFilter(object, event); +} + +void GCustomCommentFrame::showEvent(QShowEvent *) +{ + setCommentFrameMask(); +} + +void GCustomCommentFrame::resizeEvent(QResizeEvent *) +{ + setCommentFrameMask(); +} + +/** + * @brief 鼠标已经移除了当前窗体,不在做动作。 + * @param pos + * @return + */ +bool GCustomCommentFrame::isPosInFrame(QPoint pos) +{ + if ((pos.rx() < 0) || (pos.ry() < 0)) + { + return false; + } + if (pos.rx() > (m_parent->width() - c_AdjustWith)) + { + return false; + } + if (pos.ry() > (m_parent->height() - c_AdjustWith)) + { + return false; + } + return true; +} + +void GCustomCommentFrame::resetFramePosition() +{ + m_angle = cacultAngle(); + clearMask(); + setEditTextPos(); + this->repaint(); + setCommentFrameMask(); + m_plainTextEdit->setFocus(); +} + +void GCustomCommentFrame::inMoveRange(QPoint pos) +{ + if (m_starDraw) + { + return; + } + if (containPosPoint(pos, m_borderRect.bottomLeft())) + { + setCursor(Qt::SizeBDiagCursor); + m_state = m_EnbottomLeft; + } + else if (containPosPoint(pos, m_borderRect.topLeft())) + { + setCursor(Qt::SizeFDiagCursor); + m_state = m_EnLeftUp; + } + else if (containPosPoint(pos, m_borderRect.bottomRight())) + { + setCursor(Qt::SizeFDiagCursor); + m_state = m_EnRightDown; + } + else if (containPosPoint(pos, m_borderRect.topRight())) + { + setCursor(Qt::SizeBDiagCursor); + m_state = m_EnRightUp; + } + else if (containPosPoint(pos, adjustRectUpPoint())) + { + setCursor(Qt::SizeVerCursor); + m_state = m_EnUP; + } + else if (containPosPoint(pos,adjustRectBottomPoint())) + { + setCursor(Qt::SizeVerCursor); + m_state = m_EnDown; + } + else if (containPosPoint(pos, adjustRectLeftPoint())) + { + setCursor(Qt::SizeHorCursor); + m_state = m_EnLeft; + } + else if (containPosPoint(pos, adjustRectRightPoint())) + { + setCursor(Qt::SizeHorCursor); + m_state = m_EnRiht; + } + else if (containPos(pos, m_borderRect.adjusted(-10, -10, 10, 10))) + { + setCursor(Qt::SizeAllCursor); + m_state = m_EnMoving; + } + else + { + unsetCursor(); + m_state = m_EnNormal; + } +} + +/** + * @brief MyGCustomCommentFrame::containPosPoint 看鼠标点距离当前点的距离是否小时10,如果小于10,则认为在范围之内 + * @param pos + * @param border + * @return + */ +double GCustomCommentFrame::getDistance(const QPoint border, const QPoint pos) +{ + double distance = (pos.x() - border.x()) * (pos.x() - border.x()) + + (pos.y() - border.y()) * (pos.y() - border.y()); + return distance; +} + +bool GCustomCommentFrame::containPosPoint(const QPoint pos, const QPoint border) +{ + double distance = getDistance(border, pos); + if (distance < (c_AdjustWith * c_AdjustWith)) + { + return true; + } + return false; +} + +bool GCustomCommentFrame::containPos(const QPoint pos, const QRect subBorderRect) +{ + if (!m_borderRect.contains(pos) && subBorderRect.contains(pos)) + { + return true; + } + else + { + return false; + } +} + diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDCustomWaitingBox.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDCustomWaitingBox.cpp new file mode 100644 index 00000000..7727f8b3 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDCustomWaitingBox.cpp @@ -0,0 +1,151 @@ +#include +#include +#include +#include +#include + +#include "GLDCustomWaitingBox.h" + +GLDCustomWaitingBox::GLDCustomWaitingBox(QWidget *parent) + : QWidget(parent) + , m_mapWait("://icons/CLDCustomWaitingBox_Gray.png") + , m_nimageIndex(0) + , m_nTimerId(0) + , m_bkColor(0, 0, 0, 0) +{ + connect(this, SIGNAL(start()), this, SLOT(show())); + connect(this, SIGNAL(end()), this, SLOT(hide())); + + hide(); +} + +GLDCustomWaitingBox::~GLDCustomWaitingBox() +{ + if (m_nTimerId != 0) + { + QObject::killTimer(m_nTimerId); + m_nTimerId = 0; + } +} + +bool GLDCustomWaitingBox::loadWaitMap(const QString &fileName) +{ + return m_mapWait.load(fileName); +} + +void GLDCustomWaitingBox::hide() +{ + QWidget *pParent = parentWidget(); + + if (pParent != NULL) + { + pParent->removeEventFilter(this); + } + + QWidget::hide(); +} + +void GLDCustomWaitingBox::show() +{ + QWidget *pParent = parentWidget(); + + if (pParent != NULL) + { + move(0, 0); + resize(pParent->size()); + } + + QWidget::show(); + + raise(); + + if (pParent != NULL) + { + pParent->installEventFilter(this); + } + + if (m_nTimerId != 0) + { + QObject::killTimer(m_nTimerId); + m_nTimerId = 0; + } + + m_nTimerId = QObject::startTimer(60); + + this->activateWindow(); +} + +void GLDCustomWaitingBox::setBackGroundColor(const QColor &color) +{ + m_bkColor = color; + update(); +} + +QColor GLDCustomWaitingBox::backGroundColor() +{ + return m_bkColor; +} + +bool GLDCustomWaitingBox::eventFilter(QObject *target, QEvent *event) +{ + QWidget *pParent = parentWidget(); + + if (target == pParent) + { + if (event->type() == QEvent::Resize) + { + QResizeEvent *presizeEvent = (QResizeEvent *)event; + move(0, 0); + resize(presizeEvent->size()); + } + } + + if (event->type() == QEvent::HoverMove + && event->type() == QEvent::MouseButtonPress + && event->type() == QEvent::MouseButtonDblClick + && event->type() == QEvent::MouseButtonPress + && event->type() == QEvent::MouseMove + && event->type() == QEvent::MouseMove + && event->type() == QEvent::Wheel + && event->type() == QEvent::KeyPress + && event->type() == QEvent::KeyRelease) + { + return true; + } + + return QWidget::eventFilter(target, event); +} + +void GLDCustomWaitingBox::paintEvent(QPaintEvent *) +{ + QPainter painterMem(this); + painterMem.setPen(QPen(m_bkColor)); + painterMem.setBrush(QBrush(m_bkColor)); + painterMem.drawRect(0, 0, width(), height()); + + int nxIndex = m_nimageIndex % 6; + int nyIndex = m_nimageIndex / 6; + + int nwidth = m_mapWait.width() / 6; + int nheight = m_mapWait.height() / 2; + + painterMem.drawPixmap((width() - nwidth) / 2 + , (height() - nheight) / 2 + , nwidth + , nheight + , m_mapWait + , nxIndex * nwidth + , nyIndex * nheight + , nwidth + , nheight); +} + +void GLDCustomWaitingBox::timerEvent(QTimerEvent *event) +{ + if (event->timerId() == m_nTimerId) + { + m_nimageIndex = m_nimageIndex % 11; + update(); + ++m_nimageIndex; + } +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDateTimeEdit.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDateTimeEdit.cpp new file mode 100644 index 00000000..fae8c0e7 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDateTimeEdit.cpp @@ -0,0 +1,59 @@ +#include "GLDDateTimeEdit.h" +#include "qabstractspinbox.h" +#include + +GLDDateTimeEdit::GLDDateTimeEdit(QWidget *parent): + QDateTimeEdit(parent) +{ + connect(lineEdit(), SIGNAL(selectionChanged()), + this, SLOT(doSelectionChanged())); + connect(lineEdit(), SIGNAL(cursorPositionChanged(int,int)), + this, SLOT(doCursorPositionChanged(int,int))); +} + +GLDDateTimeEdit::GLDDateTimeEdit(const QDateTime &dt, QWidget *parent): + QDateTimeEdit(dt, parent) +{ + connect(lineEdit(), SIGNAL(selectionChanged()), + this, SLOT(doSelectionChanged())); + connect(lineEdit(), SIGNAL(cursorPositionChanged(int,int)), + this, SLOT(doCursorPositionChanged(int,int))); +} + +bool GLDDateTimeEdit::hasSelectedText() +{ + return lineEdit()->hasSelectedText(); +} + +void GLDDateTimeEdit::cut() +{ + lineEdit()->cut(); +} + +void GLDDateTimeEdit::doSelectionChanged() +{ + emit selectionChanged(); +} + +void GLDDateTimeEdit::doCursorPositionChanged(int, int) +{ + emit cursorPositionChanged(); +} + +void GLDDateTimeEdit::copy() +{ + lineEdit()->copy(); +} + +void GLDDateTimeEdit::deleteSelectedText() +{ + if (hasSelectedText()) + { + lineEdit()->del(); + } +} + +void GLDDateTimeEdit::paste() +{ + lineEdit()->paste(); +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDateTimeEditEx.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDateTimeEditEx.cpp new file mode 100644 index 00000000..5704499f --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDateTimeEditEx.cpp @@ -0,0 +1,608 @@ +#include "GLDDateTimeEditEx.h" + +#include +#include +#include +#include +#include +#include + +#include "GLDWidget_Global.h" +#include "GLDShadow.h" +#include "GLDStrUtils.h" +#include "GLDFileUtils.h" + +const QString c_sDateTimeQssFile = ":/qsses/GLDDateTimeEditEx.qss"; + +const char *c_objectName = "GLDDateTimeEditEx"; +const char *c_hasPopup = "GLDHasPopup"; +const char *c_hasBorderStyle = "GLDBorderStyle"; +const char *c_noBorder = "noBorder"; +const char *c_upDownBtnBorder = "UpDownBtnBorder"; + +const char *c_hint = QT_TRANSLATE_NOOP("GLDDateTimeEditEx", "HINT"); // 提示 +const char *c_dateLessThanSysDate = QT_TRANSLATE_NOOP("GLDDateTimeEditEx", "The selecting dateTime is before the minimum date"); // 您所选择的日期小于最小日期 +const char *c_dateLargerThanSysDate = QT_TRANSLATE_NOOP("GLDDateTimeEditEx", "The selecting dateTime is after the maximum date"); // 您所选择的日期大于最大日期 +const char *c_excludeLetter = QT_TRANSLATE_NOOP("GLDDateTimeEditEx", "The datetime can not include letters"); // 日期不能包含字母 +const char *c_errorDate = QT_TRANSLATE_NOOP("GLDDateTimeEditEx", "You have input a wrong datetime, please input it again"); // 您的日期输入方式有误,请重新输入 + +GLDDateTimeEditEx::GLDDateTimeEditEx(const QDateTime &dt, QWidget *parent) : + GLDDateTimeEdit(dt, parent), + m_isCalendarPopup(false), + m_calendarWidget(NULL), + m_hasBorder(true), + m_curKeyIsEnter(false), + m_buttonType(None), + m_justKeyPressed(false), + m_curPos(0), + m_keyPressing(false), + m_xOffset(0), + m_yOffset(0) +{ + if (!dt.isValid()) + { + m_dateTime = QDateTime::currentDateTime(); + } + else if(dt < minimumDateTime()) + { + emit inputInvalid(true); + dateLessThanSysDateMessageBox(); + m_dateTime = QDateTime::currentDateTime(); + } + else if(dt > maximumDateTime()) + { + emit inputInvalid(true); + dateLargerThanSysDateMessageBox(); + m_dateTime = QDateTime::currentDateTime(); + } + else + { + m_dateTime = dt; + } + setDateTime(m_dateTime); + setObjectName(c_objectName); + setProperty(c_hasPopup, false); + this->setStyleSheet(loadQssFile(qssFilePath(c_sDateTimeQssFile))); + GLDShadow *pShadow = new GLDShadow(this); + pShadow->removeShadow(); +} + +GLDDateTimeEditEx::~GLDDateTimeEditEx() +{ + +} + +QString GLDDateTimeEditEx::plainText() +{ + return parseText(lineEdit()->text()); +} + +bool GLDDateTimeEditEx::calendarPopup() const +{ + return m_isCalendarPopup; +} + +void GLDDateTimeEditEx::setCalendarPopup(bool enable) +{ + m_isCalendarPopup = enable; + setProperty(c_hasPopup, enable); + if (enable) + { + m_buttonType = ComboBoxArrow; + initCalendarPopup(); + m_calendarWidget->setFocus(); + } + this->setStyleSheet(loadQssFile(qssFilePath(c_sDateTimeQssFile))); +} + +void GLDDateTimeEditEx::setHasBorder(const bool bValue) +{ + m_hasBorder = bValue; + if (!bValue) + { + setProperty(c_hasBorderStyle, c_noBorder); + } + this->setStyleSheet(loadQssFile(qssFilePath(c_sDateTimeQssFile))); +} + +const QString GLDDateTimeEditEx::qssFilePath(const QString &path) +{ + return path; +} + +void GLDDateTimeEditEx::excludeLetterMessageBox() +{ + QMessageBox::information(this, tr(c_hint), tr(c_excludeLetter)); +} + +void GLDDateTimeEditEx::errorDateMessageBox() +{ + QMessageBox::information(this, tr(c_hint), tr(c_errorDate)); +} + +void GLDDateTimeEditEx::dateLessThanSysDateMessageBox() +{ + QMessageBox::information(this, tr(c_hint), tr(c_dateLessThanSysDate)); +} + +void GLDDateTimeEditEx::dateLargerThanSysDateMessageBox() +{ + QMessageBox::information(this, tr(c_hint), tr(c_dateLargerThanSysDate)); +} + +void GLDDateTimeEditEx::updateValue() +{ + m_curKeyIsEnter = true; + if (lineEdit()->text().trimmed().isEmpty()) + { + return; + } + QString strDateTimeValue = parseText(lineEdit()->text()); + + //QDateTime中的合法性验证利用了lineEdit的字符串长度,所以需要将字符串设置入控件中 + GString strOriginValue = lineEdit()->text(); + + lineEdit()->setText(strDateTimeValue); + + if (!strDateTimeValue.isEmpty()) + { + if (0 != strOriginValue.compare(dateTime().toString(displayFormat())) + &&0 == strDateTimeValue.compare(dateTime().toString(displayFormat()))) + { + QDateTime dateTime = QDateTime::fromString(strDateTimeValue, displayFormat()); + selectDateTime(dateTime); + return; + } + if (0 != strDateTimeValue.compare(dateTime().toString(displayFormat()))) + { + for (int i = 0; i < strDateTimeValue.length(); ++i) + { + if (strDateTimeValue.at(i).isLetter()) + { + emit inputInvalid(true); + excludeLetterMessageBox(); + selectDateTime(QDateTime::currentDateTime()); + return; + } + QValidator::State state; + state = QDateTimeEdit::validate(strDateTimeValue, i); + + if (QValidator::Acceptable != state) + { + emit inputInvalid(true); + errorDateMessageBox(); + selectDateTime(QDateTime::currentDateTime()); + return; + } + } + + QDateTime dateTime = QDateTime::fromString(strDateTimeValue, displayFormat()); + selectDateTime(dateTime); + return; + } + } +} + +QString GLDDateTimeEditEx::displayFormat() const +{ + return GLDDateTimeEdit::displayFormat(); +} + +void GLDDateTimeEditEx::setDisplayFormat(const QString &format) +{ + GLDDateTimeEdit::setDisplayFormat(format); +} + +void GLDDateTimeEditEx::setCalendarPopupOffset(int xOffset, int yOffset) +{ + m_xOffset = xOffset; + m_yOffset = yOffset; +} + +void GLDDateTimeEditEx::keyPressEvent(QKeyEvent *event) +{ + m_curKeyIsEnter = false; + switch (event->key()) + { + case Qt::Key_Enter: + case Qt::Key_Return: + updateValue(); + break; + default: + // 编辑框在全删除完日期的第一次输入,会在keyPressEvent时回调dateTimeFromText和textFromDateTime函数, + // 在focusOutEvent将值设到lineEdit上,而之后输入日期的时,会在keyPressEvent时回调dateTimeFromText, + // keyPressEvent执行完毕再去回调textFromDateTime函数 + m_justKeyPressed = false; + m_keyPressing = true; + QAbstractSpinBox::keyPressEvent(event); + m_curStr = lineEdit()->text(); + m_curPos = lineEdit()->cursorPosition(); + m_justKeyPressed = true; + m_keyPressing = false; + break; + } +} + +void GLDDateTimeEditEx::mousePressEvent(QMouseEvent *event) +{ + if (!calendarPopup()) + { + GLDDateTimeEdit::mousePressEvent(event); + return; + } + + if (ComboBoxArrow == m_buttonType + && NULL != style() + && NULL != style()->proxy() + ) + { + QStyleOptionComboBox optCombo; + optCombo.init(this); + QRect subRect = style()->proxy()->subControlRect(QStyle::CC_ComboBox, &optCombo, + QStyle::SC_ComboBoxArrow, this); + event->accept(); + positionCalendarPopup(); + if (subRect.contains(event->pos())) + { + bool bValue = true; + emit onshowPopup(bValue); + if (bValue) + { + showPopUp(); + } + } + } + else + { + GLDDateTimeEdit::mousePressEvent(event); + } +} + +void GLDDateTimeEditEx::focusOutEvent(QFocusEvent *event) +{ + QAbstractSpinBox::focusOutEvent(event); + if (m_justKeyPressed) + { + lineEdit()->setText(m_curStr); + lineEdit()->setCursorPosition(m_curPos); + } + if (!m_curKeyIsEnter) + { + updateValue(); + } +} + +void GLDDateTimeEditEx::paintEvent(QPaintEvent *event) +{ + GLDDateTimeEdit::paintEvent(event); + QStyleOptionSpinBox opt; + initStyleOption(&opt); + + QStyleOptionComboBox optCombo; + + optCombo.init(this); + optCombo.editable = true; + optCombo.frame = opt.frame; + optCombo.subControls = opt.subControls; + optCombo.activeSubControls = opt.activeSubControls; + optCombo.state = opt.state; + + if (lineEdit()->isReadOnly()) + { + optCombo.state &= ~QStyle::State_Enabled; + } + + // 鼠标位于箭头所在区域高亮,其他地方不高亮 + QPoint curPos = mapFromGlobal(QCursor::pos()); + QRect subRect = style()->proxy()->subControlRect(QStyle::CC_ComboBox, &optCombo, QStyle::SC_ComboBoxArrow, this); + + if (subRect.contains(curPos)) + { + optCombo.activeSubControls |= newHoverControl(curPos); + } + else + { + optCombo.activeSubControls &= newHoverControl(curPos); + } + + QPainter tmpPt(this); + + if (ComboBoxArrow == m_buttonType && NULL != style()) + { + style()->drawComplexControl(QStyle::CC_ComboBox, &optCombo, &tmpPt, this); + } +} + +void GLDDateTimeEditEx::enterEvent(QEvent *event) +{ + // 处理无弹出框的日历控件进入上下微调按钮的特效 + if (None == m_buttonType) + { + setProperty(c_upDownBtnBorder, true); + } + this->setStyleSheet(loadQssFile(qssFilePath(c_sDateTimeQssFile))); + G_UNUSED(event); +} + +void GLDDateTimeEditEx::leaveEvent(QEvent *event) +{ + // 处理无弹出框的日历控件进入上下微调按钮的特效 + if (None == m_buttonType) + { + setProperty(c_upDownBtnBorder, false); + } + this->setStyleSheet(loadQssFile(qssFilePath(c_sDateTimeQssFile))); + G_UNUSED(event); +} + +QDateTime GLDDateTimeEditEx::dateTimeFromText(const QString &text) const +{ + // 不带日历弹出框的时间控件 + if (None == m_buttonType) + { + return QDateTimeEdit::dateTimeFromText(text); + } + + // 带日历弹出框的时间控件 + m_lastStrForDatetime = text; + if (!text.isNull() && text.length() > 0) + { + return QDateTime::fromString(text, displayFormat()); + } + return QDateTime::currentDateTime(); +} + +QString GLDDateTimeEditEx::textFromDateTime(const QDateTime &dt) const +{ + // 不带日历弹出框的时间控件 + if (None == m_buttonType) + { + return locale().toString(dt, displayFormat()); + } + + // 带日历弹出框的时间控件 + // 编辑框删除后第二次之后的输入由此进入 + if (m_justKeyPressed) + { + return m_curStr; + } + // 编辑框删除后第一次输入由此进入 + else if (m_keyPressing) + { + return m_lastStrForDatetime; + } + return locale().toString(dt, displayFormat()); +} + +QValidator::State GLDDateTimeEditEx::validate(QString &input, int &pos) const +{ + // 不带日历弹出框的时间控件 + if (None == m_buttonType) + { + return QDateTimeEdit::validate(input, pos); + } + + // 带日历弹出框的时间控件 + // 当前的key是QKey_Enter和QKey_Return时,执行校验 + if (m_curKeyIsEnter) + { + return QDateTimeEdit::validate(input, pos); + } + QValidator::State state = QValidator::Acceptable; + return state; +} + +void GLDDateTimeEditEx::initCalendarPopup() +{ + if (NULL == m_calendarWidget) + { + m_calendarWidget = new GLDCalendarWidget(m_dateTime, this); + m_calendarWidget->setWindowFlags(Qt::Popup); + } + connect(m_calendarWidget, &GLDCalendarWidget::clicked, + this, &GLDDateTimeEditEx::selectDate); + connect(m_calendarWidget, &GLDCalendarWidget::activated, + this, &GLDDateTimeEditEx::selectDate); + connect(m_calendarWidget, &GLDCalendarWidget::passDateToEdit, + this, &GLDDateTimeEditEx::setDate); + // 日历控件发出信号,只要编辑框的日期时间变化,就发出信号,弹出框GLDCalendarWidget去响应这种变化 + connect(this, &GLDDateTimeEditEx::dateTimeChanged, + m_calendarWidget, &GLDCalendarWidget::dateTimeChanged); + this->setStyleSheet(loadQssFile(qssFilePath(c_sDateTimeQssFile))); +} + +void GLDDateTimeEditEx::selectDate(const QDate &date) +{ + if (!date.isValid()) + { + return; + } + QDateTime dateTime(date, QTime::currentTime()); + selectDateTime(dateTime); +} + +void GLDDateTimeEditEx::selectDateTime(const QDateTime &dateTime) +{ + // 此处设置两变量为false在于让textFromDateTime由默认的分支执行 + m_justKeyPressed = false; + m_keyPressing = false; + if (!dateTime.isValid()) + { + return; + } + setDateTime(dateTime); + hidePopUp(); +} + + // 定位弹出框的位置 +void GLDDateTimeEditEx::positionCalendarPopup() +{ + QPoint pos = (layoutDirection() == Qt::RightToLeft) ? rect().bottomRight() : + rect().bottomLeft(); + QPoint pos2 = (layoutDirection() == Qt::RightToLeft) ? rect().topRight() : + rect().topLeft(); + + pos = mapToGlobal(pos); + pos2 = mapToGlobal(pos2); + + QSize size = m_calendarWidget->sizeHint(); + QRect screen = QApplication::desktop()->availableGeometry(pos); + + //handle popup falling off screen + if (Qt::RightToLeft == layoutDirection()) + { + pos.setX(pos.x() - size.width()); + pos2.setX(pos2.x() - size.width()); + + if (pos.x() < screen.left()) + { + pos.setX(qMax(pos.x(), screen.left())); + } + else if (pos.x() + size.width() > screen.right()) + { + pos.setX(qMax(pos.x() - size.width(), screen.right() - size.width())); + } + } + else + { + if (pos.x() + size.width() > screen.right()) + { + pos.setX(screen.right() - size.width()); + } + pos.setX(qMax(pos.x(), screen.left())); + } + + if (pos.y() + size.height() > screen.bottom()) + { + pos.setY(pos2.y() - size.height()); + } + else if (pos.y() < screen.top()) + { + pos.setY(screen.top()); + } + + if (pos.y() < screen.top()) + { + pos.setY(screen.top()); + } + if (pos.y() + size.height() > screen.bottom()) + { + pos.setY(screen.bottom() - size.height()); + } + pos.setX(pos.x() + m_xOffset); + pos.setY(pos.y() + m_yOffset); + m_calendarWidget->move(pos); +} + +void GLDDateTimeEditEx::showPopUp() +{ + if (NULL != m_calendarWidget && m_calendarWidget->isVisible()) + { + return; + } + m_calendarWidget->show(); +} + +void GLDDateTimeEditEx::hidePopUp() +{ + if (NULL != m_calendarWidget && m_calendarWidget->isVisible()) + { + m_calendarWidget->hide(); + } +} + +QStyle::SubControl GLDDateTimeEditEx::newHoverControl(const QPoint &pos) +{ + QStyleOptionComboBox optCombo; + optCombo.init(this); + optCombo.editable = true; + optCombo.subControls = QStyle::SC_ComboBoxArrow; + return style()->hitTestComplexControl(QStyle::CC_ComboBox, &optCombo, pos, this); +} + +QString GLDDateTimeEditEx::parseText(const QString &input) +{ + if (input.trimmed().isEmpty()) + { + return input; + } + + QString text = formatDate(input.trimmed()); + QString format = displayFormat(); + // 如果是系统默认格式, 不做解析,直接返回 + if (format.endsWith("yyyy/M/d H:mm")) + { + return input; + } + + // 对比用户设置格式与用户当前输入的每一位,发现格式匹配不上,在单位数前补0 + if (!format.isEmpty() && format.length() > 0) + { + int delta = 0; + // 进行到最后一位,用户输入的日期较用户设置格式位数少,需要做跳出操作 + for (int i = 0; i < format.length(); ++i) + { + if (i == text.length()) + { + text.insert(i - 1, '0'); + break; + } + + // 发现用户设置格式当前位为字母,用户输入日期当前位不为数字,对用户输入日期当前位的前一位补0 + if (format.at(i).isLetter() && !text.at(i).isDigit()) + { + text.insert(i - 1, '0'); + ++delta; + } + } + } + + return text; +} + +QString GLDDateTimeEditEx::formatDate(const QString &input) +{ + QString text = input; + + if (!displayFormat().contains("yy") && !displayFormat().contains("MM") + && !displayFormat().contains("dd")) + { + return text; + } + + const GString c_sSpliterString = "-"; + text.replace(".", "-"); + text.replace("/", "-"); + text.replace("y", "-"); + text.replace("m", "-"); + text.replace("d", ""); + // "年" + text.replace(tr("GLD_Year"), "-"); + // "月" + text.replace(tr("GLD_Month"), "-"); + // "日" + text.replace(tr("GLD_Day"), ""); + + int nSplitSymbolNumber = 0; + for (int i = 0; i < text.length(); ++i) + { + if(sameText(text.at(i), c_sSpliterString)) + { + nSplitSymbolNumber++; + } + } + + if (nSplitSymbolNumber == 1) + { + QString sCurrentYear = QString::number(QDateTime::currentDateTime().date().year()); + text = sCurrentYear + "-" + text; + } + + if (nSplitSymbolNumber == 0) + { + QString sCurrentYear = QString::number(QDateTime::currentDateTime().date().year()); + QString sCurrentMonth = QString::number(QDateTime::currentDateTime().date().month()); + text = sCurrentYear + "-" + sCurrentMonth + "-" + text; + } + return text; +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDefaultItemDelegate.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDefaultItemDelegate.cpp new file mode 100644 index 00000000..9f2f2993 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDefaultItemDelegate.cpp @@ -0,0 +1,3589 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "GLDGlobal.h" +#include "GLDStream.h" +#include "GLDUITypes.h" +#include "GLDSpinBox.h" +#include "GLDEllipsis.h" +#include "GLDStrUtils.h" +#include "GLDTextEdit.h" +#include "GLDFontListEx.h" +#include "GLDTableView.h" +#include "GLDColorList.h" +#include "GLDColorListEx.h" +#include "GLDTreeModel.h" +#include "GLDGroupModel.h" +#include "GLDImageEditor.h" +#include "qabstractitemview.h" +#include "GLDWindowComboBoxEx.h" +#include "GLDStylePaintUtils.h" +#include "GLDAbstractItemModel.h" +#include "TextDocumentRtfOutput.h" +#include "GLDDefaultItemDelegate.h" +#include "GLDDrawSymbol.h" +#include "GLDDateTimeEditEx.h" +#include "GLDLineWidthComboBoxEx.h" +#define QFIXED_MAX (INT_MAX/256) +#define CON_INDENT 10 + +const int minColorRGB = 0; // 最小颜色值的十进制表示 +const int maxColorRGB = 16777215; // 最大颜色值的十进制表示 + +using namespace gld; + +class GlodonDefaultItemDelegatePrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(GlodonDefaultItemDelegate) + +public: + GlodonDefaultItemDelegatePrivate() : f(0), clipPainting(true) {} + + inline const QItemEditorFactory *editorFactory() const + { + return f ? f : QItemEditorFactory::defaultFactory(); + } + + inline QIcon::Mode iconMode(QStyle::State state) const + { + if (QStyle::State_Enabled != (state & QStyle::State_Enabled)) + { + return QIcon::Disabled; + } + + if (QStyle::State_Selected == (state & QStyle::State_Selected)) + { + return QIcon::Selected; + } + + return QIcon::Normal; + } + + inline QIcon::State iconState(QStyle::State state) const + { + return (QStyle::State_Open == (state & QStyle::State_Open)) ? QIcon::On : QIcon::Off; + } + + inline static QString replaceNewLine(QString text) + { + const QChar c_nl = QLatin1Char('\n'); + + for (int i = 0; i < text.count(); ++i) + if (text.at(i) == c_nl) + { + text[i] = QChar::LineSeparator; + } + + return text; + } + + QItemEditorFactory *f; + bool clipPainting; + QSizeF doTextLayout(int lineWidth) const; + + mutable QTextLayout textLayout; + mutable QTextOption textOption; + + // ### temporary hack until we have QStandardItemDelegate + mutable struct Icon + { + QIcon icon; + QIcon::Mode mode; + QIcon::State state; + } tmp; + + static QString valueToText(const QVariant &value); + + const QWidget *widget(const QStyleOptionViewItem &option) const + { + return option.widget; + } + + int textHMargin(const QVariant &marginData, const QStyleOptionViewItem &option) const + { + if (marginData.isValid()) + { + return (marginData.toInt() & 0x00FF0000) >> 16; + } + else + { + const QWidget *widget = option.widget; + QStyle *style = widget ? widget->style() : QApplication::style(); + return style->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, widget) + 1; + } + } + + inline int textVMargin(const QVariant &marginData) const + { + return marginData.isValid() ? (marginData.toInt() & 0x000000FF) / 2 : 0; + } +}; + +/* GlodonDefaultItemDelegate */ + +GlodonDefaultItemDelegate::GlodonDefaultItemDelegate(QObject *parent) : + QItemDelegate(parent), m_curEditor(NULL), m_pTable(NULL), m_oComboBoxCurIndex(-1), m_factor(1), + m_closeEditEvent(NULL), m_comboBoxConvenient(true), m_bCloseEditorOnFocusOut(false), m_inCommitData(false), + m_inSetModelData(false), m_checkSetModelData(true), m_bUseBlendColor(false), m_includingLeading(false), + m_enterJump(false), m_isTextEllipse(false), m_bRepeatCommit(false), m_bCanHideEidtOnExit(true), + m_bIgnoreActiveWindowFocusReason(false), m_bUseComboBoxCompleter(true), + m_wrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere), m_oSelectedCellBackgroundColor() +{ + setClipping(false); +} + +void GlodonDefaultItemDelegate::paintDouble(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + bool bReadOnly = false; + GEditStyle editstyle = editStyle(dataIndex(index), bReadOnly); + + if (editstyle == esLineWidthList) + { + drawBackground(painter, option, index); + + QRect rect = option.rect.adjusted(8, 4, -10, -6); + painter->save(); + QPen pen = painter->pen(); + pen.setColor(Qt::black); + pen.setWidthF(m_oDisplayData.toDouble()); + painter->setPen(pen); + + if (m_oDisplayData.toDouble() != 0) + { + painter->drawLine(rect.left(), (rect.top() + rect.bottom()) / 2, + rect.right(), (rect.top() + rect.bottom()) / 2); + } + + painter->restore(); + drawFocus(painter, option, option.rect); + } + else + { + + QString strFloatview(""); + emit onQueryFloatOrDoubleViewFormat(index, strFloatview); + + if (strFloatview.length() == 0) + { + paintOther(painter, option, index); + // QItemDelegate::paint(painter, option, index); + } + else + { + QPixmap pixmap; + QVariant ico = index.data(Qt::DecorationRole); + QRect decorationRect; + + if (ico.isValid()) + { + pixmap = decoration(option, ico); + decorationRect = QRect(QPoint(0, 0), pixmap.size()); + } + else + { + decorationRect = QRect(); + } + + QRect displayRect = textRectangle(textLayoutBounds(option), option.font, strFloatview); + + QRect checkRect; + //Qt::CheckState checkState = Qt::Unchecked; + m_oDisplayData = index.data(Qt::CheckStateRole); + + if (m_oDisplayData.isValid()) + { + //checkState = static_cast(value.toInt()); +#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) + checkRect = doCheck(option, option.rect, m_oDisplayData); +#else + checkRect = check(option, option.rect, value); +#endif + } + + innerDoLayout(option, &checkRect, &decorationRect, &displayRect, false); + + drawBackground(painter, option, index); + + QImage img = pixmap.toImage(); + img.scaled(decorationRect.size()); + painter->drawImage(decorationRect, img); + + drawDisplay(painter, option, displayRect, strFloatview, index); + drawFocus(painter, option, displayRect); + } + } +} + +void GlodonDefaultItemDelegate::paintBool(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + QStyleOptionViewItem opt(option); + opt.rect = option.rect; + opt.state = opt.state & ~QStyle::State_HasFocus; + + bool bReadOnly = false; + GEditStyle editstyle = editStyle(dataIndex(index), bReadOnly); + + if (editstyle == esNone || bReadOnly) + { + opt.state = opt.state & ~QStyle::State_Enabled; + } + + if (m_oDisplayData.isNull()) + { + opt.state |= QStyle::State_NoChange; + } + else if (m_oDisplayData.toBool()) + { + opt.state |= QStyle::State_On; + } + else + { + opt.state |= QStyle::State_Off; + } + + drawBackground(painter, option, index); + + QPoint center = opt.rect.center(); + QRect checkBox(center.x() - 6, center.y() - 6, 13, 13); + + GlodonTableView *tableView = (GlodonTableView *)(this->parent()); + + if (tableView && tableView->isTree() && index.column() == tableView->treeColumn()) + { + const GTreeViewItem &viewItem = tableView->treeDrawInfo()->m_viewItems.at(index.row()); + + if (!((viewItem.parentIndex == -1) && viewItem.hasChildren != 1)) + { + QRect textRect(opt.rect.left() - CON_INDENT * (viewItem.treeLevel + 1) - 6, opt.rect.top(), + opt.rect.width() + CON_INDENT * (viewItem.treeLevel + 1) + 6, opt.rect.height()); + checkBox = QRect(textRect.center().rx() - 6, textRect.center().ry() - 6, 13, 13); + } + } + + opt.rect = checkBox; + //设置“_q_no_animation”值是因为如果把CheckBox的State_Enable去掉时,可能会出现画得不正确 + bool b_q_no_animation = opt.styleObject->property("_q_no_animation").toBool(); + opt.styleObject->setProperty("_q_no_animation", true); + + // 去掉该效果,该效果在ribbon风格下,会出现刷新问题 + opt.state &= ~QStyle::State_MouseOver; + + const QWidget *widget = opt.widget; + QStyle *style = widget ? widget->style() : QApplication::style(); + +#ifndef __APPLE__ + style->drawPrimitive(QStyle::PE_IndicatorItemViewItemCheck, &opt, painter, widget); +#else + style->drawPrimitive(QStyle::PE_IndicatorCheckBox, &opt, painter, widget); +#endif + opt.styleObject->setProperty("_q_no_animation", b_q_no_animation); + + drawFocus(painter, option, option.rect); +} + +void GlodonDefaultItemDelegate::paintImg(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + QStyleOptionViewItem opt = setOptions(index, option); + GAspectRatioMode gRatioMode = KeepAspectPixel; + emit onQueryImageAspectRatioMode(index, gRatioMode); + drawBackground(painter, opt, index); + drawFocus(painter, opt, opt.rect); + + QPoint topLeft = opt.rect.topLeft(); + QImage img = m_oDisplayData.value(); + topLeft.setY(topLeft.y() + opt.rect.height() / 2 - img.height() / 2); + + if (opt.displayAlignment.testFlag(Qt::AlignLeft)) + { + topLeft.setX(topLeft.x() + 1); + } + else if (opt.displayAlignment.testFlag(Qt::AlignRight)) + { + topLeft.setX(opt.rect.right() - img.width()); + } + else + { + topLeft.setX(topLeft.x() + opt.rect.width() / 2 - img.width() / 2); + } + + if (gRatioMode == KeepAspectRatio || gRatioMode == KeepAspectRatioByExpanding) + { + QImage result = img.scaled(opt.rect.width() - 2, opt.rect.height() - 2, (Qt::AspectRatioMode)gRatioMode); + + topLeft.setX(topLeft.x() + 1); + painter->drawImage(topLeft, result); + } + else if (gRatioMode == IgnoreAspectRatio) + { + QRect source = img.rect(); + QRect target = QRect(opt.rect.left() - 1, opt.rect.top() - 1, + opt.rect.width() - 2, opt.rect.height() - 2); + painter->drawImage(target, img, source); + } + else + { + painter->drawImage(topLeft, img); + } +} + +void GlodonDefaultItemDelegate::paintColor(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + drawBackground(painter, option, index); + + QRect rect = option.rect.adjusted(8, 4, -10, -6); + QPixmap pix(rect.size()); + pix.fill(m_oDisplayData.value()); + painter->drawPixmap(rect, pix); + painter->drawRect(rect); + + drawFocus(painter, option, option.rect); +} + +void GlodonDefaultItemDelegate::paintGType(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index, + GlodonDefaultItemDelegate::GDataType type) const +{ + QStyleOptionViewItem opt = setOptions(index, option); + opt.rect = option.rect; + + QPixmap pixmap; + QVariant ico = index.data(Qt::DecorationRole); + QRect decorationRect; + + if (ico.isValid()) + { + pixmap = decoration(opt, ico); + decorationRect = QRect(QPoint(0, 0), pixmap.size()); + } + else + { + decorationRect = QRect(); + } + + QRect displayRect = textRectangle(textLayoutBounds(opt), opt.font, m_oDisplayData.toString()); + QRect checkRect; + QRect focusRect = displayRect; + innerDoLayout(opt, &checkRect, &decorationRect, &displayRect, false); + + drawBackground(painter, opt, index); + + QVariant margin = index.data(262); + + if (margin.isValid()) + { + int nMargin = margin.toInt(); + displayRect.adjust((nMargin & 0x00FF0000) >> 16, (nMargin & 0x000000FF) / 2, + -(nMargin & 0x00FF0000) >> 16, -(nMargin & 0x000000FF) / 2); + } + + if (type == GTypeHTML) + { + QImage img = pixmap.toImage(); + img.scaled(decorationRect.size()); + painter->drawImage(decorationRect, img); + + QFont font = opt.font; + font.setUnderline(true); + painter->save(); + painter->setPen(Qt::blue); + painter->setFont(font); + + painter->drawText(displayRect, Qt::AlignVCenter, m_oDisplayData.toString()); + painter->restore(); + } + else if (type == GRichText) + { + painter->save(); + + //暂时取消对 RichText 的支持,后续需要重构 TODO zhangjq 2015.09.24 +// RtfReader::Reader reader; +// GByteArray byteArray(m_oDisplayData.toByteArray()); +// GMemoryStream buffer(&byteArray, false); +// bool result = reader.open(buffer); + +// if (!result) +// { +// qWarning() << "failed to open file: "; +// return; +// } + +// painter->translate(displayRect.x(), displayRect.y()); +// QTextDocument rtfDocument; +// RtfReader::TextDocumentRtfOutput *output = new RtfReader::TextDocumentRtfOutput(&rtfDocument); +// reader.parseTo(output); +// rtfDocument.drawContents(painter); +// freeAndNil(output) + painter->restore(); + + } + else if (type == GDiaSymbol) + { + painter->save(); + painter->setFont(opt.font); + painter->setPen(opt.palette.color(QPalette::Text)); + drawDiaSymbol(painter, m_factor * 100, QString(m_oDisplayData.toString()), opt.displayAlignment, displayRect); + painter->restore(); + } + else if (type == GMeterSymbol) + { + painter->save(); + painter->setFont(opt.font); + drawTextMx(painter, m_oDisplayData.toString(), opt.displayAlignment, displayRect); + painter->restore(); + } + + drawFocus(painter, opt, focusRect); +} + +void GlodonDefaultItemDelegate::paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + //for recrod,because the QItemDelegate::paint will use another QStyleOptionViewItem obj + m_oDisplayData = index.model()->data(index, Qt::DisplayRole); + //bool readOnly = false; + QVariant::Type valType = m_oDisplayData.type(); + + if (valType == QVariant::Bool) + { + paintBool(painter, option, index); + } + else if (valType == QVariant::Image) + { + paintImg(painter, option, index); + } + else if (valType == QVariant::Int) + { + paintOther(painter, option, index); + } + else if (valType == QVariant::Double) + { + paintDouble(painter, option, index); + } + else if (valType == QVariant::Color) + { + paintColor(painter, option , index); + } + else + { + GDataType type = GTypeNormal; + + emit onQueryIndexDataType(index, type); + + if (type == GTypeHTML || type == GRichText || type == GDiaSymbol || type == GMeterSymbol) + { + paintGType(painter, option, index, type); + + return; + } + + paintOther(painter, option, index); // QItemDelegate::paint(painter, option, index); + } +} + +void GlodonDefaultItemDelegate::adjustRectByTextMargin( + const QModelIndex &index, const QStyleOptionViewItem &opt, bool isIncludeMargin, QRect &rect) const +{ + Q_D(const GlodonDefaultItemDelegate); + + QVariant oTextMargin = index.data(gidrCellMargin); + + int nTextHMargin = d->textHMargin(oTextMargin, opt); + int nTextVMargin = d->textVMargin(oTextMargin); + + if (isIncludeMargin) + { + rect.adjust(-nTextHMargin, -nTextVMargin, nTextHMargin, nTextVMargin); + } + else + { + rect.adjust(nTextHMargin, nTextVMargin, -nTextHMargin, -nTextVMargin); + } +} + +QSize GlodonDefaultItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + QVariant value = index.data(Qt::SizeHintRole); + if (value.isValid()) + return qvariant_cast(value); + + QStyleOptionViewItem opt = option; + + // 如果option的rect是有效时,计算textRect会把option的宽度作为固定宽度,从而计算高度 + // 见tableView的sizeHintForRow时,就是这么特殊处理的。此时,需要先把margin剪掉 + if (option.rect.isValid()) + { + adjustRectByTextMargin(index, opt, false, opt.rect); + } + + QRect decorationRect = calcRectByData(opt, index, Qt::DecorationRole); + QRect displayRect = calcRectByData(opt, index, Qt::DisplayRole); + QRect checkRect = calcRectByData(opt, index, Qt::CheckStateRole); + + innerDoLayout(option, &checkRect, &decorationRect, &displayRect, true); + + QRect oSizeHint = decorationRect|displayRect|checkRect; + + // 如果rect无效,则说明是在计算自动列宽,此时在计算完之后,需要把margin给加上,因为计算时没有包含margin + // 而显示的时候,是包含了margin的 + if (!option.rect.isValid()) + { + adjustRectByTextMargin(index, opt, true, oSizeHint); + } + + return oSizeHint.size(); +} + +QWidget *GlodonDefaultItemDelegate::createEditor(QWidget *parent, + const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + return const_cast(this)->doCreateEditor(parent, option, index); +} + +void GlodonDefaultItemDelegate::createTreeViewEditor(QWidget *parent, QModelIndex &dIndex, bool bReadOnly) +{ + GLDCustomComboBoxEx *comboBox = new GLDCustomComboBoxEx(parent); + + m_curEditor = comboBox; + + comboBox->setHasBorder(false); + comboBox->setReadOnly(bReadOnly); + + initComboBoxCompleter(comboBox, dIndex); + initComboBox(comboBox, dIndex); + + if (m_comboBoxConvenient) + { + connect(comboBox, SIGNAL(activated(int)), this, SLOT(doComboBoxActivated(int))); + connect(comboBox, SIGNAL(onSetCurrentIndex(int)), this, SLOT(doComboBoxActivated(int))); + } +} + +void GlodonDefaultItemDelegate::createLineEditEditor(QWidget *parent, bool bReadOnly) +{ + GLDCustomLineEdit *lineEdit = new GLDCustomLineEdit(parent); + + m_curEditor = lineEdit; + + lineEdit->setHasBorder(false); + lineEdit->setReadOnly(bReadOnly); +} + +void GlodonDefaultItemDelegate::createDropDownWindowEditor(QWidget *parent, QModelIndex &dIndex, + bool bReadOnly, GEditStyle eEditStyle) +{ + GLDWindowComboBoxEx *comboBox = new GLDWindowComboBoxEx(parent); + + m_curEditor = comboBox; + + if (eEditStyle == esDropDownWindowEllipsis) + { + comboBox->setButtonTypes(GLDWindowComboBoxEx::Ellipsis); + } + else if (eEditStyle == esDropDownWindowNone) + { + comboBox->setButtonTypes(GLDWindowComboBoxEx::None); + } + + comboBox->getLineEdit()->setFrameShape(QFrame::NoFrame); + comboBox->setHasBorder(false); + comboBox->setEditable(!bReadOnly); + initWindowComboBox(comboBox, dIndex); + comboBox->setComboBoxPopupOffset(-2, 3); + + if (m_comboBoxConvenient) + { + connect(comboBox, SIGNAL(onManualColsePopup()), this, SIGNAL(onCommitDataAndCloseEditor())); + } +} + +void GlodonDefaultItemDelegate::createMonthCalendarEditor(QWidget *parent, QModelIndex &dIndex, QVariant::Type vType) +{ + QVariant value = dIndex.model()->data(dIndex, Qt::EditRole); + QDateTime dt = QDateTime::currentDateTime(); + GLDDateTimeEditEx *pDateTimeEditEx = NULL; + + switch (vType) + { + case QVariant::Time: + dt.setTime(value.value()); + pDateTimeEditEx = new GLDDateTimeEditEx(dt, parent); + pDateTimeEditEx->setCalendarPopup(false); + pDateTimeEditEx->setDisplayFormat("hh:mm:ss"); + break; + + case QVariant::Date: + dt.setDate(value.value()); + pDateTimeEditEx = new GLDDateTimeEditEx(dt, parent); + pDateTimeEditEx->setCalendarPopup(true); + pDateTimeEditEx->setDisplayFormat("yyyy-MM-dd"); + pDateTimeEditEx->setCalendarPopupOffset(-2, 3); + break; + + default: + dt = value.value(); + pDateTimeEditEx = new GLDDateTimeEditEx(dt, parent); + pDateTimeEditEx->setCalendarPopup(true); + pDateTimeEditEx->setDisplayFormat("yyyy-MM-dd hh:mm:ss"); + pDateTimeEditEx->setCalendarPopupOffset(-2, 3); + break; + } + + m_curEditor = pDateTimeEditEx; + pDateTimeEditEx->setHasBorder(false); + initDateTimeEdit(pDateTimeEditEx, dIndex); +} + +void GlodonDefaultItemDelegate::createColorListEditor(QWidget *parent, QModelIndex &dIndex, bool bReadOnly) +{ + QVariant value = dIndex.model()->data(dIndex, Qt::EditRole); + QColor color = value.value(); + + GColorListEx *colorListEx = new GColorListEx(parent, color); + + m_curEditor = colorListEx; + colorListEx->setHasBorder(false); + + if(!bReadOnly) + { + colorListEx->setEditable(!bReadOnly); + colorListEx->setIsShowRGBStr(!bReadOnly); + + QIntValidator* pIntValidator = new QIntValidator(colorListEx->lineEdit()); + pIntValidator->setRange(minColorRGB, maxColorRGB); + colorListEx->lineEdit()->setValidator(pIntValidator); + } + + if (m_comboBoxConvenient) + { + connect(colorListEx, SIGNAL(colorBlockClicked(int)), this, SLOT(doComboBoxActivated(int))); + } +} + +void GlodonDefaultItemDelegate::createFontListEditor(QWidget *parent) +{ + GFontListEx *comboBox = new GFontListEx(parent);//new QFontComboBox(parent); + + m_curEditor = comboBox; + + comboBox->setHasBorder(false); + + if (m_comboBoxConvenient) + { + connect(comboBox, SIGNAL(activated(int)), this, SLOT(doComboBoxActivated(int))); + } +} + +void GlodonDefaultItemDelegate::createLineWidthEditor(QModelIndex &dIndex, QWidget *parent) +{ + GLDLineWidthComboBoxEx *lineWidthComboBox = new GLDLineWidthComboBoxEx(parent); + + m_curEditor = lineWidthComboBox; + + lineWidthComboBox->setHasBorder(false); + + if (m_comboBoxConvenient) + { + connect(lineWidthComboBox, SIGNAL(itemClicked(int)), lineWidthComboBox, SIGNAL(activated(int)));// 连接此信号与槽后, 选中后即可退出编辑状态 + connect(lineWidthComboBox, SIGNAL(activated(int)), this, SLOT(doComboBoxActivated(int))); + } + + initLineWidthComboBox(lineWidthComboBox, dIndex); +} + +QWidget *GlodonDefaultItemDelegate::doCreateEditor(QWidget *parent, + const QStyleOptionViewItem &option, + const QModelIndex &index) +{ + QModelIndex dIndex = dataIndex(index); + + if (!editable(dIndex)) + { + m_curEditor = NULL; + + return m_curEditor; + } + + m_currTreeEditing = index; + + bool bReadOnly = false; + bool bNumberRightAlign = false; + + GEditStyle eEditStyle = editStyle(dIndex, bReadOnly); + QVariant::Type vType = dIndex.model()->data(dIndex, Qt::EditRole).type(); + + if (esSimple == eEditStyle) + { + eEditStyle = editStyleByVariantType(vType); + } + + QFont font = zoomFont(dIndex, QFont(), m_factor); + + switch (eEditStyle) + { + case esNone: + m_curEditor = NULL; + break; + + case esLineEdit: + { + createLineEditEditor(parent, bReadOnly); + break; + } + + case esImage: + m_curEditor = new GImageEditor(parent); + break; + + case esDropDown: + case esTreeView: + { + createTreeViewEditor(parent, dIndex, bReadOnly); + break; + } + + // 修改计价提的BUG,新增可多行编辑的下拉框 + case esDropDownWindowEllipsis: + case esDropDownWindowNone: + case esDropDownWindow: + { + createDropDownWindowEditor(parent, dIndex, bReadOnly, eEditStyle); + break; + } + + case esMonthCalendar: + { + createMonthCalendarEditor(parent, dIndex, vType); + break; + } + + case esColorList: + { + createColorListEditor(parent, dIndex, bReadOnly); + break; + } + + case esFontList: + { + createFontListEditor(parent); + break; + } + + case esLineWidthList: + { + createLineWidthEditor(dIndex, parent); + break; + } + + case esPlainEllipsis: + { + createEllipsisEditor(parent, dIndex, bReadOnly); + break; + } + + case esLineEllipsis: + { + createEllipsisEditor(parent, dIndex, bReadOnly); + break; + } + + case esVectorGraph: + case esBool: + { + m_curEditor = NULL; + break; + } + + case esUpDown: + { + if (variantTypeIsByte(vType) || variantTypeIsShort(vType) + || variantTypeIsInt(vType)) + { + GLDSpinBoxEx *pIntEdit = new GLDSpinBoxEx(parent); + pIntEdit->setHasBorder(false); + + if ((NULL != m_pTable) && !m_pTable->alwaysShowEditorPro()) + { + pIntEdit->selectAll(); + } + + m_curEditor = pIntEdit; + break; + } + else if (variantTypeIsFloat(vType)) + { + GLDDoubleSpinBoxEx *pDoubleEdit = new GLDDoubleSpinBoxEx(parent); + pDoubleEdit->setHasBorder(false); + + if ((NULL != m_pTable) && !m_pTable->alwaysShowEditorPro()) + { + pDoubleEdit->selectAll(); + } + + m_curEditor = pDoubleEdit; + break; + } + } + + case esSimple: + { + if (QVariant::Bool == vType) + { + m_curEditor = NULL; + break; + } + + createSpinBox(parent, index, option, vType, bReadOnly, bNumberRightAlign); + + if (QVariant::LongLong == vType) + { + QRegExp regExp("\\d*"); + QLineEdit *pLineEdit = new QLineEdit(parent); + QRegExpValidator *pRegExValidator = new QRegExpValidator(regExp, pLineEdit); + pLineEdit->setValidator(pRegExValidator); + m_curEditor = pLineEdit; + } + + if (m_curEditor != NULL) + { + break; + } + } + + case esPlainEdit: + default: + GLDPlainTextEditEx *plainTextEdit = new GLDPlainTextEditEx(parent); + plainTextEdit->setFrameShape(QFrame::NoFrame); + plainTextEdit->setReadOnly(bReadOnly); + plainTextEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + plainTextEdit->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_curEditor = plainTextEdit; + break; + } + + if (m_curEditor != NULL) + { + if (!bNumberRightAlign) //非数字 + { + QMargins margins = m_curEditor->contentsMargins(); + margins.setTop(0); + margins.setLeft(0); + m_curEditor->setContentsMargins(margins); + } + + m_curEditor->setFont(font); + } + + return m_curEditor; +} + +void GlodonDefaultItemDelegate::createSpinBox(QWidget *parent, + const QModelIndex &dIndex, + const QStyleOptionViewItem &option, + QVariant::Type vType, bool bReadOnly, + bool &numberRightAlign) +{ + QAbstractSpinBox *pSpinBox = NULL; + + if (variantTypeIsByte(vType) || variantTypeIsShort(vType) || variantTypeIsInt(vType)) + { + numberRightAlign = true; + GLDSpinBoxEx *pGLDSpinBoxEx = new GLDSpinBoxEx(parent); + pGLDSpinBoxEx->setMinimum(MinInt); + pGLDSpinBoxEx->setMaximum(MaxInt); + pGLDSpinBoxEx->setHasBorder(false); + pSpinBox = pGLDSpinBoxEx; + } + else if (variantTypeIsFloat(vType)) + { + numberRightAlign = true; + GLDDoubleSpinBoxEx *pGLDDoubleSpinBoxEx = new GLDDoubleSpinBoxEx(parent); + pGLDDoubleSpinBoxEx->setHasBorder(false); + pSpinBox = pGLDDoubleSpinBoxEx; + } + + if (NULL != pSpinBox) + { + pSpinBox->setButtonSymbols(QAbstractSpinBox::NoButtons); + Qt::Alignment align = option.displayAlignment & ~Qt::AlignLeft; + align |= Qt::AlignRight; + pSpinBox->setAlignment(align); + pSpinBox->setReadOnly(bReadOnly); + } + + initSpinBox(pSpinBox, dIndex); + + m_curEditor = pSpinBox; +} + +void GlodonDefaultItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + if (m_inSetModelData && !m_pTable->alwaysShowEditorPro()) + { + return; + } + + bool bReadOnly = false; + QModelIndex dIndex = dataIndex(index); + QVariant value = dIndex.model()->data(dIndex, Qt::EditRole); + +#ifdef _FONTSYMBOL_ + QString displaySymbols = value.toString(); + GlodonSymbols glodonSymbols; + QString aliases = glodonSymbols.aliasesFromDisplaySymbols(displaySymbols); + value = QVariant(aliases); +#endif + + m_currTreeEditing = index; + + QVariant::Type vType = value.type(); + GEditStyle eEditStyle = editStyle(dIndex, bReadOnly); + + if (esSimple == eEditStyle) + { + eEditStyle = editStyleByVariantType(vType); + } + + switch (eEditStyle) + { + case esNone: + break; + + case esLineEdit: + { + QLineEdit *edit = static_cast(editor); + + if (value.isNull()) + { + edit->setText(""); + } + else + { + edit->setText(value.toString()); + } + + if ((NULL != m_pTable) && !m_pTable->alwaysShowEditorPro()) + { + edit->selectAll(); + } + + break; + } + + case esImage: + { + QImage img = value.value(); + GImageEditor *imageEditor = static_cast(editor); + imageEditor->setImage(img); + break; + } + + case esDropDown: + case esTreeView: + { + GLDCustomComboBox *comboBox = static_cast(editor); + QString sEditText = value.toString(); + + if (value.isNull()) + { + sEditText = ""; + } + + int nIndex = comboBox->findText(sEditText); + + if (nIndex <= -1 && !value.isNull()) + { + nIndex = comboBox->findData(value); + m_oComboBoxCurIndex = nIndex; + } + + if (nIndex > -1) + { + comboBox->setCurrentIndex(nIndex); + } + + if (comboBox->isEditable()) + { + comboBox->setEditText(sEditText); + } + + QLineEdit *lineEdit = comboBox->lineEdit(); + + if ((NULL != lineEdit) && (NULL != m_pTable) && !m_pTable->alwaysShowEditorPro()) + { + lineEdit->selectAll(); + } + + break; + } + + // 修改计价提的BUG,新增可多行编辑的下拉框 + case esDropDownWindowEllipsis: + case esDropDownWindowNone: + case esDropDownWindow: + { + GLDWindowComboBoxEx *pComboBox = dynamic_cast(editor); + if (NULL == pComboBox) + { + break; + } + + if (value.isNull()) + { + pComboBox->setEditText(""); + } + else + { + pComboBox->setEditText(value.toString()); + } + + if ((NULL != m_pTable) && !m_pTable->alwaysShowEditorPro()) + { + pComboBox->selectAll(); + } + + break; + } + + case esMonthCalendar: + { + GLDDateTimeEditEx *pDateTimeEditEx = static_cast(editor); + + if (QVariant::Time == vType) + { + pDateTimeEditEx->setTime(value.toTime()); + } + else if (QVariant::Date == vType) + { + pDateTimeEditEx->setDate(value.toDate()); + } + else + { + pDateTimeEditEx->setDateTime(value.toDateTime()); + } + + break; + } + + case esColorList: + { + GColorListEx *colorListEx = static_cast(editor); + QColor color = value.value(); + + if (colorListEx->lineEdit()) + { + // 颜色的name函数返回值形如"#FF0000",需截取#后的十六进制值 + colorListEx->lineEdit()->setText(int64ToStr(strToInt64(color.name().mid(1), 16))); + } + + colorListEx->setCurrentColor(color); + break; + } + + case esFontList: + { + QFont font = value.value(); + GFontListEx *fontComboBox = static_cast(editor); + fontComboBox->setCurrentFont(font); + + if ((NULL != fontComboBox->lineEdit()) && (NULL != m_pTable) && !m_pTable->alwaysShowEditorPro()) + { + fontComboBox->lineEdit()->selectAll(); + } + + break; + } + + case esLineWidthList: + { + GLDLineWidthComboBoxEx *lineWidthComboBox = static_cast(editor); + lineWidthComboBox->setCurLineWidth(value.toDouble()); + break; + } + + case esPlainEllipsis: + case esLineEllipsis: + { + GLDAbstractButtonEdit *ellipsis = static_cast(editor); + ellipsis->setModelIndex(dIndex); + + if (value.isNull()) + { + ellipsis->setText(""); + } + else + { + ellipsis->setText(value.toString()); + } + + if ((NULL != m_pTable) && !m_pTable->alwaysShowEditorPro()) + { + ellipsis->selectAll(); + } + + break; + } + + case esVectorGraph: + case esBool: + break; + + case esUpDown: + case esSimple: + { + if (QVariant::Bool == vType) + { + break; + } + else if (variantTypeIsByte(vType) || variantTypeIsShort(vType) + || variantTypeIsInt(vType)) + { + + GLDSpinBoxEx *pIntEdit = static_cast(editor); + + if ((NULL != m_pTable) && !m_pTable->alwaysShowEditorPro()) + { + pIntEdit->selectAll(); + } + + pIntEdit->setValue(value.toInt()); + break; + } + else if (variantTypeIsFloat(vType)) + { + GLDDoubleSpinBoxEx *pDoubleEdit = static_cast(editor); + pDoubleEdit->setValue(value.toDouble()); + + if ((NULL != m_pTable) && !m_pTable->alwaysShowEditorPro()) + { + pDoubleEdit->selectAll(); + } + + break; + } + + else if (QVariant::LongLong == vType) + { + QLineEdit *pLineEdit = static_cast(editor); + pLineEdit->setText(value.toString()); + + if ((NULL != m_pTable) && !m_pTable->alwaysShowEditorPro()) + { + pLineEdit->selectAll(); + } + + break; + } + } + + case esPlainEdit: + default: + { + QPlainTextEdit *plainTextEdit = static_cast(editor); + + if (value.isNull()) + { + plainTextEdit->setPlainText(""); + } + else + { + plainTextEdit->setPlainText(value.toString()); + } + + if ((NULL != m_pTable) && !m_pTable->alwaysShowEditorPro()) + { + plainTextEdit->selectAll(); + } + + break; + } + } +} + +bool GlodonDefaultItemDelegate::setTreeViewModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const +{ + bool result = true; + + GLDCustomComboBox *comboBox = static_cast(editor); + + int nItemIndex = comboBox->findText(comboBox->currentText()); + + if (nItemIndex >= 0) + { + QVariant value = comboBox->itemData(nItemIndex); + + if (value.isValid()) + { + // 先去data中找,如果找到,就直接设置 + result = model->setData(index, value); + } + else + { + // 否则去text中去找,找到对应的text,就把data设置进去, + result = model->setData(index, comboBox->itemText(nItemIndex)); + } + } + else + { + // 如果没找到就直接设置comboBox现在的值 + result = model->setData(index, comboBox->currentText()); + } + + //说明用的是ItemData + if (m_comboBoxConvenient) + { + disconnect(comboBox, SIGNAL(activated(int)), this, SLOT(doComboBoxActivated(int))); + disconnect(comboBox, SIGNAL(onSetCurrentIndex(int)), this, SLOT(doComboBoxActivated(int))); + } + + return result; +} + +bool GlodonDefaultItemDelegate::setDropDownWindowModelData(QWidget *editor, + QAbstractItemModel *model, + const QModelIndex &index) const +{ + bool result = true; + GLDWindowComboBoxEx *comboBox = static_cast(editor); + + QString text = comboBox->editText(); + +#ifdef _FONTSYMBOL_ + QString aliases = text; + GlodonSymbols glodonSymbols; + text = glodonSymbols.displaySymbolsFromAliases(aliases); +#endif + + result = model->setData(index, text); + + if (m_comboBoxConvenient) + { + disconnect(comboBox, SIGNAL(onManualColsePopup()), this, SIGNAL(onCommitDataAndCloseEditor())); + } + + return result; +} + +bool GlodonDefaultItemDelegate::setMonthCalendarModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index, QVariant::Type vType) const +{ + bool result = true; + + GLDDateTimeEditEx *pDateTimeEditEx = static_cast(editor); + + // 因为事件调用顺序,导致此事件在 GLDDateTimeEditEx 写入之前发生,所以手动更新其值 + pDateTimeEditEx->updateValue(); + + if (pDateTimeEditEx->plainText().isEmpty()) + { + if (QVariant::Time == vType) + { + result = model->setData(index, QTime()); + } + else if (QVariant::Date == vType) + { + result = model->setData(index, QDate()); + } + else + { + result = model->setData(index, QDateTime()); + } + } + else + { + if (QVariant::Time == vType) + { + result = model->setData(index, pDateTimeEditEx->time()); + } + else if (QVariant::Date == vType) + { + result = model->setData(index, pDateTimeEditEx->date()); + } + else + { + result = model->setData(index, pDateTimeEditEx->dateTime()); + } + } + + return result; +} + +void GlodonDefaultItemDelegate::setModelData(QWidget *editor, + QAbstractItemModel *model, + const QModelIndex &index) const +{ + const_cast(this)->m_inSetModelData = true; + + try + { + bool bReadOnly = false; + bool result = true; + + m_currTreeEditing = index; + + QModelIndex dIndex = dataIndex(index); + + QVariant value = dIndex.model()->data(dIndex, Qt::EditRole); + QVariant::Type vType = value.type(); + + GEditStyle eEditStyle = editStyle(dIndex, bReadOnly); + + if (esSimple == eEditStyle) + { + eEditStyle = editStyleByVariantType(vType); + } + + switch (eEditStyle) + { + case esNone: + break; + + case esImage: + { + GImageEditor *imageEditor = static_cast(editor); + QImage img = imageEditor->image(); + result = model->setData(index, img); + break; + } + + case esDropDown: + case esTreeView: + { + result = setTreeViewModelData(editor, model, index); + break; + } + + // 修改计价提的BUG,新增可多行编辑的下拉框 + case esDropDownWindowEllipsis: + case esDropDownWindowNone: + case esDropDownWindow: + { + result = setDropDownWindowModelData(editor, model, index); + break; + } + + case esMonthCalendar: + { + result = setMonthCalendarModelData(editor, model, index, vType); + break; + } + + case esColorList: + { + GColorListEx *colorListEx = static_cast(editor); + + if(colorListEx->isShowRGBStr()) + { + GString colorRGBStr = colorListEx->currentText(); + + if (colorRGBStr.isEmpty()) + { + result = model->setData(index, colorListEx->currentColor()); + } + else + { + GString str = intToColorHex(strToInt64(colorRGBStr)); + result = model->setData(index, QColor(str)); + } + } + else + { + result = model->setData(index, colorListEx->currentColor()); + } + + break; + } + + case esFontList: + { + GFontListEx *fontComboBox = static_cast(editor); + result = model->setData(index, fontComboBox->currentFont()); + break; + } + + case esLineWidthList: + { + GLDLineWidthComboBoxEx *lineWidthComboBox = static_cast(editor); + result = model->setData(index, lineWidthComboBox->curLineWidth()); + break; + } + + case esPlainEllipsis: + case esLineEllipsis: + { + GLDAbstractButtonEdit *ellipsis = static_cast(editor); + QString text = ellipsis->text(); + +#ifdef _FONTSYMBOL_ + QString aliases = text; + GlodonSymbols glodonSymbols; + text = glodonSymbols.displaySymbolsFromAliases(aliases); +#endif + + result = model->setData(index, text); + break; + } + + case esLineEdit: + { + QLineEdit *edit = static_cast(editor); + QString text = edit->text(); + +#ifdef _FONTSYMBOL_ + QString aliases = text; + GlodonSymbols glodonSymbols; + text = glodonSymbols.displaySymbolsFromAliases(aliases); +#endif + + result = model->setData(index, text/*edit->text()*/); + break; + } + + case esUpDown: + case esSimple: + { + if (variantTypeIsByte(vType) || variantTypeIsShort(vType) + || variantTypeIsInt(vType)) + { + GLDSpinBoxEx *pIntEdit = static_cast(editor); + result = model->setData(index, compareDataByType(value, pIntEdit->value())); + break; + } + else if (variantTypeIsFloat(vType)) + { + GLDDoubleSpinBoxEx *pDoubleEdit = static_cast(editor); + result = model->setData(index, compareDataByType(value, pDoubleEdit->value())); + break; + } + else if (QVariant::LongLong == vType) + { + QLineEdit *pLineEdit = static_cast(editor); + result = model->setData(index, compareDataByType(value, pLineEdit->text().trimmed().toLongLong())); + break; + } + // 此处不需要break,如果编译方式是esSimple,默认会走QPlanTextEdit,在createEdit中和setEditData中都是这个流程 + } + + default: + QPlainTextEdit *plainTextEdit = static_cast(editor); + QString str = plainTextEdit->toPlainText(); + + if (str.length() == 0) + { + result = model->setData(index, QVariant()); + break; + } + +#ifdef _FONTSYMBOL_ + QString aliases = str; + GlodonSymbols glodonSymbols; + str = glodonSymbols.displaySymbolsFromAliases(aliases); +#endif + + result = model->setData(index, str); + break; + } + + const_cast(this)->setCheckSetModelData(result); + } + catch (...) + { + const_cast(this)->m_inSetModelData = false; + throw; + } + + const_cast(this)->m_inSetModelData = false; +} + +void GlodonDefaultItemDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + // 当第一行或者第一列时,需要将Edit的边线向内调整1像素 + // 将画在里面的格线让出来 + QRect editRect = option.rect; + if (0 == index.row()) + { + editRect.setTop(editRect.top() + 1); + } + if (0 == index.column()) + { + editRect.setLeft(editRect.left() + 1); + } + editor->setGeometry(editRect); + Q_UNUSED(index); +} + +void GlodonDefaultItemDelegate::drawFocus(QPainter *painter, + const QStyleOptionViewItem &option, + const QRect &rect) const +{ + // 现在不再绘制焦点,通过当前焦点格的背景不同,区分选择区域与焦点格 + G_UNUSED(painter); + G_UNUSED(option); + G_UNUSED(rect); +} + +void GlodonDefaultItemDelegate::drawBackground(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + bool bEditStyleDrawNeedEditorBg = false; + QVariant oBackColor = index.data(Qt::BackgroundRole); + + GlodonTableView *pGldTable = dynamic_cast(m_pTable); + + if (NULL != m_pTable + && (NULL != pGldTable && !pGldTable->showCurCellBackgroundColor()) + && (m_pTable->currentIndex() == index + && (index.flags() & Qt::ItemIsSelectable) == Qt::ItemIsSelectable)) + { + painter->fillRect(option.rect, qvariant_cast(oBackColor)); + return; + } + + if (option.showDecorationSelected && (QStyle::State_Selected == (option.state & QStyle::State_Selected)) + && !bEditStyleDrawNeedEditorBg) + { + QPalette::ColorGroup cg = (QStyle::State_Enabled == (option.state & QStyle::State_Enabled)) + ? QPalette::Normal : QPalette::Disabled; + + if (cg == QPalette::Normal && !(option.state & QStyle::State_Active)) + { + cg = QPalette::Inactive; + } + + //使用混合色绘制背景 + if (m_bUseBlendColor) + { + if (!oBackColor.isValid()) + { + oBackColor = QColor(255, 255, 255); + QBrush brush = qvariant_cast(oBackColor); + painter->fillRect(option.rect, brush.color().darker(108)); + } + else + { + //设置混合色,把单元格背景色跟选中色进行等比例混合; zhangjq + QColor oSelectedColor = selectedCellBackgroundColor(); + QColor oBackGroundColor = qvariant_cast(oBackColor); + QColor oBlendColor((oSelectedColor.red() + oBackGroundColor.red()) / 2, + (oSelectedColor.green() + oBackGroundColor.green()) / 2, + (oSelectedColor.blue() + oBackGroundColor.blue()) / 2, + (oSelectedColor.alpha() + oBackGroundColor.alpha()) / 2); + + painter->fillRect(option.rect, oBlendColor); + } + } + else + { + painter->fillRect(option.rect, selectedCellBackgroundColor()); + } + } + else + { + QPointF oldBO = painter->brushOrigin(); + + if (oBackColor.canConvert()) + { + painter->setBrushOrigin(option.rect.topLeft()); + +// bool readOnly = true; + //需要editor背景,//且并不是空editor格子 + if (bEditStyleDrawNeedEditorBg)// && editStyle(index, readOnly) != esNone) + { + painter->fillRect(option.rect, QBrush(Qt::white)); + } + else + { + painter->fillRect(option.rect, qvariant_cast(oBackColor)); +// painter->fillRect(option.rect, qvariant_cas); + } + + painter->setBrushOrigin(oldBO); + } + } +} + +void GlodonDefaultItemDelegate::drawDisplay(QPainter *painter, const QStyleOptionViewItem &option, + const QRect &rect, const QString &text, const QModelIndex &index) const +{ + QRect newRect(rect); + bool bReadOnly = false; + + GLDTableView *pGLDTableView = dynamic_cast(m_pTable); + if ((pGLDTableView != NULL) && pGLDTableView->shouldDoEditorDraw(option.index)) + { + QModelIndex dIndex = dataIndex(option.index); + + switch (editStyle(dIndex, bReadOnly)) + { + case esDropDown: + newRect.adjust(0, 0, -6, 0); + break; + + case esMonthCalendar: + newRect.adjust(0, 0, -6, 0); + break; + + default: + break; + } + } + + QVariant textColor = index.data(Qt::TextColorRole); + + QStyleOptionViewItem opt(option); + + if (textColor.isValid()) + { + QColor color = textColor.value(); + opt.palette.setColor(QPalette::HighlightedText, color); + opt.palette.setColor(QPalette::Text, color); + } + + //使用混合色时去除选中标记,否则会使用Qt方式绘制背景 + QStyle::State preState; + bool bRemoved = QStyle::State_Selected == (opt.state & QStyle::State_Selected); + + if (bRemoved) + { + preState = opt.state; + opt.state &= ~QStyle::State_Selected; + } + + doDrawDisplay(painter, opt, newRect, text, index); + + if (bRemoved) + { + opt.state = preState; + } +} + +void GlodonDefaultItemDelegate::drawEditStyleDraw( + QPainter *painter, QStyleOptionViewItem &option, QRect &rect) const +{ + if (!option.index.isValid()) + { + return; + } + + if (!m_pTable) + { + return; + } + + GLDTableView *pGLDTableView = dynamic_cast(m_pTable); + if (pGLDTableView->shouldDoEditorDraw(option.index)) + { + QModelIndex dIndex = dataIndex(option.index); + bool bReadOnly = false; + + if (!editable(dIndex)) + { + return; + } + + switch (editStyle(dIndex, bReadOnly)) + { + // 只读下,不需要绘制 + if (bReadOnly) + { + return; + } + + //无需绘制 + case esNone: + case esPlainEdit: + case esLineEdit: + case esImage: + case esBool: + case esDropDownWindowNone: + break; + + // 向下箭头 + case esDropDownWindowEllipsis: + { + QStyleOptionButton opt; + GLDStylePaintUtils::initPushButtonOpt(opt, rect, QString("...")); + m_pTable->style()->drawItemPixmap( + painter, opt.rect, Qt::AlignCenter, + QPixmap(":/icons/GLDWindowComboBoxEx-ellipsis.png")); + + rect.adjust(0, 0, -opt.rect.width(), 0); + option.rect = rect; + break; + } + + case esDropDownWindow: + case esDropDown: + case esTreeView: + case esColorList: + case esFontList: + case esLineWidthList: + { + QStyleOptionComboBox tempOpt; + GLDStylePaintUtils::initComboBoxOpt(tempOpt, rect); + QRect subControlRect = m_pTable->style()->subControlRect(QStyle::CC_ComboBox, &tempOpt, + QStyle::SC_ComboBoxArrow, m_pTable); + rect.adjust(0, 0, - subControlRect.width(), 0); + subControlRect.adjust(-4, 0, 0, 0); // 为了让非编辑状态时与进入编辑状态时,编辑方式的位置少偏移,所以减去4,下同 + m_pTable->style()->drawItemPixmap( + painter, subControlRect, Qt::AlignCenter, + QPixmap(":/icons/GLDCustomComboBoxEx-downarrow.png")); + option.rect = rect; + break; + } + + case esMonthCalendar: + { + QStyleOptionComboBox tempOpt; + GLDStylePaintUtils::initComboBoxOpt(tempOpt, rect); + QRect subControlRect = m_pTable->style()->subControlRect(QStyle::CC_ComboBox, &tempOpt, + QStyle::SC_ComboBoxArrow, m_pTable); + rect.adjust(0, 0, - subControlRect.width(), 0); + + subControlRect.adjust(-8, 0, 0, 0); + m_pTable->style()->drawItemPixmap( + painter, subControlRect, Qt::AlignCenter, + QPixmap(":/icons/calendar.png")); + option.rect = rect; + break; + } + + // 带三点button + case esPlainEllipsis: + case esLineEllipsis: + { + QStyleOptionButton opt; + GLDStylePaintUtils::initPushButtonOpt(opt, rect, QString("...")); + m_pTable->style()->drawItemPixmap( + painter, opt.rect, Qt::AlignCenter, + QPixmap(":/icons/GLDLineButtonEditEx-ellipsis.png")); + + rect.adjust(0, 0, -opt.rect.width(), 0); + option.rect = rect; + break; + } + + // 带上下箭头或者加减号button + case esUpDown: + { + QStyleOptionSpinBox opt; + GLDStylePaintUtils::initSpinBoxOpt(opt, rect); + opt.subControls &= ~QStyle::SC_SpinBoxFrame; + + QRect spinBoxUpRect = m_pTable->style()->subControlRect(QStyle::CC_SpinBox, &opt, + QStyle::SC_SpinBoxUp, + m_pTable); + rect.adjust(0, 0, - spinBoxUpRect.width(), 0); + m_pTable->style()->drawComplexControl(QStyle::CC_SpinBox, &opt, painter); + option.rect = rect; + break; + } + + default: + break; + } + } +} + +int GlodonDefaultItemDelegate::calculateLineCount(const QRect &textRect) const +{ + Q_D(const GlodonDefaultItemDelegate); + + d->textLayout.beginLayout(); + QTextLine line = d->textLayout.createLine(); + line.setLeadingIncluded(true); + line.setLineWidth(textRect.width()); + line.setPosition(QPointF(0, 0)); + int nLineHeight = line.height(); + d->textLayout.endLayout(); + + int nLineCount = textRect.height() / (nLineHeight); + + if (nLineCount == 0) + { + nLineCount = 1; + } + + return nLineCount; +} + +QString GlodonDefaultItemDelegate::elidedText(int &textLineCount, + int rectLineCount, const QRect &textRect, + const QString &text, const QStyleOptionViewItem &option) const +{ + QString strElided; + + if (text.isEmpty()) + { + textLineCount = 1; + return strElided; + } + + QString strRestText = text; + int nJ = 0; + int ntextRectWidth = textRect.width(); + int nRestStartPos = 0; + + while (!strRestText.isEmpty()) + { + nJ++; + + if (m_isTextEllipse) + { + if (nJ > rectLineCount) + { + break; + } + } + else + { + if (nJ >= rectLineCount) + { + strElided += option.fontMetrics.elidedText(strRestText, option.textElideMode, ntextRectWidth); + break; + } + } + + int nI = 0; + + while (true) + { + if (nI >= strRestText.length()) + { + nRestStartPos += nI; + strElided += strRestText.mid(0, nI); + break; + } + + QChar ch; + int nWord = 0; + ch = strRestText[nI + nWord]; + + // 获得字母字符串 + while (ch < 128 && ch != QChar::Space && (nI + nWord) < strRestText.length()) + { + nWord++; + ch = strRestText[nI + nWord]; + } + + // 字母后的空格 + while (ch == QChar::Space && (nI + nWord) < strRestText.length()) + { + nWord++; + ch = strRestText[nI + nWord]; + } + + int noTrimeWidth; + + if (nWord > 0) + { + noTrimeWidth = option.fontMetrics.width(strRestText, nI + nWord); + } + else + { + noTrimeWidth = option.fontMetrics.width(strRestText, nI + 1); + } + + if (noTrimeWidth > textRect.width()) + { + QString trimedText = strRestText.mid(0, nI + nWord).trimmed(); + int nTrimedWidth = option.fontMetrics.width(trimedText); + + if (nTrimedWidth > ntextRectWidth && nWord > 0) + { + if (nI == 0) + { + QString strMidRestText = strRestText.mid(nI, nWord); + int nWordWidth = option.fontMetrics.width(strMidRestText); + + if (nWordWidth <= ntextRectWidth) + { + nI = nWord; + } + else + { + while (true) + { + int nMidPos = nWord / 2; + + if (nMidPos == 0) + { + nWord = 0; + break; + } + + nWordWidth = option.fontMetrics.width(strRestText.mid(0, nI + nMidPos)); + + if (nWordWidth > ntextRectWidth) + { + nWord = nMidPos; + } + else + { + nI += nMidPos; + nWord -= nMidPos; + } + } + } + } + } + else + { + nI += nWord; + } + + nRestStartPos = nI; + strElided += strRestText.mid(0, nI); + break; + } + + if (nWord > 0) + { + nI += nWord; + } + else + { + nI++; + } + } + + strRestText = strRestText.mid(nRestStartPos); + } + + textLineCount = nJ; + + return strElided; +} + +QString GlodonDefaultItemDelegate::elidedTextWithoutLineFeed(const QRect &textRect, + const QString &text, + const QStyleOptionViewItem &option) const +{ + int nRectLineCount = calculateLineCount(textRect); + int nTextLineCount = 0; + + return elidedText(nTextLineCount, nRectLineCount, textRect, text, option); +} + +QString GlodonDefaultItemDelegate::elidedTextWithLineFeed(const QRect &textRect, + const QString &text, + const QStyleOptionViewItem &option) const +{ + QString strElided; + int nRectLineCount = calculateLineCount(textRect); + int nTextLineCount = 0; + + int nStart = 0; + int nEnd = 0; + QString strRestText; + + while (nRectLineCount > 0) + { + if (!strElided.isEmpty()) + { + strElided += QChar::LineSeparator; + } + + nEnd = text.indexOf(QChar::LineFeed, nStart); + + if (nEnd != -1) + { + strRestText = text.mid(nStart, nEnd - nStart); + nStart = nEnd + 1; + } + else + { + // get the string, between last linefeed and the string end + strRestText = text.mid(nStart, text.size() - 1); + } + + strElided += elidedText(nTextLineCount, nRectLineCount, textRect, strRestText, option); + nRectLineCount -= nTextLineCount; + } + + return strElided; +} + +QFont GlodonDefaultItemDelegate::zoomFont(QModelIndex index, QFont font, double factor) const +{ + QFont result = font; + QVariant value = index.data(Qt::FontRole); + + if (value.isValid()) + { + result = qvariant_cast(value).resolve(font); + } + + if (result.pointSize() > 0) + { + result.setPointSize(result.pointSize() * factor); + } + + return result; +} + +void GlodonDefaultItemDelegate::initComboBoxCompleter(QComboBox *comboBox, QModelIndex index) +{ + if (m_bUseComboBoxCompleter) + { + QCompleter *pCompleter = new QCompleter(comboBox); + pCompleter->setModel(comboBox->model()); + pCompleter->setCaseSensitivity(Qt::CaseInsensitive); + comboBox->setCompleter(pCompleter); + } + + G_UNUSED(index); +} + +QRect GlodonDefaultItemDelegate::editStyleRect(QModelIndex index, QRect rect) +{ + QModelIndex dIndex = dataIndex(index); + + bool bReadOnly = false; + + if (!editable(dIndex)) + { + return QRect(); + } + + switch (editStyle(dIndex, bReadOnly)) + { + // 向下箭头 + case esDropDownWindowEllipsis: + case esDropDownWindow: + case esDropDown: + case esTreeView: + case esColorList: + case esFontList: + case esMonthCalendar: + case esLineWidthList: + { + QStyleOptionComboBox tempOpt; + GLDStylePaintUtils::initComboBoxOpt(tempOpt, rect); + QRect subControlRect = m_pTable->style()->subControlRect(QStyle::CC_ComboBox, &tempOpt, + QStyle::SC_ComboBoxArrow, m_pTable); + return subControlRect; + } + + // 带三点button + case esPlainEllipsis: + case esLineEllipsis: + { + QStyleOptionButton opt; + GLDStylePaintUtils::initPushButtonOpt(opt, rect, QString("...")); + return opt.rect; + } + + // 带上下箭头或者加减号button + case esUpDown: + { + QStyleOptionSpinBox opt; + GLDStylePaintUtils::initSpinBoxOpt(opt, rect); + opt.subControls &= ~QStyle::SC_SpinBoxFrame; + + QRect spinBoxUpRect = m_pTable->style()->subControlRect(QStyle::CC_SpinBox, &opt, + QStyle::SC_SpinBoxUp, + m_pTable); + return spinBoxUpRect; + } + + default: + return QRect(); + } +} + +bool GlodonDefaultItemDelegate::isInSubControlRect(QModelIndex index, QPoint pos) +{ + QRect oSubControlRect = editStyleRect(index, m_pTable->visualRect(index)); + + if (index.data(Qt::DecorationPropertyRole) == QStyleOptionViewItem::Right + && index.data(Qt::DecorationRole).isValid()) + { + int nWidth = oSubControlRect.width(); + oSubControlRect.setLeft(oSubControlRect.left() - nWidth); + oSubControlRect.setRight(oSubControlRect.right() - nWidth); + } + + return oSubControlRect.contains(pos); +} + +void GlodonDefaultItemDelegate::clickSubControl(QModelIndex index) +{ + QRect oEditStyleRect = editStyleRect(index, m_pTable->visualRect(index)); + + QWidget *pCurrentEditor = curEditor(); + if (GLDAbstractButtonEdit *pButtonEdit = + dynamic_cast(pCurrentEditor)) + { + pButtonEdit->onEllipsisButtonClicked(); + } + else if (pCurrentEditor != NULL) + { + QMouseEvent oMouseEvent( + QMouseEvent::MouseButtonPress, + curEditor()->mapFrom(m_pTable->viewport(), oEditStyleRect.center()), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + QApplication::sendEvent(curEditor(), &oMouseEvent); + } +} + +template +QVariant GlodonDefaultItemDelegate::compareDataByType(QVariant oldData, T newData) const +{ + if (oldData.value() == newData) + return oldData; + else + return newData; +} + +QVariant GlodonDefaultItemDelegate::compareDataByType(QVariant oldData, double newData) const +{ + if (sameValue(oldData.toDouble(), newData)) + return oldData; + else + return newData; +} + +void GlodonDefaultItemDelegate::doComboBoxActivated(int index) +{ + m_oComboBoxCurIndex = index; + try + { + QComboBox *pCombox = dynamic_cast(curEditor()); + if (pCombox) + { + m_bCanHideEidtOnExit = false; + itemViewSelected(pCombox, m_currTreeEditing, pCombox->view()->currentIndex()); + m_bCanHideEidtOnExit = true; + } + + m_bCanHideEidtOnExit = false; + emit onCommitDataAndCloseEditor(); + m_bCanHideEidtOnExit = true; + } + catch (...) + { + m_oComboBoxCurIndex = -1; + m_bCanHideEidtOnExit = true; + throw; + } + + m_oComboBoxCurIndex = -1; +} + +void GlodonDefaultItemDelegate::doDrawDisplay(QPainter *painter, const QStyleOptionViewItem &option, + const QRect &rect, const QString &text, const QModelIndex &index) const +{ + Q_D(const GlodonDefaultItemDelegate); + + QPalette::ColorGroup cg = (QStyle::State_Enabled == (option.state & QStyle::State_Enabled)) + ? QPalette::Normal : QPalette::Disabled; + + if (cg == QPalette::Normal && !(option.state & QStyle::State_Active)) + { + cg = QPalette::Inactive; + } + + if (QStyle::State_Selected == (option.state & QStyle::State_Selected)) + { + painter->fillRect(rect, option.palette.brush(cg, QPalette::Highlight)); + painter->setPen(option.palette.color(cg, QPalette::HighlightedText)); + } + else + { + painter->setPen(option.palette.color(cg, QPalette::Text)); + } + + if (text.isEmpty()) + { + return; + } + + if (QStyle::State_Editing == (option.state & QStyle::State_Editing)) + { + painter->save(); + painter->setPen(option.palette.color(cg, QPalette::Text)); + painter->drawRect(rect.adjusted(0, 0, -1, -1)); + painter->restore(); + } + + QVariant oTextMargin = index.data(gidrCellMargin); + + const int c_nTextHMargin = d->textHMargin(oTextMargin, option); + const int c_nTextVMargin = d->textVMargin(oTextMargin); + QRect textRect = rect.adjusted(c_nTextHMargin, c_nTextVMargin, -c_nTextHMargin, -c_nTextVMargin); + + const bool c_bWrapText = option.features & QStyleOptionViewItem::WrapText; + d->textOption.setWrapMode(c_bWrapText ? QTextOption::WrapAtWordBoundaryOrAnywhere : QTextOption::ManualWrap); + + if (d->textOption.wrapMode() != m_wrapMode) + { + d->textOption.setWrapMode(m_wrapMode); + } + + d->textOption.setTextDirection(option.direction); + d->textOption.setAlignment(QStyle::visualAlignment(option.direction, option.displayAlignment)); + d->textLayout.setTextOption(d->textOption); + d->textLayout.setFont(option.font); + d->textLayout.setText(d->replaceNewLine(text)); + + QSizeF textLayoutSize = d->doTextLayout(textRect.width()); + + if (textRect.width() < textLayoutSize.width() + || textRect.height() < textLayoutSize.height()) + { + QString strElided; + int nEnd = text.indexOf(QChar::LineFeed); + + if (nEnd == -1)// 没有换行符 + { + strElided = elidedTextWithoutLineFeed(textRect, text, option); + } + else + { + strElided = elidedTextWithLineFeed(textRect, text, option); + } + + d->textLayout.setText(strElided); + textLayoutSize = d->doTextLayout(textRect.width()); + } + + const QSize c_layoutSize(textRect.width(), int(textLayoutSize.height())); + const QRect c_layoutRect = QStyle::alignedRect(option.direction, option.displayAlignment, + c_layoutSize, textRect); + + // if we still overflow even after eliding the text, enable clipping + if (!hasClipping() && (textRect.width() < textLayoutSize.width() + || textRect.height() < textLayoutSize.height())) + { + painter->save(); + painter->setClipRect(c_layoutRect); + d->textLayout.draw(painter, c_layoutRect.topLeft(), QVector(), c_layoutRect); + painter->restore(); + } + else + { + d->textLayout.draw(painter, c_layoutRect.topLeft(), QVector(), c_layoutRect); + } +} + +void GlodonDefaultItemDelegate::drawDiagonal(QPainter *painter, const QRect &rect, const QModelIndex &index) const +{ + painter->save(); + QPen pen = painter->pen(); + painter->setRenderHint(QPainter::Antialiasing); + + int nDiagonal = index.data(gidrDiagonal).toInt(); + int nAntiDiagonal = index.data(gidrAntiDiagonal).toInt(); + + if (nDiagonal != 0) + { + pen.setWidth(nDiagonal); + painter->setPen(pen); + painter->drawLine(rect.left(), rect.top(), rect.right(), rect.bottom()); + } + + if (nAntiDiagonal != 0) + { + pen.setWidth(nAntiDiagonal); + painter->setPen(pen); + painter->drawLine(rect.left(), rect.bottom(), rect.right(), rect.top()); + } + + painter->restore(); +} + +QModelIndex GlodonDefaultItemDelegate::dataIndex(const QModelIndex &index) const +{ + const GlodonTreeModel *treeModel = dynamic_cast(index.model()); + + if (!treeModel) + { + return index; + } + + const QModelIndex c_treeIndex = treeModel->dataIndex(index); + + const GlodonGroupModel *groupModel = dynamic_cast(c_treeIndex.model()); + + if (groupModel) + { + return groupModel->dataIndex(c_treeIndex); + } + + return c_treeIndex; +} + +QModelIndex GlodonDefaultItemDelegate::treeIndex(const QModelIndex &) const +{ + return m_currTreeEditing; +} + +bool GlodonDefaultItemDelegate::editable(const QModelIndex &) const +{ + return true; +} + +GEditStyle GlodonDefaultItemDelegate::editStyle(const QModelIndex &, bool &) const +{ + return esSimple; +} + +GEditStyle GlodonDefaultItemDelegate::editStyleByVariantType(QVariant::Type vType) +{ + if (variantTypeIsDateTime(vType)) + { + return esMonthCalendar; + } + + switch (vType) + { + case QVariant::Bool: + return esBool; + + case QVariant::Image: + return esImage; + + case QVariant::Font: + return esFontList; + + case QVariant::Color: + return esColorList; + + default: + return esSimple; + } +} + +void GlodonDefaultItemDelegate::setIsTextEllipse(bool value) +{ + m_isTextEllipse = value; +} + +void GlodonDefaultItemDelegate::initEllipsisButtonEdit(GLDAbstractButtonEdit *ellipsis, const QModelIndex &index) const +{ + Q_UNUSED(ellipsis); + Q_UNUSED(index); +} + +void GlodonDefaultItemDelegate::initComboBox(QComboBox *comboBox, const QModelIndex &index) const +{ + Q_UNUSED(comboBox); + Q_UNUSED(index); +} + +void GlodonDefaultItemDelegate::initWindowComboBox(GLDWindowComboBoxEx *, const QModelIndex &) const +{ + +} + +void GlodonDefaultItemDelegate::initLineWidthComboBox(GLDLineWidthComboBoxEx *, const QModelIndex &) const +{ + +} + +void GlodonDefaultItemDelegate::initSpinBox(QAbstractSpinBox *spinBox, const QModelIndex &index) +{ + Q_UNUSED(spinBox); + Q_UNUSED(index); +} + +void GlodonDefaultItemDelegate::initDateTimeEdit(GLDDateTimeEdit *dateTimeEdit, const QModelIndex &index) +{ + Q_UNUSED(dateTimeEdit); + Q_UNUSED(index); +} + +void GlodonDefaultItemDelegate::itemViewSelected(QComboBox *, const QModelIndex &, const QModelIndex &) const +{ + +} + +QVariant GlodonDefaultItemDelegate::currentEditorData(const QModelIndex &index, QWidget *editor) +{ + if (!index.isValid() || editor == NULL) + { + return QVariant(); + } + + m_currTreeEditing = index; + + QModelIndex dIndex = dataIndex(index); + QVariant value = dIndex.model()->data(dIndex, Qt::EditRole); + QVariant::Type vType = value.type(); + + bool bReadOnly = false; + GEditStyle eEditStyle = editStyle(dIndex, bReadOnly); + + if (esSimple == eEditStyle) + { + eEditStyle = editStyleByVariantType(vType); + } + + switch (eEditStyle) + { + case esNone: + return QVariant(); + + case esLineEdit: + { + QLineEdit *edit = static_cast(editor); + return edit->text(); + } + + case esImage: + { + GImageEditor *imageEditor = static_cast(editor); + return imageEditor->image(); + } + + case esDropDown: + case esTreeView: + { + QComboBox *comboBox = static_cast(editor); + return comboBox->currentText(); + } + + // 修改计价提的BUG,新增可多行编辑的下拉框 + case esDropDownWindowEllipsis: + case esDropDownWindowNone: + case esDropDownWindow: + { + GLDWindowComboBoxEx *comboBox = static_cast(editor); + return comboBox->editText(); + } + + case esMonthCalendar: + { + GLDDateTimeEditEx *pDateTimeEditEx = static_cast(editor); + + if (QVariant::Time == vType) + { + return pDateTimeEditEx->time(); + } + else if (QVariant::Date == vType) + { + return pDateTimeEditEx->date(); + } + else + { + return pDateTimeEditEx->dateTime(); + } + } + + case esColorList: + { + GColorListEx *colorListEx = static_cast(editor); + return colorListEx->currentColor(); + } + + case esFontList: + { + GFontListEx *fontComboBox = static_cast(editor); + return fontComboBox->currentFont(); + } + + case esLineWidthList: + { + GLDLineWidthComboBoxEx *lineWidthComboBox = static_cast(editor); + return lineWidthComboBox->curLineWidth(); + } + + case esPlainEllipsis: + case esLineEllipsis: + { + GLDAbstractButtonEdit *ellipsis = static_cast(editor); + return ellipsis->text(); + } + + case esUpDown: + case esSimple: + { + if (variantTypeIsByte(vType) || variantTypeIsShort(vType) + || variantTypeIsInt(vType)) + { + GLDSpinBoxEx *pIntEdit = static_cast(editor); + return pIntEdit->value(); + } + else if (variantTypeIsFloat(vType)) + { + GLDDoubleSpinBoxEx *pDoubleEdit = static_cast(editor); + return pDoubleEdit->value(); + } + else if (QVariant::LongLong == vType) + { + QLineEdit *pLineEdit = static_cast(editor); + return pLineEdit->text().trimmed().toLongLong(); + } + break; + } + + default: + QPlainTextEdit *plainTextEdit = static_cast(editor); + QString str = plainTextEdit->toPlainText(); + + if (str.length() == 0) + { + return QVariant(); + } + + return str; + } + + return QVariant(); +} + +QRect GlodonDefaultItemDelegate::textLayoutBounds(const QStyleOptionViewItem &option) const +{ + QRect rect = option.rect; + const bool c_wrapText = (QStyleOptionViewItem::WrapText == (option.features & QStyleOptionViewItem::WrapText)); + + switch (option.decorationPosition) + { + case QStyleOptionViewItem::Left: + case QStyleOptionViewItem::Right: + { + rect.setWidth(c_wrapText && rect.isValid() ? rect.width() : (QFIXED_MAX)); + break; + } + + case QStyleOptionViewItem::Top: + case QStyleOptionViewItem::Bottom: + { + rect.setWidth(c_wrapText ? option.decorationSize.width() : (QFIXED_MAX)); + break; + } + } + + return rect; +} + +bool GlodonDefaultItemDelegate::isBoolCell(const QModelIndex &index) const +{ + return m_oDisplayData.type() == QVariant::Bool; + G_UNUSED(index); +} + +bool GlodonDefaultItemDelegate::eventFilter(QObject *object, QEvent *event) +{ + QWidget *pEditor = dynamic_cast(object); + if (!pEditor) + { + return false; + } + + switch (event->type()) + { + case QEvent::KeyPress: + return filterKeyPress(pEditor, event); + case QEvent::FocusOut: + case QEvent::Hide: + return dealWithLoseFocus(event, pEditor); + case QEvent::ShortcutOverride: + { + return dealWithShortCutOverride(event); + } + default: + return false; + } +} + +template +bool GlodonDefaultItemDelegate::commitIfCanElseSelectAll(QEvent *event, QWidget *editor, bool &state) +{ + T *pEditor = dynamic_cast(editor); + + state = false; + + if (!pEditor) + { + return false; + } + + state = true; + + if (commitDataAndCloseEditor(editor, SubmitModelCache)) + { + if (parent() && m_enterJump) //如果tableView是回车跳格,才发Enter时间,否则会再次进入编辑状态 + { + QApplication::sendEvent(parent(), event); + } + } + else + { + setTextAllSelected(pEditor); + } + + return true; + +} + +bool GlodonDefaultItemDelegate::setTextAllSelected(QWidget *editor) +{ + if (!editor || !editor->isVisible() || !editor->isActiveWindow()) + { + return false; + } + + if (QPlainTextEdit *plainTextEdit = dynamic_cast(editor)) + { + plainTextEdit->selectAll(); + } + else if (QSpinBox *pSpinBox = dynamic_cast(editor)) + { + pSpinBox->selectAll(); + } + else if (QDoubleSpinBox *pDoubleSpinBox = dynamic_cast(editor)) + { + pDoubleSpinBox->selectAll(); + } + else if (GLDAbstractButtonEdit *pbtnEdit = dynamic_cast(editor)) + { + //自写btnEdit类控件需要向其中的Edit发送全选命令 + return pbtnEdit->selectAll(); + } + else + { + //暂时未枚举类型,可能会向其发送Ctrl + A全选命令失败,导致tableView区域被全部选中!!! TODO + if (editor->hasFocus()) + { + Qt::KeyboardModifiers modifiers = (Qt::KeyboardModifiers)(Qt::CTRL); + QKeyEvent allSelectEvent = QKeyEvent(QEvent::KeyPress, Qt::Key_A, modifiers); + + return QApplication::sendEvent(editor, &allSelectEvent); + } + + return false; + } + + return true; +} + +bool GlodonDefaultItemDelegate::commitDataAndCloseEditor(QWidget *editor, GlodonDefaultItemDelegate::EndEditHint hint) +{ + if (m_inCommitData) + { + return false; + } + + bool bCanCloseEditor = true; + + try + { + emit commitData(editor, bCanCloseEditor); + + //emit commitData(editor); + if (bCanCloseEditor) + { + emit closeEditor(editor, bCanCloseEditor, hint); + } + + if (!bCanCloseEditor) + { + editor->setFocus(); + } + } + catch (...) + { + throw; + } + + m_inCommitData = false; + + return bCanCloseEditor; +} + +void GlodonDefaultItemDelegate::cursorMoveTextEndByEndKey(QWidget *editor) +{ + Qt::KeyboardModifiers modifiers = (Qt::KeyboardModifiers)(Qt::UNICODE_ACCEL); + QKeyEvent cursorToEnd = QKeyEvent(QEvent::KeyPress, Qt::Key_End, modifiers); + QCoreApplication::sendEvent(editor, &cursorToEnd); +} + +bool GlodonDefaultItemDelegate::cursorMoveTextEnd(QWidget *editor) +{ + if (GLDAbstractButtonEdit *pbtnEdit = dynamic_cast(editor)) + { + //自写btnEdit类控件需要向其中的Edit发送全选命令 + pbtnEdit->cursorMoveTextEnd(); + return true; + } + else if (dynamic_cast(editor) || dynamic_cast(editor)) + { + cursorMoveTextEndByEndKey(editor); + return true; + } + +#ifndef QT_NO_TEXTEDIT + QTextEdit *textEdit = NULL; + QPlainTextEdit *plainTextEdit = NULL; + + if ((textEdit = dynamic_cast(editor)) + || (plainTextEdit = dynamic_cast(editor))) + { + if (textEdit) + { + textEdit->moveCursor(QTextCursor::End); + + return true; + } + else if (plainTextEdit) + { + plainTextEdit->moveCursor(QTextCursor::End); + + return true; + } + } + + return false; + +#endif // QT_NO_TEXTEDIT + +#ifndef QT_NO_LINEEDIT + + if (QLineEdit *edit = dynamic_cast(editor)) + { + if (edit->hasAcceptableInput()) + { + return true; + } + } + + return false; + +#endif // QT_NO_LINEEDIT +} + +bool GlodonDefaultItemDelegate::cursorPosInsertANewLine(QWidget *editor) +{ +#ifndef QT_NO_TEXTEDIT + + QTextEdit *textEdit = NULL; + QPlainTextEdit *plainTextEdit = NULL; + GLDWindowComboBoxEx *mutilLineWindowComboBox = NULL; + + // 对不同的Edit控件进行判断,由于GLDWindowComboBoxEx是需要进行回车特殊操作的,因此在这里需要加上 + if ((textEdit = dynamic_cast(editor)) + || (mutilLineWindowComboBox = dynamic_cast(editor)) + || (plainTextEdit = dynamic_cast(editor))) + { + editor->removeEventFilter(this); + QKeyEvent keyEvent(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier); + QCoreApplication::sendEvent(editor, &keyEvent); + editor->installEventFilter(this); + + return true; + } + else + { + // 在不需要做特殊的回车处理的,就不需要发信号了,因此返回false + return false; + } + +#endif // QT_NO_TEXTEDIT + +#ifndef QT_NO_LINEEDIT + + if (QLineEdit *edit = dynamic_cast(editor)) + { + if (edit->hasAcceptableInput()) + { + return true; + } + } + +#endif // QT_NO_LINEEDIT + + return false; +} + +QStyleOptionViewItem GlodonDefaultItemDelegate::setOptions(const QModelIndex &index, + const QStyleOptionViewItem &option) const +{ + QStyleOptionViewItem opt = option; + + // set font + opt.font = zoomFont(index, opt.font, m_factor); + opt.fontMetrics = QFontMetrics(opt.font); + + // set text alignment + QVariant value = index.data(Qt::TextAlignmentRole); + + if (value.isValid()) + { + if ((value.toInt() & Qt::AlignHorizontal_Mask) == 0) + { + opt.displayAlignment &= ~Qt::AlignHorizontal_Mask; + + if (variantTypeIsNumeric(m_oDisplayData.type())) + { + opt.displayAlignment |= Qt::AlignRight; + } + else + { + opt.displayAlignment |= Qt::AlignLeft; + } + } + else + { + opt.displayAlignment = Qt::Alignment(value.toInt()); + } + } + + return opt; +} + +void GlodonDefaultItemDelegate::adjustDecorationAlignment(const QModelIndex &index, QStyleOptionViewItem &opt) const +{ + QVariant decorationAlignment = index.data(gidrDecorationAlignmentRole); + + if (!decorationAlignment.isValid() || decorationAlignment.isNull()) + { + return; + } + + const int nDecorationAlignment = decorationAlignment.toInt(); + + if (nDecorationAlignment == 0) + { + return; + } + + opt.decorationAlignment = Qt::Alignment(nDecorationAlignment); +} + +bool GlodonDefaultItemDelegate::filterRightKeyPress(QWidget *editor, QKeyEvent *keyEvent) +{ + bool bNoModifierPressed = keyEvent->modifiers().testFlag(Qt::NoModifier); + bool bShiftPressed = keyEvent->modifiers().testFlag(Qt::ShiftModifier); + bool bAltPressed = keyEvent->modifiers().testFlag(Qt::AltModifier); + bool bCtrlPressed = keyEvent->modifiers().testFlag(Qt::ControlModifier); + + if (bAltPressed) + { + keyEvent->accept(); + } + else if (bNoModifierPressed) + { + if (editor) + { + try + { + editor->removeEventFilter(this); + QCoreApplication::sendEvent(editor, keyEvent); + editor->installEventFilter(this); + } + catch (...) + { + editor->installEventFilter(this); + } + } + } + else if (bCtrlPressed || bShiftPressed) + { + editor->removeEventFilter(this); + QCoreApplication::sendEvent(editor, keyEvent); + editor->installEventFilter(this); + } + + return true; +} + +bool GlodonDefaultItemDelegate::filterUpKeyPress(QWidget *editor, QKeyEvent *keyEvent) +{ + bool bAltPressed = keyEvent->modifiers().testFlag(Qt::AltModifier); + bool bCtrlPressed = keyEvent->modifiers().testFlag(Qt::ControlModifier); + if (bAltPressed) + { + //GLDAbstractButton的处理放到该控件的内部 + if (QComboBox *comboBox = dynamic_cast(editor)) + { + comboBox->showPopup(); + } + else if (QDateTimeEdit *dateTime = dynamic_cast(editor)) + { + QMouseEvent *mouseEvent = new QMouseEvent(QEvent::MouseButtonPress, + QPointF(dateTime->width() - 10, dateTime->height() - 5), + Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + QApplication::sendEvent(dateTime, mouseEvent); + } + else if (GLDWindowComboBoxEx *comboBox = dynamic_cast(editor)) + { + comboBox->showPopup(); + } + + keyEvent->accept(); + return true; + } + + if (bCtrlPressed) + { + //do nothing + return true; + } + + try + { + bool bCanClose = commitDataAndCloseEditor(editor, SubmitModelCache); + if (bCanClose) + { + QApplication::sendEvent(m_pTable, keyEvent); + } + else + { + setTextAllSelected(editor); + } + } + catch (...) + { + setTextAllSelected(editor); + throw; + } + + return true; +} + +bool GlodonDefaultItemDelegate::dealWithLoseFocus(QEvent *event, QWidget *pEditor) +{ + if (event->type() == QEvent::Hide && !pEditor->isWindow()) + { + return false; + } + + //the Hide event will take care of he editors that are in fact complete dialogs + if ((QApplication::focusWidget() == pEditor) && pEditor->isActiveWindow()) + { + return false; + } + + QWidget *pFocusWidget = QApplication::focusWidget(); + while (pFocusWidget) + { + // don't worry about focus changes internally in the editor + if (pFocusWidget == pEditor) + { + return false; + } + pFocusWidget = pFocusWidget->parentWidget(); + } + + if (!m_bCloseEditorOnFocusOut || !m_bCanHideEidtOnExit) + { + return false; + } + + if (m_bRepeatCommit) + { + m_bRepeatCommit = false; + } + else + { + QFocusEvent *pFocusEvent = static_cast(event); + if (!pFocusEvent) + { + return false; + } + + if (m_bIgnoreActiveWindowFocusReason && pFocusEvent->reason() == Qt::ActiveWindowFocusReason) + { + return false; + } + + if (m_pTable->isVisible()) + { + return !commitDataAndCloseEditor(pEditor, NoHint); + } + } + + return false; +} + +bool GlodonDefaultItemDelegate::dealWithShortCutOverride(QEvent *event) +{ + if (static_cast(event)->key() == Qt::Key_Escape) + { + event->accept(); + return true; + } + else + { + return false; + } +} + +QRect GlodonDefaultItemDelegate::calcRectByData(const QStyleOptionViewItem &option, const QModelIndex &index, int role) const +{ + Q_D(const GlodonDefaultItemDelegate); + + QVariant value = index.data(role); + if (role == Qt::CheckStateRole) + return doCheck(option, option.rect, value); + + if (value.isValid() && !value.isNull()) + { + switch (value.type()) + { + case QVariant::Invalid: + break; + case QVariant::Pixmap: + { + const QPixmap &pixmap = qvariant_cast(value); + return QRect(QPoint(0, 0), pixmap.size() / pixmap.devicePixelRatio() ); + } + case QVariant::Image: + { + const QImage &image = qvariant_cast(value); + return QRect(QPoint(0, 0), image.size() / image.devicePixelRatio() ); + } + case QVariant::Icon: + { + QIcon::Mode mode = d->iconMode(option.state); + QIcon::State state = d->iconState(option.state); + QIcon icon = qvariant_cast(value); + QSize size = icon.actualSize(option.decorationSize, mode, state); + return QRect(QPoint(0, 0), size); + } + case QVariant::Color: + return QRect(QPoint(0, 0), option.decorationSize); + case QVariant::String: + default: + { + QString text = GlodonDefaultItemDelegatePrivate::valueToText(value); + value = index.data(Qt::FontRole); + QFont fnt = qvariant_cast(value).resolve(option.font); + return textRectangle(textLayoutBounds(option), fnt, text); + } + } + } + return QRect(); +} + +QRect GlodonDefaultItemDelegate::textRectangle(const QRect &rect, const QFont &font, const QString &text) const +{ + Q_D(const GlodonDefaultItemDelegate); + + d->textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); + d->textLayout.setTextOption(d->textOption); + d->textLayout.setFont(font); + d->textLayout.setText(GlodonDefaultItemDelegatePrivate::replaceNewLine(text)); + QSizeF fpSize = d->doTextLayout(rect.width()); + const QSize size = QSize(qCeil(fpSize.width()), qCeil(fpSize.height())); + return QRect(0, 0, size.width(), size.height()); +} + +void GlodonDefaultItemDelegate::innerDoLayout( + const QStyleOptionViewItem &option, QRect *checkRect, QRect *pixmapRect, QRect *textRect, + bool hint) const +{ + Q_ASSERT(checkRect && pixmapRect && textRect); + + Q_D(const GlodonDefaultItemDelegate); + + const QWidget *widget = d->widget(option); + QStyle *style = widget ? widget->style() : QApplication::style(); + const bool hasCheck = checkRect->isValid(); + const bool hasPixmap = pixmapRect->isValid(); + const bool hasText = textRect->isValid(); + const int pixmapMargin = hasPixmap ? style->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, widget) + 1 : 0; + const int checkMargin = hasCheck ? style->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, widget) + 1 : 0; + int x = option.rect.left(); + int y = option.rect.top(); + int w, h; + + if (textRect->height() == 0 && (!hasPixmap || !hint)) + { + //if there is no text, we still want to have a decent height for the item sizeHint and the editor size + textRect->setHeight(option.fontMetrics.height()); + } + + QSize pm(0, 0); + if (hasPixmap) + { + pm = pixmapRect->size(); + pm.rwidth() += 2 * pixmapMargin; + } + if (hint) + { + h = qMax(checkRect->height(), qMax(textRect->height(), pm.height())); + + if (option.decorationPosition == QStyleOptionViewItem::Left + || option.decorationPosition == QStyleOptionViewItem::Right) + { + w = textRect->width() + pm.width(); + } + else + { + w = qMax(textRect->width(), pm.width()); + } + } + else + { + w = option.rect.width(); + h = option.rect.height(); + } + + int cw = 0; + QRect check; + if (hasCheck) + { + cw = checkRect->width() + 2 * checkMargin; + if (hint) w += cw; + + if (option.direction == Qt::RightToLeft) + { + check.setRect(x + w - cw, y, cw, h); + } + else + { + check.setRect(x + checkMargin, y, cw, h); + } + } + + // at this point w should be the *total* width + + QRect display; + QRect decoration; + switch (option.decorationPosition) + { + case QStyleOptionViewItem::Top: + { + if (hasPixmap) + { + pm.setHeight(pm.height() + pixmapMargin); // add space + } + + h = hint ? textRect->height() : h - pm.height(); + + if (option.direction == Qt::RightToLeft) + { + decoration.setRect(x, y, w - cw, pm.height()); + display.setRect(x, y + pm.height(), w - cw, h); + } + else + { + decoration.setRect(x + cw, y, w - cw, pm.height()); + display.setRect(x + cw, y + pm.height(), w - cw, h); + } + break; + } + case QStyleOptionViewItem::Bottom: + { + if (hasText) + { + textRect->setHeight(textRect->height()); // add space + } + h = hint ? textRect->height() + pm.height() : h; + + if (option.direction == Qt::RightToLeft) + { + display.setRect(x, y, w - cw, textRect->height()); + decoration.setRect(x, y + textRect->height(), w - cw, h - textRect->height()); + } + else + { + display.setRect(x + cw, y, w - cw, textRect->height()); + decoration.setRect(x + cw, y + textRect->height(), w - cw, h - textRect->height()); + } + break; + } + case QStyleOptionViewItem::Left: + { + if (option.direction == Qt::LeftToRight) + { + decoration.setRect(x + cw, y, pm.width(), h); + display.setRect(decoration.right() + 1, y, w - pm.width() - cw, h); + } + else + { + display.setRect(x, y, w - pm.width() - cw, h); + decoration.setRect(display.right() + 1, y, pm.width(), h); + } + break; + } + case QStyleOptionViewItem::Right: + { + if (option.direction == Qt::LeftToRight) + { + display.setRect(x + cw, y, w - pm.width() - cw, h); + decoration.setRect(display.right() + 1, y, pm.width(), h); + } + else + { + decoration.setRect(x, y, pm.width(), h); + display.setRect(decoration.right() + 1, y, w - pm.width() - cw, h); + } + break; + } + default: + qWarning("doLayout: decoration position is invalid"); + decoration = *pixmapRect; + break; + } + + if (!hint) + { // we only need to do the internal layout if we are going to paint + *checkRect = QStyle::alignedRect(option.direction, Qt::AlignCenter, + checkRect->size(), check); + *pixmapRect = QStyle::alignedRect(option.direction, option.decorationAlignment, + pixmapRect->size(), decoration); + // the text takes up all available space, unless the decoration is not shown as selected + if (option.showDecorationSelected) + *textRect = display; + else + *textRect = QStyle::alignedRect(option.direction, option.displayAlignment, + textRect->size().boundedTo(display.size()), display); + } + else + { + *checkRect = check; + *pixmapRect = decoration; + *textRect = display; + } +} + +void GlodonDefaultItemDelegate::dealWithEscapeKeyPress(QWidget *editor) +{ + // don't commit data + bool bCanCloseEditor = true; + emit closeEditor(editor, bCanCloseEditor, GlodonDefaultItemDelegate::RevertModelCache); + + if (GLDTableView *pTable = dynamic_cast(parent())) + { + pTable->resetEnterJumpPreState(); + } +} + +bool GlodonDefaultItemDelegate::dealWithTabKeyPress(QWidget *editor) +{ + if (!commitDataAndCloseEditor(editor, EditNextItem)) + { + setTextAllSelected(editor); + } + return true; +} + +bool GlodonDefaultItemDelegate::dealWithBackTabPress(QWidget *editor) +{ + if (!commitDataAndCloseEditor(editor, EditPreviousItem)) + { + setTextAllSelected(editor); + } + return true; +} + +bool GlodonDefaultItemDelegate::filterKeyPress(QWidget *editor, QEvent *event) +{ + QKeyEvent *pKeyEvent = static_cast(event); + switch (pKeyEvent->key()) + { + case Qt::Key_Tab: + { + return dealWithTabKeyPress(editor); + } + case Qt::Key_Backtab: + { + return dealWithBackTabPress(editor); + } + case Qt::Key_Left: + case Qt::Key_Right: + { + return filterRightKeyPress(editor, pKeyEvent); + } + case Qt::Key_Down: + case Qt::Key_Up: + { + return filterUpKeyPress(editor, pKeyEvent); + } + case Qt::Key_Enter: + case Qt::Key_Return: + { + return filterReturnKeyPress(editor, pKeyEvent); + } + case Qt::Key_Escape: + { + dealWithEscapeKeyPress(editor); + break; + } + case Qt::Key_F2: + { + cursorMoveTextEnd(editor); + return true; + } + default: + return false; + } + + if (editor->parentWidget()) + { + editor->parentWidget()->setFocus(); + } + + return true; +} + +bool GlodonDefaultItemDelegate::filterReturnKeyPress(QWidget *editor, QKeyEvent *keyEvent) +{ + if (keyEvent) + { + bool bAltPressed = (Qt::ALT == (keyEvent->modifiers() & Qt::ALT)); + bool bControlPressed = (Qt::CTRL == (keyEvent->modifiers() & Qt::CTRL)); + + // 当有按下alt和ctrl时,需要对回车键做特殊处理 + if (bAltPressed || bControlPressed) + { + return cursorPosInsertANewLine(editor); + } + } + + m_closeEditEvent = keyEvent; + +#ifndef QT_NO_TEXTEDIT + bool bstopEventPassOn = false; + + if (commitIfCanElseSelectAll(keyEvent, editor, bstopEventPassOn)) + { + return bstopEventPassOn; + } + + if (commitIfCanElseSelectAll(keyEvent, editor, bstopEventPassOn)) + { + return bstopEventPassOn; + } + + if (commitIfCanElseSelectAll(keyEvent, editor, bstopEventPassOn)) + { + return bstopEventPassOn; + } + + if (commitIfCanElseSelectAll(keyEvent, editor, bstopEventPassOn)) + { + return bstopEventPassOn; + } + + if (commitIfCanElseSelectAll(keyEvent, editor, bstopEventPassOn)) + { + return bstopEventPassOn; + } + + if (commitIfCanElseSelectAll(keyEvent, editor, bstopEventPassOn)) + { + return bstopEventPassOn; + } + + if (commitIfCanElseSelectAll(keyEvent, editor, bstopEventPassOn)) + { + return bstopEventPassOn; + } + + if (commitIfCanElseSelectAll(keyEvent, editor, bstopEventPassOn)) + { + return bstopEventPassOn; + } + + if (dynamic_cast(editor)) + { + return false; // don't filter enter key events for QTextEdit + } + + // We want the editor to be able to process the key press + // before committing the data (e.g. so it can do + // validation/fixup of the input). +#endif // QT_NO_TEXTEDIT +#ifndef QT_NO_LINEEDIT + + if (QLineEdit *pEdit = dynamic_cast(editor)) + if (!pEdit->hasAcceptableInput()) + { + return false; + } + +#endif // QT_NO_LINEEDIT + // QMetaObject::invokeMethod(this, "_q_commitDataAndCloseEditor", + // Qt::QueuedConnection, Q_ARG(QWidget*, editor)); + // return false; + return !commitDataAndCloseEditor(editor, SubmitModelCache); +} + +void GlodonDefaultItemDelegate::paintOther(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + Q_D(const GlodonDefaultItemDelegate); + Q_ASSERT(index.isValid()); + + //TODO + QStyleOptionViewItem opt = setOptions(index, option); + + // prepare + painter->save(); + + if (hasClipping()) + { + painter->setClipRect(opt.rect); + } + + // get the data and the rectangles + QPixmap pixmap; + QRect decorationRect; + QVariant value = index.data(Qt::DecorationRole); + + if (value.isValid()) + { + // ### we need the pixmap to call the virtual function + pixmap = decoration(opt, value); + opt.decorationPosition = (QStyleOptionViewItem::Position)index.data(Qt::DecorationPropertyRole).toInt(); + adjustDecorationAlignment(index, opt); + + if (value.type() == QVariant::Icon) + { + d->tmp.icon = qvariant_cast(value); + d->tmp.mode = d->iconMode(option.state); + d->tmp.state = d->iconState(option.state); + const QSize c_size = d->tmp.icon.actualSize(option.decorationSize, + d->tmp.mode, d->tmp.state); + decorationRect = QRect(QPoint(0, 0), c_size); + } + else + { + d->tmp.icon = QIcon(); + decorationRect = QRect(QPoint(0, 0), pixmap.size()); + } + } + else + { + d->tmp.icon = QIcon(); + decorationRect = QRect(); + } + + + QString text; + QRect displayRect; + if (m_oDisplayData.isValid() && !m_oDisplayData.isNull()) + { + text = GlodonDefaultItemDelegatePrivate::valueToText(m_oDisplayData); + displayRect = textRectangle(textLayoutBounds(opt), opt.font, text); + } + + QRect checkRect; + Qt::CheckState checkState = Qt::Unchecked; + value = index.data(Qt::CheckStateRole); + + if (value.isValid()) + { + checkState = static_cast(value.toInt()); + checkRect = doCheck(opt, opt.rect, value); + } + + innerDoLayout(opt, &checkRect, &decorationRect, &displayRect, false); + + // draw the item + drawBackground(painter, opt, index); + + drawEditStyleDraw(painter, opt, displayRect); // GLD + + drawCheck(painter, opt, checkRect, checkState); + drawDecoration(painter, opt, decorationRect, pixmap); + + drawDiagonal(painter, displayRect, index); // GLD + + drawDisplay(painter, opt, displayRect, text, index); + drawFocus(painter, opt, displayRect); + + // done + painter->restore(); +} + +QSizeF GlodonDefaultItemDelegatePrivate::doTextLayout(int lineWidth) const +{ + Q_Q(const GlodonDefaultItemDelegate); + qreal height = 0; + qreal widthUsed = 0; + textLayout.beginLayout(); + + while (true) + { + QTextLine line = textLayout.createLine(); + + if (!line.isValid()) + { + break; + } + + line.setLineWidth(lineWidth); + line.setPosition(QPointF(0, height)); + + height += line.height(); + + if (q->isIncludeLeading()) + { + if (false == line.leadingIncluded()) + { + line.setLeadingIncluded(true); + height += line.leading(); + } + } + + widthUsed = qMax(widthUsed, line.naturalTextWidth());// TODO line.naturalLineWidth() > widthUsed + } + + textLayout.endLayout(); + + return QSizeF(widthUsed, height); +} + +QString GlodonDefaultItemDelegatePrivate::valueToText(const QVariant &value) +{ + QString text = value.toString(); + + if (value.type() == QVariant::Time) + { + QTime time = value.value(); + text = time.toString("hh:mm:ss"); + } + else if (value.type() == QVariant::Date) + { + QDate date = value.value(); + text = date.toString("yyyy-MM-dd"); + } + else if (value.type() == QVariant::DateTime) + { + QDateTime datetime = value.value(); + text = datetime.toString("yyyy-MM-dd"); + } + else if (value.isNull() && (variantTypeIsByte(value.type()) || variantTypeIsShort(value.type()) + || variantTypeIsInt(value.type()) || variantTypeIsFloat(value.type()))) + { + text = ""; + } + + return text; +} + +bool GlodonDefaultItemDelegate::isEditing() +{ + return curEditor() != NULL; +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDefaultItemDelegateFactory.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDefaultItemDelegateFactory.cpp new file mode 100644 index 00000000..ac11f65e --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDefaultItemDelegateFactory.cpp @@ -0,0 +1,11 @@ +#include "GLDDefaultItemDelegateFactory.h" + +GlodonDefaultItemDelegateFactory::GlodonDefaultItemDelegateFactory(/*QObject *parent*/) //: +// QObject(parent) +{ +} + +GlodonDefaultItemDelegateFactory::~GlodonDefaultItemDelegateFactory() +{ + +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDocView.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDocView.cpp new file mode 100644 index 00000000..dc602799 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDocView.cpp @@ -0,0 +1,2645 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "GLDPaperWidget.h" +#include "GLDMultiHeaderView.h" +#include "GLDDocView.h" +#include "GLDPaperTableView.h" + +const GString c_GLDDocView_HHeader = "GLDDocView_HHeader"; + +/* GLDDocInfo */ +int GLDDocInfo::pageOf(int nValue) +{ + if(nValue < 0) + { + return -1; + } + + const int nPageGeoCount = pageGeometryInfoList.count(); + + if(nPageGeoCount == 0) + { + return -1; + } + + if (nValue > pageGeometryInfoList[nPageGeoCount - 1].bottom() + nPageSplitterHeight) + { + return -1; + } + + for (int i = 0; i < nPageGeoCount; ++i) + { + const QRect pageGeometryInfo = pageGeometryInfoList.at(i); + + if ((nValue >= pageGeometryInfo.top() - nPageSplitterHeight) && ((nValue < pageGeometryInfo.bottom()))) + { + return i; + } + } + + return nPageGeoCount - 1; +} + +GIntList GLDDocInfo::pageOf(int nValue, const QRect &rc) +{ + GIntList pageInRect; + + const int nCurPage = pageOf(nValue); + + if (nCurPage < 0) + { + return pageInRect; + } + + const int visableAreaHScrollPos = rc.top() + nValue; + + QRect nextVisibleAreaRc(0, visableAreaHScrollPos, 20000, rc.height()); + + for (int i = (nCurPage - 8 > 0) ? nCurPage - 8 : 0; (i < (nCurPage + 8)); ++i) + { + if(i >= pageGeometryInfoList.count()) + { + break; + } + + if (nextVisibleAreaRc.intersects(pageGeometryInfoList[i])) + { + pageInRect.push_back(i); + } + } + + return pageInRect; +} + +/* GLDScrollArea */ +GLDScrollArea::GLDScrollArea(GLDDocView *parent): + QScrollArea(parent), m_parent(parent) +{ + +} + +bool GLDScrollArea::event(QEvent *e) +{ + // 不调用基类 + return QAbstractScrollArea::event(e); +} + +bool GLDScrollArea::eventFilter(QObject *o, QEvent *e) +{ + // 不调用基类 + return QAbstractScrollArea::eventFilter(o, e); +} + +void GLDScrollArea::resizeEvent(QResizeEvent *) +{ + // 不调用基类 +} + +void GLDScrollArea::wheelEvent(QWheelEvent *event) +{ + QScrollArea::wheelEvent(event); + m_parent->wheelEvent(event); +} + +/* GLDDocView */ +void GLDDocView::initScrollArea() +{ + QPalette palette; + palette.setColor(QPalette::Background, QColor(180, 180, 180)); + + m_scrollArea->setAutoFillBackground(true); + m_scrollArea->setPalette(palette); + m_scrollArea->setContentsMargins(0, 0, 0, 0); + m_scrollArea->setAlignment(Qt::AlignHCenter); + m_scrollArea->setUpdatesEnabled(true); + m_scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + m_scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); + m_scrollArea->installEventFilter(this); + m_scrollArea->verticalScrollBar()->setFocusProxy(m_scrollArea); + m_scrollArea->horizontalScrollBar()->setFocusProxy(m_scrollArea); + setFocusProxy(m_scrollArea); + + connect(m_scrollArea->verticalScrollBar(), SIGNAL(valueChanged(int)), + this, SLOT(verticalScrollBarValueChanged(int))); + connect(m_scrollArea->horizontalScrollBar(), SIGNAL(valueChanged(int)), + this, SLOT(horizontalScrollBarValueChanged(int))); + + QHBoxLayout *layout = new QHBoxLayout(); + layout->setContentsMargins(0, 0, 0, 0); + layout->addWidget(m_scrollArea); + setLayout(layout); +} + +void GLDDocView::initPageGeometry() +{ + m_nInitMaxPageNo = 16; + + m_nInitPageLabelFontSize = 10; + + m_nCurrentDPI = logicalDpiX(); + + // 以下计算数字单位为毫米 + m_dInitPageWidth = POINT_NUMBER_FROM_MM(210, m_nCurrentDPI); + m_dInitPageHeight = POINT_NUMBER_FROM_MM(297, m_nCurrentDPI); + + m_dInitHeaderHeight = POINT_NUMBER_FROM_MM(31.8, m_nCurrentDPI); + m_dInitFooterHeight = POINT_NUMBER_FROM_MM(31.8, m_nCurrentDPI); + + m_dInitLeftMargin = POINT_NUMBER_FROM_MM(19.1, m_nCurrentDPI); + m_dInitRightMargin = POINT_NUMBER_FROM_MM(19.1, m_nCurrentDPI); + + m_nInitPageSplitterHeight = POINT_NUMBER_FROM_MM(2, m_nCurrentDPI); + m_nInitTableViewHHeaderHeight = POINT_NUMBER_FROM_MM(10, m_nCurrentDPI); + + m_nPageWidth = m_dInitPageWidth; + m_nPageHeight = m_dInitPageHeight; + + m_nHeaderHeight = m_dInitHeaderHeight; + m_nFooterHeight = m_dInitFooterHeight; + + m_nLeftMargin = m_dInitLeftMargin; + m_nRightMargin = m_dInitRightMargin; + + m_nPageSplitterHeight = m_nInitPageSplitterHeight; + m_nTableViewHHeaderHeight = m_nInitTableViewHHeaderHeight; +} + + + +GLDDocView::GLDDocView(QWidget *parent, Qt::WindowFlags f): + QWidget(parent, f), + m_allowToResize(false), + m_allowZoom(false), + m_isHorizontalMutilHeaderView(false), + m_isInClearOtherIndex(false), + m_isInManualControlScrollBar(false), + m_suitRowHeight(false), + m_headerAndFooterWidgetFactory(NULL), + m_tableViewFactory(NULL), + m_delegateFactory(NULL), + m_resizeMode(GlodonHeaderView::Fixed), + m_treeModel(NULL), + m_nCellHeight(30), + m_nCurPageNo(0), + m_nCurrentDPI(0), + m_nSettedWidthsSum(0), + m_dataModel(NULL), + m_model(NULL), + m_scrollArea(new GLDScrollArea(this)), + m_zoomFactor(percent_100), + m_bDrawFrameLine(true), + m_bShowHHeaderView(true), + m_bHorzLine(true), + m_bVertLine(true), + m_nGridLineWidth(1), + m_printerOrientation(QPrinter::Portrait) +{ + initPageGeometry(); + + setContentsMargins(0, 0, 0, 0); + + initScrollArea(); +} + +GLDDocView::~GLDDocView() +{ + freeAndNil(m_headerAndFooterWidgetFactory); + freeAndNil(m_delegateFactory); + freeAndNil(m_tableViewFactory); +} + +GLDPaperWidget *GLDDocView::newPaper(int nPageNo) +{ + return new GLDPaperWidget(this, + nPageNo, + m_docInfo.nPageCount, + m_resizeMode, + m_tableViewFactory, + m_scrollArea->viewport()); +} + +GLDPaperWidget *GLDDocView::findPaper(QModelIndex &tableViewIndex) +{ + QAbstractItemModel *model = const_cast(tableViewIndex.model()); + + GLDPaperWidgetModel *pModel = NULL; + + if ((pModel = dynamic_cast(model)) != NULL) + { + return findPaper(pModel->curPageNo()); + } + + return NULL; +} + +void GLDDocView::removePaper(int nPageNo) +{ + int nIndex = indexPaper(nPageNo); + + if (nIndex >= 0) + { + GLDPaperWidget *paper = m_papers[nIndex]; + m_papers.removeAt(nIndex); + freeAndNil(paper); + } +} + +void GLDDocView::clearPagers() +{ + for (int i = 0; i < m_papers.count(); ++i) + { + GLDPaperWidget *paper = m_papers[i]; + freeAndNil(paper); + } + + m_papers.clear(); +} + +bool GLDDocView::paperVisible(int nPageNo) +{ + for (int i = 0; i < m_visiblePageNoList.count(); ++i) + { + if (m_visiblePageNoList[i] == nPageNo) + { + return true; + } + } + + return false; +} + +// 布局显示页面 +int GLDDocView::updateLeftLayout(int nHpos, const QRect &rc, GLDPaperWidget *pPaperWidget) +{ + int nPosX = rc.left() + rc.width() / 2 - pPaperWidget->width() - m_nPageSplitterHeight - nHpos; + + if (nPosX < 0) + { + nPosX = -nHpos; + m_scrollArea->horizontalScrollBar()->setRange(0, pPaperWidget->width() * 2 - rc.width()); + m_scrollArea->horizontalScrollBar()->setPageStep(rc.width()); + } + else + { + m_scrollArea->horizontalScrollBar()->setRange(0, 0); + m_scrollArea->horizontalScrollBar()->setPageStep(rc.width()); + } + + return nPosX; +} + +int GLDDocView::updateRightLayout(int nHpos, const QRect &rc, GLDPaperWidget *pPaperWidget) +{ + int nPosX = rc.left() + rc.width() / 2 - pPaperWidget->width() - m_nPageSplitterHeight - nHpos; + + if (nPosX < 0) + { + nPosX = -nHpos + m_nPageSplitterHeight + pPaperWidget->width(); + } + else + { + nPosX = nPosX + m_nPageSplitterHeight + pPaperWidget->width(); + } + + return nPosX; +} + +int GLDDocView::updatePageLayout(int nHpos, const QRect &rc, GLDPaperWidget *pPaperWidget) +{ + int nPosX = rc.left() + rc.width() / 2 - pPaperWidget->width() / 2 - nHpos; + + if (nPosX < 0) + { + nPosX = -nHpos; + m_scrollArea->horizontalScrollBar()->setRange(0, pPaperWidget->width() - rc.width()); + m_scrollArea->horizontalScrollBar()->setPageStep(rc.width()); + } + else + { + m_scrollArea->horizontalScrollBar()->setRange(0, 0); + m_scrollArea->horizontalScrollBar()->setPageStep(rc.width()); + } + + return nPosX; +} + +void GLDDocView::updatePaperLayout(int nVpos, int nHpos, const QRect &rc) +{ + for (int i = 0; i < m_visiblePageNoList.count(); ++i) + { + GLDPaperWidget *pPaperWidget = findPaper(m_visiblePageNoList[i]); + + int nPosX = 0; + int nPosY = 0; + + if (m_zoomFactor == percent_50) + { + if (i % 2 == 0) // 左边 + { + nPosX = updateLeftLayout(nHpos, rc, pPaperWidget); + } + else // 右边 + { + nPosX = updateRightLayout(nHpos, rc, pPaperWidget); + } + } + else + { + nPosX = updatePageLayout(nHpos, rc, pPaperWidget); + } + + nPosY = m_docInfo.pageGeometryInfoList[m_visiblePageNoList[i]].top() - nVpos; + pPaperWidget->move(nPosX, nPosY); + + pPaperWidget->setVisible(true); + } +} + +void GLDDocView::updateFocusWidget() +{ + if (GLDPaperWidget *pPaperWidget = findPaper(m_nCurFocusPageNo)) + { + GlodonTableView *pTableView = pPaperWidget->tableView(); + + if ((NULL != pTableView) && (pTableView->isEditing())) + { + GlodonDefaultItemDelegate *pItemDelegate = NULL; + + pItemDelegate = dynamic_cast(pTableView->itemDelegate()); + + if ((NULL != pItemDelegate) && (NULL != pItemDelegate->curEditor())) + { + pItemDelegate->curEditor()->setFocus(); + } + } + } +} + +void GLDDocView::setColumnHidden(int column, bool hide) +{ + this->columnsVisableMap[column] = hide; + + for (int i = 0; i < m_papers.count(); ++i) + { + GlodonTableView *pTableView = m_papers[i]->tableView(); + pTableView->setColumnHidden(column, hide); + } +} + +bool GLDDocView::columnHidden(int column) const +{ + return columnsVisableMap[column]; +} + +bool GLDDocView::hasColumnHidden() const +{ + return !columnsVisableMap.empty(); +} + +QMap &GLDDocView::columnsVisableState() +{ + return columnsVisableMap; +} + +bool GLDDocView::isPaperCacheFull() +{ + return m_papers.count() + m_visiblePageNoList.count() > m_nInitMaxPageNo; +} + + + + + +void GLDDocView::clearPaperCache() +{ + for (int i = 0; i < 4; ++i) + { + GLDPaperWidget *paper = m_papers.dequeue(); + freeAndNil(paper); + } +} + +void GLDDocView::hidePapersOutOfView() +{ + for (int i = 0; i < m_papers.count(); ++i) + { + if (!paperVisible(m_papers[i]->curPageNo())) + { + GLDPaperWidget *paper = m_papers[i]; + + if (paper) + { + paper->move(0, -2000);//->setVisible(false); + } + } + } +} + +void GLDDocView::cacheNewPapers() +{ + for (int i = 0; i < m_visiblePageNoList.count(); ++i) + { + int nPageNo = m_visiblePageNoList[i]; + int nIndex = indexPaper(nPageNo); + + if (nIndex < 0) + { + m_papers.insert(nPageNo, newPaper(nPageNo));; + } + else + { + // 根据最近显示页面调整位置 + GLDPaperWidget *paper = m_papers[nIndex]; + m_papers.takeAt(nIndex); + m_papers.append(paper); + } + } +} + +void GLDDocView::updateVisablePapersList() +{ + const QRect scrollAreaRect = m_scrollArea->rect(); + int verticalScrollBarPos = m_scrollArea->verticalScrollBar()->value(); + m_visiblePageNoList = m_docInfo.pageOf(verticalScrollBarPos, scrollAreaRect); + + //如果当前只有一页,数据刚好占满,插入一行,需要先把新分的页创建出来,再定位焦点,调整滚动条位置 + bool b1 = m_docInfo.nPageCount > m_docFocusInfo.nFocusPageNo; + bool b2 = m_docFocusInfo.nFocusPageNo > 0; + bool b3 = m_visiblePageNoList.contains(m_docFocusInfo.nFocusPageNo); + bool b4 = m_visiblePageNoList.count() + 1 <= m_docInfo.nPageCount; + + if (b1 && b2 && !b3 && b4) + { + m_visiblePageNoList.push_back(m_docFocusInfo.nFocusPageNo); + } +} + +void GLDDocView::updateScrollArea() +{ + const int vValue = m_scrollArea->verticalScrollBar()->value(); + const int hValue = m_scrollArea->horizontalScrollBar()->value(); + const QRect scrollAreaRect = m_scrollArea->rect(); + updatePaperLayout(vValue, hValue, scrollAreaRect); + + updateFocusWidget(); +} + +void GLDDocView::updatePapers() +{ + // 刷新可见页面列表 + updateVisablePapersList(); + + // 如果缓存已满,则清空 + if (isPaperCacheFull()) + { + clearPaperCache(); + } + + // 从可见列表创建新页面并加入缓存 + cacheNewPapers(); + + // 隐藏不在视图内的页面 + hidePapersOutOfView(); + + // 滚动显示页面 + updateScrollArea(); +} + +int GLDDocView::rowPosition(QModelIndex dataIndex) +{ + return verticalPosition(index(dataIndex)); +} + +int GLDDocView::columnPosition(QModelIndex dataIndex) +{ + return horizontalPosition(index(dataIndex)); +} + +QRect GLDDocView::visualRect(const QModelIndex dataIndex) +{ + QModelIndex tableViewIndex = index(dataIndex); + + int nCurPaperNo = curPageNo(tableViewIndex); + + GLDPaperWidget *curPaperWidget = findPaper(nCurPaperNo, true); + + GlodonTableView *curPaperTableView = curPaperWidget->tableView(); + + QRect tableViewRect = curPaperTableView->visualRect(tableViewIndex); + + const int nLeft = tableViewRect.left(); + const int nTop = tableViewRect.top() + curPaperTableView->horizontalHeader()->height(); + const int nWidth = tableViewRect.width(); + const int nHeight = tableViewRect.height(); + QRect tableViewAndHeaderViewRect(nLeft, nTop, nWidth, nHeight); + + QPoint globalTopLeft = curPaperTableView->mapToGlobal(tableViewAndHeaderViewRect.topLeft()); + + const int nX = globalTopLeft.x(); + const int nY = globalTopLeft.y(); + const int width = tableViewAndHeaderViewRect.width(); + const int height = tableViewAndHeaderViewRect.height(); + + return QRect(nX, nY, width, height); +} + +void GLDDocView::scrollTo(QModelIndex dataIndex, ScrollHint hint) +{ + if (!dataIndex.isValid()) + { + return; + } + + GLDPaperWidget *pScrollToPage = findPaper(dataIndexPageNo(dataIndex), true); + + if (NULL == pScrollToPage) + { + return; + } + + // todo liurx 竖直方向暂时没有处理 + QModelIndex destTableViewIndex = index(dataIndex); + int nDestPosition = verticalPosition(destTableViewIndex); + + try + { + m_isInManualControlScrollBar = true; + clearOtherIndex(); + setCurrentIndex(dataIndex); + m_scrollArea->verticalScrollBar()->setValue(nDestPosition); + m_isInManualControlScrollBar = false; + } + catch (...) + { + m_isInManualControlScrollBar = false; + } + + G_UNUSED(hint) +} + +QQueue &GLDDocView::paperWidgetList() +{ + return m_papers; +} + +QModelIndexList GLDDocView::selectedIndexes() +{ + GLDPaperWidget *paperWidget = findPaper(m_nCurFocusPageNo); + + if (paperWidget != NULL) + { + QModelIndexList modelIndexList = paperWidget->tableView()->selectedIndexes(); + QModelIndexList result; + + for (int i = 0; i < modelIndexList.count(); ++i) + { + result.append(dataIndex(m_nCurFocusPageNo, modelIndexList.at(i))); + } + + return result; + } + + return QModelIndexList(); +} + +void GLDDocView::verticalScrollBarValueChanged(int value) +{ + updatePapers(); + + // 计算当前页码 + if (m_zoomFactor == percent_50) + { + m_nCurPageNo = 2 * qRound((float)value / (m_nPageHeight + m_nPageSplitterHeight)); + } + else + { + m_nCurPageNo = qRound((float)value / (m_nPageHeight + m_nPageSplitterHeight)); + } + + emit currPageChanged(m_nCurPageNo); +} + +void GLDDocView::horizontalScrollBarValueChanged(int value) +{ + const int nOffSet = m_scrollArea->verticalScrollBar()->value(); + const QRect scrollAreaRect = m_scrollArea->rect(); + updatePaperLayout(nOffSet, value, scrollAreaRect); + + updateFocusWidget(); +} + +void GLDDocView::printDocument(QPrinter *printer) +{ + QPainter painter; + + if (!painter.begin(printer)) + { + return; + } + + const int nFromPage = printer->fromPage(); + const int nToPage = printer->toPage(); + + QProgressDialog progress(this); + progress.setWindowModality(Qt::ApplicationModal); + progress.setMinimum(nFromPage - 1); + progress.setMaximum(nToPage); + + bool firstPage = true; + + for (int page = nFromPage; page <= nToPage; ++page) + { + + if (!firstPage) + { + printer->newPage(); + } + + qApp->processEvents(); + + if (progress.wasCanceled()) + { + break; + } + + printPage(page - 1, painter, printer); + progress.setValue(page); + firstPage = false; + } + + painter.end(); +} + +void GLDDocView::printDocument(QPrinter *printer, QPrintDialog *printDialog) +{ + int fromPage = printDialog->fromPage(); + int toPage = printDialog->toPage(); + + if (fromPage > toPage) + { + return; + } + + QAbstractPrintDialog::PrintRange printRange = printDialog->printRange(); + + switch (printRange) + { + case QAbstractPrintDialog::AllPages: + { + printer->setFromTo(1, m_docInfo.nPageCount); + break; + }; + + case QAbstractPrintDialog::PageRange: + { + if (fromPage <= 0) + { + fromPage = 1; + } + + if (toPage > m_docInfo.nPageCount) + { + toPage = m_docInfo.nPageCount; + } + + printer->setFromTo(fromPage, toPage); + break; + }; + + case QAbstractPrintDialog::CurrentPage: + { + printer->setFromTo(m_nCurFocusPageNo, m_nCurFocusPageNo); + break; + }; + + default: + break; + } + + printDocument(printer); +} + +void GLDDocView::printPage(int index, QPainter &painter, QPrinter *printer) +{ + GLDPaperWidget *paper = newPaper(index); + QPixmap image = QPixmap::grabWidget(paper, 0, 0, paper->width(), paper->height()); + QRect rect = printer->paperRect(); + painter.drawPixmap(rect, image); + freeAndNil(paper); +} + +void GLDDocView::printPage(int index, QPainter &painter) +{ + GLDPaperWidget *paper = newPaper(index); + QPixmap image = QPixmap::grabWidget(paper, 0, 0, paper->width(), paper->height()); + QRect rect = painter.viewport(); + QSize size = image.size(); + size.scale(rect.size(), Qt::KeepAspectRatio); // 此处保证图片显示完整 + painter.setViewport(rect.x(), rect.y(), size.width(), size.height()); + painter.setWindow(image.rect()); + painter.drawPixmap(0, 0, image); + freeAndNil(paper); +} + +void GLDDocView::printALLDocument(QPrinter *printer) +{ + QPainter painter(printer); + + for (int i = 0; i < m_docInfo.nPageCount; ++i) + { + if (i > 0) + { + printer->newPage(); + } + + printPage(i, painter); + } +} + +void GLDDocView::setModel(QAbstractItemModel *model) +{ + if (model == m_dataModel) + { + return; + } + else + { + freeAndNil(m_dataModel); + m_dataModel = model; + } + + freeAndNil(m_treeModel); + m_treeModel = new GlodonTreeModel(m_dataModel, this); + m_treeModel->setObjectName("m_treeModel"); + + GlodonTreeDrawInfo *pDrawInfo = new GlodonTreeDrawInfo(this); + pDrawInfo->setModel(m_dataModel); + m_treeModel->drawInfo = pDrawInfo; + + freeAndNil(m_model); + m_model = m_treeModel; + + connect(m_dataModel, SIGNAL(modelReset()), this, SLOT(calculatePages()), Qt::QueuedConnection); + connect(m_dataModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SLOT(calculatePages()), Qt::QueuedConnection); + connect(m_dataModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SLOT(calculatePages()), Qt::QueuedConnection); + connect(m_dataModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(dataChanged(QModelIndex, QModelIndex))); + + if (m_colWidth.count() > m_model->columnCount()) + { + bool bChanged = false; + + for (int i = m_colWidth.count() - 1; i >= m_model->columnCount(); --i) + { + m_colWidth.remove(i); + bChanged = true; + } + + if (bChanged) + { + m_nSettedWidthsSum = 0; + } + } + + // calculatePages(); +} + +QAbstractItemModel *GLDDocView::dataModel() +{ + return m_dataModel; +} + +void GLDDocView::print() +{ + if (this->pageCount() <= 0) + { + return; + } + + QPrinter printer(QPrinter::HighResolution); + printer.setOrientation(m_printerOrientation); + printer.setOutputFormat(QPrinter::NativeFormat); + printer.setPageMargins(0, 0, 0, 0, QPrinter::Millimeter); + + QPrintDialog printDlg(&printer, this); + + if (printDlg.exec() != QDialog::Accepted) + { + return; + } + + printDocument(&printer, &printDlg); +} + +void GLDDocView::printPreview() +{ + QPrinter printer(QPrinter::HighResolution); + printer.setOutputFormat(QPrinter::PdfFormat); + printer.setOrientation(m_printerOrientation); + + QPrintPreviewDialog preview(&printer, this); + connect(&preview, SIGNAL(paintRequested(QPrinter *)), this, SLOT(printALLDocument(QPrinter *))); + + if (m_zoomFactor == percent_400) + { + preview.setMinimumSize(QSize(1200, 800)); + } + else + { + preview.setMinimumSize(m_papers[0]->size()); + } + + preview.exec(); +} + +void GLDDocView::exportToPdf() +{ + printPreview(); +} + +void GLDDocView::exportToPdf(QString fileName) +{ + QPrinter printer(QPrinter::HighResolution); + printer.setOutputFormat(QPrinter::PdfFormat); + printer.setOrientation(m_printerOrientation); + + printer.setOutputFileName(fileName); + QPainter painter; + + painter.begin(&printer); + + for (int i = 0; i < m_docInfo.nPageCount; ++i) + { + if (i > 0) + { + printer.newPage(); + } + + printPage(i, painter); + } + + painter.end(); +} + +void GLDDocView::fistPage() +{ + if (m_nCurPageNo == 0) + { + return; + } + + gotoPage(0); + m_nCurPageNo = 0; +} + +void GLDDocView::lastPage() +{ + if (m_nCurPageNo == pageCount() - 1) + { + return; + } + + gotoPage(pageCount() - 1); + m_nCurPageNo = pageCount() - 1; +} + +void GLDDocView::prevPage() +{ + int nGotoPage = m_nCurPageNo; + + if (m_zoomFactor == percent_50) + { + if (nGotoPage <= 1) + { + return; + } + + nGotoPage -= 2; + } + else + { + if (nGotoPage == 0) + { + return; + } + + nGotoPage -= 1; + } + + gotoPage(nGotoPage); + m_nCurPageNo = nGotoPage; +} + +void GLDDocView::nextPage() +{ + int nGotoPage = m_nCurPageNo; + + if (m_zoomFactor == percent_50) + { + if (nGotoPage >= pageCount() - 2) + { + return; + } + + nGotoPage += 2; + } + else + { + if (nGotoPage == pageCount() - 1) + { + return; + } + + nGotoPage += 1; + } + + gotoPage(nGotoPage); + m_nCurPageNo = nGotoPage; +} + +void GLDDocView::gotoPage(int value) +{ + if (m_nCurPageNo == value) + { + return; + } + + int nValue = 0; + + if (m_zoomFactor == percent_50) + { + nValue = (value) * (m_nPageHeight + m_nPageSplitterHeight) / 2 + m_nPageSplitterHeight; + } + else + { + nValue = (value) * (m_nPageHeight + m_nPageSplitterHeight) + m_nPageSplitterHeight; + } + + m_scrollArea->verticalScrollBar()->setValue(nValue); +} + +void GLDDocView::calculatePageGeometryInfo() +{ + m_docInfo.nPageSplitterHeight = m_nPageSplitterHeight; + m_docInfo.pageGeometryInfoList.clear(); + + for (int i = 0; i < m_docInfo.nPageCount; ++i) + { + int x = 0; + int y = 0; + int width = 2000; + int height = m_nPageHeight + 1; + + if (m_zoomFactor == percent_50) + { + y = (m_nPageHeight + m_nPageSplitterHeight) * (i / 2) + m_nPageSplitterHeight; + } + else + { + y = (m_nPageHeight + m_nPageSplitterHeight) * i + m_nPageSplitterHeight; + } + + QRect pageRect(x, y, width, height); + + m_docInfo.pageGeometryInfoList.push_back(pageRect); + + if ((m_zoomFactor == percent_50) && (i < m_docInfo.nPageCount - 1)) + { + m_docInfo.pageGeometryInfoList.push_back(pageRect); + ++i; + } + } +} + +int GLDDocView::curPageNo(const QModelIndex& currentIndex) const +{ + QAbstractItemModel *itemModel = const_cast(currentIndex.model()); + GLDPaperWidgetModel *paperModel = dynamic_cast(itemModel); + + if (paperModel != NULL) + { + return paperModel->curPageNo(); + } + else + { + return -1; + } +} + +int GLDDocView::dataIndexPageNo(QModelIndex dataIndex) +{ + if (NULL == m_treeModel) + { + return -1; + } + + if (!dataIndex.isValid()) + { + return -1; + } + + QModelIndex treeIndex = m_treeModel->treeIndex(dataIndex); + + GIntList startRows = m_docInfo.startRowList; + int nTreeIndexPaperNo = 0; + int nStartRow = 0; + bool bHasDataIndexPageNo = false; + + for (int i = 0; i < startRows.count(); ++i) + { + if (startRows.at(i) > treeIndex.row()) + { + if (0 == i) + { + break; + } + + nTreeIndexPaperNo = i - 1; + nStartRow = startRows.at(i - 1); + bHasDataIndexPageNo = true; + break; + } + else if (startRows.at(i) <= treeIndex.row() && + treeIndex.row() < m_docInfo.rowCountPerPageList.at(i) + startRows.at(i)) + { + nTreeIndexPaperNo = i; + nStartRow = startRows.at(i); + bHasDataIndexPageNo = true; + break; + } + } + + if (bHasDataIndexPageNo) + { + return nTreeIndexPaperNo; + } + else + { + return -1; + } +} + +QModelIndex GLDDocView::index(QModelIndex dataIndex) +{ + int nDataIndexPageNo = dataIndexPageNo(dataIndex); + + if (nDataIndexPageNo != -1) + { + QModelIndex treeIndex = m_treeModel->treeIndex(dataIndex); + GLDPaperWidget *paper = findPaper(nDataIndexPageNo); + + if (paper != NULL) + { + const int row = treeIndex.row() - m_docInfo.startRowList.at(nDataIndexPageNo); + return paper->tableView()->model()->index(row, treeIndex.column()); + } + } + + return QModelIndex(); +} + +void GLDDocView::updateModelIndex(QModelIndex dataIndex) +{ + QModelIndex tableViewIndex = index(dataIndex); + int nPageNo = curPageNo(tableViewIndex); + + if (GLDPaperWidget *pPageWidget = findPaper(nPageNo)) + { + if (GlodonTableView *pTableView = pPageWidget->tableView()) + { + pTableView->updateModelIndex(tableViewIndex); + } + } +} + +void GLDDocView::updateCol(QModelIndex dataIndex) +{ + QModelIndex tableViewIndex = index(dataIndex); + int nPageNo = curPageNo(tableViewIndex); + + if (GLDPaperWidget *pPageWidget = findPaper(nPageNo)) + { + if (GlodonTableView *pTableView = pPageWidget->tableView()) + { + pTableView->updateCol(tableViewIndex.column()); + } + } +} + +void GLDDocView::updateRow(QModelIndex dataIndex) +{ + QModelIndex tableViewIndex = index(dataIndex); + int nPageNo = curPageNo(tableViewIndex); + + if (GLDPaperWidget *pPageWidget = findPaper(nPageNo)) + { + if (GlodonTableView *pTableView = pPageWidget->tableView()) + { + pTableView->updateRow(tableViewIndex.row()); + } + } +} + +void GLDDocView::updateAll() +{ + for (int i = 0; i < m_papers.count(); ++i) + { + GlodonTableView *pTableView = m_papers[i]->tableView(); + + if (pTableView) + { + pTableView->updateAll(); + } + } +} + +void GLDDocView::clearOtherIndex() +{ + m_isInClearOtherIndex = true; + + for (int i = 0; i < m_papers.count(); ++i) + { + GlodonTableView *pTableView = m_papers[i]->tableView(); + + if (pTableView->isEditing()) + { + pTableView->forceCloseEditor(); + } + + pTableView->clearSelection(); + pTableView->selectionModel()->clearCurrentIndex(); + } + + m_isInClearOtherIndex = false; +} + +double GLDDocView::colWidthRate(int col) const +{ + if (col < 0 || col >= m_colWidth.count()) + { + return 0.0; + } + + int nSum = 0; + + if (0 == m_nSettedWidthsSum) + { + for (int i = 0; i < m_colWidth.count(); ++i) + { + nSum += m_colWidth[i]; + } + } + else + { + nSum = m_nSettedWidthsSum; + } + + double dRate = m_colWidth[col] / (double)nSum; + return dRate; +} + +int GLDDocView::paperVerticalPosition(const QModelIndex &tableViewIndex) +{ + const int nCurPaperNo = curPageNo(tableViewIndex); + + GLDPaperWidget *curPaperWidget = findPaper(nCurPaperNo, true); + GlodonTableView *curPaperTableView = curPaperWidget->tableView(); + + const int nPageHeaderHeight = curPaperWidget->headerHeight(); + const int nTableViewHeaderHeight = curPaperTableView->horizontalHeader()->height(); + const int nCurPaperHeaderHeight = nPageHeaderHeight + nTableViewHeaderHeight; + const int nVerticalPosition = curPaperTableView->rowViewportPosition(tableViewIndex.row()); + const int nIndexPositionWithTableView = nVerticalPosition + nCurPaperHeaderHeight; + + return nIndexPositionWithTableView; +} + +int GLDDocView::paperHorizontalPosition(const QModelIndex &tableViewIndex) +{ + const int nCurPaperNo = curPageNo(tableViewIndex); + + GLDPaperWidget *curPaperWidget = findPaper(nCurPaperNo, true); + GlodonTableView *curPaperTableView = curPaperWidget->tableView(); + + const int nHorizentalPosition = curPaperTableView->columnViewportPosition(tableViewIndex.column()); + const int nLeftPaperMargin = curPaperWidget->leftMargin(); + + return nHorizentalPosition + nLeftPaperMargin; +} + +int GLDDocView::verticalPosition(const QModelIndex &tableViewIndex) +{ + int nCurPaperNo = curPageNo(tableViewIndex); + return paperVerticalPosition(tableViewIndex) + m_docInfo.pageGeometryInfoList.at(nCurPaperNo).top(); +} + +int GLDDocView::horizontalPosition(const QModelIndex &tableViewIndex) +{ + int nCurPaperNo = curPageNo(tableViewIndex); + return paperHorizontalPosition(tableViewIndex) + m_docInfo.pageGeometryInfoList.at(nCurPaperNo).left(); +} + +int GLDDocView::rowHeight(const QModelIndex &tableViewIndex) +{ + int ncurPaperNo = curPageNo(tableViewIndex); + GLDPaperWidget *curPaperWidget = findPaper(ncurPaperNo, true); + GlodonTableView *curPaperTableView = curPaperWidget->tableView(); + return curPaperTableView->rowHeight(tableViewIndex.row()); +} + +void GLDDocView::postUpdatePaperEvent() +{ + QEvent *pEvent = new QEvent((QEvent::Type)GM_DocViewCalculatePage); + QApplication::postEvent(this, pEvent); +} + +QModelIndex GLDDocView::indexAt(QPoint pos) +{ + int nPageNo = m_docInfo.pageOf(pos.y()); + GLDPaperWidget *pPaperWidget = findPaper(nPageNo, true); + + if (NULL == pPaperWidget) + { + return QModelIndex(); + } + + GlodonTableView *pTableView = pPaperWidget->tableView(); + QPoint tableViewPos(pPaperWidget->leftMargin() + pTableView->verticalHeader()->width(), + pPaperWidget->headerHeight() + pTableView->horizontalHeader()->height()); + QPoint paperWidgetPos = QPoint(m_docInfo.pageGeometryInfoList.at(nPageNo).left(), m_docInfo.pageGeometryInfoList.at(nPageNo).top()); + QPoint posInTableView = pos - tableViewPos - paperWidgetPos; + + if (posInTableView.y() > pTableView->verticalHeader()->length()) + { + posInTableView.setY(pTableView->verticalHeader()->length() - 1); + } + else if (posInTableView.y() < 0) + { + posInTableView.setY(0); + } + + if (posInTableView.x() > pTableView->horizontalHeader()->length()) + { + posInTableView.setX(pTableView->horizontalHeader()->length() - 1); + } + else if (posInTableView.x() < 0) + { + posInTableView.setX(0); + } + + return dataIndex(nPageNo, pTableView->indexAt(posInTableView)); +} + +void GLDDocView::setMutilHeaderView(bool value, Qt::Orientation orientation) +{ + if (m_bShowHHeaderView && orientation == Qt::Horizontal) + { + m_isHorizontalMutilHeaderView = value; + } +} + +bool GLDDocView::isMutilHeaderViewEnable() const +{ + return m_isHorizontalMutilHeaderView; +} + +QScrollArea *GLDDocView::scrollArea() +{ + return m_scrollArea; +} + +void GLDDocView::recoverFocusState() +{ + if (GLDPaperWidget *pPaperWidget = findPaper(m_docFocusInfo.nFocusPageNo)) + { + if (GlodonTableView *pTableView = pPaperWidget->tableView()) + { + QModelIndex curIndex = pTableView->model()->index(m_docFocusInfo.nFocusRow, m_docFocusInfo.nFocusColumn); + pTableView->setCurrentIndex(curIndex); + pTableView->setFocus(); + } + } +} + +GLDPaperWidget *GLDDocView::editingPaper() +{ + for (int i = 0; i < m_papers.count(); ++i) + { + if (GLDPaperWidget *pPaperWidget = m_papers.at(i)) + { + if (GlodonTableView *pTableView = pPaperWidget->tableView()) + { + if (pTableView->isEditing()) + { + return pPaperWidget; + } + } + } + } + + return NULL; +} + +void GLDDocView::prepareLoadPages() +{ + calculatePageGeometryInfo(); + + clearPagers(); + + resizeEvent(NULL); +} + +void GLDDocView::calculatePages() +{ + m_docInfo.rowCountPerPageList.clear(); + m_docInfo.startRowList.clear(); + m_docInfo.startRowList.push_back(0); + m_docInfo.nPageCount = 1; + + calculatePageCount(); + + prepareLoadPages(); + + if (m_model->rowCount() == 0) + { + m_model->insertRows(0, 1); + } + else + { + recoverFocusState(); + } +} + +void GLDDocView::onCurrentFocusChanged(const QModelIndex ¤t, const QModelIndex &previous) +{ + if (!m_isInClearOtherIndex) + { + m_nCurFocusPageNo = curPageNo(current); + m_currentIndex = dataIndex(m_nCurFocusPageNo, current); + m_docFocusInfo.nFocusPageNo = m_nCurFocusPageNo; + m_docFocusInfo.nFocusRow = current.row(); + m_docFocusInfo.nFocusColumn = current.column(); + + if (GlodonAbstractItemModel *pModel = dynamic_cast(m_model)) + { + pModel->afterCurrentChanged(m_currentIndex); + } + + emit currentFocusChanged(dataIndex(curPageNo(previous), previous), + m_currentIndex); + + onAfterCurrentFocusChanged(current, previous); + } +} + +void GLDDocView::onAfterCurrentFocusChanged(const QModelIndex ¤t, const QModelIndex &previous) +{ + if (!previous.isValid() && current.isValid()) + { + if (GLDPaperWidget *pPaperWidget = findPaper(m_nCurFocusPageNo)) + { + pPaperWidget->setFocusProxy(pPaperWidget->tableView()); + QWidget *pParentWidget = pPaperWidget->parentWidget(); + + while (pParentWidget) + { + pParentWidget->setFocusProxy(pPaperWidget); + pParentWidget = pParentWidget->parentWidget(); + } + + m_scrollArea->setFocusProxy(pPaperWidget); + } + } +} + +void GLDDocView::onbeforeMoveCurrent(const QModelIndex &oldIndex, + const QModelIndex &newIndex, + QItemSelectionModel::SelectionFlags &command, + MoveReason moveReason, bool &canMove) +{ + if (oldIndex.isValid()) + { + m_preIndex = dataIndex(oldIndex); + } + + if (newIndex.isValid()) + { + emit onbeforeMoveCursor(m_preIndex, dataIndex(newIndex), command, moveReason, canMove); + } + + if (m_isInManualControlScrollBar) + { + return; + } + + //控制在整个分页表格中,有且只有一页处于焦点状态 + if (!oldIndex.isValid() && newIndex.isValid()) + { + clearOtherIndex(); + + if (moveReason == mrProgram || moveReason == mrKey) + { + int nCurPaperNo = curPageNo(newIndex); + + if (nCurPaperNo > m_nCurFocusPageNo) + { + m_scrollArea->verticalScrollBar()->setValue(m_docInfo.pageGeometryInfoList.at(nCurPaperNo).top()); + } + else if (nCurPaperNo < m_nCurFocusPageNo) + { + GlodonTableView *pCurTableView = findPaper(nCurPaperNo)->tableView(); + int nPosition = m_docInfo.pageGeometryInfoList.at(nCurPaperNo).bottom() - m_nFooterHeight - m_nPageSplitterHeight + - pCurTableView->rowHeight(newIndex.row()) * 2; + m_scrollArea->verticalScrollBar()->setValue(nPosition); + } + } + } + + if (GLDPaperWidgetModel * pModel + = dynamic_cast(const_cast(oldIndex.model()))) + { + if (oldIndex.column() == pModel->columnCount() - 1 && newIndex.column() == 0 + && newIndex.row() < pModel->rowCount() && oldIndex.row() < newIndex.row() && moveReason != mrMouse) + { + emit focusToNextRow(dataIndex(pModel->curPageNo(), oldIndex), + dataIndex(pModel->curPageNo(), newIndex), canMove); + } + } + + if (oldIndex.isValid() && newIndex.isValid()) + { + //如果已经是处于一页的最后一个格子,那么就跳到下一个格子 + if ((oldIndex.row() == (oldIndex.model()->rowCount() - 1)) + && (oldIndex.column() == (oldIndex.model()->columnCount() - 1)) + && (newIndex.row() == 0) && (newIndex.column() == 0) && (moveReason == mrProgram || moveReason == mrKey)) + { + canMove = false; + int nprePaperNo = curPageNo(oldIndex); + + int ncurPaperNo = nprePaperNo + 1; + + if (ncurPaperNo >= m_docInfo.nPageCount) + { + m_docFocusInfo.nFocusPageNo = ncurPaperNo; + m_docFocusInfo.nFocusRow = 0; + m_docFocusInfo.nFocusColumn = 0; + emit focusToNextRow(dataIndex(oldIndex), QModelIndex(), canMove); + canMove = false; + return; + } + + m_scrollArea->verticalScrollBar()->setValue(m_docInfo.pageGeometryInfoList.at(ncurPaperNo).top()); + + GlodonTableView *pCurTableView = findPaper(ncurPaperNo)->tableView(); + QModelIndex currentIndex = pCurTableView->model()->index(0, 0); + setCurrentIndex(dataIndex(currentIndex)); + pCurTableView->edit(currentIndex); + } + else if ((newIndex.row() < newIndex.model()->rowCount()) && (moveReason == mrKey || moveReason == mrProgram)) + { + int ncurPaperNo = curPageNo(newIndex); + int nNewIndexPosition = paperVerticalPosition(newIndex); + + int nOldIndexPosition = paperVerticalPosition(oldIndex); + int nCurPaperOffset = m_docInfo.pageGeometryInfoList.at(ncurPaperNo).top() + - m_scrollArea->verticalScrollBar()->value(); + + if (nOldIndexPosition + nCurPaperOffset < 0) + { + m_scrollArea->verticalScrollBar()->setValue(m_docInfo.pageGeometryInfoList.at(ncurPaperNo).top() + + nNewIndexPosition); + } + else + { + if (nNewIndexPosition + nCurPaperOffset + rowHeight(newIndex) > m_scrollArea->height()) + { + m_scrollArea->verticalScrollBar()->setValue(m_scrollArea->verticalScrollBar()->value() + + rowHeight(newIndex)); + } + else if (nNewIndexPosition + nCurPaperOffset < 0) + { + m_scrollArea->verticalScrollBar()->setValue(m_scrollArea->verticalScrollBar()->value() + - rowHeight(newIndex)); + } + } + } + + } + + G_UNUSED(command); +} + +void GLDDocView::doNewWidthsToPapers(GIntList *widths) +{ + const int c_headerCount = widths->count(); + + for (int i = 0; i < c_headerCount; ++i) + { + setColumnWidthPixel(i, widths->at(i)); + } +} + +void GLDDocView::enableFitColWidths(bool enable) +{ + if (enable) + { + if (m_fitColWidths.count() > 0) + { + GIntList oList; + + for (int i = 0; i < m_fitColWidths.count(); ++i) + { + oList.push_back(m_fitColWidths[i]); + } + + foreach(GLDPaperWidget * paper, m_papers) + { + if (paper != NULL) + { + paper->tableView()->setFitColWidths(oList); + } + } + } + } + else + { + foreach(GLDPaperWidget * paper, m_papers) + { + if (paper != NULL) + { + GIntList oList; + paper->tableView()->setFitColWidths(oList); + } + } + } +} + +void GLDDocView::queryIndexDataType(const QModelIndex &index, GlodonDefaultItemDelegate::GDataType &dataType) +{ + emit onQueryIndexDataType(dataIndex(index), dataType); +} + +void GLDDocView::commitEditor(const QModelIndex &index, QVariant data, bool &commit) +{ + emit onCommitEditor(dataIndex(index), data, commit); +} + +void GLDDocView::onTableViewRangeFill(QModelIndexList src, + QModelIndexList dest, + int rowCount, + int columnCount, + bool &handled) +{ + QModelIndexList destModelIndexList; + QModelIndexList srcModelIndexList; + + for (int i = 0; i < m_papers.count(); ++i) + { + GLDPaperWidget *pPaperWidget = m_papers.at(i); + + if (pPaperWidget->curPageNo() == m_nCurFocusPageNo) + { + if (NULL != pPaperWidget->tableView()) + { + foreach(const QModelIndex& tableViewIndex, src) + { + srcModelIndexList.push_back(dataIndex(tableViewIndex)); + } + + foreach(const QModelIndex& tableViewIndex, dest) + { + destModelIndexList.push_back(dataIndex(tableViewIndex)); + } + } + } + } + + emit onRangeFill(srcModelIndexList, destModelIndexList, rowCount, columnCount, handled); +} + +void GLDDocView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) +{ + updateModelIndex(topLeft); + updateModelIndex(bottomRight); +} + +void GLDDocView::registerTableViewFactory(GLDDocViewTableViewFactory *tableViewFactory) +{ + m_tableViewFactory = tableViewFactory; +} + +void GLDDocView::setAllowToResize(bool value) +{ + m_allowToResize = value; +} + +bool GLDDocView::allowToResize() const +{ + return m_allowToResize; +} + +QModelIndex GLDDocView::editingIndex() +{ + if (GLDPaperWidget *pPaperWidget = editingPaper()) + { + return dataIndex(pPaperWidget->tableView()->currentIndex()); + } + + return QModelIndex(); +} + +void GLDDocView::forceCloseEditor() +{ + if (GLDPaperWidget *pPaperWidget = editingPaper()) + { + pPaperWidget->tableView()->forceCloseEditor(); + } +} + +void GLDDocView::setShowHorizontalHeaderView(bool value) +{ + m_bShowHHeaderView = value; + + if (!value) + { + setTableViewHorizontalHeaderHeight(0); + } +} + +bool GLDDocView::isShowHorizontalHeaderView() +{ + return m_bShowHHeaderView; +} + +void GLDDocView::setDrawFrameLine(bool value) +{ + m_bDrawFrameLine = value; +} + +bool GLDDocView::drawFrameLine() +{ + return m_bDrawFrameLine; +} + +void GLDDocView::setShowVerticalLine(bool value) +{ + m_bVertLine = value; +} + +bool GLDDocView::isShowVerticalLine() +{ + return m_bVertLine; +} + +void GLDDocView::setShowHorizontalLine(bool value) +{ + m_bHorzLine = value; +} + +bool GLDDocView::isShowHorizontalLine() +{ + return m_bHorzLine; +} + +void GLDDocView::setGridLineWidth(int value) +{ + m_nGridLineWidth = value; +} + +int GLDDocView::gridLineWidth() +{ + return m_nGridLineWidth; +} + +void GLDDocView::setPrintOrientation(QPrinter::Orientation oritation) +{ + m_printerOrientation = oritation; +} + +QPrinter::Orientation GLDDocView::printOrientation() +{ + return m_printerOrientation; +} + +bool GLDDocView::suitRowHeight() const +{ + return m_suitRowHeight; +} + +void GLDDocView::setSuitRowHeight(bool suitRowHeight) +{ + m_suitRowHeight = suitRowHeight; +} + +int GLDDocView::cellHeight() const +{ + return m_nCellHeight; +} + +void GLDDocView::setCellHeight(int cellHeight) +{ + m_nCellHeight = cellHeight; +} + +bool GLDDocView::allowZoom() const +{ + return m_allowZoom; +} + +void GLDDocView::setAllowZoom(bool bAllowZoom) +{ + m_allowZoom = bAllowZoom; +} + +GlodonHeaderView::ResizeMode GLDDocView::resizeMode() const +{ + return m_resizeMode; +} + +void GLDDocView::setResizeMode(const GlodonHeaderView::ResizeMode &resizeMode) +{ + m_resizeMode = resizeMode; +} + +GIntList GLDDocView::fitColWidths() const +{ + return m_fitColWidths; +} + +void GLDDocView::setFitColWidths(const GIntList &fitColWidths) +{ + m_fitColWidths = fitColWidths; +} + +bool GLDDocView::hasFitColumn() const +{ + return !m_fitColWidths.empty(); +} + +void GLDDocView::setCurrentIndex(QModelIndex dataIndex) +{ + QModelIndex tableViewIndex = index(dataIndex); + GLDPaperWidget *pPaperWidget = findPaper(tableViewIndex); + + if (NULL != pPaperWidget) + { + GlodonTableView *pTableView = pPaperWidget->tableView(); + pTableView->setCurrentIndex(tableViewIndex); + + if (!(pTableView->hasFocus())) + { + pTableView->setFocus(); + } + } +} + +void GLDDocView::setIndexEdit(QModelIndex dataIndex) +{ + if (dataIndex.isValid() == false) + { + return; + } + + QModelIndex tableViewIndex = index(dataIndex); + GLDPaperWidget *pPaperWidget = findPaper(tableViewIndex); + + if (NULL != pPaperWidget) + { + GlodonTableView *pTableView = pPaperWidget->tableView(); + + if (tableViewIndex != pTableView->currentIndex()) + { + pTableView->setCurrentIndex(tableViewIndex); + } + + pPaperWidget->tableView()->edit(tableViewIndex); + } +} + +void GLDDocView::reLayoutPaperWidget() +{ + for (int i = 0; i < m_papers.count(); ++i) + { + GLDPaperWidget *pPaperWidget = m_papers[i]; + pPaperWidget->setPaperWidth(m_dInitPageWidth); + pPaperWidget->setPaperHeight(m_dInitPageHeight); + pPaperWidget->setHeaderHeight(m_nHeaderHeight); + pPaperWidget->setFooterHeight(m_nFooterHeight); + pPaperWidget->setTableViewHeight(m_nPageHeight - m_nHeaderHeight - m_nFooterHeight); + pPaperWidget->setLeftMargin(m_nLeftMargin); + pPaperWidget->setRightMargin(m_nRightMargin); + pPaperWidget->setTableViewWidth(m_nPageWidth - m_nLeftMargin - m_nRightMargin); + pPaperWidget->tableView()->horizontalHeader()->setFixedHeight(m_nTableViewHHeaderHeight); + pPaperWidget->setFactor(m_zoomFactor); + pPaperWidget->reLayout(); + } +} + +int GLDDocView::paperWidth() const +{ + return m_nPageWidth; +} + +void GLDDocView::setInitPageWidth(int value) +{ + m_dInitPageWidth = value; +} + +void GLDDocView::calculatePageWidth() +{ + double dZoomFactor = zoomFactorAsDouble(); + + m_nPageWidth = m_dInitPageWidth * dZoomFactor; +} + +void GLDDocView::setPaperWidth(int value) +{ + setInitPageWidth(value); + calculatePageWidth(); +} + +int GLDDocView::paperHeight() const +{ + return m_nPageHeight; +} + +void GLDDocView::setInitPageHeight(int value) +{ + m_dInitPageHeight = value; +} + +void GLDDocView::calculatePageHeight() +{ + double dZoomFactor = zoomFactorAsDouble(); + + m_nPageHeight = m_dInitPageHeight * dZoomFactor; +} + +void GLDDocView::setPaperHeight(int value) +{ + setInitPageHeight(value); + calculatePageHeight(); +} + +void GLDDocView::setBackgroundPalette(QPalette palette) +{ + m_scrollArea->setPalette(palette); +} + +int GLDDocView::rightMargin() const +{ + return m_nRightMargin; +} + +void GLDDocView::setRightMargin(int rightMargin) +{ + m_dInitRightMargin = POINT_NUMBER_FROM_MM(rightMargin, m_nCurrentDPI); + m_nRightMargin = m_dInitRightMargin; + reLayoutPaperWidget(); +} + +QModelIndex GLDDocView::dataIndex(int pageNo, const QModelIndex &index) +{ + if (pageNo >= 0 && pageNo < m_docInfo.startRowList.count()) + { + int ndataRow = m_docInfo.startRowList[pageNo] + index.row(); + + if (GlodonTreeModel *pTreeModel = dynamic_cast(m_model)) + { + return pTreeModel->dataIndex(ndataRow, index.column()); + } + else + { + return m_dataModel->index(ndataRow, index.column(), index.parent()); + } + } + else + { + return QModelIndex(); + } +} + +void GLDDocView::registerWidgetFactory(GLDBaseWidgetFactory *factory) +{ + if (m_headerAndFooterWidgetFactory == factory) + { + return; + } + + freeAndNil(m_headerAndFooterWidgetFactory); + m_headerAndFooterWidgetFactory = factory; +} + +GLDBaseWidgetFactory *GLDDocView::registeredWidgetFactory() const +{ + return m_headerAndFooterWidgetFactory; +} + +void GLDDocView::registerDelegateFactory(GlodonDefaultItemDelegateFactory *factory) +{ + if (m_delegateFactory == factory) + { + return; + } + + freeAndNil(m_delegateFactory); + m_delegateFactory = factory; +} + +GlodonDefaultItemDelegateFactory *GLDDocView::registeredDelegateFactory() const +{ + return m_delegateFactory; +} + +int GLDDocView::curPageNo() +{ + return m_nCurPageNo; // 从0开始 +} + +int GLDDocView::curFocusPageNo() +{ + return m_nCurFocusPageNo; // 从0开始 +} + +bool GLDDocView::removePageAt(int nPage) +{ + if ((nPage < 0) || (nPage >= m_docInfo.nPageCount)) + { + return false; + } + + m_model->removeRows(m_docInfo.startRowList[nPage], m_docInfo.rowCountPerPageList[nPage]); + return true; +} + +bool GLDDocView::removeRows(int row, int count, const QModelIndex &parent) +{ + if (dynamic_cast(m_model)) + { + return m_model->removeRows(row, count, parent); + } + + return false; +} + +bool GLDDocView::insertRows(int row, int count, const QModelIndex &parent) +{ + if (dynamic_cast(m_dataModel)) + { + return m_dataModel->insertRows(row, count, parent); + } + + return false; +} + +bool GLDDocView::appendRows(int count, const QModelIndex &parent) +{ + QStandardItemModel *standardItemModel = dynamic_cast(m_dataModel); + + if (standardItemModel != NULL) + { + for (int i = 0; i < count; ++i) + { + standardItemModel->appendRow(new QStandardItem("")); + return true; + } + } + else + { + return m_dataModel->insertRows(m_dataModel->rowCount(), count, parent); + } + + return false; +} + +void GLDDocView::setColumnWidth(int column, int size) +{ + size = POINT_NUMBER_FROM_MM(size, m_nCurrentDPI); + setColumnWidthPixel(column, size); +} + +void GLDDocView::setColumnWidthPixel(int column, int size) +{ + for (int i = m_colWidth.count(); i <= column; ++i) + { + m_colWidth.push_back(-1); + m_nSettedWidthsSum = 0; + } + + if ((column >= 0) && (column < m_colWidth.count()) && (m_colWidth.at(column) != size)) + { + m_colWidth.replace(column, size); + m_nSettedWidthsSum = 0; + + setPaperColumnWidth(column, size); + } +} + +void GLDDocView::setPaperColumnWidth(int column, int size) +{ + for (int i = 0; i < m_papers.count(); ++i) + { + GlodonTableView *pTableView = m_papers[i]->tableView(); + pTableView->setColumnWidth(column, size); + } +} + +int GLDDocView::columnWidth(int column) +{ + if ((column >= 0) && (column < m_colWidth.count())) + { + return m_colWidth.at(column); + } + else + { + return -1; + } +} + +GLDDocInfo &GLDDocView::docInfo() +{ + return m_docInfo; +} + +QAbstractItemModel *GLDDocView::model() const +{ + return m_model; +} + +int GLDDocView::columnCount() const +{ + return m_colWidth.count(); +} + +int GLDDocView::leftMargin() const +{ + return m_nLeftMargin; +} + +void GLDDocView::setLeftMargin(int leftMargin) +{ + m_dInitLeftMargin = POINT_NUMBER_FROM_MM(leftMargin, m_nCurrentDPI); + m_nLeftMargin = m_dInitLeftMargin; + + reLayoutPaperWidget(); +} + +int GLDDocView::tableViewHorizontalHeaderHeight() const +{ + return m_nTableViewHHeaderHeight; +} + +void GLDDocView::setTableViewHorizontalHeaderHeight(int tableViewHHeaderHeight) +{ + m_nInitTableViewHHeaderHeight = POINT_NUMBER_FROM_MM(tableViewHHeaderHeight, m_nCurrentDPI); + m_nTableViewHHeaderHeight = m_nInitTableViewHHeaderHeight; +} + +#ifndef QT_NO_WHEELEVENT +void GLDDocView::wheelEvent(QWheelEvent *event) +{ + Qt::KeyboardModifiers modifier = event->modifiers(); + + if (m_allowZoom && (Qt::CTRL == (modifier & Qt::CTRL))) + { + int nfactor = m_zoomFactor; + + // 缩小 + if (event->delta() < 0) + { + if (m_zoomFactor <= percent_100) + { + nfactor = 0; + } + else + { + nfactor = m_zoomFactor / 2; + } + } + // 放大 + else if (event->delta() > 0) + { + if (m_zoomFactor == percent_50) + { + nfactor = percent_100; + } + else if (m_zoomFactor == percent_100) + { + nfactor = percent_200; + } + else if (m_zoomFactor == percent_200) + { + nfactor = percent_400; + } + } + + setFactor(ZoomFactor(nfactor)); + event->accept(); + } + else + { + QWidget::wheelEvent(event); + } +} + +#endif // QT_NO_WHEELEVENT + +bool GLDDocView::eventFilter(QObject *object, QEvent *event) +{ + if (event->type() == QEvent::KeyPress || event->type() == QEvent::InputMethod) + { + QKeyEvent *keyEvent = static_cast(event); + return keyPressEventFilter(object, keyEvent); + } + else if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick) + { + QMouseEvent *pMouseEvent = static_cast(event); + return mousePressEventFilter(object, pMouseEvent); + } + + Q_UNUSED(event); + return false; +} + +bool GLDDocView::mousePressEventFilter(QObject *object, QMouseEvent *pMouseEvent) +{ + GlodonTableView *pTableView = NULL; + + if ((pTableView = dynamic_cast(QApplication::focusWidget())) != NULL) + { + QWidget *pScrollArea = dynamic_cast(object); + + QPoint posInTableView = pMouseEvent->pos(); + QPoint globalPos = pScrollArea->mapToGlobal(pMouseEvent->pos()); + + QModelIndex tableViewIndex = pTableView->indexAt(posInTableView); + + bool bHandled = false; + + if (pMouseEvent->type() == QEvent::MouseButtonPress) + { + emit onMousePress(dataIndex(tableViewIndex), globalPos, pMouseEvent, bHandled); + } + else if (pMouseEvent->type() == QEvent::MouseButtonDblClick) + { + emit onMouseButtonDblClick(dataIndex(tableViewIndex), globalPos, pMouseEvent, bHandled); + } + + if (bHandled) + { + pMouseEvent->accept(); + return true; + } + } + + Q_UNUSED(pMouseEvent); + return false; +} + +bool GLDDocView::onKeyUp(GlodonTableView *tableView, QKeyEvent *keyEvent) +{ + QModelIndex curIndex = tableView->currentIndex(); + + if (curIndex.row() == 0) + { + int ncurPageNo = curPageNo(curIndex); + + // todo 如果当前页不是第一页,就会跳到上一页。否则应该跳到最后一页? + if (ncurPageNo > 0) + { + GlodonTableView *preTableView = findPaper(ncurPageNo - 1, true)->tableView(); + QModelIndex preIndex = + preTableView->model()->index(preTableView->model()->rowCount() - 1, curIndex.column()); + m_currentIndex = dataIndex(preIndex); + preTableView->setCurrentIndex(preIndex); + + if (!preTableView->hasFocus()) + { + preTableView->setFocus(); + } + + keyEvent->accept(); + + return true; + } + } + + return false; +} + +bool GLDDocView::onKeyDown(GlodonTableView *tableView, QKeyEvent *keyEvent) +{ + QModelIndex curIndex = tableView->currentIndex(); + + if (curIndex.isValid() && curIndex.row() == curIndex.model()->rowCount() - 1) + { + int ncurPageNo = curPageNo(curIndex); + + // todo 如果当前的也不是最后一页,就会跳到下一页。否则应该跳到第一页? + if (ncurPageNo < m_docInfo.nPageCount - 1) + { + GLDPaperWidget *paper = findPaper(ncurPageNo + 1, true); + GlodonTableView *nextTableView = paper->tableView(); + + QModelIndex nextIndex = nextTableView->model()->index(0, curIndex.column()); + + m_currentIndex = dataIndex(nextIndex); + nextTableView->setCurrentIndex(nextIndex); + + if (!nextTableView->hasFocus()) + { + nextTableView->setFocus(); + } + + keyEvent->accept(); + + return true; + } + } + + return false; +} + +bool GLDDocView::onKeyPress(GlodonTableView *tableView, QKeyEvent *keyEvent) +{ + switch (keyEvent->key()) + { + case Qt::Key_Down: + { + return onKeyDown(tableView, keyEvent); + } + break; + + case Qt::Key_Up: + { + return onKeyUp(tableView, keyEvent); + } + break; + + case Qt::Key_PageDown: + { + return onKeyPageDown(tableView, keyEvent); + } + break; + + case Qt::Key_PageUp: + { + return onKeyPageUp(tableView, keyEvent); + } + break; + } + + return false; +} + +bool GLDDocView::onKeyPageUp(GlodonTableView *tableView, QKeyEvent *keyEvent) +{ + QModelIndex curIndex = tableView->currentIndex(); + + int nextPosition = m_nPageSplitterHeight + m_scrollArea->verticalScrollBar()->value() + - m_scrollArea->height(); + + if (nextPosition >= m_docInfo.pageGeometryInfoList.at(0).top()) + { + scrollTo(indexAt(QPoint(horizontalPosition(curIndex), nextPosition))); + } + else + { + m_scrollArea->verticalScrollBar()->setValue(0); + tableView->setCurrentIndex(tableView->model()->index(0, curIndex.column())); + } + + keyEvent->accept(); + + return true; +} + +bool GLDDocView::onKeyPageDown(GlodonTableView *tableView, QKeyEvent *keyEvent) +{ + QModelIndex curIndex = tableView->currentIndex(); + + int nextPosition = m_scrollArea->verticalScrollBar()->value() + m_scrollArea->height(); + + if (m_scrollArea->horizontalScrollBar()->isVisible()) + { + nextPosition -= m_scrollArea->horizontalScrollBar()->height(); + } + + if (nextPosition <= m_docInfo.pageGeometryInfoList.at(m_docInfo.nPageCount - 1).bottom()) + { + scrollTo(indexAt(QPoint(horizontalPosition(curIndex), nextPosition))); + } + else + { + m_scrollArea->verticalScrollBar()->setValue(m_scrollArea->maximumHeight()); + + const int row = tableView->model()->rowCount() - 1; + const int col = curIndex.column(); + QModelIndex nextIndex = tableView->model()->index(row, col); + + tableView->setCurrentIndex(nextIndex); + } + + keyEvent->accept(); + + return true; +} + +bool GLDDocView::keyPressEventFilter(QObject *object, QKeyEvent *keyEvent) +{ + bool bHandle = false; + + emit onKeyPress(m_currentIndex, *keyEvent, bHandle); + + if (bHandle) + { + keyEvent->accept(); + return true; + } + + GlodonTableView *currentTableView = dynamic_cast(object); + + if (NULL == currentTableView) + { + return false; + } + + return onKeyPress(currentTableView, keyEvent); + +} + +int GLDDocView::headerHeight() const +{ + return m_nHeaderHeight; +} + +void GLDDocView::setHeaderHeight(int headerHeight) +{ + m_dInitHeaderHeight = POINT_NUMBER_FROM_MM(headerHeight, m_nCurrentDPI); + m_nHeaderHeight = m_dInitHeaderHeight; + + reLayoutPaperWidget(); +} + +int GLDDocView::footerHeight() const +{ + return m_nFooterHeight; +} + +void GLDDocView::setFooterHeight(int footerHeight) +{ + m_dInitFooterHeight = POINT_NUMBER_FROM_MM(footerHeight, m_nCurrentDPI);; + m_nFooterHeight = m_dInitFooterHeight; + + reLayoutPaperWidget(); +} + +ZoomFactor GLDDocView::factor() const +{ + return m_zoomFactor; +} + +void GLDDocView::setFactor(const ZoomFactor &value) +{ + if (m_zoomFactor == value) + { + return; + } + + m_zoomFactor = value; + + double dZoomFactor = zoomFactorAsDouble(); + + m_nPageWidth = m_dInitPageWidth * dZoomFactor; + m_nPageHeight = m_dInitPageHeight * dZoomFactor; + m_nHeaderHeight = m_dInitHeaderHeight * dZoomFactor; + m_nFooterHeight = m_dInitFooterHeight * dZoomFactor; + m_nLeftMargin = m_dInitLeftMargin * dZoomFactor; + m_nRightMargin = m_dInitRightMargin * dZoomFactor; + + m_nTableViewHHeaderHeight = m_nInitTableViewHHeaderHeight * dZoomFactor; + m_nPageSplitterHeight = m_nInitPageSplitterHeight * dZoomFactor; + + m_scrollArea->horizontalScrollBar()->setValue(0); + + prepareLoadPages(); +} + +QSize GLDDocView::sizeHint() const +{ + return QWidget::sizeHint(); +} + +void GLDDocView::resizeEvent(QResizeEvent *) +{ + int nPageRemainedHeight = 0; + + QRect scrollAreaRect = m_scrollArea->rect(); + + if (m_zoomFactor == percent_50) + { + const int nCurPageNo = int(m_docInfo.nPageCount + 1) / 2; + const int nPageContentHeight = (m_nPageHeight + m_nPageSplitterHeight) * (nCurPageNo) + m_nPageSplitterHeight; + nPageRemainedHeight = nPageContentHeight - scrollAreaRect.height(); + } + else + { + const int nPageContentHeight = (m_nPageHeight + m_nPageSplitterHeight) * (m_docInfo.nPageCount) + m_nPageSplitterHeight; + nPageRemainedHeight = nPageContentHeight - scrollAreaRect.height(); + } + + m_scrollArea->verticalScrollBar()->setRange(0, nPageRemainedHeight); + m_scrollArea->verticalScrollBar()->setPageStep(scrollAreaRect.height()); + + verticalScrollBarValueChanged(m_scrollArea->verticalScrollBar()->value()); +} + +void GLDDocView::customEvent(QEvent *event) +{ + if (event->type() == (int)GM_DocViewCalculatePage) + { + calculatePages(); + } +} + +bool GLDDocView::hasPager(int nPageNo) +{ + return indexPaper(nPageNo) != -1; +} + +int GLDDocView::indexPaper(int nPageNo) +{ + for (int i = 0; i < m_papers.count(); ++i) + { + if (nPageNo == m_papers[i]->curPageNo()) + { + return i; + } + } + + return -1; +} + +GLDPaperWidget *GLDDocView::findPaper(int nPageNo, bool createIfNotFound) +{ + for (int i = 0; i < m_papers.count(); ++i) + { + if (nPageNo == m_papers[i]->curPageNo()) + { + return m_papers[i]; + } + } + + if (createIfNotFound) + { + if (nPageNo >= 0 && nPageNo < m_docInfo.nPageCount) + { + GLDPaperWidget *pPaperWidget = newPaper(nPageNo); + m_papers.insert(nPageNo, pPaperWidget); + return pPaperWidget; + } + } + + return NULL; +} + +int GLDDocView::pageCount() const +{ + return m_docInfo.nPageCount; +} + +struct PageCountCalculater +{ + +}; + +double GLDDocView::zoomFactorAsDouble() const +{ + double dZoomFactor = 0.5; + + if (m_zoomFactor != percent_50) + { + dZoomFactor = m_zoomFactor; + } + + return dZoomFactor; +} + +void GLDDocView::calculatePageCount() +{ + int nModelRowCount = m_model->rowCount(); + + if(nModelRowCount == 0) + { + m_docInfo.rowCountPerPageList.push_back(28); + + return; + } + + int nPageHeight = 0; + int nRowCountPerPage = 0; + + double dZoomFactor = zoomFactorAsDouble(); + + const int nCellHeight = m_nCellHeight * dZoomFactor; + + int nFirstRowIndex = 0; + int nNextRowIndex = 0; + + int nTableViewHeight = 0; + int nRemainHeight = 0; + + while (nFirstRowIndex < nModelRowCount || nRowCountPerPage != 0) + { + QVariant firstRowHeight; + QVariant nextRowHeight; + + if (nFirstRowIndex < nModelRowCount) + { + firstRowHeight = m_model->index(nFirstRowIndex, 0).data(gidrRowHeightRole); + } + + if (nFirstRowIndex + 1 < nModelRowCount) + { + nextRowHeight = m_model->index(nFirstRowIndex + 1, 0).data(gidrRowHeightRole); + } + + // 以下都加格线的宽度的原因是现在tableView的格线不再占用格子的宽度 + + if (firstRowHeight.isValid()) + { + nPageHeight += firstRowHeight.toInt(); + } + else + { + nPageHeight += nCellHeight; // ? + } + + nPageHeight += m_nGridLineWidth; + + if (nextRowHeight.isValid()) + { + nextRowHeight = nextRowHeight.toInt(); + } + else + { + nextRowHeight = nCellHeight; + } + + nextRowHeight.setValue(nextRowHeight.toInt() + m_nGridLineWidth); + + nRowCountPerPage++; + + nTableViewHeight = m_nPageHeight - m_nHeaderHeight - m_nFooterHeight; + nRemainHeight = nTableViewHeight - m_nTableViewHHeaderHeight - nPageHeight; + + if (nRemainHeight < nextRowHeight.toInt()) + { + m_docInfo.rowCountPerPageList.push_back(nRowCountPerPage); + + nPageHeight = 0; + nRowCountPerPage = 0; + + if (nFirstRowIndex + 1 < nModelRowCount) + { + m_docInfo.startRowList.push_back(nFirstRowIndex + 1); + m_docInfo.nPageCount++; + } + } + else + { + if (nFirstRowIndex + 1 >= nModelRowCount) + { + nNextRowIndex++; + } + } + + nFirstRowIndex++; + } + + if (nFirstRowIndex >= m_model->rowCount() + 1) + { + if (nNextRowIndex != 0) + { + m_model->insertRows(m_model->rowCount(), nNextRowIndex); + // return; + } + } +} + +/* CBaseWidgetFactory */ +GLDBaseWidgetFactory::~GLDBaseWidgetFactory() +{ + +} + +/* GLDDocViewTableViewFactory */ +GLDDocViewTableViewFactory::~GLDDocViewTableViewFactory() +{ + +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockContainer.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockContainer.cpp new file mode 100644 index 00000000..98666d5a --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockContainer.cpp @@ -0,0 +1,1115 @@ +#include +#include +#include + +#include "GLDGlobal.h" +#include "GLDDockContainer.h" + +/*CDockWidget*/ + +GLDDockContainer::GLDDockContainer(const GString &title, QWidget *parent, bool bWest) : QWidget(parent), + m_fixedFrame(true), m_barAtLeft(bWest), m_oldMargin(NULL), m_indexAtSplitter(-1), m_preParent(NULL), + m_title(title), m_minWidth(-1) +{ + //@attention dockContainer 本身是一个Widget,但其实是里面的GLDDockContainerTabBar和加入的DockContainerWidget + //作为显示的模块,dockContainer本身不要显示出来。这里需要visible设置为false,否则dockWidget会透明占用父窗口的一定空间 + setVisible(false); + m_tabBar = new GLDDockContainerTabBar(this); + m_tabBar->installEventFilter(this); + m_tabBar->setShape(GLDDockContainerTabBar::RoundedWest); + m_tabBar->addTab(title); + m_tabBar->resize(m_tabBar->sizeHint()); + m_tabBar->hide(); + m_tabBar->setObjectName("m_tabBar"); + + connect(m_tabBar, SIGNAL(clicked()), this, SLOT(doClickBar())); + + m_titleBar = new GLDDockContainerTitleBar(title, this); + connect(m_titleBar->m_closeBtn, SIGNAL(clicked()), this, SLOT(close())); + connect(m_titleBar->m_fixedBtn, SIGNAL(clicked()), this, SLOT(doFixedClick())); + + m_gridLayout = new QGridLayout(this); + if (m_barAtLeft) + { + m_gridLayout->addWidget(m_tabBar, 0, 0, 2, 1, Qt::AlignTop); + m_gridLayout->addWidget(m_titleBar, 0, 1, 1, 1); + } + else + { + m_gridLayout->addWidget(m_tabBar, 0, 1, 2, 1, Qt::AlignTop); + m_gridLayout->addWidget(m_titleBar, 0, 0, 1, 1); + } + m_gridLayout->setContentsMargins(0, 0, 0, 0); + m_gridLayout->setSpacing(0); + + m_dockWidget = NULL; + setWindowFlags(Qt::WindowStaysOnTopHint); +} + +GLDDockContainer::~GLDDockContainer() +{ + freeAndNil(m_oldMargin) +} + +void GLDDockContainer::addDockWidget(QWidget *w) +{ + if (m_dockWidget) + { + m_gridLayout->removeWidget(m_dockWidget); + } + + m_dockWidget = w; + + if (m_barAtLeft) + { + m_gridLayout->addWidget(m_dockWidget, 1, 1, 1, 1); + } + else + { + m_gridLayout->addWidget(m_dockWidget, 1, 0, 1, 1); + } +} + +void GLDDockContainer::setCloseBtnVisible(bool value) +{ + m_titleBar->setCloseBtnVisible(value); +} + +void GLDDockContainer::setTabsCloseAble(bool value) +{ + m_tabBar->setTabsClosable(value); +} + +void GLDDockContainer::setTitleBar(GLDDockContainerTitleBar *titleBar) +{ + if (m_titleBar != titleBar) + { + m_gridLayout->removeWidget(m_titleBar); + + if (m_titleBar != NULL) + { + delete m_titleBar; + } + + m_titleBar = titleBar; + reInitTitleBar(); + } +} + +void GLDDockContainer::setTabBar(GLDDockContainerTabBar *tabBar) +{ + if (m_tabBar != tabBar) + { + if (m_barAtLeft) + { + m_gridLayout->removeWidget(m_tabBar); + } + else + { + m_gridLayout->removeWidget(m_tabBar); + } + + if (m_tabBar != NULL) + { + delete m_tabBar; + } + + m_tabBar = tabBar; + reInitTabBar(); + } +} + +QIcon GLDDockContainer::fixedIcon() +{ + return m_titleBar->m_fixedBtn->icon(); +} + +void GLDDockContainer::setFixedIcon(QIcon &icon) +{ + m_titleBar->m_fixedBtn->setNormIcon(icon); + m_titleBar->m_fixedBtn->setIcon(icon); +} + +void GLDDockContainer::setFixedDockIcon(QIcon &icon) +{ + m_titleBar->m_fixedBtn->setDockIcon(icon); +} + +QIcon GLDDockContainer::closeIcon() +{ + return m_titleBar->m_closeBtn->icon(); +} + +void GLDDockContainer::setCloseIcon(QIcon &icon) +{ + m_titleBar->m_closeBtn->setNormIcon(icon); + m_titleBar->m_closeBtn->setIcon(icon); +} + +void GLDDockContainer::paintEvent(QPaintEvent *event) +{ + QWidget::paintEvent(event); +} + +void GLDDockContainer::initStyleOption(QStyleOptionDockWidget *option) const +{ + if (!option) + { + return; + } + + option->initFrom(this); + option->closable = true; + option->movable = true; + option->floatable = true; + + QStyleOptionDockWidgetV2 *v2 = qstyleoption_cast(option); + + if (v2 != 0) + { + v2->verticalTitleBar = false; + } +} + +void GLDDockContainer::doShow() +{ + doShowFrame(false); + m_fixedFrame = false; + if (dynamic_cast(parentWidget())) + { + alignSplitter(); + } + else + { + alignWidgets(); + } +} + +void GLDDockContainer::alignWidgets(bool bNeedRemove) +{ + QLayout *layout = parentWidget()->layout(); + if (!layout) + { + return; + } + + QRect barRet = m_tabBar->rect(); + if (bNeedRemove) + { + layout->removeWidget(this); + + if (!m_barAtLeft) + { + parentWidget()->installEventFilter(this); + } + } + if (m_oldMargin == NULL) + { + QMargins margin = layout->contentsMargins(); + m_oldMargin = new QMargins(margin.left(), margin.top(), margin.right(), margin.bottom()); + } + if (m_barAtLeft) + { + layout->setContentsMargins(barRet.width(), m_oldMargin->top(), m_oldMargin->right(), m_oldMargin->bottom()); + setGeometry(0, m_oldMargin->top(), width(), + parentWidget()->height() - m_oldMargin->top() - m_oldMargin->bottom()); + } + else + { + layout->setContentsMargins(m_oldMargin->left(), m_oldMargin->top(), barRet.width(), m_oldMargin->bottom()); + setGeometry(parentWidget()->width() - width(), m_oldMargin->top(), + width(), parentWidget()->height() - m_oldMargin->top() - m_oldMargin->bottom()); + } + raise(); +} + +void GLDDockContainer::alignSplitter() +{ + QWidget *pSplitter = parentWidget(); + if (m_preParent == NULL) + { + m_preParent = pSplitter; + } + + QRect rParentRect = pSplitter->rect(); + QRect barRet = m_tabBar->rect(); + m_indexAtSplitter = dynamic_cast(pSplitter)->indexOf(this); + setParent(pSplitter->parentWidget()); + + if (!m_barAtLeft) + { + parentWidget()->installEventFilter(this); + } + + if (parentWidget()->layout() == NULL) + { + if (m_barAtLeft) + { + int nLeft = rParentRect.left(); + setGeometry(nLeft, rParentRect.top(), width(), pSplitter->height()); + const_cast(pSplitter->geometry()).setLeft(nLeft + barRet.width()); + } + else + { + int nRight = rParentRect.right(); + setGeometry(nRight - width(), rParentRect.top(), width(), pSplitter->height()); + const_cast(pSplitter->geometry()).setRight(nRight - barRet.width()); + } + raise(); + } + else + { + alignWidgets(false); + show(); + } +} + +void GLDDockContainer::reInitTitleBar() +{ + connect(m_titleBar->m_closeBtn, SIGNAL(clicked()), this, SLOT(close())); + connect(m_titleBar->m_fixedBtn, SIGNAL(clicked()), this, SLOT(doFixedClick())); + + if (m_barAtLeft) + { + m_gridLayout->addWidget(m_titleBar, 0, 1, 1, 1); + } + else + { + m_gridLayout->addWidget(m_titleBar, 0, 0, 1, 1); + } +} + +void GLDDockContainer::reInitTabBar() +{ + m_tabBar->installEventFilter(this); + m_tabBar->setShape(GLDDockContainerTabBar::RoundedWest); + m_tabBar->addTab(m_tabBar->title()); + m_tabBar->resize(m_tabBar->sizeHint()); + m_tabBar->hide(); + + connect(m_tabBar, SIGNAL(clicked()), this, SLOT(doClickBar())); + + if (m_barAtLeft) + { + m_gridLayout->addWidget(m_titleBar, 0, 1, 1, 1); + } + else + { + m_gridLayout->addWidget(m_titleBar, 0, 0, 1, 1); + } + +} + +bool GLDDockContainer::eventFilter(QObject *obj, QEvent *event) +{ + if ((m_tabBar == obj) && (m_tabBar->isVisible())) + { + switch (event->type()) + { + case QEvent::Enter: + doShow(); + event->accept(); + return true; + + case QEvent::Leave: + if (!underMouse()) + { + doHideContainer(); + event->accept(); + return true; + } + else + { + break; + } + + default: + break; + } + } + else if (obj == parentWidget()) + { + if ((event->type() == QEvent::Resize) && (!m_fixedFrame)) + { + setGeometry(parentWidget()->width() - m_tabBar->width(), 0, + m_tabBar->width(), m_tabBar->height()); + } + } + return QWidget::eventFilter(obj, event); +} + +bool GLDDockContainer::event(QEvent *event) +{ + if (event->type() == QEvent::Leave && !m_fixedFrame) + { + doHideContainer(); + event->accept(); + return true; + } + return QWidget::event(event); +} + +QSize GLDDockContainer::sizeHint() const +{ + if (m_titleBar->isVisible() && m_tabBar->isHidden()) + { + if (m_dockWidget) + { + return m_dockWidget->sizeHint(); + } + else + { + return m_titleBar->sizeHint(); + } + } + else + { + return m_tabBar->sizeHint(); + } +} + +QSize GLDDockContainer::minimumSizeHint() const +{ + if (m_titleBar->isVisible() && m_tabBar->isHidden()) + { + if (-1 == m_minWidth) + { + return m_titleBar->sizeHint() * 2; + } + else + { + return QSize(m_minWidth, m_titleBar->height() * 2); + } + } + else + { + return m_tabBar->sizeHint(); + } +} + +void GLDDockContainer::doFixedClick() +{ + QSize tabSize = m_tabBar->size(); + if (m_tabBar->isVisible()) + { + doClickBar(); + resize(size().width() - tabSize.width(), size().height()); + } + else + { + m_preSize = size() + QSize(tabSize.width(), 0); + doHideContainer(); + m_titleBar->m_fixedBtn->setInDock(true); + } +} + +void GLDDockContainer::doHideContainer() +{ + QRect rPreGeom = geometry(); + m_fixedFrame = false; + + if (!m_titleBar->isVisible()) + { + return; + } + +// m_preSize = size(); + m_titleBar->hide(); + + if (m_dockWidget) + { + m_dockWidget->hide(); + } + + if (m_barAtLeft) + { + resize(m_tabBar->size()); + } + else + { + setGeometry(parentWidget()->width() - m_tabBar->width(), rPreGeom.top(), + m_tabBar->width(), m_tabBar->height()); + } + + m_tabBar->show(); + + if (dynamic_cast(parentWidget())) + { + alignSplitter(); + } +} + +void GLDDockContainer::doShowContainer() +{ + doShowFrame(true); + QLayout *layout = parentWidget()->layout(); + + if (!layout) + { + return; + } + + layout->setContentsMargins(*m_oldMargin); + delete m_oldMargin; + m_oldMargin = NULL; + QList list; + int nWidgets = layout->count(); + for (int i = 0; i < nWidgets; i++) + { + list.append(layout->itemAt(i)->widget()); + layout->removeWidget(list.at(i)); + } + if (m_barAtLeft) + { + layout->addWidget(this); + } + + for (int i = 0; i < nWidgets; i++) + { + layout->addWidget(list.at(i)); + } + + if (!m_barAtLeft) + { + layout->addWidget(this); + parentWidget()->removeEventFilter(this); + } +} + +void GLDDockContainer::doAddToSplitter() +{ + QSplitter *pSlitter = dynamic_cast(m_preParent); + if (parentWidget()->layout()) + { + parentWidget()->layout()->setContentsMargins(*m_oldMargin); + + if (!m_barAtLeft) + { + parentWidget()->removeEventFilter(this); + } + + delete m_oldMargin; + m_oldMargin = NULL; + } + pSlitter->insertWidget(m_indexAtSplitter, this); + QList sizes = pSlitter->sizes(); + if (m_indexAtSplitter + 1 < sizes.count()) + { + sizes[m_indexAtSplitter + 1] += sizes[m_indexAtSplitter] - m_preSize.width() + 1; + } + sizes[m_indexAtSplitter] = m_preSize.width() - 1; + pSlitter->setSizes(sizes); + doShowFrame(true); + m_preParent = NULL; +} + +void GLDDockContainer::doClickBar() +{ + m_titleBar->m_fixedBtn->setInDock(false); + if (dynamic_cast(m_preParent)) + { + doAddToSplitter(); + } + else + { + doShowContainer(); + } +} + +void GLDDockContainer::doShowFrame(bool bHideBar) +{ + m_fixedFrame = true; + if (bHideBar) + { + m_tabBar->hide(); + } + + if (m_titleBar->isVisible()) + { + return; + } + + m_titleBar->show(); + if (m_dockWidget) + { + m_dockWidget->show(); + } + resize(m_preSize); +} + +Qt::Orientation GLDDockContainer::tabTextOrientation() +{ + return m_tabBar->textOrientation(); +} + +void GLDDockContainer::setTabTextOrientation( Qt::Orientation orient ) +{ + m_tabBar->setTextOrientation(orient); +} + +GLDDockContainerTitleButton::GLDDockContainerTitleButton(QWidget *dockWidget) + : QAbstractButton(dockWidget) +{ + setFocusPolicy(Qt::NoFocus); +} + +void GLDDockContainerTitleButton::setInDock(bool value) +{ + if (value && !m_dockIcon.isNull()) + { + setIcon(m_dockIcon); + } + else + { + setIcon(m_icon); + } +} + +QSize GLDDockContainerTitleButton::sizeHint() const +{ + ensurePolished(); + + int nsize = 2 * style()->pixelMetric(QStyle::PM_DockWidgetTitleBarButtonMargin, 0, this); + if (!icon().isNull()) + { + int niconSize = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this); + QSize sz = icon().actualSize(QSize(niconSize, niconSize)); + nsize += qMax(sz.width(), sz.height()); + } + + return QSize(nsize * 1, nsize); +} + +void GLDDockContainerTitleButton::enterEvent(QEvent *event) +{ + if (isEnabled()) + { + update(); + } + + QAbstractButton::enterEvent(event); +} + +void GLDDockContainerTitleButton::leaveEvent(QEvent *event) +{ + if (isEnabled()) + { + update(); + } + + QAbstractButton::leaveEvent(event); +} + +void GLDDockContainerTitleButton::paintEvent(QPaintEvent *event) +{ + QPainter painter(this); + + QStyleOptionToolButton opt; + opt.init(this); + opt.state |= QStyle::State_AutoRaise; + + if (0 != style()->styleHint(QStyle::SH_DockWidget_ButtonsHaveFrame, 0, this)) + { + if (isEnabled() && underMouse() && !isChecked() && !isDown()) + { + opt.state |= QStyle::State_Raised; + } + + if (isChecked()) + { + opt.state |= QStyle::State_On; + } + + if (isDown()) + { + opt.state |= QStyle::State_Sunken; + } + + style()->drawPrimitive(QStyle::PE_PanelButtonTool, &opt, &painter, this); + } + + opt.icon = icon(); + opt.subControls = 0; + opt.activeSubControls = 0; + opt.features = QStyleOptionToolButton::None; + opt.arrowType = Qt::NoArrow; + int nSize = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this); + opt.iconSize = QSize(nSize, nSize); + style()->drawComplexControl(QStyle::CC_ToolButton, &opt, &painter, this); + G_UNUSED(event) +} + +GLDDockContainerTabBar::GLDDockContainerTabBar(QWidget *parent) : QTabBar(parent) + ,m_textOrientation(Qt::Horizontal) +{ + m_inResize = false; +} + +GLDDockContainerTabBar::GLDDockContainerTabBar(QString title, QWidget *parent) + : QTabBar(parent) + , m_title(title) + , m_textOrientation(Qt::Horizontal) +{ + m_inResize = false; +} + +void GLDDockContainerTabBar::setTabsClosable(bool closable) +{ + QTabBar::setTabsClosable(closable); +} + +GString GLDDockContainerTabBar::title() const +{ + return m_title; +} + +void GLDDockContainerTabBar::paintEvent(QPaintEvent *event) +{ +// QTabBar::paintEvent(event); + for (int i = 0; i < count(); i++) + { + QStylePainter painter(this); + QStyleOptionTabV3 tab; + initStyleOption(&tab, i); + if (m_textOrientation == Qt::Vertical) + { + QString oldText = tab.text; + tab.text = ""; + painter.drawControl(QStyle::CE_TabBarTab, tab); + + tab.text= verticalString(oldText); + QTextOption opt; + opt.setAlignment(Qt::AlignCenter); + painter.setPen(tab.palette.color(QPalette::WindowText)); + painter.drawText(tab.rect, tab.text, opt); + } + else + { + painter.drawControl(QStyle::CE_TabBarTab, tab); + } + } + G_UNUSED(event) +} + +void GLDDockContainerTabBar::mousePressEvent(QMouseEvent *event) +{ + emit clicked(); + QTabBar::mousePressEvent(event); +} + +void GLDDockContainerTabBar::initStyleOption(QStyleOptionTab *option, int tabIndex) const +{ + QTabBar::initStyleOption(option, tabIndex); + option->state = 0; + option->state |= QStyle::State_Active; + option->state |= QStyle::State_Enabled; + if (underMouse()) + { + option->state |= QStyle::State_MouseOver; + } +} + +GString GLDDockContainerTabBar::verticalString( const GString &str ) +{ + QChar buffer[255]; + int nChar = 0; + + for (int i = 0; i < str.count(); ++i) + { + buffer[nChar] = str[i]; + buffer[++nChar] = '\n'; + ++nChar; + } + + buffer[nChar - 1] = '\0'; + return GString(buffer); +} + +Qt::Orientation GLDDockContainerTabBar::textOrientation() +{ + return m_textOrientation; +} + +void GLDDockContainerTabBar::setTextOrientation( Qt::Orientation orient ) +{ + m_textOrientation = orient; +} + +GLDDockContainerTitleBar::GLDDockContainerTitleBar(const GString &title, QWidget *parent) : QWidget(parent) +{ + m_title = title; + m_showCloseBtn = true; + this->setObjectName("titleBar"); + init(); +} + +GLDDockContainerTitleBar::~GLDDockContainerTitleBar() +{ + +} + +void GLDDockContainerTitleBar::init() +{ + QStyleOptionDockWidgetV2 opt; + m_fixedBtn = new GLDDockContainerTitleButton(this); + m_fixedBtn->setIcon(style()->standardIcon(QStyle::SP_TitleBarNormalButton, &opt, this)); + m_fixedBtn->setNormIcon(m_fixedBtn->icon()); + m_fixedBtn->resize(m_fixedBtn->sizeHint()); + + m_closeBtn = new GLDDockContainerTitleButton(this); + m_closeBtn->setIcon(style()->standardIcon(QStyle::SP_TitleBarCloseButton, &opt, this)); + m_closeBtn->setNormIcon(m_closeBtn->icon()); + m_closeBtn->resize(m_closeBtn->sizeHint()); + + alignBtns(m_showCloseBtn); +} + +void GLDDockContainerTitleBar::setCloseBtnVisible(bool bShow) +{ + if (m_showCloseBtn == bShow) + { + return; + } + + if (bShow) + { + m_closeBtn->show(); + } + else + { + m_closeBtn->hide(); + } + + m_showCloseBtn = bShow; + alignBtns(m_showCloseBtn); +} + + +void GLDDockContainerTitleBar::paintEvent(QPaintEvent *evente) +{ + QPainter painter(this); + QStyleOptionDockWidget opt; + opt.rect = this->rect(); + opt.rect.adjust(0, -2, 0, 3); + opt.title = m_title; + opt.closable = true; + opt.floatable = true; + opt.verticalTitleBar = false; + + painter.setBrush(opt.palette.background().color().darker(110)); + style()->drawControl(QStyle::CE_DockWidgetTitle, &opt, &painter, this); + G_UNUSED(evente) +} + +void GLDDockContainerTitleBar::resizeEvent(QResizeEvent *event) +{ + QWidget::resizeEvent(event); + alignBtns(m_showCloseBtn); +} + +QSize GLDDockContainerTitleBar::sizeHint() const +{ + return minimumSizeHint(); +} + +QSize GLDDockContainerTitleBar::minimumSizeHint() const +{ + QSize size = QWidget::sizeHint(); + return QSize(qMax(m_closeBtn->width() * 2, size.width()), m_closeBtn->height() + 4); +} + +GLDDockContainerTitleButton *GLDDockContainerTitleBar::fixButton() +{ + return m_fixedBtn; +} + +GLDDockContainerTitleButton *GLDDockContainerTitleBar::closeButton() +{ + return m_closeBtn; +} + +GString GLDDockContainerTitleBar::title() +{ + return m_title; +} + +void GLDDockContainerTitleBar::alignBtns(bool isCloseBtnShow) +{ + if (isCloseBtnShow) + { + m_closeBtn->setGeometry(width() - m_closeBtn->width() - 2, 2, m_closeBtn->width(), m_closeBtn->height()); + m_fixedBtn->setGeometry(m_closeBtn->geometry().left() - m_fixedBtn->width() - 2, + 2, m_fixedBtn->width(), m_fixedBtn->height()); + } + else + { + m_fixedBtn->setGeometry(width() - m_closeBtn->width() - 2, 2, m_closeBtn->width(), m_closeBtn->height()); + } +} + +//标题栏由图片构成的实现 +GLDDockContainerImageTitleBar::GLDDockContainerImageTitleBar(const GString &title, QWidget *parent) + : GLDDockContainerTitleBar(title, parent) + , m_textColor(0,0,0) + , m_useCustomPixmap(false) + , m_textAlignment(Qt::AlignLeft | Qt::AlignVCenter) + , m_textMargins(30,1,30,1) +{ + +} + +GLDDockContainerImageTitleBar::~GLDDockContainerImageTitleBar() +{ +} + +void GLDDockContainerImageTitleBar::setCustomTitlePixmap(const QPixmap &leftPm, const QPixmap ¢erPm, const QPixmap &rightPm) +{ + m_leftPm = leftPm; + m_rightPm = rightPm; + m_centerPm = centerPm; +} + +void GLDDockContainerImageTitleBar::setUseCustomPixmap(bool used) +{ + m_useCustomPixmap = used; + + if (used) + { + fixButton()->setVisible(false); + closeButton()->setVisible(false); + } +} + +void GLDDockContainerImageTitleBar::setTextColor(const QColor &textColor) +{ + m_textColor = textColor; +} + +void GLDDockContainerImageTitleBar::setTextAlignment(Qt::Alignment alignment) +{ + m_textAlignment = alignment; +} + +void GLDDockContainerImageTitleBar::setTextMargins(const QMargins &margins) +{ + m_textMargins = margins; +} + +QColor GLDDockContainerImageTitleBar::textColor() const +{ + return m_textColor; +} + +Qt::Alignment GLDDockContainerImageTitleBar::textAlignment() const +{ + return m_textAlignment; +} + +QMargins GLDDockContainerImageTitleBar::textMargins() const +{ + return m_textMargins; +} + +void GLDDockContainerImageTitleBar::paintEvent(QPaintEvent *event) +{ + QPainter painter(this); + QRect rect(this->rect()); + + if (m_useCustomPixmap) + { + painter.drawPixmap(rect.topLeft(), m_leftPm); + painter.drawPixmap(rect.topRight() - QPoint(m_rightPm.width() - 1, 0), m_rightPm); + QBrush brush(m_centerPm); + QRect centerRect(rect.left() + m_leftPm.width(), rect.top(), + rect.width() - m_leftPm.width() - m_rightPm.width(), + rect.height()); + painter.fillRect(centerRect, brush); + QTextOption textOpt; + textOpt.setAlignment(m_textAlignment); + + //int nFontHeight = painter.fontMetrics().height(); + //int nHalfRemove = (centerRect.height() - nFontHeight) / 2; + + QRect textRect(m_textMargins.left(),m_textMargins.top(),rect.width(),rect.height() - m_textMargins.top() + - m_textMargins.bottom()); + + if (m_textColor.isValid()) + { + painter.setPen(m_textColor); + } + + painter.setFont(font()); + painter.drawText(textRect, title(), textOpt); + } + else + { + GLDDockContainerTitleBar::paintEvent(event); + } +} + +void GLDDockContainerImageTitleBar::mousePressEvent(QMouseEvent *event) +{ + QPoint pos = event->pos(); + QRect rect = this->rect(); + + if (m_useCustomPixmap) + { + const int buttonWidth = m_rightPm.width(); + QRect rightRect(rect.right() - buttonWidth, 0, buttonWidth, rect.height()); + + if (rightRect.contains(pos)) + { + fixButton()->click(); + } + } + else + { + GLDDockContainerTitleBar::mousePressEvent(event); + } +} + +GLDDockContainerImageTabBar::GLDDockContainerImageTabBar(QString title, QWidget *parent) + : GLDDockContainerTabBar(parent) + , m_usePixmap(false) + , m_title(title) + , m_textColor(0, 0, 0) + , m_textAlignment(Qt::AlignHCenter | Qt::AlignTop) + , m_textMargins(1, 10, 1, 10) +{ + +} + +void GLDDockContainerImageTabBar::setCustomTitlePixmap(const QPixmap &leftPm, const QPixmap ¢erPm, const QPixmap &rightPm) +{ + m_leftPm = leftPm; + m_rightPm = rightPm; + m_centerPm = centerPm; +} + +void GLDDockContainerImageTabBar::setUseCustomPixmap(bool used) +{ + m_usePixmap = used; +} + +void GLDDockContainerImageTabBar::paintEvent(QPaintEvent *event) +{ + if (m_usePixmap) + { + for (int i = 0; i < count(); i++) + { + QStyleOptionTabV3 tab; + initStyleOption(&tab, i); + QBrush centerBrush(m_centerPm); + + QRect vRect(tab.rect);//竖 + QSize vSize = this->sizeHint(); //竖 + QSize hSize(vSize);//横 + hSize.transpose(); + + vRect.setSize(vSize); + + QRect hRect(vRect); + hRect.setSize(hSize); + + QRect centerRect(hRect); + QSize centerSize(hRect.width() - m_leftPm.width() - m_rightPm.width(), hRect.height()); + centerRect.setSize(centerSize); + centerRect.translate(m_leftPm.width(), 0); + + // 转换坐标系 + QStylePainter vPainter(this); + vPainter.translate(vRect.width(), 0); + vPainter.rotate(90); + + QRect textRect(vRect.left() - m_textMargins.left(), vRect.top() + m_textMargins.top(), + vRect.width() - m_textMargins.left() - m_textMargins.right(), vRect.height() - m_textMargins.top() - m_textMargins.bottom()); + + + vPainter.drawPixmap(hRect.topLeft(), m_leftPm); + + vPainter.fillRect(centerRect, centerBrush); + vPainter.drawPixmap(centerRect.topRight(), m_rightPm); + vPainter.rotate(-90); + vPainter.translate(-vRect.width(), 0); + + if (m_textColor.isValid()) + { + vPainter.setPen(m_textColor); + } + + QTextOption textOpt; + textOpt.setAlignment(m_textAlignment); + vPainter.drawText(textRect, verticalTitle(), textOpt); + } + } + else + { + GLDDockContainerTabBar::paintEvent(event); + } +} + +QString GLDDockContainerImageTabBar::verticalTitle() +{ + QChar buffer[255]; + int nChar = 0; + + for (int i = 0; i < m_title.count(); ++i) + { + buffer[nChar] = m_title[i]; + buffer[++nChar] = '\n'; + ++nChar; + } + + buffer[nChar - 1] = '\0'; + return QString(buffer); +} + +QSize GLDDockContainerImageTabBar::sizeHint() const +{ + if (m_size.isValid()) + { + return m_size; + } + + return GLDDockContainerTabBar::sizeHint(); +} + +void GLDDockContainerImageTabBar::setSize(const QSize &size) +{ + m_size = size; +} + +void GLDDockContainerImageTabBar::setTextColor(const QColor &textColor) +{ + m_textColor = textColor; +} + +void GLDDockContainerImageTabBar::setTextMargins(const QMargins &margins) +{ + m_textMargins = margins; +} + +void GLDDockContainerImageTabBar::setTextAlignment(Qt::Alignment alignment) +{ + m_textAlignment = alignment; +} + +QSize GLDDockContainerImageTabBar::size() const +{ + return m_size; +} + +QColor GLDDockContainerImageTabBar::textColor() const +{ + return m_textColor; +} + +QMargins GLDDockContainerImageTabBar::textMargins() const +{ + return m_textMargins; +} + +Qt::Alignment GLDDockContainerImageTabBar::textAlignment() const +{ + return m_textAlignment; +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockArrows.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockArrows.cpp new file mode 100644 index 00000000..1ef044f8 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockArrows.cpp @@ -0,0 +1,207 @@ +#include "GLDDockArrows.h" +#include +#include +#include +#include +#include + +class QArrowWidget : public QWidget +{ +public: + explicit QArrowWidget(const char *imgPath, GLDDockArrows *arrows, DockArea area, QWidget *parent) + : QWidget(parent, Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint), pixmap(imgPath), arrows_(arrows), area_(area) + { + setAttribute(Qt::WA_TranslucentBackground); + resize(pixmap.size()); + } + +private: + QPixmap pixmap; + GLDDockArrows *arrows_; + DockArea area_; +protected: + void paintEvent(QPaintEvent *) + { + QPainter painter(this); + painter.drawPixmap(0, 0, pixmap); + } +}; + +GLDDockArrows::GLDDockArrows(QWidget *parent) + : QObject(parent), + leftWid(new QArrowWidget(":/icons/GLDDockPanel/left.png", this, LeftArea, parent)), + rightWid(new QArrowWidget(":/icons/GLDDockPanel/right.png", this, RightArea, parent)), + topWid(new QArrowWidget(":/icons/GLDDockPanel/top.png", this, TopArea, parent)), + bottomWid(new QArrowWidget(":/icons/GLDDockPanel/bottom.png", this, BottomArea, parent)), + centerWid(new QArrowWidget(":/icons/GLDDockPanel/center.png", this, CenterArea, parent)), + centerLeftWid(new QArrowWidget(":/icons/GLDDockPanel/left.png", this, CenterLeftArea, parent)), + centerRightWid(new QArrowWidget(":/icons/GLDDockPanel/right.png", this, CenterRightArea, parent)), + centerTopWid(new QArrowWidget(":/icons/GLDDockPanel/top.png", this, CenterTopArea, parent)), + centerBottomWid(new QArrowWidget(":/icons/GLDDockPanel/bottom.png", this, CenterBottomArea, parent)), + parentWid(parent) +{ + leftWid->hide(); + rightWid->hide(); + topWid->hide(); + bottomWid->hide(); + centerWid->hide(); + centerLeftWid->hide(); + centerRightWid->hide(); + centerTopWid->hide(); + centerBottomWid->hide(); +} + +void GLDDockArrows::show(int dockArea) +{ + int w = parentWid->width(); + int h = parentWid->height(); + + if (dockArea & LeftArea) + { + leftWid->move(0, (h - leftWid->height()) / 2); + leftWid->show(); + leftWid->raise(); + } + else + { + leftWid->hide(); + } + + if (dockArea & RightArea) + { + rightWid->move(w - rightWid->width(), (h - rightWid->height()) / 2); + rightWid->show(); + rightWid->raise(); + } + else + { + rightWid->hide(); + } + + if (dockArea & TopArea) + { + topWid->move((w - rightWid->width()) / 2, 0); + topWid->show(); + topWid->raise(); + } + else + { + topWid->hide(); + } + + if (dockArea & BottomArea) + { + bottomWid->move((w - rightWid->width()) / 2, h - bottomWid->height()); + bottomWid->show(); + bottomWid->raise(); + } + else + { + bottomWid->hide(); + } + + if (dockArea & CenterArea) + { + centerWid->move((w - centerWid->width()) / 2, (h - leftWid->height()) / 2); + centerWid->show(); + centerWid->raise(); + } + else + { + centerWid->hide(); + } + + if (dockArea & CenterLeftArea) + { + centerLeftWid->move((w - centerLeftWid->width()) / 2 - centerLeftWid->width(), (h - centerLeftWid->height()) / 2); + centerLeftWid->show(); + centerLeftWid->raise(); + } + else + { + centerLeftWid->hide(); + } + + if (dockArea & CenterRightArea) + { + centerRightWid->move((w - centerRightWid->width()) / 2 + centerRightWid->width(), (h - centerRightWid->height()) / 2); + centerRightWid->show(); + centerRightWid->raise(); + } + else + { + centerRightWid->hide(); + } + + if (dockArea & CenterTopArea) + { + centerTopWid->move((w - centerTopWid->width()) / 2, (h - centerTopWid->height()) / 2 - centerTopWid->height()); + centerTopWid->show(); + centerTopWid->raise(); + } + else + { + centerTopWid->hide(); + } + + if (dockArea & CenterBottomArea) + { + centerBottomWid->move((w - centerBottomWid->width()) / 2, (h - centerBottomWid->height()) / 2 + centerBottomWid->height()); + centerBottomWid->show(); + centerBottomWid->raise(); + } + else + { + centerBottomWid->hide(); + } +} + +DockArea GLDDockArrows::getDockAreaByPos(QPoint pos) +{ + if (leftWid->isVisible() && leftWid->geometry().contains(pos)) + { + return LeftArea; + } + + if (rightWid->isVisible() && rightWid->geometry().contains(pos)) + { + return RightArea; + } + + if (topWid->isVisible() && topWid->geometry().contains(pos)) + { + return TopArea; + } + + if (bottomWid->isVisible() && bottomWid->geometry().contains(pos)) + { + return BottomArea; + } + + if (centerWid->isVisible() && centerWid->geometry().contains(pos)) + { + return CenterArea; + } + + if (centerLeftWid->isVisible() && centerLeftWid->geometry().contains(pos)) + { + return CenterLeftArea; + } + + if (centerRightWid->isVisible() && centerRightWid->geometry().contains(pos)) + { + return CenterRightArea; + } + + if (centerTopWid->isVisible() && centerTopWid->geometry().contains(pos)) + { + return CenterTopArea; + } + + if (centerBottomWid->isVisible() && centerBottomWid->geometry().contains(pos)) + { + return CenterBottomArea; + } + + return NoneArea; +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockArrows.h b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockArrows.h new file mode 100644 index 00000000..533957cb --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockArrows.h @@ -0,0 +1,37 @@ +#ifndef GLDDockARROWS_H +#define GLDDockARROWS_H + +#include +#include +#include + +#include "GLDDockCommon.h" + +class QArrowWidget; + +class GLDDockArrows : public QObject +{ + Q_OBJECT +public: + explicit GLDDockArrows(QWidget *parent = 0); + + void show(int dockArea); + + DockArea getDockAreaByPos(QPoint pos); +private: + QArrowWidget *leftWid; + QArrowWidget *topWid; + QArrowWidget *rightWid; + QArrowWidget *bottomWid; + QArrowWidget *centerWid; + QArrowWidget *centerLeftWid; + QArrowWidget *centerRightWid; + QArrowWidget *centerTopWid; + QArrowWidget *centerBottomWid; + + QWidget *parentWid; +public slots: + +}; + +#endif // GLDDockARROWS_H diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockDataBuilder.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockDataBuilder.cpp new file mode 100644 index 00000000..6b3548f4 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockDataBuilder.cpp @@ -0,0 +1,29 @@ +#include "GLDDockDataBuilder.h" +#include +#include "GLDGlobal.h" + +GLDDockDataBuilder::GLDDockDataBuilder(void) +{ +} + +GLDDockDataBuilder::~GLDDockDataBuilder(void) +{ +} + +QByteArray GLDDockDataBuilder::toByteArray() +{ + QByteArray ba(sizeof(data_) + 1, '\0'); + gMemCopy(ba.data(), &data_, sizeof(data_)); + return ba; +} + +bool GLDDockDataBuilder::fromByteArray(const QByteArray &ba) +{ + if (ba.size() != sizeof(data_) + 1) + { + return false; + } + + gMemCopy(&data_, ba.data(), sizeof(data_)); + return true; +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockDataBuilder.h b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockDataBuilder.h new file mode 100644 index 00000000..ea427560 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockDataBuilder.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include + +class GLDDockDataBuilder +{ +public: + GLDDockDataBuilder(void); + ~GLDDockDataBuilder(void); + + QByteArray toByteArray(); + bool fromByteArray(const QByteArray &ba); + void setWidget(QWidget *widget) + { + data_.widget = widget; + } + QWidget *getWidget() + { + return data_.widget; + } +private: + struct + { + QWidget *widget; + } data_; +}; + diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockFrame.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockFrame.cpp new file mode 100644 index 00000000..66ec2079 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockFrame.cpp @@ -0,0 +1,152 @@ +#include "GLDDockFrame.h" +#include +#include +#include "GLDDockNode.h" +#include "GLDDockMaskWidget.h" +#include +#include +#include "GLDDockPanel.h" +#include "GLDDockDataBuilder.h" +#include "GLDDockManager.h" +#include "GLDDockArrows.h" + +GLDDockFrame::GLDDockFrame(GLDDockManager *manager, QWidget *parent) + : QWidget(parent) + , m_pArrows(nullptr) + , manager_(manager) + , lastMaskArea_(NoneArea) +{ + rootNode_ = new GLDDockNode(this); + maskWidget_ = new GLDDockMaskWidget(this); + maskWidget_->hide(); + + m_pArrows = new GLDDockArrows(this); + setAcceptDrops(true); +} + +GLDDockFrame::~GLDDockFrame() +{ + delete m_pArrows; +} + +void GLDDockFrame::showArrow() +{ + if (rootNode_->count() == 0) + { + m_pArrows->show(CenterArea); + } + else + { + m_pArrows->show(LeftArea | TopArea | RightArea | BottomArea); + } +} + +void GLDDockFrame::dragEnterEvent(QDragEnterEvent *e) +{ + const QMimeData *mimeData = e->mimeData(); + + if (mimeData && mimeData->hasFormat("dockpanellib/dockdata")) + { + showArrow(); + e->accept(); + } + else + { + e->ignore(); + } +} + +void GLDDockFrame::dragMoveEvent(QDragMoveEvent *e) +{ + DockArea area = m_pArrows->getDockAreaByPos(mapFromGlobal(QCursor::pos())); + + if (area != lastMaskArea_) + { + maskWidget_->showOnDockArea(area); + lastMaskArea_ = area; + } + + e->accept(); +} + +void GLDDockFrame::dragLeaveEvent(QDragLeaveEvent *e) +{ + if (!rect().contains(mapFromGlobal(QCursor::pos()))) + { + m_pArrows->show(NoneArea); + } + + lastMaskArea_ = NoneArea; + maskWidget_->showOnDockArea(NoneArea); + e->accept(); +} + +void GLDDockFrame::dropEvent(QDropEvent *e) +{ + const QMimeData *mimeData = e->mimeData(); + + if (!mimeData->hasFormat("dockpanellib/dockdata")) + { + e->ignore(); + return; + } + + QByteArray ba = mimeData->data("dockpanellib/dockdata"); + GLDDockDataBuilder builder; + builder.fromByteArray(ba); + + GLDDockPanel *panel = qobject_cast(builder.getWidget()); + + if (panel && lastMaskArea_ != NoneArea) + { + manager_->dockPanelToFrame(panel, lastMaskArea_); + e->accept(); + } + else + { + e->ignore(); + } + + lastMaskArea_ = NoneArea; + m_pArrows->show(NoneArea); + maskWidget_->showOnDockArea(NoneArea); +} + +void GLDDockFrame::resizeEvent(QResizeEvent *) +{ + relayout(); +} + +void GLDDockFrame::relayout() +{ + rootNode_->setGeometry(rect()); + + if (!rootNode_->isVisible()) + { + rootNode_->show(); + } +} + +void GLDDockFrame::onDragEnterPanel() +{ + showArrow(); + maskWidget_->showOnDockArea(NoneArea); +} + +void GLDDockFrame::onDragLeavePanel() +{ + if (!rect().contains(mapFromGlobal(QCursor::pos()))) + { + m_pArrows->show(NoneArea); + } + + lastMaskArea_ = NoneArea; + maskWidget_->showOnDockArea(NoneArea); +} + +void GLDDockFrame::onEndDragAtPanel() +{ + m_pArrows->show(NoneArea); + lastMaskArea_ = NoneArea; + maskWidget_->showOnDockArea(NoneArea); +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockManager.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockManager.cpp new file mode 100644 index 00000000..4c89a050 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockManager.cpp @@ -0,0 +1,1063 @@ +#include "GLDDockManager.h" +#include "GLDDockFrame.h" +#include "GLDDockPanel.h" +#include +#include "GLDDockNode.h" +#include +#include "GLDDockMaskWidget.h" +#include "GLDDockTabWidget.h" + +GLDDockManager::GLDDockManager(QWidget *parent) + : QObject(parent), dockFrmae_(new GLDDockFrame(this, parent)) +{ + +} + +GLDDockManager::~GLDDockManager() +{ + +} + +GLDDockPanel *GLDDockManager::addPanel(int id, const QString &title, QPoint pos, QSize size, QWidget *contensWidget /*= NULL*/) +{ + if (dockPanels_.find(id) != dockPanels_.end()) + { + return NULL; + } + + GLDDockPanel *p = new GLDDockPanel(this, dockFrmae_); + p->setId(id); + p->setWindowTitle(title); + p->resetContensWidget(contensWidget); + p->move(pos); + p->resize(size); + p->show(); + dockPanels_.insert(std::make_pair(id, p)); + + return p; +} + +GLDDockPanel *GLDDockManager::getDockPanelByID(int id) +{ + std::map::iterator it = dockPanels_.find(id); + + if (it == dockPanels_.end()) + { + return NULL; + } + + return it->second; +} + +bool GLDDockManager::dockPanelToFrame(GLDDockPanel *panel, DockArea area) +{ + if (panel->panelType_ == GLDDockPanel::SplitContainer) + { + GLDDockNode *fromNode = qobject_cast(panel->contensWidget_); + assert(fromNode); + panel->deleteLater(); + + switch (area) + { + case LeftArea: + { + QList sizes; + sizes.push_back(30); + sizes.push_back(70); + + int c = dockFrmae_->rootNode_->count(); + + if (c == 1) + { + dockFrmae_->rootNode_->setOrientation(Qt::Horizontal); + dockFrmae_->rootNode_->insertWidget(0, fromNode); + dockFrmae_->rootNode_->setSizes(sizes); + } + else if (c == 2) + { + GLDDockNode *tmpNode = dockFrmae_->rootNode_; + dockFrmae_->rootNode_ = new GLDDockNode(dockFrmae_); + dockFrmae_->rootNode_->setOrientation(Qt::Horizontal); + dockFrmae_->rootNode_->insertWidget(0, fromNode); + dockFrmae_->rootNode_->insertWidget(1, tmpNode); + dockFrmae_->relayout(); + dockFrmae_->rootNode_->setSizes(sizes); + } + else + { + assert(false); + } + + break; + } + + case TopArea: + { + QList sizes; + sizes.push_back(30); + sizes.push_back(70); + + int c = dockFrmae_->rootNode_->count(); + + if (c == 1) + { + dockFrmae_->rootNode_->setOrientation(Qt::Vertical); + dockFrmae_->rootNode_->insertWidget(0, fromNode); + dockFrmae_->rootNode_->setSizes(sizes); + } + else if (c == 2) + { + GLDDockNode *tmpNode = dockFrmae_->rootNode_; + dockFrmae_->rootNode_ = new GLDDockNode(dockFrmae_); + dockFrmae_->rootNode_->setOrientation(Qt::Vertical); + dockFrmae_->rootNode_->insertWidget(0, fromNode); + dockFrmae_->rootNode_->insertWidget(1, tmpNode); + dockFrmae_->relayout(); + dockFrmae_->rootNode_->setSizes(sizes); + } + else + { + assert(false); + } + + break; + } + + case RightArea: + { + QList sizes; + sizes.push_back(70); + sizes.push_back(30); + + int c = dockFrmae_->rootNode_->count(); + + if (c == 1) + { + dockFrmae_->rootNode_->setOrientation(Qt::Horizontal); + dockFrmae_->rootNode_->insertWidget(1, fromNode); + dockFrmae_->rootNode_->setSizes(sizes); + } + else if (c == 2) + { + GLDDockNode *tmpNode = dockFrmae_->rootNode_; + dockFrmae_->rootNode_ = new GLDDockNode(dockFrmae_); + dockFrmae_->rootNode_->setOrientation(Qt::Horizontal); + dockFrmae_->rootNode_->insertWidget(0, tmpNode); + dockFrmae_->rootNode_->insertWidget(1, fromNode); + dockFrmae_->relayout(); + dockFrmae_->rootNode_->setSizes(sizes); + } + else + { + assert(false); + } + + break; + } + + case BottomArea: + { + QList sizes; + sizes.push_back(70); + sizes.push_back(30); + + int c = dockFrmae_->rootNode_->count(); + + if (c == 1) + { + dockFrmae_->rootNode_->setOrientation(Qt::Vertical); + dockFrmae_->rootNode_->insertWidget(0, fromNode); + dockFrmae_->rootNode_->setSizes(sizes); + } + else if (c == 2) + { + GLDDockNode *tmpNode = dockFrmae_->rootNode_; + dockFrmae_->rootNode_ = new GLDDockNode(dockFrmae_); + dockFrmae_->rootNode_->setOrientation(Qt::Vertical); + dockFrmae_->rootNode_->insertWidget(0, tmpNode); + dockFrmae_->rootNode_->insertWidget(1, fromNode); + dockFrmae_->relayout(); + dockFrmae_->rootNode_->setSizes(sizes); + } + else + { + assert(false); + } + + break; + } + + case CenterArea: + assert(dockFrmae_->rootNode_->count() == 0); + dockFrmae_->rootNode_->deleteLater(); + dockFrmae_->rootNode_ = fromNode; + fromNode->show(); + fromNode->setParent(dockFrmae_); + dockFrmae_->relayout(); + break; + + default: + return false; + } + + return true; + } + + + switch (area) + { + case LeftArea: + { + QList sizes; + sizes.push_back(30); + sizes.push_back(70); + + int c = dockFrmae_->rootNode_->count(); + + if (c == 1) + { + dockFrmae_->rootNode_->setOrientation(Qt::Horizontal); + panel->setDockStatus(); + dockFrmae_->rootNode_->insertWidget(0, panel); + dockFrmae_->rootNode_->setSizes(sizes); + } + else if (c == 2) + { + GLDDockNode *tmpNode = dockFrmae_->rootNode_; + panel->setDockStatus(); + dockFrmae_->rootNode_ = new GLDDockNode(dockFrmae_); + dockFrmae_->rootNode_->setOrientation(Qt::Horizontal); + dockFrmae_->rootNode_->insertWidget(0, panel); + dockFrmae_->rootNode_->insertWidget(1, tmpNode); + dockFrmae_->relayout(); + dockFrmae_->rootNode_->setSizes(sizes); + } + else + { + assert(false); + } + + break; + } + + case TopArea: + { + QList sizes; + sizes.push_back(30); + sizes.push_back(70); + + int c = dockFrmae_->rootNode_->count(); + + if (c == 1) + { + dockFrmae_->rootNode_->setOrientation(Qt::Vertical); + panel->setDockStatus(); + dockFrmae_->rootNode_->insertWidget(0, panel); + dockFrmae_->rootNode_->setSizes(sizes); + } + else if (c == 2) + { + GLDDockNode *tmpNode = dockFrmae_->rootNode_; + panel->setDockStatus(); + dockFrmae_->rootNode_ = new GLDDockNode(dockFrmae_); + dockFrmae_->rootNode_->setOrientation(Qt::Vertical); + dockFrmae_->rootNode_->insertWidget(0, panel); + dockFrmae_->rootNode_->insertWidget(1, tmpNode); + dockFrmae_->relayout(); + dockFrmae_->rootNode_->setSizes(sizes); + } + else + { + assert(false); + } + + break; + } + + case RightArea: + { + QList sizes; + sizes.push_back(70); + sizes.push_back(30); + + int c = dockFrmae_->rootNode_->count(); + + if (c == 1) + { + dockFrmae_->rootNode_->setOrientation(Qt::Horizontal); + panel->setDockStatus(); + dockFrmae_->rootNode_->insertWidget(1, panel); + dockFrmae_->rootNode_->setSizes(sizes); + } + else if (c == 2) + { + GLDDockNode *tmpNode = dockFrmae_->rootNode_; + panel->setDockStatus(); + dockFrmae_->rootNode_ = new GLDDockNode(dockFrmae_); + dockFrmae_->rootNode_->setOrientation(Qt::Horizontal); + dockFrmae_->rootNode_->insertWidget(0, tmpNode); + dockFrmae_->rootNode_->insertWidget(1, panel); + dockFrmae_->relayout(); + dockFrmae_->rootNode_->setSizes(sizes); + } + else + { + assert(false); + } + + break; + } + + case BottomArea: + { + QList sizes; + sizes.push_back(70); + sizes.push_back(30); + + int c = dockFrmae_->rootNode_->count(); + + if (c == 1) + { + dockFrmae_->rootNode_->setOrientation(Qt::Vertical); + panel->setDockStatus(); + dockFrmae_->rootNode_->insertWidget(0, panel); + dockFrmae_->rootNode_->setSizes(sizes); + } + else if (c == 2) + { + GLDDockNode *tmpNode = dockFrmae_->rootNode_; + panel->setDockStatus(); + dockFrmae_->rootNode_ = new GLDDockNode(dockFrmae_); + dockFrmae_->rootNode_->setOrientation(Qt::Vertical); + dockFrmae_->rootNode_->insertWidget(0, tmpNode); + dockFrmae_->rootNode_->insertWidget(1, panel); + dockFrmae_->relayout(); + dockFrmae_->rootNode_->setSizes(sizes); + } + else + { + assert(false); + } + + break; + } + + case CenterArea: + assert(dockFrmae_->rootNode_->count() == 0); + panel->setDockStatus(); + panel->setParent(dockFrmae_->rootNode_); + break; + + default: + return false; + } + + return true; +} + +bool GLDDockManager::dockPanelToPanel(GLDDockPanel *from, GLDDockPanel *target, DockArea area) +{ + if (target->isDocked()) + { + return dockPanelToDockedPanel(from, target, area); + } + else + { + QTimer *t = new QTimer; + QObject::connect(t, &QTimer::timeout, [ = ]() + { + t->deleteLater(); + dockPanelToFloatPanel(from, target, area); + }); + t->start(1); + + return true; + } + + return false; +} + +bool GLDDockManager::isRootNode(GLDDockNode *node) +{ + return node == dockFrmae_->rootNode_; +} + +void GLDDockManager::undockPanel(GLDDockPanel *panel) +{ + GLDDockNode *parentNode = qobject_cast(panel->parentWidget()); + + if (parentNode) + { + panel->setParent(dockFrmae_); + panel->setFloatStatus(); + + if (isRootNode(parentNode)) + { + GLDDockNode *otherChildNode = qobject_cast(parentNode->widget(0)); + + if (otherChildNode) + { + QList sizes = otherChildNode->sizes(); + parentNode->setOrientation(otherChildNode->orientation()); + parentNode->insertWidget(0, otherChildNode->widget(0)); + parentNode->insertWidget(1, otherChildNode->widget(0)); + parentNode->setSizes(sizes); + otherChildNode->deleteLater(); + } + + return; + } + + assert(parentNode->count() == 1); + + GLDDockPanel *containerPanel = qobject_cast(parentNode->parentWidget()); + + if (containerPanel) + { + QWidget *widget = parentNode->widget(0); + GLDDockPanel *otherPanel = qobject_cast(widget); + + if (otherPanel) + { + otherPanel->setParent(dockFrmae_); + otherPanel->setFloatStatus(); + otherPanel->resize(containerPanel->size()); + otherPanel->move(containerPanel->pos()); + otherPanel->show(); + containerPanel->close(); + containerPanel->deleteLater(); + } + else if (GLDDockNode *otherNode = qobject_cast(widget)) + { + containerPanel->contensWidget_->deleteLater(); + containerPanel->resetContensWidget(otherNode); + otherNode->show(); + } + else + { + assert(false); + } + } + else + { + GLDDockNode *grandParentNode = qobject_cast(parentNode->parentWidget()); + assert(grandParentNode); + QList sizes = grandParentNode->sizes(); + QWidget *widget = parentNode->widget(0); + int index = grandParentNode->indexOf(parentNode); + parentNode->close(); + parentNode->deleteLater(); + grandParentNode->insertWidget(index, widget); + grandParentNode->setSizes(sizes); + + } + + return; + } + + panel->setParent(dockFrmae_); + panel->setFloatStatus(); + + return; +} + +void GLDDockManager::onDragEnterPanel() +{ + dockFrmae_->onDragEnterPanel(); +} + +void GLDDockManager::onDragLeavePanel() +{ + dockFrmae_->onDragLeavePanel(); +} + +void GLDDockManager::onEndDragAtPanel() +{ + dockFrmae_->onEndDragAtPanel(); +} + +bool GLDDockManager::dockPanelToFloatPanel(GLDDockPanel *from, GLDDockPanel *target, DockArea area) +{ + if (from->panelType_ == GLDDockPanel::TabContainer) + { + switch (area) + { + case CenterArea: + { + GLDDockTabWidget *tabWidget = qobject_cast(from->contensWidget_); + assert(tabWidget); + from->move(target->pos()); + from->resize(target->size()); + tabWidget->addTab(target, target->windowTitle()); + target->setDockStatus(); + target->setTabbedStatus(true, from); + } + break; + + case CenterLeftArea: + { + GLDDockPanel *tabPanel = new GLDDockPanel(this, dockFrmae_); + tabPanel->panelType_ = GLDDockPanel::SplitContainer; + tabPanel->resize(target->size()); + tabPanel->move(target->pos()); + tabPanel->setAcceptDrops(false); + GLDDockNode *node = new GLDDockNode(tabPanel); + tabPanel->resetContensWidget(node); + node->setOrientation(Qt::Horizontal); + from->setDockStatus(); + target->setDockStatus(); + node->insertWidget(0, from); + node->insertWidget(1, target); + tabPanel->setWindowTitle(QString("%1 & %2").arg(from->windowTitle()).arg(target->windowTitle())); + tabPanel->show(); + } + break; + + case CenterTopArea: + { + GLDDockPanel *tabPanel = new GLDDockPanel(this, dockFrmae_); + tabPanel->panelType_ = GLDDockPanel::SplitContainer; + tabPanel->resize(target->size()); + tabPanel->move(target->pos()); + tabPanel->setAcceptDrops(false); + GLDDockNode *node = new GLDDockNode(tabPanel); + tabPanel->resetContensWidget(node); + node->setOrientation(Qt::Vertical); + from->setDockStatus(); + target->setDockStatus(); + node->insertWidget(0, from); + node->insertWidget(1, target); + tabPanel->setWindowTitle(QString("%1 & %2").arg(from->windowTitle()).arg(target->windowTitle())); + tabPanel->show(); + } + break; + + case CenterRightArea: + { + GLDDockPanel *tabPanel = new GLDDockPanel(this, dockFrmae_); + tabPanel->panelType_ = GLDDockPanel::SplitContainer; + tabPanel->resize(target->size()); + tabPanel->move(target->pos()); + tabPanel->setAcceptDrops(false); + GLDDockNode *node = new GLDDockNode(tabPanel); + tabPanel->resetContensWidget(node); + node->setOrientation(Qt::Horizontal); + from->setDockStatus(); + target->setDockStatus(); + node->insertWidget(0, target); + node->insertWidget(1, from); + tabPanel->setWindowTitle(QString("%1 & %2").arg(target->windowTitle()).arg(from->windowTitle())); + tabPanel->show(); + } + break; + + case CenterBottomArea: + { + GLDDockPanel *tabPanel = new GLDDockPanel(this, dockFrmae_); + tabPanel->panelType_ = GLDDockPanel::SplitContainer; + tabPanel->resize(target->size()); + tabPanel->move(target->pos()); + tabPanel->setAcceptDrops(false); + GLDDockNode *node = new GLDDockNode(tabPanel); + tabPanel->resetContensWidget(node); + node->setOrientation(Qt::Vertical); + from->setDockStatus(); + target->setDockStatus(); + node->insertWidget(0, target); + node->insertWidget(1, from); + tabPanel->setWindowTitle(QString("%1 & %2").arg(target->windowTitle()).arg(from->windowTitle())); + tabPanel->show(); + } + break; + default: + break; + } + + return true; + } + + + if (from->panelType_ == GLDDockPanel::SplitContainer) + { + switch (area) + { + case CenterArea: + { + + } + break; + + case CenterLeftArea: + { + QWidget *tmp = from->contensWidget_; + GLDDockNode *node = new GLDDockNode(from); + from->resetContensWidget(node); + node->setOrientation(Qt::Horizontal); + node->show(); + + from->move(target->pos()); + from->resize(target->size()); + + node->insertWidget(0, tmp); + target->setDockStatus(); + node->insertWidget(1, target); + } + break; + + case CenterTopArea: + { + QWidget *tmp = from->contensWidget_; + GLDDockNode *node = new GLDDockNode(from); + from->resetContensWidget(node); + node->setOrientation(Qt::Vertical); + node->show(); + + from->move(target->pos()); + from->resize(target->size()); + + node->insertWidget(0, tmp); + target->setDockStatus(); + node->insertWidget(1, target); + } + break; + + case CenterRightArea: + { + QWidget *tmp = from->contensWidget_; + GLDDockNode *node = new GLDDockNode(from); + from->resetContensWidget(node); + node->setOrientation(Qt::Horizontal); + node->show(); + + from->move(target->pos()); + from->resize(target->size()); + + target->setDockStatus(); + node->insertWidget(0, target); + node->insertWidget(1, tmp); + } + break; + + case CenterBottomArea: + { + QWidget *tmp = from->contensWidget_; + GLDDockNode *node = new GLDDockNode(from); + from->resetContensWidget(node); + node->setOrientation(Qt::Vertical); + node->show(); + + from->move(target->pos()); + from->resize(target->size()); + + target->setDockStatus(); + node->insertWidget(0, target); + node->insertWidget(1, tmp); + } + break; + default: + break; + } + + return true; + } + + switch (area) + { + case CenterArea: + { + GLDDockPanel *tabPanel = new GLDDockPanel(this, dockFrmae_); + tabPanel->panelType_ = GLDDockPanel::TabContainer; + tabPanel->resize(target->size()); + tabPanel->move(target->pos()); + tabPanel->setAcceptDrops(false); + GLDDockTabWidget *tabWidget = new GLDDockTabWidget(tabPanel); + tabPanel->resetContensWidget(tabWidget); + tabWidget->addTab(target, target->windowTitle()); + target->setDockStatus(); + target->setTabbedStatus(true, tabPanel); + from->setDockStatus(); + from->setTabbedStatus(true, tabPanel); + tabWidget->addTab(from, from->windowTitle()); + connect(tabWidget, SIGNAL(setBasePanelTitle(const QString &)), tabPanel, SLOT(setWindowTitle(const QString &))); + tabPanel->setWindowTitle(tabWidget->currentWidget()->windowTitle()); + tabPanel->show(); + } + break; + + case CenterLeftArea: + { + GLDDockPanel *tabPanel = new GLDDockPanel(this, dockFrmae_); + tabPanel->panelType_ = GLDDockPanel::SplitContainer; + tabPanel->resize(target->size()); + tabPanel->move(target->pos()); + tabPanel->setAcceptDrops(false); + GLDDockNode *node = new GLDDockNode(tabPanel); + tabPanel->resetContensWidget(node); + node->setOrientation(Qt::Horizontal); + from->setDockStatus(); + target->setDockStatus(); + node->insertWidget(0, from); + node->insertWidget(1, target); + tabPanel->setWindowTitle(QString("%1 & %2").arg(from->windowTitle()).arg(target->windowTitle())); + tabPanel->show(); + } + break; + + case CenterTopArea: + { + GLDDockPanel *tabPanel = new GLDDockPanel(this, dockFrmae_); + tabPanel->panelType_ = GLDDockPanel::SplitContainer; + tabPanel->resize(target->size()); + tabPanel->move(target->pos()); + tabPanel->setAcceptDrops(false); + GLDDockNode *node = new GLDDockNode(tabPanel); + tabPanel->resetContensWidget(node); + node->setOrientation(Qt::Vertical); + from->setDockStatus(); + target->setDockStatus(); + node->insertWidget(0, from); + node->insertWidget(1, target); + tabPanel->setWindowTitle(QString("%1 & %2").arg(from->windowTitle()).arg(target->windowTitle())); + tabPanel->show(); + } + break; + + case CenterRightArea: + { + GLDDockPanel *tabPanel = new GLDDockPanel(this, dockFrmae_); + tabPanel->panelType_ = GLDDockPanel::SplitContainer; + tabPanel->resize(target->size()); + tabPanel->move(target->pos()); + tabPanel->setAcceptDrops(false); + GLDDockNode *node = new GLDDockNode(tabPanel); + tabPanel->resetContensWidget(node); + node->setOrientation(Qt::Horizontal); + from->setDockStatus(); + target->setDockStatus(); + node->insertWidget(0, target); + node->insertWidget(1, from); + tabPanel->setWindowTitle(QString("%1 & %2").arg(target->windowTitle()).arg(from->windowTitle())); + tabPanel->show(); + } + break; + + case CenterBottomArea: + { + GLDDockPanel *tabPanel = new GLDDockPanel(this, dockFrmae_); + tabPanel->panelType_ = GLDDockPanel::SplitContainer; + tabPanel->resize(target->size()); + tabPanel->move(target->pos()); + tabPanel->setAcceptDrops(false); + GLDDockNode *node = new GLDDockNode(tabPanel); + tabPanel->resetContensWidget(node); + node->setOrientation(Qt::Vertical); + from->setDockStatus(); + target->setDockStatus(); + node->insertWidget(0, target); + node->insertWidget(1, from); + tabPanel->setWindowTitle(QString("%1 & %2").arg(target->windowTitle()).arg(from->windowTitle())); + tabPanel->show(); + } + break; + default: + break; + } + + return true; +} + +bool GLDDockManager::dockPanelToDockedPanel(GLDDockPanel *from, GLDDockPanel *target, DockArea area) +{ + if (target->isTabbed_) + { + switch (area) + { + case CenterArea: + { + if (from->panelType_ == GLDDockPanel::SplitContainer) + { + return true; + } + + if (from->panelType_ == GLDDockPanel::TabContainer) + { + return true; + } + + GLDDockTabWidget *tabWidget = qobject_cast(target->parentTabPanel_->contensWidget_); + from->setDockStatus(); + from->setTabbedStatus(true, target->parentTabPanel_); + tabWidget->addTab(from, from->windowTitle()); + } + break; + + case CenterLeftArea: + case CenterTopArea: + case CenterRightArea: + case CenterBottomArea: + dockPanelToPanel(from, target->parentTabPanel_, area); + break; + default: + break; + } + + return true; + } + +// if (from->panelType_ == GLDDockPanel::TabPanel) +// { +// return true; +// } + + if (from->panelType_ == GLDDockPanel::SplitContainer) + { + QList sizes; + sizes.push_back(5); + sizes.push_back(5); + + GLDDockNode *parentNode = qobject_cast(target->parentWidget()); + QWidget *fromWidget = from->contensWidget_; + from->deleteLater(); + + assert(parentNode); + + if (parentNode->count() == 1) + { + assert(isRootNode(parentNode)); + + switch (area) + { + case CenterLeftArea: + parentNode->setOrientation(Qt::Horizontal); + parentNode->insertWidget(0, fromWidget); + parentNode->setSizes(sizes); + break; + + case CenterTopArea: + parentNode->setOrientation(Qt::Vertical); + parentNode->insertWidget(0, fromWidget); + parentNode->setSizes(sizes); + break; + + case CenterRightArea: + parentNode->setOrientation(Qt::Horizontal); + parentNode->insertWidget(1, fromWidget); + parentNode->setSizes(sizes); + break; + + case CenterBottomArea: + parentNode->setOrientation(Qt::Vertical); + parentNode->insertWidget(1, fromWidget); + parentNode->setSizes(sizes); + break; + + case CenterArea: + { + } + break; + + default: + return false; + } + + return true; + } + + //parentNode->count() != 1 + int parentIndex = parentNode->indexOf(target); + QList parentSizes = parentNode->sizes(); + + GLDDockNode *node = new GLDDockNode(NULL); + + switch (area) + { + case CenterLeftArea: + node->setOrientation(Qt::Horizontal); + node->insertWidget(0, fromWidget); + node->insertWidget(1, target); + node->setSizes(sizes); + parentNode->insertWidget(parentIndex, node); + parentNode->setSizes(parentSizes); + break; + + case CenterTopArea: + node->setOrientation(Qt::Vertical); + node->insertWidget(0, fromWidget); + node->insertWidget(1, target); + node->setSizes(sizes); + parentNode->insertWidget(parentIndex, node); + parentNode->setSizes(parentSizes); + break; + + case CenterRightArea: + node->setOrientation(Qt::Horizontal); + node->insertWidget(0, target); + node->insertWidget(1, fromWidget); + node->setSizes(sizes); + parentNode->insertWidget(parentIndex, node); + parentNode->setSizes(parentSizes); + break; + + case CenterBottomArea: + node->setOrientation(Qt::Vertical); + node->insertWidget(0, target); + node->insertWidget(1, fromWidget); + node->setSizes(sizes); + parentNode->insertWidget(parentIndex, node); + parentNode->setSizes(parentSizes); + break; + + case CenterArea: + { + } + break; + + default: + return false; + } + + return true; + } + + QList sizes; + sizes.push_back(5); + sizes.push_back(5); + + GLDDockNode *parentNode = qobject_cast(target->parentWidget()); + assert(parentNode); + + if (parentNode->count() == 1) + { + assert(isRootNode(parentNode)); + + switch (area) + { + case CenterLeftArea: + from->setDockStatus(); + parentNode->setOrientation(Qt::Horizontal); + parentNode->insertWidget(0, from); + parentNode->setSizes(sizes); + break; + + case CenterTopArea: + from->setDockStatus(); + parentNode->setOrientation(Qt::Vertical); + parentNode->insertWidget(0, from); + parentNode->setSizes(sizes); + break; + + case CenterRightArea: + from->setDockStatus(); + parentNode->setOrientation(Qt::Horizontal); + parentNode->insertWidget(1, from); + parentNode->setSizes(sizes); + break; + + case CenterBottomArea: + from->setDockStatus(); + parentNode->setOrientation(Qt::Vertical); + parentNode->insertWidget(1, from); + parentNode->setSizes(sizes); + break; + + case CenterArea: + { + GLDDockPanel *tabPanel = new GLDDockPanel(this, dockFrmae_); + tabPanel->panelType_ = GLDDockPanel::TabContainer; + tabPanel->setAcceptDrops(false); + GLDDockTabWidget *tabWidget = new GLDDockTabWidget(tabPanel); + tabPanel->resetContensWidget(tabWidget); + tabWidget->addTab(target, target->windowTitle()); + from->setDockStatus(); + from->setTabbedStatus(true, tabPanel); + tabWidget->addTab(from, from->windowTitle()); + target->setTabbedStatus(true, tabPanel); + tabPanel->resize(target->size()); + tabPanel->setDockStatus(); + parentNode->insertWidget(0, tabPanel); + connect(tabWidget, SIGNAL(setBasePanelTitle(const QString &)), tabPanel, SLOT(setWindowTitle(const QString &))); + tabPanel->setWindowTitle(tabWidget->currentWidget()->windowTitle()); + } + break; + + default: + return false; + } + + return true; + } + + int parentIndex = parentNode->indexOf(target); + QList parentSizes = parentNode->sizes(); + + GLDDockNode *node = new GLDDockNode(NULL); + + switch (area) + { + case CenterLeftArea: + from->setDockStatus(); + node->setOrientation(Qt::Horizontal); + node->insertWidget(0, from); + node->insertWidget(1, target); + node->setSizes(sizes); + parentNode->insertWidget(parentIndex, node); + parentNode->setSizes(parentSizes); + break; + + case CenterTopArea: + from->setDockStatus(); + node->setOrientation(Qt::Vertical); + node->insertWidget(0, from); + node->insertWidget(1, target); + node->setSizes(sizes); + parentNode->insertWidget(parentIndex, node); + parentNode->setSizes(parentSizes); + break; + + case CenterRightArea: + from->setDockStatus(); + node->setOrientation(Qt::Horizontal); + node->insertWidget(0, target); + node->insertWidget(1, from); + node->setSizes(sizes); + parentNode->insertWidget(parentIndex, node); + parentNode->setSizes(parentSizes); + break; + + case CenterBottomArea: + from->setDockStatus(); + node->setOrientation(Qt::Vertical); + node->insertWidget(0, target); + node->insertWidget(1, from); + node->setSizes(sizes); + parentNode->insertWidget(parentIndex, node); + parentNode->setSizes(parentSizes); + break; + + case CenterArea: + { + GLDDockPanel *tabPanel = new GLDDockPanel(this, dockFrmae_); + tabPanel->panelType_ = GLDDockPanel::TabContainer; + tabPanel->setAcceptDrops(false); + GLDDockTabWidget *tabWidget = new GLDDockTabWidget(tabPanel); + tabPanel->resetContensWidget(tabWidget); + tabWidget->addTab(target, target->windowTitle()); + from->setDockStatus(); + from->setTabbedStatus(true, tabPanel); + tabWidget->addTab(from, from->windowTitle()); + target->setTabbedStatus(true, tabPanel); + tabPanel->resize(target->size()); + tabPanel->setDockStatus(); + parentNode->insertWidget(parentIndex, tabPanel); + parentNode->setSizes(sizes); + connect(tabWidget, SIGNAL(setBasePanelTitle(const QString &)), tabPanel, SLOT(setWindowTitle(const QString &))); + tabPanel->setWindowTitle(tabWidget->currentWidget()->windowTitle()); + } + break; + + default: + return false; + } + + return true; +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockMaskWidget.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockMaskWidget.cpp new file mode 100644 index 00000000..4d06fb51 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockMaskWidget.cpp @@ -0,0 +1,68 @@ +#include "GLDDockMaskWidget.h" + +GLDDockMaskWidget::GLDDockMaskWidget(QWidget *parent) + : QWidget(parent) +{ + setAttribute(Qt::WA_InputMethodTransparent); + setAttribute(Qt::WA_TransparentForMouseEvents); + + setPalette(QColor(0, 0, 255, 100)); + setAutoFillBackground(true); +} + +GLDDockMaskWidget::~GLDDockMaskWidget() +{ + +} + +void GLDDockMaskWidget::showOnDockArea(DockArea area) +{ + QRect rc = parentWidget()->rect(); + + switch (area) + { + case LeftArea: + rc.setWidth(rc.width() * 3 / 10); + break; + + case CenterLeftArea: + rc.setWidth(rc.width() / 2); + break; + + case TopArea: + rc.setHeight(rc.height() * 3 / 10); + break; + + case CenterTopArea: + rc.setHeight(rc.height() / 2); + break; + + case RightArea: + rc.setLeft(rc.left() + rc.width() * 7 / 10); + break; + + case CenterRightArea: + rc.setLeft(rc.left() + rc.width() / 2); + break; + + case BottomArea: + rc.setTop(rc.top() + rc.height() * 7 / 10); + break; + + case CenterBottomArea: + rc.setTop(rc.top() + rc.height() / 2); + break; + + case CenterArea: + break; + + default: + hide(); + return; + } + + move(rc.topLeft()); + resize(rc.size()); + show(); + raise(); +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockMaskWidget.h b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockMaskWidget.h new file mode 100644 index 00000000..d3bfe11f --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockMaskWidget.h @@ -0,0 +1,20 @@ +#ifndef GLDDockMASKWIDGET_H +#define GLDDockMASKWIDGET_H + +#include +#include "GLDDockCommon.h" + +class GLDDockMaskWidget : public QWidget +{ + Q_OBJECT + +public: + GLDDockMaskWidget(QWidget *parent); + ~GLDDockMaskWidget(); + + void showOnDockArea(DockArea area); +private: + +}; + +#endif // GLDDockMASKWIDGET_H diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockNode.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockNode.cpp new file mode 100644 index 00000000..e31d645d --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockNode.cpp @@ -0,0 +1,13 @@ +#include "GLDDockNode.h" +#include + +GLDDockNode::GLDDockNode(QWidget *parent) + : QSplitter(parent) +{ + +} + +GLDDockNode::~GLDDockNode() +{ + +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockNode.h b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockNode.h new file mode 100644 index 00000000..5d479f02 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockNode.h @@ -0,0 +1,17 @@ +#ifndef GLDDockNODE_H +#define GLDDockNODE_H + +#include + +class GLDDockNode : public QSplitter +{ + Q_OBJECT + +public: + GLDDockNode(QWidget *parent); + ~GLDDockNode(); +private: + +}; + +#endif // GLDDockNODE_H diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockPanel.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockPanel.cpp new file mode 100644 index 00000000..1a901f20 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockPanel.cpp @@ -0,0 +1,267 @@ +#include "GLDDockPanel.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "GLDDockDataBuilder.h" +#include "GLDDockNode.h" +#include +#include "GLDDockFrame.h" +#include "GLDDockManager.h" +#include "GLDDockMaskWidget.h" +#include +#include +#include +#include + +GLDDockPanel::GLDDockPanel(GLDDockManager *manager, QWidget *frame) + : QWidget(frame, Qt::FramelessWindowHint | Qt::Tool), + titleRectHeight_(20), contensWidget_(NULL), edgeWidth_(3), + isDocked_(false), manager_(manager), arrows_(this), lastMaskArea_(NoneArea), isTabbed_(false), + parentTabPanel_(NULL), panelType_(DockPanel) +{ + title_ = new GLDDockPanelTitle(this); + connect(this, SIGNAL(windowTitleChanged(const QString &)), title_, SLOT(setTitle(const QString &))); + leftEdge_ = new GLDDockPanelEdgeLeft(this); + leftTopEdge_ = new GLDDockPanelEdgeLeftTop(this); + topEdge_ = new GLDDockPanelEdgeTop(this); + rightTopEdge_ = new GLDDockPanelEdgeRightTop(this); + rightEdge_ = new GLDDockPanelEdgeRight(this); + rightBottomEdge_ = new GLDDockPanelEdgeRightBottom(this); + bottomEdge_ = new GLDDockPanelEdgeBottom(this); + leftBottomEdge_ = new GLDDockPanelEdgeLeftBottom(this); + + maskWidget_ = new GLDDockMaskWidget(this); + maskWidget_->hide(); + + setAcceptDrops(true); + + setMinimumSize(50, 50); +} + +void GLDDockPanel::paintEvent(QPaintEvent *) +{ + QPainter p(this); +} + +void GLDDockPanel::resizeEvent(QResizeEvent *) +{ + relayout(); +} + +void GLDDockPanel::resetContensWidgetPosAndSize() +{ + if (!contensWidget_) + { + return; + } + + if (contensWidget_->parentWidget() != this) + { + contensWidget_->setParent(this); + } + + if (isDocked_) + { + if (isTabbed_) + { + contensWidget_->move(0, 0); + contensWidget_->resize(width(), height()); + } + else + { + contensWidget_->move(0, edgeWidth_ + titleRectHeight_); + contensWidget_->resize(width(), height() - edgeWidth_ - titleRectHeight_); + } + } + else + { + contensWidget_->move(edgeWidth_, edgeWidth_ * 2 + titleRectHeight_); + contensWidget_->resize(width() - edgeWidth_ * 2, height() - edgeWidth_ * 3 - titleRectHeight_); + } +} + +void GLDDockPanel::relayout() +{ + if (isDocked_) + { + if (isTabbed_) + { + title_->hide(); + } + else + { + title_->move(0, 0); + title_->resize(width(), titleRectHeight_); + title_->show(); + } + + leftEdge_->hide(); + leftTopEdge_->hide(); + topEdge_->hide(); + rightTopEdge_->hide(); + rightEdge_->hide(); + rightBottomEdge_->hide(); + bottomEdge_->hide(); + leftBottomEdge_->hide(); + } + else + { + title_->move(edgeWidth_, edgeWidth_); + title_->resize(width() - edgeWidth_ * 2, titleRectHeight_); + title_->show(); + + leftEdge_->move(0, edgeWidth_); + leftEdge_->resize(edgeWidth_, height() - edgeWidth_ * 2); + leftEdge_->show(); + + leftTopEdge_->move(0, 0); + leftTopEdge_->resize(edgeWidth_, edgeWidth_); + leftTopEdge_->show(); + + topEdge_->move(edgeWidth_, 0); + topEdge_->resize(width() - edgeWidth_ * 2, edgeWidth_); + topEdge_->show(); + + rightTopEdge_->move(width() - edgeWidth_, 0); + rightTopEdge_->resize(edgeWidth_, edgeWidth_); + rightTopEdge_->show(); + + rightEdge_->move(width() - edgeWidth_, edgeWidth_); + rightEdge_->resize(edgeWidth_, height() - edgeWidth_ * 2); + rightEdge_->show(); + + rightBottomEdge_->move(width() - edgeWidth_, height() - edgeWidth_); + rightBottomEdge_->resize(edgeWidth_, edgeWidth_); + rightBottomEdge_->show(); + + bottomEdge_->move(edgeWidth_, height() - edgeWidth_); + bottomEdge_->resize(width() - edgeWidth_ * 2, edgeWidth_); + bottomEdge_->show(); + + leftBottomEdge_->move(0, height() - edgeWidth_); + leftBottomEdge_->resize(edgeWidth_, edgeWidth_); + leftBottomEdge_->show(); + } + + resetContensWidgetPosAndSize(); +} + +void GLDDockPanel::setDockStatus() +{ + floatSize_ = size(); + setWindowFlags(Qt::SubWindow); + relayout(); + isDocked_ = true; +} + +void GLDDockPanel::setFloatStatus() +{ + setWindowFlags(Qt::FramelessWindowHint | Qt::Tool); + resize(floatSize_); + relayout(); + isDocked_ = false; + isTabbed_ = false; +} + +bool GLDDockPanel::dockTo(QWidget *, DockArea ) +{ + return false; +} + +void GLDDockPanel::undock() +{ + manager_->undockPanel(this); +} + +void GLDDockPanel::dragEnterEvent(QDragEnterEvent *e) +{ + manager_->onDragEnterPanel(); + const QMimeData *mimeData = e->mimeData(); + + if (mimeData && mimeData->hasFormat("dockpanellib/dockdata")) + { + showArrow(); + e->accept(); + } + else + { + e->ignore(); + } +} + +void GLDDockPanel::dragMoveEvent(QDragMoveEvent *e) +{ + DockArea area = arrows_.getDockAreaByPos(mapFromGlobal(QCursor::pos())); + + if (area != lastMaskArea_) + { + maskWidget_->showOnDockArea(area); + lastMaskArea_ = area; + } + + e->accept(); +} + +void GLDDockPanel::dragLeaveEvent(QDragLeaveEvent *e) +{ + manager_->onDragLeavePanel(); + arrows_.show(NoneArea); + lastMaskArea_ = NoneArea; + maskWidget_->showOnDockArea(NoneArea); + e->accept(); +} + +void GLDDockPanel::dropEvent(QDropEvent *e) +{ + const QMimeData *mimeData = e->mimeData(); + + if (!mimeData->hasFormat("dockpanellib/dockdata")) + { + e->ignore(); + return; + } + + QByteArray ba = mimeData->data("dockpanellib/dockdata"); + GLDDockDataBuilder builder; + builder.fromByteArray(ba); + + GLDDockPanel *panel = qobject_cast(builder.getWidget()); + + if (panel && lastMaskArea_ != NoneArea) + { + e->accept(); + manager_->dockPanelToPanel(panel, this, lastMaskArea_); + } + else + { + e->ignore(); + } + + lastMaskArea_ = NoneArea; + arrows_.show(NoneArea); + maskWidget_->showOnDockArea(NoneArea); + + manager_->onEndDragAtPanel(); +} + +void GLDDockPanel::showArrow() +{ + arrows_.show(CenterArea | CenterLeftArea | CenterTopArea | CenterRightArea | CenterBottomArea); +} + +void GLDDockPanel::startDrag() +{ + title_->startDrag(); +} + +void GLDDockPanel::setTabbedStatus(bool isTabbed, GLDDockPanel *parentTabPanel) +{ + isTabbed_ = isTabbed; + parentTabPanel_ = parentTabPanel; + relayout(); +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockPanel.h b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockPanel.h new file mode 100644 index 00000000..fbd6144a --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockPanel.h @@ -0,0 +1,106 @@ +#ifndef GLDDockPANEL_H +#define GLDDockPANEL_H + +#include +#include "GLDDockCommon.h" +#include "GLDDockPanelComponents.h" +#include "GLDDockArrows.h" + +class GLDDockManager; +class GLDDockMaskWidget; +class GLDDockTabWidget; + +class GLDDockPanel : public QWidget +{ + Q_OBJECT +public: + explicit GLDDockPanel(GLDDockManager *manager, QWidget *frame); + + QWidget *getContensWidget() + { + return contensWidget_; + } + QWidget *resetContensWidget(QWidget *newWidget) + { + QWidget *old = contensWidget_; + contensWidget_ = newWidget; + resetContensWidgetPosAndSize(); + + return old; + } + + void setId(int id) + { + id_ = id; + } + int id() + { + return id_; + } + + bool isDocked() + { + return isDocked_; + } + bool dockTo(QWidget *, DockArea); + void undock(); + void startDrag(); +private: + void resizeWidget(int curX, int curY); + void relayout(); + void setDockStatus(); + void setFloatStatus(); + void setTabbedStatus(bool isTabbed, GLDDockPanel *parentTabPanel); + +private: + int id_; //panel ID + int titleRectHeight_; // panel窗口的标题栏的高度. + QWidget *contensWidget_; // panel窗口内的widget. + int edgeWidth_; // 边框的宽度. + bool isDocked_; + QSize floatSize_; + GLDDockManager *manager_; + GLDDockArrows arrows_; + DockArea lastMaskArea_; + GLDDockMaskWidget *maskWidget_; + + bool isTabbed_; + GLDDockPanel *parentTabPanel_; + + enum PanelType + { + DockPanel, + TabContainer, + SplitContainer, + }; + + PanelType panelType_; + + GLDDockPanelTitle *title_; + GLDDockPanelEdgeLeft *leftEdge_; + GLDDockPanelEdgeTop *topEdge_; + GLDDockPanelEdgeRight *rightEdge_; + GLDDockPanelEdgeBottom *bottomEdge_; + GLDDockPanelEdgeLeftTop *leftTopEdge_; + GLDDockPanelEdgeRightTop *rightTopEdge_; + GLDDockPanelEdgeRightBottom *rightBottomEdge_; + GLDDockPanelEdgeLeftBottom *leftBottomEdge_; + +private: + void showArrow(); +protected: + void paintEvent(QPaintEvent *); + void resizeEvent(QResizeEvent *e); + void resetContensWidgetPosAndSize(); + + virtual void dragEnterEvent(QDragEnterEvent *); + virtual void dragMoveEvent(QDragMoveEvent *); + virtual void dragLeaveEvent(QDragLeaveEvent *); + virtual void dropEvent(QDropEvent *); + + friend class GLDDockManager; + friend class GLDDockPanelTitle; + friend class GLDDockTabWidget; +}; + +#endif // GLDDockPANEL_H diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockPanelComponents.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockPanelComponents.cpp new file mode 100644 index 00000000..3f72741f --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockPanelComponents.cpp @@ -0,0 +1,442 @@ +#include "GLDDockPanelComponents.h" + +#include "GLDDockPanel.h" +#include "GLDDockDataBuilder.h" +#include +#include +#include +#include +#include + +GLDDockPanelTitle::GLDDockPanelTitle(QWidget *parent) : QWidget(parent), isLBtnPressed_(false) +{ + setPalette(QPalette(Qt::lightGray)); + setAutoFillBackground(true); +} + +void GLDDockPanelTitle::paintEvent(QPaintEvent *) +{ + QPainter p(this); + p.drawText(rect(), Qt::AlignLeft | Qt::AlignVCenter, title_); +} + +void GLDDockPanelTitle::setTitle(const QString &title) +{ + title_ = title; + repaint(); +} + +void GLDDockPanelTitle::mousePressEvent(QMouseEvent *e) +{ + if (e->button() == Qt::LeftButton) + { + isLBtnPressed_ = true; + pressedPos_ = e->globalPos(); + parentOldPos_ = parentWidget()->pos(); + } +} + +void GLDDockPanelTitle::mouseReleaseEvent(QMouseEvent *) +{ + isLBtnPressed_ = false; +} + +void GLDDockPanelTitle::mouseMoveEvent(QMouseEvent *e) +{ + if (!isLBtnPressed_) + { + return; + } + + GLDDockPanel *panel = qobject_cast(parentWidget()); + + if (panel && panel->isDocked_) + { + panel->undock(); + } + + if (QApplication::keyboardModifiers() != Qt::ControlModifier) + { + startDrag(); + return; + } + + parentWidget()->move(parentOldPos_.x() + e->globalX() - pressedPos_.x(), parentOldPos_.y() + e->globalY() - pressedPos_.y()); +} + +void GLDDockPanelTitle::startDrag() +{ + QMimeData *mimeData = new QMimeData; + GLDDockDataBuilder data; + data.setWidget(parentWidget()); + mimeData->setData("dockpanellib/dockdata", data.toByteArray()); + QDrag drag(this); + QPixmap pic(parentWidget()->size()); + parentWidget()->render(&pic); + drag.setPixmap(pic); + drag.setMimeData(mimeData); + parentWidget()->hide(); + + if (drag.start() == Qt::IgnoreAction) + { + parentWidget()->move(QCursor::pos()); + } + + parentWidget()->show(); + isLBtnPressed_ = false; +} + +GLDDockPanelEdgeLeft::GLDDockPanelEdgeLeft(QWidget *parent) : QWidget(parent), isLBtnPressed_(false) +{ + setCursor(Qt::SizeHorCursor); +} + +void GLDDockPanelEdgeLeft::mousePressEvent(QMouseEvent *e) +{ + if (e->button() == Qt::LeftButton) + { + isLBtnPressed_ = true; + pressedPos_ = e->globalPos(); + parentOldRect_ = parentWidget()->geometry(); + } +} + +void GLDDockPanelEdgeLeft::mouseReleaseEvent(QMouseEvent *) +{ + isLBtnPressed_ = false; +} + +void GLDDockPanelEdgeLeft::mouseMoveEvent(QMouseEvent *e) +{ + if (!isLBtnPressed_) + { + return; + } + + int x, y, w, h; + x = parentOldRect_.x() + e->globalX() - pressedPos_.x(); + y = parentWidget()->pos().y(); + w = parentOldRect_.width() - (e->globalX() - pressedPos_.x()); + + if (w < 20) + { + return; + } + + h = parentWidget()->height(); + parentWidget()->move(x, y); + parentWidget()->resize(w, h); +} + +GLDDockPanelEdgeTop::GLDDockPanelEdgeTop(QWidget *parent) : QWidget(parent), isLBtnPressed_(false) +{ + setCursor(Qt::SizeVerCursor); +} + +void GLDDockPanelEdgeTop::mousePressEvent(QMouseEvent *e) +{ + if (e->button() == Qt::LeftButton) + { + isLBtnPressed_ = true; + pressedPos_ = e->globalPos(); + parentOldRect_ = parentWidget()->geometry(); + } +} + +void GLDDockPanelEdgeTop::mouseReleaseEvent(QMouseEvent *) +{ + isLBtnPressed_ = false; +} + +void GLDDockPanelEdgeTop::mouseMoveEvent(QMouseEvent *e) +{ + if (!isLBtnPressed_) + { + return; + } + + int x, y, w, h; + x = parentWidget()->pos().x(); + y = parentOldRect_.y() - (pressedPos_.y() - e->globalY()); + w = parentWidget()->width(); + h = parentOldRect_.height() - (e->globalY() - pressedPos_.y()); + + if (h < 20) + { + return; + } + + parentWidget()->move(x, y); + parentWidget()->resize(w, h); +} + +GLDDockPanelEdgeRight::GLDDockPanelEdgeRight(QWidget *parent) : QWidget(parent), isLBtnPressed_(false) +{ + setCursor(Qt::SizeHorCursor); +} + +void GLDDockPanelEdgeRight::mousePressEvent(QMouseEvent *e) +{ + if (e->button() == Qt::LeftButton) + { + isLBtnPressed_ = true; + pressedPos_ = e->globalPos(); + parentOldWidth_ = parentWidget()->width(); + } +} + +void GLDDockPanelEdgeRight::mouseReleaseEvent(QMouseEvent *) +{ + isLBtnPressed_ = false; +} + +void GLDDockPanelEdgeRight::mouseMoveEvent(QMouseEvent *e) +{ + if (!isLBtnPressed_) + { + return; + } + + int w, h; + w = parentOldWidth_ - (pressedPos_.x() - e->globalX()); + + if (w < 20) + { + return; + } + + h = parentWidget()->height(); + parentWidget()->resize(w, h); +} + +GLDDockPanelEdgeBottom::GLDDockPanelEdgeBottom(QWidget *parent) : QWidget(parent) +{ + setCursor(Qt::SizeVerCursor); +} + +void GLDDockPanelEdgeBottom::mousePressEvent(QMouseEvent *e) +{ + if (e->button() == Qt::LeftButton) + { + isLBtnPressed_ = true; + pressedPos_ = e->globalPos(); + parentOldHeight_ = parentWidget()->height(); + } +} + +void GLDDockPanelEdgeBottom::mouseReleaseEvent(QMouseEvent *) +{ + isLBtnPressed_ = false; +} + +void GLDDockPanelEdgeBottom::mouseMoveEvent(QMouseEvent *e) +{ + if (!isLBtnPressed_) + { + return; + } + + int w, h; + w = parentWidget()->width(); + h = parentOldHeight_ - (pressedPos_.y() - e->globalY()); + + if (h < 20) + { + return; + } + + parentWidget()->resize(w, h); +} + +GLDDockPanelEdgeLeftTop::GLDDockPanelEdgeLeftTop(QWidget *parent) : QWidget(parent), isLBtnPressed_(false) +{ + setCursor(Qt::SizeFDiagCursor); +} + +void GLDDockPanelEdgeLeftTop::mousePressEvent(QMouseEvent *e) +{ + if (e->button() == Qt::LeftButton) + { + isLBtnPressed_ = true; + pressedPos_ = e->globalPos(); + parentOldRect_ = parentWidget()->geometry(); + } +} + +void GLDDockPanelEdgeLeftTop::mouseReleaseEvent(QMouseEvent *) +{ + isLBtnPressed_ = false; +} + +void GLDDockPanelEdgeLeftTop::mouseMoveEvent(QMouseEvent *e) +{ + if (!isLBtnPressed_) + { + return; + } + + int x, y, w, h; + x = parentOldRect_.x() + e->globalX() - pressedPos_.x(); + y = parentOldRect_.y() - (pressedPos_.y() - e->globalY()); + w = parentOldRect_.width() - (e->globalX() - pressedPos_.x()); + + if (w < 20) + { + w = 20; + x = parentWidget()->pos().x(); + } + + h = parentOldRect_.height() - (e->globalY() - pressedPos_.y()); + + if (h < 20) + { + h = 20; + y = parentWidget()->pos().y(); + } + + parentWidget()->move(x, y); + parentWidget()->resize(w, h); +} + +GLDDockPanelEdgeRightTop::GLDDockPanelEdgeRightTop(QWidget *parent) : QWidget(parent), isLBtnPressed_(false) +{ + setCursor(Qt::SizeBDiagCursor); +} + +void GLDDockPanelEdgeRightTop::mousePressEvent(QMouseEvent *e) +{ + if (e->button() == Qt::LeftButton) + { + isLBtnPressed_ = true; + pressedPos_ = e->globalPos(); + parentOldRect_ = parentWidget()->geometry(); + } +} + +void GLDDockPanelEdgeRightTop::mouseReleaseEvent(QMouseEvent *) +{ + isLBtnPressed_ = false; +} + +void GLDDockPanelEdgeRightTop::mouseMoveEvent(QMouseEvent *e) +{ + if (!isLBtnPressed_) + { + return; + } + + int x, y, w, h; + x = parentWidget()->pos().x(); + y = parentOldRect_.y() - (pressedPos_.y() - e->globalY()); + w = parentOldRect_.width() - (pressedPos_.x() - e->globalX()); + + if (w < 20) + { + w = 20; + } + + h = parentOldRect_.height() - (e->globalY() - pressedPos_.y()); + + if (h < 20) + { + h = 20; + y = parentWidget()->pos().y(); + } + + parentWidget()->move(x, y); + parentWidget()->resize(w, h); +} + +GLDDockPanelEdgeRightBottom::GLDDockPanelEdgeRightBottom(QWidget *parent) : QWidget(parent), isLBtnPressed_(false) +{ + setCursor(Qt::SizeFDiagCursor); +} + +void GLDDockPanelEdgeRightBottom::mousePressEvent(QMouseEvent *e) +{ + if (e->button() == Qt::LeftButton) + { + isLBtnPressed_ = true; + pressedPos_ = e->globalPos(); + parentOldSize_ = parentWidget()->size(); + } +} + +void GLDDockPanelEdgeRightBottom::mouseReleaseEvent(QMouseEvent *) +{ + isLBtnPressed_ = false; +} + +void GLDDockPanelEdgeRightBottom::mouseMoveEvent(QMouseEvent *e) +{ + if (!isLBtnPressed_) + { + return; + } + + int w, h; + w = parentOldSize_.width() - (pressedPos_.x() - e->globalX()); + + if (w < 20) + { + w = 20; + } + + h = parentOldSize_.height() - (pressedPos_.y() - e->globalY()); + + if (h < 20) + { + h = 20; + } + + parentWidget()->resize(w, h); +} + +GLDDockPanelEdgeLeftBottom::GLDDockPanelEdgeLeftBottom(QWidget *parent) : QWidget(parent), isLBtnPressed_(false) +{ + setCursor(Qt::SizeBDiagCursor); +} + +void GLDDockPanelEdgeLeftBottom::mousePressEvent(QMouseEvent *e) +{ + if (e->button() == Qt::LeftButton) + { + isLBtnPressed_ = true; + pressedPos_ = e->globalPos(); + parentOldRect_ = parentWidget()->geometry(); + } +} + +void GLDDockPanelEdgeLeftBottom::mouseReleaseEvent(QMouseEvent *) +{ + isLBtnPressed_ = false; +} + +void GLDDockPanelEdgeLeftBottom::mouseMoveEvent(QMouseEvent *e) +{ + if (!isLBtnPressed_) + { + return; + } + + int x, y, w, h; + x = parentOldRect_.x() + e->globalX() - pressedPos_.x(); + y = parentWidget()->pos().y(); + w = parentOldRect_.width() - (e->globalX() - pressedPos_.x()); + + if (w < 20) + { + w = 20; + x = parentWidget()->pos().x(); + } + + h = parentOldRect_.height() - (pressedPos_.y() - e->globalY()); + + if (h < 20) + { + h = 20; + } + + parentWidget()->move(x, y); + parentWidget()->resize(w, h); +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockPanelComponents.h b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockPanelComponents.h new file mode 100644 index 00000000..de53732e --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockPanelComponents.h @@ -0,0 +1,186 @@ +#ifndef GLDDockPANELCONPONENTS_H +#define GLDDockPANELCONPONENTS_H + +#include +#include "GLDWidget_Global.h" + +class GLDWIDGETSHARED_EXPORT GLDDockPanelTitle : public QWidget +{ + Q_OBJECT + +public: + GLDDockPanelTitle(QWidget *parent); + ~GLDDockPanelTitle() {} + + virtual void paintEvent(QPaintEvent *); + +public slots: + void setTitle(const QString &title); + void startDrag(); + +private: + virtual void mousePressEvent(QMouseEvent *e); + virtual void mouseReleaseEvent(QMouseEvent *); + virtual void mouseMoveEvent(QMouseEvent *e); + +private: + QString title_; + + bool isLBtnPressed_; + QPoint pressedPos_; + QPoint parentOldPos_; +}; + +class GLDWIDGETSHARED_EXPORT GLDDockPanelEdgeLeft : public QWidget +{ + Q_OBJECT + +public: + GLDDockPanelEdgeLeft(QWidget *parent); + ~GLDDockPanelEdgeLeft() {} + +private: + virtual void mousePressEvent(QMouseEvent *e); + virtual void mouseReleaseEvent(QMouseEvent *); + virtual void mouseMoveEvent(QMouseEvent *e); + +private: + bool isLBtnPressed_; + QPoint pressedPos_; + QRect parentOldRect_; +}; + +class GLDWIDGETSHARED_EXPORT GLDDockPanelEdgeTop : public QWidget +{ + Q_OBJECT + +public: + GLDDockPanelEdgeTop(QWidget *parent); + ~GLDDockPanelEdgeTop() {} + +private: + virtual void mousePressEvent(QMouseEvent *e); + virtual void mouseReleaseEvent(QMouseEvent *); + virtual void mouseMoveEvent(QMouseEvent *e); + +private: + bool isLBtnPressed_; + QPoint pressedPos_; + QRect parentOldRect_; +}; + +class GLDWIDGETSHARED_EXPORT GLDDockPanelEdgeRight : public QWidget +{ + Q_OBJECT + +public: + GLDDockPanelEdgeRight(QWidget *parent); + ~GLDDockPanelEdgeRight() {} + +private: + virtual void mousePressEvent(QMouseEvent *e); + virtual void mouseReleaseEvent(QMouseEvent *); + virtual void mouseMoveEvent(QMouseEvent *e); + +private: + bool isLBtnPressed_; + QPoint pressedPos_; + int parentOldWidth_; +}; + +class GLDWIDGETSHARED_EXPORT GLDDockPanelEdgeBottom : public QWidget +{ + Q_OBJECT + +public: + GLDDockPanelEdgeBottom(QWidget *parent); + ~GLDDockPanelEdgeBottom() {} + +private: + virtual void mousePressEvent(QMouseEvent *e); + virtual void mouseReleaseEvent(QMouseEvent *); + virtual void mouseMoveEvent(QMouseEvent *e); + +private: + bool isLBtnPressed_; + QPoint pressedPos_; + int parentOldHeight_; +}; + +class GLDWIDGETSHARED_EXPORT GLDDockPanelEdgeLeftTop : public QWidget +{ + Q_OBJECT + +public: + GLDDockPanelEdgeLeftTop(QWidget *parent); + ~GLDDockPanelEdgeLeftTop() {} + +private: + virtual void mousePressEvent(QMouseEvent *e); + virtual void mouseReleaseEvent(QMouseEvent *); + virtual void mouseMoveEvent(QMouseEvent *e); + +private: + bool isLBtnPressed_; + QPoint pressedPos_; + QRect parentOldRect_; +}; + +class GLDWIDGETSHARED_EXPORT GLDDockPanelEdgeRightTop : public QWidget +{ + Q_OBJECT + +public: + GLDDockPanelEdgeRightTop(QWidget *parent); + ~GLDDockPanelEdgeRightTop() {} + +private: + virtual void mousePressEvent(QMouseEvent *e); + virtual void mouseReleaseEvent(QMouseEvent *); + virtual void mouseMoveEvent(QMouseEvent *e); + +private: + bool isLBtnPressed_; + QPoint pressedPos_; + QRect parentOldRect_; +}; + +class GLDWIDGETSHARED_EXPORT GLDDockPanelEdgeRightBottom : public QWidget +{ + Q_OBJECT + +public: + GLDDockPanelEdgeRightBottom(QWidget *parent); + ~GLDDockPanelEdgeRightBottom() {} + +private: + virtual void mousePressEvent(QMouseEvent *e); + virtual void mouseReleaseEvent(QMouseEvent *); + virtual void mouseMoveEvent(QMouseEvent *e); + +private: + bool isLBtnPressed_; + QPoint pressedPos_; + QSize parentOldSize_; +}; + +class GLDWIDGETSHARED_EXPORT GLDDockPanelEdgeLeftBottom : public QWidget +{ + Q_OBJECT + +public: + GLDDockPanelEdgeLeftBottom(QWidget *parent); + ~GLDDockPanelEdgeLeftBottom() {} + +private: + virtual void mousePressEvent(QMouseEvent *e); + virtual void mouseReleaseEvent(QMouseEvent *); + virtual void mouseMoveEvent(QMouseEvent *e); + +private: + bool isLBtnPressed_; + QPoint pressedPos_; + QRect parentOldRect_; +}; + +#endif // GLDDockPANELCONPONENTS_H diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockTabBar.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockTabBar.cpp new file mode 100644 index 00000000..d54a1c45 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockTabBar.cpp @@ -0,0 +1,99 @@ +#include "GLDDockTabBar.h" +#include +#include +#include +#include + +GLDDockTabBar::GLDDockTabBar(QWidget *parent) + : QTabBar(parent), isLButtonDown_(false), + sendDragOut_(false), insertPos_(-1) +{ + setAcceptDrops(true); +} + +GLDDockTabBar::~GLDDockTabBar() +{ + +} + + + +void GLDDockTabBar::mousePressEvent(QMouseEvent *e) +{ + if (e->button() == Qt::LeftButton) + { + isLButtonDown_ = true; + sendDragOut_ = false; + } + + QTabBar::mousePressEvent(e); +} + +void GLDDockTabBar::mouseReleaseEvent(QMouseEvent *e) +{ + isLButtonDown_ = false; + QTabBar::mouseReleaseEvent(e); + + if (insertPos_ >= 0) + { + moveTab(currentIndex(), insertPos_); + } + + insertPos_ = -1; + repaint(); +} + +void GLDDockTabBar::mouseMoveEvent(QMouseEvent *e) +{ + QTabBar::mouseMoveEvent(e); + + if (!isLButtonDown_) + { + return; + } + + if (!rect().contains(e->pos())) + { + insertPos_ = -1; + + if (!sendDragOut_) + { + emit dragTabOut(currentIndex()); + sendDragOut_ = true; + } + + return; + } + + insertPos_ = tabAt(e->pos()); + repaint(); +} + +void GLDDockTabBar::paintEvent(QPaintEvent *e) +{ + QTabBar::paintEvent(e); + + QPainter p(this); + QRect rc = tabRect(insertPos_); + rc.moveCenter(QPoint(rc.left(), rc.center().y())); + + p.setBrush(QBrush(QColor(0, 0, 255, 100))); + p.setPen(QPen(Qt::blue)); + p.drawRect(rc); +} + +void GLDDockTabBar::dragEnterEvent(QDragEnterEvent *) +{ + +} + +void GLDDockTabBar::dragMoveEvent(QDragMoveEvent *) +{ + insertPos_ = tabAt(mapFromGlobal(QCursor::pos())); + repaint(); +} + +void GLDDockTabBar::dropEvent(QDropEvent *) +{ + +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockTabBar.h b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockTabBar.h new file mode 100644 index 00000000..4ac3e31d --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockTabBar.h @@ -0,0 +1,35 @@ +#ifndef GLDDockTABBAR_H +#define GLDDockTABBAR_H + +#include + +class GLDDockTabBar : public QTabBar +{ + Q_OBJECT + +public: + GLDDockTabBar(QWidget *parent); + ~GLDDockTabBar(); + + // QWidget interface +protected: + void mousePressEvent(QMouseEvent *e); + void mouseReleaseEvent(QMouseEvent *e); + void mouseMoveEvent(QMouseEvent *e); + +private: + bool isLButtonDown_; + bool sendDragOut_; + int insertPos_; + +signals: + void dragTabOut(int index); + +protected: + virtual void paintEvent(QPaintEvent *); + virtual void dragMoveEvent(QDragMoveEvent *); + virtual void dropEvent(QDropEvent *); + virtual void dragEnterEvent(QDragEnterEvent *); +}; + +#endif // GLDDockTABBAR_H diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockTabWidget.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockTabWidget.cpp new file mode 100644 index 00000000..11d93593 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockTabWidget.cpp @@ -0,0 +1,78 @@ +#include "GLDDockTabWidget.h" +#include "GLDDockTabBar.h" +#include +#include +#include "GLDDockNode.h" +#include "GLDDockPanel.h" +#include + +GLDDockTabWidget::GLDDockTabWidget(QWidget *parent) + : QTabWidget(parent) +{ + GLDDockTabBar *bar = new GLDDockTabBar(this); + bar->setMovable(false); + + connect(bar, SIGNAL(dragTabOut(int)), this, SLOT(onDragTabOut(int)), Qt::QueuedConnection); + setTabBar(bar); + + setTabPosition(South); + + connect(this, SIGNAL(currentChanged(int)), this, SLOT(onCurrenChanged(int))); +} + +GLDDockTabWidget::~GLDDockTabWidget() +{ + +} + +void GLDDockTabWidget::onDragTabOut(int index) +{ + GLDDockPanel *currentPanel = qobject_cast(widget(index)); + currentPanel->undock(); + currentPanel->show(); + currentPanel->startDrag(); +} + +void GLDDockTabWidget::onCurrenChanged(int) +{ + QWidget *cur = currentWidget(); + + if (!cur) + { + return; + } + + emit setBasePanelTitle(cur->windowTitle()); +} + +void GLDDockTabWidget::tabRemoved(int) +{ + if (count() == 1) + { + GLDDockPanel *panel = qobject_cast(widget(0)); + GLDDockPanel *parentPanel = qobject_cast(parentWidget()); + GLDDockNode *parentNode = qobject_cast(parentPanel->parentWidget()); + + if (parentNode) + { + QList sizes = parentNode->sizes(); + int thisIndex = parentNode->indexOf(parentPanel); + parentPanel->setParent(NULL); + parentPanel->close(); + parentPanel->deleteLater(); + panel->setTabbedStatus(false, NULL); + parentNode->insertWidget(thisIndex, panel); + parentNode->setSizes(sizes); + } + else + { + panel->undock(); + panel->show(); + panel->move(parentPanel->pos()); + panel->resize(parentPanel->size()); + + parentPanel->close(); + parentPanel->deleteLater(); + } + } +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockTabWidget.h b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockTabWidget.h new file mode 100644 index 00000000..f1ff1fbc --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockPanel/GLDDockTabWidget.h @@ -0,0 +1,24 @@ +#ifndef GLDDockTABWIDGET_H +#define GLDDockTABWIDGET_H + +#include +#include "GLDWidget_Global.h" + +class GLDWIDGETSHARED_EXPORT GLDDockTabWidget : public QTabWidget +{ + Q_OBJECT + +public: + GLDDockTabWidget(QWidget *parent); + ~GLDDockTabWidget(); + +signals: + void setBasePanelTitle(const QString &); +private slots: + void onDragTabOut(int index); + void onCurrenChanged(int index); +protected: + virtual void tabRemoved(int); +}; + +#endif // GLDDockTABWIDGET_H diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockWidget.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockWidget.cpp new file mode 100644 index 00000000..c75535aa --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDDockWidget.cpp @@ -0,0 +1,286 @@ +#include "GLDDockWidget.h" +#include +#include +#include +#include +#include +#include + +/** + 锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷tabBars锟铰硷拷 +*/ +class GLDTabBarsControl: public QObject +{ +public: + explicit GLDTabBarsControl(QObject *parent = 0); +protected: + bool eventFilter(QObject *obj, QEvent *event); +private: + void pressEventOnTabBar(QTabBar *bar, QMouseEvent *event); + void moveEventOnTabBar(QTabBar *bar, QMouseEvent *event); + void releaseEventOnDock(GLDDockWidget *dockWidget, QMouseEvent *event); + void leaveDockWidget(GLDDockWidget *dockWidget); +private: + int m_xOffset; + int m_yOffset; + + QPoint m_pressPosOnTab; + QPoint m_releasePosOnTab; + + GLDDockWidget *m_nowDraggingDock; + QTabBar *m_nowTabBar; + friend class GLDDockWidget; +}; +/** + GLDTabBarsControl锟斤拷全锟街憋拷锟? +*/ +GLDTabBarsControl gTabBarsControl; + +GLDTabBarsControl::GLDTabBarsControl(QObject *parent): + QObject(parent), m_pressPosOnTab(-1, -1), m_releasePosOnTab(-1, -1), + m_nowDraggingDock(NULL), m_nowTabBar(NULL), m_xOffset(0), m_yOffset(0) +{} + +/** + 锟铰硷拷锟斤拷锟斤拷锟斤拷锟斤拷锟铰硷拷锟斤拷锟斤拷锟斤拷锟斤拷 +*/ +bool GLDTabBarsControl::eventFilter(QObject *obj, QEvent *event) +{ + if (QTabBar *bar = dynamic_cast(obj)) + { + m_nowTabBar = bar; + switch (event->type()) + { + case QEvent::MouseButtonPress: + { + QMouseEvent *mouseEvent = dynamic_cast(event); + pressEventOnTabBar(bar, mouseEvent); + break; + } + case QEvent::MouseMove: + { + QMouseEvent *mouseEvent = dynamic_cast(event); + moveEventOnTabBar(bar, mouseEvent); + break; + } + default: + break; + } + } + + return QObject::eventFilter(obj, event); +} + +void GLDTabBarsControl::pressEventOnTabBar(QTabBar *bar, QMouseEvent *event) +{ + m_pressPosOnTab = QPoint(-1, -1); + for (int index = 0; NULL != bar && index < bar->count(); ++index) + { + QRect tabRect = bar->tabRect(index); + QPoint pressPos = event->pos(); + if (tabRect.contains(pressPos)) + { + m_pressPosOnTab = pressPos; + break; + } + } +} + +void GLDTabBarsControl::moveEventOnTabBar(QTabBar *bar, QMouseEvent *event) +{ + if (NULL != m_nowDraggingDock) + { + QPoint gPoint = event->globalPos(); + gPoint.setX(gPoint.x() - m_xOffset); + gPoint.setY(gPoint.y() - m_yOffset); + m_nowDraggingDock->move(gPoint); + return; + } + for (int index = 0; NULL != bar && index < bar->count(); ++index) + { + QRect tabRect = bar->tabRect(index); + + QPoint point = event->pos(); + if (!tabRect.contains(point) && (tabRect.contains(m_pressPosOnTab)) + && !bar->rect().contains(point)) + { + QVariant tmp = bar->tabData(index); + GLDDockWidget *dockWidget = reinterpret_cast(tmp.toULongLong()); + QRect dockRect = dockWidget->geometry(); + dockWidget->setFloating(true); + m_nowDraggingDock = dockWidget; + bar->removeTab(index); + // 锟斤拷锟街革拷锟斤拷之前锟侥达拷小 + dockWidget->setGeometry(dockRect); + QPoint gPoint = event->globalPos(); + // 锟斤拷锟斤拷偏锟斤拷锟斤拷锟斤拷堑锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟? + m_xOffset = m_pressPosOnTab.x() - 3; + m_yOffset = dockRect.height() - 3; + gPoint.setX(gPoint.x() - m_xOffset); + gPoint.setY(gPoint.y() - m_yOffset); + dockWidget->move(gPoint); + m_pressPosOnTab = QPoint(-1, -1); + + dockWidget->installEventFilter(this); + } + } +} + +void GLDTabBarsControl::releaseEventOnDock(GLDDockWidget *dockWidget, QMouseEvent *event) +{ + if (NULL == m_nowTabBar) + { + return; + } + m_releasePosOnTab = event->pos(); + m_nowTabBar->removeEventFilter(dockWidget); + m_nowDraggingDock = NULL; + m_nowTabBar = NULL; +} + +void GLDTabBarsControl::leaveDockWidget(GLDDockWidget *dockWidget) +{ + if (NULL == m_nowTabBar) + { + return; + } + m_nowTabBar->removeEventFilter(dockWidget); + m_nowDraggingDock = NULL; + m_nowTabBar = NULL; +} + +/** + GLDDockWidget +*/ +GLDDockWidget::GLDDockWidget(const QString &title, QWidget *parent, Qt::WindowFlags flags) : + QDockWidget(title, parent, flags) +{ + initTitleBar(); + m_title->setText(title); + + connect(this, SIGNAL(allowedAreasChanged(Qt::DockWidgetAreas)), + this, SLOT(allowedAreasChanged(Qt::DockWidgetAreas))); + connect(this, SIGNAL(featuresChanged(QDockWidget::DockWidgetFeatures)), + this, SLOT(featuresChanged(QDockWidget::DockWidgetFeatures))); + connect(this, SIGNAL(dockLocationChanged(Qt::DockWidgetArea)), + this, SLOT(dockLocationChanged(Qt::DockWidgetArea))); + connect(this, SIGNAL(topLevelChanged(bool)), + this, SLOT(topLevelChanged(bool))); + connect(this, SIGNAL(visibilityChanged(bool)), + this, SLOT(visibilityChanged(bool))); +} + +QAction *GLDDockWidget::addAction(const QIcon &icon, const QString &text) +{ + QAction *act = new QAction(icon, text, m_titleBar); + m_titleBar->insertAction(m_actLock, act); + return act; +} + +void GLDDockWidget::setIcon(const QIcon &icon) +{ + setWindowIcon(icon); +} + +void GLDDockWidget::resizeEvent(QResizeEvent *) +{ + // 锟斤拷锟斤拷锟侥憋拷锟斤拷小锟斤拷时锟斤拷锟斤拷锟节碉拷锟斤拷锟斤拷 + m_titleBar->setAutoFillBackground(true); + m_titleBar->setBackgroundRole(QPalette::Highlight); +} + +void GLDDockWidget::mouseReleaseEvent(QMouseEvent *event) +{ + gTabBarsControl.releaseEventOnDock(this, event); + QDockWidget::mouseReleaseEvent(event); +} + +void GLDDockWidget::leaveEvent(QEvent *event) +{ + gTabBarsControl.leaveDockWidget(this); + QDockWidget::leaveEvent(event); +} + + +void GLDDockWidget::allowedAreasChanged(Qt::DockWidgetAreas) +{ +} + +void GLDDockWidget::featuresChanged(QDockWidget::DockWidgetFeatures) +{ +} + +void GLDDockWidget::dockLocationChanged(Qt::DockWidgetArea) +{ + m_actFloat->setVisible(!isFloating()); + m_actFloat->setDisabled(isFloating()); + m_actLock->setVisible(isFloating()); + m_actLock->setEnabled(isFloating()); +} + +void GLDDockWidget::topLevelChanged(bool) +{ + m_actFloat->setVisible(!isFloating()); + m_actFloat->setDisabled(isFloating()); + m_actLock->setVisible(isFloating()); + m_actLock->setEnabled(isFloating()); + this->activateWindow(); +} + +void GLDDockWidget::visibilityChanged(bool) +{ + QObject *widget = this->nativeParentWidget(); + if (NULL == widget) + { + return; + } + // 锟斤拷锟斤拷锟叫碉拷bars锟斤拷装一锟斤拷锟铰硷拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷械锟絙ars锟较碉拷锟铰硷拷锟斤拷 + QList bars = widget->findChildren(QString(), Qt::FindDirectChildrenOnly); + for (int i = 0; i < bars.count(); ++i) + { + QTabBar *tabs = bars.at(i); + tabs->installEventFilter(&gTabBarsControl); + } +} + +void GLDDockWidget::onFloat() +{ + setFloating(true); +} + +void GLDDockWidget::onLock() +{ + setFloating(false); +} + +void GLDDockWidget::onClose() +{ + close(); +} + +void GLDDockWidget::initTitleBar() +{ + m_titleBar = new QToolBar(this); + this->setTitleBarWidget(m_titleBar); + m_titleBar->setStyleSheet("border: 0px"); + m_titleBar->setAutoFillBackground(true); + m_titleBar->setBackgroundRole(QPalette::Highlight); + m_titleBar->setToolButtonStyle(Qt::ToolButtonIconOnly); + + m_title = new QLabel(this); + m_title->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding); + m_actTitle = m_titleBar->addWidget(m_title); + + m_actLock = m_titleBar->addAction(QIcon(":Res/Floating16.png"), tr("&Lock")); + connect(m_actLock, SIGNAL(triggered()), this, SLOT(onLock())); + m_actFloat = m_titleBar->addAction(QIcon(":Res/Locked16.png"), tr("&Float")); + connect(m_actFloat, SIGNAL(triggered()), this, SLOT(onFloat())); + m_actClose = m_titleBar->addAction(QIcon(":Res/Close16.png"), tr("&Close")); + connect(m_actClose, SIGNAL(triggered()), this, SLOT(onClose())); +} + + +QAction *GLDDockWidget::addWidget(QWidget *widget) +{ + return m_titleBar->insertWidget(m_actLock, widget); +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDEllipsis.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDEllipsis.cpp new file mode 100644 index 00000000..2c78fc27 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDEllipsis.cpp @@ -0,0 +1,601 @@ +#include +#include + +#include "GLDEllipsis.h" +#include "GLDFileUtils.h" + +const QString c_sLineButtonEditQssFile = ":/qsses/GLDLineButtonEditEx.qss"; +const QString c_sPlainButtonEditQssFile = ":/qsses/GLDPlainButtonEditEx.qss"; + +GLDAbstractButtonEdit::GLDAbstractButtonEdit(QWidget *parent) : + QWidget(parent) +{ + m_button = new QPushButton(QString(" ..."), this); +// m_button->installEventFilter(this); + + int nTargetBtnWidth = qMax(c_MinButtonEditBtnWidth, m_button->fontMetrics().width(" ...")); + m_button->resize(nTargetBtnWidth + 1, height() + 2); + m_button->move(width() - nTargetBtnWidth, -1); + + connect(m_button, SIGNAL(clicked()), this, SLOT(onEllipsisButtonClicked())); +} + +GLDAbstractButtonEdit::~GLDAbstractButtonEdit() +{ + if (m_button != NULL) + { + freeAndNil(m_button); + } +} + +QString GLDAbstractButtonEdit::buttonCaption() const +{ + return m_button->text(); +} + +void GLDAbstractButtonEdit::setButtonCaption(QString caption) +{ + m_button->setText(caption); +} + +QModelIndex GLDAbstractButtonEdit::modelIndex() const +{ + return index; +} + +void GLDAbstractButtonEdit::setModelIndex(QModelIndex newIndex) +{ + index = newIndex; +} + +void GLDAbstractButtonEdit::onEllipsisButtonClicked() +{ + emit ellipsisButtonClicked(); + emit ellipsisButtonClicked(index); + + // 在tableView开启失去焦点退出编辑状态时,如果外部在接收到以上两个信号后,弹框,会导致tableView立即closeEdit, + // 当前对象就被释放了,再setFocus会引起崩溃。 + // litz-a之前修改的回车跳格问题,先暂时不处理。 +// setFocus(); +} + +//bool GLDAbstractButtonEdit::event(QEvent *e) +//{ +// if (e->type() == QEvent::Wheel) +// { +// //数据非法会出现两次弹窗 +//// parentWidget()->setFocus(); +// return true; +// } +// return QWidget::event(e); +//} + +QString GLDPlainButtonEdit::text() const +{ + QString strPlainText = m_plainTextEdit->toPlainText(); + return strPlainText; +} + +void GLDPlainButtonEdit::setText(QString text) +{ +#ifdef Q_OS_WIN + text.replace("\r\n", "\n"); +#endif + m_plainTextEdit->setPlainText(text); + m_plainTextEdit->selectAll(); +} + +void GLDPlainButtonEdit::setEditable(bool canEdit) +{ + m_plainTextEdit->setReadOnly(!canEdit); +} + +bool GLDPlainButtonEdit::eventFilter(QObject *obj, QEvent *event) +{ + QWidget *editor = dynamic_cast(obj); + if (!editor) + return false; + if (event->type() == QEvent::KeyPress) + { + QKeyEvent* keyEvent = static_cast(event); + if (keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return) + { + if (keyEvent->modifiers() == Qt::CTRL) + { + onEllipsisButtonClicked(); + return true; + } + else if (keyEvent->modifiers() == Qt::ALT) + { + cursorPosInsertANewLine(true); + return true; + } + else + { + QCoreApplication::sendEvent(this, event); + return true; + } + } + else if (keyEvent->key() == Qt::Key_Up || keyEvent->key() == Qt::Key_Down) + { + if (keyEvent->modifiers() == Qt::ALT) + { + onEllipsisButtonClicked(); + return true; + } + else + { + QCoreApplication::sendEvent(this, event); + return true; + } + } + else if (keyEvent->key() == Qt::Key_Tab || keyEvent->key() == Qt::Key_Backtab) + { + QCoreApplication::sendEvent(this, event); + return true; + } + else if (keyEvent->key() != Qt::Key_Left && keyEvent->key() != Qt::Key_Right + && keyEvent->key() != Qt::Key_Home && keyEvent->key() != Qt::Key_End) + { + event->ignore(); + return false; + } + } + if(event->type() == QEvent::FocusOut) + { + if(QApplication::focusWidget() != m_button) + { + QCoreApplication::sendEvent(this, event); + return false; + } + } + return QWidget::eventFilter(obj, event); +} + +bool GLDPlainButtonEdit::selectAll() +{ + bool bSelectSuccess = false; + if (m_plainTextEdit && m_plainTextEdit->isEnabled() && m_plainTextEdit->hasFocus()) + { + m_plainTextEdit->selectAll(); + bSelectSuccess = true; + } + return bSelectSuccess; +} + +bool GLDPlainButtonEdit::cursorPosInsertANewLine(bool addANewLine) +{ + bool bSelectSuccess = false; + if (m_plainTextEdit && m_plainTextEdit->isEnabled() && m_plainTextEdit->hasFocus()) + { + if (addANewLine) + { + m_plainTextEdit->removeEventFilter(this); + QKeyEvent keyEvent(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier); + QCoreApplication::sendEvent(m_plainTextEdit, &keyEvent); + m_plainTextEdit->installEventFilter(this); + } + else + m_plainTextEdit->moveCursor(QTextCursor::End); + bSelectSuccess = true; + } + return bSelectSuccess; +} + +bool GLDPlainButtonEdit::cursorMoveTextEnd() +{ + return cursorPosInsertANewLine(false); +} + +QMargins GLDPlainButtonEdit::contentsMargins() const +{ + return m_plainTextEdit->contentsMargins(); +} + +void GLDPlainButtonEdit::setContentsMargins(const QMargins &rhs) const +{ + m_plainTextEdit->setContentsMargins(rhs); +} + +void GLDPlainButtonEdit::setFont(const QFont &font) +{ + m_plainTextEdit->setFont(font); +} + +void GLDPlainButtonEdit::cut() +{ + m_plainTextEdit->cut(); +} + +void GLDPlainButtonEdit::paste() +{ + m_plainTextEdit->paste(); +} + +void GLDPlainButtonEdit::copy() +{ + m_plainTextEdit->copy(); +} + +void GLDPlainButtonEdit::deleteSelectedText() +{ + if (hasSelectedText()) + { + m_plainTextEdit->textCursor().removeSelectedText(); + } +} + +void GLDPlainButtonEdit::onCopyAvailable(bool yes) +{ + m_hasSelectedText = yes; + emit copyAvailable(yes); +} + +GLDPlainButtonEdit::GLDPlainButtonEdit(QWidget *parent) : + GLDAbstractButtonEdit(parent), m_hasSelectedText(false) +{ + m_plainTextEdit = new QPlainTextEdit(this); + m_plainTextEdit->installEventFilter(this); + + int nTargetBtnWidth = qMax(c_MinButtonEditBtnWidth, m_button->fontMetrics().width(" ...")); + m_plainTextEdit->setGeometry(0, 0, width() - nTargetBtnWidth + 2, height()); + m_plainTextEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_plainTextEdit->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_plainTextEdit->document()->setDocumentMargin(0); + this->setFocusProxy(m_plainTextEdit); + + connect(m_plainTextEdit, SIGNAL(copyAvailable(bool)), + this, SLOT(onCopyAvailable(bool))); +} + +GLDPlainButtonEdit::~GLDPlainButtonEdit() +{ + if (m_plainTextEdit != NULL) + { + delete m_plainTextEdit; + } +} + +void GLDPlainButtonEdit::paintEvent(QPaintEvent *) +{ + int nTargetBtnWidth = qMax(c_MinButtonEditBtnWidth, m_button->fontMetrics().width(" ...")); + m_plainTextEdit->setGeometry(0 ,0, width() - nTargetBtnWidth + 2, height()); + m_button->resize(nTargetBtnWidth + 1, height() + 2); + m_button->move(width() - nTargetBtnWidth, -1); +} + +QString GLDLineButtonEdit::text() const +{ + return m_lineEdit->text(); +} + +void GLDLineButtonEdit::setText(QString text) +{ + m_lineEdit->setText(text); +} + +void GLDLineButtonEdit::setEditable(bool canEdit) +{ + m_lineEdit->setReadOnly(!canEdit); +} + +bool GLDLineButtonEdit::eventFilter(QObject *obj, QEvent *event) +{ + QWidget *editor = dynamic_cast(obj); + if (!editor) + return false; + if (event->type() == QEvent::KeyPress) + { + QKeyEvent* keyEvent = static_cast(event); + if (keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return) + { + if (keyEvent->modifiers() == Qt::CTRL) + { + onEllipsisButtonClicked(); + return true; + } + else + { + QCoreApplication::sendEvent(this, event); + return true; + } + } + else if (keyEvent->key() == Qt::Key_Up || keyEvent->key() == Qt::Key_Down) + { + if (keyEvent->modifiers() == Qt::ALT) + { + onEllipsisButtonClicked(); + return true; + } + } + else if (keyEvent->key() == Qt::Key_Tab || keyEvent->key() == Qt::Key_Backtab) + { + QCoreApplication::sendEvent(this, event); + return true; + } + else if (keyEvent->key() != Qt::Key_Left && keyEvent->key() != Qt::Key_Right + && keyEvent->key() != Qt::Key_Home && keyEvent->key() != Qt::Key_End) + { + event->ignore(); + return false; + } + } + return QWidget::eventFilter(obj, event); +} + +bool GLDLineButtonEdit::selectAll() +{ + bool bSelectSuccess = false; + if (m_lineEdit && m_lineEdit->isEnabled()) + { + m_lineEdit->setFocus(); + m_lineEdit->selectAll(); + bSelectSuccess = true; + } + return bSelectSuccess; +} + +bool GLDLineButtonEdit::cursorPosInsertANewLine(bool addANewLine) +{ + Q_UNUSED(addANewLine); + bool bSelectSuccess = false; + if (m_lineEdit && m_lineEdit->isEnabled() && m_lineEdit->hasFocus()) + { + //官方QLineEdit不提供折行功能 +// m_lineEdit->cursorForward(false,m_lineEdit->text().length()); + bool bSelectText = false; + m_lineEdit->end(bSelectText); + bSelectSuccess = true; + } + return bSelectSuccess; +} + +bool GLDLineButtonEdit::cursorMoveTextEnd() +{ + return cursorPosInsertANewLine(false); +} + +QMargins GLDLineButtonEdit::contentsMargins() const +{ + return m_lineEdit->contentsMargins(); +} + +void GLDLineButtonEdit::setContentsMargins(const QMargins &rhs) const +{ + m_lineEdit->setContentsMargins(rhs); +} + +void GLDLineButtonEdit::setFont(const QFont &font) +{ + m_lineEdit->setFont(font); +} + +void GLDLineButtonEdit::cut() +{ + m_lineEdit->cut(); +} + +void GLDLineButtonEdit::paste() +{ + m_lineEdit->paste(); +} + +void GLDLineButtonEdit::copy() +{ + m_lineEdit->copy(); +} + +void GLDLineButtonEdit::deleteSelectedText() +{ + if (hasSelectedText()) + { + m_lineEdit->del(); + } +} + +GLDLineButtonEdit::GLDLineButtonEdit(QWidget *parent, QLineEdit *editor) : + GLDAbstractButtonEdit(parent) +{ + if (editor == NULL) + { + m_lineEdit = new GLDEllipsisLineEdit(this); + } + else + { + m_lineEdit = editor; + m_lineEdit->setParent(this); + } + m_lineEdit->installEventFilter(this); + + int nTargetBtnWidth = qMax(c_MinButtonEditBtnWidth, m_button->fontMetrics().width(" ...")); + int nBtnWidth = nTargetBtnWidth + 2; + int nLineEditWidth = width() - nBtnWidth; + + m_lineEdit->setGeometry(0, 0, nLineEditWidth, height()); + this->setFocusProxy(m_lineEdit); + + connect(m_lineEdit, SIGNAL(cursorPositionChanged(int,int)), + this, SLOT(doCursorPositionChanged(int,int))); + connect(m_lineEdit, SIGNAL(selectionChanged()), + this, SLOT(doSelectionChanged())); +} + +GLDLineButtonEdit::~GLDLineButtonEdit() +{ + if (m_lineEdit != NULL) + { + delete m_lineEdit; + } +} + +void GLDLineButtonEdit::paintEvent(QPaintEvent *) +{ + int nTargetBtnWidth = qMax(c_MinButtonEditBtnWidth, m_button->fontMetrics().width(" ...")); + int nLineWidth = width() - nTargetBtnWidth + 2; + m_lineEdit->setGeometry(0 ,0, nLineWidth, height()); + + int nBtnWidth = nTargetBtnWidth + 1; + m_button->resize(nBtnWidth, height() + 2); + m_button->move(nLineWidth - 2, -1); +} + +void GLDLineButtonEdit::doSelectionChanged() +{ + emit selectionChanged(); +} + +void GLDLineButtonEdit::doCursorPositionChanged(int, int) +{ + emit cursorPositionChanged(); +} + +void GLDLineButtonEdit::closeCopy() +{ + GLDEllipsisLineEdit *oLineEdit = dynamic_cast(m_lineEdit); + if (NULL != oLineEdit) + { + oLineEdit->closeCopy(); + } +} + +void GLDLineButtonEdit::openCopy() +{ + GLDEllipsisLineEdit *oLineEdit = dynamic_cast(m_lineEdit); + if (NULL != oLineEdit) + { + oLineEdit->openCopy(); + } +} + +void GLDLineButtonEdit::closePaste() +{ + GLDEllipsisLineEdit *oLineEdit = dynamic_cast(m_lineEdit); + if (NULL != oLineEdit) + { + oLineEdit->closePaste(); + } +} + +void GLDLineButtonEdit::openPaste() +{ + GLDEllipsisLineEdit *oLineEdit = dynamic_cast(m_lineEdit); + if (NULL != oLineEdit) + { + oLineEdit->openPaste(); + } +} + +GLDLineButtonEditEx::GLDLineButtonEditEx(QWidget *parent, QLineEdit *editor): + GLDLineButtonEdit(parent) +{ + Q_UNUSED(editor); + setProperty("EllipsisButtonWrap", "GLDLineButtonEditEx"); + setHasBorder(true); + this->setStyleSheet(loadQssFile(c_sLineButtonEditQssFile)); +} + +GLDLineButtonEditEx::~GLDLineButtonEditEx() +{ + +} + +void GLDLineButtonEditEx::paintEvent(QPaintEvent *e) +{ + GLDLineButtonEdit::paintEvent(e); + m_button->setPalette(QPalette(Qt::white)); + m_button->setAutoFillBackground(true); +} + +void GLDLineButtonEditEx::setHasBorder(bool bHasBorder) +{ + if (bHasBorder) + { + setProperty("EllipsisButtonWrap", "GLDLineButtonEditEx"); + } + else + { + setProperty("EllipsisButtonWrap", "noborder"); + } + this->setStyleSheet(loadQssFile(c_sLineButtonEditQssFile)); +} + +GLDPlainButtonEditEx::GLDPlainButtonEditEx(QWidget *parent): + GLDPlainButtonEdit(parent) +{ + QRect buttonRect = m_button->rect(); + m_button->setGeometry(buttonRect); + // Qss美化 + setProperty("EllipsisButtonWrap", "GLDPlainButtonEditEx"); + setHasBorder(true); + this->setStyleSheet(loadQssFile(c_sPlainButtonEditQssFile)); +} + +GLDPlainButtonEditEx::~GLDPlainButtonEditEx() +{ + +} + +void GLDPlainButtonEditEx::paintEvent(QPaintEvent *e) +{ + GLDPlainButtonEdit::paintEvent(e); + m_button->setPalette(QPalette(Qt::white)); + m_button->setAutoFillBackground(true); +} + +void GLDPlainButtonEditEx::setHasBorder(bool bHasBorder) +{ + if (bHasBorder) + { + setProperty("EllipsisButtonWrap", "GLDPlainButtonEditEx"); + } + else + { + setProperty("EllipsisButtonWrap", "noborder"); + } + setStyle(NULL); + this->setStyleSheet(loadQssFile(c_sPlainButtonEditQssFile)); +} + +GLDEllipsisLineEdit::GLDEllipsisLineEdit(QWidget *parent) : + QLineEdit(parent), m_closePaste(false), m_closeCopy(false) +{ + +} + +void GLDEllipsisLineEdit::closeCopy() +{ + m_closeCopy = true; +} + +void GLDEllipsisLineEdit::openCopy() +{ + m_closeCopy = false; +} + +void GLDEllipsisLineEdit::closePaste() +{ + m_closePaste = true; +} + +void GLDEllipsisLineEdit::openPaste() +{ + m_closePaste = false; +} + +void GLDEllipsisLineEdit::keyPressEvent(QKeyEvent *e) +{ + if (m_closePaste && e->key() == Qt::Key_V && + e->modifiers() == Qt::ControlModifier) + { + e->accept(); + return ; + } + if (m_closeCopy && e->key() == Qt::Key_C && + e->modifiers() == Qt::ControlModifier) + { + e->accept(); + return ; + } + + QLineEdit::keyPressEvent(e); +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDFileSystemModel.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDFileSystemModel.cpp new file mode 100644 index 00000000..99a6abb5 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDFileSystemModel.cpp @@ -0,0 +1,1485 @@ +#include "GLDFileSystemModel.h" + +#ifndef QT_NO_DIRMODEL + +#include "GLDStrUtils.h" +#include "GLDShellComboBoxEx.h" +#include "GLDFileUtils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * @class GLDFileSystemModel + * @brief 文件系统模型 + * @brief Copy from QDirModel source file + */ + +/*! + Constructs a new directory model with the given \a parent. + Only those files matching the \a nameFilters and the + \a filters are included in the model. The sort order is given by the + \a sort flags. +*/ +GLDFileSystemModel::GLDFileSystemModel(const QStringList &nameFilters, + QDir::Filters filters, + QDir::SortFlags sort, + QObject *parent) + : GLDCustomFileSystemModel(*new GLDFileSystemModelPrivate, parent) +{ + Q_D(GLDFileSystemModel); + // we always start with QDir::drives() + d->nameFilters = nameFilters.isEmpty() ? QStringList(QLatin1String("*")) : nameFilters; + d->filters = filters; + d->sort = sort; + d->root.parent = 0; + d->root.info = QFileInfo(); + d->clear(&d->root); +} + +/*! + Constructs a directory model with the given \a parent. +*/ +GLDFileSystemModel::GLDFileSystemModel(bool includingFile, QObject *parent) + : GLDCustomFileSystemModel(*new GLDFileSystemModelPrivate, parent) +{ + Q_D(GLDFileSystemModel); + QStringList nameFilters; + d->nameFilters = nameFilters.isEmpty() ? QStringList(QLatin1String("*")) : nameFilters; + QDir::Filters filts = QDir::AllEntries | QDir::AllDirs | QDir::NoDotAndDotDot; + if (!includingFile) + { + filts &= ~QDir::Files; + } + d->filters = filts; + + QDir::SortFlags sorts = QDir::DirsFirst | QDir::Name | QDir::IgnoreCase; + d->sort = sorts; + d->root.parent = 0; + d->root.info = QFileInfo(); + d->clear(&d->root); + + d->init(); +} + +/*! + \internal +*/ +GLDFileSystemModel::GLDFileSystemModel(GLDFileSystemModelPrivate &dd, QObject *parent) + : GLDCustomFileSystemModel(dd, parent) +{ + Q_D(GLDFileSystemModel); + d->init(); +} + +/*! + Destroys this directory model. +*/ + +GLDFileSystemModel::~GLDFileSystemModel() +{ + +} + +/*! + Returns the model item index for the item in the \a parent with the + given \a row and \a column. + +*/ + +QModelIndex GLDFileSystemModel::index(int row, int column, const QModelIndex &parent) const +{ + Q_D(const GLDFileSystemModel); + // note that rowCount does lazy population + if (column < 0 || column >= columnCount(parent) || row < 0 || parent.column() > 0) + return QModelIndex(); + // make sure the list of children is up to date + GLDFileSystemModelPrivate::QDirNode *nod = (d->indexValid(parent) ? d->node(parent) : &d->root); + Q_ASSERT(nod); + if (!nod->populated) + d->populate(nod); // populate without stat'ing + if (row >= nod->children.count()) + return QModelIndex(); + // now get the internal pointer for the index + GLDFileSystemModelPrivate::QDirNode *pNode = d->node(row, d->indexValid(parent) ? nod : 0); + Q_ASSERT(pNode); + + return createIndex(row, column, pNode); +} + +/*! + Return the parent of the given \a child model item. +*/ + +QModelIndex GLDFileSystemModel::parent(const QModelIndex &child) const +{ + Q_D(const GLDFileSystemModel); + + if (!d->indexValid(child)) + return QModelIndex(); + GLDFileSystemModelPrivate::QDirNode *node = d->node(child); + GLDFileSystemModelPrivate::QDirNode *par = (node ? node->parent : 0); + if (par == 0) // parent is the root node + return QModelIndex(); + + // get the parent's row + const QVector c_children = + par->parent ? par->parent->children : d->root.children; + Q_ASSERT(c_children.count() > 0); + int row = (par - &(c_children.at(0))); + Q_ASSERT(row >= 0); + + return createIndex(row, 0, par); +} + +/*! + Returns the number of rows in the \a parent model item. + +*/ + +int GLDFileSystemModel::rowCount(const QModelIndex &parent) const +{ + Q_D(const GLDFileSystemModel); + if (parent.column() > 0) + return 0; + + if (!parent.isValid()) + { + if (!d->root.populated) // lazy population + d->populate(&d->root); + return d->root.children.count(); + } + if (parent.model() != this) + return 0; + GLDFileSystemModelPrivate::QDirNode *pNode = d->node(parent); + if (pNode->info.isDir() && !pNode->populated) // lazy population + d->populate(pNode); + return pNode->children.count(); +} + +/*! + Returns the number of columns in the \a parent model item. + +*/ + +int GLDFileSystemModel::columnCount(const QModelIndex &parent) const +{ + if (parent.column() > 0) + return 0; + return 5; +} + +/*! + Returns the data for the model item \a index with the given \a role. +*/ +QVariant GLDFileSystemModel::data(const QModelIndex &index, int role) const +{ + Q_D(const GLDFileSystemModel); + if (!d->indexValid(index)) + return QVariant(); + + if (role == Qt::DisplayRole || role == Qt::EditRole) + { + switch (index.column()) + { + case 0: + { + QString strName = d->name(index); + if (0 == strName.compare("desktop", Qt::CaseInsensitive)) + { + strName = tr("desktop");//TRANS_STRING("桌面"); //TODO 翻译的权宜之计 + } + return strName; + } + case 1: return d->type(index); + case 2: return d->updateDateTime(index); + case 3: return d->createDateTime(index); + case 4: return d->size(index); + default: + qWarning("data: invalid display value column %d", index.column()); + return QVariant(); + } + } + + if (index.column() == 0) + { + if (role == FileIconRole) + return fileIcon(index); + if (role == FilePathRole) + return filePath(index); + if (role == FileNameRole) + return fileName(index); + } + + if (role == Qt::TextAlignmentRole) + { + if (m_enViewMode == GLDListView::VSReportMode) + { + switch (index.column()) + { + case 0: + case 1: + case 2: + case 3: + return (QVariant)(Qt::AlignLeft | Qt::AlignVCenter); + case 4: + return (QVariant)(Qt::AlignRight | Qt::AlignVCenter); + } + return Qt::AlignCenter; + } + else if(m_enViewMode == GLDListView::VSIconMode) + { + return Qt::AlignCenter; + } + else + { + return Qt::AlignLeft; + } + } + return QVariant(); +} + +/*! + Sets the data for the model item \a index with the given \a role to + the data referenced by the \a value. Returns true if successful; + otherwise returns false. + + \sa Qt::ItemDataRole +*/ + +bool GLDFileSystemModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + Q_D(GLDFileSystemModel); + if (!d->indexValid(index) || index.column() != 0 + || (flags(index) & Qt::ItemIsEditable) == 0 || role != Qt::EditRole) + return false; + + GLDFileSystemModelPrivate::QDirNode *node = d->node(index); + QDir dir = node->info.dir(); + QString strname = value.toString(); + if (dir.rename(node->info.fileName(), strname)) + { + node->info = QFileInfo(dir, strname); + QModelIndex sibling = index.sibling(index.row(), 3); + emit dataChanged(index, sibling); + + d->toBeRefreshed = index.parent(); + QMetaObject::invokeMethod(this, "_q_refresh", Qt::QueuedConnection); + + return true; + } + + return false; +} + +/*! + Returns the data stored under the given \a role for the specified \a section + of the header with the given \a orientation. +*/ + +QVariant GLDFileSystemModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (orientation == Qt::Horizontal) + { + if (role != Qt::DisplayRole) + return QVariant(); + switch (section) { + case 0: return tr("Name"); + case 1: return tr("Size"); + case 2: return + #ifdef __APPLE__ + tr("Kind", "Match OS X Finder"); +#else + tr("Type", "All other platforms"); +#endif + // Windows - Type + // OS X - Kind + // Konqueror - File Type + // Nautilus - Type + case 3: return tr("Date Modified"); + default: return QVariant(); + } + } + return QAbstractItemModel::headerData(section, orientation, role); +} + +/*! + Returns true if the \a parent model item has children; otherwise + returns false. +*/ + +bool GLDFileSystemModel::hasChildren(const QModelIndex &parent) const +{ + Q_D(const GLDFileSystemModel); + if (parent.column() > 0) + return false; + + if (!parent.isValid()) // the invalid index is the "My Computer" item + return true; // the drives + GLDFileSystemModelPrivate::QDirNode *pNode = d->node(parent); + Q_ASSERT(pNode); + + if (d->lazyChildCount) // optimization that only checks for children if the node has been populated + return pNode->info.isDir(); + return pNode->info.isDir() && rowCount(parent) > 0; +} + +/*! + Returns the item flags for the given \a index in the model. + + \sa Qt::ItemFlags +*/ +Qt::ItemFlags GLDFileSystemModel::flags(const QModelIndex &index) const +{ + Q_D(const GLDFileSystemModel); + Qt::ItemFlags flags = QAbstractItemModel::flags(index); + if (!d->indexValid(index)) + return flags; + flags |= Qt::ItemIsDragEnabled; + if (d->readOnly) + return flags; + GLDFileSystemModelPrivate::QDirNode *node = d->node(index); + if ((index.column() == 0) && node->info.isWritable()) + { + flags |= Qt::ItemIsEditable; + if (fileInfo(index).isDir()) // is directory and is editable + flags |= Qt::ItemIsDropEnabled; + } + return flags; +} + +/*! + Sort the model items in the \a column using the \a order given. + The order is a value defined in \l Qt::SortOrder. +*/ + +void GLDFileSystemModel::sort(int column, Qt::SortOrder order) +{ + QDir::SortFlags sort = QDir::DirsFirst | QDir::IgnoreCase; + if (order == Qt::DescendingOrder) + sort |= QDir::Reversed; + + switch (column) { + case 0: + sort |= QDir::Name; + break; + case 1: + sort |= QDir::Size; + break; + case 2: + sort |= QDir::Type; + break; + case 3: + sort |= QDir::Time; + break; + default: + break; + } + + setSorting(sort); +} + +/*! + Returns a list of MIME types that can be used to describe a list of items + in the model. +*/ + +QStringList GLDFileSystemModel::mimeTypes() const +{ + return QStringList(QLatin1String("text/uri-list")); +} + +/*! + Returns an object that contains a serialized description of the specified + \a indexes. The format used to describe the items corresponding to the + indexes is obtained from the mimeTypes() function. + + If the list of indexes is empty, 0 is returned rather than a serialized + empty list. +*/ + +QMimeData *GLDFileSystemModel::mimeData(const QModelIndexList &indexes) const +{ + QList urls; + QList::const_iterator it = indexes.begin(); + for (; it != indexes.end(); ++it) + { + if ((*it).column() == 0) + { + urls << QUrl::fromLocalFile(filePath(*it)); + } + } + QMimeData *data = new QMimeData(); + data->setUrls(urls); + return data; +} + +/*! + Handles the \a data supplied by a drag and drop operation that ended with + the given \a action over the row in the model specified by the \a row and + \a column and by the \a parent index. + + Returns true if the drop was successful, and false otherwise. + + \sa supportedDropActions() +*/ + +bool GLDFileSystemModel::dropMimeData(const QMimeData *data, Qt::DropAction action, + int /* row */, int /* column */, const QModelIndex &parent) +{ + Q_D(GLDFileSystemModel); + if (!d->indexValid(parent) || isReadOnly()) + return false; + + bool bsuccess = true; + QString to = filePath(parent) + QDir::separator(); + QModelIndex _parent = parent; + + QList urls = data->urls(); + QList::const_iterator it = urls.constBegin(); + + switch (action) { + case Qt::CopyAction: + for (; it != urls.constEnd(); ++it) + { + QString strpath = (*it).toLocalFile(); + bsuccess = QFile::copy(strpath, to + QFileInfo(strpath).fileName()) && bsuccess; + } + break; + case Qt::LinkAction: + for (; it != urls.constEnd(); ++it) + { + QString strpath = (*it).toLocalFile(); + bsuccess = QFile::link(strpath, to + QFileInfo(strpath).fileName()) && bsuccess; + } + break; + case Qt::MoveAction: + for (; it != urls.constEnd(); ++it) + { + QString strpath = (*it).toLocalFile(); + if (QFile::copy(strpath, to + QFileInfo(strpath).fileName()) + && QFile::remove(strpath)) + { + QModelIndex idx=index(QFileInfo(strpath).path()); + if (idx.isValid()) + { + refresh(idx); + //the previous call to refresh may invalidate the _parent. so recreate a new QModelIndex + _parent = index(to); + } + } + else + { + bsuccess = false; + } + } + break; + default: + return false; + } + + if (bsuccess) + refresh(_parent); + + return bsuccess; +} + +/*! + Returns the drop actions supported by this model. + + \sa Qt::DropActions +*/ + +Qt::DropActions GLDFileSystemModel::supportedDropActions() const +{ + return Qt::CopyAction | Qt::MoveAction; // FIXME: LinkAction is not supported yet +} + +/*! + Sets the \a provider of file icons for the directory model. + +*/ + +void GLDFileSystemModel::setIconProvider(QFileIconProvider *provider) +{ + Q_D(GLDFileSystemModel); + d->iconProvider = provider; +} + +/*! + Returns the file icon provider for this directory model. +*/ + +QFileIconProvider *GLDFileSystemModel::iconProvider() const +{ + Q_D(const GLDFileSystemModel); + return d->iconProvider; +} + +/*! + Sets the name \a filters for the directory model. +*/ + +void GLDFileSystemModel::setNameFilters(const QStringList &filters) +{ + Q_D(GLDFileSystemModel); + d->nameFilters = filters; + d->populate(&(d->root)); + emit layoutAboutToBeChanged(); + if (d->shouldStat) + refresh(QModelIndex()); + else + d->invalidate(); + emit layoutChanged(); +} + +/*! + Returns a list of filters applied to the names in the model. +*/ + +QStringList GLDFileSystemModel::nameFilters() const +{ + Q_D(const GLDFileSystemModel); + return d->nameFilters; +} + +/*! + Sets the directory model's filter to that specified by \a filters. + + Note that the filter you set should always include the QDir::AllDirs enum value, + otherwise GLDFileSystemModel won't be able to read the directory structure. + + \sa QDir::Filters +*/ + +void GLDFileSystemModel::setFilter(QDir::Filters filters) +{ + Q_D(GLDFileSystemModel); + d->filters = filters; + emit layoutAboutToBeChanged(); + if (d->shouldStat) + refresh(QModelIndex()); + else + d->invalidate(); + emit layoutChanged(); +} + +/*! + Returns the filter specification for the directory model. + + \sa QDir::Filters +*/ + +QDir::Filters GLDFileSystemModel::filter() const +{ + Q_D(const GLDFileSystemModel); + return d->filters; +} + +/*! + Sets the directory model's sorting order to that specified by \a sort. + + \sa QDir::SortFlags +*/ + +void GLDFileSystemModel::setSorting(QDir::SortFlags sort) +{ + Q_D(GLDFileSystemModel); + d->sort = sort; + emit layoutAboutToBeChanged(); + if (d->shouldStat) + refresh(QModelIndex()); + else + d->invalidate(); + emit layoutChanged(); +} + +/*! + Returns the sorting method used for the directory model. + + \sa QDir::SortFlags +*/ + +QDir::SortFlags GLDFileSystemModel::sorting() const +{ + Q_D(const GLDFileSystemModel); + return d->sort; +} + +/*! + \property GLDFileSystemModel::resolveSymlinks + \brief Whether the directory model should resolve symbolic links + + This is only relevant on operating systems that support symbolic + links. +*/ +void GLDFileSystemModel::setResolveSymlinks(bool enable) +{ + Q_D(GLDFileSystemModel); + d->resolveSymlinks = enable; +} + +bool GLDFileSystemModel::resolveSymlinks() const +{ + Q_D(const GLDFileSystemModel); + return d->resolveSymlinks; +} + +/*! + \property GLDFileSystemModel::readOnly + \brief Whether the directory model allows writing to the file system + + If this property is set to false, the directory model will allow renaming, copying + and deleting of files and directories. + + This property is true by default +*/ + +void GLDFileSystemModel::setReadOnly(bool enable) +{ + Q_D(GLDFileSystemModel); + d->readOnly = enable; +} + +bool GLDFileSystemModel::isReadOnly() const +{ + Q_D(const GLDFileSystemModel); + return d->readOnly; +} + +/*! + \property GLDFileSystemModel::lazyChildCount + \brief Whether the directory model optimizes the hasChildren function + to only check if the item is a directory. + + If this property is set to false, the directory model will make sure that a directory + actually containes any files before reporting that it has children. + Otherwise the directory model will report that an item has children if the item + is a directory. + + This property is false by default +*/ + +void GLDFileSystemModel::setLazyChildCount(bool enable) +{ + Q_D(GLDFileSystemModel); + d->lazyChildCount = enable; +} + +bool GLDFileSystemModel::lazyChildCount() const +{ + Q_D(const GLDFileSystemModel); + return d->lazyChildCount; +} + +/*! + GLDFileSystemModel caches file information. This function updates the + cache. The \a parent parameter is the directory from which the + model is updated; the default value will update the model from + root directory of the file system (the entire model). +*/ + +void GLDFileSystemModel::refresh(const QModelIndex &parent) +{ + Q_D(GLDFileSystemModel); + + GLDFileSystemModelPrivate::QDirNode *nnod = d->indexValid(parent) ? d->node(parent) : &(d->root); + + int nrowscounter = nnod->children.count(); + if (nrowscounter == 0) + { + emit layoutAboutToBeChanged(); + nnod->stat = true; // make sure that next time we read all the info + nnod->populated = false; + emit layoutChanged(); + return; + } + + emit layoutAboutToBeChanged(); + d->savePersistentIndexes(); + d->rowsAboutToBeRemoved(parent, 0, nrowscounter - 1); + nnod->stat = true; // make sure that next time we read all the info +// d->clear(nnod); + d->rowsRemoved(parent, 0, nrowscounter - 1); + d->restorePersistentIndexes(); + emit layoutChanged(); +} + +/*! + \overload + + Returns the model item index for the given \a path. +*/ + +QModelIndex GLDFileSystemModel::index(const QString &path, int column) const +{ + Q_D(const GLDFileSystemModel); + + if (path.isEmpty() || path == QCoreApplication::translate("QFileDialog", "My Computer")) + return QModelIndex(); + + QString strabsolutePath = QDir(path).absolutePath(); +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) + strabsolutePath = strabsolutePath.toLower(); + // On Windows, "filename......." and "filename" are equivalent + if (strabsolutePath.endsWith(QLatin1Char('.'))) + { + int nIter; + for (nIter = strabsolutePath.count() - 1; nIter >= 0; --nIter) + { + if (strabsolutePath.at(nIter) != QLatin1Char('.')) + break; + } + strabsolutePath = strabsolutePath.left(nIter + 1); + } +#endif + + QStringList pathElements = strabsolutePath.split(QLatin1Char('/'), QString::SkipEmptyParts); + if ((pathElements.isEmpty() || !QFileInfo(path).exists()) +#if !defined(Q_OS_WIN) || defined(Q_OS_WINCE) + && path != QLatin1String("/") +#endif + ) + return QModelIndex(); + + QModelIndex idx; // start with "My Computer" + if (!d->root.populated) // make sure the root is populated + d->populate(&d->root); + +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) + if (strabsolutePath.startsWith(QLatin1String("//"))) // UNC path + { + QString strhost = pathElements.first(); + int row = 0; + for (row = 0; row < d->root.children.count(); ++row) + { + if (d->root.children.at(row).info.fileName() == strhost) + { + break; + } + } + bool bchildAppended = false; + if (row >= d->root.children.count() && d->allowAppendChild) + { + d->appendChild(&d->root, QLatin1String("//") + strhost); + bchildAppended = true; + } + idx = index(row, 0, QModelIndex()); + pathElements.pop_front(); + if (bchildAppended) + emit const_cast(this)->layoutChanged(); + } else +#endif +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) + if (pathElements.at(0).endsWith(QLatin1Char(':'))) + { + pathElements[0] += QLatin1Char('/'); + } +#else + // add the "/" item, since it is a valid path element on unix + pathElements.prepend(QLatin1String("/")); +#endif + + for (int i = 0; i < pathElements.count(); ++i) + { + Q_ASSERT(!pathElements.at(i).isEmpty()); + QString strelement = pathElements.at(i); + GLDFileSystemModelPrivate::QDirNode *parent = (idx.isValid() ? d->node(idx) : &d->root); + + Q_ASSERT(parent); + if (!parent->populated) + d->populate(parent); + + // search for the element in the child nodes first + int row = -1; + for (int j = parent->children.count() - 1; j >= 0; --j) + { + const QFileInfo& fi = parent->children.at(j).info; + QString strchildFileName; + strchildFileName = idx.isValid() ? fi.fileName() : fi.absoluteFilePath(); +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) + strchildFileName = strchildFileName.toLower(); +#endif + if (strchildFileName == strelement) + { + if (i == pathElements.count() - 1) + parent->children[j].stat = true; + row = j; + break; + } + } + + // we couldn't find the path element, we create a new node since we _know_ that the path is valid + if (row == -1) + { +#if defined(Q_OS_WINCE) + QString strNewPath; + if (parent->info.isRoot()) + strNewPath = parent->info.absoluteFilePath() + element; + else + strNewPath = parent->info.absoluteFilePath() + QLatin1Char('/') + element; +#else + QString strNewPath = parent->info.absoluteFilePath() + QLatin1Char('/') + strelement; +#endif + if (!d->allowAppendChild || !QFileInfo(strNewPath).isDir()) + return QModelIndex(); + d->appendChild(parent, strNewPath); + row = parent->children.count() - 1; + if (i == pathElements.count() - 1) // always stat children of the last element + parent->children[row].stat = true; + emit const_cast(this)->layoutChanged(); + } + + Q_ASSERT(row >= 0); + idx = createIndex(row, 0, static_cast(&parent->children[row])); + Q_ASSERT(idx.isValid()); + } + + if (column != 0) + return idx.sibling(idx.row(), column); + return idx; +} + +/*! + Returns true if the model item \a index represents a directory; + otherwise returns false. +*/ + +bool GLDFileSystemModel::isDir(const QModelIndex &index) const +{ + Q_D(const GLDFileSystemModel); + if (!d->indexValid(index)) + return false; + GLDFileSystemModelPrivate::QDirNode *node = d->node(index); + if (sameText(node->info.path(), "A:/")) + { + return false; + } + return node->info.isDir(); +} + +/*! + Create a directory with the \a name in the \a parent model item. +*/ +QModelIndex GLDFileSystemModel::mkdir(const QModelIndex &parent, const QString &name) +{ + Q_D(GLDFileSystemModel); + if (!d->indexValid(parent) || isReadOnly()) + return QModelIndex(); + + GLDFileSystemModelPrivate::QDirNode *ppNode = d->node(parent); + QString strpath = ppNode->info.absoluteFilePath(); + // For the indexOf() method to work, the new directory has to be a direct child of + // the parent directory. + + QDir newDir(name); + QDir dir(strpath); + if (newDir.isRelative()) + newDir = QDir(strpath + QLatin1Char('/') + name); + QString strchildName = newDir.dirName(); // Get the singular name of the directory + newDir.cdUp(); + + if (newDir.absolutePath() != dir.absolutePath() || !dir.mkdir(name)) + return QModelIndex(); // nothing happened + GString strChildPath; + if (strpath.endsWith('/')) + { + strChildPath = strpath + strchildName; + } + else + { + strChildPath = strpath + "/" + strchildName; + } + + beginInsertRows(parent, ppNode->children.count(), ppNode->children.count()); + d->appendChild(ppNode, strChildPath); + endInsertRows(); + + QModelIndex inde = index(ppNode->children.count() - 1, 0, parent); // return an invalid index + + return inde; +} + +/*! + Removes the directory corresponding to the model item \a index in the + directory model and \b{deletes the corresponding directory from the + file system}, returning true if successful. If the directory cannot be + removed, false is returned. + + \warning This function deletes directories from the file system; it does + \b{not} move them to a location where they can be recovered. + + \sa remove() +*/ + +bool GLDFileSystemModel::rmdir(const QModelIndex &index) +{ + Q_D(GLDFileSystemModel); + if (!d->indexValid(index) || isReadOnly()) + return false; + + GLDFileSystemModelPrivate::QDirNode *node = d_func()->node(index); + if (!node->info.isDir()) + { + qWarning("rmdir: the node is not a directory"); + return false; + } + + QModelIndex par = parent(index); + GLDFileSystemModelPrivate::QDirNode *pNode = d_func()->node(par); + QString strPath = node->info.absoluteFilePath(); + if (!deleteTree(strPath)) + { + return false; + } + + beginRemoveRows(index.parent(), index.row(), index.row()); + + d->removeChild(pNode, index); + refresh(par); + + endRemoveRows(); + return true; +} + +/*! + Removes the model item \a index from the directory model and \b{deletes the + corresponding file from the file system}, returning true if successful. If the + item cannot be removed, false is returned. + + \warning This function deletes files from the file system; it does \b{not} + move them to a location where they can be recovered. + + \sa rmdir() +*/ + +bool GLDFileSystemModel::remove(const QModelIndex &index) +{ + Q_D(GLDFileSystemModel); + if (!d->indexValid(index) || isReadOnly()) + return false; + + GLDFileSystemModelPrivate::QDirNode *pNod = d_func()->node(index); + if (pNod->info.isDir()) + return false; + + QModelIndex par = parent(index); + GLDFileSystemModelPrivate::QDirNode *pNode = d_func()->node(par); + QDir dir = pNode->info.dir(); // parent dir + QString strPath = pNod->info.absoluteFilePath(); + if (!dir.remove(strPath)) + return false; + + beginRemoveRows(index.parent(), index.row(), index.row()); + + d->removeChild(pNode, index); + refresh(par); + + endRemoveRows(); + return true; +} + +/*! + Returns the path of the item stored in the model under the + \a index given. + +*/ + +QString GLDFileSystemModel::filePath(const QModelIndex &index) const +{ + Q_D(const GLDFileSystemModel); + if (d->indexValid(index)) { + QFileInfo fi = fileInfo(index); + if (d->resolveSymlinks && fi.isSymLink()) + fi = d->resolvedInfo(fi); + return QDir::cleanPath(fi.absoluteFilePath()); + } + return QString(); // root path +} + +/*! + Returns the name of the item stored in the model under the + \a index given. + +*/ + +QString GLDFileSystemModel::fileName(const QModelIndex &index) const +{ + Q_D(const GLDFileSystemModel); + if (!d->indexValid(index)) + return QString(); + QFileInfo info = fileInfo(index); + if (info.isRoot()) + return info.absoluteFilePath(); + if (d->resolveSymlinks && info.isSymLink()) + info = d->resolvedInfo(info); + return info.fileName(); +} + +/*! + Returns the icons for the item stored in the model under the given + \a index. +*/ + +QIcon GLDFileSystemModel::fileIcon(const QModelIndex &index) const +{ + Q_D(const GLDFileSystemModel); + if (!d->indexValid(index)) + return d->iconProvider->icon(QFileIconProvider::Computer); + GLDFileSystemModelPrivate::QDirNode *node = d->node(index); + if (node->icon.isNull()) + node->icon = d->iconProvider->icon(node->info); + return node->icon; +} + +/*! + Returns the file information for the specified model \a index. + + \b{Note:} If the model index represents a symbolic link in the + underlying filing system, the file information returned will contain + information about the symbolic link itself, regardless of whether + resolveSymlinks is enabled or not. + + \sa QFileInfo::symLinkTarget() +*/ + +QFileInfo GLDFileSystemModel::fileInfo(const QModelIndex &index) const +{ + Q_D(const GLDFileSystemModel); + Q_ASSERT(d->indexValid(index)); + + GLDFileSystemModelPrivate::QDirNode *node = d->node(index); + return node->info; +} + +QString GLDFileSystemModel::makeCaseCorrespondingToSystem(const QString &path) const +{ + QModelIndex dirIndex = index(path); + QString rightCase = filePath(dirIndex); + return rightCase; +} + +/*! + \fn QObject *GLDFileSystemModel::parent() const + \internal +*/ + +/** + * @class GLDFileSystemModelPrivate + * @brief 文件系统模型私有类 + * @brief The root node is never seen outside the model. + */ + +void qt_setDirModelShouldNotStat(GLDFileSystemModelPrivate *modelPrivate) +{ + modelPrivate->shouldStat = false; +} + +void GLDFileSystemModelPrivate::init() +{ + filters = QDir::AllEntries | QDir::NoDotAndDotDot; + sort = QDir::Name; + if (nameFilters.isEmpty()) + { + nameFilters << QLatin1String("*"); + } + root.parent = 0; + root.info = QFileInfo(); + clear(&root); + roleNames.insertMulti(GLDCustomFileSystemModel::FileIconRole, QByteArrayLiteral("fileIcon")); // == Qt::decoration + roleNames.insert(GLDCustomFileSystemModel::FilePathRole, QByteArrayLiteral("filePath")); + roleNames.insert(GLDCustomFileSystemModel::FileNameRole, QByteArrayLiteral("fileName")); +} + +GLDFileSystemModelPrivate::QDirNode *GLDFileSystemModelPrivate::node(int row, QDirNode *parent) const +{ + if (row < 0) + return 0; + + bool bIsDir = !parent || parent->info.isDir(); + QDirNode *pNode = (parent ? parent : &root); + if (bIsDir && !pNode->populated) + populate(pNode); // will also resolve symlinks + + if (row >= pNode->children.count()) + { + qWarning("node: the row does not exist"); + return 0; + } + + return const_cast(&pNode->children.at(row)); +} + +QVector GLDFileSystemModelPrivate::children(QDirNode *parent, bool stat) const +{ + Q_ASSERT(parent); + //此处先这么绕过去,有的有A盘的机子,会出现驱动器未就绪 + if (sameText(parent->info.path(), "A:/")) + { + QVector nodes(0); + return nodes; + } + QFileInfoList infoList; + if (parent == &root) + { + parent = 0; + QString strDesktopDir = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); + QFileInfo ifleInfo(strDesktopDir); + infoList = QDir::drives(); + infoList.prepend(ifleInfo); + } + else if (parent->info.isDir()) + { + //resolve directory links only if requested. + if (parent->info.isSymLink() && resolveSymlinks) + { + QString strlink = parent->info.symLinkTarget(); + if (strlink.size() > 1 && strlink.at(strlink.size() - 1) == QDir::separator()) + strlink.chop(1); + if (stat) + infoList = entryInfoList(strlink); + else + infoList = QDir(strlink).entryInfoList(nameFilters, QDir::AllEntries | QDir::System); + } + else + { + if (stat) + infoList = entryInfoList(parent->info.absoluteFilePath()); + else + infoList = QDir(parent->info.absoluteFilePath()).entryInfoList(nameFilters, + QDir::AllEntries | QDir::System); + } + } + + QVector nodes(infoList.count()); + int nDriverAIndex = -1; + for (int i = 0; i < infoList.count(); ++i) + { + QDirNode &node = nodes[i]; + node.parent = parent; + node.info = infoList.at(i); + if (sameText(node.info.path(), "A:/")) + { + nDriverAIndex = i; + } + node.populated = false; + node.stat = shouldStat; + } + if (nDriverAIndex != -1) + { + nodes.remove(nDriverAIndex); + } + + return nodes; +} + +void GLDFileSystemModelPrivate::_q_refresh() +{ + Q_Q(GLDFileSystemModel); + q->refresh(toBeRefreshed); + toBeRefreshed = QModelIndex(); +} + +void GLDFileSystemModelPrivate::savePersistentIndexes() +{ + Q_Q(GLDFileSystemModel); + savedPersistent.clear(); + foreach (QPersistentModelIndexData *data, persistent.indexes) { + SavedPersistent saved; + QModelIndex index = data->index; + saved.path = q->filePath(index); + saved.column = index.column(); + saved.data = data; + saved.index = index; + savedPersistent.append(saved); + } +} + +void GLDFileSystemModelPrivate::restorePersistentIndexes() +{ + Q_Q(GLDFileSystemModel); + bool ballow = allowAppendChild; + allowAppendChild = false; + for (int i = 0; i < savedPersistent.count(); ++i) + { + QPersistentModelIndexData *data = savedPersistent.at(i).data; + QString strpath = savedPersistent.at(i).path; + int ncolumn = savedPersistent.at(i).column; + QModelIndex idx = q->index(strpath, ncolumn); + if (idx != data->index || data->model == 0) + { + //data->model may be equal to 0 if the model is getting destroyed + persistent.indexes.remove(data->index); + data->index = idx; + data->model = q; + if (idx.isValid()) + persistent.indexes.insert(idx, data); + } + } + savedPersistent.clear(); + allowAppendChild = ballow; +} + +QFileInfoList GLDFileSystemModelPrivate::entryInfoList(const QString &path) const +{ + const QDir c_dir(path); + return c_dir.entryInfoList(nameFilters, filters, sort); +} + +QStringList GLDFileSystemModelPrivate::entryList(const QString &path) const +{ + const QDir c_dir(path); + return c_dir.entryList(nameFilters, filters, sort); +} + +QString GLDFileSystemModelPrivate::name(const QModelIndex &index) const +{ + const QDirNode *pnode = node(index); + const QFileInfo c_info = pnode->info; + if (c_info.isRoot()) + { + QString strName = c_info.absoluteFilePath(); +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) + if (strName.startsWith(QLatin1Char('/'))) // UNC host + return c_info.fileName(); + if (strName.endsWith(QLatin1Char('/'))) + strName.chop(1); +#endif + return strName; + } + return c_info.fileName(); +} + +QString GLDFileSystemModelPrivate::size(const QModelIndex &index) const +{ + const QDirNode *pnode = node(index); + if (pnode->info.isDir()) + { +#ifdef __APPLE__ + return QLatin1String("--"); +#else + return QLatin1String(""); +#endif + // Windows - "" + // OS X - "--" + // Konqueror - "4 KB" + // Nautilus - "9 items" (the number of children) + } + + // According to the Si standard KB is 1000 bytes, KiB is 1024 + // but on windows sizes are calulated by dividing by 1024 so we do what they do. + const quint64 c_kb = 1024; + const quint64 c_mb = 1024 * c_kb; + const quint64 c_gb = 1024 * c_mb; + const quint64 c_tb = 1024 * c_gb; + quint64 bytes = pnode->info.size(); + if (bytes >= c_tb) + return QFileSystemModel::tr("%1 TB").arg(QLocale().toString(qreal(bytes) / c_tb, 'f', 3)); + if (bytes >= c_gb) + return QFileSystemModel::tr("%1 GB").arg(QLocale().toString(qreal(bytes) / c_gb, 'f', 2)); + if (bytes >= c_mb) + return QFileSystemModel::tr("%1 MB").arg(QLocale().toString(qreal(bytes) / c_mb, 'f', 1)); + if (bytes >= c_kb) + return QFileSystemModel::tr("%1 KB").arg(QLocale().toString(bytes / c_kb)); + return QFileSystemModel::tr("%1 byte(s)").arg(QLocale().toString(bytes)); +} + +QString GLDFileSystemModelPrivate::type(const QModelIndex &index) const +{ + return iconProvider->type(node(index)->info); +} + +QString GLDFileSystemModelPrivate::updateDateTime(const QModelIndex &index) const +{ +#ifndef QT_NO_DATESTRING + return node(index)->info.lastModified().toString(Qt::LocalDate); +#else + Q_UNUSED(index); + return QString(); +#endif +} + +QString GLDFileSystemModelPrivate::createDateTime(const QModelIndex &index) const +{ +#ifndef QT_NO_DATESTRING + return node(index)->info.created().toString(Qt::LocalDate); +#else + Q_UNUSED(index); + return QString(); +#endif +} + +void GLDFileSystemModelPrivate::appendChild(GLDFileSystemModelPrivate::QDirNode *parent, const QString &path) const +{ + GLDFileSystemModelPrivate::QDirNode node; + node.populated = false; + node.stat = shouldStat; + node.parent = (parent == &root ? 0 : parent); + node.info = QFileInfo(path); + node.info.setCaching(true); + + // The following append(node) may reallocate the vector, thus + // we need to update the pointers to the childnodes parent. + GLDFileSystemModelPrivate *that = const_cast(this); + that->savePersistentIndexes(); + parent->children.append(node); + for (int i = 0; i < parent->children.count(); ++i) + { + QDirNode *childNode = &parent->children[i]; + for (int j = 0; j < childNode->children.count(); ++j) + { + childNode->children[j].parent = childNode; + } + } + that->restorePersistentIndexes(); +} + +void GLDFileSystemModelPrivate::removeChild(GLDFileSystemModelPrivate::QDirNode *parent, + const QModelIndex &index) const +{ + if (!index.isValid()) + { + return; + } + if ((index.row()) >= (parent->children.count())) + { + return; + } + + GLDFileSystemModelPrivate *that = const_cast(this); + that->savePersistentIndexes(); + GLDFileSystemModelPrivate::QDirNode *pToRemoveChild = node(index); + if (pToRemoveChild->info.isDir()) + { + that->removeAll(pToRemoveChild); + } + parent->children.remove(index.row()); + that->restorePersistentIndexes(); +} + +void GLDFileSystemModelPrivate::removeAll(GLDFileSystemModelPrivate::QDirNode *pNode) +{ + foreach (QDirNode childNode, pNode->children) + { + if (childNode.info.isDir()) + { + removeAll(&childNode); + } + } + pNode->children.clear(); +} + +QFileInfo GLDFileSystemModelPrivate::resolvedInfo(QFileInfo info) +{ +#ifdef Q_OS_WIN + // On windows, we cannot create a shortcut to a shortcut. + return QFileInfo(info.symLinkTarget()); +#else + QStringList paths; + do { + QFileInfo link(info.symLinkTarget()); + if (link.isRelative()) + info.setFile(info.absolutePath(), link.filePath()); + else + info = link; + if (paths.contains(info.absoluteFilePath())) + return QFileInfo(); + paths.append(info.absoluteFilePath()); + } while (info.isSymLink()); + return info; +#endif +} + +GLDFileSystemModelPrivate::QDirNode *GLDFileSystemModelPrivate::node(const QModelIndex &index) const +{ + GLDFileSystemModelPrivate::QDirNode *pNode = + static_cast(index.internalPointer()); + Q_ASSERT(pNode); + return pNode; +} + +void GLDFileSystemModelPrivate::populate(QDirNode *parent) const +{ + Q_ASSERT(parent); + parent->children = children(parent, parent->stat); + parent->populated = true; +} + +void GLDFileSystemModelPrivate::clear(QDirNode *parent) const +{ + Q_ASSERT(parent); + parent->children.clear(); + parent->populated = false; +} + +void GLDFileSystemModelPrivate::invalidate() +{ + QStack nodes; + nodes.push(&root); + while (!nodes.empty()) + { + const QDirNode *current = nodes.pop(); + current->stat = false; + const QVector c_children = current->children; + for (int i = 0; i < c_children.count(); ++i) + { + nodes.push(&c_children.at(i)); + } + } +} + +#endif // QT_NO_DIRMODEL + +/** + * @class GLDCustomFileSystemModel + * @brief 文件系统模型基类 + */ +GLDCustomFileSystemModel::GLDCustomFileSystemModel(QObject *parent) + : QAbstractItemModel(parent) +{ + +} + +GLDCustomFileSystemModel::GLDCustomFileSystemModel(QAbstractItemModelPrivate &dd, QObject *parent) + : QAbstractItemModel(dd, parent) +{ + +} + +GLDFileSystemModel *GLDCustomFileSystemModel::fileSystemModel() const +{ + return NULL; +} + +bool GLDCustomFileSystemModel::rmdir(const QModelIndex &index) +{ + return false; + G_UNUSED(index) +} + +bool GLDCustomFileSystemModel::remove(const QModelIndex &index) +{ + return false; + G_UNUSED(index) +} + +void GLDCustomFileSystemModel::setViewMode(GLDListView::GLDViewMode viewMode) +{ + m_enViewMode = viewMode; +} + +GLDListView::GLDViewMode GLDCustomFileSystemModel::viewMode() +{ + return m_enViewMode; +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDFilterTableView.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDFilterTableView.cpp new file mode 100644 index 00000000..9406228a --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDFilterTableView.cpp @@ -0,0 +1,386 @@ +#include "GLDFileUtils.h" +#include "GLDFilterTableView.h" +#include "GLDFilterTableView_p.h" +#include "GLDMultiHeaderView.h" +#include "GLDScrollStyle.h" + +#include +#include + +#define CON_NO_RESULT "没有合适的筛选结果" + +GlodonFilterTableView::GlodonFilterTableView(QWidget *parent) + : GlodonTableView(*new GlodonFilterTableViewPrivate(), parent) +{ + d_func()->init(); +} + +void GlodonFilterTableView::setModel(QAbstractItemModel *model) +{ + if (m_bDisplayFilter) + { + filter()->setModel(model); + } + + GlodonTableView::setModel(model); +} + +void GlodonFilterTableView::paintEvent(QPaintEvent *e) +{ + GlodonTableView::paintEvent(e); +} + +void GlodonFilterTableView::setHorizontalHeader(GlodonHeaderView *header) +{ + Q_D(GlodonFilterTableView); + + if (!header || header == d->m_horizontalHeader) + { + return; + } + + GlodonTableView::setHorizontalHeader(header); + d->connectFilterSignal(); +} + +void GlodonFilterTableView::setIsDisplayFilter(bool show) +{ + Q_D(GlodonFilterTableView); + + if ((show == m_bDisplayFilter) || isGroupMode())//过滤行与合计行互斥 + { + return; + } + + m_bDisplayFilter = show; + + if (!d->filter) + { + d->initFilter(); + } + + if (show) + { + // TODO wangdd-a:使用dataModel,在没有SetIsTree的时候,会崩溃 + // 鉴于现在这个功能没人使用,因此先修改为直接设置Model,树形显示可能存在BUG,没有详细测试 + // 后面过滤表格需要重新实现为与Excel一致 + d->filter->setModel(model()); + + for (int nCol = 0; nCol < d->m_horizontalHeader->sectionCount(); ++nCol) + { + d->filter->resizeSection(nCol, 0, d->m_horizontalHeader->sectionSize(nCol)); + } + + d->filter->show(); + } + else + { + d->filter->hide(); + } + + updateGeometries(); +} + +bool GlodonFilterTableView::isDisplayFilter() +{ + return m_bDisplayFilter; +} + +void GlodonFilterTableView::updateGeometries() +{ + Q_D(GlodonFilterTableView); + + if (d->m_geometryRecursionBlock) + { + return; + } + + d->m_geometryRecursionBlock = true; + + bool bFilterHide = isFilterHide(); + int nVerticalHeaderWidth = d->m_verticalHeader->drawWidth(); + int nHorizontalHeaderHeight = d->m_horizontalHeader->drawWidth(); + int nFilterViewHeight = bFilterHide ? 0 : filter()->height(); + + int nAboveGridHeight = nHorizontalHeaderHeight + nFilterViewHeight; + + setViewportMargins(nVerticalHeaderWidth, nAboveGridHeight, 0, 0); + + // update headers + updateVerticalHeaderGeometry(nVerticalHeaderWidth); + updateHorizontalHeaderGeometry(nHorizontalHeaderHeight, nFilterViewHeight); + + // 更新过滤行 + updateFilterViewGeometry(nFilterViewHeight); + + // update cornerWidget + updateConrnerWidgetGeometry(nVerticalHeaderWidth, nAboveGridHeight); + + QSize oViewportSize = d->viewport->size(); + QSize oViewportMaxSize = maximumViewportSize(); + uint nVerticalHeaderLength = d->m_verticalHeader->length(); + uint nHorizontalHeaderLength = d->m_horizontalHeader->length(); + + if ((uint)oViewportMaxSize.width() >= nHorizontalHeaderLength + && (uint)oViewportMaxSize.height() >= nVerticalHeaderLength) + { + oViewportSize = oViewportMaxSize; + } + + updateHorizontalScrollBar(oViewportSize); + updateVerticalScrollBar(oViewportSize); + + d->m_geometryRecursionBlock = false; + GlodonAbstractItemView::updateGeometries(); +} + +void GlodonFilterTableView::setFixedColCount(int fixedColCount) +{ + if (!isFilterHide()) + { + filter()->setFixedCount(fixedColCount); + } + + GlodonTableView::setFixedColCount(fixedColCount); +} + +GFilterView *GlodonFilterTableView::filter() +{ + Q_D(GlodonFilterTableView); + return d->filter; +} + +void GlodonFilterTableView::setGridColor(QColor value) +{ + Q_D(GlodonFilterTableView); + + if (isCustomStyle()) + { + if (d->filter) + { + d->filter->setGridColor(value); + } + + GlodonTableView::setGridColor(value); + } +} + +void GlodonFilterTableView::setGridLineColor(QColor value) +{ + Q_D(GlodonFilterTableView); + + if (isCustomStyle()) + { + if (d->filter) + { + d->filter->setGridLineColor(value); + } + + GlodonTableView::setGridLineColor(value); + } +} + +void GlodonFilterTableView::changeViewItemsForFilter(int column) +{ + Q_UNUSED(column); + Q_D(GlodonFilterTableView); + + for (int row = 0; row < d->m_model->rowCount(); row++) + { + bool bHide = false; + + for (int col = 0; col < d->m_model->columnCount(); col++) + { + QString strFilterData = filter()->filterData(col); + + if (strFilterData == "NULL") + { + continue; + } + + QString strModelData = d->m_model->data(d->m_model->index(row, col)).toString(); + + if (!strModelData.contains(strFilterData)) + { + bHide = true; + break; + } + } + + setRowHidden(row, bHide); + } +} + +GlodonFilterTableView::GlodonFilterTableView(GlodonFilterTableViewPrivate &dd, QWidget *parent) + : GlodonTableView(dd, parent) +{ + d_func()->init(); +} + +void GlodonFilterTableView::timerEvent(QTimerEvent *event) +{ +// Q_D(GlodonFilterTableView); + +// if (event->timerId() == d->m_columnResizeTimerID) +// { +// updateGeometries(); +// killTimer(d->m_columnResizeTimerID); +// d->m_columnResizeTimerID = 0; + +// QRect rect; +// int nviewportHeight = d->viewport->height(); +// int nviewportWidth = d->viewport->width(); + +// if (d->hasSpans()) +// { +// rect = QRect(0, 0, nviewportWidth, nviewportHeight); +// } +// else +// { +// for (int i = d->m_columnsToUpdate.size() - 1; i >= 0; --i) +// { +// int column = d->m_columnsToUpdate.at(i); +// int x = columnViewportPosition(column); + +// if (isRightToLeft()) +// { +// rect |= QRect(0, 0, x + columnWidth(column), nviewportHeight); +// } +// else +// { +// rect |= QRect(x, 0, nviewportWidth - x, nviewportHeight); +// } +// } +// } + +// d->viewport->update(rect.normalized()); + +// if (!isFilterHide()) +// { +// d->filter->viewport()->update(rect.normalized()); +// } + +// d->m_columnsToUpdate.clear(); +// } +// else +// { + return GlodonTableView::timerEvent(event); +// } +} + +void GlodonFilterTableView::resetModel(QAbstractItemModel *dataModel) +{ + if (m_bDisplayFilter) + { + filter()->setModel(dataModel); + } +} + +bool GlodonFilterTableView::isFilterHide() +{ + if (!filter()) + { + return true; + } + else + { + return filter()->isHidden(); + } +} + +void GlodonFilterTableView::updateFilterViewGeometry(int nFilterViewHeight) +{ + Q_D(GlodonFilterTableView); + + QRect oViewportGeometry = d->viewport->geometry(); + + if (!isFilterHide()) + { + int nFilterTop = oViewportGeometry.top() - nFilterViewHeight; + filter()->setGeometry(oViewportGeometry.left(), nFilterTop, oViewportGeometry.width(), nFilterViewHeight); + } +} + +void GlodonFilterTableView::updateHorizontalHeaderGeometry(int nHorizontalHeaderHeight, int nFilterViewHeight) +{ + Q_D(GLDTableView); + + QRect oViewportGeometry = d->viewport->geometry(); + int nHorizontalTop = oViewportGeometry.top() - (nHorizontalHeaderHeight + nFilterViewHeight); + + d->m_horizontalHeader->setGeometry( + oViewportGeometry.left(), nHorizontalTop, + oViewportGeometry.width(), nHorizontalHeaderHeight); + + if (d->m_horizontalHeader->isHidden()) + { + QMetaObject::invokeMethod(d->m_horizontalHeader, "updateGeometries"); + } +} + +void GlodonFilterTableView::resetEllipsisButtonLocation() +{ + Q_D(GlodonFilterTableView); + + if (d->m_showEllipsisButton && NULL != d->m_ellipsisButton) + { + GlodonTableView::resetEllipsisButtonLocation(); + + if (NULL == d->filter) + { + return; + } + + QPoint posWithoutFilter = d->m_ellipsisButton->pos(); + d->m_ellipsisButton->move(posWithoutFilter + QPoint(0, filter()->height())); + } +} + +void GlodonFilterTableView::columnResized(int column, int oldWidth, int newWidth, bool isManual) +{ + if (!isFilterHide()) + { + filter()->resizeSection(column, oldWidth, newWidth); + } + + GlodonTableView::columnResized(column, oldWidth, newWidth, isManual); +} + +GlodonFilterTableViewPrivate::GlodonFilterTableViewPrivate() : filter(NULL) +{ +} + +void GlodonFilterTableViewPrivate::init() +{ + Q_Q(GlodonFilterTableView); + q->m_bDisplayFilter = false; + + q->setProperty("TableView", "GLDTableView"); + q->setStyleSheet(loadQssFile(c_sTableViewQssFile)); + GLDScrollStyle *scrollStyle = new GLDScrollStyle(q, false); + scrollStyle->setIsShowArrow(false); + q->horizontalScrollBar()->setStyle(scrollStyle); + q->verticalScrollBar()->setStyle(scrollStyle); +} + +void GlodonFilterTableViewPrivate::initFilter() +{ + Q_Q(GlodonFilterTableView); + filter = new GFilterView(q); + filter->hide(); + QObject::connect(filter, SIGNAL(onFilterChanged(int)), q, SLOT(changeViewItemsForFilter(int))); + QObject::connect(hbar, SIGNAL(valueChanged(int)), filter, SLOT(hideHiddenSection(int))); + connectFilterSignal(); +} + +void GlodonFilterTableViewPrivate::connectFilterSignal() +{ +// QObject::connect(m_horizontalHeader, SIGNAL(sectionResized(int,int,int)), +// filter, SLOT(resizeSection(int,int,int))); + if (NULL != filter) + { + QObject::connect(m_horizontalHeader, SIGNAL(sectionMoved(int, int, int)), + filter, SLOT(moveSection(int, int, int))); + QObject::connect(m_horizontalHeader, SIGNAL(scrolled(int)), filter, SLOT(setOffset(int))); + } +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDFilterView.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDFilterView.cpp new file mode 100644 index 00000000..bd9aa622 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDFilterView.cpp @@ -0,0 +1,344 @@ +#include "GLDFilterView.h" +#include "GLDFilterView_p.h" + +#include +#include + +GFilterView::GFilterView(QWidget *parent): GlodonHeaderView(Qt::Horizontal, parent), m_bHideFlag(false) +{ +} + +QString GFilterView::filterData(int logicalIndex) +{ + if (QComboBox *comboBox = dynamic_cast(indexWidget(model()->index(0, logicalIndex)))) + { + return comboBox->currentText(); + } + else + { + return "NULL"; + } +} + +void GFilterView::setModel(QAbstractItemModel *model) +{ + m_pFilterDataModel = model; + + int nCount = model->columnCount(); + if (nCount < 0) + return; + + QStandardItemModel *filterModel = new QStandardItemModel(1, nCount, this); + QList items; + for (int i = 0; i < nCount; i++) + { + QStandardItem *item = new QStandardItem(""); + items.append(item); + } + filterModel->appendRow(items); + + setFilterDataModel(filterModel); +} + +void GFilterView::setFilterDataModel(QAbstractItemModel *filterModel) +{ + Q_ASSERT(m_pFilterDataModel->columnCount() == filterModel->columnCount()); + + GlodonHeaderView::setModel(filterModel); + initFilterWidget(); + connect(filterModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), + this, SLOT(filterDataChanged(QModelIndex,QModelIndex))); +} + +QRect GFilterView::visualRect(const QModelIndex &index) const +{ + Q_D(const GFilterView); + int nLeft = sectionViewportPosition(index.column()); + return QRect(nLeft, 0, sectionSize(index.column()), d->viewport->height()); +} + +void GFilterView::paintEvent(QPaintEvent * e) +{ + GlodonHeaderView::paintEvent(e); +} + +int GFilterView::height() const +{ + if (isHidden()) + { + return 0; + } + return qMax(drawWidth(), 20); +} + +void GFilterView::resizeSection(int logicalIndex, int oldSize, int size) +{ + Q_UNUSED(oldSize); + Q_D(GFilterView); + int nOffset = size - oldSize; + //no need to resize + if (0 == nOffset) + return; + bool beginUseOffset = false; + for (int i = 0; i < d->m_model->columnCount(); i++) + { + if (i == logicalIndex) + { + beginUseOffset = true; + } + + if (QComboBox *comboBox = dynamic_cast(indexWidget(model()->index(0, i)))) + { + QRect rect = visualRect(d->m_model->index(0, i)); + //calculate the new rect from logicalIndex column + QRect rectOffset = beginUseOffset? + ( (i == logicalIndex) ? + QRect(rect.left(), 0, rect.width() + nOffset, rect.height()) : + QRect(rect.left() + nOffset,0,rect.width(), rect.height())) : + rect; + comboBox->setGeometry(rectOffset); + } + } + GlodonHeaderView::resizeSection(logicalIndex, size); +} + +void GFilterView::moveSection(int logicalIndex, int from, int to) +{ + Q_UNUSED(logicalIndex); + GlodonHeaderView::moveSection(from, to); +} + +void GFilterView::filterChanged() +{ + Q_D(GFilterView); + QObject *obj = QObject::sender(); + if (QWidget *widget = dynamic_cast(obj)) + { + QModelIndex index = d->indexForEditor(widget); + emit onFilterChanged(index.column()); + } +} + +void GFilterView::hideHiddenSection(int hbarPos) +{ + Q_UNUSED(hbarPos); + m_bHideFlag = true; + this->viewport()->update(); +} + +void GFilterView::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const +{ + Q_D(const GFilterView); + QStyleOptionHeader opt; + initStyleOption(&opt); + QStyle::State state = QStyle::State_None; + + if (isEnabled()) + { + state |= QStyle::State_Enabled; + } + if (window()->isActiveWindow()) + { + state |= QStyle::State_Active; + } + + QVariant textAlignment = d->m_model->data(d->m_model->index(0, logicalIndex), Qt::TextAlignmentRole); + + opt.rect = rect; + opt.section = logicalIndex; + opt.state |= state; + opt.textAlignment = Qt::Alignment(textAlignment.isValid() + ? Qt::Alignment(textAlignment.toInt()) + : d->defaultAlignment); + + opt.iconAlignment = Qt::AlignVCenter; + opt.text = d->m_model->data(d->m_model->index(0, logicalIndex), Qt::DisplayRole).toString(); + + if (d->m_textElideMode != Qt::ElideNone) + { + opt.text = opt.fontMetrics.elidedText(opt.text, d->m_textElideMode , rect.width() - 4); + } + + QVariant variant = d->m_model->data(d->m_model->index(0, logicalIndex), Qt::DecorationRole); + + opt.icon = qvariant_cast(variant); + if (opt.icon.isNull()) + { + opt.icon = qvariant_cast(variant); + } + + QVariant foregroundBrush = d->m_model->data(d->m_model->index(0, logicalIndex), Qt::ForegroundRole); + + if (foregroundBrush.canConvert()) + { + opt.palette.setBrush(QPalette::ButtonText, qvariant_cast(foregroundBrush)); + } + + QPointF oldBO = painter->brushOrigin(); + QVariant backgroundBrush = d->m_model->data(d->m_model->index(0, logicalIndex), Qt::BackgroundRole); + + if (backgroundBrush.canConvert()) + { + opt.palette.setBrush(QPalette::Button, qvariant_cast(backgroundBrush)); + opt.palette.setBrush(QPalette::Window, qvariant_cast(backgroundBrush)); + painter->setBrushOrigin(opt.rect.topLeft()); + } + + int nVisual = visualIndex(logicalIndex); + Q_ASSERT(nVisual != -1); + if (count() == 1) + { + opt.position = QStyleOptionHeader::OnlyOneSection; + } + else if (nVisual == 0) + { + opt.position = QStyleOptionHeader::Beginning; + } + else if (nVisual == count() - 1) + { + opt.position = QStyleOptionHeader::End; + } + else + { + opt.position = QStyleOptionHeader::Middle; + } + opt.orientation = d->orientation; + + style()->drawControl(QStyle::CE_Header, &opt, painter, this); + painter->setBrushOrigin(oldBO); + + + if (QWidget *widget = indexWidget(d->m_model->index(0, logicalIndex))) + { + int nFixedWidth = 0; + if (d->fixedCount > 0) + { + if (d->orientation == Qt::Horizontal) + { + for (int i = 0; i < d->fixedCount; i++) + { + nFixedWidth += sectionSize(i); + } + } + } + QRect rect = visualRect(d->m_model->index(0, logicalIndex)); + if ((QStyleFactory::keys().contains(qApp->style()->objectName(), Qt::CaseInsensitive))) + rect.adjust(0, -1, 0, 0); + rect.adjust(-1, -1, 0, 0); + if (d->fixedCount > 0) + { + if (rect.right() - 2 > nFixedWidth && rect.left() < nFixedWidth - 2) + { + if (logicalIndex >= d->fixedCount) + rect.setLeft(nFixedWidth); + } + else if (logicalIndex < d->fixedCount && rect.right() < nFixedWidth + 4) + { + rect = widget->geometry(); + } + } +// QRect indexRect = this->visualRect(d->indexForEditor(widget)); +// int indexWidth = indexRect.width(); 未使用变量indexWidth + widget->setGeometry(rect); + // widget->setGeometry(visualRect(d->model->index(0, logicalIndex))); + if (d->fixedCount > 0 && logicalIndex >= d->fixedCount && widget->geometry().right() <= nFixedWidth + 4) + widget->hide(); + else + widget->show(); + } + +// if (QWidget *widget = indexWidget(d->model->index(0, logicalIndex))) +// { +// QRect rect = visualRect(d->model->index(0, logicalIndex)); +// if ((QStyleFactory::keys().contains(qApp->style()->objectName(), Qt::CaseInsensitive))) +// rect.adjust(0, -1, 0, 0); +// rect.adjust(-1, -1, 0, 0); +// widget->setGeometry(rect); +//// widget->setGeometry(visualRect(d->model->index(0, logicalIndex))); +// widget->show(); + // } +} + +void GFilterView::paintSection(int beginToHideIndex) const +{ + Q_D(const GFilterView); + + if (m_bHideFlag) + { + m_bHideFlag = false; + + for (int i = beginToHideIndex; i < d->sectionCount(); ++i) + { + if (QWidget *widget = indexWidget(d->m_model->index(0, i))) + { + widget->hide(); + } + } + } +} + +void GFilterView::keyPressEvent(QKeyEvent *event) +{ + event->accept(); +} + +void GFilterView::filterDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) +{ + for (int i = topLeft.column(); i <= bottomRight.column(); i++) + { + resetFilter(i); + } +} + +void GFilterView::initFilterWidget() +{ + Q_D(GFilterView); + for (int col = 0; col < d->m_model->columnCount(); col++) + { + QComboBox *comboBox = new QComboBox(d->viewport); + QStringList list; + list.append("NULL"); + for (int row = 0; row < m_pFilterDataModel->rowCount(); row++) + { + QModelIndex index = m_pFilterDataModel->index(row, col); + if (index.isValid()) + { + QString strValue = index.data().toString(); + if (!list.contains(strValue)) + { + list.append(strValue); + } + } + } + comboBox->addItems(list); + comboBox->setEditable(true); + comboBox->setGeometry(visualRect(d->m_model->index(0, col))); + connect(comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(filterChanged())); + setIndexWidget(d->m_model->index(0, col), comboBox); + } +} + +void GFilterView::resetFilter(int col) +{ + Q_D(GFilterView); + QComboBox *comboBox = new QComboBox(d->viewport); + QStringList list; + list.append("NULL"); + for (int row = 0; row < m_pFilterDataModel->rowCount(); row++) + { + QModelIndex index = m_pFilterDataModel->index(row, col); + if (index.isValid()) + { + QString strValue = index.data().toString(); + if (!list.contains(strValue)) + { + list.append(strValue); + } + } + } + comboBox->addItems(list); + comboBox->setEditable(true); + comboBox->setGeometry(visualRect(d->m_model->index(0, col))); + connect(comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(filterChanged())); + setIndexWidget(d->m_model->index(0, col), comboBox); +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDFilterWidget.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDFilterWidget.cpp new file mode 100644 index 00000000..ab26e21d --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDFilterWidget.cpp @@ -0,0 +1,259 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "GLDFilterWidget.h" + +GLDHintLineEdit::GLDHintLineEdit(QWidget *parent) + : QLineEdit(parent), m_eDefaultFocusPolicy(focusPolicy()), m_bRefuseFocus(false) +{ +} + +bool GLDHintLineEdit::refuseFocus() const +{ + return m_bRefuseFocus; +} + +void GLDHintLineEdit::setRefuseFocus(bool v) +{ + if (v == m_bRefuseFocus) + { + return; + } + + m_bRefuseFocus = v; + setFocusPolicy(m_bRefuseFocus ? Qt::NoFocus : m_eDefaultFocusPolicy); +} + +void GLDHintLineEdit::mousePressEvent(QMouseEvent *event) +{ + // Explicitly focus on click. + + if (m_bRefuseFocus && !hasFocus()) + { + setFocus(Qt::OtherFocusReason); + } + QLineEdit::mousePressEvent(event); +} + +void GLDHintLineEdit::focusInEvent(QFocusEvent *e) +{ + if (m_bRefuseFocus) + { + // Refuse the focus if the mouse it outside. In addition to the mouse + // press logic, this prevents a re-focussing which occurs once + // we actually had focus + const Qt::FocusReason eReason = e->reason(); + if ((eReason == Qt::ActiveWindowFocusReason) || (eReason == Qt::PopupFocusReason)) + { + const QPoint oMousePos = mapFromGlobal(QCursor::pos()); + const bool bRefuse = !geometry().contains(oMousePos); + if (bRefuse) + { + e->ignore(); + return; + } + } + } + + QLineEdit::focusInEvent(e); +} + + +GLDIconButton::GLDIconButton(QWidget *parent) + : QToolButton(parent), m_fFader(1.0f) +{ + setCursor(Qt::ArrowCursor); +} + +float GLDIconButton::fader() +{ + return m_fFader; +} + +void GLDIconButton::setFader(float value) +{ + m_fFader = value; + update(); +} + +void GLDIconButton::animateShow(bool visible) +{ + if (visible) + { + QPropertyAnimation *pAnimation = new QPropertyAnimation(this, "fader"); + pAnimation->setDuration(160); + pAnimation->setEndValue(1.0); + pAnimation->start(QAbstractAnimation::DeleteWhenStopped); + } + else + { + QPropertyAnimation *pAnimation = new QPropertyAnimation(this, "fader"); + pAnimation->setDuration(160); + pAnimation->setEndValue(0.0); + pAnimation->start(QAbstractAnimation::DeleteWhenStopped); + } +} + +void GLDIconButton::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event); + QPainter oPainter(this); + // Note isDown should really use the active state but in most styles + // this has no proper feedback + QIcon::Mode eState = QIcon::Disabled; + if (isEnabled()) + { + eState = isDown() ? QIcon::Selected : QIcon::Normal; + } + QPixmap oIconpixmap = icon().pixmap( + QSize(ICONBUTTON_SIZE, ICONBUTTON_SIZE), eState, QIcon::Off); + QRect oPixmapRect = QRect(0, 0, oIconpixmap.width(), oIconpixmap.height()); + oPixmapRect.moveCenter(rect().center()); + oPainter.setOpacity(m_fFader); + oPainter.drawPixmap(oPixmapRect, oIconpixmap); +} + + +GLDFilterWidget::GLDFilterWidget( + QWidget *parent, GLDFilterWidget::GLDLayoutMode mode) + : QWidget(parent), + m_pLedtEditor(new GLDHintLineEdit(this)), + m_pBtnIcon(new GLDIconButton(m_pLedtEditor)), + m_nButtonWidth(0), + m_autoResize(false) +{ + QIcon value(":/icons/FilterWidget_ClearText.png"); + init(mode, value); +} + +GLDFilterWidget::GLDFilterWidget(QIcon icon, QWidget *parent, GLDFilterWidget::GLDLayoutMode mode) + : QWidget(parent), + m_pLedtEditor(new GLDHintLineEdit(this)), + m_pBtnIcon(new GLDIconButton(m_pLedtEditor)), + m_nButtonWidth(0), + m_autoResize(false) +{ + init(mode, icon); +} + +GString GLDFilterWidget::text() const +{ + return m_pLedtEditor->text(); +} + +void GLDFilterWidget::setText(const GString str) +{ + m_pLedtEditor->setText(str); +} + +void GLDFilterWidget::resizeEvent(QResizeEvent *event) +{ + if (m_autoResize) + { + m_pLedtEditor->resize(event->size()); + m_pLedtEditor->move(0,0); + } + + QRect oContentRect = m_pLedtEditor->rect(); + + if (layoutDirection() == Qt::LeftToRight) + { + const int nIconoffset = m_pLedtEditor->textMargins().right() + 4; + m_pBtnIcon->setGeometry(oContentRect.adjusted(m_pLedtEditor->width() - nIconoffset, 0, 0, 0)); + } + else + { + const int oIconoffset = m_pLedtEditor->textMargins().left() + 4; + m_pBtnIcon->setGeometry(oContentRect.adjusted(0, 0, -m_pLedtEditor->width() + oIconoffset, 0)); + } +} + +bool GLDFilterWidget::refuseFocus() const +{ + return m_pLedtEditor->refuseFocus(); +} + +void GLDFilterWidget::setRefuseFocus(bool v) +{ + m_pLedtEditor->setRefuseFocus(v); +} + +void GLDFilterWidget::setAutoResize(bool autoResize) +{ + m_autoResize = autoResize; +} + +void GLDFilterWidget::setInputPlaceholderText(const GString &text) +{ + m_inputPlaceholderText = text; + m_pLedtEditor->setPlaceholderText(tr(m_inputPlaceholderText.toStdString().c_str())); +} + +void GLDFilterWidget::reset() +{ + if (!m_pLedtEditor->text().isEmpty()) + { + // Editor has lost focus once this is pressed + m_pLedtEditor->clear(); + emit filterChanged(GString()); + } +} + +void GLDFilterWidget::checkButton(const GString &text) +{ + if (m_sOldText.isEmpty() || text.isEmpty()) + { + m_pBtnIcon->animateShow(!m_pLedtEditor->text().isEmpty()); + } + m_sOldText = text; +} + +void GLDFilterWidget::init(GLDLayoutMode mode, QIcon value) +{ + m_pLedtEditor->setPlaceholderText(tr(m_inputPlaceholderText.toStdString().c_str())); + + // Let the style determine minimum height for our widget + QSize oSize(ICONBUTTON_SIZE + 6, ICONBUTTON_SIZE + 2); + + // Note KDE does not reserve space for the highlight color + if (style()->inherits("OxygenStyle")) + { + oSize = oSize.expandedTo(QSize(24, 0)); + } + + // Make room for clear icon + QMargins oMargins = m_pLedtEditor->textMargins(); + if (layoutDirection() == Qt::LeftToRight) + { + oMargins.setRight(oSize.width()); + } + else + { + oMargins.setLeft(oSize.width()); + } + + m_pLedtEditor->setTextMargins(oMargins); + + QHBoxLayout *pHblFilter = new QHBoxLayout(this); + pHblFilter->setMargin(0); + pHblFilter->setSpacing(0); + if (mode == lmAlignRight) + { + pHblFilter->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum)); + } + + pHblFilter->addWidget(m_pLedtEditor); + + m_pBtnIcon->setIcon(value); + // Clear text=清空 + m_pBtnIcon->setToolTip(tr("Clear text")); + connect(m_pBtnIcon, &GLDIconButton::clicked, this, &GLDFilterWidget::reset); + connect(m_pLedtEditor, &GLDHintLineEdit::textChanged, this, &GLDFilterWidget::checkButton); + connect(m_pLedtEditor, &GLDHintLineEdit::textEdited, this, &GLDFilterWidget::filterChanged); +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDFontList.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDFontList.cpp new file mode 100644 index 00000000..a1824b3f --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDFontList.cpp @@ -0,0 +1,171 @@ +#include "GLDFontList.h" +#include +#include +#include +#include +#include + +GFontList::GFontList(QWidget *parent) : QFontComboBox(parent), + m_bFirstPopup(0) +{ + setItemDelegate(new GlodonFontFamilyDelegate(this)); +} + +GFontList::~GFontList() +{ + +} + +void GFontList::showPopup() +{ + QFontComboBox::showPopup(); + if (view() && view()->parentWidget()) + { + QRect rect = this->view()->parentWidget()->geometry(); + int ncomboBoxEditorWidth = this->geometry().width(); + QFrame* popupViewContainer = dynamic_cast(view()->parentWidget()); + if (popupViewContainer) + { + if (0 == m_bFirstPopup) + { + m_bFirstPopup = 1; + if (popupViewContainer->minimumWidth() > ncomboBoxEditorWidth) + { + popupViewContainer->setMinimumWidth(ncomboBoxEditorWidth); + } + + this->view()->resize(ncomboBoxEditorWidth, rect.height()); + this->view()->update(); + popupViewContainer->resize(ncomboBoxEditorWidth, rect.height()); + GFontList::showPopup(); + } + } + } + if (m_bFirstPopup > 0) + { + m_bFirstPopup = 0; + } +} + +static QFontDatabase::WritingSystem writingSystemForFont(const QFont &font, bool *hasLatin) +{ + QList writingSystems = QFontDatabase().writingSystems(font.family()); + + // this just confuses the algorithm below. Vietnamese is Latin with lots of special chars + writingSystems.removeOne(QFontDatabase::Vietnamese); + *hasLatin = writingSystems.removeOne(QFontDatabase::Latin); + + if (writingSystems.isEmpty()) + return QFontDatabase::Any; + + QFontDatabase::WritingSystem system = writingSystems.last(); + + if (!*hasLatin) { + // we need to show something + return system; + } + + if (writingSystems.count() == 1 && system > QFontDatabase::Cyrillic) + return system; + + if (writingSystems.count() <= 2 && system > QFontDatabase::Armenian && system < QFontDatabase::Vietnamese) + return system; + + if (writingSystems.count() <= 5 && system >= QFontDatabase::SimplifiedChinese && system <= QFontDatabase::Korean) + return system; + + return QFontDatabase::Any; +} + +GlodonFontFamilyDelegate::GlodonFontFamilyDelegate(QObject *parent) + : QAbstractItemDelegate(parent) +{ + truetype = QIcon(QLatin1String(":/qt-project.org/styles/commonstyle/images/fonttruetype-16.png")); + bitmap = QIcon(QLatin1String(":/qt-project.org/styles/commonstyle/images/fontbitmap-16.png")); + writingSystem = QFontDatabase::SimplifiedChinese; +} + +void GlodonFontFamilyDelegate::paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + QString text = index.data(Qt::DisplayRole).toString(); + QFont font(option.font); + font.setPointSize(10/*QFontInfo(font).pointSize() * 3 / 2*/); + QFont font2 = font; + font2.setFamily(text); + + bool hasLatin; + QFontDatabase::WritingSystem system = writingSystemForFont(font2, &hasLatin); + if (hasLatin) + font = font2; + + QRect r = option.rect; + + if (option.state & QStyle::State_Selected) { + painter->save(); + painter->setBrush(option.palette.highlight()); + painter->setPen(Qt::NoPen); + painter->drawRect(option.rect); + painter->setPen(QPen(option.palette.highlightedText(), 0)); + painter->restore(); + } + + const QIcon *icon = &bitmap; + if (QFontDatabase().isSmoothlyScalable(text)) { + icon = &truetype; + } + QSize actualSize = icon->actualSize(r.size()); + + icon->paint(painter, r, Qt::AlignLeft|Qt::AlignVCenter); + if (option.direction == Qt::RightToLeft) + r.setRight(r.right() - actualSize.width() - 4); + else + r.setLeft(r.left() + actualSize.width() + 4); + + QFont old = painter->font(); + painter->setFont(font); + + // If the ascent of the font is larger than the height of the rect, + // we will clip the text, so it's better to align the tight bounding rect in this case + // This is specifically for fonts where the ascent is very large compared to + // the descent, like certain of the Stix family. + QFontMetricsF fontMetrics(font); + if (fontMetrics.ascent() > r.height()) { + QRectF tbr = fontMetrics.tightBoundingRect(text); + painter->drawText(r.x(), r.y() + (r.height() + tbr.height()) / 2.0, text); + } else { + painter->drawText(r, Qt::AlignVCenter|Qt::AlignLeading|Qt::TextSingleLine, text); + } + + if (writingSystem != QFontDatabase::Any) + system = writingSystem; + +// if (system != QFontDatabase::Any) { +// int w = painter->fontMetrics().width(text + QLatin1String(" ")); +// painter->setFont(font2); +// QString sample = QFontDatabase().writingSystemSample(system); +// if (option.direction == Qt::RightToLeft) +// r.setRight(r.right() - w); +// else +// r.setLeft(r.left() + w); +// painter->drawText(r, Qt::AlignVCenter|Qt::AlignLeading|Qt::TextSingleLine, sample); +// } + painter->setFont(old); + + if (option.state & QStyle::State_Selected) + painter->restore(); + +} + +QSize GlodonFontFamilyDelegate::sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + QString text = index.data(Qt::DisplayRole).toString(); + QFont font(option.font); +// font.setFamily(text); + font.setPointSize(QFontInfo(font).pointSize() * 3/2); + QFontMetrics fontMetrics(font); + return QSize(fontMetrics.width(text), fontMetrics.height()); +} + diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDFontListEx.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDFontListEx.cpp new file mode 100644 index 00000000..83ecb148 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDFontListEx.cpp @@ -0,0 +1,325 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "GLDShadow.h" +#include "GLDStrings.h" +#include "GLDFileUtils.h" +#include "GLDFontListEx.h" +#include "GLDScrollStyle.h" + +const int c_PointSize = 10; +const int c_itemHeight = 25; +const int c_nListViewMinWidth = 350; + +const int c_highLightLeftPadding = 8; // 高亮选择的左内边距 +const int c_highLightRightPadding = 9; // 高亮选择的右内边距 +const int c_spaceWidth = 5; // 每个显示元素间的距离 +const int c_contentLeftPadding = 12; // 内容区域距离高亮区域的左内边距 +const int c_contentRightPadding = 10; // 内容区域距离高亮区域的内边距 +const int c_checkMarkLeftPadding = 2; // 对号离高亮选择的左边距 + +const QString c_sFontListQssFile = ":/qsses/GLDFontListEx.qss"; + +GFontListEx::GFontListEx(QWidget *parent) : + QFontComboBox(parent), + m_highLightBackgroundColor(QColor(219, 243, 252)), + m_highLightTextColor(QColor(0, 0, 0)) +{ + setObjectName("GLDFontListEx"); + setHasBorder(true); + this->setStyleSheet(loadQssFile(c_sFontListQssFile)); + setStyle(new GLDScrollStyle(this)); + + // 移除阴影 + GLDShadow *pShadow = new GLDShadow(this); + pShadow->removeShadow(); + + m_pFontDelegate = new GLDFontListDelegate(this); + setItemDelegate(m_pFontDelegate); + + connect(this, SIGNAL(currentTextChanged(QString)), SLOT(showFontFamily(QString))); +} + +GFontListEx::~GFontListEx() +{ +} + +void GFontListEx::showPopup() +{ + if (lineEdit() != NULL) + { + lineEdit()->selectAll(); + lineEdit()->setFocus(); + } + + if (QFrame* popupViewContainer = dynamic_cast(view()->parentWidget())) + { + setHighLighColor(m_highLightBackgroundColor, m_highLightTextColor); + QRect parentRect = view()->parentWidget()->geometry(); + popupViewContainer->setMinimumWidth(c_nListViewMinWidth); + popupViewContainer->resize(c_nListViewMinWidth, parentRect.height()); + view()->resize(c_nListViewMinWidth, parentRect.height()); + } + QFontComboBox::showPopup(); +} + +void GFontListEx::setHightBackground(QColor color) +{ + m_highLightBackgroundColor = color; +} + +void GFontListEx::setHightText(QColor color) +{ + m_highLightTextColor = color; +} + +void GFontListEx::setFontListItemDelegate(GLDFontListDelegate *delegate) +{ + m_pFontDelegate = delegate; + QFontComboBox::setItemDelegate(delegate); +} + +void GFontListEx::setHasBorder(bool bHasBorder) +{ + if (bHasBorder) + { + setProperty("GFontListEx", "hasborder"); + } + else + { + setProperty("GFontListEx", "noborder"); + } + + this->setStyleSheet(loadQssFile(c_sFontListQssFile)); +} + +void GFontListEx::showFontFamily(QString family) +{ + m_pFontDelegate->setSelectedFamily(family); // tbd +} + +void GFontListEx::setHighLighColor( QColor background, QColor text) +{ + QPalette palette = view()->palette(); + palette.setColor(QPalette::Highlight, background); + palette.setColor(QPalette::HighlightedText, text); + view()->setPalette(palette); +} + +GLDFontListDelegate::GLDFontListDelegate(QObject *parent): + QAbstractItemDelegate(parent), + m_sTTypeIconPath(QLatin1String(":/icons/GLDFontListEx-true_type.png")), + m_sBMapIconPath(QLatin1String(":/qt-project.org/styles/commonstyle/images/fontbitmap-16.png")), + m_trueTypeIcon(m_sTTypeIconPath), + m_sCMarkIconPath(QLatin1String(":/icons/GLDFontListEx-check_mark.png")), + m_bitmapIcon(m_sBMapIconPath), + m_checkMark(m_sCMarkIconPath), + m_sEnglishCaption(getGLDi18nStr(g_rsFontEffect)), + m_sZhCaption(getGLDi18nStr(g_rsEffect)), + m_sDefaultFont(getGLDi18nStr(g_rsSimsun)), + m_sSelectedFamily(m_sDefaultFont), + m_bShowCheckMark(true) +{ +} + +bool isZh(QString str) +{ + bool bZh = str.contains(QRegExp("[\\x4e00-\\x9fa5]+")); // 正则表达式判读是否包含中文 + return bZh; +} + +void GLDFontListDelegate::paintFontTypeImage(QRect &rect, QString fontFamilyName, + QPainter *painter, const QStyleOptionViewItem &option) const +{ + const QIcon *oIcon = &m_bitmapIcon; + if (QFontDatabase().isSmoothlyScalable(fontFamilyName)) + { + oIcon = &m_trueTypeIcon; + } + QSize actualSize = oIcon->actualSize(rect.size()); + if (m_bShowCheckMark && fontFamilyName == selectedFamily()) + { + rect.setLeft(rect.left() + c_contentLeftPadding); // 调整画板的左 + } + else + { + rect.setLeft(rect.left() + c_contentLeftPadding); // 调整画板的左 + } + + rect.setRight(rect.right() - c_contentRightPadding); // 调整画板的右 + oIcon->paint(painter, rect, Qt::AlignLeft | Qt::AlignVCenter); // 为字体加上标识 + if (option.direction == Qt::RightToLeft) + { + rect.setRight(rect.right() - actualSize.width()); + } + else + { + rect.setLeft(rect.left() + actualSize.width()); + } +} + +void GLDFontListDelegate::paintCheckStatusIcon(QRect &rect, QPainter *painter) const +{ + const QIcon *pIcon = &m_checkMark; + rect.setLeft(rect.left() + c_checkMarkLeftPadding); + pIcon->paint(painter, rect, Qt::AlignLeft | Qt::AlignVCenter); +} + +void GLDFontListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + // 得到需要画的区域:选中图标 + 字体族图标 + 字体名 + 效果 + QRect drawRect = option.rect; + drawRect.setLeft(drawRect.left() + c_highLightLeftPadding); + drawRect.setRight(drawRect.right() - c_highLightRightPadding); + + // 设置painter + if (option.state & QStyle::State_Selected) + { + painter->save(); + painter->setBrush(option.palette.highlight()); + painter->setPen(Qt::NoPen); + painter->drawRect(drawRect); + painter->setPen(QPen(option.palette.highlightedText(), 0)); + painter->restore(); + } + + QString sCurFamily = selectedFamily(); + QString sFontFamilyName = index.data(Qt::DisplayRole).toString(); + // 画被选中的字体前面的对号图标 + if ((m_bShowCheckMark) && (sCurFamily == sFontFamilyName)) + { + paintCheckStatusIcon(drawRect, painter); // 画选中字体前面的小图标(尚未实现) + } + // 根据组类型,画字体族的图标 + if (m_bShowTypeImageFlag) + { + paintFontTypeImage(drawRect, sFontFamilyName, painter, option); + } + + QFont curFont(option.font); + curFont.setPointSize(c_PointSize); + curFont.setFamily(m_sDefaultFont); + + QFontMetricsF fontMetrics(curFont); + QRectF curFontRect = fontMetrics.tightBoundingRect(sFontFamilyName); + + // 画字体的family名 + drawRect.setLeft(drawRect.left() + 2 * c_spaceWidth); + painter->setFont(curFont); + painter->drawText(drawRect.left(), + drawRect.y() + (drawRect.height() + curFontRect.height()) / 2.0, + sFontFamilyName); + + // 画字体的显示效果 + QString sEffectTxt; + if (isZh(sFontFamilyName)) + { + sEffectTxt = m_sEnglishCaption; + } + else + { + sEffectTxt = m_sZhCaption; + } + + QFont curFontStyle = curFont; + curFontStyle.setFamily(sFontFamilyName); + QFontMetricsF styledFontMetrics(curFontStyle); + QRectF styledFontRect = styledFontMetrics.tightBoundingRect(sEffectTxt); + + int nTextWidth = styledFontRect.width(); + drawRect.setRight(drawRect.right() - c_spaceWidth); + painter->setFont(curFontStyle); + painter->drawText(drawRect.right() - nTextWidth, + drawRect.y() + (drawRect.height() + styledFontRect.height()) / 2.0, + sEffectTxt ); + + // 如果没有被选中,则复位样式 + if (option.state & QStyle::State_Selected) + { + painter->restore(); + } +} + +QSize GLDFontListDelegate::sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + QString sFontFamily = index.data(Qt::DisplayRole).toString(); + QFont font(option.font); + font.setPointSize(QFontInfo(font).pointSize() * 3 / 2); + QFontMetrics fontMetrics(font); + + return QSize(fontMetrics.width(sFontFamily), c_itemHeight); +} + +void GLDFontListDelegate::setTTypeIconPath(const QString &path) +{ + m_sTTypeIconPath = path; +} + +void GLDFontListDelegate::setBMapIconPath(const QString &path) +{ + m_sBMapIconPath = path; +} + +void GLDFontListDelegate::setCMarkIconPath(const QString &path) +{ + m_sCMarkIconPath = path; +} + +bool GLDFontListDelegate::isShowCheckMark() +{ + return m_bShowCheckMark; +} + +void GLDFontListDelegate::setIsShowCheckMark(bool isShow) +{ + m_bShowCheckMark = isShow; +} + +bool GLDFontListDelegate::isShowFontTypeImage() +{ + return m_bShowTypeImageFlag; +} + +void GLDFontListDelegate::setIsShowFontTypeImage(bool isShow) +{ + m_bShowTypeImageFlag = isShow; +} + +void GLDFontListDelegate::setEnglishCaption(const QString &caption) +{ + m_sEnglishCaption = caption; +} + +void GLDFontListDelegate::setZhCaption(const QString &caption) +{ + m_sZhCaption = caption; +} + +QString GLDFontListDelegate::defaultFont() +{ + return m_sDefaultFont; +} + +void GLDFontListDelegate::setDefaultFont(QString family) +{ + m_sDefaultFont = family; +} + +QString GLDFontListDelegate::selectedFamily() const +{ + return m_sSelectedFamily; +} + +void GLDFontListDelegate::setSelectedFamily(const QString &family) +{ + m_sSelectedFamily = family; +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDFooterTableView.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDFooterTableView.cpp new file mode 100644 index 00000000..f057a555 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDFooterTableView.cpp @@ -0,0 +1,360 @@ +#include "GLDFileUtils.h" +#include "GLDFooterTableView.h" +#include "GLDFooterTableView_p.h" +#include "GLDMultiHeaderView.h" +#include "GLDScrollStyle.h" +#include "GLDTreeModel.h" + +#include +#include +#include + +GlodonFooterTableView::GlodonFooterTableView(QWidget *parent) + : GlodonFilterTableView(*new GlodonFooterTableViewPrivate(), parent) +{ + d_func()->init(); +} + +void GlodonFooterTableView::setHorizontalHeader(GlodonHeaderView *header) +{ + Q_D(GlodonFooterTableView); + + if (!header || header == d->m_horizontalHeader) + { + return; + } + + GlodonFilterTableView::setHorizontalHeader(header); + + d->connectFooterSignal(); +} + +void GlodonFooterTableView::setModel(QAbstractItemModel *model) +{ + Q_D(GlodonFooterTableView); + d->m_dataModel = model; + + if (d->totalRowAtFooter) + { + createModel(); + resetModel(); + } + else + { + GlodonFilterTableView::setModel(model); + } + + changeVerticalHeaderDrawWidth(); +} + +bool GlodonFooterTableView::totalRowAtFooter() const +{ + Q_D(const GlodonFooterTableView); + return d->totalRowAtFooter; +} + +void GlodonFooterTableView::setTotalRowAtFooter(bool value) +{ + Q_D(GlodonFooterTableView); + + if ((d->totalRowAtFooter != value) && (!isGroupMode())) + { + d->totalRowAtFooter = value; + + if (value) + connect(d->footer, SIGNAL(currentIndexChanged(const QModelIndex &)), + this, SLOT(setCurrentIndexForFooter(const QModelIndex &))); + else + disconnect(d->footer, SIGNAL(currentIndexChanged(const QModelIndex &)), + this, SLOT(setCurrentIndexForFooter(const QModelIndex &))); + } +} + +void GlodonFooterTableView::setTotalRowCount(int value) +{ + Q_D(GlodonFooterTableView); + + if (d->footerRowCount != value) + { + d->footerRowCount = value; + createModel(); + resetModel(); + } +} + +void GlodonFooterTableView::paintEvent(QPaintEvent *e) +{ + GlodonFilterTableView::paintEvent(e); +} + +void GlodonFooterTableView::setGridColor(QColor value) +{ + Q_D(GlodonFooterTableView); + + if (isCustomStyle()) + { + if (d->footer) + { + d->footer->setIsCustomStyle(true); + d->footer->setGridColor(value); + } + + GlodonFilterTableView::setGridColor(value); + } +} + +void GlodonFooterTableView::setGridLineColor(QColor value) +{ + Q_D(GlodonFooterTableView); + + if (isCustomStyle()) + { + if (d->footer) + { + d->footer->setIsCustomStyle(true); + d->footer->setGridLineColor(value); + } + + GlodonFilterTableView::setGridLineColor(value); + } +} + +void GlodonFooterTableView::setFixedColCount(int fixedColCount) +{ + footer()->setFixedColCount(fixedColCount); + GlodonFilterTableView::setFixedColCount(fixedColCount); +} + +GFooterView *GlodonFooterTableView::footer() +{ + return d_func()->footer; +} + +void GlodonFooterTableView::beforeReset() +{ + Q_D(GlodonFooterTableView); + + // 将resetSectionSpan方法从GSPTableView中提到FooterTableView中进行设置 + // 解决删除树节点时,界面显示问题(sectionSpan) + if (NULL != d->m_verticalHeader) + { + d->m_verticalHeader->resetSectionItems(); + } + + GlodonFilterTableView::beforeReset(); +} + +void GlodonFooterTableView::doReset() +{ + Q_D(GlodonFooterTableView); + + if (NULL != d->m_dataModel) + { + GlodonFilterTableView::resetModel(d->m_dataModel); + changeVerticalHeaderDrawWidth(); + } + + GlodonFilterTableView::doReset(); +} + +void GlodonFooterTableView::afterReset() +{ + GlodonFilterTableView::afterReset(); +} + +GlodonFooterTableView::GlodonFooterTableView(GlodonFooterTableViewPrivate &dd, QWidget *parent) + : GlodonFilterTableView(dd, parent) +{ + d_func()->init(); +} + +void GlodonFooterTableView::createModel() +{ + Q_D(GlodonFooterTableView); + freeAndNil(d->footerModel); + freeAndNil(d->footBodyModel); + // footBodyModel和footerModel的创建顺序会影响modelReset等槽的调用顺序 + // footBodyModel应该在footerModel之前调用modelReset对应的槽, treeModel + // 中的缓存才会先更新 + d->footBodyModel = new GlodonFooterBodyModel(d->m_dataModel, this); + d->footBodyModel->setFooterRowCount(d->footerRowCount); + d->footerModel = new GlodonFooterModel(d->m_dataModel, this); + d->footerModel->setFooterRowCount(d->footerRowCount); +} + +void GlodonFooterTableView::updateFooterGeometry(int nVerticalHeaderWidth) +{ + Q_D(GlodonFooterTableView); + + QRect oViewportGeometry = d->viewport->geometry(); + int nFooterHeight = footer()->height(); + int nVerticalLeft = oViewportGeometry.left() - nVerticalHeaderWidth; + int nHorzScrollbarHeight = horizontalScrollBar()->isVisibleTo(this) ? horizontalScrollBar()->height() : 0; + int nFooterTop = rect().bottom() - nFooterHeight - nHorzScrollbarHeight; + + footer()->setGeometry( + nVerticalLeft, nFooterTop, + oViewportGeometry.width() + nVerticalHeaderWidth, nFooterHeight); +} + +void GlodonFooterTableView::resetModel() +{ + Q_D(GlodonFooterTableView); + setFooterModel(d->footerModel); + //重新绑定 + d->footer->horizontalHeader()->reset(); + d->footer->verticalHeader()->reset(); + GlodonFilterTableView::setModel(d->footBodyModel); +} + +void GlodonFooterTableView::changeVerticalHeaderDrawWidth() +{ + Q_D(GlodonFooterTableView); + d->footer->setVerticalHeaderDrawWidth(d->m_verticalHeader->sizeHint().width()); + updateGeometries(); +} + +void GlodonFooterTableView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) +{ + Q_D(GlodonFooterTableView); + GlodonTableView::currentChanged(current, previous); + + if (d->totalRowAtFooter && d->footerRowCount != 0) + { + d->footer->resetCurrentIndex(current); + } +} + +void GlodonFooterTableView::columnResized(int column, int oldWidth, int newWidth, bool isManual) +{ + footer()->resizeSection(column, oldWidth, newWidth); + GlodonFilterTableView::columnResized(column, oldWidth, newWidth, isManual); +} + +void GlodonFooterTableView::setCurrentIndex(const QModelIndex &dataIndex) +{ + Q_D(GlodonFooterTableView); + + if (totalRowAtFooter()) + { + GlodonTableView::setCurrentIndex(d->footBodyModel->index(dataIndex)); + } + else + { + GlodonTableView::setCurrentIndex(dataIndex); + } +} + +void GlodonFooterTableView::setCurrentIndexForFooter(const QModelIndex &footIndex) +{ + QModelIndex current = currentIndex(); + + if (footIndex.column() != current.column()) + { + QAbstractItemModel *curModel = model(); + GlodonTreeModel *treeModel = dynamic_cast(curModel); + QModelIndex newIndex = curModel->index(current.row(), footIndex.column(), current.parent()); + + if (treeModel) + { + newIndex = treeModel->dataIndex(newIndex); + } + + setCurrentIndex(newIndex); + } +} + +void GlodonFooterTableView::updateGeometries() +{ + Q_D(GlodonFooterTableView); + + if (d->m_geometryRecursionBlock) + { + return; + } + + bool bFilterHide = isFilterHide(); + + if (verticalHeader()->isHidden()) + { + d->footer->verticalHeader()->hide(); + d->footer->verticalHeader()->setDrawWidth(0); + } + + d->m_geometryRecursionBlock = true; + + int nVerticalHeaderWidth = d->m_verticalHeader->drawWidth(); + int nHorizontalHeaderHeight = d->m_horizontalHeader->drawWidth(); + int nFilterViewHeight = bFilterHide ? 0 : filter()->height(); + int nAboveGridHeight = nHorizontalHeaderHeight + nFilterViewHeight; + + int nFooterHeight = footer()->height(); + + setViewportMargins(nVerticalHeaderWidth, nAboveGridHeight, 0, qMax(0, nFooterHeight - frameWidth())); + + // update headers + updateVerticalHeaderGeometry(nVerticalHeaderWidth); + updateHorizontalHeaderGeometry(nHorizontalHeaderHeight, nFilterViewHeight); + + // 更新过滤行 + updateFilterViewGeometry(nFilterViewHeight); + + // update cornerWidget + updateConrnerWidgetGeometry(nVerticalHeaderWidth, nAboveGridHeight); + + // 更新合计行 + updateFooterGeometry(nVerticalHeaderWidth); + + QSize oViewportSize = d->viewport->size(); + QSize oViewportMaxSize = maximumViewportSize(); + uint nHorizontalHeaderLength = d->m_horizontalHeader->length(); + uint nVerticalHeaderLength = d->m_verticalHeader->length(); + + if ((uint)oViewportMaxSize.width() >= nHorizontalHeaderLength + && (uint)oViewportMaxSize.height() >= nVerticalHeaderLength) + { + oViewportSize = oViewportMaxSize; + } + + updateHorizontalScrollBar(oViewportSize); + updateVerticalScrollBar(oViewportSize); + + d->m_geometryRecursionBlock = false; + GlodonAbstractItemView::updateGeometries(); +} + +void GlodonFooterTableView::setFooterModel(QAbstractItemModel *model) +{ + footer()->setModel(model); + changeVerticalHeaderDrawWidth(); +} + +void GlodonFooterTableViewPrivate::init() +{ + Q_Q(GlodonFooterTableView); + footer = new GFooterView(q); + connectFooterSignal(); + q->changeVerticalHeaderDrawWidth(); + footer->setItemDelegate(new GFooterViewDelegate(q)); + + q->setProperty("TableView", "GLDTableView"); + q->setStyleSheet(loadQssFile(c_sTableViewQssFile)); + GLDScrollStyle *scrollStyle = new GLDScrollStyle(q, false); + scrollStyle->setIsShowArrow(false); + q->horizontalScrollBar()->setStyle(scrollStyle); + q->verticalScrollBar()->setStyle(scrollStyle); +} + +void GlodonFooterTableViewPrivate::connectFooterSignal() +{ +// QObject::connect(horizontalHeader, SIGNAL(sectionResized(int,int,int)), +// footer, SLOT(resizeSection(int,int,int))); + QObject::connect(m_horizontalHeader, SIGNAL(sectionMoved(int, int, int)), + footer, SLOT(moveSection(int, int, int))); + QObject::connect(m_horizontalHeader, SIGNAL(scrolled(int)), + footer, SLOT(setOffset(int))); + QObject::connect(footer->horizontalHeader(), SIGNAL(scrolled(int)), + m_horizontalHeader, SLOT(setOffset(int))); + QObject::connect(footer->verticalHeader(), SIGNAL(drawWidthChanged(int)), + m_verticalHeader, SLOT(setDrawWidth(int))); +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDFooterView.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDFooterView.cpp new file mode 100644 index 00000000..cd28116f --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDFooterView.cpp @@ -0,0 +1,94 @@ +#include "GLDFooterView.h" +#include "GLDFooterView_p.h" +#include "GLDTreeModel.h" +#include + +GFooterView::GFooterView(QWidget *parent) : GlodonTableView(*new GFooterViewPrivate, parent) +{ + horizontalHeader()->hide(); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setFrameStyle(NoFrame); +} + +void GFooterView::setModel(QAbstractItemModel *model) +{ + GlodonTableView::setModel(model); +} + +int GFooterView::height() const +{ + Q_D(const GFooterView); + int nHeight = 0; + for (int i = 0; i < d->m_model->rowCount(); i++) + { + nHeight += d->m_verticalHeader->sectionSize(i); + } + return nHeight; +} + +void GFooterView::paintEvent(QPaintEvent *e) +{ + GlodonTableView::paintEvent(e); +} + +void GFooterView::resizeSection(int logicalIndex, int oldSize, int size) +{ + Q_UNUSED(oldSize); + Q_D(GFooterView); + d->m_horizontalHeader->resizeSection(logicalIndex, size); + d->viewport->update(); +} + +void GFooterView::moveSection(int logicalIndex, int from, int to) +{ + Q_UNUSED(logicalIndex); + Q_D(GFooterView); + d->m_horizontalHeader->moveSection(from, to); + d->viewport->update(); +} + +void GFooterView::setOffset(int offset) +{ + Q_D(GFooterView); + d->m_horizontalHeader->setOffset(offset); + d->viewport->update(); +} + +void GFooterView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) +{ + Q_UNUSED(previous) + emit currentIndexChanged(current); +} + +void GFooterView::resetCurrentIndex(const QModelIndex ¤t) +{ + if (current.column() != currentIndex().column()) + { + int row = qMax(0, currentIndex().row()); + QAbstractItemModel *curModel = model(); + GlodonTreeModel *treeModel = dynamic_cast(curModel); + QModelIndex newIndex = curModel->index(row, current.column()); + if (treeModel) + newIndex = treeModel->dataIndex(row, current.column()); + setCurrentIndex(newIndex); + update(newIndex); + } +} + +void GFooterView::setVerticalHeaderDrawWidth( int width ) +{ + Q_D(GFooterView); + d->m_verticalHeader->setDrawWidth(width); + updateGeometries(); +} + +GFooterViewDelegate::GFooterViewDelegate(QObject *parent) : GlodonDefaultItemDelegate(parent) +{ +} + +GEditStyle GFooterViewDelegate::editStyle(const QModelIndex &index, bool &readOnly) const +{ + return esNone; + Q_UNUSED(index); + Q_UNUSED(readOnly); +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDGroupHeaderView.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDGroupHeaderView.cpp new file mode 100644 index 00000000..d3745903 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDGroupHeaderView.cpp @@ -0,0 +1,505 @@ +#include "GLDGroupHeaderView.h" +#include "GLDGroupHeaderView_p.h" + +#include + +GlodonGroupHeaderView::GlodonGroupHeaderView(QWidget *parent) : GlodonHeaderView(Qt::Horizontal, parent) +{ + cgFrame = new GlodonColumnGroupFrame(this); + connect(cgFrame, SIGNAL(cgFrameChanged(int, bool)), this, SLOT(cgFrameChanged(int, bool))); + connect(cgFrame, SIGNAL(groupChanged()), this, SLOT(onGroupChanged())); + cgFrame->setVisible(true); + setAcceptDrops(true); + sectionLabel = 0; + updateGeometries(); +} + +int GlodonGroupHeaderView::drawWidth() const +{ + return cgFrame->frameHeight() + GlodonHeaderView::drawWidth(); +} + +void GlodonGroupHeaderView::setModel(QAbstractItemModel *model) +{ + GlodonHeaderView::setModel(model); + updateGeometries(); +} + +void GlodonGroupHeaderView::mousePressEvent(QMouseEvent *e) +{ + Q_D(GlodonGroupHeaderView); + + if (d->m_state != GlodonHeaderViewPrivate::NoState || e->button() != Qt::LeftButton) + { + return; + } + + int npos = e->x(); + int nhandle = -1; + + if (e->pos().y() > 0) + { + nhandle = d->sectionHandleAt(npos); + d->originalSize = -1; + + if (nhandle == -1) + { + d->pressed = logicalIndexAt(npos); + + if (d->clickableSections) + { + emit sectionPressed(d->pressed); + } + + d->section = d->target = d->pressed; + + if (d->section == -1) + { + return; + } + + d->m_state = GlodonHeaderViewPrivate::CXMoveSection; + setupSectionLabel(d->section); + } + else if (resizeMode(nhandle) == Interactive) + { + d->originalSize = sectionSize(nhandle); + d->m_state = GlodonHeaderViewPrivate::ResizeSection; + d->section = nhandle; + } + + d->firstPos = npos; + d->lastPos = npos; + + d->clearCascadingSections(); + } +} + +void GlodonGroupHeaderView::mouseMoveEvent(QMouseEvent *e) +{ + Q_D(GlodonGroupHeaderView); + + int npos = e->x(); + + if (npos < 0) + { + return; + } + + if (e->buttons() == Qt::NoButton) + { + d->m_state = GlodonHeaderViewPrivate::NoState; + d->pressed = -1; + } + + switch (d->m_state) + { + case GlodonHeaderViewPrivate::NoState: + { +#ifndef QT_NO_CURSOR + int nhandle = -1; + + if (e->pos().y() > 0) + { + nhandle = d->sectionHandleAt(npos); + } + + bool bhasCursor = testAttribute(Qt::WA_SetCursor); + + if (nhandle != -1 && (resizeMode(nhandle) == Interactive)) + { + if (!bhasCursor) + { + setCursor(Qt::SplitHCursor); + } + } + else if (bhasCursor) + { + unsetCursor(); + } + +#endif + return; + } + + default: + break; + } + + GlodonHeaderView::mouseMoveEvent(e); +} + +void GlodonGroupHeaderView::mouseReleaseEvent(QMouseEvent *e) +{ + Q_D(GlodonGroupHeaderView); + + if (d->m_state == GlodonHeaderViewPrivate::CXMoveSection) + { + d->m_state = GlodonHeaderViewPrivate::NoState; + } + else + { + GlodonHeaderView::mouseReleaseEvent(e); + } +} + +void GlodonGroupHeaderView::dragEnterEvent(QDragEnterEvent *dee) +{ + if (/*GColumnGroupLabel *label = */dynamic_cast(dee->source())) + { + dee->acceptProposedAction(); + } +} + +void GlodonGroupHeaderView::dragMoveEvent(QDragMoveEvent *dme) +{ + if (/*GColumnGroupLabel *label = */dynamic_cast(dme->source())) + { + dme->acceptProposedAction(); + } +} + +void GlodonGroupHeaderView::dropEvent(QDropEvent *de) +{ + Q_D(GlodonGroupHeaderView); + + if (GColumnGroupLabel *label = dynamic_cast(de->source())) + { + if (de->pos().y() > 0) + { + label->draggedLeaveFrame(); + } + } + + if (d->m_state == GlodonHeaderViewPrivate::CXMoveSection) + { + d->m_state = GlodonHeaderViewPrivate::NoState; + } +} + +void GlodonGroupHeaderView::setupSectionLabel(int section) +{ + Q_D(GlodonGroupHeaderView); + + if (sectionLabel == NULL) + { + sectionLabel = new GColumnGroupLabel(section, d->m_model->headerData(section, Qt::Horizontal).toString(), this); + } + else + { + sectionLabel->column = section; + sectionLabel->setText(d->m_model->headerData(section, Qt::Horizontal).toString()); + } + + QDrag *drag = new QDrag(sectionLabel); + QMimeData *data = new QMimeData(); + data->setText(sectionLabel->text()); + drag->setMimeData(data); + + QPixmap pix(sectionLabel->width(), sectionLabel->height()); + pix.fill(QColor(0, 0, 0, 45)); + QRect rect(0, 0, sectionLabel->width(), sectionLabel->height()); + + QPainter painter(&pix); + painter.setOpacity(0.75); + painter.drawText(rect, sectionLabel->text(), QTextOption(Qt::AlignHCenter)); + painter.end(); + + drag->setPixmap(pix); + + drag->exec(); +} + +QVector GlodonGroupHeaderView::currentGroups() +{ + QVector result; + + for (int i = 0; i < cgFrame->labels.count(); i++) + { + result << cgFrame->labels[i]->column; + } + + return result; +} + +void GlodonGroupHeaderView::updateGeometries() +{ + Q_D(GlodonGroupHeaderView); + setViewportMargins(0, cgFrame->frameHeight(), 0, 0); + cgFrame->setGeometry(0, 0, d->viewport->width(), cgFrame->frameHeight()); + repaint(); +} + +void GlodonGroupHeaderView::cgFrameChanged(int col, bool dragIn) +{ + if (dragIn) + { + showSection(col); + } + else + { + hideSection(col); + } + + updateGeometries(); + emit cgFrameChanged(); +} + +void GlodonGroupHeaderView::onGroupChanged() +{ + emit groupChanged(currentGroups()); +} + +GlodonColumnGroupFrame::GlodonColumnGroupFrame(QWidget *parent) : + QFrame(parent) +{ + setAcceptDrops(true); + moveStart = -1; + movePos = -1; +} + +void GlodonColumnGroupFrame::paintEvent(QPaintEvent *e) +{ + QPainter painter(this); + painter.fillRect(rect(), Qt::gray); + + for (int i = 0; i < labels.count(); i++) + { + QRect rect = labelRect(i); + labels[i]->setGeometry(rect); + drawBranch(i, rect); + } + + QFrame::paintEvent(e); +} + +void GlodonColumnGroupFrame::dragEnterEvent(QDragEnterEvent *dee) +{ + if (GColumnGroupLabel *label = dynamic_cast(dee->source())) + { + dee->acceptProposedAction(); + moveStart = labels.indexOf(label); + } +} + +void GlodonColumnGroupFrame::dropEvent(QDropEvent *de) +{ + if (GColumnGroupLabel *label = dynamic_cast(de->source())) + { + movePos = moveTarget(de->pos()); + moveStart = labels.indexOf(label); + + if (moveStart != -1) + { + labels[moveStart]->setStyleSheet("GColumnGroupLabel {background:rgb(255, 255, 255); color:rgb(0, 0, 0)}"); + + if (movePos != moveStart) + { + labels.move(moveStart, movePos); + } + else + { + moveStart = -1; + movePos = -1; + repaint(); + return; + } + } + else + { + GColumnGroupLabel *newLabel = new GColumnGroupLabel(label->column, label->text(), this); + connect(newLabel, SIGNAL(leaveFrame()), this, SLOT(onLabelDragOut())); + labels.append(newLabel); + newLabel->setVisible(true); + labels.move(labels.count() - 1, movePos); + emit cgFrameChanged(label->column, false); + } + + setGeometry(pos().x(), pos().y(), width(), frameHeight()); + emit groupChanged(); + moveStart = -1; + movePos = -1; + repaint(); + } +} + +void GlodonColumnGroupFrame::dragMoveEvent(QDragMoveEvent *dme) +{ + if (dynamic_cast(dme->source())) + { + dme->acceptProposedAction(); + int nold = movePos; + movePos = moveTarget(dme->pos()); + + if (nold != movePos) + { + if (nold >= moveStart) + { + update(branchRect(nold)); + } + else + { + update(branchRect(nold - 1)); + } + + if (movePos >= moveStart) + { + update(branchRect(movePos)); + } + else + { + update(branchRect(movePos - 1)); + } + } + } +} + +void GlodonColumnGroupFrame::dragLeaveEvent(QDragLeaveEvent *) +{ + if (moveStart >= 0) + { + labels[moveStart]->setStyleSheet("GColumnGroupLabel {background:rgb(0, 0, 0); color:rgb(255, 255, 255)}"); + } +} + +int GlodonColumnGroupFrame::frameHeight() const +{ + return qMax(35, (labels.count() + 1) * 11 + 24); +} + +void GlodonColumnGroupFrame::onLabelDragOut() +{ + GColumnGroupLabel *label = dynamic_cast(sender()); + label->setVisible(false); + labels.removeOne(label); + emit cgFrameChanged(label->column, true); + emit groupChanged(); + moveStart = -1; + movePos = -1; + repaint(); +} + +QRect GlodonColumnGroupFrame::labelRect(int level) +{ + if (level > labels.count() - 1 || level < 0) + { + return QRect(); + } + + int nleft = 12; + + for (int i = 0; i < level; i++) + { + nleft += labels[i]->width() + 5; + } + + int ntop = 12; + + for (int i = 0; i < level; i++) + { + ntop += 11; + } + + return QRect(nleft, ntop, labels[level]->width(), labels[level]->height()); +} + +void GlodonColumnGroupFrame::drawBranch(int level, QRect labelRect) +{ + if (level >= labels.count() - 1 || level < 0) + { + return; + } + + QPainter painter(this); + QPen old = painter.pen(); + int nleft = labelRect.right() - 5; + + if ((movePos >= moveStart && level == movePos) || (movePos < moveStart && level == movePos - 1)) + { + painter.setPen(Qt::green); + painter.drawLine(nleft, labelRect.bottom(), nleft, labelRect.bottom() + 4); + painter.drawLine(nleft, labelRect.bottom() + 4, nleft + 10, labelRect.bottom() + 4); + painter.setPen(old); + } + else + { + painter.drawLine(nleft, labelRect.bottom(), nleft, labelRect.bottom() + 4); + painter.drawLine(nleft, labelRect.bottom() + 4, nleft + 10, labelRect.bottom() + 4); + } +} + +int GlodonColumnGroupFrame::moveTarget(QPoint pos) +{ + for (int i = 0; i < labels.count(); i++) + { + if (pos.x() <= labels[i]->pos().x()) + { + if (i <= moveStart || moveStart == -1) + { + return i; + } + else + { + return i - 1; + } + } + } + + if (moveStart == -1) + { + return labels.count(); + } + else + { + return labels.count() - 1; + } +} + +QRect GlodonColumnGroupFrame::branchRect(int level) +{ + if (level < 0 || level >= labels.count() - 1) + { + return QRect(); + } + + QRect rect = labelRect(level); + return QRect(rect.right() - 6, rect.bottom() - 1, rect.width() + 2, rect.height() + 2); +} + +GColumnGroupLabel::GColumnGroupLabel(int col, QString text, QWidget *parent) : + QLabel(parent) +{ + setStyleSheet("GColumnGroupLabel {background:rgb(255, 255, 255)}"); + setFrameShape(Panel); + setText(text); + adjustSize(); + column = col; + setFixedSize(qMax(width(), 60), 22); +} + +void GColumnGroupLabel::mousePressEvent(QMouseEvent *e) +{ + QDrag *drag = new QDrag(this); + QMimeData *data = new QMimeData(); + data->setText(text()); + drag->setMimeData(data); + + QPixmap pix(width(), height()); + pix.fill(QColor(0, 0, 0, 45)); + QRect rect(0, 0, width(), height()); + + QPainter painter(&pix); + painter.setOpacity(0.75); + painter.drawText(rect, text(), QTextOption(Qt::AlignHCenter)); + painter.end(); + + drag->setPixmap(pix); + drag->setHotSpot(QPoint(e->pos())); + + drag->exec(Qt::MoveAction); +} + +void GColumnGroupLabel::draggedLeaveFrame() +{ + emit leaveFrame(); +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDHeaderView.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDHeaderView.cpp new file mode 100644 index 00000000..d1d3e2b3 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDHeaderView.cpp @@ -0,0 +1,4932 @@ +#include "GLDHeaderView.h" +#include "GLDHeaderView_p.h" + +#include "GLDTableView.h" +#include "GLDAbstractItemModel.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "GLDFilterTableView.h" +#include "GLDMultiHeaderView.h" + +#ifndef QT_NO_DATASTREAM +#include +#endif + +#ifndef QT_NO_DATASTREAM + +//排序列表头的小三角与文字的间距 +const int c_nSpacingTextToArrow = 10; +//排序列表头的小三角的size +const QSize c_sortArrow(7, 4); + +QDataStream &operator<<(QDataStream &out, const GlodonHeaderViewPrivate::SectionItem §ion) +{ + section.write(out); + return out; +} + +QDataStream &operator>>(QDataStream &in, GlodonHeaderViewPrivate::SectionItem §ion) +{ + section.read(in); + return in; +} + +#endif // QT_NO_DATASTREAM + +static const int maxSizeSection = 1048575; // since section size is in a bitfield (uint 20). + +GlodonHeaderView::GlodonHeaderView(Qt::Orientation orientation, QWidget *parent) + : GlodonAbstractItemView(*new GlodonHeaderViewPrivate, parent), + m_isSortArrowOnTextTop(false) +{ + Q_D(GlodonHeaderView); + d->setDefaultValues(orientation); + initialize(); + setAttribute(Qt::WA_Hover); +} + +GlodonHeaderView::GlodonHeaderView(GlodonHeaderViewPrivate &dd, + Qt::Orientation orientation, QWidget *parent) + : GlodonAbstractItemView(dd, parent) +{ + Q_D(GlodonHeaderView); + d->setDefaultValues(orientation); + initialize(); +} + +GlodonHeaderView::~GlodonHeaderView() +{ +} + +void GlodonHeaderView::initialize() +{ + Q_D(GlodonHeaderView); + + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setFrameStyle(NoFrame); + setFocusPolicy(Qt::NoFocus); + + d->viewport->setMouseTracking(true); + d->m_textElideMode = Qt::ElideNone; + + delete d->m_itemDelegate; +} + +void GlodonHeaderView::setModel(QAbstractItemModel *model) +{ + if (model == this->model()) + { + return; + } + + Q_D(GlodonHeaderView); + + if (d->m_model && d->m_model != QAbstractItemModelPrivate::staticEmptyModel()) + { + if (d->orientation == Qt::Horizontal) + { + QObject::disconnect(d->m_model, SIGNAL(columnsInserted(QModelIndex, int, int)), + this, SLOT(sectionsInserted(QModelIndex, int, int))); + QObject::disconnect(d->m_model, SIGNAL(columnsAboutToBeRemoved(QModelIndex, int, int)), + this, SLOT(sectionsAboutToBeRemoved(QModelIndex, int, int))); + QObject::disconnect(d->m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)), + this, SLOT(_q_sectionsRemoved(QModelIndex, int, int))); + } + else + { + QObject::disconnect(d->m_model, SIGNAL(rowsInserted(QModelIndex, int, int)), + this, SLOT(sectionsInserted(QModelIndex, int, int))); + QObject::disconnect(d->m_model, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)), + this, SLOT(sectionsAboutToBeRemoved(QModelIndex, int, int))); + QObject::disconnect(d->m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), + this, SLOT(_q_sectionsRemoved(QModelIndex, int, int))); + } + + QObject::disconnect(d->m_model, SIGNAL(headerDataChanged(Qt::Orientation, int, int)), + this, SLOT(headerDataChanged(Qt::Orientation, int, int))); + QObject::disconnect(d->m_model, SIGNAL(layoutAboutToBeChanged()), + this, SLOT(_q_layoutAboutToBeChanged())); + } + + if (model && model != QAbstractItemModelPrivate::staticEmptyModel()) + { + if (d->orientation == Qt::Horizontal) + { + QObject::connect(model, SIGNAL(columnsInserted(QModelIndex, int, int)), + this, SLOT(sectionsInserted(QModelIndex, int, int))); + QObject::connect(model, SIGNAL(columnsAboutToBeRemoved(QModelIndex, int, int)), + this, SLOT(sectionsAboutToBeRemoved(QModelIndex, int, int))); + QObject::connect(model, SIGNAL(columnsRemoved(QModelIndex, int, int)), + this, SLOT(_q_sectionsRemoved(QModelIndex, int, int))); + } + else + { + QObject::connect(model, SIGNAL(rowsInserted(QModelIndex, int, int)), + this, SLOT(sectionsInserted(QModelIndex, int, int))); + QObject::connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)), + this, SLOT(sectionsAboutToBeRemoved(QModelIndex, int, int))); + QObject::connect(model, SIGNAL(rowsRemoved(QModelIndex, int, int)), + this, SLOT(_q_sectionsRemoved(QModelIndex, int, int))); + } + + QObject::connect(model, SIGNAL(headerDataChanged(Qt::Orientation, int, int)), + this, SLOT(headerDataChanged(Qt::Orientation, int, int))); + QObject::connect(model, SIGNAL(layoutAboutToBeChanged()), + this, SLOT(_q_layoutAboutToBeChanged())); + } + + d->m_state = GlodonHeaderViewPrivate::NoClear; + GlodonAbstractItemView::setModel(model); + d->m_state = GlodonHeaderViewPrivate::NoState; + + const int nLogicalIndicesCount = d->logicalIndices.count(); + for (int i = 0; i < nLogicalIndicesCount; ++i) + { + d->logicalIndices[i] = i; + } + + const int nVisualIndicesCount = d->visualIndices.count(); + for (int i = 0; i < nVisualIndicesCount; ++i) + { + d->visualIndices[i] = i; + } + + // Users want to set sizes and modes before the widget is shown. + // Thus, we have to initialize when the model is set, + // and not lazily like we do in the other views. + initializeSections(); +} + +Qt::Orientation GlodonHeaderView::orientation() const +{ + Q_D(const GlodonHeaderView); + return d->orientation; +} + +int GlodonHeaderView::offset() const +{ + Q_D(const GlodonHeaderView); + return d->offset; +} + +void GlodonHeaderView::setOffset(int newOffset) +{ + Q_D(GlodonHeaderView); + + if (d->offset == (int)newOffset) + { + return; + } + + int ndelta = d->offset - newOffset; + d->offset = newOffset; + + if (d->orientation == Qt::Horizontal) + { + if (fixedCount() > 0) + { + QRect rect = d->viewportScrollArea(); + d->viewport->scroll(isRightToLeft() ? -ndelta : ndelta, 0, rect); + } + else + { + d->viewport->scroll(isRightToLeft() ? -ndelta : ndelta, 0); + } + } + else + { + if (fixedCount() > 0) + { + QRect rect = d->viewportScrollArea(); + d->viewport->scroll(0, ndelta, rect); + } + else + { + d->viewport->scroll(0, ndelta); + } + } + + if (d->m_state == GlodonHeaderViewPrivate::ResizeSection && !d->preventCursorChangeInSetOffset) + { + QPoint cursorPos = QCursor::pos(); + + if (d->orientation == Qt::Horizontal) + { + QCursor::setPos(cursorPos.x() + ndelta, cursorPos.y()); + } + else + { + QCursor::setPos(cursorPos.x(), cursorPos.y() + ndelta); + } + + d->firstPos += ndelta; + d->lastPos += ndelta; + } + + d->viewport->update(); + + emit scrolled(newOffset); +} + +void GlodonHeaderView::setOffsetToSectionPosition(int visualSectionNumber) +{ + Q_D(GlodonHeaderView); + + if (visualSectionNumber > -1 && visualSectionNumber < d->sectionCount()) + { + int nAdjustedVisualIndex = d->adjustedVisualIndex(visualSectionNumber); + int nPosition = 0; + + if (d->fixedCount < 1) + { + nPosition = d->headerSectionPosition(nAdjustedVisualIndex); + } + else + { + // 有固定行列存在时每次移动固定行列后面的格子大小 + nPosition = d->headerSectionPosition(nAdjustedVisualIndex + d->fixedCount); + nPosition -= d->headerSectionPosition(d->fixedCount); + } + + if (nPosition < 0) + { + return; + } + + setOffset(nPosition); + } +} + +void GlodonHeaderView::setOffsetToLastSection() +{ + Q_D(const GlodonHeaderView); + int nsize = (d->orientation == Qt::Horizontal ? viewport()->width() : viewport()->height()); + int nposition = length() - nsize; + setOffset(nposition); +} + +int GlodonHeaderView::length() const +{ + Q_D(const GlodonHeaderView); + d->executePostedLayout(); + return d->length; +} + +int GlodonHeaderView::drawWidth() const +{ + Q_D(const GlodonHeaderView); + int ndrawWidth = 0; + + if (isAllSectionHidden()) + { + return 0; + } + + if (!isHidden()) + { + if (d->orientation == Qt::Horizontal) + { + ndrawWidth = qMax(minimumHeight(), sizeHint().height()); + ndrawWidth = qMin(ndrawWidth, maximumHeight()); + } + else + { + ndrawWidth = qMax(minimumWidth(), sizeHint().width()); + ndrawWidth = qMin(ndrawWidth, maximumWidth()); + } + } + + return qMax(ndrawWidth, d->drawWidth); +} + +int GlodonHeaderView::sectionCount() const +{ + Q_D(const GlodonHeaderView); + return d->sectionCount(); +} + +QSize GlodonHeaderView::sizeHint() const +{ + Q_D(const GlodonHeaderView); + + if (d->cachedSizeHint.isValid()) + { + return d->cachedSizeHint; + } + + d->cachedSizeHint = QSize(0, 0); //reinitialize the cached size hint + const int c_sectionCount = count(); + + // get size hint for the first n sections + int nIndex = 0; + + for (int i = 0; i < 100 && nIndex < c_sectionCount; ++nIndex) + { + if (isSectionHidden(nIndex)) + { + continue; + } + else + { + // 为了提高计算SizeHint的效率,只计算第一个和后十个非隐藏section的值 + i++; + QSize hint = sectionSizeFromContents(nIndex); + d->cachedSizeHint = d->cachedSizeHint.expandedTo(hint); + break; + } + } + + // get size hint for the last n sections + nIndex = qMax(nIndex, c_sectionCount - 100); + int nchecked = 0; +// int nCalcCount = 0; + + for (int j = c_sectionCount - 1; j >= nIndex && nchecked < 100; --j) + { + if (isSectionHidden(j)) + { + continue; + } + else + { + nchecked++; + + QString oHeaderText; + + if (d->autoSectionData) + { + oHeaderText = QString::number(j + 1); + } + else + { + oHeaderText = d->m_model->headerData(j, d->orientation, + Qt::DisplayRole).toString(); + } + + if (oHeaderText.isEmpty()) + { + continue; + } + + QSize hint = sectionSizeFromContents(j); + d->cachedSizeHint = d->cachedSizeHint.expandedTo(hint); + +// if (nCalcCount++ >= 10) +// { +// break; +// } + } + } + + return d->cachedSizeHint; +} + +void GlodonHeaderView::setVisible(bool v) +{ + bool actualChange = (v != isVisible()); + + GlodonAbstractItemView::setVisible(v); + + if (actualChange) + { + QAbstractScrollArea *parent = qobject_cast(parentWidget()); + + if (parent) + { + parent->updateGeometry(); + } + } +} + +int GlodonHeaderView::sectionSizeHint(int logicalIndex) const +{ + Q_D(const GlodonHeaderView); + + if (isSectionHidden(logicalIndex)) + { + return 0; + } + + if (isInValidLogicalIndex(logicalIndex)) + { + return -1; + } + + QSize size; + QVariant value = d->m_model->headerData(logicalIndex, d->orientation, Qt::SizeHintRole); + + if (value.isValid()) + { + if (d->autoSectionData) + { + d->m_model->setHeaderData(logicalIndex, d->orientation, logicalIndex + 1); + } + else + { + size = qvariant_cast(value); + } + } + else + { + size = sectionSizeFromContents(logicalIndex); + } + + int nhint = d->orientation == Qt::Horizontal ? size.width() : size.height(); + return qMax(minimumSectionSize(), nhint); +} + +int GlodonHeaderView::visualIndexAt(int position) const +{ + Q_D(const GlodonHeaderView); + + d->executePostedLayout(); + + const int count = sectionCount(); + + if (count < 1) + { + return -1; + } + + // TODO: refactoring fixed column by separating method + for (int i = 0, nvposition = position; i < d->fixedCount; i++) + { + if (!isSectionHidden(i)) + { + nvposition = nvposition - sectionSize(i) - d->gridLineWidth; + } + + if (nvposition <= 0) + { + return i; + } + } + + if (d->reverse()) + { + position = d->viewport->width() - position; + } + + position += d->offset; + + // TODO: refactoring mouse moving state check by separating method + GlodonAbstractItemView *pParent = dynamic_cast(parentWidget()); + + if (pParent && pParent->dragSelectingState()) + { + if (position > d->length) + { + return count - 1; + } + else if (position < 0) + { + return 0; + } + } + + if (position > d->length) + { + return -1; + } + + int nVisual = d->headerVisualIndexAt(position); + + if (nVisual < 0) + { + return -1; + } + + while (d->isVisualIndexHidden(nVisual)) + { + ++nVisual; + + if (nVisual >= count) + { + return -1; + } + } + + return nVisual; +} + +int GlodonHeaderView::logicalIndexAt(int position) const +{ + const int c_visual = visualIndexAt(position); + + if (c_visual > -1) + { + return logicalIndex(c_visual); + } + + return -1; +} + + + +int GlodonHeaderView::sectionSize(int logicalIndex) const +{ + if (isSectionHidden(logicalIndex)) + { + return 0; + } + + if (isInValidLogicalIndex(logicalIndex)) + { + return 0; + } + + int nVisualIndex = visualIndex(logicalIndex); +// if (visual == -1) +// return 0; +// d->executePostedResize(); +// if (GlodonAbstractItemModel *model = dynamic_cast(d->model)) +// { +// int size = -1; +// if (d->orientation == Qt::Horizontal) +// { +// QModelIndex index = model->index(0, logicalIndex); +// size = model->data(index, gidrColWidthRole).toInt(); +// } +// else +// { +// QModelIndex index = model->index(logicalIndex, 0); +// size = model->data(index, gidrRowHeightRole).toInt(); +// } +// } +// return d->headerSectionSize(visual); + return visualSectionSize(nVisualIndex); +} + +int GlodonHeaderView::visualSectionSize(int visualIndex) const +{ + Q_D(const GlodonHeaderView); + + if (visualIndex == -1) + { + return 0; + } + + return d->headerSectionSize(visualIndex); +} + +int GlodonHeaderView::sectionPosition(int logicalIndex) const +{ + int nVisualIndex = visualIndex(logicalIndex); + return sectionVisualPosition(nVisualIndex); +// // in some cases users may change the selections +// // before we have a chance to do the layout +// if (visual == -1) +// return -1; +// d->executePostedResize(); +// return d->headerSectionPosition(visual); +} + +int GlodonHeaderView::sectionViewportPosition(int logicalIndex) const +{ + Q_D(const GlodonHeaderView); + + if (logicalIndex >= count()) + { + return -1; + } + + int nposition = sectionPosition(logicalIndex); + + if (nposition < 0) + { + return nposition; // the section was hidden + } + + int noffsetPosition; + + if (logicalIndex < d->fixedCount) + { + noffsetPosition = nposition; + } + else + { + noffsetPosition = nposition - d->offset; + } + + return noffsetPosition; +} + +int GlodonHeaderView::sectionVisualPosition(int visualIndex) const +{ + Q_D(const GlodonHeaderView); + + if (visualIndex == -1) + { + return -1; + } + + return d->headerSectionPosition(visualIndex); +} + +void GlodonHeaderView::moveSection(int from, int to) +{ + Q_D(GlodonHeaderView); + + d->executePostedLayout(); + + if (from < 0 || from >= d->sectionCount() || to < 0 || to >= d->sectionCount()) + { + return; + } + + if (from == to) + { + int nLogical = logicalIndex(from); + Q_ASSERT(nLogical != -1); + updateSection(nLogical); + return; + } + + //int oldHeaderLength = length(); // ### for debugging; remove later + d->initializeIndexMapping(); + + QBitArray sectionHidden = d->sectionHidden; + int *visualIndices = d->visualIndices.data(); + int *logicalIndices = d->logicalIndices.data(); + int nlogical = logicalIndices[from]; + int nVisualIndex = from; + + int naffected_count = qAbs(to - from) + 1; + QVarLengthArray sizes(naffected_count); + QVarLengthArray modes(naffected_count); + + // move sections and indices + if (to > from) + { + sizes[to - from] = d->headerSectionSize(from); + modes[to - from] = d->headerSectionResizeMode(from); + + while (nVisualIndex < to) + { + sizes[nVisualIndex - from] = d->headerSectionSize(nVisualIndex + 1); + modes[nVisualIndex - from] = d->headerSectionResizeMode(nVisualIndex + 1); + + if (!sectionHidden.isEmpty()) + { + sectionHidden.setBit(nVisualIndex, sectionHidden.testBit(nVisualIndex + 1)); + } + + visualIndices[logicalIndices[nVisualIndex + 1]] = nVisualIndex; + logicalIndices[nVisualIndex] = logicalIndices[nVisualIndex + 1]; + ++nVisualIndex; + } + } + else + { + sizes[0] = d->headerSectionSize(from); + modes[0] = d->headerSectionResizeMode(from); + + while (nVisualIndex > to) + { + sizes[nVisualIndex - to] = d->headerSectionSize(nVisualIndex - 1); + modes[nVisualIndex - to] = d->headerSectionResizeMode(nVisualIndex - 1); + + if (!sectionHidden.isEmpty()) + { + sectionHidden.setBit(nVisualIndex, sectionHidden.testBit(nVisualIndex - 1)); + } + + visualIndices[logicalIndices[nVisualIndex - 1]] = nVisualIndex; + logicalIndices[nVisualIndex] = logicalIndices[nVisualIndex - 1]; + --nVisualIndex; + } + } + + if (!sectionHidden.isEmpty()) + { + sectionHidden.setBit(to, d->sectionHidden.testBit(from)); + d->sectionHidden = sectionHidden; + } + + visualIndices[nlogical] = to; + logicalIndices[to] = nlogical; + + if (to > from) + { + for (nVisualIndex = from; nVisualIndex <= to; ++nVisualIndex) + { + int nsize = sizes[nVisualIndex - from]; + ResizeMode mode = modes[nVisualIndex - from]; + d->createSectionItems(nVisualIndex, nVisualIndex, nsize, mode); + } + } + else + { + for (nVisualIndex = to; nVisualIndex <= from; ++nVisualIndex) + { + int nsize = sizes[nVisualIndex - to]; + ResizeMode mode = modes[nVisualIndex - to]; + d->createSectionItems(nVisualIndex, nVisualIndex, nsize, mode); + } + } + + d->viewport->update(); + + emit sectionMoved(nlogical, from, to); +} + +void GlodonHeaderView::swapSections(int first, int second) +{ + Q_D(GlodonHeaderView); + + if (first == second) + { + return; + } + + d->executePostedLayout(); + + if (first < 0 || first >= d->sectionCount() || second < 0 || second >= d->sectionCount()) + { + return; + } + + int nFirstSize = d->headerSectionSize(first); + ResizeMode firstMode = d->headerSectionResizeMode(first); + int nFirstLogical = d->logicalIndex(first); + + int nSecondSize = d->headerSectionSize(second); + ResizeMode secondMode = d->headerSectionResizeMode(second); + int nSecondLogical = d->logicalIndex(second); + + if (d->m_state == GlodonHeaderViewPrivate::ResizeSection) + { + d->preventCursorChangeInSetOffset = true; + } + + d->createSectionItems(second, second, nFirstSize, firstMode); + d->createSectionItems(first, first, nSecondSize, secondMode); + + d->initializeIndexMapping(); + + d->visualIndices[nFirstLogical] = second; + d->logicalIndices[second] = nFirstLogical; + + d->visualIndices[nSecondLogical] = first; + d->logicalIndices[first] = nSecondLogical; + + if (!d->sectionHidden.isEmpty()) + { + bool bfirstHidden = d->sectionHidden.testBit(first); + bool bsecondHidden = d->sectionHidden.testBit(second); + d->sectionHidden.setBit(first, bsecondHidden); + d->sectionHidden.setBit(second, bfirstHidden); + } + + d->viewport->update(); + emit sectionMoved(nFirstLogical, first, second); + emit sectionMoved(nSecondLogical, second, first); +} + +void GlodonHeaderView::resizeSection(int logical, int size, bool update, bool isManual) +{ + Q_D(GlodonHeaderView); + + if (logical < 0 || logical >= count() || size < 0 || size > maxSizeSection) + { + return; + } + + if (isSectionHidden(logical)) + { + d->hiddenSectionSize.insert(logical, size); + return; + } + + int nVisual = visualIndex(logical); + + if (nVisual == -1) + { + return; + } + + if (d->m_state == GlodonHeaderViewPrivate::ResizeSection && !d->cascadingResizing && logical != d->section) + { + d->preventCursorChangeInSetOffset = true; + } + + int nOldSize = d->headerSectionSize(nVisual); + + if (nOldSize == size) + { + return; + } + + d->executePostedLayout(); + d->invalidateCachedSizeHint(); + + GlodonHeaderView::ResizeMode mode = d->headerSectionResizeMode(nVisual); + + d->createSectionItems(nVisual, nVisual, size, mode); + + if (!updatesEnabled()) + { + emit sectionResized(logical, nOldSize, size, isManual); + return; + } + + int nw = d->viewport->width(); + int nh = d->viewport->height(); + int npos = sectionViewportPosition(logical); + QRect tmpRect; + + if (d->orientation == Qt::Horizontal) + { + if (isRightToLeft()) + { + tmpRect.setRect(0, 0, npos + size, nh); + } + else + { + tmpRect.setRect(npos, 0, nw - npos, nh); + } + } + else + { + tmpRect.setRect(0, npos, nw, nh - npos); + } + + if (update) + { + d->viewport->update(tmpRect.normalized()); + emit sectionResized(logical, nOldSize, size, isManual); + } +} + +void GlodonHeaderView::setSectionSpanSeparate(bool value) +{ + Q_D(GlodonHeaderView); + d->m_createSectionSpanSeparate = value; +} + +bool GlodonHeaderView::isSectionSpanSeparate() +{ + Q_D(GlodonHeaderView); + return d->m_createSectionSpanSeparate; +} + +bool GlodonHeaderView::isSectionHidden(int logicalIndex) const +{ + Q_D(const GlodonHeaderView); + d->executePostedLayout(); + + if (logicalIndex >= d->sectionHidden.count() || logicalIndex < 0 || logicalIndex >= d->sectionCount()) + { + return false; + } + + int nVisualIndex = visualIndex(logicalIndex); + Q_ASSERT(nVisualIndex != -1); + return d->sectionHidden.testBit(nVisualIndex); +} + +GlodonHeaderView::VisibleState GlodonHeaderView::visibleState(int logicalIndex) const +{ + Q_D(const GlodonHeaderView); + + d->executePostedLayout(); + + QRect rect = this->geometry(); + int nleft = sectionViewportPosition(logicalIndex); + int nright = nleft + sectionSize(logicalIndex); + int nrectLeft = rect.left(); + int nrectRight = rect.right(); + + if (d->orientation == Qt::Vertical) + { + nrectLeft = rect.top(); + nrectRight = rect.bottom(); + } + + int nstate = 3; + + if (nleft > nrectLeft && nright < nrectRight) + { + nstate = 2; // whole section is visible + } + else if (nleft < nrectLeft && nright >= nrectLeft) + { + nstate = -1; + } + else if (nright > nrectRight && nleft <= nrectRight) + { + nstate = 1; + } + else if (nleft > nrectRight) + { + nstate = 0; + } + else if (nright < nrectLeft) + { + nstate = 0; + } + else //非常可怕的情况,一个section占据了整个宽度/高度 + { + Q_ASSERT(false); + } + + return GlodonHeaderView::VisibleState(nstate); +} + +int GlodonHeaderView::hiddenSectionCount() const +{ + Q_D(const GlodonHeaderView); + return d->hiddenSectionSize.count(); +} + +void GlodonHeaderView::setSectionHidden(int logicalIndex, bool hide) +{ + Q_D(GlodonHeaderView); + + if (isInValidLogicalIndex(logicalIndex)) + { + return; + } + + d->executePostedLayout(); + int nVisualIndex = visualIndex(logicalIndex); + Q_ASSERT(nVisualIndex != -1); + + if (hide == d->isVisualIndexHidden(nVisualIndex)) + { + return; + } + + if (hide) + { + int nsize = d->headerSectionSize(nVisualIndex); + if (nsize == 0) + { + d->hiddenSectionSize.insert(logicalIndex, d->defaultSectionSize); + } + else + { + d->hiddenSectionSize.insert(logicalIndex, nsize); + } + + resizeSection(logicalIndex, 0); + + if (d->sectionHidden.count() < count()) + { + d->sectionHidden.resize(count()); + } + + d->sectionHidden.setBit(nVisualIndex, true); + } + else + { + int nsize = d->hiddenSectionSize.value(logicalIndex, d->defaultSectionSize); + + d->hiddenSectionSize.remove(logicalIndex); + + if (d->hiddenSectionSize.isEmpty()) + { + d->sectionHidden.clear(); + } + else + { + Q_ASSERT(nVisualIndex <= d->sectionHidden.count()); + d->sectionHidden.setBit(nVisualIndex, false); + } + + if (nsize == 0) + { + nsize = d->defaultSectionSize; + } + + resizeSection(logicalIndex, nsize); + } +} + +void GlodonHeaderView::batchSetSectionHidden(QSet logicalIndexs, bool hide) +{ + Q_D(GlodonHeaderView); + + d->executePostedLayout(); + + QSet> oNeedHideLogicalAndVisualIndexs; + d->excludeNotNeedHideSections(logicalIndexs, hide, oNeedHideLogicalAndVisualIndexs); + + if (oNeedHideLogicalAndVisualIndexs.isEmpty()) + return; + + QMap oNeedResizeSections; + + if (hide) + { + if (d->sectionHidden.count() < count()) + { + d->sectionHidden.resize(count()); + } + + QSet>::iterator oNeedHideIndexIte = oNeedHideLogicalAndVisualIndexs.begin(); + while (oNeedHideIndexIte != oNeedHideLogicalAndVisualIndexs.end()) + { + QPair nCurIndexPair = *oNeedHideIndexIte; + + oNeedResizeSections.insert(nCurIndexPair.first, 0); + d->sectionHidden.setBit(nCurIndexPair.second, true); + d->hiddenSectionSize.insert(nCurIndexPair.first, d->headerSectionSize(nCurIndexPair.second)); + + oNeedHideIndexIte++; + } + } + else + { + QSet>::iterator oNeedHideIndexIte = oNeedHideLogicalAndVisualIndexs.begin(); + while (oNeedHideIndexIte != oNeedHideLogicalAndVisualIndexs.end()) + { + QPair nCurIndexPair = *oNeedHideIndexIte; + + int nCurIndexSize = d->hiddenSectionSize.value(nCurIndexPair.first, d->defaultSectionSize); + oNeedResizeSections.insert(nCurIndexPair.first, nCurIndexSize); + + d->sectionHidden.setBit(nCurIndexPair.second, false); + d->hiddenSectionSize.remove(nCurIndexPair.first); + oNeedHideIndexIte++; + } + + if (d->hiddenSectionSize.isEmpty()) + { + d->sectionHidden.clear(); + } + } + + d->doBatchResizeSection(oNeedResizeSections, true); +} + +int GlodonHeaderView::count() const +{ + Q_D(const GlodonHeaderView); + d->executePostedLayout(); + return d->sectionCount(); +} + +int GlodonHeaderView::visualIndex(int logicalIndex) const +{ + Q_D(const GlodonHeaderView); + + if (logicalIndex < 0) + { + return -1; + } + + d->executePostedLayout(); + + if (d->visualIndices.isEmpty()) + { + // nothing has been moved, so we have no mapping + if (logicalIndex < d->sectionCount()) + { + return logicalIndex; + } + } + else if (logicalIndex < d->visualIndices.count()) + { + int nVisual = d->visualIndices.at(logicalIndex); + Q_ASSERT(nVisual < d->sectionCount()); + return nVisual; + } + + return -1; +} + +int GlodonHeaderView::logicalIndex(int visualIndex) const +{ + Q_D(const GlodonHeaderView); + + if (visualIndex < 0 || visualIndex >= d->sectionCount()) + { + return -1; + } + + return d->logicalIndex(visualIndex); +} + +// ### Qt 5: change to setSectionsMovable() +void GlodonHeaderView::setMovable(bool movable) +{ + Q_D(GlodonHeaderView); + + if ((d->isTree) && (d->orientation == Qt::Vertical)) + { + return; + } + + d->movableSections = movable; +} + +// ### Qt 5: change to sectionsMovable() +bool GlodonHeaderView::isMovable() const +{ + Q_D(const GlodonHeaderView); + return d->movableSections; +} + +// ### Qt 5: change to setSectionsClickable() +void GlodonHeaderView::setClickable(bool clickable) +{ + Q_D(GlodonHeaderView); + d->clickableSections = clickable; +} + +// ### Qt 5: change to sectionsClickable() +bool GlodonHeaderView::isClickable() const +{ + Q_D(const GlodonHeaderView); + return d->clickableSections; +} + +void GlodonHeaderView::setHighlightSections(bool highlight) +{ + Q_D(GlodonHeaderView); + d->highlightSelected = highlight; +} + +bool GlodonHeaderView::highlightSections() const +{ + Q_D(const GlodonHeaderView); + return d->highlightSelected; +} + +void GlodonHeaderView::setFixedCellColor(const QColor &value, int index) +{ + if (index == -1) + { + for (int i = 0; i < count(); i++) + { + inserFixedCellColor(value, i); + } + } + else + { + Q_ASSERT((index >= 0) && (index < count())); + inserFixedCellColor(value, index); + } +} + +void GlodonHeaderView::inserFixedCellColor(const QColor &value, int index) +{ + Q_D(GlodonHeaderView); + GlodonCellAttr attr; + attr.orientation = d->orientation; + attr.background = value; + d->fixedCellsColor[index] = attr; +} + +void GlodonHeaderView::setFixedCellEvent(bool value) +{ + Q_D(GlodonHeaderView); + + if (d->fixedCellEvent != value) + { + d->fixedCellEvent = value; + } +} + +bool GlodonHeaderView::isFixedcellEvent() const +{ + Q_D(const GlodonHeaderView); + return d->fixedCellEvent; +} + +void GlodonHeaderView::setGridLineWidth(int value) +{ + Q_D(GlodonHeaderView); + + if (d->fixedCellEvent) + { + // 设置格线之后,需要重新计算length和每个Section的StartPos + d->length += (value - d->gridLineWidth) * sectionCount(); + d->gridLineWidth = value; + + d->recalcSectionStartPos(); + d->viewport->update(); + } +} + +void GlodonHeaderView::setGridLineColor(QColor value) +{ + Q_D(GlodonHeaderView); + + if (d->gridLineColor != value) + { + d->gridLineColor = value; + d->viewport->update(); + } +} + +void GlodonHeaderView::setResizeMode(ResizeMode mode) +{ + Q_D(GlodonHeaderView); + + initializeSections(); + + d->setGlobalHeaderResizeMode(mode); +} + +// ### Qt 5: change to setSectionResizeMode() +void GlodonHeaderView::setResizeMode(int logicalIndex, ResizeMode mode) +{ + Q_D(GlodonHeaderView); + + int nVisualIndex = visualIndex(logicalIndex); + Q_ASSERT(nVisualIndex != -1); + + d->setHeaderSectionResizeMode(nVisualIndex, mode); +} + +GlodonHeaderView::ResizeMode GlodonHeaderView::resizeMode() const +{ + Q_D(const GlodonHeaderView); + return d->globalResizeMode; +} + +GlodonHeaderView::ResizeMode GlodonHeaderView::resizeMode(int logicalIndex) const +{ + Q_D(const GlodonHeaderView); + int nVisualIndex = visualIndex(logicalIndex); + + if (nVisualIndex == -1) + { + return Fixed; //the default value + } + + return d->headerSectionResizeMode(nVisualIndex); +} + +void GlodonHeaderView::setSortIndicatorShown(bool show) +{ + Q_D(GlodonHeaderView); + + if (d->sortIndicatorShown == show) + { + return; + } + + d->sortIndicatorShown = show; + + if (sortIndicatorSection() < 0 || sortIndicatorSection() > count()) + { + return; + } + + d->viewport->update(); +} + +bool GlodonHeaderView::isSortIndicatorShown() const +{ + Q_D(const GlodonHeaderView); + return d->sortIndicatorShown; +} + +void GlodonHeaderView::setSortIndicator(int logicalIndex, Qt::SortOrder order) +{ + Q_D(GlodonHeaderView); + + // This is so that people can set the position of the sort indicator before the fill the model + int nold = d->sortIndicatorSection; + d->sortIndicatorSection = logicalIndex; + d->sortIndicatorOrder = order; + + if (logicalIndex >= d->sectionCount()) + { + emit sortIndicatorChanged(logicalIndex, order); + return; // nothing to do + } + + if (nold >= 0 && nold != logicalIndex) + { + updateSection(nold); + } + + if (logicalIndex >= 0) + { + updateSection(logicalIndex); + } + + emit sortIndicatorChanged(logicalIndex, order); +} + +int GlodonHeaderView::sortIndicatorSection() const +{ + Q_D(const GlodonHeaderView); + return d->sortIndicatorSection; +} + +void GlodonHeaderView::setSortIndicatorSection(int logicalIndex) +{ + Q_D(GlodonHeaderView); + d->sortIndicatorSection = logicalIndex; +} + +Qt::SortOrder GlodonHeaderView::sortIndicatorOrder() const +{ + Q_D(const GlodonHeaderView); + return d->sortIndicatorOrder; +} + +void GlodonHeaderView::setSortIndicatorOrder(Qt::SortOrder order) +{ + Q_D(GlodonHeaderView); + d->sortIndicatorOrder = order; +} + +bool GlodonHeaderView::cascadingSectionResizes() const +{ + Q_D(const GlodonHeaderView); + return d->cascadingResizing; +} + +void GlodonHeaderView::setCascadingSectionResizes(bool enable) +{ + Q_D(GlodonHeaderView); + d->cascadingResizing = enable; +} + +int GlodonHeaderView::defaultSectionSize() const +{ + Q_D(const GlodonHeaderView); + return d->defaultSectionSize; +} + +void GlodonHeaderView::setDefaultSectionSize(int size) +{ + Q_D(GlodonHeaderView); + + if (size < 0 || size > maxSizeSection) + { + return; + } + + d->setDefaultSectionSize(size); +} + +int GlodonHeaderView::minimumSectionSize() const +{ + Q_D(const GlodonHeaderView); + + if (d->minimumSectionSize == -1) + { + QSize strut = QApplication::globalStrut(); + int nMargin = style()->pixelMetric(QStyle::PM_HeaderMargin, 0, this); + + if (d->orientation == Qt::Horizontal) + { + return qMax(strut.width(), (fontMetrics().maxWidth() + nMargin)); + } + + return qMax(strut.height(), (fontMetrics().height() + nMargin)); + } + + return d->minimumSectionSize; +} + +void GlodonHeaderView::setMinimumSectionSize(int size) +{ + Q_D(GlodonHeaderView); + + if (size < -1 || size > maxSizeSection) + { + return; + } + + d->minimumSectionSize = size; +} + +bool GlodonHeaderView::isTree() const +{ + Q_D(const GlodonHeaderView); + return d->isTree; +} + +void GlodonHeaderView::setIsTree(bool showTree) +{ + Q_D(GlodonHeaderView); + + if (showTree != d->isTree) + { + d->isTree = showTree; + + if (d->orientation == Qt::Vertical) + { + d->clear(); + initializeSections(); + } + + if (showTree) + { + d->movableSections = !showTree; + } + } +} + +bool GlodonHeaderView::autoSectionData() const +{ + Q_D(const GlodonHeaderView); + return d->autoSectionData; +} + +void GlodonHeaderView::setAutoSectionData(bool autoData) +{ + Q_D(GlodonHeaderView); + + if (d->autoSectionData != autoData) + { + d->autoSectionData = autoData; + d->viewport->update(); + } +} + +int GlodonHeaderView::fixedCount() const +{ + Q_D(const GlodonHeaderView); + return d->fixedCount; +} + +void GlodonHeaderView::setFixedCount(int fixedCount) +{ + Q_D(GlodonHeaderView); + d->fixedCount = fixedCount; +} + +Qt::Alignment GlodonHeaderView::defaultAlignment() const +{ + Q_D(const GlodonHeaderView); + return d->defaultAlignment; +} + +void GlodonHeaderView::setDefaultAlignment(Qt::Alignment alignment) +{ + Q_D(GlodonHeaderView); + + if (d->defaultAlignment == alignment) + { + return; + } + + d->defaultAlignment = alignment; + d->viewport->update(); +} + +void GlodonHeaderView::doItemsLayout() +{ + initializeSections(); + GlodonAbstractItemView::doItemsLayout(); +} + +bool GlodonHeaderView::sectionsMoved() const +{ + Q_D(const GlodonHeaderView); + return !d->visualIndices.isEmpty(); +} + +void GlodonHeaderView::clearSectionMove() +{ + Q_D(const GlodonHeaderView); + d->visualIndices.clear(); + d->logicalIndices.clear(); +} + +bool GlodonHeaderView::sectionsHidden() const +{ + Q_D(const GlodonHeaderView); + return !d->hiddenSectionSize.isEmpty(); +} + +int GlodonHeaderView::getSectionHandleAt(int position) +{ + Q_D(GlodonHeaderView); + return d->sectionHandleAt(position); +} + +#ifndef QT_NO_DATASTREAM + +QByteArray GlodonHeaderView::saveState() const +{ + Q_D(const GlodonHeaderView); + QByteArray data; + QDataStream stream(&data, QIODevice::WriteOnly); + stream << GlodonHeaderViewPrivate::VersionMarker; + stream << 0; // current version is 0 + d->write(stream); + return data; +} + +bool GlodonHeaderView::restoreState(const QByteArray &state) +{ + Q_D(GlodonHeaderView); + + if (state.isEmpty()) + { + return false; + } + + QByteArray data = state; + QDataStream stream(&data, QIODevice::ReadOnly); + int nmarker; + int nver; + stream >> nmarker; + stream >> nver; + + if (stream.status() != QDataStream::Ok + || nmarker != GlodonHeaderViewPrivate::VersionMarker + || nver != 0) // current version is 0 + { + return false; + } + + if (d->read(stream)) + { + emit sortIndicatorChanged(d->sortIndicatorSection, d->sortIndicatorOrder); + d->viewport->update(); + return true; + } + + return false; +} + +#endif // QT_NO_DATASTREAM + +void GlodonHeaderView::reset() +{ + GlodonAbstractItemView::reset(); + + // it would be correct to call clear, but some apps rely + // on the header keeping the sections, even after calling reset + //d->clear(); + initializeSections(); +} + +void GlodonHeaderView::resetAfterTreeBuild(const QVector &showRows) +{ + Q_D(GlodonHeaderView); + int nOldCount = d->sectionCount(); + d->resetAfterTreeBuild(showRows); + int nNewCount = d->sectionCount(); + + emit sectionCountChanged(nOldCount, nNewCount); +} + +void GlodonHeaderViewPrivate::recalcSectionStartPos() const // linear (but fast) +{ + int pixelpos = 0; + int nPreSize = 0; + + for (QVector::const_iterator i = sectionItems.constBegin(); i != sectionItems.constEnd(); ++i) + { + if (nPreSize != 0) + { + pixelpos += gridLineWidth; + } + + i->calculated_startpos = pixelpos; // write into const mutable + + pixelpos += i->size; + nPreSize = i->size; + } + + sectionStartposRecalc = false; +} + +void GlodonHeaderView::resetSectionItems() +{ + Q_D(GlodonHeaderView); + GlodonAbstractItemView::reset(); + d->clear(); + initializeSections(); +} + +void GlodonHeaderView::zoomInSection(double factor) +{ + Q_D(GlodonHeaderView); + + if (d->sectionItems.count() <= 0) + { + return; + } + + if (d->m_srcFontPointSize == -1) + { + d->m_srcFontPointSize = font().pointSize(); + } + + QFont currentFont = font(); + currentFont.setPointSize(d->m_srcFontPointSize * factor); + setFont(currentFont); + + int nPreSrcLength = 0; + int npreLength = 0; + + for (int i = 0; i < d->sectionItems.count(); ++i) + { + GlodonHeaderViewPrivate::SectionItem curSpan = d->sectionItems.at(i); + + if (curSpan.srcSize == -1) + { + curSpan.srcSize = curSpan.size; + } + + nPreSrcLength += curSpan.srcSize; + curSpan.size = nPreSrcLength * factor - npreLength; + npreLength += curSpan.size; + d->sectionItems.replace(i, curSpan); + } + + if (d->m_srcLength == -1 || d->m_srcLength == 0) + { + d->m_srcLength = d->length; + } + + d->length = factor * d->m_srcLength; + d->viewport->update(); +} + +void GlodonHeaderView::setInZoomingSection(bool zooming) +{ + d_func()->m_inZoomForceResize = zooming; +} + +bool GlodonHeaderView::inZoomingSection() const +{ + return d_func()->m_inZoomForceResize; +} + +void GlodonHeaderView::setLogicalSectionMovable(bool isManual) +{ + d_func()->m_logicalMovable = isManual; +} + +bool GlodonHeaderView::isLogicalSectionMovable() const +{ + return d_func()->m_logicalMovable; +} + +bool GlodonHeaderView::drawBorder() const +{ + return d_func()->m_drawBorder; +} + +void GlodonHeaderView::setDrawBorder(bool value) +{ + d_func()->m_drawBorder = value; +} + +bool GlodonHeaderView::allowDoubleClicked() const +{ + return d_func()->m_allowDoubleClicked; +} + +void GlodonHeaderView::setAllowDoubleClicked(bool value) +{ + d_func()->m_allowDoubleClicked = value; +} + +bool GlodonHeaderView::boldWithSelected() +{ + return d_func()->m_boldWithSelected; +} + +void GlodonHeaderView::setBoldWithSelected(bool value) +{ + d_func()->m_boldWithSelected = value; +} + +bool GlodonHeaderView::isFontShadow() const +{ + return d_func()->m_bFontShadow; +} + +void GlodonHeaderView::setFontShadow(bool fontShadow) +{ + d_func()->m_bFontShadow = fontShadow; +} + +QColor GlodonHeaderView::fontShadowColor() const +{ + return d_func()->m_clrFontShadow; +} + +void GlodonHeaderView::setFontShadowColor(const QColor &clr) +{ + d_func()->m_clrFontShadow = clr; +} + +bool GlodonHeaderView::isHeaderLinearGradient() const +{ + return d_func()->m_bLinearGradient; +} + +void GlodonHeaderView::setHeaderLinearGradient(bool value) +{ + d_func()->m_bLinearGradient = value; +} + +void GlodonHeaderView::headerDataChanged(Qt::Orientation orientation, int logicalFirst, int logicalLast) +{ + Q_D(GlodonHeaderView); + + if (d->orientation != orientation) + { + return; + } + + if (logicalFirst < 0 || logicalLast < 0 || logicalFirst >= count() || logicalLast >= count()) + { + return; + } + + d->invalidateCachedSizeHint(); + + int nfirstVisualIndex = INT_MAX; + int nlastVisualIndex = -1; + + for (int i = logicalFirst; i <= logicalLast; ++i) + { + const int c_visual = visualIndex(i); + nfirstVisualIndex = qMin(nfirstVisualIndex, c_visual); + nlastVisualIndex = qMax(nlastVisualIndex, c_visual); + } + + const int c_first = d->headerSectionPosition(nfirstVisualIndex); + const int c_last = d->headerSectionPosition(nlastVisualIndex) + + d->headerSectionSize(nlastVisualIndex); + + if (orientation == Qt::Horizontal) + { + d->viewport->update(c_first, 0, c_last - c_first, d->viewport->height()); + } + else + { + d->viewport->update(0, c_first, d->viewport->width(), c_last - c_first); + } +} + +void GlodonHeaderView::setDrawWidth(int drawWidth) +{ + Q_D(GlodonHeaderView); + + if (drawWidth >= 0 && drawWidth != d->drawWidth) + { + d->drawWidth = drawWidth; + d->viewport->update(); + emit drawWidthChanged(drawWidth); + } +} + +void GlodonHeaderView::updateSection(int index) +{ + Q_D(GlodonHeaderView); + + if (d->orientation == Qt::Horizontal) + { + d->viewport->update(QRect(sectionViewportPosition(index), + 0, sectionSize(index), d->viewport->height())); + } + else + { + d->viewport->update(QRect(0, sectionViewportPosition(index), + d->viewport->width(), sectionSize(index))); + } +} + +void GlodonHeaderView::sectionsInserted(const QModelIndex &parent, + int logicalFirst, int logicalLast) +{ + Q_D(GlodonHeaderView); + + if (parent != d->m_root) + { + return; // we only handle changes in the top level + } + + int nOldCount = d->sectionCount(); + + d->invalidateCachedSizeHint(); + + if (d->m_state == GlodonHeaderViewPrivate::ResizeSection) + { + d->preventCursorChangeInSetOffset = true; + } + + // add the new sections + int nInsertAt = logicalFirst; + int nInsertCount = logicalLast - logicalFirst + 1; + + GlodonHeaderViewPrivate::SectionItem span(d->defaultSectionSize, d->globalResizeMode); + + d->sectionStartposRecalc = true; + + d->length += (d->defaultSectionSize + d->gridLineWidth) * nInsertCount; + + if (d->sectionItems.isEmpty() || nInsertAt >= d->sectionItems.count()) + { + nInsertAt = d->sectionItems.count(); // append + } + + d->sectionItems.insert(nInsertAt, nInsertCount, span); + + // update sorting column + if (d->sortIndicatorSection >= logicalFirst) + { + d->sortIndicatorSection += nInsertCount; + } + + // clear selection cache + d->sectionSelected.clear(); + + // update mapping + if (!d->visualIndices.isEmpty() && !d->logicalIndices.isEmpty()) + { + Q_ASSERT(d->visualIndices.count() == d->logicalIndices.count()); + int nmappingCount = d->visualIndices.count(); + + for (int i = 0; i < nmappingCount; ++i) + { + if (d->visualIndices.at(i) >= logicalFirst) + { + d->visualIndices[i] += nInsertCount; + } + + if (d->logicalIndices.at(i) >= logicalFirst) + { + d->logicalIndices[i] += nInsertCount; + } + } + + for (int j = logicalFirst; j <= logicalLast; ++j) + { + d->visualIndices.insert(j, j); + d->logicalIndices.insert(j, j); + } + } + + // insert sections into sectionsHidden + if (!d->sectionHidden.isEmpty()) + { + QBitArray sectionHidden(d->sectionHidden); + const int c_hiddenSize = sectionHidden.count(); + sectionHidden.resize(c_hiddenSize + nInsertCount); + sectionHidden.fill(false, logicalFirst, logicalLast + 1); + + for (int j = logicalLast + 1; j < c_hiddenSize; ++j) + //here we simply copy the old sectionHidden + { + sectionHidden.setBit(j, d->sectionHidden.testBit(j - nInsertCount)); + } + + d->sectionHidden = sectionHidden; + } + + // insert sections into hiddenSectionSize + QHash newHiddenSectionSize; // from logical index to section size + + for (int i = 0; i < logicalFirst; ++i) + { + if (isSectionHidden(i)) + { + newHiddenSectionSize[i] = d->hiddenSectionSize[i]; + } + } + + for (int j = logicalLast + 1; j < d->sectionCount(); ++j) + { + if (isSectionHidden(j)) + { + newHiddenSectionSize[j] = d->hiddenSectionSize[j - nInsertCount]; + } + } + + d->hiddenSectionSize = newHiddenSectionSize; + + emit sectionCountChanged(nOldCount, count()); +} + +void GlodonHeaderView::sectionsAboutToBeRemoved(const QModelIndex &parent, + int logicalFirst, int logicalLast) +{ + Q_UNUSED(parent); + Q_UNUSED(logicalFirst); + Q_UNUSED(logicalLast); +} + +void GlodonHeaderViewPrivate::updateHiddenSections(int logicalFirst, int logicalLast) +{ + Q_Q(GlodonHeaderView); + const int c_changeCount = logicalLast - logicalFirst + 1; + + // remove sections from hiddenSectionSize + QHash newHiddenSectionSize; // from logical index to section size + + for (int i = 0; i < logicalFirst; ++i) + { + if (q->isSectionHidden(i)) + { + newHiddenSectionSize[i] = hiddenSectionSize[i]; + } + } + + for (int j = logicalLast + 1; j < sectionCount(); ++j) + { + if (q->isSectionHidden(j)) + { + newHiddenSectionSize[j - c_changeCount] = hiddenSectionSize[j]; + } + } + + hiddenSectionSize = newHiddenSectionSize; + + // remove sections from sectionsHidden + if (!sectionHidden.isEmpty()) + { + const int c_hiddenSize = sectionHidden.size(); + const int c_newsize = qMin(sectionCount() - c_changeCount, c_hiddenSize); + QBitArray newSectionHidden(c_newsize); + int nk = 0; + + for (int j = 0; j < c_hiddenSize; ++j) + { + const int c_logical = logicalIndex(j); + + if (c_logical < logicalFirst || c_logical > logicalLast) + { + newSectionHidden[nk++] = sectionHidden[j]; + } + } + + sectionHidden = newSectionHidden; + } +} + +void GlodonHeaderViewPrivate::_q_sectionsRemoved(const QModelIndex &parent, int logicalFirst, int logicalLast) +{ + Q_Q(GlodonHeaderView); + + if (parent != m_root) + { + return; // we only handle changes in the top level + } + + if (qMin(logicalFirst, logicalLast) < 0 + || qMax(logicalLast, logicalFirst) >= sectionItems.count()) + { + return; + } + + int noldCount = q->count(); + int nchangeCount = logicalLast - logicalFirst + 1; + + if (m_state == GlodonHeaderViewPrivate::ResizeSection) + { + preventCursorChangeInSetOffset = true; + } + + updateHiddenSections(logicalFirst, logicalLast); + + if (visualIndices.isEmpty() && logicalIndices.isEmpty()) + { + //Q_ASSERT(headerSectionCount() == sectionSpans.count()); + removeSectionsFromSectionItems(logicalFirst, logicalLast); + } + else + { + if (logicalFirst == logicalLast) // Remove just one index. + { + int i = logicalFirst; + int nVisualIndex = visualIndices.at(i); + + for (int j = 0; j < sectionItems.count(); ++j) + { + if (j >= logicalIndices.count()) + { + continue; // the section doesn't exist + } + + if (j > nVisualIndex) + { + int nlogical = logicalIndices.at(j); + --(visualIndices[nlogical]); + } + + if (logicalIndex(j) > i) // no need to move the positions before l + { + --(logicalIndices[j]); + } + } + + logicalIndices.remove(nVisualIndex); + visualIndices.remove(i); + //Q_ASSERT(headerSectionCount() == sectionSpans.count()); + removeSectionsFromSectionItems(nVisualIndex, nVisualIndex); + } + else + { + sectionStartposRecalc = true; // We will need to recalc positions after removing items + + for (int u = 0; u < sectionItems.count(); ++u) // Store spans info + + { + sectionItems.at(u).tmpLogIdx = logicalIndices.at(u); + } + + for (int v = sectionItems.count() - 1; v >= 0; --v) // Remove the sections + { + + if (logicalFirst <= sectionItems.at(v).tmpLogIdx && sectionItems.at(v).tmpLogIdx <= logicalLast) + + { + removeSectionsFromSectionItems(v, v); // Invalidates the spans variable + } + + } + + visualIndices.resize(sectionItems.count()); + + logicalIndices.resize(sectionItems.count()); + + int *visual_data = visualIndices.data(); + + int *logical_data = logicalIndices.data(); + + for (int w = 0; w < sectionItems.count(); ++w) // Restore visual and logical indexes + { + + int logindex = sectionItems.at(w).tmpLogIdx; + + if (logindex > logicalFirst) + + { + logindex -= nchangeCount; + } + + visual_data[logindex] = w; + + logical_data[w] = logindex; + + } + + } + + // ### handle sectionSelection (sectionHidden is handled by updateHiddenSections) + } + + // update sorting column + if (sortIndicatorSection >= logicalFirst) + { + if (sortIndicatorSection <= logicalLast) + { + sortIndicatorSection = -1; + } + else + { + sortIndicatorSection -= nchangeCount; + } + } + + // if we only have the last section (the "end" position) left, the header is empty + if (sectionItems.count() <= 0) + { + clear(); + } + + invalidateCachedSizeHint(); + + emit q->sectionCountChanged(noldCount, q->count()); + + viewport->update(); +} + +void GlodonHeaderViewPrivate::_q_layoutAboutToBeChanged() +{ + //if there is no row/column we can't have mapping for columns + //because no QModelIndex in the model would be valid + // ### this is far from being bullet-proof and we would need a real system to + // ### map columns or rows persistently + if ((orientation == Qt::Horizontal && m_model->rowCount(m_root) == 0) + || m_model->columnCount(m_root) == 0) + { + return; + } + + for (int i = 0; i < sectionHidden.count(); ++i) + { + if (sectionHidden.testBit(i)) // ### note that we are using column or row 0 + { + persistentHiddenSections.append(orientation == Qt::Horizontal + ? m_model->index(0, logicalIndex(i), m_root) + : m_model->index(logicalIndex(i), 0, m_root)); + } + } +} + +void GlodonHeaderViewPrivate::_q_layoutChanged() +{ + Q_Q(GlodonHeaderView); + + viewport->update(); + + if (persistentHiddenSections.isEmpty() || modelIsEmpty()) + { + if (modelSectionCount() != sectionItems.count()) + { + q->initializeSections(); + } + + persistentHiddenSections.clear(); + + return; + } + + QBitArray oldSectionHidden = sectionHidden; + + bool bsectionCountChanged = false; + + for (int i = 0; i < persistentHiddenSections.count(); ++i) + { + QModelIndex index = persistentHiddenSections.at(i); + + if (index.isValid()) + { + const int c_logical = (orientation == Qt::Horizontal + ? index.column() + : index.row()); + q->setSectionHidden(c_logical, true); + oldSectionHidden.setBit(c_logical, false); + } + else if (!bsectionCountChanged && (modelSectionCount() != sectionItems.count())) + { + bsectionCountChanged = true; + break; + } + } + + persistentHiddenSections.clear(); + + for (int i = 0; i < oldSectionHidden.count(); ++i) + { + if (oldSectionHidden.testBit(i)) + { + q->setSectionHidden(i, false); + } + } + + // the number of sections changed; we need to reread the state of the model + if (bsectionCountChanged) + { + q->initializeSections(); + } +} + +void GlodonHeaderView::initializeSections() +{ + Q_D(GlodonHeaderView); + + const int c_oldCount = d->sectionCount(); + const int c_newCount = d->modelSectionCount(); + + if (c_newCount <= 0) + { + d->clear(); + + emit sectionCountChanged(c_oldCount, 0); + } + else if (c_newCount != c_oldCount) + { + const int c_min = qBound(0, c_oldCount, c_newCount - 1); + + initializeSections(c_min, c_newCount - 1); + + //make sure we update the hidden sections + if (c_newCount < c_oldCount) + { + d->updateHiddenSections(0, c_newCount - 1); + } + } +} + +void GlodonHeaderView::initializeSections(int start, int end) +{ + Q_D(GlodonHeaderView); + + Q_ASSERT(start >= 0); + Q_ASSERT(end >= 0); + + d->invalidateCachedSizeHint(); + + int nOldCount = d->sectionCount(); + int nNewCount = end + 1; + + if (end + 1 < d->sectionCount()) + { + d->removeSectionsFromSectionItems(nNewCount, d->sectionCount() - 1); + + if (!d->hiddenSectionSize.isEmpty()) + { + if (d->sectionCount() - nNewCount > d->hiddenSectionSize.count()) + { + for (int i = end + 1; i < d->sectionCount(); ++i) + { + d->hiddenSectionSize.remove(i); + } + } + else + { + QHash::iterator it = d->hiddenSectionSize.begin(); + + while (it != d->hiddenSectionSize.end()) + { + if (it.key() > end) + { + it = d->hiddenSectionSize.erase(it); + } + else + { + ++it; + } + } + } + } + } + + if (!d->logicalIndices.isEmpty()) + { + if (nOldCount <= nNewCount) + { + d->logicalIndices.resize(nNewCount); + d->visualIndices.resize(nNewCount); + + for (int i = nOldCount; i < nNewCount; ++i) + { + d->logicalIndices[i] = i; + d->visualIndices[i] = i; + } + } + else + { + int j = 0; + + for (int i = 0; i < nOldCount; ++i) + { + int v = d->logicalIndices.at(i); + + if (v < nNewCount) + { + d->logicalIndices[j] = v; + d->visualIndices[v] = j; + j++; + } + } + + d->logicalIndices.resize(nNewCount); + d->visualIndices.resize(nNewCount); + } + } + + if (!d->sectionHidden.isEmpty()) + { + d->sectionHidden.resize(nNewCount); + } + + if (nNewCount > nOldCount) + { + if (d->m_createSectionSpanSeparate) + { + for (int i = start; i <= end; ++i) + { + d->createSectionItems(i, i, d->defaultSectionSize, d->globalResizeMode); + } + } + else + { + d->createSectionItems(start, end, (end - start + 1) * d->defaultSectionSize, d->globalResizeMode); + } + } + + if (d->sectionCount() != nOldCount) + { + emit sectionCountChanged(nOldCount, d->sectionCount()); + } + + d->viewport->update(); +} + +void GlodonHeaderView::currentChanged(const QModelIndex ¤t, const QModelIndex &old) +{ + Q_D(GlodonHeaderView); + + if (d->orientation == Qt::Horizontal && current.column() != old.column()) + { + if (old.isValid() && old.parent() == d->m_root) + { + d->viewport->update(QRect(sectionViewportPosition(old.column()), 0, + sectionSize(old.column()), d->viewport->height())); + } + + if (current.isValid() && current.parent() == d->m_root) + { + d->viewport->update(QRect(sectionViewportPosition(current.column()), 0, + sectionSize(current.column()), d->viewport->height())); + } + } + else if (d->orientation == Qt::Vertical && current.row() != old.row()) + { + if (old.isValid() && old.parent() == d->m_root) + { + d->viewport->update(QRect(0, sectionViewportPosition(old.row()), + d->viewport->width(), sectionSize(old.row()))); + } + + if (current.isValid() && current.parent() == d->m_root) + { + d->viewport->update(QRect(0, sectionViewportPosition(current.row()), + d->viewport->width(), sectionSize(current.row()))); + } + } +} + +QPoint GlodonHeaderView::mousePosition() +{ + Q_D(GlodonHeaderView); + return d->m_mousePosition; +} + +void GlodonHeaderView::setMousePosition(QPoint pos) +{ + Q_D(GlodonHeaderView); + d->m_mousePosition = pos; +} + +void GlodonHeaderView::setResizeDelay(bool delay) +{ + Q_D(GlodonHeaderView); + d->resizeDelay = delay; +} + +bool GlodonHeaderView::event(QEvent *e) +{ + Q_D(GlodonHeaderView); + + switch (e->type()) + { + case QEvent::HoverEnter: + { + QHoverEvent *he = static_cast(e); + d->m_hover = logicalIndexAt(he->pos()); + + if (d->m_hover != -1) + { + updateSection(d->m_hover); + } + + break; + } + + case QEvent::Leave: + case QEvent::HoverLeave: + { + if (d->m_hover != -1) + { + updateSection(d->m_hover); + } + + d->m_hover = -1; + break; + } + + case QEvent::HoverMove: + { + QHoverEvent *he = static_cast(e); + + int nOldHoverIndex = d->m_hover; + + d->m_hover = logicalIndexAt(he->pos()); + + bool bChangedIndex = (d->m_hover != nOldHoverIndex); + + if (bChangedIndex) + { + if (nOldHoverIndex != -1) + { + updateSection(nOldHoverIndex); + } + + if (d->m_hover != -1) + { + updateSection(d->m_hover); + } + } + else + { + if (d->m_state == GlodonHeaderViewPrivate::MoveSection) + { + setCursor(Qt::ArrowCursor); + } + } + } + default: + break; + } + + return GlodonAbstractItemView::event(e); +} + +void GlodonHeaderView::drawImageInDesignatedLogicalIndex(QPainter *painter, QStyleOptionHeader &supopt) const +{ + Q_D(const GlodonHeaderView); + if (d->m_logicalIndexHash.keys().contains(supopt.section)) + { + QImage image(d->m_logicalIndexHash.value(supopt.section)); + int nTextWidth = painter->fontMetrics().width(supopt.text); //表头文本的宽度 + int nTextHeight = painter->fontMetrics().height(); + QRect rectImage((supopt.rect.left() + (supopt.rect.width() - nTextWidth) / 2) - image.width() - 3, + supopt.rect.top() + (supopt.rect.height() - nTextHeight) / 2, image.width(), image.height()); + painter->drawImage(rectImage, image); + } +} + +void GlodonHeaderView::paintEvent(QPaintEvent *e) +{ + Q_D(GlodonHeaderView); + + if (count() == 0) + { + return; + } + + QPainter painter(d->viewport); + + const QPoint c_offset = d->m_scrollDelayOffset; + QRect translatedEventRect = e->rect(); + translatedEventRect.translate(c_offset); + + QRect currentSectionRect; + const int c_width = d->viewport->width(); + const int c_height = d->viewport->height(); + + if (isAllSectionHidden() && d->orientation == Qt::Vertical) + { + currentSectionRect.setRect(0, 0, c_width, 22); + paintEmptySection(&painter, currentSectionRect); + return; + } + + int nlogical; + int nstart = -1; + int nend = -1; + + if (d->orientation == Qt::Horizontal) + { + nstart = visualIndexAt(translatedEventRect.left()); + nend = visualIndexAt(translatedEventRect.right()); + } + else + { + nstart = visualIndexAt(translatedEventRect.top()); + nend = visualIndexAt(translatedEventRect.bottom()); + } + + if (d->reverse()) + { + nstart = (nstart == -1 ? count() - 1 : nstart); + nend = (nend == -1 ? 0 : nend); + } + else + { + nstart = (nstart == -1 ? 0 : nstart); + nend = (nend == -1 ? count() - 1 : nend); + } + + int ntmp = nstart; + nstart = qMin(nstart, nend); + nend = qMax(ntmp, nend); + + d->prepareSectionSelected(); // clear and resize the bit array + + QRect fixedRect(0, 0, 0, 0); + QRect scrollRect = d->viewport->rect(); +// if (d->fixedCount > 0) + { + int nfixSize = d->fixedSectionsSize(); + + if (d->orientation == Qt::Vertical) + { + fixedRect.adjust(0, 0, d->viewport->width(), nfixSize); + scrollRect.adjust(0, nfixSize, 0, 0); + } + else + { + fixedRect.adjust(0, 0, nfixSize, d->viewport->height()); + scrollRect.adjust(nfixSize, 0, 0, 0); + } + + painter.setClipRect(scrollRect); + } + + GFilterView *filter = dynamic_cast(this); + bool bIsFilter = (filter != NULL); + + for (int i = nstart; i <= nend; ++i) + { + if (d->isVisualIndexHidden(i)) + { + continue; + } + + painter.save(); + nlogical = logicalIndex(i); + + if (d->orientation == Qt::Horizontal) + { + currentSectionRect.setRect(sectionViewportPosition(nlogical), 0, + sectionSize(nlogical) + d->gridLineWidth, c_height); + } + else + { + currentSectionRect.setRect(0, sectionViewportPosition(nlogical), + c_width, sectionSize(nlogical) + d->gridLineWidth); + } + + currentSectionRect.translate(c_offset); + + QVariant variant = d->m_model->headerData(nlogical, d->orientation, Qt::FontRole); + + if (variant.isValid() && variant.canConvert()) + { + QFont sectionFont = qvariant_cast(variant); + painter.setFont(sectionFont); + } + + paintSection(&painter, currentSectionRect, nlogical); + painter.restore(); + } + + if (bIsFilter && 0 == nstart && nend > nstart && nend < d->sectionCount() - 1) + //&& e->rect().width() > sectionSize(start) + sectionSize(end) ) + { + paintSection(nend + 1); + } + +// if (d->fixedCount > 0) + { + painter.setClipRect(fixedRect); + int ncurrentPos = 0; + + for (int i = 0; i < d->fixedCount; i++) + { + if (d->isVisualIndexHidden(i)) + { + continue; + } + + painter.save(); + + if (d->orientation == Qt::Horizontal) + { + currentSectionRect.setRect(ncurrentPos , 0, sectionSize(i) + d->gridLineWidth, c_height); + } + else + { + currentSectionRect.setRect(0, ncurrentPos , c_width, sectionSize(i) + d->gridLineWidth); + } + + QVariant variant = d->m_model->headerData(i, d->orientation, Qt::FontRole); + + if (variant.isValid() && variant.canConvert()) + { + QFont sectionFont = qvariant_cast(variant); + painter.setFont(sectionFont); + } + + paintSection(&painter, currentSectionRect, i); + painter.restore(); + ncurrentPos += (sectionSize(i) + d->gridLineWidth); + } + } +} + +void GlodonHeaderView::mousePressEvent(QMouseEvent *e) +{ + Q_D(GlodonHeaderView); + + d->m_isMouseDoubleClick = false; + + if (d->m_state != GlodonHeaderViewPrivate::NoState || e->button() != Qt::LeftButton) + { + return; + } + + int npos = d->orientation == Qt::Horizontal ? e->x() : e->y(); + int nhandle = d->sectionHandleAt(npos); + + d->originalSize = -1; // clear the stored original size + + if (nhandle == -1) + { + d->pressed = logicalIndexAt(npos); + + if (d->clickableSections) + { + emit sectionPressed(d->pressed); + } + + if (d->movableSections) + { + d->section = d->target = d->pressed; + + //现不做限制,即使是显示树形结构的列,也可以移动 + if (d->section == -1 || d->section < d->fixedCount) + { + return; + } + + d->m_state = GlodonHeaderViewPrivate::MoveSection; + d->setupSectionIndicator(d->section, npos); + } + else if (d->clickableSections && d->pressed != -1) + { + updateSection(d->pressed); + d->m_state = GlodonHeaderViewPrivate::SelectSections; + } + } + else if ((resizeMode(nhandle) == Interactive) && (npos < length())) + { + d->m_mousePosition = e->pos(); + //当第一次按下时,获取的是鼠标所在屏幕的位置,方便tableview中的InfoFrame的正确移动 + QPoint point = e->screenPos().toPoint(); + emit sectionResizing(point, orientation(), Press); + + d->viewport->update(d->m_mousePosition.x(), 0, 1, height()); + d->originalSize = sectionSize(nhandle); + d->m_state = GlodonHeaderViewPrivate::ResizeSection; + d->section = nhandle; + d->preventCursorChangeInSetOffset = false; + } + + d->firstPos = npos; + d->lastPos = npos; + + d->clearCascadingSections(); +} + +void GlodonHeaderView::mouseMoveEvent(QMouseEvent *e) +{ + Q_D(GlodonHeaderView); + int npos = d->orientation == Qt::Horizontal ? e->x() : e->y(); + +// if (pos < 0) +// { +// return; +// } + if (e->buttons() == Qt::NoButton) + { + d->m_state = GlodonHeaderViewPrivate::NoState; + d->pressed = -1; + } + + switch (d->m_state) + { + case GlodonHeaderViewPrivate::ResizeSection: + { + Q_ASSERT(d->originalSize != -1); + emit sectionResizing(d->m_mousePosition, orientation(), Move); + d->m_mousePosition = e->pos(); + d->viewport->update(); + + if (!d->resizeDelay) + { + if (d->cascadingResizing) + { + int ndelta = d->reverse() ? d->lastPos - npos : npos - d->lastPos; + int nVisualIndex = visualIndex(d->section); + d->cascadingResize(nVisualIndex, d->headerSectionSize(nVisualIndex) + ndelta, true); + } + else + { + int ndelta = d->reverse() ? d->firstPos - npos : npos - d->firstPos; + resizeSection(d->section, qMax(d->originalSize + ndelta, minimumSectionSize()), true, true); + } + } + + d->lastPos = npos; + return; + } + + case GlodonHeaderViewPrivate::MoveSection: + { + if (d->shouldAutoScroll(e->pos())) + { + d->startAutoScroll(); + } + + if (qAbs(npos - d->firstPos) >= QApplication::startDragDistance() + || !d->sectionIndicator->isHidden()) + { + updateTargetSectionRecord(npos); + d->updateSectionIndicator(d->section, npos); + } + + return; + } + + case GlodonHeaderViewPrivate::SelectSections: + { + int nlogical = logicalIndexAt(npos); + + if (nlogical == d->pressed) + { + return; // nothing to do + } + else if (d->pressed != -1) + { + updateSection(d->pressed); + } + + d->pressed = nlogical; + + if (d->clickableSections && nlogical != -1) + { + emit sectionEntered(d->pressed); + updateSection(d->pressed); + } + + return; + } + + case GlodonHeaderViewPrivate::NoState: + { +#ifndef QT_NO_CURSOR + int nhandle = d->sectionHandleAt(npos); + bool bhasCursor = testAttribute(Qt::WA_SetCursor); + + if (nhandle != -1 && resizeMode(nhandle) == Interactive && npos < length()) + { + bool bInState = getSectionHandleAt(npos) != -1; + + if (bInState) + { + setCursor(d->orientation == Qt::Horizontal ? Qt::SplitHCursor : Qt::SplitVCursor); + } + } + else if (bhasCursor) + { + unsetCursor(); + } + +#endif + return; + } + + default: + break; + } +} + +void GlodonHeaderView::mouseReleaseEvent(QMouseEvent *e) +{ + Q_D(GlodonHeaderView); + int npos = d->orientation == Qt::Horizontal ? e->x() : e->y(); + + switch (d->m_state) + { + case GlodonHeaderViewPrivate::MoveSection: + { + if (!d->sectionIndicator->isHidden()) + { + // moving + bool bcanMove = true; + + int nfrom = visualIndex(d->section); + Q_ASSERT(nfrom != -1); + int nto = visualIndex(d->target); + Q_ASSERT(nto != -1); + + if (d->target < d->fixedCount) + { + d->updateSectionIndicator(-1, npos); + break; + } + + emit canSectionMove(d->section, d->target, bcanMove); + + if (d->m_logicalMovable) + { + d->section = d->target = -1; + d->updateSectionIndicator(d->section, npos); + break; + } + + if (bcanMove) + { + moveSection(nfrom, nto); + d->section = d->target = -1; + d->updateSectionIndicator(d->section, npos); + break; + } + else + { + d->sectionIndicator->hide(); + break; + } + } // not moving + +// break; + } + + case GlodonHeaderViewPrivate::SelectSections: + { + if (!d->clickableSections) + { + int nsection = logicalIndexAt(npos); + updateSection(nsection); + } + +// break; + // fall through + } + + case GlodonHeaderViewPrivate::NoState: + { + if (d->clickableSections) + { + int nsection = logicalIndexAt(npos); + + if (nsection != -1 && nsection == d->pressed) + { + d->flipSortIndicator(nsection); + emit sectionClicked(nsection); + } + + if (d->pressed != -1) + { + updateSection(d->pressed); + } + } + + break; + } + + case GlodonHeaderViewPrivate::ResizeSection: + { + if (d->resizeDelay && !d->m_isMouseDoubleClick) + { + if (d->cascadingResizing) + { + int ndelta = d->reverse() ? d->lastPos - npos : npos - d->lastPos; + int nVisualIndex = visualIndex(d->section); + d->cascadingResize(nVisualIndex, d->headerSectionSize(nVisualIndex) + ndelta, true); + } + else + { + int ndelta = d->reverse() ? d->firstPos - npos : npos - d->firstPos; + resizeSection(d->section, qMax(d->originalSize + ndelta, minimumSectionSize()), true, true); + } + } + + emit sectionResizing(d->m_mousePosition, orientation(), Finish); + + if (orientation() == Qt::Horizontal) + { + d->viewport->update(d->m_mousePosition.x(), 0, 1, height()); + } + else + { + d->viewport->update(0, d->m_mousePosition.y(), width(), 1); + } + + d->originalSize = -1; + d->clearCascadingSections(); + break; + } + + default: + break; + } + + d->m_state = GlodonHeaderViewPrivate::NoState; + d->pressed = -1; +} + +void GlodonHeaderView::mouseDoubleClickEvent(QMouseEvent *e) +{ + Q_D(GlodonHeaderView); + + if (!d->m_allowDoubleClicked) + { + return; + } + + int npos = d->orientation == Qt::Horizontal ? e->x() : e->y(); + int nhandle = d->sectionHandleAt(npos); + d->m_isMouseDoubleClick = true; + + if (nhandle > -1 && resizeMode(nhandle) == Interactive) + { + emit sectionHandleDoubleClicked(nhandle); +#ifndef QT_NO_CURSOR + Qt::CursorShape splitCursor = (d->orientation == Qt::Horizontal) + ? Qt::SplitHCursor : Qt::SplitVCursor; + + if (cursor().shape() == splitCursor) + { + // signal handlers may have changed the section size + nhandle = d->sectionHandleAt(npos); + + if (!(nhandle > -1 && resizeMode(nhandle) == Interactive)) + { + setCursor(Qt::ArrowCursor); + } + } + +#endif + } + else + { + emit sectionDoubleClicked(logicalIndexAt(e->pos())); + } +} + +bool GlodonHeaderView::viewportEvent(QEvent *e) +{ + Q_D(GlodonHeaderView); + + switch (e->type()) + { +#ifndef QT_NO_TOOLTIP + + case QEvent::ToolTip: + { + QHelpEvent *he = static_cast(e); + int nlogical = logicalIndexAt(he->pos()); + + if (nlogical != -1) + { + QVariant variant = d->m_model->headerData(nlogical, d->orientation, Qt::ToolTipRole); + + if (variant.isValid()) + { + QToolTip::showText(he->globalPos(), variant.toString(), this); + return true; + } + } + + break; + } + +#endif +#ifndef QT_NO_WHATSTHIS + + case QEvent::QueryWhatsThis: + { + QHelpEvent *he = static_cast(e); + int nlogical = logicalIndexAt(he->pos()); + + if (nlogical != -1 + && d->m_model->headerData(nlogical, d->orientation, Qt::WhatsThisRole).isValid()) + { + return true; + } + + break; + } + + case QEvent::WhatsThis: + { + QHelpEvent *he = static_cast(e); + int nlogical = logicalIndexAt(he->pos()); + + if (nlogical != -1) + { + QVariant whatsthis = d->m_model->headerData(nlogical, d->orientation, + Qt::WhatsThisRole); + + if (whatsthis.isValid()) + { + QWhatsThis::showText(he->globalPos(), whatsthis.toString(), this); + return true; + } + } + + break; + } + +#endif // QT_NO_WHATSTHIS +#ifndef QT_NO_STATUSTIP + + case QEvent::StatusTip: + { + QHelpEvent *he = static_cast(e); + int nlogical = logicalIndexAt(he->pos()); + + if (nlogical != -1) + { + QString statustip = d->m_model->headerData(nlogical, d->orientation, + Qt::StatusTipRole).toString(); + + if (!statustip.isEmpty()) + { + setStatusTip(statustip); + } + } + + return true; + } + +#endif // QT_NO_STATUSTIP + + case QEvent::Hide: + { + d->invalidateCachedSizeHint(); + emit geometriesChanged(); + + break; + } + + case QEvent::Show: + case QEvent::FontChange: + case QEvent::StyleChange: + d->invalidateCachedSizeHint(); + emit geometriesChanged(); + break; + + case QEvent::ContextMenu: + { + d->m_state = GlodonHeaderViewPrivate::NoState; + d->pressed = d->section = d->target = -1; + d->updateSectionIndicator(d->section, -1); + break; + } + + case QEvent::Wheel: + { + QAbstractScrollArea *asa = dynamic_cast(parentWidget()); + + if (asa) + { + return QApplication::sendEvent(asa->viewport(), e); + } + + break; + } + + default: + break; + } + + return GlodonAbstractItemView::viewportEvent(e); +} + +void GlodonHeaderView::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const +{ + Q_D(const GlodonHeaderView); + + if (!rect.isValid()) + { + return; + } + + QStyleOptionHeader opt; + initStyleOption(&opt); + QStyle::State state = QStyle::State_None; + bool bDrawHighLight = false; + + if (isEnabled()) + { + state |= QStyle::State_Enabled; + } + + if (window()->isActiveWindow()) + { + state |= QStyle::State_Active; + } + + if (d->clickableSections) + { + if (logicalIndex == d->m_hover) + { + state |= QStyle::State_MouseOver; + } + + if (logicalIndex == d->pressed) + { + state |= QStyle::State_Sunken; + } + else if (d->highlightSelected) + { + if (d->isSectionSelected(logicalIndex)) + { + state |= QStyle::State_Sunken; + } + else if (d->sectionIntersectsSelection(logicalIndex)) + { + if (d->m_boldWithSelected) + { + state |= QStyle::State_On; + } + + if (!(state & QStyle::State_Sunken)) + { + bDrawHighLight = true; + } + } + } + } + + if (isSortIndicatorShown() && sortIndicatorSection() == logicalIndex) + { + if (sortIndicatorOrder() == Qt::AscendingOrder) + { + opt.sortIndicator = QStyleOptionHeader::SortDown; + } + else if (sortIndicatorOrder() == Qt::DescendingOrder) + { + opt.sortIndicator = QStyleOptionHeader::SortUp; + } + else + { + opt.sortIndicator = QStyleOptionHeader::None; + } + } + + // setup the style options structure + QVariant textAlignment = d->m_model->headerData(logicalIndex, d->orientation, + Qt::TextAlignmentRole); + opt.rect = rect; + opt.section = logicalIndex; + opt.state |= state; + +// opt.textAlignment = Qt::Alignment(textAlignment.isValid() +// ? Qt::Alignment(textAlignment.toInt()) +// : d->defaultAlignment); + if (textAlignment.isValid() && ((textAlignment.toInt() & Qt::AlignHorizontal_Mask) != 0)) + { + opt.textAlignment = Qt::Alignment(textAlignment.toInt()); + } + else + { + opt.textAlignment = Qt::AlignCenter; + } + + opt.textAlignment = Qt::AlignmentFlag(int(opt.textAlignment) | int(Qt::TextWordWrap)); + + opt.iconAlignment = Qt::AlignVCenter; + QVariant iconAlignment = d->m_model->headerData(logicalIndex, d->orientation, + Qt::DecorationPropertyRole); + + if (iconAlignment.isValid()) + { + opt.iconAlignment = (Qt::Alignment)iconAlignment.toInt(); + } + + if (d->autoSectionData) + { + opt.text = QString::number(visualIndex(logicalIndex) + 1); + } + else + { + opt.text = d->m_model->headerData(logicalIndex, d->orientation, + Qt::DisplayRole).toString(); + } + + if (d->m_textElideMode != Qt::ElideNone) + { + opt.text = opt.fontMetrics.elidedText(opt.text, d->m_textElideMode , rect.width() - 4); + } + + QVariant variant = d->m_model->headerData(logicalIndex, d->orientation, + Qt::DecorationRole); + opt.icon = qvariant_cast(variant); + + if (opt.icon.isNull()) + { + opt.icon = qvariant_cast(variant); + } + + QVariant foregroundBrush = d->m_model->headerData(logicalIndex, d->orientation, + Qt::ForegroundRole); + + if (foregroundBrush.canConvert()) + { + opt.palette.setBrush(QPalette::ButtonText, qvariant_cast(foregroundBrush)); + } + + QPointF oldBO = painter->brushOrigin(); + QVariant backgroundBrush = d->m_model->headerData(logicalIndex, d->orientation, + Qt::BackgroundRole); + + if (backgroundBrush.canConvert()) + { + opt.palette.setBrush(QPalette::Button, qvariant_cast(backgroundBrush)); + opt.palette.setBrush(QPalette::Window, qvariant_cast(backgroundBrush)); + painter->setBrushOrigin(opt.rect.topLeft()); + } + + // the section position + int nVisual = visualIndex(logicalIndex); + Q_ASSERT(nVisual != -1); + + bool first = d->isFirstVisibleSection(nVisual); + bool last = d->isLastVisibleSection(nVisual); + + if (first && last) + { + opt.position = QStyleOptionHeader::OnlyOneSection; + } + else if (first) + { + opt.position = QStyleOptionHeader::Beginning; + } + else if (last) + { + opt.position = QStyleOptionHeader::End; + } + else + { + opt.position = QStyleOptionHeader::Middle; + } + + opt.orientation = d->orientation; + // the selected position + bool bPreviousSelected = d->isSectionSelected(this->logicalIndex(nVisual - 1)); + bool bNextSelected = d->isSectionSelected(this->logicalIndex(nVisual + 1)); + + if (bPreviousSelected && bNextSelected) + { + opt.selectedPosition = QStyleOptionHeader::NextAndPreviousAreSelected; + } + else if (bPreviousSelected) + { + opt.selectedPosition = QStyleOptionHeader::PreviousIsSelected; + } + else if (bNextSelected) + { + opt.selectedPosition = QStyleOptionHeader::NextIsSelected; + } + else + { + opt.selectedPosition = QStyleOptionHeader::NotAdjacent; + } + + if (bDrawHighLight) + { + drawCellBorder(painter, opt); + + if (d->fixedCellEvent) + { + paintHighLightSection(painter, opt, rect); + } + else + { + paintSectionOnQt(painter, opt, this, true); + } + } + else + { + // drawHighlight为false时,只将表头字体加粗 + if (d->sectionIntersectsSelection(logicalIndex)) + { + QFont fnt = painter->font(); + + if (d->m_boldWithSelected) + { + opt.state |= QStyle::State_On; + fnt.setBold(true); + } + + painter->setFont(fnt); + } + + paintSectionOnQt(painter, opt, this, false); + + if (d->fixedCellEvent) + { + fillFixedCell(painter, opt, rect, logicalIndex); + } + + drawCellBorder(painter, opt); + } + + painter->setBrushOrigin(oldBO); + + if (Qt::Horizontal == d->orientation) + { + drawImageInDesignatedLogicalIndex(painter, opt); + } +} + +void GlodonHeaderView::paintSection(int beginToHideIndex) const +{ + Q_UNUSED(beginToHideIndex); +} + +QSize GlodonHeaderView::sectionSizeFromContents(int logicalIndex) const +{ + Q_D(const GlodonHeaderView); + Q_ASSERT(logicalIndex >= 0); + + ensurePolished(); + + // use SizeHintRole + QVariant variant = d->m_model->headerData(logicalIndex, d->orientation, Qt::SizeHintRole); + + if (variant.isValid()) + { + if (!d->autoSectionData) + { + return qvariant_cast(variant); + } + } + + QStyleOptionHeader opt; + initStyleOption(&opt); + opt.section = logicalIndex; + QVariant var = d->m_model->headerData(logicalIndex, d->orientation, + Qt::FontRole); + QFont fnt; + + if (var.isValid() && var.canConvert()) + { + fnt = qvariant_cast(var); + } + else + { + fnt = font(); + } + + fnt.setBold(true); + opt.fontMetrics = QFontMetrics(fnt); + + if (d->autoSectionData) + { + opt.text = QString::number(logicalIndex + 1); + } + else + { + opt.text = d->m_model->headerData(logicalIndex, d->orientation, + Qt::DisplayRole).toString(); + } + + variant = d->m_model->headerData(logicalIndex, d->orientation, Qt::DecorationRole); + opt.icon = qvariant_cast(variant); + + if (opt.icon.isNull()) + { + opt.icon = qvariant_cast(variant); + } + + QSize size = style()->sizeFromContents(QStyle::CT_HeaderSection, &opt, QSize(), this); + + if (isSortIndicatorShown()) + { + int nMargin = style()->pixelMetric(QStyle::PM_HeaderMargin, &opt, this); + + if (d->orientation == Qt::Horizontal) + { + size.rwidth() += size.height() + nMargin; + } + else + { + size.rheight() += size.width() + nMargin; + } + } + + return size; +} + +void GlodonHeaderView::paintEmptySection(QPainter *painter, const QRect &rect) +{ + Q_D(const GlodonHeaderView); + + if (!rect.isValid()) + { + return; + } + + QStyleOptionHeader opt; + initStyleOption(&opt); + QStyle::State state = QStyle::State_None; + + if (isEnabled()) + { + state |= QStyle::State_Enabled; + } + + if (window()->isActiveWindow()) + { + state |= QStyle::State_Active; + } + + opt.rect = rect; + opt.section = 0; + opt.state |= state; + + QPointF oldBO = painter->brushOrigin(); + + opt.position = QStyleOptionHeader::OnlyOneSection; + opt.orientation = d->orientation; + + opt.selectedPosition = QStyleOptionHeader::NotAdjacent; + + style()->drawControl(QStyle::CE_Header, &opt, painter, this); + + painter->setBrushOrigin(oldBO); +} + +void GlodonHeaderView::setSortArrowOnTextTop(bool bIsSortArrowOnTextTop) +{ + m_isSortArrowOnTextTop = bIsSortArrowOnTextTop; +} + +void GlodonHeaderView::setLogicalIndexImage(QMultiHash logicalIndexHash, int spanTop) +{ + Q_D(GlodonHeaderView); + d->m_logicalIndexHash = logicalIndexHash; + d->m_spanTop = spanTop; +} + +void GlodonHeaderView::batchResizeSection(const QMap &logicalIndexSizes) +{ + Q_D(GlodonHeaderView); + d->doBatchResizeSection(logicalIndexSizes, false); +} + +void GlodonHeaderView::paintSectionSortArrow(QPainter *painter, QStyleOptionHeader &opt, const QWidget *widget) const +{ + Q_D(const GlodonHeaderView); + QStyleOptionHeader supopt = opt; + + if (supopt.sortIndicator != QStyleOptionHeader::None && Qt::Horizontal == d->orientation) + { + supopt.rect = style()->subElementRect(QStyle::SE_HeaderArrow, &opt, widget); + if (!m_isSortArrowOnTextTop) + { + int nTextWidth = painter->fontMetrics().width(supopt.text); //表头文本的宽度 + + //如果当前列宽大于文本宽度加上两倍的c_nSpacingTextToArrow再加上箭头的宽度再加上2px,则执行排序小三角的绘制。 + //最后加的2px,1px是文本本身有1px偏移,1px是右边线的宽度 + const int nOffect = 2; + const int nTextMargins = 2 * c_nSpacingTextToArrow + c_sortArrow.width() + nOffect; + + if (opt.rect.width() > nTextWidth + nTextMargins) + { + //箭头水平偏移为文本宽度的一半加上c_nSpacingTextToArrow + int nOffsetX = nTextWidth / 2 + c_nSpacingTextToArrow; + //箭头垂直偏移为表头高度的一半减去箭头高度的一半 + int nOffsetY = (opt.rect.height() - c_sortArrow.height()) / 2; + + supopt.rect.adjust(nOffsetX, nOffsetY, nOffsetX, nOffsetY); + style()->proxy()->drawPrimitive(QStyle::PE_IndicatorHeaderArrow, &supopt, painter, widget); + } + } + else + { + style()->proxy()->drawPrimitive(QStyle::PE_IndicatorHeaderArrow, &supopt, painter, widget); + } + } +} + +void GlodonHeaderView::paintSectionOnQt(QPainter *painter, QStyleOptionHeader &opt, const QWidget *widget, bool bHighLight) const +{ + Q_D(const GlodonHeaderView); + + style()->proxy()->drawControl(QStyle::CE_HeaderSection, &opt, painter, this); + + QStyleOptionHeader supopt = opt; + + //获取文本内容有效绘制区(通过Qss等 已经计算完 margin, padding的rect) + // supopt.rect = style()->subElementRect(QStyle::SE_HeaderLabel, &opt, widget); + + if (supopt.rect.isValid()) + { + if (d->m_bFontShadow) + { + painter->save(); + painter->setPen(d->m_clrFontShadow); + QFont oldFont = painter->font(); + QFont newFont; + + if (bHighLight) + { + newFont = widget->font(); + newFont.setBold(bHighLight); + } + else + { + newFont = painter->font(); //注意 获取widget的字体 可能不会使用到qss中设置字体(包括字体大小) 暂时没有好方法从QStyle中获取应该使用的字体 + } + + painter->setFont(newFont); + QRect rect = supopt.rect; + painter->drawText(rect.adjusted(1, 1, 1, 1), supopt.textAlignment, supopt.text); + painter->setFont(oldFont); + painter->restore(); + } + + style()->proxy()->drawControl(QStyle::CE_HeaderLabel, &supopt, painter, widget); +// painter->drawText(supopt.rect.adjusted(1, 1, 1, 1), supopt.textAlignment | Qt::TextWordWrap | Qt::TextWrapAnywhere, supopt.text); + } + + paintSectionSortArrow(painter, supopt, widget); //绘制排序列的表头小三角 +} + +void GlodonHeaderView::paintHighLightSection(QPainter *painter, QStyleOptionHeader &opt, const QRect &rect) const +{ + Q_D(const GlodonHeaderView); + painter->save(); + + int nGridLineWidth = 0; + QStyleOptionHeader supopt = opt; + + if (d->m_drawBorder) + { + nGridLineWidth = 1; + } + + int nWw = rect.width() - 1; + int nHh = rect.height() - 1 - nGridLineWidth; + int nlineWidth = 1; + int nXx = rect.x(); + int nYy = rect.y() + nGridLineWidth; + + if (d->m_drawBorder && (rect.x() == 0)) + { + nXx = nXx + nGridLineWidth; + nWw = nWw - nGridLineWidth; + } + + QBrush *fill = const_cast(&opt.palette.brush(QPalette::Button)); + + if (nWw == 0 || nHh == 0) + { + return; + } + + QPen oldPen = painter->pen(); + + if (fill && d->m_bLinearGradient) + { + QLinearGradient linearGradient(nXx + nWw / 2 + nlineWidth, nYy, nXx + nWw / 2 + nlineWidth, + nYy + nHh - nlineWidth * 2 - 1); + + linearGradient.setColorAt(0.3, QColor(248, 215, 153)); + linearGradient.setColorAt(0.6, QColor(245, 203, 123)); + linearGradient.setColorAt(1, QColor(242, 196, 103)); + + painter->setBrush(linearGradient); + painter->fillRect(nXx, nYy, nWw, nHh, QBrush(linearGradient)); + } + else + { + painter->fillRect(nXx, nYy, nWw, nHh, QBrush(QColor("#ffefb5"))); + } + + painter->setPen(oldPen); + + QRect headerRect = opt.rect; + int npixw = 0; + + if (!opt.icon.isNull()) + { + QPixmap pixmap = opt.icon.pixmap(style()->proxy()->pixelMetric(QStyle::PM_SmallIconSize), + (QStyle::State_Enabled == (opt.state & QStyle::State_Enabled)) + ? QIcon::Normal : QIcon::Disabled); + npixw = pixmap.width(); + + QRect aligned = style()->alignedRect(opt.direction, QFlag(opt.iconAlignment), pixmap.size(), headerRect); + QRect inter = aligned.intersected(headerRect); + + if (d->orientation == Qt::Vertical) + { + painter->drawPixmap(inter.x() + 4, inter.y(), pixmap, inter.x() - aligned.x(), inter.y() - aligned.y(), + inter.width(), inter.height()); + } + else + { + painter->drawPixmap(inter.x(), inter.y(), pixmap, inter.x() - aligned.x(), inter.y() - aligned.y(), + inter.width(), inter.height()); + } + } + + if (QStyle::State_On == (opt.state & QStyle::State_On)) + { + QFont fnt = painter->font(); + + if (d->m_boldWithSelected) + { + fnt.setBold(true); + } + else + { + opt.state &= ~QStyle::State_On; + } + + painter->setFont(fnt); + } + + if (npixw != 0 && d->orientation == Qt::Vertical)//如果是垂直表头,需要加上偏移,不然选中后的问题绘制不正确 + { + headerRect.setLeft(headerRect.left() + npixw + 2); + } + + opt.rect = textRect(rect); + style()->proxy()->drawItemText(painter, headerRect, opt.textAlignment, opt.palette, + QStyle::State_Enabled == (opt.state & QStyle::State_Enabled), + opt.text, QPalette::ButtonText); + opt.rect = rect; + + //如果当前列为排序指示列,则画上小三角 + if (isSortIndicatorShown() && sortIndicatorSection() == opt.section) + { + QRegion clipRegion = painter->clipRegion(); + + paintSectionSortArrow(painter, supopt, this); + + painter->setClipRegion(clipRegion); + } + + painter->restore(); +} + +//自定义固定格背景色填充 +void GlodonHeaderView::fillFixedCell(QPainter *painter, QStyleOptionHeader &opt, QRect rect, int logicalIndex) const +{ + Q_D(const GlodonHeaderView); + + if (d->fixedCellsColor.contains(logicalIndex) + && d->fixedCellsColor.value(logicalIndex).orientation == d->orientation) + { + rect.adjust(0, 0, -1, -1); + QColor bkGround = d->fixedCellsColor.value(logicalIndex).background; + + painter->fillRect(rect, bkGround); + + style()->proxy()->drawItemText(painter, opt.rect, opt.textAlignment, opt.palette, + (QStyle::State_Enabled == (opt.state & QStyle::State_Enabled)), + opt.text, QPalette::ButtonText); + } +} + +int GlodonHeaderView::horizontalOffset() const +{ + Q_D(const GlodonHeaderView); + + if (d->orientation == Qt::Horizontal) + { + return d->offset; + } + + return 0; +} + +int GlodonHeaderView::verticalOffset() const +{ + Q_D(const GlodonHeaderView); + + if (d->orientation == Qt::Vertical) + { + return d->offset; + } + + return 0; +} + +void GlodonHeaderView::updateGeometries() +{ + Q_D(GlodonHeaderView); + d->layoutChildren(); +} + +void GlodonHeaderView::scrollContentsBy(int dx, int dy) +{ + Q_D(GlodonHeaderView); + d->scrollDirtyRegion(dx, dy); +} + +void GlodonHeaderView::rowsInserted(const QModelIndex &, int, int) +{ + // do nothing +} + +QRect GlodonHeaderView::visualRect(const QModelIndex &) const +{ + return QRect(); +} + +void GlodonHeaderView::scrollTo(const QModelIndex &index, ScrollHint hint) +{ + Q_UNUSED(index); + Q_UNUSED(hint); +} + +QModelIndex GlodonHeaderView::indexAt(const QPoint &) const +{ + return QModelIndex(); +} + +bool GlodonHeaderView::isIndexHidden(const QModelIndex &) const +{ + return true; // the header view has no items, just sections +} + +bool GlodonHeaderView::isAllSectionHidden() const +{ + for (int i = 0; i < count(); i++) + { + if (!isSectionHidden(i)) + { + return false; + } + } + + return true; +} + +QModelIndex GlodonHeaderView::moveCursor(CursorAction, Qt::KeyboardModifiers) +{ + return QModelIndex(); +} + +void GlodonHeaderView::setSelection(const QRect &, QItemSelectionModel::SelectionFlags) +{ + // do nothing +} + +QRegion GlodonHeaderView::visualRegionForSelection(const QItemSelection &selection) const +{ + Q_D(const GlodonHeaderView); + const int c_max = d->modelSectionCount(); + const int c_selectionCount = selection.count(); + + if (d->orientation == Qt::Horizontal) + { + int nLeft = c_max; + int nRight = 0; + int nrangeLeft(0); + int nrangeRight(0); + + for (int i = 0; i < c_selectionCount; ++i) + { + QItemSelectionRange tmpRange = selection.at(i); + + if (tmpRange.parent().isValid() || !tmpRange.isValid()) + { + continue; // we only know about toplevel items and we don't want invalid ranges + } + + // FIXME an item inside the range may be the leftmost or rightmost + nrangeLeft = visualIndex(tmpRange.left()); + + if (nrangeLeft == -1) // in some cases users may change the selections + { + continue; // before we have a chance to do the layout + } + + nrangeRight = visualIndex(tmpRange.right()); + + if (nrangeRight == -1) // in some cases users may change the selections + { + continue; // before we have a chance to do the layout + } + + if (nrangeLeft < nLeft) + { + nLeft = nrangeLeft; + } + + if (nrangeRight > nRight) + { + nRight = nrangeRight; + } + } + + int nLogicalLeft = logicalIndex(nLeft); + int nLogicalRight = logicalIndex(nRight); + + if (nLogicalLeft < 0 || nLogicalLeft >= count() + || nLogicalRight < 0 || nLogicalRight >= count()) + { + return QRegion(); + } + + int nLeftPos = sectionViewportPosition(nLogicalLeft); + int nRightPos = sectionViewportPosition(nLogicalRight); + nRightPos += sectionSize(nLogicalRight); + return QRect(nLeftPos, 0, nRightPos - nLeftPos, height()); + } + + // orientation() == Qt::Vertical + int nTop = c_max; + int nBottom = 0; + int nRangeTop(0); + int nRangeBottom(0); + + for (int i = 0; i < c_selectionCount; ++i) + { + QItemSelectionRange tmpRange = selection.at(i); + + if (tmpRange.parent().isValid() || !tmpRange.isValid()) + { + continue; // we only know about toplevel items + } + + // FIXME an item inside the range may be the leftmost or rightmost + nRangeTop = visualIndex(tmpRange.top()); + + if (nRangeTop == -1) // in some cases users may change the selections + { + continue; // before we have a chance to do the layout + } + + nRangeBottom = visualIndex(tmpRange.bottom()); + + if (nRangeBottom == -1) // in some cases users may change the selections + { + continue; // before we have a chance to do the layout + } + + if (nRangeTop < nTop) + { + nTop = nRangeTop; + } + + if (nRangeBottom > nBottom) + { + nBottom = nRangeBottom; + } + } + + int nlogicalTop = logicalIndex(nTop); + int nlogicalBottom = logicalIndex(nBottom); + + if (nlogicalTop == -1 || nlogicalBottom == -1) + { + return QRect(); + } + + int ntopPos = sectionViewportPosition(nlogicalTop); + int nbottomPos = sectionViewportPosition(nlogicalBottom) + sectionSize(nlogicalBottom); + + return QRect(0, ntopPos, width(), nbottomPos - ntopPos); +} + +// private implementation + +int GlodonHeaderViewPrivate::sectionHandleAt(int position) +{ + Q_Q(GlodonHeaderView); + int nVisualIndex = q->visualIndexAt(position); + + if (nVisualIndex == -1) + { + return -1; + } + + int nlog = logicalIndex(nVisualIndex); + int npos = q->sectionViewportPosition(nlog); + int ngrip = q->style()->pixelMetric(QStyle::PM_HeaderGripMargin, 0, q); + + bool batLeft = position < npos + ngrip; + bool batRight = (position > npos + q->sectionSize(nlog) - ngrip); + + if (reverse()) + { + qSwap(batLeft, batRight); + } + + if (batLeft) + { + //grip at the beginning of the section + while (nVisualIndex > -1) + { + int nlogical = q->logicalIndex(--nVisualIndex); + + if (!q->isSectionHidden(nlogical)) + { + return nlogical; + } + } + } + else if (batRight) + { + //grip at the end of the section + return nlog; + } + + return -1; +} + +void GlodonHeaderViewPrivate::setupSectionIndicator(int section, int position) +{ + Q_Q(GlodonHeaderView); + + if (!sectionIndicator) + { + sectionIndicator = new QLabel(viewport); + } + + int nWidth(0); + int nHeight(0); + int np = q->sectionViewportPosition(section); + + if (orientation == Qt::Horizontal) + { + nWidth = q->sectionSize(section); + nHeight = viewport->height(); + } + else + { + nWidth = viewport->width(); + nHeight = q->sectionSize(section); + } + + sectionIndicator->resize(nWidth, nHeight); + + QPixmap pm(nWidth, nHeight); + pm.fill(QColor(0, 0, 0, 45)); + QRect rect(0, 0, nWidth, nHeight); + + QPainter painter(&pm); + painter.setOpacity(0.75); + q->paintSection(&painter, rect, section); + painter.end(); + + sectionIndicator->setPixmap(pm); + sectionIndicatorOffset = position - qMax(np, 0); +} + +void GlodonHeaderViewPrivate::updateSectionIndicator(int section, int position) +{ + if (!sectionIndicator) + { + return; + } + + if (section == -1 || target == -1) + { + sectionIndicator->hide(); + return; + } + + if (orientation == Qt::Horizontal) + { + sectionIndicator->move(position - sectionIndicatorOffset, 0); + } + else + { + sectionIndicator->move(0, position - sectionIndicatorOffset); + } + + sectionIndicator->show(); +} + +void GlodonHeaderView::initStyleOption(QStyleOptionHeader *option) const +{ + Q_D(const GlodonHeaderView); + + option->initFrom(this); + option->state = QStyle::State_None | QStyle::State_Raised; + option->orientation = d->orientation; + + if (d->orientation == Qt::Horizontal) + { + option->state |= QStyle::State_Horizontal; + } + + if (isEnabled()) + { + option->state |= QStyle::State_Enabled; + } + + option->section = 0; +} + +void GlodonHeaderView::_q_sectionsRemoved(const QModelIndex &parent, int logicalFirst, int logicalLast) +{ + d_func()->_q_sectionsRemoved(parent, logicalFirst, logicalLast); +} + +void GlodonHeaderView::_q_layoutAboutToBeChanged() +{ + d_func()->_q_layoutAboutToBeChanged(); +} + +void GlodonHeaderView::updateTargetSectionRecord(int pos) +{ + Q_D(GlodonHeaderView); + int nVisualIndex = visualIndexAt(pos); + + if (nVisualIndex == -1) + { + return; + } + + int nposThreshold = d->headerSectionPosition(nVisualIndex) + d->headerSectionSize(nVisualIndex) / 2; + int nmoving = visualIndex(d->section); + + if (nVisualIndex < nmoving) + { + if (pos < nposThreshold) + { + d->target = d->logicalIndex(nVisualIndex); + } + else + { + d->target = d->logicalIndex(nVisualIndex + 1); + } + } + else if (nVisualIndex > nmoving) + { + if (pos > nposThreshold) + { + d->target = d->logicalIndex(nVisualIndex - 1); + } + else + { + d->target = d->logicalIndex(nVisualIndex); + } + } + else + { + d->target = d->section; + } +} + +void GlodonHeaderView::drawCellBorder(QPainter *painter, QStyleOptionHeader &opt) const +{ + Q_D(const GlodonHeaderView); + // m_drawBorder为true, 手动画边线, 否则调用Qt中画HeaderSection的方法画边线 + if (d->m_drawBorder) + { + QRect topBorderRect(QRect(QPoint(opt.rect.left(), opt.rect.top()), QSize(opt.rect.width(), 1))); + QRect leftBorderRect(QRect(QPoint(opt.rect.left(), opt.rect.top()), QSize(1, opt.rect.height()))); + QRect bottemBorderRect(QRect(QPoint(opt.rect.left(), opt.rect.bottom()), QSize(opt.rect.width(), 1))); + QRect rightBorderRect(QRect(QPoint(opt.rect.right(), opt.rect.top()), QSize(1, opt.rect.height()))); + // 画上边线和左边线, 水平表头只有第一个section画左边线, 垂直表头只有第一个section画上边线 + if (Qt::Horizontal == d->orientation) + { + painter->fillRect(topBorderRect, QColor(0, 0, 0)); + + if (opt.rect.left() < 2) + { + painter->fillRect(leftBorderRect, QColor(0, 0, 0)); + } + } + else + { + if (opt.rect.top() < 2) + { + painter->fillRect(topBorderRect, QColor(0, 0, 0)); + } + + painter->fillRect(leftBorderRect, QColor(0, 0, 0)); + } + + painter->fillRect(bottemBorderRect, QColor(0, 0, 0)); + + painter->fillRect(rightBorderRect, QColor(0, 0, 0)); + } +} + +QRect GlodonHeaderView::textRect(const QRect &rect) const +{ + Q_D(const GlodonHeaderView); + QVariant margin = d->m_model->headerData(0, d->orientation, + gidrCellMargin); + QRect newRect = rect; + + if (margin.isValid()) + { + int nMargin = margin.toInt(); +// newRect.adjust((nMargin & 0x00FF0000) >> 16, (nMargin & 0x000000FF) / 2, +// -(nMargin & 0x00FF0000) >> 16, -(nMargin & 0x000000FF) / 2); + newRect.adjust((nMargin & 0x00FF0000) >> 16, 0, + -(nMargin & 0x00FF0000) >> 16, 0); + + } + + return newRect; +} + +bool GlodonHeaderViewPrivate::isSectionSelected(int section) const +{ + int nIndex = section * 2; + + if (nIndex < 0 || nIndex >= sectionSelected.count()) + { + return false; + } + + if (sectionSelected.testBit(nIndex)) // if the value was cached + { + return sectionSelected.testBit(nIndex + 1); + } + + bool bStat = false; + + if (orientation == Qt::Horizontal) + { + bStat = isColumnSelected(section); + } + else + { + bStat = isRowSelected(section); + } + + sectionSelected.setBit(nIndex + 1, bStat); // selection state + sectionSelected.setBit(nIndex, true); // cache state + return bStat; +} + +bool GlodonHeaderViewPrivate::isFirstVisibleSection(int section) const +{ + if (sectionStartposRecalc) + { + recalcSectionStartPos(); + } + + const SectionItem &item = sectionItems.at(section); + + return item.size > 0 && item.calculated_startpos == 0; +} + +bool GlodonHeaderViewPrivate::isLastVisibleSection(int section) const +{ + if (sectionStartposRecalc) + { + recalcSectionStartPos(); + } + + const SectionItem &item = sectionItems.at(section); + + return item.size > 0 && item.calculatedEndPos() == length; +} + +int GlodonHeaderViewPrivate::modelSectionCount() const +{ + if (orientation == Qt::Horizontal) + { + return m_model->columnCount(m_root); + } + else + { + return m_model->rowCount(m_root); + } +} + +int GlodonHeaderViewPrivate::lastVisibleVisualIndex() const +{ + Q_Q(const GlodonHeaderView); + + for (int i = q->count() - 1; i >= 0; --i) + { + if (!q->isSectionHidden(q->logicalIndex(i))) + { + return i; + } + } + + //default value if no section is actually visible + return -1; +} + +void GlodonHeaderViewPrivate::resizeSectionItem(int newSize, SectionItem &oCurrentSectionItem) +{ + if (newSize != 0 && oCurrentSectionItem.size == 0) + { + length += gridLineWidth; + } + else if (newSize == 0 && oCurrentSectionItem.size != 0) + { + length -= gridLineWidth; + } + + length += (newSize - oCurrentSectionItem.size); + oCurrentSectionItem.size = newSize; +} + +void GlodonHeaderViewPrivate::excludeNotNeedHideSections( + const QSet &logicalIndexs, bool hide, QSet> &oNeedHideLogicalAndVisualIndexs) +{ + Q_Q(GlodonHeaderView); + + foreach (int nCurLogicalIndex, logicalIndexs) + { + if (q->isInValidLogicalIndex(nCurLogicalIndex)) + continue; + + int nVisualIndex = visualIndex(nCurLogicalIndex); + Q_ASSERT(nVisualIndex != -1); + if (hide == isVisualIndexHidden(nVisualIndex)) + continue; + + oNeedHideLogicalAndVisualIndexs.insert(QPair(nCurLogicalIndex, nVisualIndex)); + } +} + +void GlodonHeaderViewPrivate::doBatchResizeSection(const QMap &logicalIndexSizes, bool isInHiddenSection) +{ + Q_Q(GlodonHeaderView); + + QMap::const_iterator oSizeIte = logicalIndexSizes.begin(); + + GlodonHeaderViewPrivate::SectionItem *sectiondata = sectionItems.data(); + + while (oSizeIte != logicalIndexSizes.end()) + { + if (!isInHiddenSection && q->isSectionHidden(oSizeIte.key())) + { + hiddenSectionSize.insert(oSizeIte.value(), oSizeIte.key()); + } + else + { + resizeSectionItem(oSizeIte.value(), sectiondata[oSizeIte.key()]); + } + oSizeIte++; + } + + invalidateCachedSizeHint(); + recalcSectionStartPos(); + viewport->update(); +} + +void GlodonHeaderViewPrivate::createSectionItems(int start, int end, int size, GlodonHeaderView::ResizeMode mode) +{ + int sizePerSection = size / (end - start + 1); + + if (end >= sectionItems.count()) + { + sectionItems.resize(end + 1); + } + + SectionItem *sectiondata = sectionItems.data(); + + for (int i = start; i <= end; ++i) + { + sectionStartposRecalc |= (sectiondata[i].size != sizePerSection); + resizeSectionItem(sizePerSection, sectiondata[i]); + sectiondata[i].resizeMode = mode; + } +} + +void GlodonHeaderViewPrivate::removeSectionsFromSectionItems(int start, int end) +{ + // remove sections + sectionStartposRecalc |= (end != sectionItems.count() - 1); + + int removedlength = 0; + + for (int u = start; u <= end; ++u) + { + removedlength += sectionItems.at(u).size; + + if (sectionItems.at(u).size != 0) + { + removedlength += gridLineWidth; + } + } + + length -= removedlength; + + sectionItems.remove(start, end - start + 1); +} + +void GlodonHeaderViewPrivate::clear() +{ + if (m_state != NoClear) + { + length = 0; + visualIndices.clear(); + logicalIndices.clear(); + sectionSelected.clear(); + sectionHidden.clear(); + hiddenSectionSize.clear(); + sectionItems.clear(); + } +} + +void GlodonHeaderViewPrivate::flipSortIndicator(int section) +{ + Q_Q(GlodonHeaderView); + Qt::SortOrder sortOrder; + + if (sortIndicatorSection == section) + { + sortOrder = (sortIndicatorOrder == Qt::DescendingOrder) ? Qt::AscendingOrder : Qt::DescendingOrder; + } + else + { + // const QVariant value = model->headerData(section, orientation, Qt::InitialSortOrderRole); + // if (value.canConvert(QVariant::Int)) + // { + // sortOrder = static_cast(value.toInt()); + // } + // else + // { + sortOrder = Qt::AscendingOrder; + // } + } + + q->setSortIndicator(section, sortOrder); +} + +void GlodonHeaderViewPrivate::cascadingResize(int visual, int newSize, bool isManual) +{ + Q_Q(GlodonHeaderView); + const int c_minimumSize = q->minimumSectionSize(); + const int c_oldSize = headerSectionSize(visual); + int ndelta = newSize - c_oldSize; + + if (ndelta > 0) // larger + { + bool bsectionResized = false; + + // restore old section sizes + for (int i = firstCascadingSection; i < visual; ++i) + { + if (cascadingSectionSize.contains(i)) + { + int ncurrentSectionSize = headerSectionSize(i); + int noriginalSectionSize = cascadingSectionSize.value(i); + + if (ncurrentSectionSize < noriginalSectionSize) + { + int newSectionSize = ncurrentSectionSize + ndelta; + resizeSectionItem(i, ncurrentSectionSize, newSectionSize, isManual); + + if (newSectionSize >= noriginalSectionSize && false) + { + cascadingSectionSize.remove(i); // the section is now restored + } + + bsectionResized = true; + break; + } + } + + } + + // resize the section + if (!bsectionResized) + { + newSize = qMax(newSize, c_minimumSize); + + if (c_oldSize != newSize) + { + resizeSectionItem(visual, c_oldSize, newSize, isManual); + } + } + + // cascade the section size change + for (int i = visual + 1; i < sectionItems.count(); ++i) + { + if (!sectionIsCascadable(i)) + { + continue; + } + + int ncurrentSectionSize = headerSectionSize(i); + + if (ncurrentSectionSize <= c_minimumSize) + { + continue; + } + + int newSectionSize = qMax(ncurrentSectionSize - ndelta, c_minimumSize); + //qDebug() << "### cascading to" << i << newSectionSize - currentSectionSize << delta; + resizeSectionItem(i, ncurrentSectionSize, newSectionSize, isManual); + saveCascadingSectionSize(i, ncurrentSectionSize); + ndelta = ndelta - (ncurrentSectionSize - newSectionSize); + + //qDebug() << "new delta" << delta; + //if (newSectionSize != minimumSize) + if (ndelta <= 0) + { + break; + } + } + } + else // smaller + { + bool bsectionResized = false; + + // restore old section sizes + for (int i = lastCascadingSection; i > visual; --i) + { + if (!cascadingSectionSize.contains(i)) + { + continue; + } + + int ncurrentSectionSize = headerSectionSize(i); + int noriginalSectionSize = cascadingSectionSize.value(i); + + if (ncurrentSectionSize >= noriginalSectionSize) + { + continue; + } + + int newSectionSize = ncurrentSectionSize - ndelta; + resizeSectionItem(i, ncurrentSectionSize, newSectionSize, isManual); + + if (newSectionSize >= noriginalSectionSize && false) + { + //qDebug() << "section" << i << "restored to" << originalSectionSize; + cascadingSectionSize.remove(i); // the section is now restored + } + + bsectionResized = true; + break; + } + + // resize the section + resizeSectionItem(visual, c_oldSize, qMax(newSize, c_minimumSize), isManual); + + // cascade the section size change + if (ndelta < 0 && newSize < c_minimumSize) + { + for (int i = visual - 1; i >= 0; --i) + { + if (!sectionIsCascadable(i)) + { + continue; + } + + int nsectionSize = headerSectionSize(i); + + if (nsectionSize <= c_minimumSize) + { + continue; + } + + resizeSectionItem(i, nsectionSize, qMax(nsectionSize + ndelta, c_minimumSize), isManual); + saveCascadingSectionSize(i, nsectionSize); + break; + } + } + + // let the next section get the space from the resized section + if (!bsectionResized) + { + for (int i = visual + 1; i < sectionItems.count(); ++i) + { + if (!sectionIsCascadable(i)) + { + continue; + } + + int ncurrentSectionSize = headerSectionSize(i); + int newSectionSize = qMax(ncurrentSectionSize - ndelta, c_minimumSize); + resizeSectionItem(i, ncurrentSectionSize, newSectionSize, isManual); + break; + } + } + } + + viewport->update(viewportScrollArea()); +} + +void GlodonHeaderViewPrivate::setDefaultSectionSize(int size) +{ + Q_Q(GlodonHeaderView); + + defaultSectionSize = size; + + for (int i = 0; i < sectionItems.count(); ++i) + { + GlodonHeaderViewPrivate::SectionItem &span = sectionItems[i]; + + if (span.size > 0) + { + //we resize it if it is not hidden (ie size > 0) + const int c_newSize = size; + + if (c_newSize != span.size) + { + length += c_newSize - span.size; //the whole length is changed + const int c_oldSectionSize = span.sectionSize(); + span.size = size; + + emit q->sectionResized(logicalIndex(i), c_oldSectionSize, size, true); + } + } + } +} + +void GlodonHeaderViewPrivate::resetTreeSectionItems(const QVector &showRows) +{ + const int nNewSectionCount = modelSectionCount(); + + if (showRows.count() == nNewSectionCount) + { + SectionItem span(defaultSectionSize, GlodonHeaderView::Interactive); + sectionItems.insert(sectionItems.count(), nNewSectionCount, span); + + sectionHidden.fill(false); + } + else + { + for (int i = 0; i < showRows.count(); i++) + { + int nNextRowNo; + + if (i == showRows.count() - 1) + { + nNextRowNo = nNewSectionCount; + } + else + { + nNextRowNo = showRows[i + 1]; + } + + int nCurrRowNo = showRows[i]; + + for (int j = nCurrRowNo + 1; j < nNextRowNo; j++) + { + hiddenSectionSize.insert(j, defaultSectionSize); + } + + sectionHidden.fill(true, nCurrRowNo + 1, nNextRowNo); + sectionHidden.setBit(nCurrRowNo, false); + + SectionItem showRowSpan(defaultSectionSize, GlodonHeaderView::Interactive); + sectionItems.append(showRowSpan); + + SectionItem hideRowSpan(0, GlodonHeaderView::Interactive); + sectionItems.insert(sectionItems.count(), nNextRowNo - nCurrRowNo - 1, hideRowSpan); + } + } + + sectionStartposRecalc = true; + + length = showRows.count() * (defaultSectionSize + gridLineWidth); +} + +void GlodonHeaderViewPrivate::resetAfterTreeBuild(const QVector &showRows) +{ + const int nNewSectionCount = modelSectionCount(); + + sectionHidden.resize(nNewSectionCount); + logicalIndices.resize(nNewSectionCount); + visualIndices.resize(nNewSectionCount); + + sectionItems.clear(); + + for (int i = 0; i < nNewSectionCount; ++i) + { + logicalIndices[i] = i; + visualIndices[i] = i; + } + + if (!hiddenSectionSize.isEmpty()) + { + hiddenSectionSize.clear(); + } + + resetTreeSectionItems(showRows); + viewport->update(); +} + +int GlodonHeaderViewPrivate::headerLength() const +{ + int len = 0; + + for (int i = 0; i < sectionItems.count(); ++i) + { + len += sectionItems.at(i).size; + } + + return len; +} + +int GlodonHeaderViewPrivate::fixedSectionsSize() const +{ + Q_Q(const GlodonHeaderView); + + int nsectionsize = 0; + + for (int i = 0; i < fixedCount; i++) + { + nsectionsize += q->sectionSize(i) + gridLineWidth; + } + + return nsectionsize; +} + +void GlodonHeaderViewPrivate::resizeSectionItem(int visualIndex, int oldSize, int newSize, bool isManual) +{ + Q_Q(GlodonHeaderView); + + GlodonHeaderView::ResizeMode mode = headerSectionResizeMode(visualIndex); + + createSectionItems(visualIndex, visualIndex, newSize, mode); + + emit q->sectionResized(logicalIndex(visualIndex), oldSize, newSize, isManual); +} + +int GlodonHeaderViewPrivate::headerSectionSize(int visual) const +{ + if (visual < sectionItems.count() && visual >= 0) + { + return sectionItems.at(visual).sectionSize(); + } + + return -1; +} + +int GlodonHeaderViewPrivate::headerSectionPosition(int visual) const +{ + if (visual < sectionItems.count() && visual >= 0) + { + if (sectionStartposRecalc) + { + recalcSectionStartPos(); + } + + return sectionItems.at(visual).calculated_startpos; + } + + return -1; +} + +int GlodonHeaderViewPrivate::headerVisualIndexAt(int position) const +{ + if (sectionStartposRecalc) + { + recalcSectionStartPos(); + } + + int startidx = 0; + int endidx = sectionItems.count() - 1; + + while (startidx <= endidx) + { + int middle = (endidx + startidx) / 2; + + if (sectionItems.at(middle).calculated_startpos > position) + { + endidx = middle - 1; + } + else + { + if (sectionItems.at(middle).calculatedEndPos() < position) + { + startidx = middle + 1; + } + else // we found it. + { + return middle; + } + } + } + + return -1; +} + +void GlodonHeaderViewPrivate::setHeaderSectionResizeMode(int visual, GlodonHeaderView::ResizeMode mode) +{ + int nsize = headerSectionSize(visual); + createSectionItems(visual, visual, nsize, mode); +} + +GlodonHeaderView::ResizeMode GlodonHeaderViewPrivate::headerSectionResizeMode(int visual) const +{ + if (visual < 0 || visual >= sectionItems.count()) + { + return globalResizeMode; + } + + return static_cast(sectionItems.at(visual).resizeMode); +} + +void GlodonHeaderViewPrivate::setGlobalHeaderResizeMode(GlodonHeaderView::ResizeMode mode) +{ + globalResizeMode = mode; + + for (int i = 0; i < sectionItems.count(); ++i) + { + sectionItems[i].resizeMode = mode; + } +} + +int GlodonHeaderViewPrivate::viewSectionSizeHint(int logical) const +{ + if (GlodonAbstractItemView *view = dynamic_cast(parent)) + { + return (orientation == Qt::Horizontal + ? view->sizeHintForColumn(logical) + : view->sizeHintForRow(logical)); + } + + return 0; +} + +int GlodonHeaderViewPrivate::adjustedVisualIndex(int visualIndex) const +{ + if (hiddenSectionSize.count() > 0) + { + int nAdjustedVisualIndex = visualIndex; + int nCurrentVisualIndex = 0; + + for (int i = 0; i < sectionItems.count(); ++i) + { + // 在考虑是否有隐藏section时,如果隐藏的section是在固定section,就不需要考虑,因为滚动的区域是固定section之后的区域 + if ((i >= fixedCount) && (sectionItems.at(i).size == 0)) + { + ++nAdjustedVisualIndex; + } + else + { + ++nCurrentVisualIndex; + } + + // 由于currentVisualIndex实际是count,所以不应在等于的时候break // TODO liurx Qt的是>= ,整理headerView时,再详细考虑 + if (nCurrentVisualIndex > visualIndex) + { + break; + } + } + + visualIndex = nAdjustedVisualIndex; + } + + return visualIndex; +} + +void GlodonHeaderViewPrivate::setScrollOffset(const QScrollBar *scrollBar, GlodonAbstractItemView::ScrollMode scrollMode) +{ + Q_Q(GlodonHeaderView); + if (scrollMode == GlodonAbstractItemView::ScrollPerItem) { + if (scrollBar->maximum() > 0 && scrollBar->value() == scrollBar->maximum()) + q->setOffsetToLastSection(); + else + q->setOffsetToSectionPosition(scrollBar->value()); + } else { + q->setOffset(scrollBar->value()); + } +} + +QRect GlodonHeaderViewPrivate::viewportScrollArea() +{ + Q_Q(GlodonHeaderView); + int nfixedSize = fixedSectionsSize(); + + if (orientation == Qt::Horizontal) + { + return QRect(nfixedSize, 0, viewport->width() - nfixedSize, q->drawWidth()); + } + else + { + return QRect(0, nfixedSize, q->drawWidth(), viewport->height() - nfixedSize); + } +} + +#ifndef QT_NO_DATASTREAM +void GlodonHeaderViewPrivate::write(QDataStream &out) const +{ + out << int(orientation); + out << int(sortIndicatorOrder); + out << sortIndicatorSection; + out << sortIndicatorShown; + + out << visualIndices; + out << logicalIndices; + + out << sectionHidden; + out << hiddenSectionSize; + + out << length; + out << sectionItems.count(); + out << movableSections; + out << clickableSections; + out << highlightSelected; + out << cascadingResizing; + out << defaultSectionSize; + out << minimumSectionSize; + + out << int(defaultAlignment); + out << int(globalResizeMode); + + out << sectionItems; +} + +bool GlodonHeaderViewPrivate::read(QDataStream &in) +{ + int nOrient(0); + int nOrder(0); + int nAlign(0); + int nGlobal(0); + in >> nOrient; + orientation = (Qt::Orientation)nOrient; + + in >> nOrder; + sortIndicatorOrder = (Qt::SortOrder)nOrder; + + in >> sortIndicatorSection; + in >> sortIndicatorShown; + + in >> visualIndices; + in >> logicalIndices; + + in >> sectionHidden; + in >> hiddenSectionSize; + + in >> length; + int unusedSectionCount; // For compability + in >> unusedSectionCount; + in >> movableSections; + in >> clickableSections; + in >> highlightSelected; + in >> cascadingResizing; + in >> defaultSectionSize; + in >> minimumSectionSize; + + in >> nAlign; + defaultAlignment = Qt::Alignment(nAlign); + + in >> nGlobal; + globalResizeMode = (GlodonHeaderView::ResizeMode)nGlobal; + + in >> sectionItems; + + // Spans in Qt5 only contains one element - but for backward compability with Qt4 we do the following + + QVector newSectionSpans; + + for (int u = 0; u < sectionItems.count(); ++u) + { + int count = sectionItems.at(u).tmpDataStreamSectionCount; + + for (int n = 0; n < count; ++n) + { + newSectionSpans.append(sectionItems[u]); + } + } + + sectionItems = newSectionSpans; + + recalcSectionStartPos(); + + return true; +} + +GlodonHHeaderView::GlodonHHeaderView(QWidget *parent) + : GlodonHeaderView(Qt::Horizontal, parent) +{} + +GlodonHHeaderView::~GlodonHHeaderView() +{} + +GlodonVHeaderView::GlodonVHeaderView(QWidget *parent) + : GlodonHeaderView(Qt::Vertical, parent) +{} + +GlodonVHeaderView::~GlodonVHeaderView() +{} + +void GlodonHHeaderViewGraphicsEffect::draw(QPainter *painter) +{ + QPoint offset; + QPixmap pixmap = sourcePixmap(Qt::LogicalCoordinates, &offset); + QPainter p(&pixmap); + p.setBrush(Qt::NoBrush); + QRect rt = pixmap.rect(); + int x1 = 0; + int x2 = m_header->length() - 1; + int y = rt.height() - m_shadowHeight; + p.setPen(m_clrStart); + p.drawLine(QPoint(x1, y), QPoint(x2, y)); + ++y; + p.setPen(m_clrMid); + p.drawLine(QPoint(x1, y), QPoint(x2, y)); + ++y; + p.setPen(m_clrEnd); + p.drawLine(QPoint(x1, y), QPoint(x2, y)); + painter->drawPixmap(offset, pixmap); +} +QRectF GlodonHHeaderViewGraphicsEffect::boundingRectFor(const QRectF &rect) const +{ + QRectF rectF = QGraphicsEffect::boundingRectFor(rect); + rectF.setHeight(rectF.height() + m_shadowHeight); + return rectF; +} +#endif // QT_NO_DATASTREAM diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDImageEditor.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDImageEditor.cpp new file mode 100644 index 00000000..1a042346 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDImageEditor.cpp @@ -0,0 +1,87 @@ +#include "GLDImageEditor.h" +#include +#include +#include + +#include "GLDStrUtils.h" +#include "GLDStrings.h" + +GImageEditor::GImageEditor(QWidget *parent) : + QWidget(parent) +{ + m_frame = new QFrame(this); + m_frame->move(this->pos()); + m_frame->resize(this->frameSize()); + m_frame->setStyleSheet("QFrame {background-color: rgb(255,255,255);color: rgb(0,0,0);}"); + + m_button = new QPushButton("...", m_frame); + m_label = new QLabel(m_frame); + m_label->setAttribute(Qt::WA_TranslucentBackground, true); + + setFocusProxy(m_label); + setFocusPolicy(Qt::StrongFocus); + + m_label->move(m_frame->x(),m_frame->y()); + m_label->resize(m_frame->frameSize().width() - m_button->fontMetrics().width("..."), + m_frame->frameSize().height()); + m_button->move(m_frame->x() + m_frame->frameSize().width() - m_button->fontMetrics().width("...") - 2, + m_frame->y()); + m_button->resize(m_button->fontMetrics().width("...") + 2, + m_frame->frameSize().height()); + connect(m_button, SIGNAL(clicked()), this, SLOT(editorButtonClicked())); +} + +GImageEditor::~GImageEditor() +{ + if (m_button != NULL) + { + delete m_button; + } + if (m_label != NULL) + { + delete m_label; + } + if (m_frame != NULL) + { + delete m_frame; + } +} + +void GImageEditor::paintEvent(QPaintEvent *) +{ + m_frame->resize(this->size()); + + m_label->resize(m_frame->frameSize().width() - m_button->fontMetrics().width("...") - 2, + m_frame->frameSize().height()); + + m_button->move(m_label->x() + m_frame->frameSize().width() - m_button->fontMetrics().width("...") - 2, + m_label->y()); + + m_button->resize(m_button->fontMetrics().width("...") + 2, + m_frame->frameSize().height()); +} + +void GImageEditor::setImage(QImage img) +{ + QImage result = img.scaled(m_label->width(), m_label->height(), Qt::KeepAspectRatio); + m_label->setPixmap(QPixmap::fromImage(result)); +} + +QImage GImageEditor::image() +{ + const QPixmap *pixmap = m_label->pixmap(); + QImage img = pixmap->toImage(); + return img; +} + +void GImageEditor::editorButtonClicked() +{ + QString strFileName = QFileDialog::getOpenFileName(this, getGLDi18nStr(g_SelectImage), "", + "Images (*.png *.xpm *.jpg *.jpeg *.gif *.bmp *.xbm)"); + QImage img; + if (img.load(strFileName)) + { + QImage result = img.scaled(m_label->width(), m_label->height(), Qt::KeepAspectRatio); + setImage(result); + } +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDIrregularForm.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDIrregularForm.cpp new file mode 100644 index 00000000..422dc4a1 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDIrregularForm.cpp @@ -0,0 +1,76 @@ +#include "GLDCustomButton.h" +#include "GLDIrregularForm.h" + +#include +#include +#include +#include +#include +#include +#include + +GLDIrregularForm::GLDIrregularForm(QWidget *parent) + : QWidget(parent) + , m_pCustomBtn(nullptr) + , m_irregularFormPm("") +{ + setFlagAndAttribute(); +} + +GLDIrregularForm::GLDIrregularForm(const QString & irregularImgPath, const QString & btnImgPath, QWidget *parent) + : QWidget(parent) + , m_pCustomBtn(new GLDCustomButton(btnImgPath, this)) + , m_irregularFormPm("") +{ + setFlagAndAttribute(); + + loadPixmap(irregularImgPath); + + connect(m_pCustomBtn, &QPushButton::clicked, this, &GLDIrregularForm::irregularFormClicked); +} + +void GLDIrregularForm::setFlagAndAttribute() +{ + setWindowFlags(windowFlags() | Qt::FramelessWindowHint); + setAttribute(Qt::WA_NoSystemBackground); + setAttribute(Qt::WA_TranslucentBackground); +} + +GLDIrregularForm::~GLDIrregularForm() +{ + +} + +QSize GLDIrregularForm::sizeHint() const +{ + if (!m_irregularFormPm.isNull()) + { + return m_irregularFormPm.size(); + } + + return QWidget::sizeHint(); +} + +void GLDIrregularForm::loadPixmap(const QString & pixmapPath) +{ + QPixmap tempPixmap; + tempPixmap.load(pixmapPath); + setPixmap(tempPixmap); +} + +void GLDIrregularForm::setPixmap(const QPixmap & pm) +{ + m_irregularFormPm = pm; + update(); +} + +void GLDIrregularForm::paintEvent(QPaintEvent *event) +{ + QPainter painter(this); + + m_pCustomBtn->move(this->rect().topRight().x() - m_pCustomBtn->width(), this->rect().topRight().y()); + + painter.drawPixmap(0, 0, m_irregularFormPm); + + QWidget::paintEvent(event); +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDKeyboardButton.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDKeyboardButton.cpp new file mode 100644 index 00000000..fee35e20 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDKeyboardButton.cpp @@ -0,0 +1,61 @@ +#include "GLDKeyboardButton.h" + +const int c_nOneSize = 11; +const int c_nTwoSize = 10; + +const GString numbertaglistblock[c_nOneSize] = {"@","#","$","%","^","&","*","(",")","~","!"}; +const GString numbertaglist[c_nOneSize] = {"2","3","4","5","6","7","8","9","0","`","1"}; + +const GString specialSymbolListBlock[c_nTwoSize] = {"<",">","_","+","|","?","{","}",":","\""}; +const GString specialSymbolList[c_nTwoSize] = {",",".","/","-","=","\\","[","]",";","'"}; + +GLDKeyboardButton::GLDKeyboardButton(const QString &text, QWidget *parent) : + QPushButton(text, parent) +{ + setFocusProxy(parent); +} + +void GLDKeyboardButton::switchLetterCase() +{ + GString strtext = text(); + + if (strtext >= "a" && strtext <= "z") + { + setText(strtext.toUpper()); + } + + if (strtext >= "A" && strtext <= "Z") + { + setText(strtext.toLower()); + } +} + +void GLDKeyboardButton::switchNumberAndSymbol() +{ + setButtonText(numbertaglist, numbertaglistblock, c_nOneSize); +} + +void GLDKeyboardButton::switchPunctuations() +{ + setButtonText(specialSymbolList, specialSymbolListBlock, c_nTwoSize); +} + +void GLDKeyboardButton::setButtonText(const GString specialSymbolList[], const GString specialSymbolListBlock[], int length) +{ + GString strtext = text(); + + for (int i = 0; i < length; i++) + { + if (strtext == specialSymbolList[i]) + { + setText(specialSymbolListBlock[i]); + } + + if (strtext == specialSymbolListBlock[i]) + { + setText(specialSymbolList[i]); + } + } +} + + diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDKeyboardInput.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDKeyboardInput.cpp new file mode 100644 index 00000000..30478107 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDKeyboardInput.cpp @@ -0,0 +1,218 @@ +#include +#include +#include +#include +#include + +#include "GLDFileUtils.h" +#include "GLDKeyboardInput.h" +#include "GLDKeyboardButton.h" + +const int c_nHorizontalSpace = 1; +const int c_nCapsRowNumber = 1; +const int c_nCapsColoumNumber = 12; +const int c_nDeleteRowNumber = 0; +const int c_nDeleteColoumNumber = 11; +const int c_nVerticalSpace = 3; +const int c_nPatterXRadius = 3; +const int c_nPatterYRadius = 3; +const int c_nOneArraySize = 11; +const int c_nTwoArraySize = 10; +const int c_nThreeArraySize = 13; +const int c_nFourArraySize = 13; + +const QSize c_keySize = QSize(24, 24); +const QSize c_shiftSize = QSize(48, 24); +const QSize c_deleteSize = QSize(40, 24); +const QSize c_capsSize = QSize(44, 24); +const QSize c_KeyboardInputSize = QSize(360, 120); + +const QRect c_keyCloseButton = QRect(340, 3, 16, 16); + +const QMargins c_keyMargins = QMargins(8, 3, 2, 1); + +const GString numberTagListBlock[c_nOneArraySize] = {"@","#","$","%","^","&","*","(",")","~","!"}; +const GString numberTagList[c_nOneArraySize] = {"2","3","4","5","6","7","8","9","0","`","1"}; + +const GString specialSymbolListBlock[c_nTwoArraySize] = {"<",">","_","+","|","?","{","}",":","\""}; +const GString specialSymbolList[c_nTwoArraySize] = {",",".","/","-","=","\\","[","]",";","'"}; + +const GString characterOneListBlock[c_nThreeArraySize] = {"M","A","B","C","D","E","F","G","H","I","J","K","L"}; +const GString characterOneList[c_nThreeArraySize] = {"m","a","b","c","d","e","f","g","h","i","j","k","l"}; + +const GString characterTwoListBlock[c_nFourArraySize] = {"O","P","Q","R","S","T","U","V","W","X","Y","Z","N"}; +const GString characterTwoList[c_nFourArraySize] = {"o","p","q","r","s","t","u","v","w","x","y","z","n"}; + +const GString c_sKeyBordQssFile = ":/qsses/GBTKeyboardPurpleStyle.qss"; + +GLDKeyboardInput::GLDKeyboardInput(QWidget *parent) + : QWidget(parent, 0) + , m_signalMapperLowercase(new QSignalMapper(this)) + , m_signalMapperBlockletter(new QSignalMapper(this)) +{ + m_pclosebtn = new QPushButton(this); + m_pdeletebtn = new QPushButton("<-", this); + m_pshiftbtn = new QPushButton(this); + m_pcapslockbtn = new QPushButton(this); + m_pcapslockbtn->setCheckable(true); + m_pshiftbtn->setCheckable(true); + + this->setStyleSheet(loadQssFile(c_sKeyBordQssFile)); + initUI(); + initConnection(); + setFocusPolicy(Qt::WheelFocus); +} + +void GLDKeyboardInput::addButton(QGridLayout *pgridlayout, + const GString numberTagList[], + const GString numberTagListBlock[], + int lineNumber, int startKeySpace, int length) +{ + for (int i = 0; i < length; i++) + { + GLDKeyboardButton *pNumerbtn = new GLDKeyboardButton(numberTagList[i], this); + pNumerbtn->setFixedSize(c_keySize); + pNumerbtn->setObjectName("KeyboardButton"); + pNumerbtn->setCursor(Qt::PointingHandCursor); + + connect(pNumerbtn, SIGNAL(clicked()), m_signalMapperLowercase, SLOT(map())); + m_signalMapperLowercase->setMapping(pNumerbtn, numberTagList[i]); + + connect(pNumerbtn, SIGNAL(clicked()), m_signalMapperBlockletter, SLOT(map())); + m_signalMapperBlockletter->setMapping(pNumerbtn, numberTagListBlock[i]); + + if(0 == lineNumber) + { + connect(m_pshiftbtn, SIGNAL(clicked()), pNumerbtn, SLOT(switchNumberAndSymbol())); + } + else if(1 == lineNumber) + { + connect(m_pshiftbtn, SIGNAL(clicked()), pNumerbtn, SLOT(switchPunctuations())); + } + else + { + connect(m_pcapslockbtn, SIGNAL(clicked()), pNumerbtn, SLOT(switchLetterCase())); + connect(m_pshiftbtn, SIGNAL(clicked()), pNumerbtn, SLOT(switchLetterCase())); + } + + pgridlayout->addWidget(pNumerbtn, lineNumber, i + startKeySpace); + } +} + +void GLDKeyboardInput::initUI() +{ + setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); + setObjectName("Keyboard"); + setFixedSize(c_KeyboardInputSize); + setFormsMask(); + + //关闭按钮 + m_pclosebtn->setGeometry(c_keyCloseButton); + m_pclosebtn->setObjectName("KeyboardCloseButton"); + m_pclosebtn->setCursor(Qt::PointingHandCursor); + + QGridLayout *pgridlayout = new QGridLayout; + pgridlayout->setAlignment(Qt::AlignVCenter); + pgridlayout->setContentsMargins(c_keyMargins); + pgridlayout->setHorizontalSpacing(c_nHorizontalSpace); + pgridlayout->setVerticalSpacing(c_nVerticalSpace); + setLayout(pgridlayout); + // 第一行按键 + // 第一行删除按钮 + m_pdeletebtn->setFocusProxy(this); + m_pdeletebtn->setFixedSize(c_deleteSize); + m_pdeletebtn->setObjectName("KeyboardDeleteButton"); + pgridlayout->addWidget(m_pdeletebtn, c_nDeleteRowNumber, c_nDeleteColoumNumber); + addButton(pgridlayout, numberTagList, numberTagListBlock, 0, 0, c_nOneArraySize); + // 第二行按键 + // 第二行第一个为shift键,占2个键位 + m_pshiftbtn->setFocusProxy(this); + m_pshiftbtn->setFixedSize(c_shiftSize); + m_pshiftbtn->setText("Shift"); + m_pshiftbtn->setObjectName("KeyboardShift"); + pgridlayout->addWidget(m_pshiftbtn, 1, 0, Qt::AlignLeft); + // 第二行中间按键 + addButton(pgridlayout, specialSymbolList, specialSymbolListBlock, 1, 2, c_nTwoArraySize); + // 第二行最后一个键为caps键 + m_pcapslockbtn->setFocusProxy(this); + m_pcapslockbtn->setFixedSize(c_capsSize); + m_pcapslockbtn->setObjectName("KeyboardCapsButton"); + m_pcapslockbtn->setText("Caps"); + pgridlayout->addWidget(m_pcapslockbtn, c_nCapsRowNumber, c_nCapsColoumNumber); + // 第三行 + addButton(pgridlayout, characterOneList, characterOneListBlock, 2, 0, c_nThreeArraySize); + // 第四行 + addButton(pgridlayout, characterTwoList, characterTwoListBlock, 3, 0, c_nFourArraySize); +} + +void GLDKeyboardInput::initConnection() +{ + connect(m_pclosebtn, SIGNAL(clicked()), this, SLOT(close())); + connect(m_pcapslockbtn, SIGNAL(clicked(bool)), this, SLOT(onClickedCapsLock(bool))); + connect(m_pshiftbtn, SIGNAL(clicked(bool)), this, SLOT(onClickedShift(bool))); + connect(m_pdeletebtn, SIGNAL(clicked()), parentWidget(), SLOT(onClickedDeletebtn())); + connect(m_signalMapperLowercase, SIGNAL(mapped(const QString &)), parentWidget(), SLOT(onClickedBtn(const QString &))); +} + +void GLDKeyboardInput::mouseMoveEvent(QMouseEvent *event) +{ + if (event->buttons() == Qt::LeftButton) + { + event->accept(); + } + else + { + QWidget::mouseMoveEvent(event); + } +} + +void GLDKeyboardInput::onClickCapsAndShift(bool checked) +{ + if (checked) + { + disconnect(m_signalMapperLowercase, SIGNAL(mapped(const QString &)), + parentWidget(), SLOT(onClickedBtn(const QString &))); + connect(m_signalMapperBlockletter, SIGNAL(mapped(const QString &)), + parentWidget(), SLOT(onClickedBtn(const QString &))); + } + else + { + disconnect(m_signalMapperBlockletter, SIGNAL(mapped(const QString &)), + parentWidget(), SLOT(onClickedBtn(const QString &))); + connect(m_signalMapperLowercase, SIGNAL(mapped(const QString &)), + parentWidget(), SLOT(onClickedBtn(const QString &))); + } +} + +void GLDKeyboardInput::onClickedCapsLock(bool checked) +{ + onClickCapsAndShift(checked); +} + +void GLDKeyboardInput::onClickedShift(bool checked) +{ + onClickCapsAndShift(checked); +} + +void GLDKeyboardInput::focusOutEvent(QFocusEvent *) +{ + hide(); +} + +void GLDKeyboardInput::show() +{ + setFocus(); + QWidget::show(); +} + +void GLDKeyboardInput::setFormsMask() +{ + QBitmap bmp(this->size()); + bmp.fill(); + QPainter paiter(&bmp); + paiter.setPen(Qt::NoPen); + paiter.setBrush(Qt::blue); + paiter.drawRoundedRect(bmp.rect(), c_nPatterXRadius, c_nPatterYRadius); + setMask(bmp);//设置窗体遮罩 +} + diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDLineWidthComboBoxEx.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDLineWidthComboBoxEx.cpp new file mode 100644 index 00000000..2ec6d947 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDLineWidthComboBoxEx.cpp @@ -0,0 +1,340 @@ +/**** + * @file : GLDLineWidthComboBoxEx.cpp + * @brief : + * + * @date : 2014-08-18 + * @author : lijl-c + * @remarks: + ****/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "GLDShadow.h" +#include "GLDStrings.h" +#include "GLDFileUtils.h" +#include "GLDScrollStyle.h" +#include "GLDLineWidthComboBoxEx.h" + +const float c_pxToPt = (float)96 / 72; /*像素转换为磅*/ +const float c_lineWidthChangeFactor = 0.25; +const int c_LineWidthComboBoxWidth = 219; /*O设置宽度 */ +const int c_LineWidthComboBoxHight = 25; /*高度*/ +//const int c_LineWidthButtonWidth = 147; /*宽度*/ +const int c_LinePaddingButton = 5; /*线条距离button的边距*/ +const int c_ButtonPaddingTop = 12; /*button上部内边框像素*/ +const int c_LabelPtWidth = 85;/*磅数label的宽度*/ +const int c_buttonFontSize = 12;/*字体大小*/ + +const GString c_sLineWidthComboBoxQssFile = ":/qsses/GLDLineWidthComboBoxEx.qss"; + +/** + * @brief + * + * @fn GLDLineWidthComboBoxEx::GLDLineWidthComboBoxEx + * @param parent + */ +GLDLineWidthComboBoxEx::GLDLineWidthComboBoxEx(QWidget *parent) : + QComboBox(parent), + m_minLineCount(1), + m_maxLineCount(25), + m_lineWidthPopupHight(212), + m_hasBorder(true), + m_curIndex(0), + m_curLineWidth(0) +{ + initPopUp(); + + setModel(m_popupListWidgets->model()); + setView(m_popupListWidgets); + + QWidget *parentContainer = m_popupListWidgets->parentWidget(); + if (NULL != parentContainer) + { + parentContainer->setFixedWidth(m_popupListWidgets->width()); + } + + setLineEdit(new QLineEdit(this)); + lineEdit()->setReadOnly(true); + + setObjectName("GLDLineWidthComboBoxEx"); + setHasBorder(true); + + GLDShadow *pGLDShadow = new GLDShadow(this); + pGLDShadow->removeShadow(); + + setStyle(new GLDScrollStyle(this)); + this->setStyleSheet(loadQssFile(c_sLineWidthComboBoxQssFile)); + + setEditText(getGLDi18nStr(g_rsNoLine)); +} + +/** + * @brief + * + * @fn GLDLineWidthComboBoxEx::~GLDLineWidthComboBoxEx + */ +GLDLineWidthComboBoxEx::~GLDLineWidthComboBoxEx() +{ +} + +void GLDLineWidthComboBoxEx::setHasBorder(bool hasBorder) +{ + if (m_hasBorder != hasBorder) + { + m_hasBorder = hasBorder; + } + + if (!m_hasBorder) + { + setProperty("GLDBorderStyle", "noBorder"); + } + this->setStyleSheet(loadQssFile(c_sLineWidthComboBoxQssFile)); +} + +/** + * @brief + * + * @fn GLDLineWidthComboBoxEx::initModel + */ +void GLDLineWidthComboBoxEx::initPopUp() +{ + m_popupListWidgets = new QListWidget(this); + m_popupListWidgets->setProperty("GLDPopupListWidgets", true); + m_popupListWidgets->setFixedWidth(c_LineWidthComboBoxWidth * 2); + + initLineWidth(); + initMoreLinesButton(); +} + +void GLDLineWidthComboBoxEx::initLineWidth() +{ + QListWidgetItem *pLineWidthItem = new QListWidgetItem(m_popupListWidgets); + pLineWidthItem->setSizeHint(QSize(c_LineWidthComboBoxWidth, m_lineWidthPopupHight)); + + QListWidget *pLineWidthWidget = new QListWidget(this); + pLineWidthWidget->setProperty("GLDLineWidgets", true); + createLineWidthRowItem(pLineWidthWidget); + + m_popupListWidgets->setItemWidget(pLineWidthItem, pLineWidthWidget); + m_popupListWidgets->addItem(pLineWidthItem); +} + +void GLDLineWidthComboBoxEx::initMoreLinesButton() +{ + QListWidgetItem *pItemMore = new QListWidgetItem(m_popupListWidgets); + + QListWidget *pMoreWidget = new QListWidget(this); + pMoreWidget->setProperty("GLDMoreWidget", true); + + createMoreLinesItem(pMoreWidget); + + m_popupListWidgets->setItemWidget(pItemMore, pMoreWidget); + m_popupListWidgets->addItem(pItemMore); +} + +/** + * @brief + * + * @fn GLDLineWidthComboBoxEx::createLineWidthRow + * @param index + * @return QWidget + */ +QWidget* GLDLineWidthComboBoxEx::createLineWidthRow(int index) +{ + GLDLineWidthRow *pLineWidthRow = new GLDLineWidthRow(this, index); + + connect(pLineWidthRow, SIGNAL(mapped(int)), this, SLOT(onClicked(int))); + + return pLineWidthRow; +} + +/** + * @brief + * + * @fn GLDLineWidthComboBoxEx::createLineWidthRowItem + * @param pLineWidthItem + */ +void GLDLineWidthComboBoxEx::createLineWidthRowItem(QListWidget *pLineWidthItem) +{ + for (int i = 0; i< m_maxLineCount - 1; ++i) + { + QWidget *pLineWidthRow = createLineWidthRow(i); + QListWidgetItem *pLineWidgetItem = new QListWidgetItem(pLineWidthItem); + pLineWidthItem->setItemWidget(pLineWidgetItem, pLineWidthRow); + pLineWidthItem->addItem(pLineWidgetItem); + } +} + +void GLDLineWidthComboBoxEx::createMoreLinesItem(QListWidget *pMoreItem) +{ + QWidget *pMoreWidget = new QWidget(this); + QHBoxLayout *pLayout = new QHBoxLayout(this); + // 设置外边距 + pLayout->setContentsMargins(0, 0, 0, 0); + pMoreWidget->setLayout(pLayout); + + QPushButton *pMoreButton = new QPushButton(getGLDi18nStr(g_rsOtherLine)); + pMoreButton->setProperty("GLDMoreButton", true); + pLayout->addWidget(pMoreButton); + connect(pMoreButton, SIGNAL(clicked()), this, SLOT(onClicked())); + + QListWidgetItem *pMoreItemChild = new QListWidgetItem(pMoreItem); + pMoreItem->setItemWidget(pMoreItemChild, pMoreWidget); + pMoreItem->addItem(pMoreItemChild); +} + +/** + * @brief + * + * @fn GLDLineWidthComboBoxEx::onClicked + * @param index + */ +void GLDLineWidthComboBoxEx::onClicked(int index) +{ + m_curIndex = index; + if (m_curIndex == 0) + { + setCurLineWidth(0); + setEditText(getGLDi18nStr(g_rsNoLine)); + } + else + { + setCurLineWidth(m_curIndex * c_lineWidthChangeFactor); + setEditText(QString("%0 ").arg(m_curIndex * c_lineWidthChangeFactor) + getGLDi18nStr(g_rsLineWidth)); + } + hidePopup(); + + emit itemClicked(m_curIndex); +} + +void GLDLineWidthComboBoxEx::onClicked() +{ + QMessageBox::warning(this, "MoreLines", QString("more lines")); +} + +/** + * GLDLineWidthButton +*/ +GLDLineWidthButton::GLDLineWidthButton(qreal lineWeight, QWidget *parent): + QPushButton(parent), + m_lineWeigth(lineWeight) +{ + setProperty("GLDLineWidthButton", true); +} + +void GLDLineWidthButton::resizeEvent(QResizeEvent *e) +{ + drawLineWidth(m_lineWeigth, e->size().width()); +} + +void GLDLineWidthButton::drawLineWidth(qreal lineWeight, int lineLength) +{ + QPixmap pix(lineLength, c_LineWidthComboBoxHight); + pix.fill(Qt::transparent); + + QPainter painter(&pix); + QPen pen = painter.pen(); + + QIcon icon; + + if (lineWeight != 0) + { + pen.setWidthF(lineWeight); + pen.setColor(Qt::black); + painter.setPen(pen); + //padding-top为12px 高度要改变否则线条不在button中间 + //笔变粗之后会自动扩展,每次画的时候起点要向右移动笔半径的距离 + int nY = (geometry().height() - c_ButtonPaddingTop) / 2; + QLineF lineF(c_LinePaddingButton + lineWeight / 2, nY, + lineLength - c_LinePaddingButton - lineWeight / 2, nY); + painter.drawLine(lineF); + + icon.addPixmap(pix); + setIcon(icon); + setIconSize(QSize(lineLength , geometry().height())); + } + else + { + pen.setWidth(c_buttonFontSize); + pen.setColor("#44515a"); + painter.setPen(pen); + painter.drawText(QPointF(c_LinePaddingButton, c_ButtonPaddingTop - 2), getGLDi18nStr(g_rsNoLine)); + + icon.addPixmap(pix); + setIcon(icon); + setIconSize(QSize(lineLength , geometry().height())); + } +} + +GLDLineWidthRow::GLDLineWidthRow(QWidget *parent, int rowIndex) : + QWidget(parent), + m_label(new QLabel(this)), + m_rowLayout(new QHBoxLayout(this)), + m_rowIndex(rowIndex) +{ + m_lineWidthBtn = new GLDLineWidthButton(c_pxToPt * m_rowIndex * c_lineWidthChangeFactor, this); + m_rowLayout->setSpacing(4); + m_rowLayout->setContentsMargins(0, 0, 0, 0); + initRowLabel(m_rowIndex); + initRowButton(m_rowIndex); +} + +void GLDLineWidthRow::initRowLabel(int rowIndex) +{ + if (rowIndex == 0) + { + m_label->setPixmap(QPixmap(":/icons/GLDLineWidthEx-noline.png")); + m_label->setProperty("GLDNoLineLabel", true); + m_label->setFixedSize(c_LabelPtWidth, c_LineWidthComboBoxHight); + m_label->setAlignment(Qt::AlignRight); + + m_rowLayout->addWidget(m_label); + } + else + { + m_label->setText(QString("%0 ").arg(rowIndex * c_lineWidthChangeFactor) + getGLDi18nStr(g_rsLineWidth)); + m_label->setProperty("GLDPixlLable", true); + m_label->setFixedSize(c_LabelPtWidth, c_LineWidthComboBoxHight); + m_label->setAlignment(Qt::AlignRight); + + m_rowLayout->addWidget(m_label); + } +} + +void GLDLineWidthRow::initRowButton(int rowIndex) +{ + QSignalMapper *pLineMapper = new QSignalMapper(this); + + if (rowIndex == 0) + { + m_lineWidthBtn->setProperty("GLDNoLineButton", true); + + m_rowLayout->addWidget(m_lineWidthBtn); + + pLineMapper->setMapping(m_lineWidthBtn, rowIndex); + connect(m_lineWidthBtn, SIGNAL(clicked()), pLineMapper, SLOT(map())); + } + else + { + m_rowLayout->addWidget(m_lineWidthBtn); + + pLineMapper->setMapping(m_lineWidthBtn, rowIndex); + connect(m_lineWidthBtn, SIGNAL(clicked()), pLineMapper, SLOT(map())); + } + + connect(pLineMapper, SIGNAL(mapped(int)), this, SIGNAL(mapped(int))); +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDListView.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDListView.cpp new file mode 100644 index 00000000..2a00c288 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDListView.cpp @@ -0,0 +1,1062 @@ +#include "GLDListView.h" +#include "GLDShellWidgets.h" +#include "GLDScrollStyle.h" +#include "GLDFileSystemModel.h" +#include "GLDStrUtils.h" +//#include + +#include +#include +#include +#include +#include +#include +#include +#include + +const int c_nSizeUnitLength = 2; + +const GString c_sKB = "KB"; +const GString c_sMB = "MB"; +const GString c_sGB = "GB"; +const GString c_sTB = "TB"; + +const quint64 c_kb = 1024; +const quint64 c_mb = 1024 * c_kb; +const quint64 c_gb = 1024 * c_mb; +const quint64 c_tb = 1024 * c_gb; + +GLDListView::GLDListView(QWidget *parent) + : QListView(parent), stopDelayedLayoutTimer(false), m_bShowToolTip(true), m_bDragEnabled(true), + m_bVsModeSetted(false), m_viewMode(VSSmallIconMode), m_shellTree(0) +{ + bool bUseMyDelegateForStyleDraw = false; + if (bUseMyDelegateForStyleDraw) + setItemDelegate(new GLDListStyledItemDelegate(this)); + + stopDelayedLayoutTime = QTime::currentTime(); + stopDelayedLayoutTime.start(); + + if (bUseMyDelegateForStyleDraw) + setStyle(new GLDWindowsVistaStyle(this)); + init(); +} + +void GLDListView::init() +{ + connect(this, SIGNAL(pressed(const QModelIndex&)), this, SIGNAL(itemJustBeSelected(const QModelIndex&))); + QTimer::singleShot(10, this, SLOT(initVsViewState())); +} + +GLDListView::~GLDListView() +{ +} + +void GLDListView::setModel(QAbstractItemModel *model) +{ + QListView::setModel(model); + if (m_shellTree) + m_shellTree->setModel(model); +} + +void GLDListView::setRootIndex(const QModelIndex &index) +{ + QListView::setRootIndex(index); + if (m_shellTree) + m_shellTree->setRootIndex(m_shellTree->proxyIndex(index)); +} + +QRect GLDListView::visualRect(const QModelIndex &index) const +{ + QRect tmp = QListView::visualRect(index); + QSize grid = gridSize(); + if (VSIconMode == vsViewMode()) + { + if (tmp.width() + 1 < grid.width()) + { + int nhalfWidth = (grid.width() - tmp.width() - 1 ) / 2.0; + tmp.adjust(-nhalfWidth, 0, nhalfWidth, 0); + } + if (tmp.height() + 1 < grid.height()) + { + GLDWindowsVistaStyle *pStyle = dynamic_cast(this->style()); + bool badjusted = false; + if (pStyle && pStyle->m_textLineHeight > 0) + { + double distance = grid.height() - tmp.height(); + int nlineCount = distance / pStyle->m_textLineHeight; + if (nlineCount > 0) + { + tmp.adjust(0, 0, 0, qMin(( nlineCount * pStyle->m_textLineHeight - 1), distance)); + badjusted = true; + } + } + if (!badjusted) + tmp.adjust(0, 0, 0,grid.height() - tmp.height()); + } + } + else if (VSSmallIconMode == vsViewMode() || VSListMode == vsViewMode()) + { + if (tmp.width() != grid.width()) + { + tmp.adjust(0,0,grid.width() - tmp.width(),0); + } + } + return tmp; +} + +void GLDListView::paintEvent(QPaintEvent *e) +{ + Q_D(GLDListView); + if (currentReportMode()) + return; + + if (!d->itemDelegate) + return; + QStyleOptionViewItem option = d->viewOptions(); + QPainter painter(d->viewport); + + const QVector c_toBeRendered = d->intersectingSet(e->rect().translated(horizontalOffset(), + verticalOffset()), false); + + const QModelIndex c_current = currentIndex(); + const QModelIndex c_hover = d->hover; + const QAbstractItemModel *c_itemModel = d->model; + const QItemSelectionModel *c_selections = d->selectionModel; + const bool c_focus = (hasFocus() || d->viewport->hasFocus()) && c_current.isValid(); + const bool c_alternate = d->alternatingColors; + const QStyle::State c_state = option.state; + const QAbstractItemView::State c_viewState = this->state(); + const bool c_enabled = (c_state & QStyle::State_Enabled) != 0; + + bool balternateBase = false; + int npreviousRow = -2; // trigger the alternateBase adjustment on first pass + + int nmaxSize = (flow() == TopToBottom) + ? qMax(viewport()->size().width(), d->contentsSize().width()) - 2 * d->spacing() + : qMax(viewport()->size().height(), d->contentsSize().height()) - 2 * d->spacing(); + + int nitemsCount = c_toBeRendered.count(); + for (int nindex = nitemsCount - 1; nindex > -1; --nindex) + { + QModelIndex it = c_toBeRendered.at(nindex); + Q_ASSERT((it).isValid()); + option.rect = visualRect(it); + + if (flow() == TopToBottom) + option.rect.setWidth(qMin(nmaxSize, option.rect.width())); + else + option.rect.setHeight(qMin(nmaxSize, option.rect.height())); + + option.state = c_state; + if (c_selections && c_selections->isSelected(it)) + option.state |= QStyle::State_Selected; + if (c_enabled) + { + QPalette::ColorGroup cg; + if ((c_itemModel->flags(it) & Qt::ItemIsEnabled) == 0) + { + option.state &= ~QStyle::State_Enabled; + cg = QPalette::Disabled; + } + else + { + cg = QPalette::Normal; + } + option.palette.setCurrentColorGroup(cg); + } + if (c_focus && c_current == it) + { + option.state |= QStyle::State_HasFocus; + if (c_viewState == QAbstractItemView::EditingState) + option.state |= QStyle::State_Editing; + } + if (it == c_hover) + option.state |= QStyle::State_MouseOver; + else + option.state &= ~QStyle::State_MouseOver; + + if (c_alternate) + { + int row = (it).row(); + if (row != npreviousRow + 1) + { + // adjust alternateBase according to rows in the "gap" + if (!d->hiddenRows.isEmpty()) + { + for (int r = qMax(npreviousRow + 1, 0); r < row; ++r) + { + if (!d->isHidden(r)) + balternateBase = !balternateBase; + } + } + else + { + balternateBase = (row & 1) != 0; + } + } + if (balternateBase) + { + option.features |= QStyleOptionViewItem::Alternate; + } + else + { + option.features &= ~QStyleOptionViewItem::Alternate; + } + + // draw background of the item (only alternate row). rest of the background + // is provided by the delegate + QStyle::State oldState = option.state; + option.state &= ~QStyle::State_Selected; + style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &option, &painter, this); + option.state = oldState; + balternateBase = !balternateBase; + npreviousRow = row; + } + + option.features |= QStyleOptionViewItem::WrapText; + d->delegateForIndex(it)->paint(&painter, option, it); + } + +#ifndef QT_NO_DRAGANDDROP + d->commonListView->paintDragDrop(&painter); +#endif + +#ifndef QT_NO_RUBBERBAND + // #### move this implementation into a dynamic class + if (d->showElasticBand && d->elasticBand.isValid()) { + QStyleOptionRubberBand opt; + opt.initFrom(this); + opt.shape = QRubberBand::Rectangle; + opt.opaque = false; + opt.rect = d->mapToViewport(d->elasticBand, false).intersected( + d->viewport->rect().adjusted(-16, -16, 16, 16)); + painter.save(); + style()->drawControl(QStyle::CE_RubberBand, &opt, &painter); + painter.restore(); + } +#endif + +} + +void GLDListView::timerEvent(QTimerEvent *e) +{ + if (false == stopDelayedLayoutTimer) + { + stopDelayedLayoutTimer = true; + if (stopDelayedLayoutTime.elapsed() < 100) + { + stopDelayedLayoutTime.restart(); + return; + } + } + return QListView::timerEvent(e); +} + +void GLDListView::switchDragDropState() +{ + if (!currentReportMode()) + { + if (m_bDragEnabled) + { + setDragDropMode(DragOnly); + } + else + { + setDragDropMode(NoDragDrop); + } + } +} + +void GLDListView::switchChildTreeDragDropState() +{ + if (m_bDragEnabled) + { + m_shellTree->setDragDropMode(DragOnly); + } + else + { + m_shellTree->setDragDropMode(NoDragDrop); + } +} + +innerGLD::innerShellTreeView *GLDListView::createTreeView() +{ + return new innerGLD::innerShellTreeView(this); +} + +void GLDListView::onInnerShellTreeViewClick(const QModelIndex &index) +{ + QModelIndex oDataIndex = m_shellTree->dataIndex(index); + QModelIndex oCurrentIndex = model()->index(oDataIndex.row(), 0, oDataIndex.parent()); + + setCurrentIndex(oCurrentIndex); + emit clicked(oCurrentIndex); +} + +void GLDListView::setVsViewMode(GLDListView::GLDViewMode mode) +{ + if (m_viewMode == mode) + return; + + m_bVsModeSetted = true; + if (currentReportMode()) + { + if (m_shellTree) + { + m_shellTree->hide(); + } + + viewport()->show(); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + } + else if (!currentReportMode() && mode == GLDListView::VSReportMode) + { + if (m_shellTree != NULL) + { + m_shellTree->show(); + } + + viewport()->hide(); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + } + + setWrapping(true); + setUniformItemSizes(true); + switch (mode) + { + case VSListMode: //OK + QListView::setViewMode(QListView::ListMode); + setGridSize(QSize(230,17));//GSP-528,与TcxShellListView保持一致。原生200,但考虑到图标文字间距以及字体差别 + setFlow(TopToBottom); + break; + case VSIconMode: + { + QListView::setViewMode(QListView::IconMode); + QSize size(100,70); + setGridSize(size); + setFlow(LeftToRight); + setLayoutMode(Batched); + } + break; + case VSSmallIconMode: + { + setGridSize(QSize(118,17)); + setFlow(LeftToRight); + QListView::setViewMode(QListView::ListMode); + } + break; + case VSReportMode: + //to do ,switch between list/tree views + { + if (!m_shellTree) + { + m_shellTree = createTreeView();//(parentWidget()); + connect(m_shellTree, SIGNAL(clicked(QModelIndex)), this, SLOT(onInnerShellTreeViewClick(QModelIndex))); + if (!layout()) + { + QVBoxLayout *lay = new QVBoxLayout; + lay->addWidget(m_shellTree); + lay->setContentsMargins(0,0,0,0); + setLayout(lay); + } + m_shellTree->setStyleSheet("QTreeView{border:0}"); + //inherited init action + m_shellTree->setAnimated(false); + m_shellTree->setIndentation(0); + m_shellTree->setUniformRowHeights(true); + m_shellTree->setSortingEnabled(true); + } + if (m_shellTree->dataModel() != model()) + { + m_shellTree->setModel(model()); + } + QModelIndex rootIndex = this->rootIndex(); + if (rootIndex.isValid()) + { + m_shellTree->setRootIndex(m_shellTree->proxyIndex(rootIndex)); + } + + QModelIndex currentIndex = this->currentIndex(); + if (currentIndex.isValid()) + { + m_shellTree->setCurrentIndex(m_shellTree->proxyIndex(currentIndex)); + } + switchChildTreeDragDropState(); + + m_shellTree->setGeometry(geometry()); + m_shellTree->showNormal(); + } + break; + default: + break; + } + switchDragDropState(); + m_viewMode = mode; +} + +GLDListView::GLDViewMode GLDListView::vsViewMode() const +{ + return m_viewMode; +} + +void GLDListView::enterEdit(const QModelIndex &index) +{ + if (VSReportMode == m_viewMode) + { + m_shellTree->edit(m_shellTree->proxyIndex(index)); + } + else + { + edit(index); + } +} + +void GLDListView::setSectionResizeMode(int logicalIndex, QHeaderView::ResizeMode mode) +{ + if (VSReportMode == m_viewMode) + { + m_shellTree->header()->setSectionResizeMode(logicalIndex, mode); + } +} + +void GLDListView::setDragActionEnable(bool enable) +{ + m_bDragEnabled = enable; +} + +bool GLDListView::dragActionEnabled() const +{ + return m_bDragEnabled; +} + +QString GLDListView::currentVSViewStateName() const +{ + switch (m_viewMode) + { + case GLDListView::VSListMode: + return tr("List"); + case GLDListView::VSIconMode: + return tr("Icon"); + case GLDListView::VSSmallIconMode: + return tr("Small Icon"); + case GLDListView::VSReportMode: + return tr("Report"); + default: + return tr("Error"); + } +} + +innerGLD::innerShellTreeView *GLDListView::shellTreeView() +{ + return m_shellTree; +} + +void GLDListView::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) +{ + if (m_bShowToolTip) + { + if (1 == selected.size()) + { + if (1 == selected.at(0).indexes().size()) + { + QModelIndex focusIndex = selected.at(0).indexes().at(0); + if (focusIndex.isValid()) + { + setToolTip(focusIndex.data().toString()); + } + } + } + } + return QListView::selectionChanged(selected, deselected); +} + +void GLDListView::initVsViewState() +{ + if (!m_bVsModeSetted) + { + setVsViewMode(VSListMode); + } +} + +bool GLDListView::event(QEvent *e) +{ + if (e->type() == QEvent::ToolTip) + { + QHelpEvent *helpEvent = static_cast(e); + QModelIndex index = indexAt(helpEvent->pos()); + if (index.isValid()) + { + QToolTip::showText(helpEvent->globalPos(), index.data().toString()); + } + else + { + QToolTip::hideText(); + e->ignore(); + } + + return true; + } + return inherit::event(e); +} + +void GLDListView::setViewMode(QListView::ViewMode mode) +{ + Q_UNUSED(mode); + Q_ASSERT(false); +} + +void GLDListView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) +{ + QListView::currentChanged(current, previous); + emit currentItemJustChanged(current, previous); +// if (m_viewMode != VSReportMode) +// emit itemJustBeSelected(current); +} + +void GLDListView::mouseDoubleClickEvent(QMouseEvent *event) +{ + const QModelIndex c_clickedIndex = indexAt(event->pos()); + if (!currentReportMode()) + { + if (c_clickedIndex.isValid()) + emit itemJustBeDoubleClicked(c_clickedIndex); + } +} + +void GLDListView::dropEvent(QDropEvent *e) +{ + //IconMode时,一直是DragDrop,只有在此处不响应,否则会放乱。 + if (viewMode() == IconMode) + return; + QListView::dropEvent(e); +} + +QRect GLDListViewPrivate::mapToViewport(const QRect &rect, bool extend) const +{ + Q_Q(const GLDListView); + if (!rect.isValid()) + return rect; + + QRect result = extend ? commonListView->mapToViewport(rect) : rect; + int ndx = -q->horizontalOffset(); + int ndy = -q->verticalOffset(); + return result.adjusted(ndx, ndy, ndx, ndy); +} + +QStyleOptionViewItem GLDListViewPrivate::viewOptions() const +{ + Q_Q(const GLDListView); + QStyleOptionViewItem option = abstractViewOptions();//QAbstractItemViewPrivate::viewOptions(); + if (!iconSize.isValid()) { // otherwise it was already set in abstractitemview + int pm = (viewMode == GLDListView::ListMode + ? q->style()->pixelMetric(QStyle::PM_ListViewIconSize, 0, q) + : q->style()->pixelMetric(QStyle::PM_IconViewIconSize, 0, q)); + option.decorationSize = QSize(pm, pm); + } + if (viewMode == GLDListView::IconMode) { + option.showDecorationSelected = false; + option.decorationPosition = QStyleOptionViewItem::Top; + option.displayAlignment = Qt::AlignCenter; + } else { + option.decorationPosition = QStyleOptionViewItem::Left; + } + return option; +} + +void GLDListViewPrivate::interruptDelayedItemsLayout() const +{ + Q_Q(GLDListView const); + q->stopDelayedLayoutTime.restart(); + q->stopDelayedLayoutTimer = true; + delayedPendingLayout = false; +} + +QStyleOptionViewItem GLDListViewPrivate::abstractViewOptions() const +{ + Q_Q(const GLDListView); + QStyleOptionViewItem option; + option.init(q); + option.state &= ~QStyle::State_MouseOver; + option.font = q->font(); + +#ifndef Q_WS_MAC + // On mac the focus appearance follows window activation + // not widget activation + if (!q->hasFocus()) + option.state &= ~QStyle::State_Active; +#endif + + option.state &= ~QStyle::State_HasFocus; + if (iconSize.isValid()) { + option.decorationSize = iconSize; + } else { + int pm = q->style()->pixelMetric(QStyle::PM_SmallIconSize, 0, q); + option.decorationSize = QSize(pm, pm); + } + option.decorationPosition = QStyleOptionViewItem::Left; + option.decorationAlignment = Qt::AlignCenter; + option.displayAlignment = Qt::AlignLeft | Qt::AlignVCenter; + option.textElideMode = textElideMode; + option.rect = QRect(); + option.showDecorationSelected = (0 != q->style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, 0, q)); + if (wrapItemText) + option.features = QStyleOptionViewItem::WrapText; + option.locale = q->locale(); + option.locale.setNumberOptions(QLocale::OmitGroupSeparator); + option.widget = q; + return option; +} + +void GLDListStyledItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + Q_ASSERT(index.isValid()); + + QStyleOptionViewItem opt = option; + initStyleOption(&opt, index); + + const QWidget *widget = option.widget;///QStyledItemDelegatePrivate::widget(option); + QStyle *style = widget ? widget->style() : QApplication::style(); + if (dynamic_cast(style)) + { + const QStyleOptionViewItem *vopt = &opt; + const QAbstractItemView *view = dynamic_cast(widget); + if (view) + { + QPalette palette = vopt->palette; + palette.setColor(QPalette::All, QPalette::HighlightedText, palette.color(QPalette::Active, QPalette::Text)); + // Note that setting a saturated color here results in ugly XOR colors in the focus rect + palette.setColor(QPalette::All, QPalette::Highlight, palette.base().color().darker(108)); + QStyleOptionViewItem adjustedOption = *vopt; + adjustedOption.palette = palette; + // We hide the focusrect in singleselection as it is not required + if ((view->selectionMode() == QAbstractItemView::SingleSelection) + && !(vopt->state & QStyle::State_KeyboardFocusChange)) + adjustedOption.state &= ~QStyle::State_HasFocus; + } + } +// opt.rect.adjust(0,0,0,20); + opt.features |= QStyleOptionViewItem::WrapText; + style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, widget); +} + +QRect GLDWindowsVistaStyle::subElementRect(QStyle::SubElement sr, const QStyleOption *opt, const QWidget *widget) const +{ + QRect tmp = QCommonStyle::subElementRect(sr, opt, widget); + if (SE_ItemViewItemText == sr) + { + if (m_custom) + { + QSize grid = m_custom->gridSize(); + if (grid.isValid()) + { + double dFontHeight = opt->fontMetrics.height(); + m_textLineHeight = dFontHeight; + int nAdjustedHeight = grid.height() - tmp.height(); + int nHalfWidth = (grid.width() - tmp.width() - 1) / 2.0; + if (dFontHeight > 5 && nAdjustedHeight > 0) + { + int nlineCount = nAdjustedHeight / dFontHeight; + tmp.adjust(-nHalfWidth, 0, nHalfWidth, (nlineCount - 1) * dFontHeight); + } + } + } + } + else if (SE_ItemViewItemFocusRect == sr) + { + if (m_custom) + { + QSize grid = m_custom->gridSize(); + double dFontHeight = opt->fontMetrics.height(); + int nadjustedHeight = grid.height() - tmp.height(); + int nhalfWidth = (grid.width() - tmp.width() - 1) / 2.0; + if (dFontHeight > 5 && nadjustedHeight > 0) + { + int nlineCount = nadjustedHeight / dFontHeight; + tmp.adjust(-nhalfWidth, 0, nhalfWidth, (nlineCount - 1) * dFontHeight); + } + } + } + else if (static_cast(PE_PanelItemViewItem) == static_cast(sr)) + { + if (m_custom) + { + QSize grid = m_custom->gridSize(); + double dFontHeight = opt->fontMetrics.height(); + int nadjustedHeight = grid.height() - tmp.height(); + int nhalfWidth = (grid.width() - tmp.width() - 1) / 2.0; + if (dFontHeight > 5 && nadjustedHeight > 0) + { + int nlineCount = nadjustedHeight / dFontHeight; + tmp.adjust(-nhalfWidth, 0, nhalfWidth, (nlineCount - 1) * dFontHeight); + } + } + } + else + { + if (m_custom) + { + QSize grid = m_custom->gridSize(); + double dfontHeight = opt->fontMetrics.height(); + int nadjustedHeight = grid.height() - tmp.height(); + int nhalfWidth = (grid.width() - tmp.width() - 1) / 2.0; + if (dfontHeight > 5 && nadjustedHeight > 0) + { + int nlineCount = nadjustedHeight / dfontHeight; + tmp.adjust(-nhalfWidth, 0, nhalfWidth, (nlineCount - 1) * dfontHeight); + } + } + } + return tmp; +} + +void GLDWindowsVistaStyle::drawPrimitive(QStyle::PrimitiveElement element, + const QStyleOption *option, QPainter *painter, const QWidget *widget) const +{ + if (element == PE_PanelItemViewItem) + { +// painter->setClipping(false); + QStyleOption * opt = const_cast(option); + if (opt && opt->type == QStyleOption::SO_ViewItem) + { + QStyleOptionViewItem *pOpt = static_cast(opt); + if (pOpt->index.isValid()) + { + if (/*GLDListView *pList = */dynamic_cast(m_custom)) + { +// if (pList->selectionModel()->isSelected(pOpt->index)) +// { +// opt->rect.adjust(-20, 0, 20, 0); +// } +// QRect tmp = QCommonStyle::subElementRect(element, option, widget); + } + } + } + } + QProxyStyle::drawPrimitive(element, option, painter, widget); +} + +void GLDListViewPrivate::updateStyledFrameWidths() +{ + Q_Q(const QFrame); + QStyleOptionFrameV3 opt; + opt.initFrom(q); + opt.lineWidth = lineWidth; + opt.midLineWidth = midLineWidth; + opt.frameShape = QFrame::Shape(frameStyle & QFrame::Shape_Mask); + + QRect cr = q->style()->subElementRect(QStyle::SE_ShapedFrameContents, &opt, q); + leftFrameWidth = cr.left() - opt.rect.left(); + topFrameWidth = cr.top() - opt.rect.top(); + rightFrameWidth = opt.rect.right() - cr.right(), + bottomFrameWidth = opt.rect.bottom() - cr.bottom(); + frameWidth = qMax(qMax(leftFrameWidth, rightFrameWidth), + qMax(topFrameWidth, bottomFrameWidth)); +} + +innerGLD::innerShellTreeView::innerShellTreeView(QWidget *parent) + : QTreeView(parent), m_bShowBranches(false), m_pDataModel(NULL), m_pModel(NULL) +{ + setItemsExpandable(false); + connect(this, SIGNAL(pressed(QModelIndex)), this, SLOT(onItemPressed(QModelIndex))); + + if (GLDListView* list = dynamic_cast(parent)) + { + //技术平台右键菜单关联 + this->setContextMenuPolicy(Qt::CustomContextMenu); + connect(this, SIGNAL(customContextMenuRequested(QPoint)), + list, SIGNAL(customContextMenuRequested(QPoint))); + + connect(this, SIGNAL(doubleClicked(QModelIndex)), + list, SIGNAL(itemJustBeDoubleClicked(const QModelIndex &))); + + connect(this, SIGNAL(itemPressed(QModelIndex)), list, SIGNAL(itemJustBeSelected(const QModelIndex &))); + connect(this, SIGNAL(currentItemJustChanged(QModelIndex,QModelIndex)), + list, SIGNAL(currentItemJustChanged(const QModelIndex &, const QModelIndex &))); + } + + setStyle(new GLDScrollStyle(this)); +} + +void innerGLD::innerShellTreeView::setModel(QAbstractItemModel *model) +{ + if (m_pDataModel == model) + return; + + m_pDataModel = model; + m_pModel = createSortModel(); + m_pModel->setSortLocaleAware(true); + m_pModel->setSourceModel(m_pDataModel); + + QTreeView::setModel(m_pModel); + adjustColumnWidth(QModelIndex()); + + header()->setSectionsMovable(true); + // setHeaderHidden(true); +} + +QSortFilterProxyModel *innerGLD::innerShellTreeView::createSortModel() +{ + return new GLDFileSortModel(this); +} + +QAbstractItemModel *innerGLD::innerShellTreeView::dataModel() +{ + return m_pDataModel; +} + +QModelIndex innerGLD::innerShellTreeView::dataIndex(const QModelIndex &index) +{ + if (m_pModel != NULL) + { + return m_pModel->mapToSource(index); + } + return QModelIndex(); +} + +QModelIndex innerGLD::innerShellTreeView::proxyIndex(const QModelIndex &index) +{ + if (m_pModel != NULL) + { + return m_pModel->mapFromSource(index); + } + + return QModelIndex(); +} + +void innerGLD::innerShellTreeView::adjustColumnWidth(const QModelIndex &) +{ + header()->setSectionsMovable(true); +// if (-1 != header()->visualIndex(0)) +// header()->setSectionResizeMode(0, QHeaderView::ResizeToContents); +// resizeColumnToContents(0); +} + +void innerGLD::innerShellTreeView::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) +{ + if (GLDListView* list = dynamic_cast(parent())) + { + if (list->m_bShowToolTip) + { + if (1 == selected.size()) + { + if (1 == selected.at(0).indexes().size()) + { + QModelIndex focusIndex = selected.at(0).indexes().at(0); + if (focusIndex.isValid()) + { + setToolTip(focusIndex.data().toString()); + } + } + } + } + } + QTreeView::selectionChanged(selected, deselected); +} + +bool innerGLD::innerShellTreeView::event(QEvent *e) +{ + if (e->type() == QEvent::ToolTip) + { + QHelpEvent *helpEvent = static_cast(e); + QPoint ps = helpEvent->pos(); + if (header()) + { + ps.setY(ps.y() - header()->height()); + } + QModelIndex index = indexAt(ps); + if (index.isValid()) + { + QToolTip::showText(helpEvent->globalPos(), index.data().toString()); + } + else + { + QToolTip::hideText(); + e->ignore(); + } + + return true; + } + return inherit::event(e); +} + +void innerGLD::innerShellTreeView::drawBranches(QPainter *painter, const QRect &rect, const QModelIndex &index) const +{ + if (m_bShowBranches) + { + QTreeView::drawBranches(painter, rect, index); + } +} + +void innerGLD::innerShellTreeView::mousePressEvent(QMouseEvent *event) +{ + QTreeView::mousePressEvent(event); + QModelIndex pressedIndex = indexAt(event->pos()); + setCurrentIndex(pressedIndex); +} + +void innerGLD::innerShellTreeView::mouseDoubleClickEvent(QMouseEvent *event) +{ + QModelIndex tmp = indexAt(event->pos()); + if (tmp.isValid()) + { + if (0 != tmp.column()) + { + tmp = tmp.sibling(tmp.row(), 0); + if (!tmp.isValid()) + return; + } + + bool bcanIntoIndex = true; + if (this->model()) + { + if (GLDCustomFileSystemModel *pModel = dynamic_cast(m_pDataModel)) + { + if (!pModel->isDir(dataIndex(tmp))) + bcanIntoIndex = false; + } + } + emit doubleClicked(dataIndex(tmp)); + } +} + +void innerGLD::innerShellTreeView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) +{ + emit currentItemJustChanged(dataIndex(current), dataIndex(previous)); + QTreeView::currentChanged(current, previous); +} + +void innerGLD::innerShellTreeView::onItemPressed(const QModelIndex &index) +{ + emit itemPressed(dataIndex(index)); +} + +GLDFileSortModel::GLDFileSortModel(QObject *parent) + : QSortFilterProxyModel(parent) +{ + m_oSizeUnits.insert(c_sKB, c_kb); + m_oSizeUnits.insert(c_sMB, c_mb); + m_oSizeUnits.insert(c_sGB, c_gb); + m_oSizeUnits.insert(c_sTB, c_tb); +} + +bool GLDFileSortModel::lessThan(const QModelIndex &left, const QModelIndex &right) const +{ + GLDCustomFileSystemModel *pCustomFileSystemModel = dynamic_cast(sourceModel()); + G_ASSERT(pCustomFileSystemModel != NULL); + + QVariant oLeftData = (left.model() ? left.model()->data(left, sortRole()) : QVariant()); + QVariant oRightData = (right.model() ? right.model()->data(right, sortRole()) : QVariant()); + + GDateTime oLeftDateTime; + GDateTime oRightDateTime; + + // 保证在有桌面的情况下,按照升序排序,显示的顺序为 桌面,C: D: E: + if (oLeftData.type() == QVariant::String) + { + GString sLeftData = oLeftData.toString(); + GString sRightData = oRightData.toString(); + + // 当字段是日期时间类型时, data里面存储的是字符串, 先把字符串转成日期再排序,当前只支持系统默认日期格式 + oLeftDateTime = QDateTime::fromString(sLeftData, "yyyy/M/d H:m"); + oRightDateTime = QDateTime::fromString(sRightData, "yyyy/M/d H:m"); + + if (sLeftData.compare(tr("desktop"), Qt::CaseInsensitive) == 0 && + sRightData.compare(tr("desktop"), Qt::CaseInsensitive) == 0) + { + return false; + } + else if (sLeftData.compare(tr("desktop"), Qt::CaseInsensitive) == 0 && + sRightData.compare(tr("desktop"), Qt::CaseInsensitive) != 0) + { + return true; + } + else if (sLeftData.compare(QObject::tr("desktop"), Qt::CaseInsensitive) != 0 && + sRightData.compare(QObject::tr("desktop"), Qt::CaseInsensitive) == 0) + { + return false; + } + } + + bool bLeftIsDir = pCustomFileSystemModel->isDir(left); + bool bRightIsDir = pCustomFileSystemModel->isDir(right); + + // 先按照节点的类型比较,分为目录和文件,如果都是文件情况下,排序的列为“大小”列,走特性的大小比较逻辑 + if (bLeftIsDir && bRightIsDir) + { + if (oLeftDateTime.isValid() || oRightDateTime.isValid()) + { + if (oLeftDateTime < oRightDateTime) + { + return true; + } + else + { + return false; + } + } + else + { + return QSortFilterProxyModel::lessThan(left, right); + } + } + + else if (bLeftIsDir && !bRightIsDir) + return true; + else if (!bLeftIsDir && bRightIsDir) + return false; + else if (!bLeftIsDir && !bRightIsDir) + { + if (left.model()->headerData(left.column(), Qt::Horizontal).toString() == tr("Size")) + { + return sizeCompare(oLeftData, oRightData); + } + else + { + if (oLeftDateTime.isValid() || oRightDateTime.isValid()) + { + if (oLeftDateTime < oRightDateTime) + { + return true; + } + else + { + return false; + } + } + else + { + return QSortFilterProxyModel::lessThan(left, right); + } + } + } + else + { + return true; + } +} + +bool GLDFileSortModel::sizeCompare(const QVariant &oLeftData, const QVariant &oRightData) const +{ + GString sLeftData = oLeftData.toString().trimmed(); + GString sRightData = oRightData.toString().trimmed(); + + if (sLeftData.isEmpty()) + return true; + else if (sRightData.isEmpty()) + return false; + + GString sLeftSizeUnit = sLeftData.right(c_nSizeUnitLength).toUpper(); + GString sRightSizeUnit = sRightData.right(c_nSizeUnitLength).toUpper(); + + double dRelativeLeftSize = sLeftData.left(sLeftData.size() - c_nSizeUnitLength).trimmed().toDouble(); + double dRelativeRightSize = sRightData.left(sRightData.size() - c_nSizeUnitLength).trimmed().toDouble(); + + quint64 nAbsoluteLeftSize = dRelativeLeftSize * m_oSizeUnits.value(sLeftSizeUnit); + quint64 nAbsoluteRightSize = dRelativeRightSize * m_oSizeUnits.value(sRightSizeUnit); + + return nAbsoluteLeftSize < nAbsoluteRightSize; +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDMaskBox.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDMaskBox.cpp new file mode 100644 index 00000000..9ae21cc2 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDMaskBox.cpp @@ -0,0 +1,537 @@ +#include "GLDMaskBox.h" + +#include +#include +#include +#include + +GLDMaskBox* GLDMaskBox::m_pMaskBox = nullptr; + +GLDMaskBox::GLDMaskBox(QWidget *parent) + : QWidget(parent) + , m_maskColor(GLDMaskBox::GrayColor) + , m_pClippedWgt(nullptr) + , m_pTipBox(nullptr) + , m_pSettings(nullptr) + , m_bShowMask(false) +{ + m_pTipBox = new GLDIrregularForm(""/*exePath() + "/images/Msg/login.png"*/,""/* exePath() + "/images/Msg/know.png"*/, this); + + setFixedSize(QApplication::desktop()->width(), QApplication::desktop()->height()); + + connect(m_pTipBox, &GLDIrregularForm::irregularFormClicked, this, &GLDMaskBox::slotClose); +} + +GLDMaskBox::GLDMaskBox(GLDMaskBoxParam& param, QWidget * parent) + : QWidget(parent) + , m_maskColor(GLDMaskBox::GrayColor) + , m_pClippedWgt(nullptr) + , m_pTipBox(nullptr) + , m_pSettings(nullptr) + , m_bShowMask(false) + , m_arrowColor(QColor(1, 169, 240)) + , m_arrowLineWidth(2) +{ + m_oMaskBoxParam = param; + m_pClippedWgt = param.m_maskWidget; + m_pTipBox = new GLDIrregularForm(param.m_strTipPath, param.m_strBtnPath, this); + + setFixedSize(QApplication::desktop()->width(), QApplication::desktop()->height()); + + connect(m_pTipBox, &GLDIrregularForm::irregularFormClicked, this, &GLDMaskBox::slotClose); +} + +GLDMaskBox::~GLDMaskBox() +{ + +} + +void GLDMaskBox::paintEvent(QPaintEvent * event) +{ + QWidget::paintEvent(event); + + QPainter painter(this); + + const int nClippedWidgetWidth = m_pClippedWgt->size().width(); + const int nClippedWidgetHeight = m_pClippedWgt->size().height(); + + QPoint clippedWgtTopLeft = m_pClippedWgt->rect().topLeft(); + QPoint ptGlobalTopLeft = m_pClippedWgt->mapToParent(clippedWgtTopLeft); + QRect pOwnerRect(ptGlobalTopLeft.x(), ptGlobalTopLeft.y(), nClippedWidgetWidth, nClippedWidgetHeight); + + + + QPoint clippedWgtTopRight = m_pClippedWgt->rect().topRight(); + QPoint ptGlobalTopRight = m_pClippedWgt->mapToParent(clippedWgtTopRight); + + + int w = GLDCBB::topParentWidget(m_pClippedWgt)->width(); + + CoordinateParam param = calcPosOfTipInfo(); + + if(param.m_quadrant == CoordinateParam::Third || param.m_quadrant == CoordinateParam::Fourth) + { + if(w - ptGlobalTopRight.x() > m_pTipBox->width() && ptGlobalTopRight.y() > m_pTipBox->height()) + { + QPoint endPoint; + drawLeftBottomArrow(param.m_point, endPoint, painter); + endPoint += QPoint(0, -m_pTipBox->height()); + m_pTipBox->move(endPoint); + } + } + else if(param.m_quadrant == CoordinateParam::First || param.m_quadrant == CoordinateParam::Second) + { + QPoint endPoint; + drawLeftTopArrow(param.m_point, endPoint, painter); + m_pTipBox->move(endPoint); + } + + QRegion rect = this->rect(); + rect -= pOwnerRect; + painter.setClipRegion(rect); + + drawMask(painter); +} + +void GLDMaskBox::drawMask(QPainter & painter) +{ + int w = GLDCBB::topParentWidget(m_pClippedWgt)->size().width(); + int h = GLDCBB::topParentWidget(m_pClippedWgt)->size().height(); + + QColor color; + + switch (m_maskColor) + { + case GLDMaskBox::GrayColor: // 128, 128, 128 + color = QColor(0, 0, 0, 100); + break; + + case GLDMaskBox::GlassColor: // 201, 120, 12 + color = QColor(201, 120, 12); + break; + + case GLDMaskBox::CalaeattaColor: // 252, 239, 232 + color = QColor(252, 239, 232); + break; + + case GLDMaskBox::CreamColor: // 233, 241, 246 + color = QColor(233, 241, 246); + break; + + default: + color = QColor(128, 128, 128); + } + + painter.setRenderHints(QPainter::SmoothPixmapTransform | QPainter::Antialiasing); + painter.setPen(QPen(color)); + painter.setBrush(color); + painter.drawRect(1, 1, w - 2, h - 2); + + painter.setBrush(color); + QPainter::CompositionMode mode = painter.compositionMode(); + painter.setCompositionMode(QPainter::CompositionMode_Xor); + + int clippedWgtWidth = m_pClippedWgt->size().width(); + int clippedWgtHeight = m_pClippedWgt->size().height(); + QPoint globalTopLeft = m_pClippedWgt->mapToParent(m_pClippedWgt->rect().topLeft()); + painter.drawRect(globalTopLeft.x(), globalTopLeft.y(), clippedWgtWidth, clippedWgtHeight); + + painter.setCompositionMode(mode); + painter.setBrush(Qt::NoBrush); + painter.setPen(QPen(color, 2)); + painter.drawRect(globalTopLeft.x(), globalTopLeft.y(), clippedWgtWidth, clippedWgtHeight); +} + +void GLDMaskBox::drawLeftTopArrow(QPoint &startPoint, QPoint &endPoint, QPainter &painter) +{ + int x = startPoint.x(); + int y = startPoint.y(); + + int x1 = x + 70; + int y1 = y + 50; + endPoint = QPoint(x1, y1); + + painter.setPen(QPen(m_arrowColor, m_arrowLineWidth)); + painter.setRenderHint(QPainter::Antialiasing); + + QPainterPath path; + path.moveTo(startPoint); + + QPoint point1((x + (x1 - x) * 3 / 10), (y + (y1 - y) * 4 / 7)); + QPoint point2((x + (x1 - x) * 4 / 10), (y + (y1 - y) * 6 / 7)); + QPoint point3((x + (x1 - x) * 8 / 10), (y + (y1 - y) * 3 / 7)); + path.cubicTo(point1, point2, point3); + + + QPoint point4((x + (x1 - x) * 5 / 10), (y + (y1 - y) * 1 / 7)); + QPoint point5((x + (x1 - x) * 3 / 10), (y + (y1 - y) * 2 / 7)); + QPoint point6((x + (x1 - x) * 4 / 10), (y + (y1 - y) * 9 / 14)); + path.cubicTo(point4, point5, point6); + + QPoint point7((x + (x1 - x) * 5 / 10), (y + (y1 - y) * 6 / 7)); + QPoint point8((x + (x1 - x) * 5 / 10), (y + (y1 - y) * 7 / 7)); + path.cubicTo(point7, point8, endPoint); + + painter.drawPath(path); + + int xOffset = (x1 - x) / 5; + QLine line1(startPoint, QPoint(x + 2, y + xOffset)); + int yOffset = (y1 - y) / 7; + QLine line2(startPoint, QPoint(x + xOffset, y + yOffset)); + painter.drawLine(line1); + painter.drawLine(line2); +} + +void GLDMaskBox::drawLeftBottomArrow(QPoint &startPoint, QPoint &endPoint, QPainter &painter) +{ + int x = startPoint.x(); + int y = startPoint.y(); + + int x1 = x + 70; + int y1 = y + 50; + endPoint = QPoint(x1, y - 50); + + painter.setPen(QPen(m_arrowColor, m_arrowLineWidth)); + painter.setRenderHint(QPainter::Antialiasing); + + QPainterPath path; + path.moveTo(startPoint); + + QPoint point1((x + (x1 - x) * 3 / 10), (y - (y1 - y) * 4 / 7)); + QPoint point2((x + (x1 - x) * 4 / 10), (y - (y1 - y) * 6 / 7)); + QPoint point3((x + (x1 - x) * 8 / 10), (y - (y1 - y) * 3 / 7)); + path.cubicTo(point1, point2, point3); + + + QPoint point4((x + (x1 - x) * 5 / 10), (y - (y1 - y) * 1 / 7)); + QPoint point5((x + (x1 - x) * 3 / 10), (y - (y1 - y) * 2 / 7)); + QPoint point6((x + (x1 - x) * 4 / 10), (y - (y1 - y) * 9 / 14)); + path.cubicTo(point4, point5, point6); + + QPoint point7((x + (x1 - x) * 5 / 10), y - 50); + QPoint point8((x + (x1 - x) * 5 / 10), y - 50); + path.cubicTo(point7, point8, endPoint); + + painter.drawPath(path); + + int xOffset = (x1 - x) * 2 / 10; + QLine line1(startPoint, QPoint(x + 2, y - xOffset)); + int yOffset = (y1 - y) * 1 / 7; + QLine line2(startPoint, QPoint(x + xOffset, y - yOffset)); + painter.drawLine(line1); + painter.drawLine(line2); +} + +void GLDMaskBox::mousePressEvent(QMouseEvent * event) +{ + QPoint ptGlobalOwnerCenter = m_pClippedWgt->mapToParent(m_pClippedWgt->rect().topLeft()); + QRect rect(ptGlobalOwnerCenter.rx(), ptGlobalOwnerCenter.ry(), + m_pClippedWgt->width(), m_pClippedWgt->height()); + + if (rect.contains(event->pos())) + { + emit customClicked(); + } + + QWidget::mousePressEvent(event); +} + +void GLDMaskBox::openIniFile(const QString& filePath) +{ + Q_ASSERT(!filePath.isEmpty()); + + if (filePath.isEmpty()) + { + return; + } + + m_pSettings = new QSettings(filePath, QSettings::IniFormat, this); + + Q_ASSERT(m_pSettings->status() == QSettings::NoError); + + m_pSettings->sync(); + m_pSettings->setFallbacksEnabled(true); + + setMaskShow(); +} + +GLDMaskBox* GLDMaskBox::createMaskFor(QWidget* widget, const QString & tipInfoPath, const QString & btnInfoPath) +{ + GLDMaskBox* pTip = nullptr; + +// if (!m_bShowMask) +// { +// return nullptr; +// } + + do + { + if (!widget) + { + break; + } + + GLDMaskBoxParam param; + param.m_maskWidget = widget; + param.m_strTipPath = tipInfoPath; + param.m_strBtnPath = btnInfoPath; + + QWidget* pWidget = GLDCBB::topParentWidget(widget); + pTip = new GLDMaskBox(param, pWidget); + + m_pMaskBox = pTip; + + pTip->show(); + + } while (0); + + return pTip; +} + +void GLDMaskBox::setMaskColor(MASKCOLOR maskColor) +{ + if(maskColor == m_maskColor) + { + return; + } + + m_maskColor = maskColor; +} + +void GLDMaskBox::setArrowColor(const QColor &color) +{ + m_arrowColor = color; +} + +void GLDMaskBox::setArrowLineWidth(const int lineWidth) +{ + m_arrowLineWidth = lineWidth; +} + +QPoint GLDMaskBox::calcPosOfOwner() +{ + QPoint pt(0, 0); + + do + { + // 计算owner位置对应屏幕中心的象限 + if (!m_pClippedWgt) + { + break; + } + + QPoint ptGlobalOwnerCenter = m_pClippedWgt->mapToGlobal(m_pClippedWgt->rect().center()); + QPoint ptGlobalScreen = QApplication::desktop()->screenGeometry().center(); + QPoint ptDelta = ptGlobalOwnerCenter - ptGlobalScreen; + + if (ptDelta.x() >= 0 && ptDelta.y() <= 0) + { + // 第一象限 + pt = QPoint(ptGlobalOwnerCenter.x() - m_pClippedWgt->width()/2, + ptGlobalOwnerCenter.y() + m_pClippedWgt->height()/2); + pt += QPoint(-this->width()/2, 0); + } + else if (ptDelta.x() <= 0 && ptDelta.y() <= 0) + { + // 第二象限 + pt = QPoint(ptGlobalOwnerCenter.x() + m_pClippedWgt->width()/2, + ptGlobalOwnerCenter.y() + m_pClippedWgt->height()/2); + pt += QPoint(-this->width()/2, 0); + } + else if (ptDelta.x() <= 0 && ptDelta.y() >= 0) + { + // 第三象限 + pt = QPoint(ptGlobalOwnerCenter.x() + m_pClippedWgt->width()/2, + ptGlobalOwnerCenter.y() - m_pClippedWgt->height()/2); + pt += QPoint(-this->width()/2, -this->height()); + } + else if (ptDelta.x() >= 0 && ptDelta.y() >= 0) + { + // 第四象限 + pt = QPoint(ptGlobalOwnerCenter.x() - m_pClippedWgt->width()/2, + ptGlobalOwnerCenter.y() - m_pClippedWgt->height()/2); + pt += QPoint(-this->width()/2, -this->height()); + } + + // 超出屏幕范围的校准 + QRect rcThis(pt, pt + QPoint(this->width(), this->height())); + QRect rcScreen = QApplication::desktop()->screenGeometry(); + + if (!rcScreen.contains(rcThis.topLeft())) + { + int nXOffset = rcThis.topLeft().x() - rcScreen.topLeft().x(); + int nYOffset = rcThis.topLeft().y() - rcScreen.topLeft().y(); + + if (nXOffset < 0) + { + pt.setX(pt.x() - nXOffset); + } + + if (nYOffset < 0) + { + pt.setY(pt.y() - nYOffset); + } + } + else if (!rcScreen.contains(rcThis.topRight())) + { + int nXOffset = rcThis.topRight().x() - rcScreen.topRight().x(); + int nYOffset = rcThis.topRight().y() - rcScreen.topRight().y(); + + if (nXOffset > 0) + { + pt.setX(pt.x() - nXOffset); + } + + if (nYOffset < 0) + { + pt.setY(pt.y() - nYOffset); + } + } + else if (!rcScreen.contains(rcThis.bottomLeft())) + { + int nXOffset = rcThis.bottomLeft().x() - rcScreen.bottomLeft().x(); + int nYOffset = rcThis.bottomLeft().y() - rcScreen.bottomLeft().y(); + + if (nXOffset < 0) + { + pt.setX(pt.x() - nXOffset); + } + + if (nYOffset > 0) + { + pt.setY(pt.y() - nYOffset); + } + } + else if (!rcScreen.contains(rcThis.bottomRight())) + { + int nXOffset = rcThis.bottomRight().x() - rcScreen.bottomRight().x(); + int nYOffset = rcThis.bottomRight().y() - rcScreen.bottomRight().y(); + + if (nXOffset > 0) + { + pt.setX(pt.x() - nXOffset); + } + + if (nYOffset > 0) + { + pt.setY(pt.y() - nYOffset); + } + } + + } while(0); + + return pt; +} + +CoordinateParam GLDMaskBox::calcPosOfTipInfo() +{ + CoordinateParam coordinateParam; + + do + { + // 计算owner位置对应屏幕中心的象限 + if (!m_pClippedWgt) + { + break; + } + + QPoint clippedWgtTopLeft = m_pClippedWgt->rect().topLeft(); + QPoint ptParentOwnerTopLeft = m_pClippedWgt->mapToParent(clippedWgtTopLeft); + + QPoint ptGlobalOwnerCenter = m_pClippedWgt->mapToGlobal(m_pClippedWgt->rect().center()); + QPoint ptGlobalScreen = QApplication::desktop()->screenGeometry().center(); + QPoint ptDelta = ptGlobalOwnerCenter - ptGlobalScreen; + + if (ptDelta.x() >= 0 && ptDelta.y() <= 0) + { + // 第一象限 + coordinateParam.m_point = QPoint(ptParentOwnerTopLeft.x() + m_pClippedWgt->width() / 2, + ptParentOwnerTopLeft.y() + m_pClippedWgt->height()); + coordinateParam.m_quadrant = CoordinateParam::First; + } + else if(ptDelta.x() <= 0 && ptDelta.y() <= 0) + { + // 第二象限 + coordinateParam.m_point = QPoint(ptParentOwnerTopLeft.x() + m_pClippedWgt->width() / 2, + ptParentOwnerTopLeft.y() + m_pClippedWgt->height()); + coordinateParam.m_quadrant = CoordinateParam::Second; + } + else if(ptDelta.x() <= 0 && ptDelta.y() >= 0) + { + // 第三象限 + coordinateParam.m_point = QPoint(ptParentOwnerTopLeft.x() + m_pClippedWgt->width() / 2, + ptParentOwnerTopLeft.y()); + coordinateParam.m_quadrant = CoordinateParam::Third; + + } + else if(ptDelta.x() >= 0 && ptDelta.y() >= 0) + { + coordinateParam.m_point = QPoint(ptParentOwnerTopLeft.x() + m_pClippedWgt->width() / 2, + ptParentOwnerTopLeft.y()); + coordinateParam.m_quadrant = CoordinateParam::Fourth; + } + + } while (0); + + return coordinateParam; +} + +void GLDMaskBox::setMaskShow() +{ + m_bShowMask = getMaskShow(tr("Mask"), tr("MaskShow")); +} + +bool GLDMaskBox::getMaskShow(const QString &prefix, const QString &key) +{ + Q_ASSERT(m_pSettings != NULL); + + QString strValue = getValue(prefix, key); + + if (!strValue.isEmpty()) + { + if (strValue == "true") + { + // 这个函数是在最终发布的时候打开,那么蒙版只会在第一次启动的时候被调用 + // 暂时在测试功能中,先注掉,方便调试 + // setValue(prefix, key); + return true; + } + + return false; + } + + return false; +} + +QString GLDMaskBox::getValue(const QString &prefix, const QString &key) +{ + Q_ASSERT(m_pSettings != NULL); + + QString strValue; + m_pSettings->beginGroup(prefix); + QVariant value = m_pSettings->value(key); + + if (value.isValid() && value.type() == QVariant::String) + { + strValue = value.toString(); + } + + m_pSettings->endGroup(); + + return strValue; +} + +void GLDMaskBox::setValue(const QString &prefix, const QString &key) +{ + Q_ASSERT(m_pSettings != NULL); + + m_pSettings->beginGroup(prefix); + m_pSettings->setValue(key, "fasle"); + + m_pSettings->endGroup(); +} + +void GLDMaskBox::slotClose() +{ + this->close(); +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDMultiHeaderView.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDMultiHeaderView.cpp new file mode 100644 index 00000000..95f8b520 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDMultiHeaderView.cpp @@ -0,0 +1,2310 @@ +#include "GLDMultiHeaderView.h" +#include "GLDMultiHeaderView_p.h" +#include "GLDAbstractItemModel.h" +#include "GLDTableView.h" + +GlodonMultiHeaderView::GlodonMultiHeaderView(Qt::Orientation orientation, QWidget *parent) + : GlodonHeaderView(orientation, parent) +{ + headerData = new GHeaderSpanCollection(); + + pressedHeaderSpan = -1; + headerSpanIndicator = 0; + headerSpanIndicatorOffset = 0; + headerSpanIndicatorDrawPos = -1; + moveStartSpan = -1; +} + +GlodonMultiHeaderView::~GlodonMultiHeaderView() +{ + delete headerData; +} + +void GlodonMultiHeaderView::resizeSection(int logicalIndex, int size, bool update, bool isManual) +{ + GlodonHeaderView::resizeSection(logicalIndex, size, update, isManual); + + for (int i = 0; i < headerList.count(); i++) + { + headerList[i]->resizeSection(logicalIndex, size, update, isManual); + } + + updateSection(logicalIndex); +} + +void GlodonMultiHeaderView::setModel(QAbstractItemModel *model) +{ + headerData->spans.clear(); + headerList.clear(); + GlodonHeaderView::setModel(model); + initTitles(); + + const int nCount = headerList.count(); + for (int i = 0; i < nCount; i++) + { + headerList.at(i)->setModel(model); + } +} + +int GlodonMultiHeaderView::extraCount() const +{ + return headerList.count(); +} + +void GlodonMultiHeaderView::setExtraCount(int count) +{ + Q_D(GlodonMultiHeaderView); + headerList.clear(); + + if (count == -1) + { + return; + } + + headerList.resize(count); + + for (int i = 0; i < count; i++) + { + headerList[i] = new GlodonHeaderView(orientation(), this); + headerList[i]->setHidden(false); + + if (d->m_model) + { + headerList[i]->setModel(d->m_model); + } + } +} + +int GlodonMultiHeaderView::drawWidth() const +{ + int nwidth = 0; + + if (orientation() == Qt::Horizontal) + { + for (int i = 0; i < headerList.count(); i++) + { + if (headerList[i]->minimumHeight() == 0) + { + nwidth += headerList[i]->drawWidth(); + } + else + { + nwidth += headerList[i]->minimumHeight(); + } + } + + if (minimumHeight() == 0) + { + nwidth += GlodonHeaderView::drawWidth(); + } + else + { + nwidth += minimumHeight(); + } + } + else + { + for (int i = 0; i < headerList.count(); i++) + { + nwidth += headerList[i]->drawWidth(); + } + + nwidth += GlodonHeaderView::drawWidth(); + } + + return nwidth; +} + +void GlodonMultiHeaderView::updateGeometries() +{ + for (int i = 0; i < headerList.count(); i++) + { + headerList[i]->updateGeometries(); + } + + GlodonHeaderView::updateGeometries(); +} + +void GlodonMultiHeaderView::paintEvent(QPaintEvent *e) +{ + Q_D(GlodonMultiHeaderView); + QPainter painter(d->viewport); + const QPoint c_offset = d->m_scrollDelayOffset; + QRect translatedEventRect = e->rect(); + translatedEventRect.translate(c_offset); + + int nstart = -1; + int nend = -1; + + if (d->orientation == Qt::Horizontal) + { + nstart = visualIndexAt(translatedEventRect.left()); + nend = visualIndexAt(translatedEventRect.right()); + } + else + { + nstart = visualIndexAt(translatedEventRect.top()); + nend = visualIndexAt(translatedEventRect.bottom()); + } + + int ntmp = nstart; + nstart = qMin(nstart, nend); + nend = qMax(ntmp, nend); + + QRect fixedRect(0, 0, 0, 0); + QRect scrollRect = d->viewport->rect(); + + if (d->fixedCount > 0) + { + if (d->orientation == Qt::Vertical) + { + int nheight = 0; + + for (int i = 0; i < d->fixedCount; i++) + { + nheight += sectionSize(i) + d->gridLineWidth; + } + + fixedRect.adjust(0, 0, d->viewport->width(), nheight); + scrollRect.adjust(0, nheight, 0, 0); + } + else + { + int nwidth = 0; + + for (int i = 0; i < d->fixedCount; i++) + { + nwidth += sectionSize(i) + d->gridLineWidth; + } + + fixedRect.adjust(0, 0, nwidth, d->viewport->height()); + scrollRect.adjust(nwidth, 0, 0, 0); + } + + painter.setClipRect(scrollRect); + } + + QRect currentSectionRect(0, 0, 0, 0); + + for (int i = 0; i < headerData->spans.count(); i++) + { + painter.save(); + bool bPaint = true; + currentSectionRect = headerSpanRect(i); + + if (d->orientation == Qt::Vertical) + { + if (headerData->spans[i]->bottom() >= d->fixedCount) + { + painter.setClipRect(scrollRect); + + if (currentSectionRect.bottom() <= fixedRect.bottom()) + { + bPaint = false; + } + } + else + { + painter.setClipRect(fixedRect); + } + } + else + { + if (headerData->spans[i]->right() >= d->fixedCount) + { + painter.setClipRect(scrollRect); + + if (currentSectionRect.right() <= fixedRect.right()) + { + bPaint = false; + } + } + else + { + painter.setClipRect(fixedRect); + } + } + + if (bPaint) + { + paintSpanHeader(&painter, currentSectionRect, headerData->spans.at(i)); + } + + painter.restore(); + } +} + +void GlodonMultiHeaderView::deselectedHeaderSpans() +{ + for (int i = 0; i < headerData->spans.count(); i++) + { + if (i == pressedHeaderSpan || inTopHeaderRange(pressedHeaderSpan, i)) + { + continue; + } + + if (headerData->spans[i]->selected()) + { + headerData->spans[i]->setSelected(false); + updateHeaderSpan(i); + } + } +} + +void GlodonMultiHeaderView::mousePressEvent(QMouseEvent *e) +{ + Q_D(GlodonMultiHeaderView); + + d->m_isMouseDoubleClick = false; + + if (d->m_state != GlodonHeaderViewPrivate::NoState || e->button() != Qt::LeftButton) + { + return; + } + + int npos = d->orientation == Qt::Horizontal ? e->x() : e->y(); + int nindex = headerSpanAt(e->pos()); + + if (nindex != -1) + { + d->pressed = logicalIndexAt(npos); + + pressedHeaderSpan = nindex; + + if (d->clickableSections) + { + deselectedHeaderSpans(); + selectHeaderSpan(pressedHeaderSpan, true); + +// emit sectionPressed(d->pressed); //执行功能跟headerSpanPressed类似,暂去掉-By Huangp + GLDHeaderSpan span = *headerData->spans[pressedHeaderSpan]; + emit headerSpanPressed(span.left(), span.top(), span.right(), span.bottom()); + } + + if (d->movableSections && headerData->spans.count() > nindex && headerData->spans[nindex]->selected()) + { + moveStartSpan = pressedHeaderSpan; + + d->section = d->target = d->pressed; + + if (d->section == -1 || d->section < d->fixedCount) + { + return; + } + + d->m_state = GlodonHeaderViewPrivate::MoveSection; + setupHeaderSpanIndicator(npos); + } + else if (d->clickableSections && pressedHeaderSpan != -1) + { + d->m_state = GlodonHeaderViewPrivate::SelectSections; + } + } + else + { + int nhandle = d->sectionHandleAt(npos); + + if ((resizeMode(nhandle) == Interactive) && (npos < length())) + { + d->m_mousePosition = e->pos(); + //当第一次按下时,获取的是鼠标所在屏幕的位置,方便tableview中的InfoFrame的正确移动 + QPoint point = e->screenPos().toPoint(); + emit sectionResizing(point, orientation(), Press); + d->viewport->update(d->m_mousePosition.x(), 0, 1, height()); + + d->originalSize = sectionSize(nhandle); + d->m_state = GlodonHeaderViewPrivate::ResizeSection; + d->section = nhandle; + } + } + + d->firstPos = npos; + d->lastPos = npos; + + d->clearCascadingSections(); +} + +void GlodonMultiHeaderView::mouseMoveEvent(QMouseEvent *e) +{ + Q_D(GlodonMultiHeaderView); + int npos = d->orientation == Qt::Horizontal ? e->x() : e->y(); + + if (npos < 0) + { + return; + } + + if (e->buttons() == Qt::NoButton) + { + d->m_state = GlodonHeaderViewPrivate::NoState; + pressedHeaderSpan = -1; + d->pressed = -1; + } + + switch (d->m_state) + { + case GlodonHeaderViewPrivate::ResizeSection: + { + Q_ASSERT(d->originalSize != -1); + emit sectionResizing(d->m_mousePosition, orientation(), Move); + d->m_mousePosition = e->pos(); + d->viewport->update(); + + if (!d->resizeDelay) + { + if (d->cascadingResizing) + { + int ndelta = d->reverse() ? d->lastPos - npos : npos - d->lastPos; + int nVisualIndex = visualIndex(d->section); + d->cascadingResize(nVisualIndex, d->headerSectionSize(nVisualIndex) + ndelta, true); + } + else + { + int ndelta = d->reverse() ? d->firstPos - npos : npos - d->firstPos; + resizeSection(d->section, qMax(d->originalSize + ndelta, minimumSectionSize()), true, true); + } + } + + d->lastPos = npos; + return; + } + + case GlodonHeaderViewPrivate::MoveSection: + { + if (qAbs(npos - d->firstPos) >= QApplication::startDragDistance() + || !headerSpanIndicator->isHidden()) + { + int nVisualIndex = visualIndexAt(npos); + + if (nVisualIndex == -1) + { + return; + } + + int nposThreshold = sectionViewportPosition(logicalIndexAt(npos)) + + d->headerSectionSize(nVisualIndex) / 2; + int nmoving = visualIndex(d->section); + + if (nVisualIndex < nmoving) + { + if (npos < nposThreshold) + { + d->target = d->logicalIndex(nVisualIndex); + } + else + { + d->target = d->logicalIndex(nVisualIndex + 1); + } + } + else if (nVisualIndex > nmoving) + { + if (npos > nposThreshold) + { + d->target = d->logicalIndex(nVisualIndex); + } + else + { + d->target = d->logicalIndex(nVisualIndex - 1); + } + } + else + { + d->target = d->section; + } + + updateHeaderSpanIndicator(npos); + + bool bhasCursor = testAttribute(Qt::WA_SetCursor); + + if (!checkCanMove(d->target)) + { + if (!bhasCursor) + { + setCursor(Qt::ForbiddenCursor); + } + } + else if (bhasCursor) + { + unsetCursor(); + } + } + + return; + } + + case GlodonHeaderViewPrivate::SelectSections: + { + int nlogical = logicalIndexAt(npos); + + if (nlogical == d->pressed) + { + return; + } + else if (d->pressed != -1) + { + updateSection(d->pressed); + } + + d->pressed = nlogical; + + if (d->clickableSections && nlogical != -1) + { + emit sectionEntered(d->pressed); + + if (d->orientation == Qt::Horizontal) + { + int nindex = headerData->spanAt(extraCount(), d->pressed); + selectHeaderSpan(nindex, d->isColumnSelected(d->pressed)); + updateHeaderSpan(nindex); + } + else + { + int nindex = headerData->spanAt(d->pressed, extraCount()); + selectHeaderSpan(nindex, d->isRowSelected(d->pressed)); + updateHeaderSpan(nindex); + } + } + + return; + } + + case GlodonHeaderViewPrivate::NoState: + { + int nsectionhandle = -1; + int nhandle = headerSpanAt(e->pos()); + + if (nhandle == -1) + { + nsectionhandle = d->sectionHandleAt(npos); + } + + bool bhasCursor = testAttribute(Qt::WA_SetCursor); + + if (nsectionhandle != -1 && (resizeMode(nsectionhandle) == Interactive)) + { + if (!bhasCursor) + { + setCursor(d->orientation == Qt::Horizontal ? Qt::SplitHCursor : Qt::SplitVCursor); + } + } + else if (bhasCursor) + { + unsetCursor(); + } + + return; + } + + default: + break; + } +} + +void GlodonMultiHeaderView::mouseReleaseEvent(QMouseEvent *e) +{ + Q_D(GlodonMultiHeaderView); + int npos = d->orientation == Qt::Horizontal ? e->x() : e->y(); + + switch (d->m_state) + { + case GlodonHeaderViewPrivate::MoveSection: + { + if (checkCanMove(d->target) + && !headerSpanIndicator->isHidden()) + { + int ntargetSection = visualIndex(d->target); + int nmovingSectoin = visualIndex(d->section); + GLDHeaderSpan visualHeaderSpan = visualSpan(moveStartSpan); + + bool bcanMove = true; + + int ntargetSpanIndex = headerSpanAt(e->pos()); + + if (ntargetSpanIndex >= d->fixedCount && ntargetSpanIndex >= 0 && ntargetSpanIndex < headerData->spans.count() + && moveStartSpan >= 0 && moveStartSpan < headerData->spans.count()) + { + HeaderSpanRelation relation = + headerData->spans[ntargetSpanIndex]->spanRelation(*(headerData->spans[moveStartSpan])); + + if (relation == AdjacentIrrelevant || relation == Contain || relation == Overlapping) + { + bcanMove = false; + } + else + { + emit canSectionMove(d->section, d->target, bcanMove); + if (isLogicalSectionMovable()) + { + d->section = d->target = -1; + updateHeaderSpanIndicator(npos); + break; + } + } + } + else + { + bcanMove = false; + } + + if (bcanMove) + { + if (ntargetSection >= nmovingSectoin) + { + if (d->orientation == Qt::Horizontal) + { + for (int i = visualHeaderSpan.left(); i <= visualHeaderSpan.right(); i++) + { + moveSection(visualHeaderSpan.left(), ntargetSection); + } + } + else + { + for (int i = visualHeaderSpan.top(); i <= visualHeaderSpan.bottom(); i++) + { + moveSection(visualHeaderSpan.top(), ntargetSection); + } + } + } + else + { + if (d->orientation == Qt::Horizontal) + { + for (int i = visualHeaderSpan.right(); i >= visualHeaderSpan.left(); i--) + { + moveSection(visualHeaderSpan.right(), ntargetSection); + } + } + else + { + for (int i = visualHeaderSpan.bottom(); i >= visualHeaderSpan.top(); i--) + { + moveSection(visualHeaderSpan.bottom(), ntargetSection); + } + } + } + } + + d->section = d->target = -1; + updateHeaderSpanIndicator(npos); + break; + } + else + { + d->target = -1; + updateHeaderSpanIndicator(npos); + } + } + + case GlodonHeaderViewPrivate::SelectSections: + { + if (!d->clickableSections) + { + int nsection = logicalIndexAt(npos); + updateSection(nsection); + } + +// break; + } // fall through + + case GlodonHeaderViewPrivate::NoState: + { + if (d->clickableSections) + { + int nsection = logicalIndexAt(npos); + + if (nsection != -1 && nsection == d->pressed) + { + d->flipSortIndicator(nsection); + emit sectionClicked(nsection); + } + + if (d->pressed != -1) + { + updateSection(d->pressed); + } + } + + break; + } + + case GlodonHeaderViewPrivate::ResizeSection: + { + if (d->resizeDelay && !d->m_isMouseDoubleClick) + { + if (d->cascadingResizing) + { + int ndelta = d->reverse() ? d->lastPos - npos : npos - d->lastPos; + int nVisualIndex = visualIndex(d->section); + d->cascadingResize(nVisualIndex, d->headerSectionSize(nVisualIndex) + ndelta, true); + } + else + { + int ndelta = d->reverse() ? d->firstPos - npos : npos - d->firstPos; + resizeSection(d->section, qMax(d->originalSize + ndelta, minimumSectionSize()), true, true); + } + } + + emit sectionResizing(d->m_mousePosition, orientation(), Finish); + + if (orientation() == Qt::Horizontal) + { + d->viewport->update(d->m_mousePosition.x(), 0, 1, height()); + } + else + { + d->viewport->update(0, d->m_mousePosition.y(), width(), 1); + } + + d->originalSize = -1; + d->clearCascadingSections(); + break; + } + + default: + break; + } + + d->m_state = GlodonHeaderViewPrivate::NoState; + d->pressed = -1; +} + +void GlodonMultiHeaderView::initTitles() +{ + Q_D(GlodonMultiHeaderView); + headerList.clear(); + resetSpan(); + + recoverMinimumHeights(); + + d->viewport->update(); +} + +int GlodonMultiHeaderView::headerSpanAt(QPoint point) +{ + Q_D(GlodonMultiHeaderView); + + int ncolPos = point.x(); + int nrowPos = point.y(); + + if (d->orientation == Qt::Vertical) + { + int row = logicalIndexAt(nrowPos); + int col = 0; + + for (col = 0; col < headerList.count(); col++) + { + ncolPos -= headerList[col]->drawWidth(); + + if (ncolPos <= 0) + { + break; + } + } + + int nindex = headerData->spanAt(row, col); + QRect rect = headerSpanRect(nindex); + int ngrip = style()->pixelMetric(QStyle::PM_HeaderGripMargin, 0, this); + + if (qAbs(rect.top() - nrowPos) <= ngrip || qAbs(rect.bottom() - nrowPos) <= ngrip) + { + return -1; + } + else + { + return nindex; + } + } + else + { + int col = logicalIndexAt(ncolPos); + int row = 0; + + for (row = 0; row < headerList.count(); row++) + { + nrowPos -= headerList[row]->drawWidth(); + + if (nrowPos <= 0) + { + break; + } + } + + int nIndex = headerData->spanAt(row, col); + QRect rect = headerSpanRect(nIndex); + int nGrip = style()->pixelMetric(QStyle::PM_HeaderGripMargin, 0, this); + + if (qAbs(rect.left() - ncolPos) <= nGrip || qAbs(rect.right() - ncolPos) <= nGrip) + { + return -1; + } + else + { + return nIndex; + } + } +} + +QRegion GlodonMultiHeaderView::visualRegionForSelection(const QItemSelection &selection) const +{ + Q_D(const GlodonMultiHeaderView); + const int c_max = d->modelSectionCount(); + + if (d->orientation == Qt::Horizontal) + { + int nLeft = c_max; + int nRight = 0; + int nRangeLeft(0); + int nRangeRight(0); + + for (int i = 0; i < selection.count(); ++i) + { + QItemSelectionRange tmpRange = selection.at(i); + + if (tmpRange.parent().isValid() || !tmpRange.isValid()) + { + continue; + } + + // FIXME an item inside the range may be the leftmost or rightmost + nRangeLeft = visualIndex(tmpRange.left()); + + if (nRangeLeft == -1) // in some cases users may change the selections + { + continue; // before we have a chance to do the layout + } + + nRangeRight = visualIndex(tmpRange.right()); + + if (nRangeRight == -1) // in some cases users may change the selections + { + continue; // before we have a chance to do the layout + } + + if (nRangeLeft < nLeft) + { + nLeft = nRangeLeft; + } + + if (nRangeRight > nRight) + { + nRight = nRangeRight; + } + } + + int nlogicalLeft = logicalIndex(nLeft); + int nlogicalRight = logicalIndex(nRight); + + if (nlogicalLeft < 0 || nlogicalLeft >= count() + || nlogicalRight < 0 || nlogicalRight >= count()) + { + return QRegion(); + } + + int nleftPos = sectionViewportPosition(nlogicalLeft); + int nrightPos = sectionViewportPosition(nlogicalRight); + nrightPos += sectionSize(nlogicalRight); + return QRect(nleftPos, 0, nrightPos - nleftPos, drawWidth()); + } + else + { + int nTop = c_max; + int nBottom = 0; + int nRangeTop(0); + int nRangeBottom(0); + + for (int i = 0; i < selection.count(); ++i) + { + QItemSelectionRange tmpRange = selection.at(i); + + if (tmpRange.parent().isValid() || !tmpRange.isValid()) + { + continue; // we only know about toplevel items + } + + // FIXME an item inside the range may be the leftmost or rightmost + nRangeTop = visualIndex(tmpRange.top()); + + if (nRangeTop == -1) // in some cases users may change the selections + { + continue; // before we have a chance to do the layout + } + + nRangeBottom = visualIndex(tmpRange.bottom()); + + if (nRangeBottom == -1) // in some cases users may change the selections + { + continue; // before we have a chance to do the layout + } + + if (nRangeTop < nTop) + { + nTop = nRangeTop; + } + + if (nRangeBottom > nBottom) + { + nBottom = nRangeBottom; + } + } + + int nlogicalTop = logicalIndex(nTop); + int nlogicalBottom = logicalIndex(nBottom); + + if (nlogicalTop == -1 || nlogicalBottom == -1) + { + return QRect(); + } + + int ntopPos = sectionViewportPosition(nlogicalTop); + int nbottomPos = sectionViewportPosition(nlogicalBottom) + sectionSize(nlogicalBottom); + + return QRect(0, ntopPos, drawWidth(), nbottomPos - ntopPos); + } +} + +GLDHeaderSpan GlodonMultiHeaderView::visualSpan(int index) +{ + Q_D(GlodonMultiHeaderView); + GLDHeaderSpan *logicalSpan = headerData->spans[index]; + + if (d->orientation == Qt::Horizontal) + { + int nleft = d->sectionCount(); + int nright = 0; + + for (int i = logicalSpan->left(); i <= logicalSpan->right(); i++) + { + int nVisual = visualIndex(i); + + if (nVisual < nleft) + { + nleft = nVisual; + } + + if (nVisual > nright) + { + nright = nVisual; + } + } + + GLDHeaderSpan visualHeader; + visualHeader.setLeft(nleft); + visualHeader.setRight(nright); + visualHeader.setTop(logicalSpan->top()); + visualHeader.setBottom(logicalSpan->bottom()); + return visualHeader; + } + else + { + int nTop = d->sectionCount(); + int nBottom = 0; + + for (int i = logicalSpan->top(); i <= logicalSpan->bottom(); i++) + { + int nVisual = visualIndex(i); + + if (nVisual < nTop) + { + nTop = nVisual; + } + + if (nVisual > nBottom) + { + nBottom = nVisual; + } + } + + GLDHeaderSpan visualHeader; + visualHeader.setLeft(logicalSpan->left()); + visualHeader.setRight(logicalSpan->right()); + visualHeader.setTop(nTop); + visualHeader.setBottom(nBottom); + return visualHeader; + } +} + +void GlodonMultiHeaderView::setOffset(int offset) +{ + Q_D(GlodonMultiHeaderView); + + for (int i = 0; i < headerList.count(); i++) + { + headerList[i]->setOffset(offset); + } + + GlodonHeaderView::setOffset(offset); + + d->viewport->update(); +} + +void GlodonMultiHeaderView::selectionChanged(const QItemSelection &selected, + const QItemSelection &deselected) +{ + Q_D(GlodonMultiHeaderView); + + if (isVisible() && updatesEnabled()) + { + QRegion deRegion = visualRegionForSelection(deselected); + QRegion selRegion = visualRegionForSelection(selected); + + for (int i = 0; i < headerData->spans.count(); i++) + { + if (d->orientation == Qt::Horizontal) + { + QRect span = headerSpanRect(i); + QRect spanLeftTop = QRect(span.topLeft(), span.topLeft()); + + if (deRegion.contains(spanLeftTop)) + { + deRegion = deRegion.united(span); + } + + if (selRegion.contains(spanLeftTop)) + { + selRegion = selRegion.united(span); + } + + if (deRegion.contains(span) || selRegion.contains(span)) // in one's subarea + { + if (d->isColumnSelected(headerData->spans[i]->left())) + { + selectHeaderSpan(i, true, false, false); + } + else + { + selectHeaderSpan(i, false, false); + } + } + } + else + { + QRect span = headerSpanRect(i); + QRect spanTopLeft = QRect(span.topLeft(), span.topLeft()); + + if (deRegion.contains(spanTopLeft)) + { + deRegion = deRegion.united(span); + } + + if (selRegion.contains(spanTopLeft)) + { + selRegion = selRegion.united(spanTopLeft); + } + + if (deRegion.contains(span) || selRegion.contains(span)) + { + if (d->isRowSelected(headerData->spans[i]->top())) + { + selectHeaderSpan(i, true); + } + else + { + selectHeaderSpan(i, false); + } + } + } + } + + d->viewport->update(deRegion | selRegion); + } +} + +int GlodonMultiHeaderView::rowCount() const +{ + Q_D(const GlodonMultiHeaderView); + + if (d->orientation == Qt::Horizontal) + { + return extraCount() + 1; + } + else + { + return count(); + } +} + +int GlodonMultiHeaderView::colCount() const +{ + Q_D(const GlodonMultiHeaderView); + + if (d->orientation == Qt::Horizontal) + { + return count(); + } + else + { + return extraCount() + 1; + } +} + +void GlodonMultiHeaderView::setupHeaderSpanIndicator(int position) +{ + Q_D(GlodonMultiHeaderView); + + /*因为一个目前不知道为什么会出现的bug而不得不采用的方式 + bug现象:不断的进行几次窗口最大最小化,或者调整窗体大小后 + 再进行拖拽移动时会崩溃*/ + if (headerSpanIndicator != NULL) + { + headerSpanIndicator = NULL; + } + + headerSpanIndicator = new QLabel(d->viewport); + + int nwidth = 0; + int nheight = 0; + int nP = 0; + QRect start = headerSpanRect(moveStartSpan); + GLDHeaderSpan *moveStart = headerData->spans[moveStartSpan]; + QPoint point = start.topLeft(); + + if (d->orientation == Qt::Horizontal) + { + nwidth = start.width(); + + for (int i = headerData->spans[moveStartSpan]->top(); i <= extraCount() - 1; i++) + { + nheight += headerList[i]->drawWidth(); + } + + nheight += lastDrawWidth(); + } + else + { + nheight = start.height(); + + for (int i = headerData->spans[moveStartSpan]->top(); i <= extraCount() - 1; i++) + { + nwidth += headerList[i]->drawWidth(); + } + + nwidth += lastDrawWidth(); + } + + headerSpanIndicator->resize(nwidth, nheight); + + QPixmap pm(nwidth, nheight); + pm.fill(QColor(0, 0, 0, 45)); + QRect rect(0, 0, 0, 0); + + QPainter painter(&pm); + painter.setOpacity(0.75); + + if (d->orientation == Qt::Horizontal) + { + nP = start.left(); + + for (int i = 0; i < headerData->spans.count(); i++) + { + if (headerData->spans[i]->left() >= moveStart->left() + && headerData->spans[i]->right() <= moveStart->right()) + { + rect = headerSpanRect(i); + rect.translate(-point.x(), -point.y()); + paintSpanHeader(&painter, rect, headerData->spans[i]); + } + } + + headerSpanIndicatorDrawPos = start.top(); + } + else + { + nP = start.top(); + + for (int i = 0; i < headerData->spans.count(); i++) + { + if (headerData->spans[i]->top() >= moveStart->top() + && headerData->spans[i]->bottom() <= moveStart->bottom()) + { + rect = headerSpanRect(i); + rect.translate(-point.x(), -point.y()); + paintSpanHeader(&painter, rect, headerData->spans[i]); + } + } + + headerSpanIndicatorDrawPos = start.left(); + } + + painter.end(); + + headerSpanIndicator->setPixmap(pm); + headerSpanIndicatorOffset = position - qMax(nP, 0); +} + +void GlodonMultiHeaderView::updateHeaderSpanIndicator(int position) +{ + Q_D(GlodonMultiHeaderView); + + if (!headerSpanIndicator) + { + return; + } + + if (d->section == -1 || d->target == -1) + { + headerSpanIndicator->hide(); + return; + } + + if (d->orientation == Qt::Horizontal) + { + headerSpanIndicator->move(position - headerSpanIndicatorOffset, headerSpanIndicatorDrawPos); + } + else + { + headerSpanIndicator->move(headerSpanIndicatorDrawPos, position - headerSpanIndicatorOffset); + } + + headerSpanIndicator->show(); +} + +void GlodonMultiHeaderView::currentChanged(const QModelIndex ¤t, const QModelIndex &old) +{ + for (int i = 0; i < headerList.count(); i++) + { + headerList[i]->currentChanged(current, old); + } + + GlodonHeaderView::currentChanged(current, old); +} + +void GlodonMultiHeaderView::updateSection(int logicalIndex) +{ + Q_D(GlodonMultiHeaderView); + + if (d->orientation == Qt::Horizontal) + { + int nindex = headerData->spanAt(extraCount(), logicalIndex); + + if (nindex == -1) + { + return; + } + + for (int i = 0; i < headerData->spans.count(); i++) + { + if (headerData->spans[i]->left() <= headerData->spans[nindex]->left() + && headerData->spans[i]->right() >= headerData->spans[nindex]->right()) + { + nindex = i; + } + } + + int nwidth = 0; + + for (int i = headerData->spans[nindex]->left(); i <= headerData->spans[nindex]->right(); i++) + { + nwidth += sectionSize(i); + } + + d->viewport->update(QRect(sectionViewportPosition(headerData->spans[nindex]->left()), + 0, nwidth, d->viewport->height())); + } + else + { + int nindex = headerData->spanAt(logicalIndex, headerList.count() + 1); + + if (nindex == -1) + { + return; + } + + for (int i = 0; i < headerData->spans.count(); i++) + { + if (headerData->spans[i]->top() <= headerData->spans[nindex]->top() + && headerData->spans[i]->bottom() >= headerData->spans[nindex]->bottom()) + { + nindex = i; + } + } + + int nheight = 0; + + for (int i = headerData->spans[nindex]->top(); i <= headerData->spans[nindex]->bottom(); i++) + { + nheight += sectionSize(i); + } + + d->viewport->update(QRect(0, sectionViewportPosition(headerData->spans[nindex]->top()), + d->viewport->width(), nheight)); + } +} + +int GlodonMultiHeaderView::lastDrawWidth() +{ + Q_D(GlodonMultiHeaderView); + int nWidth = 0; + + for (int i = 0; i < headerList.count(); i++) + { + nWidth += headerList[i]->drawWidth(); + } + + if (d->orientation == Qt::Horizontal) + { + return (viewport()->height() - nWidth); + } + else + { + return (viewport()->width() - nWidth); + } +} + +void GlodonMultiHeaderView::paintSpanHeader(QPainter *painter, const QRect &rect, GLDHeaderSpan *span) const +{ + Q_D(const GlodonMultiHeaderView); + + if (!rect.isValid() || rect.height() == 1 || rect.width() == 1) //高度和宽度为1的时候不应该绘制,不然会出现多余的线 + { + return; + } + + QStyleOptionHeader opt; + initStyleOption(&opt); + QStyle::State state = QStyle::State_None; + bool bDrawHighLight = false; + + if (isEnabled()) + { + state |= QStyle::State_Enabled; + } + + if (window()->isActiveWindow()) + { + state |= QStyle::State_Active; + } + + if (d->clickableSections) + { + if (span->selected()) + { + state |= QStyle::State_Sunken; + } + + if (d->highlightSelected) + { + bool bstate_on = false; + int nStart = d->orientation == Qt::Horizontal ? span->left() : span->top(); + + if (d->sectionIntersectsSelection(nStart)) + { + bstate_on = true; + } + + if (bstate_on) + { + if (d->m_boldWithSelected) + { + state |= QStyle::State_On; + } + + if (!span->selected()) + { + bDrawHighLight = true; + } + } + } + } + + if (isSortIndicatorShown() && sortIndicatorSection() == span->section()) + { + if (sortIndicatorOrder() == Qt::AscendingOrder) + { + opt.sortIndicator = QStyleOptionHeader::SortDown; + } + else if (sortIndicatorOrder() == Qt::DescendingOrder) + { + opt.sortIndicator = QStyleOptionHeader::SortUp; + } + else + { + opt.sortIndicator = QStyleOptionHeader::None; + } + } + + QVariant textAlignment = d->m_model->headerData(span->section(), d->orientation, + Qt::TextAlignmentRole); + + opt.rect = rect; + opt.section = span->section(); + opt.state |= state; + +// opt.textAlignment = Qt::Alignment(textAlignment.isValid() +// ? Qt::Alignment(textAlignment.toInt()) +// : d->defaultAlignment); + if (textAlignment.isValid() && ((textAlignment.toInt() & Qt::AlignHorizontal_Mask) != 0)) + { + opt.textAlignment = Qt::Alignment(textAlignment.toInt()); + } + else + { + opt.textAlignment = Qt::AlignCenter; + } + + opt.textAlignment = Qt::AlignmentFlag(int(opt.textAlignment) | int(Qt::TextWordWrap)); + opt.iconAlignment = Qt::AlignVCenter; + + QVariant var = d->m_model->headerData(span->section(), Qt::Horizontal, Qt::FontRole); + QFont fnt; + + if (var.isValid() && var.canConvert()) + { + fnt = qvariant_cast(var); + } + else + { + fnt = font(); + } + + painter->setFont(fnt); + + QVariant variant = d->m_model->headerData(span->section(), d->orientation, + Qt::DecorationRole); + opt.icon = qvariant_cast(variant); + + if (opt.icon.isNull()) + { + opt.icon = qvariant_cast(variant); + } + + variant = d->m_model->headerData(span->section(), d->orientation, + Qt::DecorationPropertyRole); + + if (variant.isValid()) + { + opt.iconAlignment = (Qt::Alignment)variant.toInt(); + } + + QVariant foregroundBrush = d->m_model->headerData(span->section(), d->orientation, + Qt::ForegroundRole); + + if (foregroundBrush.canConvert()) + { + opt.palette.setBrush(QPalette::ButtonText, qvariant_cast(foregroundBrush)); + } + + QPointF oldBO = painter->brushOrigin(); + QVariant backgroundBrush = d->m_model->headerData(span->section(), d->orientation, + Qt::BackgroundRole); + + if (backgroundBrush.canConvert()) + { + opt.palette.setBrush(QPalette::Button, qvariant_cast(backgroundBrush)); + opt.palette.setBrush(QPalette::Window, qvariant_cast(backgroundBrush)); + painter->setBrushOrigin(opt.rect.topLeft()); + } + + if (d->orientation == Qt::Horizontal) + { + if (count() == 1) + { + opt.position = QStyleOptionHeader::OnlyOneSection; + } + else if (span->left() == 0) + { + opt.position = QStyleOptionHeader::Beginning; + } + else if (span->right() == count() - 1) + { + opt.position = QStyleOptionHeader::End; + } + else + { + opt.position = QStyleOptionHeader::Middle; + } + } + else + { + if (count() == 1) + { + opt.position = QStyleOptionHeader::OnlyOneSection; + } + else if (span->top() == 0) + { + opt.position = QStyleOptionHeader::Beginning; + } + else if (span->bottom() == count() - 1) + { + opt.position = QStyleOptionHeader::End; + } + else + { + opt.position = QStyleOptionHeader::Middle; + } + } + + opt.orientation = d->orientation; + drawCellBorder(painter, opt); + + if (bDrawHighLight) + { + opt.text = span->text(); + + if (d->m_textElideMode != Qt::ElideNone) + { + opt.text = opt.fontMetrics.elidedText(opt.text, d->m_textElideMode , rect.width() - 4); + } + +// paintHighLightSection(painter, opt, rect); + + if (isFixedcellEvent()) + { + paintHighLightSection(painter, opt, rect); + } + else + { +// style()->drawControl(QStyle::CE_Header, &opt, painter, this); + paintSectionOnQt(painter, opt, this, true); + } + } + else + { +// style()->drawControl(QStyle::CE_Header, &opt, painter, this); + + opt.text = span->text(); + + if (d->m_textElideMode != Qt::ElideNone) + { + opt.text = opt.fontMetrics.elidedText(opt.text, d->m_textElideMode , rect.width() - 4); + } + +// opt.rect = textRect(rect); +// opt.icon = QIcon(); + + paintSectionOnQt(painter, opt, this, false); +// style()->drawControl(QStyle::CE_HeaderLabel, &opt, painter, this); + + opt.rect = rect; + } + + painter->setBrushOrigin(oldBO); + if (span->top() == d->m_spanTop) + { + if (Qt::Horizontal == d->orientation) + { + drawImageInDesignatedLogicalIndex(painter, opt); + } + } +} + +bool GlodonMultiHeaderView::checkLogicalTitles(int fixedCount) +{ + bool blogical = true; + + for (int i = 0; i < headerData->spans.count(); i++) + { + if (headerData->spans[i]->left() < fixedCount && fixedCount < headerData->spans[i]->right()) + { + blogical = false; + } + } + + return blogical; +} + +bool GlodonMultiHeaderView::inTopHeaderRange(int topHeaderIndex, int index) +{ + Q_D(GlodonMultiHeaderView); + int nMin(0); + int nMax = -1; + + if (d->orientation == Qt::Horizontal) + { + if (headerData->spans[topHeaderIndex]->top() == 0) + { + nMin = headerData->spans[topHeaderIndex]->left(); + nMax = headerData->spans[topHeaderIndex]->right(); + } + else + { + for (int i = 0; i < headerData->spans.count(); i++) + { + if (headerData->spans[i]->left() <= headerData->spans[topHeaderIndex]->left() + && headerData->spans[i]->right() >= headerData->spans[topHeaderIndex]->right() + && headerData->spans[i]->top() == 0) + { + nMin = headerData->spans[i]->left(); + nMax = headerData->spans[i]->right(); + break; + } + } + } + + return (headerData->spans[index]->left() >= nMin && headerData->spans[index]->right() <= nMax); + } + else + { + if (headerData->spans[topHeaderIndex]->left() == 0) + { + nMin = headerData->spans[topHeaderIndex]->top(); + nMax = headerData->spans[topHeaderIndex]->bottom(); + } + else + { + for (int i = 0; i < headerData->spans.count(); i++) + { + if (headerData->spans[i]->top() <= headerData->spans[topHeaderIndex]->top() + && headerData->spans[i]->bottom() >= headerData->spans[topHeaderIndex]->bottom() + && headerData->spans[i]->left() == 0) + { + nMin = headerData->spans[i]->top(); + nMax = headerData->spans[i]->bottom(); + break; + } + } + } + + return (headerData->spans[index]->top() >= nMin && headerData->spans[index]->bottom() <= nMax); + } +} + +bool GlodonMultiHeaderView::checkCanMove(int targetLogicalIndex) +{ + Q_D(GlodonMultiHeaderView); + int nto = visualIndex(targetLogicalIndex); + GLDHeaderSpan *moveStart = headerData->spans[moveStartSpan]; + int nfrom = visualIndex(d->section); + + if (d->orientation == Qt::Horizontal) + { + int nTargetIndex = headerData->spanAt(moveStart->top(), targetLogicalIndex); + GLDHeaderSpan *targetSpan = headerData->spans[nTargetIndex]; + GLDHeaderSpan visualTarget = visualSpan(nTargetIndex); + + if (targetSpan->top() == moveStart->top()) + { + if (moveStart->top() > 0) + { + //如果上一层是合并格的话,不在同一个合并格的不让拖动 + int nTop = moveStart->top() - 1; + int nMoveTopIndex = headerData->spanAt(nTop, moveStart->left()); + int nTargetTopIndex = headerData->spanAt(nTop, targetSpan->left()); + + if (nMoveTopIndex != nTargetTopIndex) + { + return false; + } + } + + if (nfrom < nto) + { + if (visualTarget.left() > nto || visualTarget.right() <= nto) + { + return true; + } + } + else + { + if (visualTarget.left() >= nto || visualTarget.right() < nto) + { + return true; + } + } + } + } + else + { + int nTargetIndex = headerData->spanAt(targetLogicalIndex, moveStart->left()); + GLDHeaderSpan *targetSpan = headerData->spans[nTargetIndex]; + GLDHeaderSpan visualTarget = visualSpan(nTargetIndex); + + if (targetSpan->left() == moveStart->left()) + { + if (nfrom < nto) + { + if (visualTarget.top() > nto || visualTarget.bottom() <= nto) + { + return true; + } + } + else + { + if (visualTarget.top() >= nto || visualTarget.bottom() < nto) + { + return true; + } + } + } + } + + return false; +} + +int GlodonMultiHeaderView::parseSpan(int nFirstVisual, int nLastVisual, int nMaxCount) +{ + QString strTitle; + QList titles; + + for (int i = nFirstVisual; i >= 0 && i < nLastVisual; i++) + { + strTitle = model()->headerData(i, orientation()).toString(); + + if ("|" == strTitle) + { + strTitle = " | "; + } + + titles.append(strTitle.split('|')); + } + + for (int i = 0; i < titles.count(); i++) + { + int nCurrentCount = titles.at(i).count(); + + if (orientation() == Qt::Horizontal) + { + for (int j = 0; j < nCurrentCount - 1; j++) + { + GLDHeaderSpan *newspan + = new GLDHeaderSpan(j, i + nFirstVisual, 1, 1, titles.at(i).at(j), i + nFirstVisual); + headerData->addSpan(newspan); + } + + GLDHeaderSpan *newspan = new GLDHeaderSpan(nCurrentCount - 1, i + nFirstVisual, + nMaxCount - nCurrentCount + 1, 1, + titles.at(i).at(nCurrentCount - 1), i + nFirstVisual); + headerData->addSpan(newspan); + } + else + { + for (int j = 0; j < nCurrentCount - 1; j++) + { + GLDHeaderSpan *newspan + = new GLDHeaderSpan(i + nFirstVisual, j, 1, 1, titles.at(i).at(j), i + nFirstVisual); + headerData->addSpan(newspan); + } + + GLDHeaderSpan *newspan = new GLDHeaderSpan(i + nFirstVisual, nCurrentCount - 1, + 1, nMaxCount - nCurrentCount + 1, + titles.at(i).at(nCurrentCount - 1), i + nFirstVisual); + headerData->addSpan(newspan); + } + } + + return nMaxCount; +} + +int GlodonMultiHeaderView::maxCount() +{ + Q_D(GlodonMultiHeaderView); + QString strTitle; + int nMaxCount = 0; + + for (int i = 0; i >= 0 && i < d->sectionCount(); i++) + { + strTitle = model()->headerData(i, orientation()).toString(); + nMaxCount = qMax(nMaxCount, strTitle.split('|').count()); + } + + return nMaxCount; +} + +void GlodonMultiHeaderView::recoverMinimumHeights() +{ + Q_D(GlodonMultiHeaderView); + + if (d->orientation == Qt::Horizontal && m_minimumHeights.count() > 0) + { + for (int i = 0; i < headerList.count(); i++) + { + headerList.at(i)->setMinimumHeight(m_minimumHeights.at(i)); + } + + setMinimumHeight(m_minimumHeights.at(headerList.count())); + } +} + +int GlodonMultiHeaderView::resetSpan() +{ + Q_D(GlodonMultiHeaderView); + headerData->spans.clear(); + + int nMaxCount = maxCount(); + parseSpan(0, d->sectionCount(), nMaxCount); + Q_ASSERT_X(checkLogicalTitles(d->fixedCount), "resetSpan", + "cannot resetSpan that makes part of a combined cell fixed"); + // 2015/11/5 chensf 刷新Tableview时 考虑多重表头个数发生改变的情况,重新计算GlodonHeaderView的数量 + setExtraCount(nMaxCount - 1); + updateGeometries(); + d->viewport->update(); + return nMaxCount; +} + +void GlodonMultiHeaderView::updateSpan(int index) +{ + Q_D(GlodonMultiHeaderView); + QStringList title = model()->headerData(index, orientation()).toString().split("|"); + + for (int i = 0; i < headerData->spans.count(); ++i) + { + GLDHeaderSpan *currentSpan = headerData->spans.at(i); + + if (orientation() == Qt::Horizontal) + { + if (currentSpan->left() == index) + { + if (title.count() > 1) + { + for (int row = 0; row < title.count(); ++row) + { + headerData->spans.at(headerData->spanAt(row, index))->setText(title.at(row)); + } + } + else + { + currentSpan->setText(title.at(0)); + } + + break; + } + } + else + { + if (currentSpan->top() == index) + { + if (title.count() > 1) + { + for (int col = 0; col < title.count(); ++col) + { + headerData->spans.at(headerData->spanAt(index, col))->setText(title.at(col)); + } + } + else + { + currentSpan->setText(title.at(0)); + } + + break; + } + } + } + + d->viewport->update(); +} + +void GlodonMultiHeaderView::setSpansSelected(int index, bool selected) +{ + Q_D(GlodonMultiHeaderView); + + if (Qt::Horizontal == d->orientation) + { + for (int i = 0; i < headerData->spans.count(); i++) + { + if ((index >= headerData->spans.at(i)->left()) + && (index <= headerData->spans.at(i)->right())) + { + headerData->spans.at(i)->setSelected(selected); + } + } + } + else + { + for (int i = 0; i < headerData->spans.count(); i++) + { + if ((index >= headerData->spans.at(i)->top()) + && (index <= headerData->spans.at(i)->bottom())) + { + headerData->spans.at(i)->setSelected(selected); + } + } + } +} + +void GlodonMultiHeaderView::setMinimumHeights(QVector &minHs) +{ + Q_D(GlodonMultiHeaderView); + + if (d->orientation == Qt::Horizontal) + { + m_minimumHeights = minHs; + } +} + +void GHeaderSpanCollection::addSpan(GLDHeaderSpan *span) +{ + if (parseSpanRelationRecursively(span, false, -1)) + { + freeAndNil(span); + } + else + { + spans.append(span); + } +} + +void GHeaderSpanCollection::parseSpanInternal(int index, bool isInRecursion, int i) +{ + + if(isInRecursion) + { + if(index <= i) + { + i--; + } + + spans.removeAt(index); + + } + + parseSpanRelationRecursively(spans[i], true, i); +} + +bool GHeaderSpanCollection::parseSpanRelationRecursively(GLDHeaderSpan *span, bool isInRecursion, int index) +{ + // 先判断上一级标题是否相同 + for (int i = 0; i < spans.count(); ++i) + { + if ((spans.at(i)->bottom() == (span->top() - 1)) + && (spans.at(i)->left() == span->left()) + ) + { + if (spans.at(i)->text() != span->text()) + { + return false; + } + } + } + + HeaderSpanRelation relation; + + for (int i = spans.count() - 1; i >= 0; i--) // reverse + { + relation = spans[i]->spanRelation(*span); + Q_ASSERT(relation != Overlapping); + + switch (relation) + { + case Overlapping: + case Irrelevant: + case AdjacentIrrelevant: + { + continue; + } + + case Contain: + { + if (!isInRecursion) + { + return true; + } + + continue; + } + + case AdjacentRight: + { + spans[i]->setLeft(span->left()); + + break; + } + + case AdjacentLeft: + { + spans[i]->setRight(span->right()); + + break; + } + + case AdjacentDown: + { + spans[i]->setTop(span->top()); + + break; + } + + case AdjacentUp: + { + spans[i]->setBottom(span->bottom()); + + break; + } + } + + parseSpanInternal(index, isInRecursion, i); + + return true; + } + + return false; +} + +HeaderSpanRelation GLDHeaderSpan::spanRelation(GLDHeaderSpan span) +{ + if (m_text != span.text()|| ((m_text == "") && (span.text() == "")) + || m_left > span.right() + 1 || m_top > span.bottom() + 1 + || m_right < span.left() - 1 || m_bottom < span.top() - 1) + { + return Irrelevant; + } + + if (m_left <= span.left() && m_top <= span.top() && m_bottom >= span.bottom() && m_right >= span.right()) + { + return Contain; + } + + if (m_left == span.right() + 1) + { + if (height() == span.height()) + { + return AdjacentRight; + } + else + { + return AdjacentIrrelevant; + } + } + + if (m_right == span.left() - 1) + { + if (height() == span.height()) + { + return AdjacentLeft; + } + else + { + return AdjacentIrrelevant; + } + } + + // Span上下左右是屏幕坐标系 + // 数字的加减是笛卡尔坐标系 + + if (m_top == span.bottom() + 1) + { + if (width() == span.width()) + { + return AdjacentDown; + } + else + { + return AdjacentIrrelevant; + } + } + + if (m_bottom == span.top() - 1) + { + if (width() == span.width()) + { + return AdjacentUp; + } + else + { + return AdjacentIrrelevant; + } + } + + return Overlapping; +} + +void GlodonMultiHeaderView::setFixedCount(int fixedCount) +{ + //由于动态设置列隐藏的过程中,由可编辑固定都隐藏,到显示一列可编辑固定列,会出现checkLogicalTitles不合法的情况, + //但是由于不设置GlodonHeaderView中的fixedCol,GlodonMultiHeaderView就不能正确的initTitle,所以不合法校验,不在 + //setFixedCount中进行 +// Q_ASSERT_X(checkLogicalTitles(fixedCount), "setFixedCount", +// "cannot set fixed count that makes part of a combined cell fixed"); + GlodonHeaderView::setFixedCount(fixedCount); +} + +int GHeaderSpanCollection::spanAt(int rowIndex, int colIndex) const +{ + for (int i = 0; i < spans.count(); i++) + { + if (spans[i]->left() <= colIndex && spans[i]->right() >= colIndex + && spans[i]->top() <= rowIndex && spans[i]->bottom() >= rowIndex) + { + return i; + } + } + + return -1; +} + +void GlodonMultiHeaderView::updateHeaderSpan(int index) +{ + Q_D(GlodonMultiHeaderView); + QRect rect = headerSpanRect(index); + d->viewport->update(rect); +} + +void GlodonMultiHeaderView::selectHeaderSpan(int index, bool select, bool checkParent, bool checkChild) +{ + Q_D(GlodonMultiHeaderView); + + if (index < 0 || index > headerData->spans.count() || headerData->spans[index]->selected() == select) + { + return; + } + + headerData->spans[index]->setSelected(select); + updateHeaderSpan(index); + + if (d->orientation == Qt::Horizontal) + { + if (!checkChild && headerData->spans[index]->top() == 0) + { + return; + } + + if (!checkParent && headerData->spans[index]->bottom() == extraCount()) + { + return; + } + + for (int i = 0; i < headerData->spans.count(); i++) + { + if (headerData->spans[i]->left() <= headerData->spans[index]->left() + && headerData->spans[i]->right() >= headerData->spans[index]->right() + && headerData->spans[i]->bottom() == headerData->spans[index]->top() - 1 + && checkParent) + { + if (headerData->spans[i]->selected() != select) + { + if (select) + { + bool bAllChildrenSelected = true; + + for (int j = 0; j < headerData->spans.count(); j++) + { + if (headerData->spans[i]->left() <= headerData->spans[j]->left() + && headerData->spans[i]->right() >= headerData->spans[j]->right() + && headerData->spans[i]->bottom() == headerData->spans[j]->top() - 1 + && !headerData->spans[j]->selected()) + { + bAllChildrenSelected = false; + break; + } + } + + if (bAllChildrenSelected) + { + selectHeaderSpan(i, true, true, false); + } + } + else + { + selectHeaderSpan(i, false, true, false); + } + } + } + else if (headerData->spans[i]->left() >= headerData->spans[index]->left() + && headerData->spans[i]->right() <= headerData->spans[index]->right() + && headerData->spans[i]->top() == headerData->spans[index]->bottom() + 1 + && checkChild) + { + if (headerData->spans[i]->selected() != select) + { + selectHeaderSpan(i, select, false, true); + } + } + } + } + else + { + if (!checkChild && headerData->spans[index]->left() == 0) + { + return; + } + + if (!checkParent && headerData->spans[index]->right() == extraCount()) + { + return; + } + + for (int i = 0; i < headerData->spans.count(); i++) + { + if (headerData->spans[i]->top() <= headerData->spans[index]->top() + && headerData->spans[i]->bottom() >= headerData->spans[index]->bottom() + && headerData->spans[i]->right() == headerData->spans[index]->left() - 1 + && checkParent) + { + if (headerData->spans[i]->selected() != select) + { + if (select) + { + bool bAllChildrenSelected = true; + + for (int j = 0; j < headerData->spans.count(); j++) + { + if (headerData->spans[i]->top() <= headerData->spans[j]->top() + && headerData->spans[i]->bottom() >= headerData->spans[j]->bottom() + && headerData->spans[i]->right() == headerData->spans[j]->left() - 1 + && !headerData->spans[j]->selected()) + { + bAllChildrenSelected = false; + break; + } + } + + if (bAllChildrenSelected) + { + selectHeaderSpan(i, true, true, false); + } + } + else + { + selectHeaderSpan(i, false, true, false); + } + } + } + else if (headerData->spans[i]->top() >= headerData->spans[index]->top() + && headerData->spans[i]->bottom() <= headerData->spans[index]->bottom() + && headerData->spans[i]->left() == headerData->spans[index]->right() + 1 + && checkChild) + { + if (headerData->spans[i]->selected() != select) + { + selectHeaderSpan(i, select, false, true); + } + } + } + } +} + +QRect GlodonMultiHeaderView::headerSpanRect(int index) +{ + Q_D(GlodonMultiHeaderView); + + if (index < 0 || index >= headerData->spans.count()) + { + return QRect(); + } + + QRect currentRect(0, 0, 0, 0); + + if (d->orientation == Qt::Horizontal) + { + int nLogical = headerData->spans.at(index)->left(); + currentRect.setLeft(sectionViewportPosition(nLogical)); + int nRectWidth = 0; + + bool bSpanVisualFirst = isSectionHidden(headerData->spans.at(index)->left()); + + for (int i = headerData->spans.at(index)->left(); i <= headerData->spans.at(index)->right(); i++) + { + if (bSpanVisualFirst) + { + if (isSectionHidden(i)) + { + currentRect.setLeft(sectionViewportPosition(i) + 1); + } + else + { + bSpanVisualFirst = false; + } + } + + int nRectLeft = sectionViewportPosition(i); + + if (nRectLeft < currentRect.left() && !bSpanVisualFirst && + !isSectionHidden(i)) + { + currentRect.setLeft(nRectLeft); + } + + if (isSectionHidden(i)) + { + nRectWidth -= d->gridLineWidth; + } + + nRectWidth += sectionSize(i) + d->gridLineWidth; + } + + currentRect.setWidth(nRectWidth); + + int nRectTop = 0; + + for (int i = 0; i < headerData->spans.at(index)->top(); i++) + { +// rectTop += headerList[i]->drawWidth(); + if (headerList[i]->minimumHeight() == 0) + { + nRectTop += headerList[i]->drawWidth(); + } + else + { + nRectTop += headerList[i]->minimumHeight(); + } + } + + currentRect.setTop(nRectTop); + + int nRectHeight = 0; + + for (int i = headerData->spans.at(index)->top(); i <= headerData->spans.at(index)->bottom(); i++) + { + if (i < headerList.count()) + { +// rectHeight += headerList[i]->drawWidth(); + if (headerList[i]->minimumHeight() == 0) + { + nRectHeight += headerList[i]->drawWidth(); + } + else + { + nRectHeight += headerList[i]->minimumHeight(); + } + } + else + { + if (minimumHeight() == 0) + { + nRectHeight += lastDrawWidth(); + } + else + { + nRectHeight += /*lastDrawWidth()*/minimumHeight(); + } + } + } + + currentRect.setHeight(nRectHeight); + } + else + { + int nLogical = headerData->spans.at(index)->top(); + currentRect.setTop(sectionViewportPosition(nLogical)); + int nRectHeight = 0; + + for (int i = headerData->spans.at(index)->top(); i <= headerData->spans.at(index)->bottom(); i++) + { + int nRectTop = sectionViewportPosition(i); + + if (nRectTop < currentRect.top()) + { + currentRect.setTop(nRectTop); + } + + nRectHeight += sectionSize(i) + d->lineWidth; + } + + currentRect.setHeight(nRectHeight); + + int nRectLeft = 0; + + for (int i = 0; headerList.count() > 0 && i < headerData->spans.at(index)->left(); i++) + { + nRectLeft += headerList[i]->drawWidth(); + } + + currentRect.setLeft(nRectLeft); + + int nRectWidth = 0; + + for (int i = headerData->spans.at(index)->left(); i <= headerData->spans.at(index)->right(); i++) + { + if (i < headerList.count()) + { + nRectWidth += headerList[i]->drawWidth(); + } + else + { + nRectWidth += lastDrawWidth(); + } + } + + currentRect.setWidth(nRectWidth); + } + + return currentRect; +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDNetScapeSplitter.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDNetScapeSplitter.cpp new file mode 100644 index 00000000..a205c6a9 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDNetScapeSplitter.cpp @@ -0,0 +1,601 @@ +#include +#include +#include + +#include "GLDNetScapeSplitter.h" +#include "GLDStrUtils.h" + +/* GLDNestScapSplitterTripleHelper */ + +QPoint GLDNestScapSplitterTripleHelper::vertexA() const +{ + switch (m_direction) + { + case leftToRight: + return QPoint(m_midPoint.x(), m_midPoint.y() + m_radius); + + case rightToleft: + return QPoint(m_midPoint.x(), m_midPoint.y() - m_radius); + + case TopToBottom: + return QPoint(m_midPoint.x() - m_radius, m_midPoint.y()); + + case bottomToTop: + return QPoint(m_midPoint.x() + m_radius, m_midPoint.y()); + + default: + return m_midPoint; + } +} + +QPoint GLDNestScapSplitterTripleHelper::vertexB() const +{ + switch (m_direction) + { + case leftToRight: + return QPoint(m_midPoint.x() - m_radius, m_midPoint.y()); + + case rightToleft: + return QPoint(m_midPoint.x() + m_radius, m_midPoint.y()); + + case TopToBottom: + return QPoint(m_midPoint.x(), m_midPoint.y() - m_radius); + + case bottomToTop: + return QPoint(m_midPoint.x(), m_midPoint.y() + m_radius); + + default: + return m_midPoint; + } +} + +QPoint GLDNestScapSplitterTripleHelper::vertexC() const +{ + switch (m_direction) + { + case leftToRight: + return QPoint(m_midPoint.x(), m_midPoint.y() - m_radius); + + case rightToleft: + return QPoint(m_midPoint.x(), m_midPoint.y() + m_radius); + + case TopToBottom: + return QPoint(m_midPoint.x() + m_radius, m_midPoint.y()); + + case bottomToTop: + return QPoint(m_midPoint.x() - m_radius, m_midPoint.y()); + + default: + return m_midPoint; + } +} + +/* GLDNetScapeSplitter */ + +GLDNetScapeSplitter::GLDNetScapeSplitter(bool initCollapse, QWidget *parent) : + GLDSplitter(parent), + m_minHideLength(c_InitialHidenLength), m_align(alLeftBottom), m_bFirstTimeShow(true), m_bInitCollapse(initCollapse), + m_bCollapseCompletable(false), m_bUsingLastExpandSize(true), + m_nWantedExpandSize(-1), m_dWantedExpandFactor(-1) +{ + init(); +} + +GLDNetScapeSplitter::GLDNetScapeSplitter(Qt::Orientation original, bool initCollapse, QWidget *parent): + GLDSplitter(original, parent), + m_minHideLength(c_InitialHidenLength), m_align(alLeftBottom), m_bFirstTimeShow(true), m_bInitCollapse(initCollapse), + m_bCollapseCompletable(false),m_bUsingLastExpandSize(true), + m_nWantedExpandSize(-1), m_dWantedExpandFactor(-1), m_handle(NULL) +{ + init(); +} + +GLDNetScapeSplitter::GLDNetScapeSplitter(QWidget *parent) : + GLDSplitter(parent), m_align(alLeftBottom), + m_minHideLength(c_InitialHidenLength), m_bFirstTimeShow(true), m_bInitCollapse(false), + m_bCollapseCompletable(false),m_bUsingLastExpandSize(true), + m_nWantedExpandSize(-1), m_dWantedExpandFactor(-1), m_handle(NULL) +{ + init(); +} + +GLDNetScapeSplitter::GLDNetScapeSplitter(Qt::Orientation original, QWidget *parent) : + GLDSplitter(original, parent), m_align(alLeftBottom), + m_minHideLength(c_InitialHidenLength), m_bFirstTimeShow(true), m_bInitCollapse(false), + m_bCollapseCompletable(false),m_bUsingLastExpandSize(true), + m_nWantedExpandSize(-1), m_dWantedExpandFactor(-1), m_handle(NULL) +{ + init(); +} + +void GLDNetScapeSplitter::setCollpaseCompletable(bool enabled) +{ + m_bCollapseCompletable = enabled; + + if (!m_bFirstTimeShow) + { + emit splitterMoved(0, 1); + } +} + +bool GLDNetScapeSplitter::setCollpaseSideStretchFactor(double rate) +{ + if (!m_bFirstTimeShow) + { + return false; + } + + if (rate < 1e-6 || rate > 1 - 1e-6) + { + return false; + } + + m_dWantedExpandFactor = rate; + m_nWantedExpandSize = -1; + + return true; +} + +void GLDNetScapeSplitter::doTrigger(bool show) +{ + if (NULL == m_handle) + { + return; + } + + bool bState = m_handle->getSplitterState(); + if (bState == show) + { + return; + } + m_handle->m_dragMoveState = GLDNetScapeSplitterHandle::pressed; + m_handle->handlerButtonClick(); +} + +int GLDNetScapeSplitter::getHandleIndexOffset() +{ + switch (this->m_align) + { + case alLeftBottom: + return orientation() == Qt::Vertical ? 1 : 0; + + case alRightTop: + return orientation() == Qt::Vertical ? 0 : 1; + } + + return 0; +} + +void GLDNetScapeSplitter::changeHandleLength(GLDNetScapeSplitterHandle *handle, int handleLength) +{ + int nHandleIndex = indexOf(handle); + + if (nHandleIndex == -1) + { + return; + } + + int nPrevIndex = nHandleIndex - 1; + + nHandleIndex = nHandleIndex - 1 + getHandleIndexOffset(); + + if (nHandleIndex == -1) + return; + + QList lengths(sizes()); + + if (handle->m_dragMoveState >= GLDNetScapeSplitterHandle::moved) + { + handle->saveExpandLength(qMax(handle->collapseLength(), lengths.at(nHandleIndex))); + } + else + { + if (nPrevIndex == nHandleIndex) + { + nPrevIndex++; + } + + int nLengthOffset = handleLength - lengths.at(nHandleIndex); + + if (handle->collapseLength() == handleLength) + { + handle->saveExpandLength(qMax(handle->collapseLength(), lengths.at(nHandleIndex))); + } + + if (nPrevIndex == -1) + return; + + if ((this->m_align == alLeftBottom && this->orientation() == Qt::Horizontal) + || (m_align == alRightTop && this->orientation() == Qt::Vertical)) + { + lengths[nPrevIndex] = lengths.at(nPrevIndex) - nLengthOffset; + lengths[nHandleIndex] = handleLength; + } + else + { + lengths[nPrevIndex] = lengths.at(nPrevIndex) - nLengthOffset; + lengths[nHandleIndex] = handleLength; + } + + this->setSizes(lengths); + } +} + +void GLDNetScapeSplitter::emitHandlerMoved(int length, int index) +{ + GLDNetScapeSplitterHandle *hand = dynamic_cast(handle(index)); + + if (hand == NULL) + { + return; + } + + int nMinIndexWidth = hand->collapseLength(); + int nMin(0); + int nMax(1); + + getRange(index, &nMin, &nMax); + + bool bleftType = (this->m_align == alLeftBottom); + + if (bleftType != (this->orientation() == Qt::Vertical)) //TODOREVIEW + { + bleftType = true; + } + else + { + bleftType = false; + } + + if (this->childrenCollapsible()) + { + nMinIndexWidth = 0; + } + + if (bleftType ? (length <= nMinIndexWidth) : (length + nMinIndexWidth >= nMax)) + { + QList childrenSizes = sizes(); + int nFixedDistance = bleftType ? (nMinIndexWidth - length) : (length + nMinIndexWidth - nMax); + + if (bleftType) + { + childrenSizes[index - 1] = nMinIndexWidth; + childrenSizes[index] += nFixedDistance; + } + else + { + childrenSizes[index - 1] -= nFixedDistance; + childrenSizes[index] = nMinIndexWidth; + } + + setSizes(childrenSizes); + + if (true == hand->m_bExpanded) + { + hand->m_bExpanded = false; + hand->adjustArrowDirection(); + hand->update(); + } + } + else + { + if (false == hand->m_bExpanded) + { + hand->m_bExpanded = true; + hand->adjustArrowDirection(); + } + + hand->update(); + } +} + +void GLDNetScapeSplitter::init() +{ + setHandleWidth(c_InitialHandleWidth); + connect(this, SIGNAL(splitterMoved(int, int)), + this, SLOT(emitHandlerMoved(int, int))); +} + +void GLDNetScapeSplitter::updateSplitterExpendLength(GLDNetScapeSplitterHandle *splitterHandle) +{ + if (m_nWantedExpandSize > 0) + { + if (m_nWantedExpandSize < (orientation() == Qt::Horizontal ? width() : height())) + { + splitterHandle->m_expandedLength = m_nWantedExpandSize; + } + } + else if (isInInterval(m_dWantedExpandFactor, 0.0, 1.0, 0)) + { + splitterHandle->m_expandedLength = m_dWantedExpandFactor + * (orientation() == Qt::Horizontal ? width() : height()); + } +} + +void GLDNetScapeSplitter::updateSplitterSizes() +{ + QList indexSizes = sizes(); + + int nSize1 = indexSizes[0]; + int nSize2 = indexSizes[1]; + + if (m_align == alLeftBottom) + { + if (orientation() == Qt::Horizontal) + { + indexSizes[0] = 0; + indexSizes[1] += nSize1; + } + else + { + indexSizes[0] += nSize2; + indexSizes[1] = 0; + } + } + else //alRightTop + { + if (orientation() == Qt::Horizontal) + { + indexSizes[0] += nSize2; + indexSizes[1] = 0; + } + else + { + indexSizes[0] = 0; + indexSizes[1] += nSize1; + } + } + + setSizes(indexSizes); +} + +void GLDNetScapeSplitter::showSplitterHandle(GLDNetScapeSplitterHandle *splitterHandle) +{ + updateSplitterExpendLength(splitterHandle); + + if(m_bInitCollapse || m_bCollapseCompletable) + { + splitterHandle->m_collapseLength = 0; + } + + if (m_bInitCollapse) + { + this->setChildrenCollapsible(true); + + splitterHandle->m_bExpanded = false; + + updateSplitterSizes(); + } + + splitterHandle->adjustArrowDirection(); +} + +void GLDNetScapeSplitter::onFirstTimeShowEvent() +{ + m_bFirstTimeShow = false; + + const int nWidgetsCount = count(); + + emit resizeSignal(this->orientation() == Qt::Horizontal ? height() : width()); + + for (int i = 0; i < nWidgetsCount; ++i) + { + GLDNetScapeSplitterHandle *splitterHandle = dynamic_cast(handle(i)); + + if (splitterHandle == NULL) + { + continue; + } + + if (splitterHandle->isVisibleTo(this)) + { + showSplitterHandle(splitterHandle); + } + } +} + +void GLDNetScapeSplitter::onShowEvent() +{ + if (count() > 2) + { + return; + } + + if (m_bFirstTimeShow) + { + onFirstTimeShowEvent(); + } +} + +void GLDNetScapeSplitter::initSignalSlot(GLDNetScapeSplitterHandle *handle) +{ + handle->initButton(); + handle->setCollapseLength(m_minHideLength); + + connect(this, SIGNAL(resizeSignal(QResizeEvent *)), + handle, SLOT(onSplitterResized(QResizeEvent *))); + connect(this, SIGNAL(resizeSignal(int)), + handle, SLOT(onSplitterResized(int))); + connect(handle, SIGNAL(splitterStateSwitched(GLDNetScapeSplitterHandle *, int)), + this, SLOT(changeHandleLength(GLDNetScapeSplitterHandle *, int))); +} + +GLDSplitterHandle *GLDNetScapeSplitter::createHandle() +{ + GLDNetScapeSplitterHandle *handle = new GLDNetScapeSplitterHandle(this->orientation(), this); + m_handle = handle; + if (NULL != handle) + { + initSignalSlot(handle); + } + + return handle; +} + + +/* GLDNetScapeSplitterButton */ + +void GLDNetScapeSplitterButton::setButtonNameByArrowDirection() +{ + switch (m_arrowDirection) + { + case rightToleft: + { + this->setObjectName("left"); + break; + } + + case leftToRight: + { + this->setObjectName("right"); + break; + } + + case bottomToTop: + { + this->setObjectName("top"); + break; + } + + case TopToBottom: + { + this->setObjectName("bottom"); + break; + } + + default: + Q_ASSERT(false); + } +} + +bool GLDNetScapeSplitterButton::hitButton(const QPoint &pos) const +{ + GLDNetScapeSplitterHandle *hand = dynamic_cast(parentWidget()); + + if (NULL != hand) + { + if (GLDNetScapeSplitterHandle::moved == hand->dragMoveState()) + { + return false; + } + } + + return QPushButton::hitButton(pos); +} + +void GLDNetScapeSplitterButton::mousePressEvent(QMouseEvent *e) +{ + GLDNetScapeSplitterHandle *hand = dynamic_cast(parentWidget()); + + if (NULL != hand) + { + if (Qt::LeftButton == (e->buttons() & Qt::LeftButton)) + { + hand->setDragMoveState(0); + } + } + + return QPushButton::mousePressEvent(e); +} + +void GLDNetScapeSplitterButton::paintEvent(QPaintEvent *e) +{ + QPixmap pixmap; + QPushButton::paintEvent(e); + QPainter painter(this); + + int nwidth = this->width(); + int nheight = this->height(); + int ntoBottom = c_TriangleBottomToBorderPixel; + QImage image(nwidth, nheight, QImage::Format_ARGB32_Premultiplied); + image.fill(0); + QPainter imagePainter(&image); + + QPolygon polyA;// left or top + QPolygon polyB;//right or bottom + int npaddingLen = 2; + + switch (m_arrowDirection) + { + case leftToRight: + { + int ntoSide = nheight / (double)c_TriangleToEndRate; + int ntriangleWidth = nwidth - ntoBottom - npaddingLen; + int nusingWidth = ntriangleWidth; + QPoint midA(nwidth - ntoBottom, nheight - ntoSide - nusingWidth); + GLDNestScapSplitterTripleHelper tmpA(midA, nusingWidth, 0); + polyA.setPoints(3, tmpA.vertexA().x(), tmpA.vertexA().y(), tmpA.vertexB().x(), + tmpA.vertexB().y(), tmpA.vertexC().x(), tmpA.vertexC().y()); + QPoint midB(nwidth - ntoBottom, ntoSide + nusingWidth); + GLDNestScapSplitterTripleHelper tmpB(midB, nusingWidth, 0); + polyB.setPoints(3, tmpB.vertexA().x(), tmpB.vertexA().y(), tmpB.vertexB().x(), + tmpB.vertexB().y(), tmpB.vertexC().x(), tmpB.vertexC().y()); + break; + } + + case rightToleft: + { + int ntoSide = nheight / (double)c_TriangleToEndRate; + int ntriangleWidth = nwidth - ntoBottom - npaddingLen; + int nusingWidth = ntriangleWidth; + QPoint midA(ntoBottom, nheight - ntoSide - nusingWidth); + GLDNestScapSplitterTripleHelper tmpA(midA, nusingWidth, 1); + polyA.setPoints(3, tmpA.vertexA().x(), tmpA.vertexA().y(), tmpA.vertexB().x(), + tmpA.vertexB().y(), tmpA.vertexC().x(), tmpA.vertexC().y()); + QPoint midB(ntoBottom, ntoSide + nusingWidth); + GLDNestScapSplitterTripleHelper tmpB(midB, nusingWidth, 1); + polyB.setPoints(3, tmpB.vertexA().x(), tmpB.vertexA().y(), tmpB.vertexB().x(), + tmpB.vertexB().y(), tmpB.vertexC().x(), tmpB.vertexC().y()); + break; + } + + case TopToBottom: + { + int ntoSide = nwidth / (double)c_TriangleToEndRate; + int ntriangleHeight = nheight - ntoBottom - npaddingLen; + int nusingHeight = ntriangleHeight - npaddingLen; + polyA.setPoints(3, ntoSide, ntriangleHeight, ntoSide + nusingHeight, npaddingLen, + ntoSide + 2 * nusingHeight, ntriangleHeight); + polyB.setPoints(3, nwidth - ntoSide, ntriangleHeight, nwidth - (ntoSide + nusingHeight), npaddingLen, + nwidth - (ntoSide + 2 * nusingHeight), ntriangleHeight); + break; + } + + case bottomToTop: + { + int ntoSide = nwidth / (double)c_TriangleToEndRate; + int ntriangleHeight = nheight - ntoBottom - npaddingLen; + int nusingHeight = ntriangleHeight - npaddingLen; + polyA.setPoints(3, ntoSide, ntoBottom, ntoSide + nusingHeight, ntriangleHeight, + ntoSide + 2 * nusingHeight, ntoBottom); + polyB.setPoints(3, nwidth - ntoSide, ntoBottom, nwidth - (ntoSide + nusingHeight), ntriangleHeight, + nwidth - (ntoSide + 2 * nusingHeight), ntoBottom); + break; + } + default: + break; + } + + imagePainter.setPen(this->palette().buttonText().color()); + imagePainter.setBrush(this->palette().buttonText()); + imagePainter.setRenderHint(QPainter::Antialiasing); + + imagePainter.drawPolygon(polyA); + imagePainter.drawPolygon(polyB); + { + QPolygon lines; + lines.push_back(polyA.boundingRect().center()); + lines.push_back(polyB.boundingRect().center()); + + int nwidth = painter.pen().width(); + Qt::PenStyle style = Qt::PenStyle(Qt::DotLine); + Qt::PenCapStyle cap = painter.pen().capStyle(); + Qt::PenJoinStyle join = painter.pen().joinStyle(); + + imagePainter.setPen(QPen(Qt::black, nwidth, style, cap, join)); + imagePainter.drawPolyline(lines); + } + imagePainter.end(); + pixmap = QPixmap::fromImage(image); + painter.drawPixmap(0, 0, pixmap); +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDNetScapeSplitterEx.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDNetScapeSplitterEx.cpp new file mode 100644 index 00000000..debd4f06 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDNetScapeSplitterEx.cpp @@ -0,0 +1,95 @@ +#include "GLDNetScapeSplitterEx.h" + +GLDNetScapeSplitterButtonEx::GLDNetScapeSplitterButtonEx(Qt::Orientation o, QWidget *parent) + : GLDNetScapeSplitterButton(o, parent) +{ + setButtonNameByArrowDirection(); + loadStyleSheet(QString("://qsses/splitter.qss")); +} + +void GLDNetScapeSplitterButtonEx::paintEvent(QPaintEvent *e) +{ + QPushButton::paintEvent(e); +} + +void GLDNetScapeSplitterButtonEx::loadStyleSheet(const QString &fileName) +{ + QFile styleSheet(fileName); + + if (!styleSheet.open(QIODevice::ReadOnly)) + { + qWarning(QString("Can't open style sheet file: %1").arg(fileName).toLatin1().data()); + return; + } + + this->setQssFileName(fileName); + this->setStyleSheet(styleSheet.readAll()); +} + +//---GLDNetScapeSplitterHandle +GLDNetScapeSplitterHandleEx::GLDNetScapeSplitterHandleEx(Qt::Orientation o, GLDNetScapeSplitter *parent) + : GLDNetScapeSplitterHandle(o, parent) +{ + +} + +void GLDNetScapeSplitterHandleEx::initButton() +{ + m_pButton = new GLDNetScapeSplitterButtonEx(this->orientation(), this); + + m_pButton->setCursor(Qt::ArrowCursor); + + connect(m_pButton, SIGNAL(clicked()), this, SLOT(handlerButtonClick())); +} + +//---GLDNetScapeSplitter +void GLDNetScapeSplitterEx::init() +{ + setHandleWidth(c_InitialHandleWidthEx); +} + +GLDNetScapeSplitterEx::GLDNetScapeSplitterEx(QWidget *parent): + GLDNetScapeSplitter(parent) +{ + init(); +} + +GLDNetScapeSplitterEx::GLDNetScapeSplitterEx(Qt::Orientation original, + QWidget *parent): + GLDNetScapeSplitter(original, parent) +{ + init(); +} + +GLDNetScapeSplitterEx::GLDNetScapeSplitterEx(bool initCollapsed, + QWidget *parent): + GLDNetScapeSplitter(initCollapsed, parent) +{ + init(); +} + +GLDNetScapeSplitterEx::GLDNetScapeSplitterEx(Qt::Orientation original, + bool initCollapsed, QWidget *parent): + GLDNetScapeSplitter(original, initCollapsed, parent) +{ + init(); +} + +void GLDNetScapeSplitterEx::loadStyleSheet(const QString &fileName) +{ + m_handle->getButton()->loadStyleSheet(fileName); +} + +GLDSplitterHandle *GLDNetScapeSplitterEx::createHandle() +{ + GLDNetScapeSplitterHandleEx *handle = new GLDNetScapeSplitterHandleEx(this->orientation(), this); + + m_handle = handle; + + if (NULL != handle) + { + initSignalSlot(handle); + } + + return handle; +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDNetScapeSplitterHandle.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDNetScapeSplitterHandle.cpp new file mode 100644 index 00000000..b8e49167 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDNetScapeSplitterHandle.cpp @@ -0,0 +1,219 @@ +#include "GLDStrUtils.h" +#include "GLDNetScapeSplitter.h" +#include "GLDNetScapeSplitterHandle.h" + +/* GLDNetScapeSplitterHandle */ + + +GLDNetScapeSplitterHandle::GLDNetScapeSplitterHandle(Qt::Orientation o, GLDSplitter *parent): + GLDSplitterHandle(o, parent), + m_buttonHeight(c_InitialButtonLength), + m_collapseLength(c_InitialHidenLength), + m_expandedLength(100), + m_pSplitter(dynamic_cast(parent)), + m_dragMoveState(initial), + m_bExpanded(true) +{ + +} + +void GLDNetScapeSplitterHandle::initButton() +{ + m_pButton = new GLDNetScapeSplitterButton(this->orientation(), this); + m_pButton->setStyleSheet("border-width:1px;");//border:none; + m_pButton->setVisible(true); + m_pButton->setCursor(Qt::ArrowCursor); + + connect(m_pButton, SIGNAL(clicked()), this, SLOT(handlerButtonClick())); +} + +int GLDNetScapeSplitterHandle::newArrowDirection() const +{ + int nDirection = -1; + + const int nlocalOffset = m_pSplitter->indexOffsetForCollapse(); //注意此处的方向与定义处略有不同,因此时的expanded值在对应状态时是现在的值的非 + const bool bHorizontal = this->orientation() == Qt::Horizontal; + + if (m_bExpanded) + { + nDirection = bHorizontal ? (1 - nlocalOffset) : (2 + nlocalOffset); + } + else + { + nDirection = bHorizontal ? nlocalOffset : (3 - nlocalOffset); + } + + return nDirection; +} + +void GLDNetScapeSplitterHandle::handlerButtonClick() +{ + m_bExpanded = !m_bExpanded; + + Q_ASSERT(m_pSplitter != NULL); + + emit splitterStateSwitched(this, m_bExpanded ? m_expandedLength : m_collapseLength ); + + if (m_dragMoveState >= moved) + { + m_dragMoveState = initial; + } + else + { + m_pButton->update(); + + const int nDirection = newArrowDirection(); + + m_pButton->setArrowDirection(nDirection); + } +} + +void GLDNetScapeSplitterHandle::adjustButtonPos(int splitterLength) +{ + QRect thisRect = this->rect(); + + if (this->orientation() == Qt::Horizontal) + { + m_pButton->setGeometry(0, (splitterLength - m_buttonHeight) / 2.0, + thisRect.width(), m_buttonHeight); + } + else + { + m_pButton->setGeometry((splitterLength - m_buttonHeight) / 2.0, 0, + m_buttonHeight, thisRect.height()); + } +} + +void GLDNetScapeSplitterHandle::onSplitterResized(int nSplitterLength) +{ + if (!m_pButton) + { + return; + } + + if(nSplitterLength <= 20) + { + return; + } + + adjustButtonPos(nSplitterLength); +} + +void GLDNetScapeSplitterHandle::onSplitterResized(QResizeEvent *e) +{ + const int nSplitterLength = (orientation() == Qt::Horizontal)? e->size().height() : e->size().width(); + + onSplitterResized(nSplitterLength); + + changeSplitterExpendLength(e); +} + +void GLDNetScapeSplitterHandle::changeSplitterExpendLength(QResizeEvent *e) +{ + // 重新计算 + if(!m_pSplitter) + { + return; + } + + if(m_pSplitter->isUsingLastExpandSize()) + { + return; + } + + if((orientation() == Qt::Horizontal + ? e->size().width() == e->oldSize().width() + : e->size().height() == e->oldSize().height())) + { + return; + } + + if(m_expandedLength <= 1) + { + return; + } + + if (m_pSplitter->isUsingLastExpandSize() && isInInterval(m_pSplitter->m_dWantedExpandFactor, 0.0, 1.0, 0)) + { + m_expandedLength = m_pSplitter->m_dWantedExpandFactor + * (orientation() == Qt::Horizontal ? e->size().width() : e->size().height()); + } +} + +void GLDNetScapeSplitterHandle::mousePressEvent(QMouseEvent *e) +{ + if (Qt::LeftButton == (e->buttons() & Qt::LeftButton)) + { + m_dragMoveState = pressed; + } + + return GLDSplitterHandle::mousePressEvent(e); +} + +void GLDNetScapeSplitterHandle::mouseMoveEvent(QMouseEvent *e) +{ + if (Qt::LeftButton == (e->buttons() & Qt::LeftButton)) + { + m_dragMoveState = moved; + } + + return GLDSplitterHandle::mouseMoveEvent(e); +} + +void GLDNetScapeSplitterHandle::mouseReleaseEvent(QMouseEvent *e) +{ + if (Qt::LeftButton == (e->button() & Qt::LeftButton)) + { + m_dragMoveState = dragging; + } + + return GLDSplitterHandle::mouseReleaseEvent(e); +} + +int GLDNetScapeSplitterHandle::curArrowDirection() const +{ + if (this->orientation() == Qt::Horizontal) + { + switch (m_pSplitter->m_align) + { + case GLDNetScapeSplitter::alLeftBottom: + return m_bExpanded ? rightToleft : leftToRight; + + case GLDNetScapeSplitter::alRightTop: + return m_bExpanded ? leftToRight :rightToleft; + } + } + else + { + switch (m_pSplitter->m_align) + { + case GLDNetScapeSplitter::alLeftBottom: + return m_bExpanded ? TopToBottom : bottomToTop; + + case GLDNetScapeSplitter::alRightTop: + return m_bExpanded ? bottomToTop : TopToBottom; + } + } + + return inValidDirection; +} + +void GLDNetScapeSplitterHandle::saveExpandLength(int expandLength) const +{ + if (m_pSplitter->isUsingLastExpandSize()) + { + m_expandedLength = expandLength; + } +} + +void GLDNetScapeSplitterHandle::adjustArrowDirection() +{ + if (m_pSplitter) + { + int nDirection = curArrowDirection(); + m_pButton->setArrowDirection(nDirection); + } +} + + + diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDPaperTableView.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDPaperTableView.cpp new file mode 100644 index 00000000..61dc03f7 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDPaperTableView.cpp @@ -0,0 +1,136 @@ +#include "GLDPaperTableView.h" +#include "GLDPaperTableView_p.h" +#include "GLDAbstractItemModel.h" +#include "GLDGlobal.h" + +GlodonPaperTableView::GlodonPaperTableView(QWidget *parent) + : GlodonTableView(*new GlodonPaperTableViewPrivate, parent) +{ + +} + +GlodonPaperTableView::GlodonPaperTableView(GlodonPaperTableViewPrivate &dd, QWidget *parent) + : GlodonTableView(dd, parent) +{ + +} + +void GlodonPaperTableView::showSectionResizingInfoFrame( + const QPoint &mousePosition, Qt::Orientation direction, GlodonHeaderView::ResizeState state) +{ + Q_D(GlodonPaperTableView); + + GlodonTableView::showSectionResizingInfoFrame(mousePosition, direction, state); + + d->m_paperState = state; +} + +void GlodonPaperTableView::columnResized(int column, int oldWidth, int newWidth, bool isManual) +{ + Q_D(GlodonPaperTableView); + + if (GlodonHeaderView::Press == d->m_paperState || GlodonHeaderView::Finish == d->m_paperState) + { + GlodonTableView::columnResized(column, oldWidth, newWidth, isManual); + return; + } + + const double c_fixedWidth = this->width() - oldWidth; + + if (newWidth >= width() || c_fixedWidth <= 0 || newWidth <= 0) + { + d->m_horizontalHeader->resizeSection(column, oldWidth, false, false); + return; + } + + if (d->m_bIsInAdjustFitCols == true) + { + return; + } + + d->m_bIsInAdjustFitCols = true; + + const int c_colCount = d->m_horizontalHeader->count(); + + if (0 == c_colCount) + { + return; + } + + emit enableFitColWidths(false); + + GIntList *originColWidths = new GIntList(); +// QList *originColRate = new QList(); + + for (int i = 0; i < c_colCount; ++i) + { + if (columnWidth(i) > 0) + { + originColWidths->push_back(columnWidth(i)); +// originColRate->push_back(columnWidth(i) / c_fixedWidth); + } + else + { + QModelIndex modelIndex = model()->index(0, i); + QVariant colWidth = modelIndex.data(gidrColWidthRole); + + if (colWidth.isValid()) + { + originColWidths->push_back(colWidth.toInt()); +// originColRate->push_back(colWidth.toInt() / c_fixedWidth); + } + else + { + G_ASSERT(false); +// qDebug() << "GLDTableView::columnResized on paper mode problem"; + } + } + } + + GIntList newWidths(*originColWidths); + { + int nNext = column + 1; + + if (nNext > c_colCount - 1) + { + nNext = column - 1; + } + + int nNextWidth = newWidths[nNext] + oldWidth - newWidth; + const int c_fontSize = horizontalHeader()->fontInfo().pixelSize(); + nNextWidth = (nNextWidth > c_fontSize) ? nNextWidth : c_fontSize; + int nNewWidth = newWidths[nNext] + oldWidth - nNextWidth; + newWidths[column] = nNewWidth; + newWidths[nNext] = nNextWidth; + } + + for (int i = 0; i < newWidths.size(); ++i) + { + if (columnWidth(i) != newWidths.at(i)) + { + setColumnWidth(i, newWidths.at(i)); + } + } + + for (int i = 0; i < d->m_horizontalHeader->count(); ++i) + { + QModelIndex modelIndex = model()->index(0, i); + model()->setData(modelIndex, newWidths.at(i), gidrColWidthRole); + } + + emit columnNewWidths(&newWidths); + d->m_bIsInAdjustFitCols = false; + emit enableFitColWidths(true); + + freeAndNil(originColWidths); + + // Timer 刷新处理 + d->m_columnsToUpdate.append(column); + + if (d->m_columnResizeTimerID == 0) + { + d->m_columnResizeTimerID = startTimer(0); + } +// freeAndNil(originColRate); +} + diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDPaperWidget.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDPaperWidget.cpp new file mode 100644 index 00000000..783450b0 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDPaperWidget.cpp @@ -0,0 +1,576 @@ +#include "GLDDocView.h" +#include "GLDPaperWidget.h" +#include "GLDMultiHeaderView.h" +#include "GLDPaperTableView.h" + +void GLDPaperWidget::createTableView() +{ + if (m_tableViewFactory != NULL) + { + m_tableView = m_tableViewFactory->createTableView(this); + } + else + { + m_tableView = new GlodonPaperTableView(this); + } +} + +void GLDPaperWidget::initTableView() +{ + m_tableView->setFrameShape(QFrame::NoFrame); + m_tableView->setUseBlendColor(true); + + m_tableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_tableView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + +// m_tableView->setEnterJumpPro(true); + m_tableView->setFrameStyle(QFrame::NoFrame); + m_tableView->setAllowSelectCol(false); + m_tableView->setAllowRangeFilling(true); +} + +void GLDPaperWidget::initHeaderView() +{ + m_tableView->verticalHeader()->setHidden(true); + + if (!m_docView->isShowHorizontalHeaderView()) + { + m_tableView->horizontalHeader()->setVisible(false); + } + else if (m_docView->isMutilHeaderViewEnable()) + { + GlodonMultiHeaderView *mHeaderView = new GlodonMultiHeaderView(Qt::Horizontal); + mHeaderView->setDrawBorder(true); + mHeaderView->setObjectName(c_GLDDocView_HHeader); + m_tableView->setHorizontalHeader(mHeaderView); + } + + m_tableView->horizontalHeader()->setMovable(false); + m_tableView->horizontalHeader()->setDragEnabled(false); + m_tableView->horizontalHeader()->setSectionSpanSeparate(true); + m_tableView->horizontalHeader()->setResizeMode(m_resizeMode); + m_tableView->horizontalHeader()->setObjectName(c_GLDDocView_HHeader); + m_tableView->horizontalHeader()->setDrawBorder(true); + m_tableView->horizontalHeader()->setAllowDoubleClicked(false); + m_tableView->horizontalHeader()->setFixedHeight(m_docView->tableViewHorizontalHeaderHeight()); + + connect(m_tableView->horizontalHeader(), SIGNAL(sectionResized(int, int, int, bool)), + this, SLOT(columnResized(int, int, int, bool))); + +} + +void GLDPaperWidget::initHeaderFooter() +{ + const int headerHeight = m_docView->headerHeight(); + const int footerHeight = m_docView->footerHeight(); + + GLDBaseWidgetFactory *factory = m_docView->registeredWidgetFactory(); + + // 把页眉页脚控件拆出去 + + if (factory != NULL) + { + const int pageWidth = m_docView->paperWidth(); + const int leftMargin = m_docView->leftMargin(); + const int rightMargin = m_docView->rightMargin(); + const ZoomFactor zoomFactor = m_docView->factor(); + + this->setHeaderWidget(factory->createHeaderWidget(pageWidth, + headerHeight, + leftMargin, + rightMargin, + zoomFactor, + m_curPageNo, + m_pageCount)); + this->setFooterWidget(factory->createFooterWidget(pageWidth, + footerHeight, + leftMargin, + rightMargin, + zoomFactor, + m_curPageNo, + m_pageCount)); + } + + this->setHeaderHeight(headerHeight); + this->setFooterHeight(footerHeight); +} + +void GLDPaperWidget::initPageGeometry() +{ + const int pageWidth = m_docView->paperWidth(); + const int pageHeight = m_docView->paperHeight(); + + const int headerHeight = m_docView->headerHeight(); + const int footerHeight = m_docView->footerHeight(); + + const int leftMargin = m_docView->leftMargin(); + const int rightMargin = m_docView->rightMargin(); + + const ZoomFactor zoomFactor = m_docView->factor(); + + const int c_FixedWidth = pageWidth - leftMargin - rightMargin; + this->setTableViewWidth(c_FixedWidth); + + const int c_FixedHeight = pageHeight - headerHeight - footerHeight; + this->setTableViewHeight(c_FixedHeight); + + this->setLeftMargin(leftMargin); + this->setRightMargin(rightMargin); + + this->setFactor(zoomFactor); +} + +void GLDPaperWidget::initDelegate() +{ + GlodonDefaultItemDelegateFactory *delegateFactory = m_docView->registeredDelegateFactory(); + + if (delegateFactory != NULL) + { + GlodonDefaultItemDelegate *delegate = delegateFactory->createDelegate(); + delegate->setParent(m_tableView); + + m_tableView->setItemDelegate(delegate); + + connect(delegate, SIGNAL(onQueryIndexDataType(QModelIndex, GlodonDefaultItemDelegate::GDataType &)), + m_docView, SLOT(queryIndexDataType(QModelIndex, GlodonDefaultItemDelegate::GDataType &))); + } +} + +void GLDPaperWidget::initColWidths() +{ + for (int i = 0; i < m_docView->columnCount(); ++i) + { + int ncolWidth = m_docView->columnWidth(i); + + if (ncolWidth != -1) + { + m_tableView->setColumnWidth(i, ncolWidth); + } + } + + if (m_docView->hasFitColumn()) + { + m_tableView->setFitColWidths(m_docView->fitColWidths()); + } +} + +void GLDPaperWidget::initRowHeights() +{ + for (int nRow = 0; nRow < m_tableView->model()->rowCount(); ++nRow) + { + QVariant variant = m_tableView->model()->index(nRow, 0).data(gidrRowHeightRole); + + if (variant.isValid()) + { + m_tableView->setRowHeight(nRow, variant.toInt(), false); + } + } + + + if (m_docView->suitRowHeight()) + { + GIntList oList; + oList.push_back(0); + m_tableView->setSuitRowHeights(oList); + } +} + +void GLDPaperWidget::installEventFilter() +{ + m_tableView->installEventFilter(m_docView); + m_tableView->viewport()->installEventFilter(m_docView); +} + +void GLDPaperWidget::initDataModel() +{ + const int nPageStartRow = m_docView->docInfo().startRowList[m_curPageNo]; + const int nPageRowCount = m_docView->docInfo().rowCountPerPageList[m_curPageNo]; + + GLDPaperWidgetModel *paperModel = new GLDPaperWidgetModel( + m_docView->model(), + m_curPageNo, + nPageStartRow, + nPageRowCount, + m_tableView + ); + + m_tableView->setModel(paperModel); + + connect(paperModel, SIGNAL(rowHeightChanged(QModelIndex, int)), + m_docView, SLOT(postUpdatePaperEvent())); +} + +void GLDPaperWidget::initTableViewMisc() +{ + m_tableView->setAllowResizeCellByDragGridLine(m_docView->allowToResize()); + m_tableView->setAlternatingRowColors(false); +} + +void GLDPaperWidget::initColumnHidden() +{ + if (m_docView->hasColumnHidden()) + { + QMap &map = m_docView->columnsVisableState(); + + QMapIterator i(map); + + while (i.hasNext()) + { + i.next(); + + const int column = i.key(); + const bool visable = i.value(); + + if (m_tableView->isColumnHidden(column) != visable) + { + m_tableView->setColumnHidden(column, visable); + } + + } + } +} + +void GLDPaperWidget::configGridLine() +{ + m_tableView->setShowVerticalGridLine(m_docView->isShowVerticalLine()); + m_tableView->setShowHorizontalGridLine(m_docView->isShowHorizontalLine()); + m_tableView->setGridLineWidth(m_docView->gridLineWidth()); + m_tableView->setIsCustomStyle(true); + m_tableView->setGridLineColor(Qt::black); + m_tableView->setDrawTopAndLeftBorderLine(m_docView->drawFrameLine()); + m_tableView->setFrameLineColor(Qt::black); +} + +void GLDPaperWidget::connectTableViewSignalSlot() +{ + connect(m_tableView, SIGNAL(columnNewWidths(GIntList *)), + m_docView, SLOT(doNewWidthsToPapers(GIntList *))); + + connect(m_tableView, SIGNAL(enableFitColWidths(bool)), + m_docView, SLOT(enableFitColWidths(bool))); + + connect(m_tableView->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), + m_docView, SLOT(onCurrentFocusChanged(QModelIndex, QModelIndex))); + + connect(m_tableView, + SIGNAL(onbeforeMoveCurrent(QModelIndex, QModelIndex, QItemSelectionModel::SelectionFlags &, MoveReason, bool &)), + m_docView, + SLOT(onbeforeMoveCurrent(QModelIndex, QModelIndex, QItemSelectionModel::SelectionFlags &, MoveReason, bool &))); + + connect(m_tableView, SIGNAL(onCommitEditor(QModelIndex, QVariant, bool &)), + m_docView, SLOT(commitEditor(QModelIndex, QVariant, bool &))); + + connect(m_tableView, SIGNAL(rangeFill(QModelIndexList, QModelIndexList, int, int, bool &)), + m_docView, SLOT(onTableViewRangeFill(QModelIndexList, QModelIndexList, int, int, bool &))); + + connect(m_tableView->verticalHeader(), SIGNAL(sectionResized(int, int, int, bool)), + this, SLOT(rowHeightResized(int, int, int, bool))); +} + +GLDPaperWidget::GLDPaperWidget(GLDDocView *docView, + int curPageNo, + int pageCount, + GlodonHeaderView::ResizeMode resizeMode, + GLDDocViewTableViewFactory *tableViewFactory, + QWidget *parent, + Qt::WindowFlags f): + QWidget(parent , f), + m_headerWidget(NULL), + m_factor(NoneFactor), + m_footerWidget(NULL), + m_headerHeight(docView->m_nHeaderHeight), + m_footerHeight(docView->m_nFooterHeight), + m_leftMargin(docView->m_nLeftMargin), + m_rightMargin(docView->m_nRightMargin), + m_docView(docView), + m_resizeMode(resizeMode), + m_curPageNo(curPageNo), + m_pageCount(pageCount), + m_tableViewFactory(tableViewFactory) +{ + m_dPageWidth = m_docView->m_dInitPageWidth; + m_dPageHeight = m_docView->m_dInitPageHeight; + + this->setFixedHeight(m_dPageHeight); + this->setFixedWidth(m_dPageWidth); + + setAutoFillBackground(true); + setBackgroundRole(QPalette::BrightText); + + createTableView(); + + initTableView(); + initHeaderView(); + initDelegate(); + initDataModel(); + initColWidths(); + initRowHeights(); + installEventFilter(); + initTableViewMisc(); + initColumnHidden(); + + configGridLine(); + connectTableViewSignalSlot(); + + initHeaderFooter(); + initPageGeometry(); +} + +GLDPaperWidget::~GLDPaperWidget() +{ + +} + +int GLDPaperWidget::curPageNo() +{ + return m_curPageNo; +} + +void GLDPaperWidget::rowHeightResized(int row, int oldSize, int newSize, bool isManual) +{ + if (!isManual) + { + return; + } + + GlodonHeaderView *pHeaderView = dynamic_cast(sender()); + + if (NULL != pHeaderView) + { + GLDPaperWidgetModel *pModel = NULL; + + if ((pModel = dynamic_cast(pHeaderView->model())) != NULL) + { + QModelIndex tableViewIndex = pModel->index(row, 0); + pModel->setData(tableViewIndex, newSize, gidrRowHeightRole); + } + } + + G_UNUSED(oldSize); +} + +void GLDPaperWidget::columnResized(int column, int oldSize, int newSize, bool isManual) +{ + if (!isManual) + { + return; + } + + GlodonHeaderView *pHeaderView = dynamic_cast(sender()); + + if (NULL != pHeaderView) + { + GLDPaperWidgetModel *pModel = NULL; + + if ((pModel = dynamic_cast(pHeaderView->model())) != NULL) + { + QModelIndex tableViewIndex = pModel->index(column, 0); + pModel->setData(tableViewIndex, newSize, gidrColWidthRole); + } + } + + G_UNUSED(oldSize); +} + +ZoomFactor GLDPaperWidget::factor() const +{ + return m_factor; +} + +void GLDPaperWidget::setFactor(const ZoomFactor &value) +{ + if (m_factor == value) + { + return; + } + + m_factor = value; + double dfactor = m_factor; + + if (m_factor == percent_50) + { + dfactor = 0.5; + } + + m_dPageWidth = m_docView->m_dInitPageWidth * dfactor; + m_dPageHeight = m_docView->m_dInitPageHeight * dfactor; + + m_tableView->zoomTableView(dfactor); + + this->setFixedHeight(m_dPageHeight); + this->setFixedWidth(m_dPageWidth); + + reLayout(); +} + +QSize GLDPaperWidget::sizeHint() const +{ + return QWidget::sizeHint(); +} + +int GLDPaperWidget::headerHeight() const +{ + return m_headerHeight; +} + +void GLDPaperWidget::setHeaderHeight(int headerHeight) +{ + m_headerHeight = headerHeight; + + if (m_headerWidget != NULL) + { + m_headerWidget->setFixedHeight(headerHeight); + } +} + +int GLDPaperWidget::footerHeight() const +{ + return m_footerHeight; +} + +void GLDPaperWidget::setFooterHeight(int footerHeight) +{ + m_footerHeight = footerHeight; + + if (m_footerWidget != NULL) + { + m_footerWidget->setFixedHeight(footerHeight); + } +} + +int GLDPaperWidget::tableViewWidth() const +{ + return m_tableViewWidth; +} + +void GLDPaperWidget::setTableViewWidth(int tableViewWidth) +{ + m_tableViewWidth = tableViewWidth; + m_tableView->setFixedWidth(m_tableViewWidth); +} + +int GLDPaperWidget::tableViewHeight() const +{ + return m_tableViewHeight; +} + +void GLDPaperWidget::setTableViewHeight(int tableViewHeight) +{ + m_tableViewHeight = tableViewHeight; + m_tableView->setFixedHeight(m_tableViewHeight); +} + +void GLDPaperWidget::reLayout() +{ + m_tableView->move(m_leftMargin, m_headerHeight); + + if (m_footerWidget != NULL) + { + m_footerWidget->move(0, m_headerHeight + m_tableViewHeight); + m_footerWidget->setFixedWidth(this->width()); + } + + if (m_headerWidget != NULL) + { + m_headerWidget->move(0, 0); + m_headerWidget->setFixedWidth(this->width()); + } +} + +QWidget *GLDPaperWidget::headerWidget() const +{ + return m_headerWidget; +} + +void GLDPaperWidget::setHeaderWidget(QWidget *headerWidget) +{ + if (m_headerWidget == headerWidget) + { + return; + } + + freeAndNil(m_headerWidget); + m_headerWidget = headerWidget; + + if (m_headerWidget != NULL) + { + m_headerWidget->setParent(this); + m_headerWidget->setFixedWidth(this->width()); + } +} + +QWidget *GLDPaperWidget::footerWidget() const +{ + return m_footerWidget; +} + +void GLDPaperWidget::setFooterWidget(QWidget *footerWidget) +{ + if (m_footerWidget == footerWidget) + { + return; + } + + freeAndNil(m_footerWidget); + m_footerWidget = footerWidget; + + if (footerWidget != NULL) + { + m_footerWidget->setParent(this); + m_footerWidget->setFixedWidth(this->width()); + } +} + +int GLDPaperWidget::rightMargin() const +{ + return m_rightMargin; +} + +void GLDPaperWidget::setRightMargin(int rightMargin) +{ + m_rightMargin = rightMargin; +} + +int GLDPaperWidget::leftMargin() const +{ + return m_leftMargin; +} + +void GLDPaperWidget::setLeftMargin(int leftMargin) +{ + m_leftMargin = leftMargin; +} + +void GLDPaperWidget::setPaperWidth(int value) +{ + G_UNUSED(value); + + double dfactor = int(m_factor); + + if (m_factor == percent_50) + { + dfactor = 0.5; + } + + m_dPageWidth = m_docView->m_dInitPageWidth * dfactor; +} + +int GLDPaperWidget::paperHeight() const +{ + return m_dPageHeight; +} + +void GLDPaperWidget::setPaperHeight(int value) +{ + G_UNUSED(value); + + double dfactor = int(m_factor); + + if (m_factor == percent_50) + { + dfactor = 0.5; + } + + m_dPageHeight = m_docView->m_dInitPageHeight * dfactor; +} + diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDPaperWidgetModel.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDPaperWidgetModel.cpp new file mode 100644 index 00000000..53909fa2 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDPaperWidgetModel.cpp @@ -0,0 +1,149 @@ +#include "GLDPaperWidgetModel.h" + +#include "GLDAbstractItemModel.h" + +/* GLDPaperWidgetModel */ +GLDPaperWidgetModel::GLDPaperWidgetModel(QAbstractItemModel *pModel, + int nCurPageNo, int startRow, int rowCount, + QObject *parent) + : GlodonAbstractItemModel(parent), m_nCurPageNo(nCurPageNo) +{ + setObjectName("GLDPaperWidgetModel"); + m_dataModel = pModel; + m_nStartRow = startRow; + m_nRowCountPerPage = rowCount; +} + +GLDPaperWidgetModel::~GLDPaperWidgetModel() +{ + +} + +QModelIndex GLDPaperWidgetModel::index(int row, + int column, + const QModelIndex &parent) const +{ + QModelIndex dataIndex = m_dataModel->index(row + m_nStartRow, column, parent); + return createIndex(row, column, dataIndex.internalPointer()); +} + +QModelIndex GLDPaperWidgetModel::parent(const QModelIndex &child) const +{ + Q_UNUSED(child) + return QModelIndex(); +} + +int GLDPaperWidgetModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + return m_nRowCountPerPage; +} + +int GLDPaperWidgetModel::columnCount(const QModelIndex &parent) const +{ + return m_dataModel->columnCount(parent); +} + +QVariant GLDPaperWidgetModel::data(const QModelIndex &index, int role) const +{ + return m_dataModel->data(dataIndex(index), role); +} + +bool GLDPaperWidgetModel::setData(const QModelIndex &index, + const QVariant &value, + int role) +{ + bool bSuccess = m_dataModel->setData(dataIndex(index), value, role); + + if (bSuccess) + { + switch (role) + { + case gidrColWidthRole: + emit columnWidthChanged(index, value.toInt()); + break; + + case gidrRowHeightRole: + emit rowHeightChanged(index, value.toInt()); + break; + + default: + break; + } + } + + return bSuccess; +} + +Qt::ItemFlags GLDPaperWidgetModel::flags(const QModelIndex &index) const +{ + return m_dataModel->flags(dataIndex(index)); +} + +QModelIndex GLDPaperWidgetModel::dataIndex(const QModelIndex &index) const +{ + return m_dataModel->index(index.row() + m_nStartRow, index.column(), index.parent()); +} + +QVariant GLDPaperWidgetModel::headerData(int section, + Qt::Orientation orientation, + int role) const +{ + //当竖直方向表头不是数字时,需要特殊处理 + return m_dataModel->headerData(section, orientation, role); +} + +bool GLDPaperWidgetModel::setHeaderData(int section, + Qt::Orientation orientation, + const QVariant &value, int role) +{ + return m_dataModel->setHeaderData(section, orientation, value, role); +} + +bool GLDPaperWidgetModel::insertRows(int row, + int count, + const QModelIndex &parent) +{ + return m_dataModel->insertRows(row, count, dataIndex(parent)); +} + +bool GLDPaperWidgetModel::insertColumns(int column, + int count, + const QModelIndex &parent) +{ + return m_dataModel->insertColumns(column, count, dataIndex(parent)); +} + +bool GLDPaperWidgetModel::removeRows(int row, + int count, + const QModelIndex &parent) +{ + return m_dataModel->removeRows(row, count, dataIndex(parent)); +} + +bool GLDPaperWidgetModel::removeColumns(int column, + int count, + const QModelIndex &parent) +{ + return m_dataModel->removeColumns(column, count, dataIndex(parent)); +} + +void GLDPaperWidgetModel::setStartRow(int startRow) +{ + m_nStartRow = startRow; +} + +void GLDPaperWidgetModel::setRowCountPerPage(int rowCount) +{ + m_nRowCountPerPage = rowCount; +} + +int GLDPaperWidgetModel::curPageNo() const +{ + return m_nCurPageNo; +} + +void GLDPaperWidgetModel::setCurPageNo(int nCurPageNo) +{ + m_nCurPageNo = nCurPageNo; +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDPlainTextEdit.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDPlainTextEdit.cpp new file mode 100644 index 00000000..675bd055 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDPlainTextEdit.cpp @@ -0,0 +1,97 @@ +#include "GLDPlainTextEdit.h" +#include +#include +#include +#include +#include +#include "GLDTableView.h" + +//GLDPlainTextEdit::GLDPlainTextEdit(QWidget *parent) : QPlainTextEdit(parent), +// prevLineCount(-1), prevTopPadding(-1), prevLeftPadding(-1), firstShow(true), gridDrawIndex(0,0) +//{ +// QObject::connect(this, SIGNAL(textChanged()), this, SLOT(adjustVerticalPadding())); +//} + +//GLDPlainTextEdit::GLDPlainTextEdit(QWidget *parent, QPoint gridIndex) : QPlainTextEdit(parent), firstShow(true), +// gridDrawIndex(gridIndex), prevLineCount(-1), prevTopPadding(-1), prevLeftPadding(-1) +//{ +// QObject::connect(this, SIGNAL(textChanged()), this, SLOT(adjustVerticalPadding())); +//} + +//void GLDPlainTextEdit::setPaddingByOffset() +//{ +// setPaddingByOffset(gridUsingOffset()); +//} + +//void GLDPlainTextEdit::setPaddingByOffset(const QPoint &gridUsingOffset) +//{ +// QPointF offset(QPlainTextEdit::contentOffset()); +// resetPadding(gridUsingOffset.x() - offset.x(), gridUsingOffset.y() - (offset.y()<0? 1 :offset.y())); +//} + +//void GLDPlainTextEdit::resetPadding(int left, int top, int right, int bottom) +//{ +// prevLeftPadding = left; +// prevTopPadding = top; +// QString styleSheet = right < 0x7fff ? leftTopRightBottomStyleString().arg(left).arg(top).arg(right).arg(bottom) : leftTopStyleString().arg(left).arg(top) ; +// styleSheet = "background-color:rgb(255, 255, 255); " + styleSheet; +// this->setStyleSheet(styleSheet); +//} + +//void GLDPlainTextEdit::adjustVerticalPadding() +//{ +// int newLineCount = this->document()->lineCount(); +// if (prevLineCount != newLineCount ) +// { +// if (QTextLayout *textLayout = this->firstVisibleBlock().layout()) +// { +// QTextLine firstLine = textLayout->lineAt(0); +// if (firstLine.isValid()) +// { +// int lineHeight = firstLine.height(); +// if (lineHeight * newLineCount >= this->viewport()->height()) +// { +// prevTopPadding = 1; +// } +// else +// prevTopPadding = prevTopPadding + lineHeight *(prevLineCount - newLineCount) / 2.0; + +// if (prevTopPadding <= 0) +// prevTopPadding = 1; +// QString styleSheet = leftTopStyleString().arg(prevLeftPadding).arg(prevTopPadding); +// this->setStyleSheet(styleSheet); +// prevLineCount = newLineCount; +// } +// } +// } +//} + +//void GLDPlainTextEdit::showEvent(QShowEvent *e) +//{ +// QPlainTextEdit::showEvent(e); +// if (firstShow) +// { +// firstShow = false; +// setPaddingByOffset(); +// prevLineCount = firstVisibleBlock().layout()->lineCount(); +// } +//} + +//QPoint GLDPlainTextEdit::gridUsingOffset() +//{ +// QPoint offsetPadding(0,0); +// QWidget *pViewPort = qobject_cast(parent()); +// if (pViewPort) +// { +// GlodonTableView *pParent = qobject_cast(pViewPort->parent()); +// if (pParent) +// { +//// qDebug()<index2Offset; +// if (pParent->index2Offset.contains(this->gridDrawIndex)) +// { +// offsetPadding = pParent->index2Offset[this->gridDrawIndex]; +// } +// } +// } +// return offsetPadding; +//} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDPopupWindow.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDPopupWindow.cpp new file mode 100644 index 00000000..45ed91f1 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDPopupWindow.cpp @@ -0,0 +1,1140 @@ +#include "GLDPopupWindow.h" + +#include "qcombobox.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef QT_NO_IM +#include "qinputcontext.h" +#endif +#include +#include +#include +#include +#include +#include + +#ifndef QT_NO_EFFECTS +# include +#endif + +#ifndef QT_NO_ACCESSIBILITY +#include "qaccessible.h" +#endif + +GLDPopupWindowPrivate::GLDPopupWindowPrivate() + : QWidgetPrivate(), + lineEdit(0), + container(0), + sizeAdjustPolicy(GLDPopupWindow::AdjustToContentsOnFirstShow), + minimumContentsLength(0), + shownOnce(false), + duplicatesEnabled(false), + frame(true), + arrowState(QStyle::State_None), + hoverControl(QStyle::SC_None), + indexBeforeChange(-1) +{ +} + +void GLDPopupWindowPrivate::updateArrow(QStyle::StateFlag state) +{ + Q_Q(GLDPopupWindow); + if (arrowState == state) + return; + arrowState = state; + QStyleOptionComboBox opt; + q->initStyleOption(&opt); + q->update(q->style()->subControlRect(QStyle::CC_ComboBox, &opt, QStyle::SC_ComboBoxArrow, q)); +} + +QRect GLDPopupWindowPrivate::popupGeometry(int screen) const +{ + return QApplication::desktop()->screenGeometry(screen); +} + +bool GLDPopupWindowPrivate::updateHoverControl(const QPoint &pos) +{ + + Q_Q(GLDPopupWindow); + QRect lastHoverRect = hoverRect; + QStyle::SubControl lastHoverControl = hoverControl; + bool doesHover = q->testAttribute(Qt::WA_Hover); + if (lastHoverControl != newHoverControl(pos) && doesHover) { + q->update(lastHoverRect); + q->update(hoverRect); + return true; + } + return !doesHover; +} + +QStyle::SubControl GLDPopupWindowPrivate::newHoverControl(const QPoint &pos) +{ + Q_Q(GLDPopupWindow); + QStyleOptionComboBox opt; + q->initStyleOption(&opt); + opt.subControls = QStyle::SC_All; + hoverControl = q->style()->hitTestComplexControl(QStyle::CC_ComboBox, &opt, pos, q); + hoverRect = (hoverControl != QStyle::SC_None) + ? q->style()->subControlRect(QStyle::CC_ComboBox, &opt, hoverControl, q) + : QRect(); + return hoverControl; +} + +int GLDPopupWindowPrivate::computeWidthHint() const +{ + Q_Q(const GLDPopupWindow); + + int width = 0; + + QStyleOptionComboBox opt; + q->initStyleOption(&opt); + QSize tmp(width, 0); + tmp = q->style()->sizeFromContents(QStyle::CT_ComboBox, &opt, tmp, q); + return tmp.width(); +} + +QSize GLDPopupWindowPrivate::recomputeSizeHint(QSize &sh) const +{ + Q_Q(const GLDPopupWindow); + if (!sh.isValid()) + { + const QFontMetrics &fm = q->fontMetrics(); + + // text width + if (&sh == &sizeHint || minimumContentsLength == 0) + { + switch (sizeAdjustPolicy) + { + case GLDPopupWindow::AdjustToContents: + case GLDPopupWindow::AdjustToContentsOnFirstShow: + sh.rwidth() = 7 * fm.width(QLatin1Char('x')); + break; + default: + ; + } + } + + if (minimumContentsLength > 0) + sh.setWidth(qMax(sh.width(), minimumContentsLength * fm.width(QLatin1Char('X')))); + + // height + sh.setHeight(qMax(qCeil(QFontMetricsF(fm).height()), 14) + 2); + + // add style and strut values + QStyleOptionComboBox opt; + q->initStyleOption(&opt); + sh = q->style()->sizeFromContents(QStyle::CT_ComboBox, &opt, sh, q); + } + return sh.expandedTo(QApplication::globalStrut()); +} + +void GLDPopupWindowPrivate::adjustComboBoxSize() +{ + viewContainer()->adjustSizeTimer.start(20, container); +} + +void GLDPopupWindowPrivate::updateLayoutDirection() +{ + Q_Q(const GLDPopupWindow); + QStyleOptionComboBox opt; + q->initStyleOption(&opt); + Qt::LayoutDirection dir = Qt::LayoutDirection( + q->style()->styleHint(QStyle::SH_ComboBox_LayoutDirection, &opt, q)); + if (lineEdit) + lineEdit->setLayoutDirection(dir); + if (container) + container->setLayoutDirection(dir); +} + + +void GPopupWindowPrivateContainer::timerEvent(QTimerEvent *timerEvent) +{ + if (timerEvent->timerId() == adjustSizeTimer.timerId()) { + adjustSizeTimer.stop(); + if (combo->sizeAdjustPolicy() == GLDPopupWindow::AdjustToContents) { + combo->updateGeometry(); + combo->adjustSize(); + combo->update(); + } + } +} + +void GPopupWindowPrivateContainer::resizeEvent(QResizeEvent *e) +{ + QStyleOptionComboBox opt = comboStyleOption(); + if (combo->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, combo)) { + QStyleOption myOpt; + myOpt.initFrom(this); + QStyleHintReturnMask mask; + if (combo->style()->styleHint(QStyle::SH_Menu_Mask, &myOpt, this, &mask)) { + setMask(mask.region); + } + } else { + clearMask(); + } + QFrame::resizeEvent(e); +} + +GPopupWindowPrivateContainer::GPopupWindowPrivateContainer(GLDPopupWindow *parent) + : QFrame(parent, Qt::Popup), combo(parent) +{ + Q_ASSERT(parent); + + setAttribute(Qt::WA_WindowPropagation); + setAttribute(Qt::WA_X11NetWmWindowTypeCombo); + + // setup container + blockMouseReleaseTimer.setSingleShot(true); + + // we need a vertical layout + QBoxLayout *layout = new QBoxLayout(QBoxLayout::TopToBottom, this); + layout->setSpacing(0); + layout->setMargin(0); + + // add scroller arrows if style needs them + QStyleOptionComboBox opt = comboStyleOption(); + const bool usePopup = combo->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, combo); + if (!usePopup) + { + setLineWidth(1); + } + + setFrameStyle(combo->style()->styleHint(QStyle::SH_ComboBox_PopupFrameStyle, &opt, combo)); + + // Some styles (Mac) have a margin at the top and bottom of the popup. + layout->insertSpacing(0, 0); + layout->addSpacing(0); + updateTopBottomMargin(); +} + +int GPopupWindowPrivateContainer::spacing() const +{ + return 0; +} + +void GPopupWindowPrivateContainer::updateTopBottomMargin() +{ + if (!layout() || layout()->count() < 1) + return; + + QBoxLayout *boxLayout = qobject_cast(layout()); + if (!boxLayout) + return; + + const QStyleOptionComboBox opt = comboStyleOption(); + const bool usePopup = combo->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, combo); + const int margin = usePopup ? combo->style()->pixelMetric(QStyle::PM_MenuVMargin, &opt, combo) : 0; + + QSpacerItem *topSpacer = boxLayout->itemAt(0)->spacerItem(); + if (topSpacer) + topSpacer->changeSize(0, margin, QSizePolicy::Minimum, QSizePolicy::Fixed); + + QSpacerItem *bottomSpacer = boxLayout->itemAt(boxLayout->count() - 1)->spacerItem(); + if (bottomSpacer && bottomSpacer != topSpacer) + bottomSpacer->changeSize(0, margin, QSizePolicy::Minimum, QSizePolicy::Fixed); + + boxLayout->invalidate(); +} + +void GPopupWindowPrivateContainer::setWidget(QWidget *newWidget) +{ + if (popupWidget != newWidget) + { + popupWidget = newWidget; + popupWidget->setParent(this); + setFixedSize(popupWidget->size()); + popupWidget->setGeometry(0, 0, popupWidget->width(), popupWidget->height()); + popupWidget->setVisible(true); + } +} + +QWidget *GPopupWindowPrivateContainer::widget() +{ + return popupWidget; +} + +void GPopupWindowPrivateContainer::changeEvent(QEvent *e) +{ + if (e->type() == QEvent::StyleChange) { + QStyleOptionComboBox opt = comboStyleOption(); + setFrameStyle(combo->style()->styleHint(QStyle::SH_ComboBox_PopupFrameStyle, &opt, combo)); + } + QWidget::changeEvent(e); +} + + +bool GPopupWindowPrivateContainer::eventFilter(QObject *o, QEvent *e) +{ + switch (e->type()) { + case QEvent::ShortcutOverride: + switch (static_cast(e)->key()) + { + case Qt::Key_Enter: + case Qt::Key_Return: + return true; + case Qt::Key_Down: + if (!(static_cast(e)->modifiers() & Qt::AltModifier)) + break; + // fall through + case Qt::Key_F4: + case Qt::Key_Escape: + combo->hidePopup(); + return true; + default: + break; + } + break; + case QEvent::MouseMove: + if (isVisible()) { + QMouseEvent *m = static_cast(e); + QWidget *widget = static_cast(o); + QPoint vector = widget->mapToGlobal(m->pos()) - initialClickPosition; + if (vector.manhattanLength() > 9 && blockMouseReleaseTimer.isActive()) + blockMouseReleaseTimer.stop(); + } + break; + case QEvent::MouseButtonRelease: { + if (isVisible()) + { + combo->hidePopup(); + return true; + } + break; + } + default: + break; + } + return QFrame::eventFilter(o, e); +} + +void GPopupWindowPrivateContainer::showEvent(QShowEvent *) +{ + combo->update(); +} + +void GPopupWindowPrivateContainer::hideEvent(QHideEvent *) +{ + emit resetButton(); + combo->update(); +#ifndef QT_NO_GRAPHICSVIEW + // QGraphicsScenePrivate::removePopup closes the combo box popup, it hides it non-explicitly. + // Hiding/showing the GLDPopupWindow after this will unexpectedly show the popup as well. + // Re-hiding the popup container makes sure it is explicitly hidden. + if (QGraphicsProxyWidget *proxy = graphicsProxyWidget()) + proxy->hide(); +#endif +} + +void GPopupWindowPrivateContainer::mousePressEvent(QMouseEvent *e) +{ + QStyleOptionComboBox opt = comboStyleOption(); + opt.subControls = QStyle::SC_All; + opt.activeSubControls = QStyle::SC_ComboBoxArrow; + QStyle::SubControl sc = combo->style()->hitTestComplexControl(QStyle::CC_ComboBox, &opt, + combo->mapFromGlobal(e->globalPos()), + combo); + if ((combo->isEditable() && sc == QStyle::SC_ComboBoxArrow) + || (!combo->isEditable() && sc != QStyle::SC_None)) + setAttribute(Qt::WA_NoMouseReplay); +} + +void GPopupWindowPrivateContainer::mouseReleaseEvent(QMouseEvent *e) +{ + Q_UNUSED(e); + if (!blockMouseReleaseTimer.isActive()) + { + combo->hidePopup(); + emit resetButton(); + } +} + +QStyleOptionComboBox GPopupWindowPrivateContainer::comboStyleOption() const +{ + // ### This should use GLDPopupWindow's initStyleOption(), but it's protected + // perhaps, we could cheat by having the QCombo private instead? + QStyleOptionComboBox opt; + opt.initFrom(combo); + opt.subControls = QStyle::SC_All; + opt.activeSubControls = QStyle::SC_None; + opt.editable = combo->isEditable(); + return opt; +} + +GLDPopupWindow::GLDPopupWindow(QWidget *parent) + : QWidget(*new GLDPopupWindowPrivate(), parent, 0) +{ + Q_D(GLDPopupWindow); + d->init(); +} + +GLDPopupWindow::GLDPopupWindow(GLDPopupWindowPrivate &dd, QWidget *parent) + : QWidget(dd, parent, 0) +{ + Q_D(GLDPopupWindow); + d->init(); +} + +void GLDPopupWindowPrivate::init() +{ + Q_Q(GLDPopupWindow); + q->setFocusPolicy(Qt::WheelFocus); + q->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed, + QSizePolicy::ComboBox)); + setLayoutItemMargins(QStyle::SE_ComboBoxLayoutItem); + if (!q->isEditable()) + q->setAttribute(Qt::WA_InputMethodEnabled, false); + else + q->setAttribute(Qt::WA_InputMethodEnabled); +} + +GPopupWindowPrivateContainer* GLDPopupWindowPrivate::viewContainer() +{ + if (container) + return container; + + Q_Q(GLDPopupWindow); + + container = new GPopupWindowPrivateContainer(q); + updateLayoutDirection(); + updateViewContainerPaletteAndOpacity(); + QObject::connect(container, SIGNAL(resetButton()), q, SLOT(_q_resetButton())); + return container; +} + + +void GLDPopupWindowPrivate::_q_resetButton() +{ + updateArrow(QStyle::State_None); +} + +void GLDPopupWindowPrivate::updateViewContainerPaletteAndOpacity() +{ + if (!container) + return; + Q_Q(GLDPopupWindow); + QStyleOptionComboBox opt; + q->initStyleOption(&opt); +#ifndef QT_NO_MENU + if (q->style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, q)) { + QMenu menu; + menu.ensurePolished(); + container->setPalette(menu.palette()); + container->setWindowOpacity(menu.windowOpacity()); + } else +#endif + { + container->setPalette(q->palette()); + container->setWindowOpacity(1.0); + } + if (lineEdit) + lineEdit->setPalette(q->palette()); +} + +void GLDPopupWindow::initStyleOption(QStyleOptionComboBox *option) const +{ + if (!option) + return; + + Q_D(const GLDPopupWindow); + option->initFrom(this); + option->editable = isEditable(); + option->frame = d->frame; + if (hasFocus() && !option->editable) + option->state |= QStyle::State_Selected; + option->subControls = QStyle::SC_All; + if (d->arrowState == QStyle::State_Sunken) { + option->activeSubControls = QStyle::SC_ComboBoxArrow; + option->state |= d->arrowState; + } + else + { + option->activeSubControls = d->hoverControl; + } + if (d->container && d->container->isVisible()) + option->state |= QStyle::State_On; +} + +void GLDPopupWindowPrivate::updateLineEditGeometry() +{ + if (!lineEdit) + return; + + Q_Q(GLDPopupWindow); + QStyleOptionComboBox opt; + q->initStyleOption(&opt); + QRect editRect = q->style()->subControlRect(QStyle::CC_ComboBox, &opt, + QStyle::SC_ComboBoxEditField, q); + lineEdit->setGeometry(editRect); +} + +Qt::MatchFlags GLDPopupWindowPrivate::matchFlags() const +{ + // Base how duplicates are determined on the autocompletion case sensitivity + Qt::MatchFlags flags = Qt::MatchFixedString; +#ifndef QT_NO_COMPLETER + if (!lineEdit->completer() || lineEdit->completer()->caseSensitivity() == Qt::CaseSensitive) +#endif + flags |= Qt::MatchCaseSensitive; + return flags; +} + +void GLDPopupWindowPrivate::_q_returnPressed() +{ + if (lineEdit && !lineEdit->text().isEmpty()) { + lineEdit->deselect(); + lineEdit->end(false); + + // check for duplicates (if not enabled) and quit + if (!duplicatesEnabled) + { + return; + } + } +} + +GLDPopupWindow::~GLDPopupWindow() +{ +} + +bool GLDPopupWindow::duplicatesEnabled() const +{ + Q_D(const GLDPopupWindow); + return d->duplicatesEnabled; +} + +void GLDPopupWindow::setDuplicatesEnabled(bool enable) +{ + Q_D(GLDPopupWindow); + d->duplicatesEnabled = enable; +} + +GLDPopupWindow::SizeAdjustPolicy GLDPopupWindow::sizeAdjustPolicy() const +{ + Q_D(const GLDPopupWindow); + return d->sizeAdjustPolicy; +} + +void GLDPopupWindow::setSizeAdjustPolicy(GLDPopupWindow::SizeAdjustPolicy policy) +{ + Q_D(GLDPopupWindow); + if (policy == d->sizeAdjustPolicy) + return; + + d->sizeAdjustPolicy = policy; + d->sizeHint = QSize(); + d->adjustComboBoxSize(); + updateGeometry(); +} + +int GLDPopupWindow::minimumContentsLength() const +{ + Q_D(const GLDPopupWindow); + return d->minimumContentsLength; +} + +void GLDPopupWindow::setMinimumContentsLength(int characters) +{ + Q_D(GLDPopupWindow); + if (characters == d->minimumContentsLength || characters < 0) + return; + + d->minimumContentsLength = characters; + + if (d->sizeAdjustPolicy == AdjustToContents + || d->sizeAdjustPolicy == AdjustToMinimumContentsLengthWithIcon) + { + d->sizeHint = QSize(); + d->adjustComboBoxSize(); + updateGeometry(); + } +} + +bool GLDPopupWindow::isEditable() const +{ + Q_D(const GLDPopupWindow); + return d->lineEdit != 0; +} + +void GLDPopupWindow::setEditable(bool editable) +{ + Q_D(GLDPopupWindow); + if (isEditable() == editable) + return; + + QStyleOptionComboBox opt; + initStyleOption(&opt); + if (editable) + { + QLineEdit *le = new QLineEdit(this); + setLineEdit(le); + } + else + { + setAttribute(Qt::WA_InputMethodEnabled, false); + d->lineEdit->hide(); + d->lineEdit->deleteLater(); + d->lineEdit = 0; + } + + d->viewContainer()->updateTopBottomMargin(); + if (!testAttribute(Qt::WA_Resized)) + adjustSize(); +} + +void GLDPopupWindow::setLineEdit(QLineEdit *edit) +{ + Q_D(GLDPopupWindow); + if (!edit) { + qWarning("GLDPopupWindow::setLineEdit: cannot set a 0 line edit"); + return; + } + + if (edit == d->lineEdit) + return; + + edit->setText(currentText()); + delete d->lineEdit; + + d->lineEdit = edit; + if (d->lineEdit->parent() != this) + d->lineEdit->setParent(this); + connect(d->lineEdit, SIGNAL(returnPressed()), this, SLOT(_q_returnPressed())); + connect(d->lineEdit, SIGNAL(editingFinished()), this, SLOT(_q_editingFinished())); + connect(d->lineEdit, SIGNAL(textChanged(QString)), this, SIGNAL(editTextChanged(QString))); + d->lineEdit->setFrame(false); + d->lineEdit->setContextMenuPolicy(Qt::NoContextMenu); + d->lineEdit->setFocusProxy(this); + d->lineEdit->setAttribute(Qt::WA_MacShowFocusRect, false); + setAttribute(Qt::WA_InputMethodEnabled); + d->updateLayoutDirection(); + d->updateLineEditGeometry(); + if (isVisible()) + d->lineEdit->show(); + + update(); +} + +/*! + Returns the line edit used to edit items in the combobox, or 0 if there + is no line edit. + + Only editable combo boxes have a line edit. +*/ +QLineEdit *GLDPopupWindow::lineEdit() const +{ + Q_D(const GLDPopupWindow); + return d->lineEdit; +} + +#ifndef QT_NO_VALIDATOR +/*! + \fn void GLDPopupWindow::setValidator(const QValidator *validator) + + Sets the \a validator to use instead of the current validator. +*/ + +void GLDPopupWindow::setValidator(const QValidator *v) +{ + Q_D(GLDPopupWindow); + if (d->lineEdit) + d->lineEdit->setValidator(v); +} + +const QValidator *GLDPopupWindow::validator() const +{ + Q_D(const GLDPopupWindow); + return d->lineEdit ? d->lineEdit->validator() : 0; +} +#endif // QT_NO_VALIDATOR + +QString GLDPopupWindow::currentText() const +{ + Q_D(const GLDPopupWindow); + if (d->lineEdit) + return d->lineEdit->text(); + else + return QString(); +} + +QSize GLDPopupWindow::minimumSizeHint() const +{ + Q_D(const GLDPopupWindow); + return d->recomputeSizeHint(d->minimumSizeHint); +} + +QSize GLDPopupWindow::sizeHint() const +{ + Q_D(const GLDPopupWindow); + return d->recomputeSizeHint(d->sizeHint); +} + +void GLDPopupWindow::showPopup() +{ + Q_D(GLDPopupWindow); + if (d->container->widget() == 0) + { + return; + } + + QStyle * const style = this->style(); + + // set current item and select it + + GPopupWindowPrivateContainer* container = d->viewContainer(); + QStyleOptionComboBox opt; + initStyleOption(&opt); + QRect listRect(style->subControlRect(QStyle::CC_ComboBox, &opt, + QStyle::SC_ComboBoxListBoxPopup, this)); + + QRect vcRect(0, 0, container->width(), container->height()); + + QRect screen = d->popupGeometry(QApplication::desktop()->screenNumber(this)); + + QPoint below = mapToGlobal(listRect.bottomLeft()); + int belowHeight = screen.bottom() - below.y(); + QPoint above = mapToGlobal(listRect.topLeft()); + int aboveHeight = above.y() - screen.y(); + bool boundToScreen = !window()->testAttribute(Qt::WA_DontShowOnScreen); + + const bool usePopup = style->styleHint(QStyle::SH_ComboBox_Popup, &opt, this); + { + // add the spacing for the grid on the top and the bottom; + int heightMargin = 2*container->spacing(); + + // add the frame of the container + int marginTop, marginBottom = 0; + container->getContentsMargins(0, &marginTop, 0, &marginBottom); + heightMargin += marginTop + marginBottom; + + //add the frame of the view + heightMargin += marginTop + marginBottom; + + listRect.setHeight(listRect.height() + heightMargin); + } + + // Add space for margin at top and bottom if the style wants it. + if (usePopup) + listRect.setHeight(listRect.height() + style->pixelMetric(QStyle::PM_MenuVMargin, &opt, this) * 2); + + // Make sure the popup is wide enough to display its contents. + if (usePopup) { + const int diff = d->computeWidthHint() - width(); + if (diff > 0) + listRect.setWidth(listRect.width() + diff); + } + + //we need to activate the layout to make sure the min/maximum size are set when the widget was not yet show + container->layout()->activate(); + //takes account of the minimum/maximum size of the container + + // make sure the widget fits on screen + if (boundToScreen) + { + if (vcRect.width() > screen.width()) + { + vcRect.setWidth(screen.width()); + } + + if (mapToGlobal(vcRect.bottomRight()).x() > screen.right()) + { + below.setX(screen.x() + screen.width() - vcRect.width()); + above.setX(screen.x() + screen.width() - vcRect.width()); + } + + if (mapToGlobal(vcRect.topLeft()).x() < screen.x()) + { + below.setX(screen.x()); + above.setX(screen.x()); + } + } + + if (usePopup) + { + // Position horizontally. + listRect.moveLeft(above.x()); + + const int height = !boundToScreen ? listRect.height() : qMin(listRect.height(), screen.height()); + listRect.setHeight(height); + + if (boundToScreen) + { + if (listRect.top() < screen.top()) + listRect.moveTop(screen.top()); + if (listRect.bottom() > screen.bottom()) + listRect.moveBottom(screen.bottom()); + } + } + else if (!boundToScreen || vcRect.height() <= belowHeight) + { + vcRect.moveTopLeft(below); + } + else if (vcRect.height() <= aboveHeight) + { + vcRect.moveBottomLeft(above); + } + else if (belowHeight >= aboveHeight) + { + vcRect.setHeight(belowHeight); + vcRect.moveTopLeft(below); + } + else + { + vcRect.setHeight(aboveHeight); + vcRect.moveBottomLeft(above); + } + +#ifndef QT_NO_IM + if (QInputContext *qic = inputContext()) + qic->reset(); +#endif + + container->setGeometry(vcRect); + +#ifndef Q_WS_MAC + const bool updatesEnabled = container->updatesEnabled(); +#endif + +#if defined(Q_WS_WIN) && !defined(QT_NO_EFFECTS) + bool scrollDown = (vcRect.topLeft() == below); + if (QApplication::isEffectEnabled(Qt::UI_AnimateCombo) + && !style->styleHint(QStyle::SH_ComboBox_Popup, &opt, this) && !window()->testAttribute(Qt::WA_DontShowOnScreen)) + qScrollEffect(container, scrollDown ? QEffects::DownScroll : QEffects::UpScroll, 150); +#endif + +#ifndef Q_WS_MAC + container->setUpdatesEnabled(false); +#endif + + container->raise(); + container->show(); + +#ifndef Q_WS_MAC + container->setUpdatesEnabled(updatesEnabled); +#endif + + container->update(); +} + +void GLDPopupWindow::hidePopup() +{ + Q_D(GLDPopupWindow); + if (d->container && d->container->isVisible()) + { +#if !defined(QT_NO_EFFECTS) + d->container->blockSignals(true); + bool needFade = style()->styleHint(QStyle::SH_Menu_FadeOutOnHide); + d->container->blockSignals(false); + + if (!needFade) +#endif + d->container->hide(); + } + d->_q_resetButton(); +} + +void GLDPopupWindow::clear() +{ +#ifndef QT_NO_ACCESSIBILITY + QAccessible::updateAccessibility(this, 0, QAccessible::NameChanged); +#endif +} + +void GLDPopupWindow::clearEditText() +{ + Q_D(GLDPopupWindow); + if (d->lineEdit) + d->lineEdit->clear(); +#ifndef QT_NO_ACCESSIBILITY + QAccessible::updateAccessibility(this, 0, QAccessible::NameChanged); +#endif +} + +void GLDPopupWindow::setEditText(const QString &text) +{ + Q_D(GLDPopupWindow); + if (d->lineEdit) + d->lineEdit->setText(text); +#ifndef QT_NO_ACCESSIBILITY + QAccessible::updateAccessibility(this, 0, QAccessible::NameChanged); +#endif +} + +void GLDPopupWindow::focusInEvent(QFocusEvent *e) +{ + Q_D(GLDPopupWindow); + update(); + if (d->lineEdit) + { + d->lineEdit->event(e); + } +} + +void GLDPopupWindow::focusOutEvent(QFocusEvent *e) +{ + Q_D(GLDPopupWindow); + update(); + if (d->lineEdit) + d->lineEdit->event(e); +} + +void GLDPopupWindow::changeEvent(QEvent *e) +{ + Q_D(GLDPopupWindow); + switch (e->type()) { + case QEvent::StyleChange: +#ifdef Q_WS_MAC + case QEvent::MacSizeChange: +#endif + d->sizeHint = QSize(); // invalidate size hint + d->minimumSizeHint = QSize(); + d->updateLayoutDirection(); + if (d->lineEdit) + d->updateLineEditGeometry(); + d->setLayoutItemMargins(QStyle::SE_ComboBoxLayoutItem); + break; + case QEvent::EnabledChange: + if (!isEnabled()) + hidePopup(); + break; + case QEvent::PaletteChange: { + d->updateViewContainerPaletteAndOpacity(); + break; + } + case QEvent::FontChange: + d->sizeHint = QSize(); // invalidate size hint + if (d->lineEdit) + d->updateLineEditGeometry(); + break; + default: + break; + } + QWidget::changeEvent(e); +} + +void GLDPopupWindow::resizeEvent(QResizeEvent *) +{ + Q_D(GLDPopupWindow); + d->updateLineEditGeometry(); +} + +void GLDPopupWindow::paintEvent(QPaintEvent *) +{ + QStylePainter painter(this); + painter.setPen(palette().color(QPalette::Text)); + + // draw the combobox frame, focusrect and selected etc. + QStyleOptionComboBox opt; + initStyleOption(&opt); + painter.drawComplexControl(QStyle::CC_ComboBox, opt); + + // draw the icon and text + painter.drawControl(QStyle::CE_ComboBoxLabel, opt); +} + +void GLDPopupWindow::showEvent(QShowEvent *e) +{ + Q_D(GLDPopupWindow); + if (!d->shownOnce && d->sizeAdjustPolicy == GLDPopupWindow::AdjustToContentsOnFirstShow) { + d->sizeHint = QSize(); + updateGeometry(); + } + d->shownOnce = true; + QWidget::showEvent(e); +} + +void GLDPopupWindow::hideEvent(QHideEvent *) +{ + hidePopup(); +} + +bool GLDPopupWindow::event(QEvent *event) +{ + Q_D(GLDPopupWindow); + switch(event->type()) + { + case QEvent::LayoutDirectionChange: + case QEvent::ApplicationLayoutDirectionChange: + d->updateLayoutDirection(); + d->updateLineEditGeometry(); + break; + case QEvent::HoverEnter: + case QEvent::HoverLeave: + case QEvent::HoverMove: + if (const QHoverEvent *he = static_cast(event)) + d->updateHoverControl(he->pos()); + break; + case QEvent::ShortcutOverride: + if (d->lineEdit) + return d->lineEdit->event(event); + break; + default: + break; + } + return QWidget::event(event); +} + +void GLDPopupWindow::mousePressEvent(QMouseEvent *e) +{ + Q_D(GLDPopupWindow); + QStyleOptionComboBox opt; + initStyleOption(&opt); + QStyle::SubControl sc = style()->hitTestComplexControl(QStyle::CC_ComboBox, &opt, e->pos(), + this); + if (e->button() == Qt::LeftButton && (sc == QStyle::SC_ComboBoxArrow || !isEditable()) + && !d->viewContainer()->isVisible()) { + if (sc == QStyle::SC_ComboBoxArrow) + { + d->updateArrow(QStyle::State_Sunken); + } + d->viewContainer()->blockMouseReleaseTimer.start(QApplication::doubleClickInterval()); + d->viewContainer()->initialClickPosition = mapToGlobal(e->pos()); + + showPopup(); + } + else + { + QWidget::mousePressEvent(e); + } +} + +void GLDPopupWindow::mouseReleaseEvent(QMouseEvent *e) +{ + Q_D(GLDPopupWindow); + Q_UNUSED(e); + d->updateArrow(QStyle::State_None); +} + +void GLDPopupWindow::keyPressEvent(QKeyEvent *e) +{ + Q_D(GLDPopupWindow); + + switch (e->key()) { + case Qt::Key_Up: + if (e->modifiers() & Qt::ControlModifier) + break; // pass to line edit for auto completion + case Qt::Key_Down: + if (e->modifiers() & Qt::AltModifier) { + showPopup(); + return; + } else if (e->modifiers() & Qt::ControlModifier) + break; // pass to line edit for auto completion + // fall through + case Qt::Key_F4: + if (!e->modifiers()) { + showPopup(); + return; + } + break; + case Qt::Key_Space: + if (!d->lineEdit) { + showPopup(); + return; + } + case Qt::Key_Enter: + case Qt::Key_Return: + case Qt::Key_Escape: + if (!d->lineEdit) + e->ignore(); + break; + default: + if (!d->lineEdit) + { + e->ignore(); + } + } + if (d->lineEdit) + { + d->lineEdit->event(e); + } +} + +void GLDPopupWindow::keyReleaseEvent(QKeyEvent *e) +{ + Q_D(GLDPopupWindow); + if (d->lineEdit) + d->lineEdit->event(e); +} + +#ifndef QT_NO_WHEELEVENT +void GLDPopupWindow::wheelEvent(QWheelEvent *e) +{ + Q_D(GLDPopupWindow); + if (!d->viewContainer()->isVisible()) + { + e->accept(); + } +} +#endif + +void GLDPopupWindow::contextMenuEvent(QContextMenuEvent *e) +{ + Q_D(GLDPopupWindow); + if (d->lineEdit) { + Qt::ContextMenuPolicy p = d->lineEdit->contextMenuPolicy(); + d->lineEdit->setContextMenuPolicy(Qt::DefaultContextMenu); + d->lineEdit->event(e); + d->lineEdit->setContextMenuPolicy(p); + } +} + +void GLDPopupWindow::inputMethodEvent(QInputMethodEvent *e) +{ + Q_D(GLDPopupWindow); + if (d->lineEdit) + { + d->lineEdit->event(e); + } + else + { + if (e->commitString().isEmpty()) + e->ignore(); + } +} + +QVariant GLDPopupWindow::inputMethodQuery(Qt::InputMethodQuery query) const +{ + Q_D(const GLDPopupWindow); + if (d->lineEdit) + return d->lineEdit->inputMethodQuery(query); + return QWidget::inputMethodQuery(query); +} + +bool GLDPopupWindow::hasFrame() const +{ + Q_D(const GLDPopupWindow); + return d->frame; +} + +void GLDPopupWindow::setPopupWidget(QWidget *newWidget) +{ + Q_D(GLDPopupWindow); + d->viewContainer()->setWidget(newWidget); +} + +QWidget *GLDPopupWindow::PopupWidget() +{ + Q_D(GLDPopupWindow); + return d->viewContainer()->widget(); +} + +void GLDPopupWindow::setFrame(bool enable) +{ + Q_D(GLDPopupWindow); + d->frame = enable; + update(); + updateGeometry(); +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDProgressBar.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDProgressBar.cpp new file mode 100644 index 00000000..3c8620ec --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDProgressBar.cpp @@ -0,0 +1,179 @@ +#include +#include +#include +#include "GLDProgressBar.h" +#include "GLDProgressBarEvent.h" + +GLDProgressBar::GLDProgressBar(QWidget *parent) +{ + m_progressDlg = new QProgressDialog(parent); + m_progressDlg->setCancelButton(NULL); + m_progressDlg->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint); + m_progressDlg->setAutoFillBackground(true); + m_progressDlg->setMaximum(0); + m_progressDlg->setModal(true); + m_progressDlg->setAutoClose(true); + m_progressDlg->setAutoReset(false); + + m_barThreadId = this->thread()->currentThreadId(); +} + +GLDProgressBar::~GLDProgressBar() +{ + if (!isCreateThread()) + { + QApplication::postEvent(this, new GDisposeEvent()); + QApplication::sendPostedEvents(this, Dispose); + QMutex mutex; + QMutexLocker locker(&mutex); + QThread::msleep(100); + } + else + { + delete m_progressDlg; + } +} + +void GLDProgressBar::setRange(int LRange, int RRange) +{ + m_progressDlg->setRange(LRange, RRange); +} + +void GLDProgressBar::updateProgress(int pos) +{ + if (!isCreateThread()) + { + GUpdateEvent *evt = new GUpdateEvent(); + evt->setValue(pos); + QApplication::postEvent(this, evt, Qt::HighEventPriority); + QApplication::flush(); + m_cachePos = pos; + QMutex mutex; + QMutexLocker locker(&mutex); + m_waitobj.wait(&mutex, 10); + } + else + { + m_progressDlg->setValue(pos); + } +} + +int GLDProgressBar::getProgressPos() +{ + return m_progressDlg->value(); +} + +void GLDProgressBar::setValue(const int pos) +{ + qApp->processEvents(); + m_progressDlg->setValue(pos); + m_waitobj.wakeAll(); +} + +bool GLDProgressBar::event(QEvent *event) +{ + if (event->type() == SetValue) + { + m_progressDlg->setValue(m_cachePos); + QApplication::flush(); + m_waitobj.wakeAll(); + } + else if (event->type() == SetVisible) + { + GVisibleEvent *pEvt = dynamic_cast(event); + m_progressDlg->setVisible(pEvt->visible()); + m_waitobj.wakeAll(); + } + else if (event->type() == Resize) + { + GResizeEvent *pEvt = dynamic_cast(event); + m_progressDlg->resize(pEvt->width(), pEvt->height()); + } + else if (event->type() == SetPosition) + { + GSetPosEvent *pEvt = dynamic_cast(event); + m_progressDlg->move(pEvt->x(), pEvt->y()); + } + else if (event->type() == Dispose) + { + delete m_progressDlg; + } + + return true; +} + +void GLDProgressBar::hide() +{ + if (!isCreateThread()) + { + GVisibleEvent *evt = new GVisibleEvent(); + evt->setIsVisible(false); + QApplication::postEvent(this, evt, Qt::HighEventPriority); + } + else + { + m_progressDlg->hide(); + } +} + +void GLDProgressBar::show() +{ + if (!isCreateThread()) + { + GVisibleEvent *evt = new GVisibleEvent(); + evt->setIsVisible(true); + QApplication::postEvent(this, evt, Qt::HighEventPriority); + QApplication::sendPostedEvents(this, SetVisible); + QMutex mutex; + QMutexLocker locker(&mutex); + m_waitobj.wait(&mutex, 10);; + } + else + { + m_progressDlg->show(); + } +} + +bool GLDProgressBar::isCreateThread() +{ + return m_barThreadId == this->thread()->currentThreadId(); +} + +void GLDProgressBar::setSize(int width, int height) +{ + if (!isCreateThread()) + { + GResizeEvent *evt = new GResizeEvent(); + evt->setWidth(width); + evt->setHeight(height); + QApplication::postEvent(this, evt, Qt::HighEventPriority); + } + else + { + m_progressDlg->resize(width, height); + } +} + +void GLDProgressBar::setPos(int x, int y) +{ + if (!isCreateThread()) + { + GSetPosEvent *evt = new GSetPosEvent(); + evt->setX(x); + evt->setY(y); + QApplication::postEvent(this, evt, Qt::HighEventPriority); + } + else + { + m_progressDlg->move(x, y); + } +} + +void GLDProgressBar::setText(const QString &str) +{ + qApp->processEvents(); + m_progressDlg->setLabelText(str); +} + + + diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDProgressBarEvent.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDProgressBarEvent.cpp new file mode 100644 index 00000000..68b6e39d --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDProgressBarEvent.cpp @@ -0,0 +1,61 @@ +#include "GLDProgressBarEvent.h" + +bool GVisibleEvent::visible() +{ + return m_visible; +} + +void GVisibleEvent::setIsVisible( bool visible ) +{ + m_visible = visible; +} + +int GResizeEvent::width() +{ + return m_width; +} + +int GResizeEvent::height() +{ + return m_height; +} + +void GResizeEvent::setWidth( int width ) +{ + m_width = width; +} + +void GResizeEvent::setHeight( int height ) +{ + m_height = height; +} + +int GSetPosEvent::x() +{ + return m_x; +} + +int GSetPosEvent::y() +{ + return m_y; +} + +void GSetPosEvent::setX( int x ) +{ + m_x = x; +} + +void GSetPosEvent::setY( int y ) +{ + m_y = y; +} + +int GUpdateEvent::value() +{ + return m_value; +} + +void GUpdateEvent::setValue( int value ) +{ + m_value = value; +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDScrollStyle.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDScrollStyle.cpp new file mode 100644 index 00000000..2a62eee9 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDScrollStyle.cpp @@ -0,0 +1,377 @@ +#include "GLDFileUtils.h" +#include "GLDWidget_Global.h" +#include "GLDScrollStyle.h" + +#include +#include +#include +#include +#include + +GLDScrollStyle::GLDScrollStyle(QObject *parent, bool isSubControl): + m_isShowArrow(false), + m_bFirstLoad(true), + m_nSliderMinLength(60), + m_nSliderSize(8), + m_nArrowWidth(8), + m_nArrowHeight(4), + m_nSliderX(3), + m_nSliderY(3), + m_nArrowX(3), + m_nArrowY(6), + m_nSubSliderMinLength(45), + m_nSliderAddOffset(8), + m_nSliderSubOffset(4), + m_scrollBarHandleColor("#648dd8"), + m_scrollBarHandleHoverColor("#7da6e4"), + m_scrollBarTrackColor("#ffffff"), + m_scrollBarTrackHoverColor("#f4f4f4") +{ + setParent(parent); // 防止内存泄漏 + setIsShowArrow(); + loadStyleIniFile(); + + if (isSubControl) + { + m_nSliderMinLength = m_nSubSliderMinLength; + } + else + { + m_nSliderMinLength = 60; + } +} + +GLDScrollStyle::~GLDScrollStyle() +{ +} + +void GLDScrollStyle::loadStyleIniFile(const QString &path) +{ + if (m_bFirstLoad) + { + if (!fileExists(path)) + { + return; + } + QSettings settings(path, QSettings::IniFormat); + + m_nSliderSize = settings.value("sliderSize").toInt(); + m_nSliderMinLength = settings.value("sliderMinLength").toInt(); + m_nSubSliderMinLength = settings.value("subSliderMinLength").toInt(); + m_nArrowWidth = settings.value("arrowWidth").toInt(); + m_nArrowHeight = settings.value("arrowHeight").toInt(); + m_nSliderX = settings.value("sliderX").toInt(); + m_nSliderY = settings.value("sliderY").toInt(); + m_nArrowX = settings.value("arrowX").toInt(); + m_nArrowY = settings.value("arrowY").toInt(); + m_nSliderAddOffset = settings.value("sliderAddOffset").toInt(); + m_nSliderSubOffset = settings.value("sliderSubOffset").toInt(); + + m_scrollBarHandleColor = QColor(settings.value("scrollBarHandleColor").toString()); + m_scrollBarHandleHoverColor = QColor(settings.value("scrollBarHandleHoverColor").toString()); + m_scrollBarTrackColor = QColor(settings.value("scrollBarTrackColor").toString()); + m_scrollBarTrackHoverColor = QColor(settings.value("scrollBarTrackHoverColor").toString()); + m_bFirstLoad = false; + } +} + +void GLDScrollStyle::drawComplexControl(QStyle::ComplexControl control, + const QStyleOptionComplex *option, + QPainter *painter, const QWidget *widget) const +{ + if (control == CC_ScrollBar) + { + drawScrollbar(control, option, painter, widget); + return; + } + else + { + QProxyStyle::drawComplexControl(control, option, painter, widget); + } +} + +int GLDScrollStyle::pixelMetric(QStyle::PixelMetric metric, const QStyleOption *option, + const QWidget *widget) const +{ + if (metric == QStyle::PM_ScrollBarSliderMin) + { + return m_nSliderMinLength; + } + else + { + return QProxyStyle::pixelMetric(metric, option, widget); + } +} + +QRect GLDScrollStyle::subControlRect(QStyle::ComplexControl cc, + const QStyleOptionComplex *opt, + QStyle::SubControl sc, const QWidget *widget) const +{ + bool bIsHorz = opt->state & State_Horizontal; + + if (cc == CC_ScrollBar + && (sc == QStyle::SC_ScrollBarGroove + || sc == QStyle::SC_ScrollBarSlider)) + { + QRect rectRes = QProxyStyle::subControlRect(cc, opt, sc, widget); + + if (bIsHorz) + { + rectRes.setLeft(rectRes.left() - m_nSliderAddOffset); + rectRes.setRight(rectRes.right() + m_nSliderSubOffset); + } + else + { + rectRes.setBottom(rectRes.bottom() + m_nSliderSubOffset); + rectRes.setTop(rectRes.top() - m_nSliderAddOffset); + } + + return rectRes; + } + + return QProxyStyle::subControlRect(cc, opt, sc, widget); +} + +void GLDScrollStyle::drawArrows( + QPainter * painter, + QRect drawRectAdd, + QRect drawRectSub, + Qt::Orientation Direct, + bool bMouseOver + ) const +{ + QPixmap pixmapAdd; + QPixmap pixmapSub; + QPixmap pixmap; + + // 如果支持鼠标滑过才显示箭头的效果,并且鼠标没有滑过,显示无图片 + // 否则全部贴图 + if (!m_isShowArrow && !bMouseOver) + { + pixmap.load(""); + } + else + { + drawRectSub.adjust(m_nArrowX, m_nArrowX, m_nArrowX, m_nArrowX); + if (Direct == Qt::Horizontal) + { + drawRectAdd.adjust(m_nArrowY, m_nArrowX, m_nArrowY, m_nArrowX); + + pixmapAdd.load(":/icons/scrollrightarrow.png"); + pixmapSub.load(":/icons/scrollleftarrow.png"); + } + else + { + drawRectAdd.adjust(m_nArrowX, m_nArrowY, m_nArrowX, m_nArrowY); + + pixmapAdd.load(":/icons/scrolldownarrow.png"); + pixmapSub.load(":/icons/scrolluparrow.png"); + } + } + + painter->drawPixmap(drawRectAdd, pixmapAdd); + painter->drawPixmap(drawRectSub, pixmapSub); +} + +void GLDScrollStyle::drawSlider(QStyle::SubControls sc, + QPainter *painter, + const QStyleOptionComplex *option, + const QWidget *widget, + bool bHorizontal) const +{ + QRect drawRect = subControlRect(CC_ScrollBar, option, SC_ScrollBarSlider, widget); + if (bHorizontal) + { + drawRect.adjust(0, m_nSliderY, 0, m_nSliderY); + drawRect.setHeight(m_nSliderSize); + } + else + { + drawRect.adjust(m_nSliderX, 0, m_nSliderX, 0); + drawRect.setWidth(m_nSliderSize); + } + + QPainterPath painterPath; + painterPath.addRect(drawRect); + if (sc & SC_ScrollBarSlider) + { + painter->fillPath(painterPath, m_scrollBarHandleHoverColor); // 鼠标在滚动柄上时的颜色 + } + else + { + painter->fillPath(painterPath, m_scrollBarHandleColor); // 鼠标不在滚动柄上时的颜色 + } +} + + // 画渐变背景(包括:AddLine、SubLine、ScrollBarGroove) +void GLDScrollStyle::drawBackground(QRect drawRect, QPainter *painter, + bool bMouseOver, bool bHorizontal) const +{ + QColor startColor; + QColor middleColor; + QColor endColor; + getScrollBarColors(startColor, middleColor, endColor, bMouseOver); + + QLinearGradient linearGradient; + if (bHorizontal) + { + linearGradient = QLinearGradient(drawRect.left(), + drawRect.top(), + drawRect.left(), + drawRect.bottom()); + } + else + { + linearGradient = QLinearGradient(drawRect.left(), + drawRect.top(), + drawRect.right(), + drawRect.top()); + } + + linearGradient.setColorAt(0.0, startColor); + linearGradient.setColorAt(0.3, middleColor); + linearGradient.setColorAt(0.8, middleColor); + linearGradient.setColorAt(1.0, endColor); + painter->setBrush(QBrush(linearGradient)); + painter->setPen(QPen(Qt::transparent)); + painter->drawRect(drawRect); +} + +void GLDScrollStyle::getScrollBarColors(QColor &startColor, QColor &middleColor, + QColor &endColor, + bool bMouseOver) const +{ + if (!bMouseOver) + { + if (m_isShowArrow) + { + // 水平滚动条轨道的默认渐变 + startColor = m_scrollBarTrackColor; + middleColor = m_scrollBarTrackColor; + endColor = m_scrollBarTrackColor; + } + else + { + startColor = m_scrollBarTrackColor; + middleColor = m_scrollBarTrackColor; + endColor = m_scrollBarTrackColor; + } + } + else + { + // 鼠标滑过水平滚动条时的背景渐变 + startColor = m_scrollBarTrackHoverColor; + middleColor = m_scrollBarTrackHoverColor; + endColor = m_scrollBarTrackHoverColor; + } +} + +void GLDScrollStyle::drawScrollBarAddLine(const QStyleOptionComplex *option, + QPainter *painter, const QWidget *widget, + bool bMouseOver, bool bHorizontal) const +{ + // 画水平、垂直AddLine的渐变背景 + QRect drawRectAdd = subControlRect(CC_ScrollBar, option, SC_ScrollBarAddLine, widget); + drawBackground(drawRectAdd, painter, bMouseOver, bHorizontal); +} + +void GLDScrollStyle::drawScrollBarSubLine(const QStyleOptionComplex *option, + QPainter *painter, const QWidget *widget, + bool bMouseOver, bool bHorizontal) const +{ + // 画水平、垂直SubLine的渐变背景 + QRect drawRectSub = subControlRect(CC_ScrollBar, option, SC_ScrollBarSubLine, widget); + drawBackground(drawRectSub, painter, bMouseOver, bHorizontal); +} + +void GLDScrollStyle::drawScrollBarGroove(const QStyleOptionComplex *option, + QPainter *painter, const QWidget *widget, + bool bMouseOver, bool bHorizontal) const +{ + // 画水平、垂直ScrollBarGroove的渐变背景 + QRect drawRectGroove = subControlRect(CC_ScrollBar, option, SC_ScrollBarGroove, widget); + drawBackground(drawRectGroove, painter, bMouseOver, bHorizontal); +} + +void GLDScrollStyle::initScrollBar( + const QStyleOptionComplex * option, + const QWidget * widget, + QPainter * painter, + bool bMouseOver, + bool bHorizontal, + bool bIsMaxOut + ) const +{ + if (bIsMaxOut) + { + bMouseOver = true; + } + drawScrollBarAddLine(option, painter, widget, bMouseOver, bHorizontal); + drawScrollBarSubLine(option, painter, widget, bMouseOver, bHorizontal); + drawScrollBarGroove(option, painter, widget, bMouseOver, bHorizontal); +} + +void GLDScrollStyle::drawScrollbar( + QStyle::ComplexControl control, + const QStyleOptionComplex * option, + QPainter * painter, + const QWidget * widget + ) const +{ + const QStyleOptionSlider *pScrollbar = qstyleoption_cast(option); + if (!pScrollbar) + { + return; + } + + bool bIsMaxOut = (pScrollbar->maximum == pScrollbar->minimum); + State flags = option->state; + if (widget && widget->testAttribute(Qt::WA_UnderMouse) && widget->isActiveWindow()) + { + flags |= State_MouseOver; + } + if (bIsMaxOut) + { + flags &= ~State_Enabled; + } + + painter->save(); + painter->setRenderHint(QPainter::Antialiasing); + bool bMouseOver = flags & State_MouseOver; + bool bHorizontal = flags & State_Horizontal; + initScrollBar(option, widget, painter, bMouseOver, bHorizontal, bIsMaxOut); // 初始化滚动条颜色 + + // 画滚动柄 + SubControls sub = option->subControls; + QStyle::SubControls sc = pScrollbar->activeSubControls; + if ((sub & SC_ScrollBarSlider) && !bIsMaxOut) + { + drawSlider(sc, painter, option, widget, bHorizontal); + } + + // 鼠标滑过滚动条时显示上下箭头 + if ((sub & SC_ScrollBarGroove) && !bIsMaxOut) + { + QRect drawRectAdd = subControlRect(CC_ScrollBar, option, SC_ScrollBarAddLine, widget); + QRect drawRectSub = subControlRect(CC_ScrollBar, option, SC_ScrollBarSubLine, widget); + if (bHorizontal) + { + drawRectAdd.setWidth(m_nArrowHeight); + drawRectAdd.setHeight(m_nArrowWidth); + drawRectSub.setWidth(m_nArrowHeight); + drawRectSub.setHeight(m_nArrowWidth); + drawArrows(painter, drawRectAdd, drawRectSub, Qt::Horizontal, bMouseOver); + } + else + { + drawRectAdd.setWidth(m_nArrowWidth); + drawRectAdd.setHeight(m_nArrowHeight); + drawRectSub.setWidth(m_nArrowWidth); + drawRectSub.setHeight(m_nArrowHeight); + drawArrows(painter, drawRectAdd, drawRectSub, Qt::Vertical, bMouseOver); + } + } + + painter->restore(); + G_UNUSED(control); +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDSearchEdit.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDSearchEdit.cpp new file mode 100644 index 00000000..dbfd0ec1 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDSearchEdit.cpp @@ -0,0 +1,182 @@ +#include "GLDSearchEdit.h" +#include +#include +#include +#include +#include +#include "GLDFileUtils.h" + +const QSize c_nSearchIconSize(34, 25); + +GLDSearchEdit::GLDSearchEdit(QWidget *parent) + : QLineEdit(parent), m_pSearchAndClearButton(NULL) +{ +// setAttribute(Qt::WA_WindowPropagation); + initButton(); + initTipsView(); + setObjectName("GLDSearchEdit"); + m_sQss = loadQssFile(":/qsses/GLDSearchEdit.qss"); + setStyleSheet(m_sQss); + setFixedHeight(25); +} + +GLDSearchEdit::~GLDSearchEdit() +{ +} + +void GLDSearchEdit::setRecentSearchs(QStringList &recentSearchs) +{ + m_oRecentSearchs = recentSearchs; +} + +QStringList &GLDSearchEdit::recentSearchs() +{ + return m_oRecentSearchs; +} + +bool GLDSearchEdit::hasFocus() +{ + return m_pSearchAndClearButton->hasFocus(); +} + +bool GLDSearchEdit::event(QEvent *e) +{ + if ((e->type() == QEvent::HoverEnter || e->type() == QEvent::FocusIn) + && m_pSearchAndClearButton != NULL) + { + m_pSearchAndClearButton->setHasFocus(true); + setStyleSheet(m_sQss); + } + else if ((e->type() == QEvent::HoverLeave || e->type() == QEvent::FocusOut) + && m_pSearchAndClearButton != NULL) + { + m_pSearchAndClearButton->setHasFocus(false); + setStyleSheet(m_sQss); + } + return QLineEdit::event(e); +} + +void GLDSearchEdit::resizeEvent(QResizeEvent *e) +{ + QLineEdit::resizeEvent(e); + m_pSearchAndClearButton->move(rect().right() - c_nSearchIconSize.width(), + (rect().height() - c_nSearchIconSize.height()) / 2); + moveRecentTipsView(); +} + +void GLDSearchEdit::mousePressEvent(QMouseEvent *e) +{ + QLineEdit::mousePressEvent(e); + if (text().isEmpty()) + { + moveRecentTipsView(); + m_pRecentCompleter->popup()->show(); + } +} + +void GLDSearchEdit::initButton() +{ + m_pSearchAndClearButton = new GLDSearchButton(this); + m_pSearchAndClearButton->setObjectName("m_pSearchAndClearButton"); + + QMargins oOldMargins = contentsMargins(); + oOldMargins.setRight(c_nSearchIconSize.width()); + setContentsMargins(oOldMargins); + + connect(this, &QLineEdit::textChanged, this, &GLDSearchEdit::onTextChange); + connect(m_pSearchAndClearButton, &QPushButton::clicked, this, &GLDSearchEdit::onButtonClick); + connect(this, &QLineEdit::editingFinished, this, &GLDSearchEdit::onEditingFinished); +} + +void GLDSearchEdit::initTipsView() +{ + m_pRecentCompleter = new QCompleter(m_oRecentSearchs, this); + m_pRecentCompleter->setMaxVisibleItems(3); + m_pRecentCompleter->popup()->resize(rect().width(), 56); + setCompleter(m_pRecentCompleter); +} + +void GLDSearchEdit::moveRecentTipsView() +{ + QPoint oEditBottomLeft = mapToGlobal(rect().bottomLeft()); + m_pRecentCompleter->popup()->resize(rect().width(), 56); + m_pRecentCompleter->popup()->move(oEditBottomLeft); +} + +void GLDSearchEdit::onTextChange(const QString &) +{ + if (!text().isEmpty() && !m_pSearchAndClearButton->searching()) + { + m_pSearchAndClearButton->setProperty("searching", true); + setStyleSheet(m_sQss); + } + else if (text().isEmpty() && m_pSearchAndClearButton->searching()) + { + m_pSearchAndClearButton->setProperty("searching", false); + setStyleSheet(m_sQss); + } +} + +void GLDSearchEdit::onButtonClick() +{ + if (m_pSearchAndClearButton->searching()) + { + clear(); + } +} + +void GLDSearchEdit::onEditingFinished() +{ + if (!text().isEmpty() && !m_oRecentSearchs.contains(text())) + { + m_pRecentCompleter->model()->insertRow(0); + QModelIndex oRecentIndex = m_pRecentCompleter->model()->index(0, 0); + m_pRecentCompleter->model()->setData(oRecentIndex, text()); + m_oRecentSearchs.append(text()); + } +} + +void GLDSearchEdit::onRecentTipsSelected(const QModelIndex &index) +{ + setText(index.data().toString()); +} + +GLDSearchButton::GLDSearchButton(QWidget *parent) + : QPushButton(parent), m_bSearching(false) +{ +} + +GLDSearchButton::~GLDSearchButton() +{ + +} + +void GLDSearchButton::setSearching(bool searching) +{ + m_bSearching = searching; +} + +bool GLDSearchButton::searching() +{ + return m_bSearching; +} + +bool GLDSearchButton::hasFocus() +{ + return m_bHasFocus; +} + +void GLDSearchButton::setHasFocus(bool value) +{ + m_bHasFocus = value; +} + +bool GLDSearchButton::event(QEvent *e) +{ + if (e->type() == QEvent::HoverEnter) + { + setCursor(QCursor(Qt::ArrowCursor)); + } + + return QPushButton::event(e); +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDShadow.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDShadow.cpp new file mode 100644 index 00000000..e0b7a5c0 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDShadow.cpp @@ -0,0 +1,210 @@ +#include +#include +#include +#include +#include + +#ifdef Q_OS_WIN +#include +#endif + +#include "GLDShadow.h" + +const int c_nShadowWidth = 2; +const int c_nShadowRGB = 240; +const int c_nShadowRGBGrowth = 2; +//const int c_nShadowMaxAlpha = 255; +//const int c_nShadowAlphaGrowth = 10; +const int c_nShadowAlpha[8] = {255, 100, 90, 60, 30, 30, 15, 15}; + +const char c_strHasShadow[] = "hasShadow"; + +GLDShadow::GLDShadowWidget::GLDShadowWidget(QWidget *parent) : + QWidget(parent, Qt::Popup) +{ +} + +bool GLDShadow::GLDShadowWidget::event(QEvent *e) +{ +#ifdef Q_OS_WIN + if (e->type() == QEvent::WinIdChange) + { + HWND hwnd = reinterpret_cast(winId()); + DWORD DWStyle = ::GetClassLong(hwnd, GCL_STYLE); + DWStyle &= ~CS_DROPSHADOW; + ::SetClassLong(hwnd, GCL_STYLE, DWStyle); + } +#endif + return QWidget::event(e); +} + +GLDShadow::GLDShadow(QWidget *parent): + QObject(parent), + m_bHandleResize(true), + m_parent(parent) +{ +} + +void GLDShadow::doRemoveShadow() +{ + static bool s_bFirstRun = true; + + if (s_bFirstRun) + { + GLDShadowWidget Widget; + Widget.show(); + s_bFirstRun = false; + } +} + +void GLDShadow::removeShadow() +{ + if (m_parent) + { + if (addShadow(m_parent)) + { + doRemoveShadow(); + } + } +} + +bool GLDShadow::addShadow(QWidget *popup) +{ + if (NULL == popup) + { + return false; + } + else if (addShadow(dynamic_cast(popup))) + { + return true; + } + else + { + popup->installEventFilter(this); + return true; + } +} + +bool GLDShadow::addShadow(QComboBox *popup) +{ + if (popup == NULL) + { + return false; + } + + QWidget *pContainer = popup->view()->parentWidget(); + + pContainer->setWindowFlags(pContainer->windowFlags() | Qt::FramelessWindowHint); + pContainer->installEventFilter(this); + pContainer->setProperty(c_strHasShadow, true); + + return true; +} + +bool GLDShadow::eventFilter(QObject *object, QEvent *event) +{ + + if (object->property(c_strHasShadow).isValid() && object->property(c_strHasShadow).toBool()) + { + QWidget *pContainer = static_cast(object); + + switch (event->type()) + { + case QEvent::Paint: + paintShadow(pContainer); + break; + + case QEvent::Show: + extendWidth(pContainer); + break; + + case QEvent::Hide: + doViewHide(pContainer); + break; + + default: + break; + } + } + + return QObject::eventFilter(object, event); +} + +void GLDShadow::extendWidth(QWidget *container) +{ + if (!m_bHandleResize) + { + return; + } + + m_bHandleResize = false; + + QWidget *pParent = container->parentWidget(); + container->resize(container->width() + c_nShadowWidth * 2, container->height() + c_nShadowWidth); + container->layout()->setContentsMargins(c_nShadowWidth, 0, c_nShadowWidth, c_nShadowWidth); + + QPoint pointNow = container->pos(); + int nOffsetX = pParent->mapFromGlobal(pointNow).x() - pointNow.x(); + + container->move(-nOffsetX - 2, pointNow.y()); + m_bHandleResize = true; +} + +void GLDShadow::doViewHide(QWidget *container) +{ + container->resize(container->width() - c_nShadowWidth * 2, container->height() - c_nShadowWidth); + + if (NULL != container->layout()) + { + container->layout()->setContentsMargins(0, 0, 0, 0); + } +} + +void GLDShadow::paintShadow(QWidget *container) +{ + QPainter painter(container); + + for (int i = 0; i < c_nShadowWidth; i++) + { + int nRGB = c_nShadowRGB + i * c_nShadowRGBGrowth; + QPen pen; + // 需要先画2像素的阴影 + const QString c_sShadows[2] = {"#c0cce5", "#e1e5ed"}; + if (i < 2) + { + pen.setColor(QColor(c_sShadows[i])); + painter.setPen(pen); + } + else + { + pen.setColor(QColor(nRGB, nRGB, nRGB, c_nShadowAlpha[i])); + } + pen.setWidth(1); + painter.setPen(pen); + + QPoint pointStart; + QPoint pointEnd; + QRect rect = container->rect(); + + // 画左侧阴影 + pointStart.setX(c_nShadowWidth - i - 1); + pointStart.setY(rect.bottomLeft().y() - c_nShadowWidth + i + 1); + pointEnd.setX(pointStart.x()); + pointEnd.setY(0); + painter.drawLine(pointStart, pointEnd); + + // 画下边阴影 + pointStart.setX(c_nShadowWidth - i - 1); + pointStart.setY(rect.bottomLeft().y() - c_nShadowWidth + i + 1); + pointEnd.setX(rect.bottomRight().x() - c_nShadowWidth + i + 1); + pointEnd.setY(pointStart.y()); + painter.drawLine(pointStart, pointEnd); + + // 画右侧阴影 + pointStart.setX(rect.bottomRight().x() - c_nShadowWidth + i + 1); + pointStart.setY(rect.bottomRight().y() - c_nShadowWidth + i + 1); + pointEnd.setX(pointStart.x()); + pointEnd.setY(0); + painter.drawLine(pointStart, pointEnd); + } +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDShellComboBoxEx.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDShellComboBoxEx.cpp new file mode 100644 index 00000000..1939c7b9 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDShellComboBoxEx.cpp @@ -0,0 +1,900 @@ +#include +#include +#include + +#include "GLDShadow.h" +#include "GLDStrUtils.h" +#include "GLDFileUtils.h" +#include "GLDScrollStyle.h" +#include "GLDFileSystemModel.h" +#include "GLDShellComboBoxEx.h" +#include "GLDShellTreeViewEx.h" + +const QString c_strRootColor = "RootColor"; +const QString c_strOthersColor = "OthersColor"; +const int c_nColorLength = 7; +const QColor c_colorRootName = QColor("#626262"); +const QColor c_colorOthersName = QColor("#010101"); + +const int c_nTreeViewIndentation = 15; +const int c_nTreeViewItemHeight = 25; +const int c_nTreeViewButtomOffset = -14; +const int c_nTreeViewMaxHeight = 320; +const int c_nTreeViewMinHeight = 20; +//const int c_nMaxImageWidth = 7; +const int c_nArrowOffset = 4; + +const QVector c_vec_iconType = QVector() + << "QFileIconProviderComputer" + << "QFileIconProviderDesktop" + << "QFileIconProviderTrashcan" + << "QFileIconProviderNetwork" + << "QFileIconProviderDrive" + << "QFileIconProviderFolder" + << "QFileIconProviderFile"; + +const int c_nArrowToIcon = 8; +//const int c_nComboBoxArrowToRight = 10; + +const char c_strIconTreeRoot[] = "://icons/right.png"; +const char c_strIconTreeChild[] = "://icons/rigjt02.png"; +const char c_strIconTreeHover[] = "://icons/r-hover.png"; +const char c_strIconTreeOpen[] = "://icons/hs.png"; +const char c_strIconTreeOpenHover[] = "://icons/z-hover.png"; + +const int c_nShadowWidth = 8; +const int c_nShadowRGB = 240; +const int c_nShadowRGBGrowth = 2; +const int c_nShadowAlpha[8] = {255, 100, 90, 60, 30, 30, 15, 15}; + +const GString c_sShellComboBoxQssFile = ":/qsses/GLDShellComboBoxEx.qss"; + +GLDShellComboBoxEx::GLDShellComboBoxEx(const QString &rootPath, QWidget *parent): + GLDShellComboBox(rootPath, parent), + m_bIsShow(false), + m_bIsLineEdit(true), + m_bIsShowIcon(false), + m_bIsDrag(false), + m_bIsPopMove(false), + m_nCanSetCursor(0), + m_bHasShadow(true), + m_delegate(NULL) +{ + init(rootPath); + // Qss进行美化 + setStyle(new GLDScrollStyle(this)); + setHasBorder(true); + setEditProperty(false); + this->setStyleSheet(loadQssFile(c_sShellComboBoxQssFile)); + + // 移除阴影 + GLDShadow *pShadow = new GLDShadow(this); + pShadow->removeShadow(); + + initConnection(); + installEventFilters(); +} + +void GLDShellComboBoxEx::init(const QString &rootPath) +{ + initPopupFlags(); + initFileModel(rootPath); + initShadow(); + setPopupWidget(m_popupShellTree); +} + +void GLDShellComboBoxEx::initPopupFlags() +{ + Qt::WindowFlags flags; + flags = Qt::MSWindowsFixedSizeDialogHint | Qt::FramelessWindowHint | Qt::Popup; + comboBoxPopup()->setWindowFlags(flags); + comboBoxPopup()->repaint(); +} + +void GLDShellComboBoxEx::initFileModel(const QString &rootPath) +{ + freeAndNil(m_pFileModel); + + m_pFileModel = new GLDFileSystemModelEX(true, this); + QModelIndex pathIndex = m_pFileModel->index(""); + + if (rootPath.length() > 0) + { + QModelIndex pathIndexTmp = m_pFileModel->index(rootPath); + + if (pathIndexTmp.isValid() && m_pFileModel->isDir(pathIndexTmp)) + { + pathIndex = pathIndexTmp; + } + } + initTreeView(pathIndex); +} + +void GLDShellComboBoxEx::initTreeView(QModelIndex pathIndex) +{ + freeAndNil(m_popupShellTree); + + GLDShellTreeViewEx *pTreeView = new GLDShellTreeViewEx(true, this); + m_popupShellTree = pTreeView; + //set tree as combobox`s popup + m_popupShellTree->setSingleRoot(false); + m_popupShellTree->setModel(m_pFileModel); + Q_ASSERT(m_pFileModel == m_popupShellTree->model()); + m_popupShellTree->setRootIndex(pathIndex); + + //inherited init action + m_popupShellTree->setAnimated(false); + m_popupShellTree->setIndentation(c_nTreeViewIndentation); + m_popupShellTree->setSortingEnabled(true); + initDelegate(pTreeView); +} + +void GLDShellComboBoxEx::initDelegate(GLDShellTreeViewEx *pTreeView) +{ + m_delegate = new GLDShellComboBoxItemDelegate("", this); + m_popupShellTree->setItemDelegate(m_delegate); + m_delegate->setTreeView(pTreeView); + GLDFileSystemModelEX *pModel = + dynamic_cast(m_pFileModel); + + if (pModel) + { + m_delegate->setFileSystemModel(pModel); + pModel->setDelegate(m_delegate); + } +} + +void GLDShellComboBoxEx::initShadow() +{ + comboBoxPopup()->setAttribute(Qt::WA_TranslucentBackground); +} + +void GLDShellComboBoxEx::setHasBorder(bool bHasBorder) +{ + getLineEdit()->setProperty("borderStyle", bHasBorder); + this->setStyleSheet(loadQssFile(c_sShellComboBoxQssFile)); +} + +void GLDShellComboBoxEx::setEditProperty(bool bShow) +{ + QString sProperty = QString(""); + if (bShow) + { + sProperty = sProperty + QString("show"); + } + else + { + sProperty = sProperty + QString("hide"); + } + + getLineEdit()->setProperty( + "GLDPlainTextEditState", sProperty); +} + +void GLDShellComboBoxEx::setFileModel(GLDCustomFileSystemModel *model) +{ + freeAndNil(m_pFileModel); + m_pFileModel = model; + QModelIndex pathIndex = m_pFileModel->index(""); + initTreeView(pathIndex); +} + +void GLDShellComboBoxEx::setShellListView(GLDShellListView *list) +{ + GLDFileSystemModelEX *pFileModel = dynamic_cast(m_pFileModel); + if(pFileModel) + { + m_pFileModel = pFileModel; + } + GLDShellComboBox::setShellListView(list); +} + +void GLDShellComboBoxEx::initConnection() +{ + connect(this, &GLDShellComboBox::onHide, + this, &GLDShellComboBoxEx::onSignalOnHide); + connect(this, &GLDShellComboBox::shouldShowPopup, + this, &GLDShellComboBoxEx::onShouldShowPopup); + connect(getLineEdit(), &GLDPlainTextEdit::cursorPositionChanged, + this, &GLDShellComboBoxEx::doAfterEditCursorChanged); + connect(m_popupShellTree, &GLDShellTreeView::expanded, + this, &GLDShellComboBoxEx::doAfterExpanded); + connect(m_popupShellTree, &GLDShellTreeView::collapsed, + this, &GLDShellComboBoxEx::doAfterCollapsed); +} + +void GLDShellComboBoxEx::installEventFilters() +{ + m_popupShellTree->installEventFilter(this); + m_popupShellTree->viewport()->installEventFilter(this); + getLineEdit()->installEventFilter(this); + getLineEdit()->viewport()->installEventFilter(this); + comboBoxPopup()->installEventFilter(this); +} + +void GLDShellComboBoxEx::paintEvent(QPaintEvent *event) +{ + if (m_bIsShowIcon) + { + GLDShellComboBox::paintEvent(event); + } + + if (!framePopup()) + { + GLDWindowComboBox::paintEvent(event); + } +} + +void GLDShellComboBoxEx::resizeEvent(QResizeEvent *event) +{ + GLDShellComboBox::resizeEvent(event); + getLineEdit()->setMaximumSize(size()); + getLineEdit()->setGeometry(rect()); + comboBoxPopup()->setFixedWidth(width() + c_nShadowWidth * 2); +} + +bool GLDShellComboBoxEx::eventFilter(QObject *object, QEvent *event) +{ + // 如果是ShellTreeView弹出 + if (object == m_popupShellTree) + { + if (event->type() != QEvent::KeyPress) + { + QKeyEvent *keyEvent = static_cast(event); + if (keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return) + { + GLDShellTreeViewEx *pTreeView = static_cast (m_popupShellTree); + if (pTreeView->selectedIndexes().size()) + { + closePopup(); + setEditTextByIndex(pTreeView->selectedIndexes()[0]); + } + } + } + } + // 如果是ComboBox弹出 + if (object == comboBoxPopup()) + { + if (event->type() == QEvent::Paint) + { + if (!m_bIsPopMove) + { + QPoint point = comboBoxPopup()->pos(); + point.setX(point.x() - c_nShadowWidth); + comboBoxPopup()->move(point); + m_bIsPopMove = true; + } + + if (m_bHasShadow) + { + QPainter painter(comboBoxPopup()); + + for (int i = 0; i < c_nShadowWidth; i++) + { + int nRGB = c_nShadowRGB + i * c_nShadowRGBGrowth; + QPen pen; + // 需要先画2像素的阴影 + const QString c_sShadows[2] = {"#c0cce5", "#e1e5ed"}; + if (i < 2) + { + pen.setColor(QColor(c_sShadows[i])); + painter.setPen(pen); + } + else + { + pen.setColor(QColor(nRGB, nRGB, nRGB, c_nShadowAlpha[i])); + } + pen.setWidth(1); + painter.setPen(pen); + + QPoint pointStart; + QPoint pointEnd; + QRect rect = comboBoxPopup()->rect(); + + // 画左侧阴影 + pointStart.setX(c_nShadowWidth - i - 1); + pointStart.setY(rect.bottomLeft().y() - c_nShadowWidth + i + 1); + pointEnd.setX(pointStart.x()); + pointEnd.setY(0); + painter.drawLine(pointStart, pointEnd); + + // 画下边阴影 + pointStart.setX(c_nShadowWidth - i - 1); + pointStart.setY(rect.bottomLeft().y() - c_nShadowWidth + i + 1); + pointEnd.setX(rect.bottomRight().x() - c_nShadowWidth + i + 1); + pointEnd.setY(pointStart.y()); + painter.drawLine(pointStart, pointEnd); + + // 画右侧阴影 + pointStart.setX(rect.bottomRight().x() - c_nShadowWidth + i + 1); + pointStart.setY(rect.bottomRight().y() - c_nShadowWidth + i + 1); + pointEnd.setX(pointStart.x()); + pointEnd.setY(0); + painter.drawLine(pointStart, pointEnd); + } + } + } + } + return GLDShellComboBox::eventFilter(object, event); +} + +void GLDShellComboBoxEx::onSignalOnHide() +{ + if (comboBoxPopup()->isActiveWindow()) + { + return; + } + + m_bIsShow = false; + setEditProperty(m_bIsShow); + this->setStyleSheet(loadQssFile(c_sShellComboBoxQssFile)); + updateEditFieldGeometry(); + + //发送afterPopupHid信号 + emit GLDShellComboBoxEx::afterPopupHid(); + //发送onHide信号 + emit GLDShellComboBoxEx::onHide(); + m_nCanSetCursor = 2; +} + +void GLDShellComboBoxEx::autoSetContainerHeight() +{ + GLDShellTreeViewEx *pTreeView = dynamic_cast(m_popupShellTree); + + if (pTreeView) + { + int nRows = pTreeView->countAllShownRows(); + int nHeight = nRows * c_nTreeViewItemHeight + c_nTreeViewMinHeight; + if (nHeight > c_nTreeViewMaxHeight) + { + nHeight = c_nTreeViewMaxHeight; + m_popupShellTree->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + } + else + { + m_popupShellTree->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + } + + if (nHeight != comboBoxPopup()->popuHeight()) + { + comboBoxPopup()->setPopupHeight(nHeight); + } + } +} + +void GLDShellComboBoxEx::keyPressEvent(QKeyEvent *event) +{ + if (event->key() == Qt::Key_Down || event->key() == Qt::Key_Up) + { + QModelIndex index = m_popupShellTree->currentIndex(); + + if (index.isValid()) + { + int nRow = index.row(); + + if (event->key() == Qt::Key_Down) + { + if (index.sibling(nRow + 1, 0).isValid()) + { + ++nRow; + } + else + { + nRow = 0; + } + } + else + { + if (index.row() != 0) + { + --nRow; + } + else + { + while (index.sibling(++nRow, 0).isValid()); + --nRow; + } + } + + index = index.sibling(nRow, 0); + + GLDShellTreeViewEx *pTreeView = static_cast (m_popupShellTree); + pTreeView->setCurrentIndex(index); + m_nCanSetCursor = 2; + setEditTextByIndex(index); + } + } + + GLDShellComboBox::keyPressEvent(event); +} + +void GLDShellComboBoxEx::updateEditFieldGeometry() +{ + QStyleOptionComboBox optCombo; + optCombo.init(this); + optCombo.editable = true; + optCombo.subControls = QStyle::SC_ComboBoxFrame | QStyle::SC_ComboBoxEditField; + + if (m_buttonType != None) + { + optCombo.subControls |= QStyle::SC_ComboBoxArrow; + // Qss需要 + QRect editRect = rect().adjusted(0, 0, 0, 0); + // 由于在setGeometry的时候,会再次计算并设置MinimumSize和MaximumSize + // 会出现区域改变的问题,因此在这里先设置好MinimumSize和MaximumSize + lineEdit()->setMinimumSize(editRect.width(), editRect.height()); + lineEdit()->setMaximumSize(editRect.width(), editRect.height()); + lineEdit()->setGeometry(editRect); + } + else + { + QRect editRect = rect().adjusted(0, 0, 0, -1); + lineEdit()->setMinimumSize(editRect.width(), editRect.height()); + lineEdit()->setMaximumSize(editRect.width(), editRect.height()); + } +} + +void GLDShellComboBoxEx::onShouldShowPopup(bool &value) +{ + setEditProperty(value); + this->setStyleSheet(loadQssFile(c_sShellComboBoxQssFile)); + updateEditFieldGeometry(); + //发送信号 + emit GLDShellComboBoxEx::shouldShowPopup(value); + + if (value) + { + emit GLDShellComboBoxEx::afterPopupShowed(); + m_bIsShow = true; + m_bIsPopMove = false; + autoSetContainerHeight(); + } +} + +void GLDShellComboBoxEx::doAfterEditCursorChanged() +{ + if (m_nCanSetCursor) + { + getLineEdit()->blockSignals(true); + getLineEdit()->moveCursor(QTextCursor::End); + getLineEdit()->blockSignals(false); + --m_nCanSetCursor; + getLineEdit()->selectAll(); + } + + emit cursorPositionChanged(); +} + +void GLDShellComboBoxEx::doAfterExpanded(const QModelIndex &index) +{ + autoSetContainerHeight(); + emit expanded(index); +} + +void GLDShellComboBoxEx::doAfterCollapsed(const QModelIndex &index) +{ + autoSetContainerHeight(); + emit collapsed(index); +} + +GLDFileSystemModelEX::GLDFileSystemModelEX(bool includingFile, QObject *parent): + GLDFileSystemModel(includingFile, parent), + m_colorRoot(c_colorRootName), + m_colorOthers(c_colorOthersName), m_delegate(NULL) +{ + m_pIconProvider = new GLDFileIconProvider; + setIconProvider(m_pIconProvider); +} + +GLDFileSystemModelEX::~GLDFileSystemModelEX() +{ + freeAndNil(m_pIconProvider); +} + +QVariant GLDFileSystemModelEX::data(const QModelIndex &index, int role) const +{ + Q_D(const GLDFileSystemModel); + + if (!d->indexValid(index)) + { + return QVariant(); + } + + if (role == Qt::DisplayRole || role == Qt::EditRole) + { + switch (index.column()) + { + case 0: + { + QString strName = d->name(index); + + if (0 == strName.compare("desktop", Qt::CaseInsensitive)) + { + QLocale locale; + + switch (locale.country()) //判断操作系统语言 + { + case QLocale::China: + case QLocale::Chinese: + strName = TRANS_STRING("桌面"); + break; + + default: + strName = "DeskTop"; + break; + } + } + + return strName; + } + + case 1: + return d->size(index); + + case 2: + return d->type(index); + + case 3: + return d->updateDateTime(index); + + default: + qWarning("data: invalid display value column %d", index.column()); + return QVariant(); + } + } + + if (index.column() == 0) + { + switch (role) + { + case FileIconRole: + return fileIcon(index); + + case FilePathRole: + return filePath(index); + + case FileNameRole: + case Qt::ToolTipRole: + return fileName(index); + + case Qt::ForegroundRole: + return fileNameColor(index); + + default: + return QVariant(); + } + } + + if (role == Qt::TextAlignmentRole) + { + if (m_enViewMode == GLDListView::VSReportMode) + { + switch (index.column()) + { + case 0: + case 1: + case 2: + case 3: + return (QVariant)(Qt::AlignLeft | Qt::AlignVCenter); + case 4: + return (QVariant)(Qt::AlignRight | Qt::AlignVCenter); + } + return Qt::AlignCenter; + } + else if(m_enViewMode == GLDListView::VSIconMode) + { + return Qt::AlignCenter; + } + else + { + return Qt::AlignLeft; + } + } + return QVariant(); +} + +QIcon GLDFileSystemModelEX::fileIcon(const QModelIndex &index) const +{ + Q_D(const GLDFileSystemModel); + + if (!d->indexValid(index)) + { + return d->iconProvider->icon(QFileIconProvider::Computer); + } + + GLDFileSystemModelPrivate::QDirNode *node = d->node(index); + + if (node->icon.isNull()) + { + node->icon = d->iconProvider->icon(node->info); + } + + return node->icon; +} + +QColor GLDFileSystemModelEX::fileNameColor(const QModelIndex &index) const +{ + Q_D(const GLDFileSystemModel); + + if (!d->indexValid(index)) + { + return QColor(); + } + + if (NULL == m_delegate) + { + return m_colorRoot; + } + + else if (m_delegate->isParentExpandedRecently(index)) + { + return m_colorOthers; + } + + return m_colorRoot; +} + +void GLDFileSystemModelEX::setFontColor(const QString &setting) +{ + int nIndex = -1; + + nIndex = setting.indexOf(c_strRootColor); + + if (nIndex > -1) + { + QString strRootColor = setting.mid(nIndex + c_strRootColor.size(), + c_nColorLength); + m_colorRoot = QColor(strRootColor); + } + + nIndex = setting.indexOf(c_strOthersColor); + + if (nIndex > -1) + { + QString strOthersColor = setting.mid(nIndex + c_strOthersColor.size(), + c_nColorLength); + m_colorOthers = QColor(strOthersColor); + } +} + +GLDFileSystemModelEX::GLDFileSystemModelEX(const QStringList &nameFilters, + QDir::Filters filters, + QDir::SortFlags sort, + QObject *parent): + GLDFileSystemModel(nameFilters, filters, sort, parent) +{ +} + +GLDFileSystemModelEX::GLDFileSystemModelEX(GLDFileSystemModelPrivate &model, QObject *parent): + GLDFileSystemModel(model, parent) +{ +} + +GLDFileIconProvider::GLDFileIconProvider() +{ +} + +GLDFileIconProvider::~GLDFileIconProvider() +{ +} + +QIcon GLDFileIconProvider::icon(QFileIconProvider::IconType type) const +{ + if (m_map_icon.contains(type)) + { + return m_map_icon[type]; + } + else + { + return QFileIconProvider::icon(type); + } +} + +QIcon GLDFileIconProvider::icon(const QFileInfo &info) const +{ + if (info.isRoot()) + { + if (info.isNativePath() && info.isReadable())//磁盘 + { + if (m_map_icon.contains(QFileIconProvider::Drive)) + { + return icon(QFileIconProvider::Drive); + } + } + + return QFileIconProvider::icon(info); + } + + if (info.isDir())//文件夹 + { + if (info.fileName().compare("Desktop", Qt::CaseInsensitive) == 0)//桌面文件夹 + { + if (m_map_icon.contains(QFileIconProvider::Desktop)) + { + return icon(QFileIconProvider::Desktop); + } + } + else + { + if (m_map_icon.contains(QFileIconProvider::Folder)) + { + return icon(QFileIconProvider::Folder); + } + } + } + + return QFileIconProvider::icon(info); +} + +void GLDFileIconProvider::loadIcon(QMap mapURL) +{ + QMap::iterator it; + + for (it = mapURL.begin(); it != mapURL.end(); ++it) + { + m_map_icon[it.key()] = QIcon(QPixmap(*it)); + } +} + +void GLDFileIconProvider::loadSetting(const QString &setting) +{ + int nIndex = -1; + + for (int i = 0; i < c_vec_iconType.size(); i++) + { + if (nIndex > -1) + { + int nStringSize = c_vec_iconType[i].size(); + int nLengthIndex = setting.indexOf("\n", nIndex); + + if (nLengthIndex < 0) + { + continue; + } + + int nLength = nLengthIndex - (nIndex + nStringSize); + QString strIconURL = setting.mid(nIndex + nStringSize, nLength); + m_map_icon[QFileIconProvider::IconType(i)] = QIcon(QPixmap(strIconURL)); + } + } +} + +GLDShellComboBoxItemDelegate::GLDShellComboBoxItemDelegate( + const QString &rootPath, QWidget *parent): + QStyledItemDelegate(parent), + m_treeView(NULL), + m_model(NULL) +{ + G_UNUSED(rootPath); +} + +QPixmap GLDShellComboBoxItemDelegate::pixmap(const QModelIndex &index) const +{ + if (!m_model->hasChildren(index)) + { + return QPixmap(); + } + + if (index == m_treeView->hoverIndex()) + { + if (m_treeView->isExpanded(index)) + { + return QPixmap(c_strIconTreeOpenHover); + } + else + { + return QPixmap(c_strIconTreeHover); + } + } + + if (m_model->fileInfo(index).isRoot() + || m_model->fileInfo(index).fileName().compare("Desktop", Qt::CaseInsensitive) == 0) + { + if (m_treeView->isExpanded(index)) + { + return QPixmap(c_strIconTreeOpen); + } + else + { + return QPixmap(c_strIconTreeRoot); + } + } + + if (m_treeView->isExpanded(index)) + { + return QPixmap(c_strIconTreeOpen); + } + + if (isParentExpandedRecently(index)) + { + return QPixmap(c_strIconTreeChild); + } + + return QPixmap(c_strIconTreeRoot); +} + +bool GLDShellComboBoxItemDelegate::isParentExpandedRecently(const QModelIndex &index)const +{ + return (index.parent() == m_indexExpanded); +} + +void GLDShellComboBoxItemDelegate::setExpandedIndex(const QModelIndex &index) +{ + m_indexExpanded = index; +} + +QSize GLDShellComboBoxItemDelegate::sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + QSize size = QStyledItemDelegate::sizeHint(option, index); + size.setHeight(c_nTreeViewItemHeight); + return size; +} + +void GLDShellComboBoxItemDelegate::paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + QRect rect = option.rect; + + if (rect.height() != c_nTreeViewItemHeight) + { + return; + } + + if (rect.y() + rect.height() > m_treeView->height() + c_nTreeViewButtomOffset) + { + return; + } + + rect.adjust(-c_nTreeViewIndentation, 0, -rect.width(), 0); + m_treeView->setModelIndexRect(index, rect); + + rect.adjust(c_nArrowOffset, 0, -c_nArrowToIcon + c_nArrowOffset, 0); + QPixmap image = pixmap(index); + int nPosx = rect.x(); + int nPosy = rect.y() + (rect.height() - image.height()) / 2; + painter->drawPixmap(nPosx, nPosy, image.width(), image.height(), image); + + QStyledItemDelegate::paint(painter, option, index); +} + +void GLDShellComboBoxItemDelegate::doAfterExpanded(const QModelIndex &index) +{ + setExpandedIndex(index); +} + +void GLDShellComboBoxItemDelegate::doAfterCollapsed(const QModelIndex &index) +{ + QModelIndex indexSiling = index.sibling(0, 0); + for (int i = 0; indexSiling.isValid(); indexSiling = index.sibling(++i, 0)) + { + if (m_treeView->isExpanded(indexSiling)) + { + setExpandedIndex(QModelIndex()); + return; + } + } + setExpandedIndex(index.parent()); +} + +QModelIndex GLDShellComboBoxItemDelegate::findLonelyExpanded(const QModelIndex &root) +{ + Q_UNUSED(root); + return QModelIndex(); +} + +void GLDShellComboBoxItemDelegate::setTreeView(GLDShellTreeViewEx *treeView) +{ + m_treeView = treeView; + connect(m_treeView, &GLDShellTreeViewEx::expanded, this, + &GLDShellComboBoxItemDelegate::doAfterExpanded); + connect(m_treeView, &GLDShellTreeViewEx::collapsed, + this, &GLDShellComboBoxItemDelegate::doAfterCollapsed); +} + +void GLDShellComboBoxItemDelegate::setFileSystemModel(GLDFileSystemModelEX *model) +{ + m_model = model; + m_indexExpanded = model->index(""); +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDShellTreeViewEx.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDShellTreeViewEx.cpp new file mode 100644 index 00000000..39ebf584 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDShellTreeViewEx.cpp @@ -0,0 +1,192 @@ +#include "GLDScrollStyle.h" +#include "GLDShellTreeViewEx.h" + +#include +#include +#include +#include +#include +#include + +#include "GLDFileUtils.h" + +const int c_itemIndentation = 15; +//const int c_arroyOffset = 7; +const int c_arroyToIcon = 8; +//const int c_iconOffset = 12; +const QColor c_currentColor = QColor("#010101"); +const QColor c_otherColor = QColor("#626262"); +const QColor c_backgroundColor = QColor("#dbf3fc"); +const QString c_collapseIconPath = "://icons/right.png"; +const QString c_collapseHoverIconPath = "://icons/r-hover.png"; +const QString c_expandIconPath = "://icons/hs.png"; + +const GString c_sShellTreeViewQssFile = ":/qsses/GLDShellTreeViewEx.qss"; + +GLDShellTreeViewEx::GLDShellTreeViewEx(QWidget *parent) + : GLDShellTreeView(parent) +{ + init(); +} + +GLDShellTreeViewEx::GLDShellTreeViewEx(bool popup, GLDShellComboBox *combo): + GLDShellTreeView(popup, combo) +{ +} + +GLDShellTreeViewEx::~GLDShellTreeViewEx() +{ +} + +QModelIndex GLDShellTreeViewEx::point2ModelIndex(const QPoint &pos) +{ + for (QMap::iterator it = m_map_arrowRect.begin(); + it != m_map_arrowRect.end(); ++it) + { + if ((*it).contains(pos)) + { + return it.key(); + } + } + + return QModelIndex(); +} + +void GLDShellTreeViewEx::setModelIndexRect(const QModelIndex &index, const QRect &rect) +{ + m_map_arrowRect[index] = rect; +} + +int GLDShellTreeViewEx::countAllShownRows() +{ + return countAllShownRows(rootIndex()); +} + +void GLDShellTreeViewEx::init() +{ + setIndentation(c_itemIndentation); + setHeaderHidden(true); + + this->setStyleSheet(loadQssFile(c_sShellTreeViewQssFile)); + setStyle(new GLDScrollStyle(this)); + connect(this, SIGNAL(expanded(QModelIndex)), this, + SLOT(doAfterExpand(QModelIndex))); +} + +QModelIndex GLDShellTreeViewEx::expandedIndex() const +{ + return m_expandedIndex; +} + +void GLDShellTreeViewEx::mouseMoveEvent(QMouseEvent *event) +{ + QPoint point = event->pos(); + QModelIndex index = point2ModelIndex(point); + + if (visualRect(index).isValid())//可见 + { + setHoverIndex(index); + } + else + { + setHoverIndex(QModelIndex()); + } + + GLDShellTreeView::mouseMoveEvent(event); +} + +void GLDShellTreeViewEx::doAfterExpand(const QModelIndex &index) +{ + m_expandedIndex = index; +} + +int GLDShellTreeViewEx::countAllShownRows(const QModelIndex &root) +{ + int nRows = model()->rowCount(root); + + for (int i = 0; i < nRows; ++i) + { + QModelIndex child = model()->index(i, 0, root); + + if (isExpanded(child)) + { + nRows += countAllShownRows(child); + } + } + + return nRows; +} + +void GLDShellTreeViewEx::setModel(QAbstractItemModel *model) +{ + GLDShellTreeView::setModel(model); + setItemDelegate(new GLDShellTreeDelegate(this)); +} + +GLDShellTreeDelegate::GLDShellTreeDelegate(GLDShellTreeViewEx *parent) + : QStyledItemDelegate(parent) + , m_pTreeView(parent) +{ +} + +void GLDShellTreeDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + QStyleOptionViewItem optionItem = option; + + optionItem.rect.adjust(0, 0, -8, 0); //右侧距离边线或者滚动条8像素 + QRect rect = option.rect; + QPixmap image = decorationIcon(index); + int nPosx = rect.x() - c_arroyToIcon - 4;//控制左侧图标X坐标 + int nPosy = rect.y() + rect.height() / 2 - image.height() / 2;//控制左侧图标Y坐标 + painter->drawPixmap(nPosx, nPosy, image.width(), image.height(), image); + + //设置颜色 + QPalette palette; + QColor color = fontColor(index); + palette.setColor(QPalette::Text, color); + optionItem.palette = palette; + + QStyledItemDelegate::paint(painter, optionItem, index); + +} + +QColor GLDShellTreeDelegate::fontColor(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return QColor(); + } + + QModelIndex expandIndex = m_pTreeView->expandedIndex(); + if (!expandIndex.isValid() || index.parent() == expandIndex) + { + return c_currentColor; + } + return c_otherColor; +} + +QPixmap GLDShellTreeDelegate::decorationIcon(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return QPixmap(); + } + QModelIndex expandIndex = m_pTreeView->expandedIndex(); + if (index.model()->hasChildren(index)) + { + if (expandIndex.isValid() && index.parent() == expandIndex) + { + return QPixmap(c_collapseHoverIconPath); + } + else if (!m_pTreeView->isExpanded(index)) + { + return QPixmap(c_collapseIconPath); + } + else + { + return QPixmap(c_expandIconPath); + } + } + return QPixmap(); +} + diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDShellWidgets.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDShellWidgets.cpp new file mode 100644 index 00000000..ba9d9ef6 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDShellWidgets.cpp @@ -0,0 +1,1397 @@ +#include +#include +#include +#include +#include +#include +#include +#include "GLDStrUtils.h" +#include +#include +#include +#include "GLDShellWidgets.h" +#include "GLDFileSystemModel.h" +#include "GLDShellComboBoxEx.h" + +const int c_NormalSmallIconSize = 16; +GLDShellTreeView::GLDShellTreeView(QWidget *parent) : + QTreeView(parent), m_getPathType(AbsoluteName), m_comboBox(NULL), m_iFirstShow(0), m_bTreeRootWithCombo(true), + m_bSelfClicked(false), m_bComboClickeSignal(false), m_pDirModel(NULL), m_pHiddenBuddies(NULL), + m_pHiddenBuddys(NULL), m_preRoot(QModelIndex()), m_bSingleRoot(true), m_bUsingVariant(true), m_neverChangeRoot(false) +{ + GLDShellHeaderView *pHeader = new GLDShellHeaderView(this); + this->setHeader(pHeader); + + setMouseTracking(true); + setUniformRowHeights(true); + resizeColumnToContents(0); + + QObject::connect(this, SIGNAL(expanded(const QModelIndex &)), + this,SLOT(adjustColumnWidth(const QModelIndex &))); + QObject::connect(this, SIGNAL(pressed(QModelIndex)), this, SIGNAL(itemJustBeSelected(QModelIndex))); + QObject::connect(this, SIGNAL(doubleClicked(QModelIndex)), this, SIGNAL(itemJustBeDoubleClicked(QModelIndex))); +} + +GLDShellTreeView::~GLDShellTreeView() +{ + freeAndNil(m_pHiddenBuddies) + freeAndNil(m_pHiddenBuddys) +} + +void GLDShellTreeView::setModel(QAbstractItemModel *model) +{ + if (GLDCustomFileSystemModel *pModel = dynamic_cast(model)) + { + m_pDirModel = pModel; + } + inherit::setModel(model); + GLDShellHeaderView *pHeader = dynamic_cast(this->header()); + if (pHeader) + { + pHeader->setSection0AutoResize(); + pHeader->setSectionsHiddenExcept0(); + } + else + { + const int c_HeaderSectionCount = header()->count(); + for (int i = 1; i < c_HeaderSectionCount; ++i) + { +// hideColumn(i); +// setColumnWidth(i, 0); +// header()->resizeSection(i, 0); + header()->setSectionHidden(i, false); + } + } + setHeaderHidden(true); +} + +void GLDShellTreeView::setNameFilters(const QStringList &filters) +{ + return doSetNameFilters(model(), filters); +} + +QStringList GLDShellTreeView::nameFilters() const +{ + return doNameFilters(model()); +} + +QString GLDShellTreeView::currentPath(DirName dirType, SLASHTYPE xieGang) const +{ + QString tmp(""); + QModelIndex currentIndex = this->currentIndex(); + if (!currentIndex.isValid()) + { + currentIndex = this->rootIndex(); + } + if (currentIndex.isValid()) + { + if (this->selectionModel()) + { + tmp = filePathByType(currentIndex, dirType); + } + } + if (xieGang == BACKSLASH && tmp.length() > 0) + { + tmp = stringReplace(tmp,"/","\\"); + } + return tmp; +} + +GLDDirFilter::ISDIR GLDShellTreeView::isCurrentPathDir() const +{ + GLDFileSystemModel *pModel = dynamic_cast(model()); + if (pModel) + { + QModelIndex current = currentIndex(); + if (current.isValid()) + { + if (pModel->isDir(current)) + return GLDShellListView::ISFOLDER; + else + return GLDShellListView::ISFILE; + } + else + return GLDShellListView::NOITEMSELECTED; + } + return GLDShellListView::NOITEMSELECTED; +} + +void GLDShellTreeView::setAssociatedItemView(QAbstractItemView *view) +{ + QListView *list = dynamic_cast(view); + if (list) + { + const QModelIndex c_tmp = currentIndex(); + if (c_tmp.isValid()) + list->setRootIndex(c_tmp); + QObject::connect(this, SIGNAL(clicked(QModelIndex)), list, + SLOT(setRootIndex(QModelIndex))); + } + else + { + GLDShellTreeView *tree = dynamic_cast(view); + if (tree) + { + const QModelIndex c_tmp = rootIndex(); + if (tree->singleRoot()) + { + if (c_tmp.isValid()) + { + QString rootPath = dynamic_cast(tree->model())->filePath(c_tmp); + tree->setRootPath(rootPath); + } + } + else + { + if (c_tmp.isValid()) + tree->setRootIndex(c_tmp); + } + connect(this, SIGNAL(expanded(QModelIndex)), tree, SLOT(expand(QModelIndex))); + connect(this, SIGNAL(collapsed(QModelIndex)), tree, SLOT(collapse(QModelIndex))); + connect(tree, SIGNAL(expanded(QModelIndex)), this, SLOT(slotExpand(QModelIndex))); + connect(tree, SIGNAL(collapsed(QModelIndex)), this, SLOT(slotCollapse(QModelIndex))); + + connect(this, SIGNAL(clicked(QModelIndex)), tree, SLOT(setRootIndex(QModelIndex))); + connect(this, SIGNAL(expanded(QModelIndex)), tree, SLOT(setCurrentIndex(QModelIndex))); + connect(this, SIGNAL(collapsed(QModelIndex)), tree, SLOT(setCurrentIndex(QModelIndex))); + } + } +} + +void GLDShellTreeView::adjustColumnWidth(const QModelIndex &) +{ + resizeColumnToContents(0); +} + +void GLDShellTreeView::upToParentDir(const QModelIndex &parentDirIndex) +{ + if (m_bTreeRootWithCombo) + { + if (!isAssociatedAComboBox()) + this->setRootIndex(parentDirIndex); + } + if (isAssociatedAComboBox()) + { + inherit::setCurrentIndex(parentDirIndex); + m_comboBox->setEditText(m_pDirModel->filePath(parentDirIndex)); + m_comboBox->getLineEdit()->moveCursor(QTextCursor::Start); + } +} + +void GLDShellTreeView::slotExpand(QModelIndex index) +{ + if (!isExpanded(index)) + expand(index); +} + +void GLDShellTreeView::slotCollapse(QModelIndex index) +{ + if (isExpanded(index)) + collapse(index); +} + +void GLDShellTreeView::makePreBuddiesVisible() +{ + if (!m_bUsingVariant) + { + if (m_pHiddenBuddies && m_pHiddenBuddies->count() > 0) + { + QModelIndex par = m_pHiddenBuddies->front(); + m_pHiddenBuddies->pop_front(); + Q_ASSERT(m_pDirModel == model()); + while (m_pHiddenBuddies->count() > 0) + { + if (m_pHiddenBuddies->front().isValid()) + { + setRowHidden(m_pHiddenBuddies->front().row(), par, false); + } + m_pHiddenBuddies->pop_front(); + } + } + } + else + { + if (m_pHiddenBuddys && m_pHiddenBuddys->count() > 0) + { + QVariant var = m_pHiddenBuddys->front(); + QModelIndex par = m_pDirModel->index(var.toString()); + m_pHiddenBuddys->pop_front(); + Q_ASSERT(m_pDirModel == model()); + while (m_pHiddenBuddys->count() > 0) + { + QVariant buddyRow = m_pHiddenBuddys->front(); + setRowHidden(buddyRow.toInt(), par, false); + m_pHiddenBuddys->pop_front(); + } + } + } +} + +void GLDShellTreeView::makesureBuddyContainerExist() +{ + if (!m_bUsingVariant) + { + if (NULL == m_pHiddenBuddies) + { + m_pHiddenBuddies = new QList; + m_pHiddenBuddies->reserve(200); + } + } + else + { + if (NULL == m_pHiddenBuddys) + { + m_pHiddenBuddys = new QList; + } + } +} + +void GLDShellTreeView::makeRootParentAsRootAndHideBuddies() +{ + QModelIndex root = this->rootIndex(); + if (root.isValid()) + { + QDirModel *pModel = dynamic_cast(model()); + if (!pModel) + return; + m_preRoot = root; + root = root.parent(); +// if (root.isValid()) //磁盘根目录时root就是!isValid的 + { + inherit::setRootIndex(root); + inherit::setCurrentIndex(m_preRoot); + makesureBuddyContainerExist(); + hideBuddiesAndInsertList(m_preRoot, root, pModel->rowCount(root)); + } + } +} + +void GLDShellTreeView::hideBuddiesAndInsertList(const QModelIndex &visibleChild, const QModelIndex &par, int buddyCount) +{ + if (!m_bUsingVariant) + { + m_pHiddenBuddies->append(par); + while (buddyCount-- > 0) + { + if (buddyCount == visibleChild.row()) + continue; + QModelIndex buddyIndex = par.child(buddyCount, visibleChild.column()); + if (!par.isValid()) + { + buddyIndex = visibleChild.sibling(buddyCount, visibleChild.column()); + } + /*if (!isRowHidden(buddyCount, par))*/ //当有过滤时,被隐藏的不必增加,否则回设状态时将与过滤隐藏的行为矛盾 + { + m_pHiddenBuddies->append(buddyIndex); + setRowHidden(buddyCount, par, true); + } + } + } + else + { + m_pHiddenBuddys->append(m_pDirModel->filePath(par)); + while (buddyCount-- > 0) + { + if (buddyCount == visibleChild.row()) + continue; + QModelIndex buddyIndex = par.child(buddyCount, visibleChild.column()); + if (!par.isValid()) + { + buddyIndex = visibleChild.sibling(buddyCount, visibleChild.column()); + } + /*if (!isRowHidden(buddyCount, par))*/ //当有过滤时,被隐藏的不必增加,否则回设状态时将与过滤隐藏的行为矛盾 + { + m_pHiddenBuddys->append(buddyIndex.row()); + Q_ASSERT(buddyIndex.row() == buddyCount); + setRowHidden(buddyCount, par, true); + } + } + } +} + +void GLDShellTreeView::setCurrentIndex(const QModelIndex &index) +{ + if (!m_bSingleRoot) + { + if (index.isValid() && !isAssociatedAComboBox() && m_bTreeRootWithCombo) + { + bool bPrevState = this->blockSignals(true); + if (index.parent().isValid()) + { + inherit::setRootIndex(index.parent()); + } + else + { + inherit::setRootIndex(index); + } + this->blockSignals(bPrevState); + } + else + { + inherit::setCurrentIndex(index); + } + } + else + { + if (!m_bSelfClicked) + { + if (m_bTreeRootWithCombo && m_bComboClickeSignal) + { + setRootIndex(index); + m_bComboClickeSignal = false; + } + inherit::setCurrentIndex(index); + } + else + { + inherit::setCurrentIndex(index); + } + } +} + +void GLDShellTreeView::shellTreeOwnScrollTo() +{ + scrollTo(currentIndex()); +} + +QString GLDShellTreeView::getIndexFileName(QModelIndex pressedIndex) +{ + if (pressedIndex.column() > 0) + { + QModelIndex sibling = pressedIndex.sibling(pressedIndex.row(), 0); + return filePathByType(sibling, m_getPathType); + } + return filePathByType(pressedIndex, m_getPathType); +} + +void GLDShellTreeView::setSingleRoot(bool singleRoot) +{ + m_bSingleRoot = singleRoot; +} + +bool GLDShellTreeView::singleRoot() const +{ + return m_bSingleRoot; +} + +void GLDShellTreeView::setRootIndex(const QModelIndex &index) +{ + if (m_neverChangeRoot) + { + return; + } + if (m_bSingleRoot) + { + makePreBuddiesVisible(); + inherit::setRootIndex(index); + makeRootParentAsRootAndHideBuddies(); + } + else + { + inherit::setRootIndex(index); + } +} + +void GLDShellTreeView::setRootPath(const QString &path) +{ + QModelIndex root = m_pDirModel->index(path); + this->setRootIndex(root); +} + +void GLDShellTreeView::mousePressEvent(QMouseEvent *event) +{ + QTreeView::mousePressEvent(event); + QModelIndex pressedIndex = indexAt(event->pos()); + if (!visualRect(pressedIndex).contains(event->pos())) + return; + if (m_comboBox && pressedIndex.isValid()) + { + if (isAssociatedAComboBox()) + { + if (visualRect(pressedIndex).contains(event->pos())) + { + m_comboBox->closePopup(); + // m_comboBox->hidePopup(); + m_comboBox->setEditTextByIndex(pressedIndex); + } + if (isAssociatedAComboBox() && m_comboBox->m_shellTreeView) + { + bool bPreState = m_comboBox->m_shellTreeView->m_bComboClickeSignal; + m_comboBox->m_shellTreeView->m_bComboClickeSignal = true; + emit clicked(pressedIndex); + m_comboBox->m_shellTreeView->expand(pressedIndex); + m_comboBox->m_shellTreeView->m_bComboClickeSignal = bPreState; + } + else + emit clicked(pressedIndex); + } + } + bool bPrev = m_bTreeRootWithCombo; + m_bTreeRootWithCombo = false; + + m_bSelfClicked = true; + setCurrentIndex(pressedIndex); + m_bSelfClicked = false; + + m_bTreeRootWithCombo = bPrev; +} + +void GLDShellTreeView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) +{ + QTreeView::currentChanged(current, previous); + emit currentItemJustChanged(current, previous); +} + +void GLDShellTreeView::showEvent(QShowEvent *e) +{ + ++m_iFirstShow; + if (m_iFirstShow < 4) + { + QModelIndex index = currentIndex(); + if (index.isValid()) + scrollTo(index); + } + inherit::showEvent(e); +} + +void GLDShellTreeView::doItemsLayout() +{ + QTreeView::doItemsLayout(); + if (!m_bSingleRoot) + { + if (currentIndex().isValid()) + { + QTimer::singleShot(1, this, SLOT(shellTreeOwnScrollTo())); + } + } +} + +void GLDShellTreeView::setCurrentIndexPro(const QModelIndex &index) +{ + emit itemJustBeSelected(index); + setCurrentIndex(index); +} + +GLDShellTreeView::GLDShellTreeView(bool popup, GLDShellComboBox *combo) : + QTreeView(combo), m_getPathType(AbsoluteName), m_comboBox(combo), m_iFirstShow(0), m_bTreeRootWithCombo(false), + m_pDirModel(NULL), m_pHiddenBuddies(NULL), m_pHiddenBuddys(NULL), m_preRoot(QModelIndex()) +{ + Q_UNUSED(popup); + GLDShellHeaderView *pHeader = new GLDShellHeaderView(this); + this->setHeader(pHeader); + setMouseTracking(true); + setUniformRowHeights(true); + resizeColumnToContents(0); + QObject::connect(this, SIGNAL(expanded(const QModelIndex &)), + this,SLOT(adjustColumnWidth(const QModelIndex &))); +} + +GLDShellComboBox::GLDShellComboBox(const QString &rootPath, QWidget *parent) : + GLDWindowComboBox(parent), m_popupShellTree(NULL), m_shellListView(NULL), + m_shellTreeView(NULL), m_pFileModel(NULL), m_currentPathSetted(false) +{ + getLineEdit()->setLineWrapMode(QPlainTextEdit::NoWrap); + setFrame(true); + setAnimationPopup(false); + init(rootPath); +} + +GLDShellComboBox::~GLDShellComboBox() +{ + +} + +void GLDShellComboBox::setFileModel(GLDCustomFileSystemModel *model) +{ + freeAndNil(m_pFileModel); + m_pFileModel = model; + m_popupShellTree->setModel(model); + m_shellListView->setModel(model); +} + +void GLDShellComboBox::disconnectClick(QAbstractItemView *view) +{ + QObject::disconnect(m_popupShellTree, SIGNAL(clicked(QModelIndex)), view, + SLOT(setRootIndex(QModelIndex))); +} + +void GLDShellComboBox::setShellListView(GLDShellListView *list) +{ + if (m_shellListView) + { + disconnect(m_shellListView, SIGNAL(upToDir(QModelIndex)), m_popupShellTree, SLOT(upToParentDir(QModelIndex))); + if (m_shellTreeView) + { + disconnect(m_shellListView, SIGNAL(upToDir(QModelIndex)), + m_shellTreeView, SLOT(upToParentDir(QModelIndex))); + } + //防止内存泄漏 + if (!m_shellListView->parentWidget()) + m_shellListView->setParent(this); + } + m_shellListView = list; + if (m_popupShellTree && m_pFileModel && m_shellListView) + { + m_shellListView->setModel(m_pFileModel); + Q_ASSERT(m_popupShellTree->model() == m_pFileModel); + m_shellListView->setRootIndex(this->m_popupShellTree->currentIndex()); + m_popupShellTree->setAssociatedItemView(m_shellListView); + + connect(m_shellListView, SIGNAL(upToDir(QModelIndex)), m_popupShellTree, SLOT(upToParentDir(QModelIndex))); + connect(m_shellListView, SIGNAL(upToDir(QModelIndex)), m_shellTreeView, SLOT(upToParentDir(QModelIndex))); + connect(m_shellListView, SIGNAL(itemJustBeSelected(QModelIndex)), this, SLOT(synToComboAndTree(QModelIndex))); + } + if (m_currentPathSetted && m_shellListView) + { + QModelIndex path = m_popupShellTree->currentIndex(); + if (path.isValid()) + { + locateListTo(path); + } + } +} + +void GLDShellComboBox::locateListTo(QModelIndex path) +{ + m_shellListView->setRootIndex(path); + m_shellListView->setCurrentIndex(path); + m_shellListView->scrollTo(path); +} + +void GLDShellComboBox::expandTreeTo(QModelIndex path) +{ + m_shellTreeView->setCurrentIndex(path); + m_shellTreeView->expand(path); + m_shellTreeView->scrollTo(path); +} + +void GLDShellComboBox::setShellTreeView(GLDShellTreeView *tree) +{ + if (m_shellTreeView) + { + if (m_shellListView) + { + disconnect(m_shellListView, SIGNAL(upToDir(QModelIndex)), + m_shellTreeView, SLOT(upToParentDir(QModelIndex))); + disconnect(m_shellListView, SIGNAL(upToDir(QModelIndex)), + m_popupShellTree, SLOT(upToParentDir(QModelIndex))); + } + //防止内存泄漏 + if (!m_shellTreeView->parentWidget()) + m_shellTreeView->setParent(this); + } + m_shellTreeView = tree; + if (m_popupShellTree && m_pFileModel && m_shellTreeView) + { + m_shellTreeView->setModel(m_pFileModel); + Q_ASSERT(m_pFileModel == m_popupShellTree->model()); + m_shellTreeView->setRootIndex(m_popupShellTree->rootIndex()); + m_popupShellTree->setAssociatedItemView(m_shellTreeView); + if (m_shellListView) + connect(m_shellListView, SIGNAL(upToDir(QModelIndex)), m_shellTreeView, SLOT(upToParentDir(QModelIndex))); + + connect(m_shellTreeView, SIGNAL(itemJustBeSelected(QModelIndex)), this, SLOT(synToComboAndList(QModelIndex))); + } + if (m_currentPathSetted && m_shellTreeView) + { + QModelIndex path = m_popupShellTree->currentIndex(); + if (path.isValid()) + { + ISDIR isDir = getTheIndexDirType(path, m_pFileModel); + QModelIndex dirIndex = path.parent(); + QString sCurrentPath = m_pFileModel->filePath(path); + if (isDir == ISFOLDER) + { + m_shellTreeView->setRootPath(sCurrentPath); + m_shellTreeView->expand(m_popupShellTree->m_pDirModel->index(sCurrentPath)); + } + else if (isDir == ISFILE) + { + if (!m_shellTreeView->singleRoot()) + { + expandTreeTo(dirIndex); + m_shellTreeView->setCurrentIndex(path); + } + else + { + m_shellTreeView->setRootIndex(dirIndex); + m_shellTreeView->setCurrentIndex(path); + } + } + } + } +} + +void GLDShellComboBox::setChildrenRootIndex(QModelIndex path) +{ + m_popupShellTree->setRootIndex(path); + if (m_shellListView) + m_shellListView->setRootIndex(path); + if (m_shellTreeView) + m_shellTreeView->setRootIndex(path); +} + +void GLDShellComboBox::setCustomPath(const QString &rootPath) +{ + return setCurrentPath(rootPath); +// if (m_pFileModel && m_popupShellTree) +// { +// QModelIndex path = m_pFileModel->index(rootPath); +// if (path.isValid()&& m_pFileModel->isDir(path) ) +// { +// setChildrenRootIndex(path); +// } +// } +} + +void GLDShellComboBox::setEditTextByIndex(QModelIndex curIndex) +{ + QString strFilePathName = m_popupShellTree->getIndexFileName(curIndex); + if (curIndex.column() > 0 && curIndex.isValid()) + { + curIndex = curIndex.sibling(curIndex.row(), 0); + if (curIndex.isValid()) + { + strFilePathName = m_popupShellTree->getIndexFileName(curIndex); + } + } + setEditText(strFilePathName); + lineEdit()->moveCursor(QTextCursor::Start); +} + +void GLDShellComboBox::setCurrentPath(const QString ¤tPath) +{ + if (m_pFileModel && m_popupShellTree) + { + QString sCurrentPath = m_pFileModel->makeCaseCorrespondingToSystem(currentPath); + QModelIndex curIndex = m_pFileModel->index(sCurrentPath); + if (curIndex.isValid() && m_pFileModel->isDir(curIndex)) + { + m_popupShellTree->setCurrentIndex(curIndex); + m_popupShellTree->scrollTo(curIndex); + setEditTextByIndex(curIndex); + m_currentPathSetted = true; + + if (m_shellListView) + { + locateListTo(curIndex); + } + if (m_shellTreeView) + { + if (!m_shellTreeView->singleRoot()) + expandTreeTo(curIndex); + else + m_shellTreeView->setRootPath(sCurrentPath); + } + } + } +} + +void GLDShellComboBox::setCurrentFile(const QString ¤tFilePath) +{ + if (m_pFileModel && m_popupShellTree) + { + QString sCurrentPath = m_pFileModel->makeCaseCorrespondingToSystem(currentFilePath); + QModelIndex curIndex = m_pFileModel->index(sCurrentPath); + ISDIR isDir = getTheIndexDirType(curIndex, m_pFileModel); + if (curIndex.isValid()) + { + if (isDir == ISFOLDER) + { + m_popupShellTree->setCurrentIndex(curIndex); + m_popupShellTree->scrollTo(curIndex); + setEditTextByIndex(curIndex); + m_currentPathSetted = true; + + if (m_shellListView) + { + locateListTo(curIndex); + } + if (m_shellTreeView) + { + if (!m_shellTreeView->singleRoot()) + expandTreeTo(curIndex); + else + m_shellTreeView->setRootPath(sCurrentPath); + } + } + else if (isDir == ISFILE) + { + QModelIndex dirIndex = curIndex.parent(); + m_popupShellTree->setCurrentIndex(curIndex); + m_popupShellTree->expand(dirIndex); + m_popupShellTree->scrollTo(dirIndex); + setEditTextByIndex(curIndex); + m_currentPathSetted = true; + + if (m_shellListView) + { + locateListTo(dirIndex); + } + if (m_shellTreeView) + { + if (!m_shellTreeView->singleRoot()) + { + expandTreeTo(dirIndex); + m_shellTreeView->setCurrentIndex(curIndex); + } + else + { + m_shellTreeView->setRootIndex(dirIndex); + m_shellTreeView->setCurrentIndex(curIndex); + } + } + } + } + } +} + +void GLDShellComboBox::setNameFilters(const QStringList &filters) +{ + if (m_popupShellTree) + doSetNameFilters(m_popupShellTree->model(), filters); +} + +QStringList GLDShellComboBox::nameFilters() const +{ + if (m_popupShellTree) + return doNameFilters(m_popupShellTree->model()); + return QStringList(); +} + +void GLDShellComboBox::setDirNameType(GLDDirFilter::DirName type) +{ + m_popupShellTree->m_getPathType = type; +} + +GLDDirFilter::DirName GLDShellComboBox::dirNameType() const +{ + return m_popupShellTree->m_getPathType; +} + +QString GLDShellComboBox::getCurrentPath(DirName type, SLASHTYPE xieGang) const +{ + return m_popupShellTree->currentPath(type, xieGang); +} + +QString GLDShellComboBox::getIndexFilePath(const QModelIndex &index, GLDDirFilter::SLASHTYPE xieGang) const +{ + QString tmp(m_popupShellTree->getIndexFileName(index)); + if (xieGang == BACKSLASH && tmp.length() > 0) + { + tmp = stringReplace(tmp,"/","\\"); + } + return tmp; +} + +void GLDShellComboBox::synToComboAndTree(QModelIndex clickedIndex) +{ + bool bs = m_popupShellTree->blockSignals(true); + m_popupShellTree->setCurrentIndex(clickedIndex); + setEditTextByIndex(clickedIndex); + if (!bs) + m_popupShellTree->blockSignals(false); + if (m_shellTreeView && !m_shellTreeView->neverChangeRoot()) + { + bool bs = m_shellTreeView->blockSignals(true); + m_shellTreeView->setCurrentIndex(clickedIndex); + if (!bs) + m_shellTreeView->blockSignals(false); + } +} + +void GLDShellComboBox::synToComboAndList(QModelIndex clickedIndex) +{ + bool bs = m_popupShellTree->blockSignals(true); + m_popupShellTree->setCurrentIndex(clickedIndex); + setEditTextByIndex(clickedIndex); + if (!bs) + m_popupShellTree->blockSignals(false); + if (m_shellListView) + { + bool bs = m_shellListView->blockSignals(true); + m_shellListView->setRootIndex(clickedIndex); + m_shellListView->setCurrentIndex(clickedIndex); + if (!bs) + m_shellListView->blockSignals(false); + } +} + +void GLDShellComboBox::init(const QString &rootPath) +{ + m_pFileModel = new GLDFileSystemModel(true, this); +// m_pFileModel->setRootPath(rootPath); + + QModelIndex pathIndex = m_pFileModel->index(""); + if (rootPath.length() > 0) + { + QModelIndex pathIndexTmp = m_pFileModel->index(rootPath); + if (pathIndexTmp.isValid() && m_pFileModel->isDir(pathIndexTmp)) + pathIndex = pathIndexTmp; + } + //set tree as combobox`s popup + m_popupShellTree = new GLDShellTreeView(true, this); + m_popupShellTree->setSingleRoot(false); + m_popupShellTree->setModel(m_pFileModel); + Q_ASSERT(m_pFileModel == m_popupShellTree->model()); + m_popupShellTree->setRootIndex(pathIndex); + + //inherited init action + m_popupShellTree->setAnimated(false); + m_popupShellTree->setIndentation(10); + m_popupShellTree->setSortingEnabled(true); + + setPopupWidget(m_popupShellTree); +} + +void GLDShellComboBox::doAfterResize() +{ + if (m_popupShellTree) + { + double dHeight = width() / 0.618; + QPoint pos(this->width(), this->height()); + QRect screen = QApplication::desktop()->availableGeometry(pos); + pos = mapToGlobal(pos); + double distance = screen.bottom() - pos.y(); + if (distance > 0) + { + while (dHeight > 15) + { + if (dHeight > distance) + dHeight = dHeight / 1.6666667; + else + break; + } + } + else + { + dHeight = qMax(10, (int)(-distance)); + } + QSize geo(width(), dHeight); + setPopupSize(geo); + setPopupFixedWidth(geo.width()); + getLineEdit()->setFixedWidth(width() - c_NormalSmallIconSize - 18); + } +} + +QIcon GLDShellComboBox::itemIcon(const QModelIndex &index, const QAbstractItemModel *model) +{ + QVariant decoration = model->data(index, Qt::DecorationRole); + if (decoration.type() == QVariant::Pixmap) + return QIcon(qvariant_cast(decoration)); + else + return qvariant_cast(decoration); + +} + +void GLDShellComboBox::resizeEvent(QResizeEvent *event) +{ + Q_UNUSED(event) + GLDWindowComboBox::resizeEvent(event); + doAfterResize(); +} + +void GLDShellComboBox::paintEvent(QPaintEvent *event) +{ + QRect rect = getLineEdit()->geometry(); + if (rect.left() < 10) + { + getLineEdit()->setGeometry(rect.adjusted(c_NormalSmallIconSize, 0, 0, 0)); + } + if (!framePopup()) + { + GLDWindowComboBox::paintEvent(event); + return; + } + + QStyleOptionSpinBox opt; + initStyleOption(&opt); + + QStyleOptionComboBox optCombo; + + int niconWidth = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this); + QSize tmpSize(niconWidth, niconWidth); + + optCombo.init(this); + optCombo.editable = true; + optCombo.frame = opt.frame; + optCombo.subControls = opt.subControls; + optCombo.activeSubControls = opt.activeSubControls; + optCombo.state = opt.state; + if (lineEdit()->isReadOnly()) + { + optCombo.state &= ~QStyle::State_Enabled; + } + optCombo.iconSize = tmpSize; + + int nitemRole = (isEditable() ? Qt::EditRole : Qt::DisplayRole); + if (m_popupShellTree && m_popupShellTree->currentIndex().isValid()) + { + optCombo.currentText = m_popupShellTree->currentIndex().isValid() ? + m_pFileModel->data(m_popupShellTree->currentIndex(), nitemRole).toString() : QString(); + optCombo.currentIcon = itemIcon(m_popupShellTree->currentIndex(), m_popupShellTree->model()); + } + + //鼠标位于箭头所在区域高亮,其他地方不高亮 + QPoint curPos = mapFromGlobal(QCursor::pos()); + QRect subRect = style()->proxy()->subControlRect(QStyle::CC_ComboBox, &optCombo, QStyle::SC_ComboBoxArrow, this); + if (subRect.contains(curPos)) + optCombo.activeSubControls |= newHoverControl(curPos); + else + optCombo.activeSubControls &= newHoverControl(curPos); + + QStylePainter painter(this); + + painter.setPen(palette().color(QPalette::Text)); + + // draw the combobox frame, focusrect and selected etc. + painter.drawComplexControl(QStyle::CC_ComboBox, optCombo); + + // draw the icon and text + painter.drawControl(QStyle::CE_ComboBoxLabel, optCombo); +} + +GLDShellHeaderView::GLDShellHeaderView(QWidget *parent) : QHeaderView(Qt::Horizontal, parent) +{ + setDefaultSectionSize(0); + setSectionsMovable(true); + setStretchLastSection(true); + setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter); + setMouseTracking(true); +} + +GLDShellHeaderView::~GLDShellHeaderView() +{ + +} + +void GLDShellHeaderView::setSection0AutoResize() +{ +// setSectionsMovable(true); +// setSectionResizeMode(0, QHeaderView::ResizeToContents); + setSectionResizeMode(0, QHeaderView::Stretch); +// setSectionResizeMode(1, QHeaderView::Custom); +// setSectionResizeMode(2, QHeaderView::Custom); +// setSectionResizeMode(3, QHeaderView::Custom); +} + +void GLDShellHeaderView::setSectionsHiddenExcept0() +{ + const int c_SectionCount = count(); + if (c_SectionCount > 0) + { +// for (int i = 1; i < iSectionCount; ++i) +// { +//// setSectionHidden(i, true); +// resizeSection(i, 0); +// } + setStretchLastSection(false); + } +} + +GLDShellListView::GLDShellListView(QWidget *parent) : GLDListView(parent), + commentFrame(0),m_hintExistSeconds(2), m_bShowHint(false), m_bFirstShow(false), + m_bOpenFileWhileDblClk(false) +{ + connect(this, SIGNAL(itemJustBeSelected(const QModelIndex&)), this, SLOT(showHint(const QModelIndex&))); + connect(this, SIGNAL(itemJustBeDoubleClicked(const QModelIndex&)), + this, SLOT(mouseDoubleClickSlot(const QModelIndex&))); + init(); +} + +void GLDShellListView::init() +{ + GLDFileSystemModelEX *pModel = new GLDFileSystemModelEX(true, this); +// pModel->setRootPath(""); + this->setModel(pModel); +} + +void GLDShellListView::setCustomPath(QString rootPath) +{ + GLDFileSystemModel *pModel = dynamic_cast(this->model()); + if (pModel) + { + QModelIndex path = pModel->index(rootPath); + if (path.isValid() && pModel->isDir(path)) + { + setRootIndex(path); + } + } +} + +QString GLDShellListView::currentPath(DirName dirType, SLASHTYPE defType) const +{ + QString tmp = ""; + if (!currentReportMode()) + { + QModelIndex currentIndex = this->currentIndex(); + if (!currentIndex.isValid()) + { + currentIndex = this->rootIndex(); + } + if (currentIndex.isValid()) + { + if (this->selectionModel() && this->selectionModel()->selectedIndexes().size() > 0) + { + tmp = filePathByType(currentIndex, dirType); + } + } + } + else + { + QModelIndex currentIndex = this->m_shellTree->currentIndex(); + if (!currentIndex.isValid()) + { + currentIndex = m_shellTree->rootIndex(); + } + if (currentIndex.isValid()) + { + if (m_shellTree->selectionModel() && m_shellTree->selectionModel()->selectedIndexes().size() > 0) + { + tmp = filePathByType(currentIndex, dirType); + } + } + } + if (defType == BACKSLASH && tmp.length() > 0) + { + tmp = stringReplace(tmp,"/","\\"); + } + return tmp; +} + +GLDDirFilter::ISDIR GLDShellListView::isCurrentPathDir() const +{ + const GLDCustomFileSystemModel * pModel = dynamic_cast(model()); + ISDIR dir = GLDShellListView::NOITEMSELECTED; + if (pModel) + { + QModelIndex current = GLDListView::currentIndex(); + if (currentReportMode()) + { + pModel = dynamic_cast(m_shellTree->model()); + current = m_shellTree->dataIndex(m_shellTree->currentIndex()); + } + if (pModel) + { + dir = getTheIndexDirType(current, pModel); + } + } + return dir; +} + +bool GLDShellListView::upToParentDir() +{ + if (!currentReportMode()) + { + QModelIndex currentRoot = currentIndex(); + if (!currentRoot.isValid()) + currentRoot = rootIndex(); + if (currentRoot.isValid()) + { + QModelIndex parentIndex = currentRoot.parent(); + if (parentIndex.isValid()) + { + setRootIndex(parentIndex); + setCurrentIndex(parentIndex); + emit rootIndexChanged(parentIndex); + emit upToDir(parentIndex); + return true; + } + else + { + if (dynamic_cast(model())) + { + this->GLDListView::setRootIndex(parentIndex); + this->GLDListView::setCurrentIndex(parentIndex); + emit rootIndexChanged(parentIndex); + emit upToDir(parentIndex); + return true; + } + } + } + } + else + { + QModelIndex currentRoot = m_shellTree->currentIndex(); + if (!currentRoot.isValid()) + currentRoot = m_shellTree->rootIndex(); + if (currentRoot.isValid()) + { + QModelIndex parentIndex = currentRoot.parent(); + if (parentIndex.isValid()) + { + setRootIndex(m_shellTree->dataIndex(parentIndex)); + m_shellTree->setCurrentIndex(parentIndex); + emit rootIndexChanged(parentIndex); + emit upToDir(parentIndex); + return true; + } + else + { + if (dynamic_cast(model())) + { + this->GLDListView::setRootIndex(parentIndex); + this->GLDListView::setCurrentIndex(parentIndex); + emit rootIndexChanged(parentIndex); + emit upToDir(parentIndex); + return true; + } + } + } + } + return false; +} + +void GLDShellListView::setNameFilters(const QStringList &filters) +{ + doSetNameFilters(model(), filters); +} + +QStringList GLDShellListView::nameFilters() const +{ + return doNameFilters(model()); +} + +void GLDShellListView::setCurrentPath(const QString &path) +{ + if (path.isEmpty()) + { + if (qobject_cast(model())) + { + this->GLDListView::setRootIndex(QModelIndex()); + this->GLDListView::setCurrentIndex(QModelIndex()); + + emit rootIndexChanged(QModelIndex()); + emit upToDir(QModelIndex()); + } + } +} + +void GLDShellListView::setRootIndex(const QModelIndex &index) +{ + GLDCustomFileSystemModel *pModel = dynamic_cast(this->model()); + + if (pModel && index.isValid()) + { + if (!pModel->isDir(index)) + { + if (m_bOpenFileWhileDblClk) + { + QVariant varPath = model()->data(index, GLDCustomFileSystemModel::FilePathRole); + QDesktopServices::openUrl(QUrl::fromLocalFile(varPath.toString())); + } + else + { + GLDListView::setRootIndex(index); + GLDListView::setCurrentIndex(index); + emit rootIndexChanged(index); + } + } + else + { + GLDListView::setRootIndex(index); + GLDListView::setCurrentIndex(index); + emit rootIndexChanged(index); + } + } +} + +void GLDShellListView::showHint(const QModelIndex &index) +{ + if (!m_bFirstShow) + { + if (m_bShowHint && index.isValid()) + { + drawComment(index); + } + } + else + { + m_bFirstShow = false; + } +} + +void GLDShellListView::mouseDoubleClickSlot(const QModelIndex &index) +{ + if (index.isValid()) + { + if (!m_bOpenFileWhileDblClk) + { + GLDCustomFileSystemModel *pModel = dynamic_cast(model()); + if (pModel && ISFILE == getTheIndexDirType(index, pModel)) + { + setVsViewMode(m_viewMode); + if (m_shellTree && !currentReportMode()) + { + m_shellTree->setCurrentIndex(m_shellTree->proxyIndex(index)); + } + return; + } + } + setRootIndex(index); + setVsViewMode(m_viewMode); + if (m_shellTree && !currentReportMode()) + { + m_shellTree->setRootIndex(m_shellTree->proxyIndex(index)); + m_shellTree->setCurrentIndex(m_shellTree->proxyIndex(index)); + } + } +} + +void GLDShellListView::mousePressEvent(QMouseEvent *event) +{ + QModelIndex clickedIndex = indexAt(event->pos()); + GLDListView::mousePressEvent(event); + if ((event->button() == Qt::RightButton) && (!clickedIndex.isValid())) + { + return; + } + setCurrentIndex(clickedIndex); +} + +void GLDShellListView::drawComment(const QPersistentModelIndex &index) +{ + if (!(commentFrame)) + { + commentFrame = new GCommentFrame(this); + commentFrame->m_arrow->hide(); + } + if (!index.isValid()) + { + commentFrame->hide(); + } + else + { + QVariant name = index.data(GLDFileSystemModel::FileNameRole); + QString str = name.toString(); + if (str == "") + str = index.data().toString(); //model()->data(index, gidrCommentRole).toString(); + if (str != "") + { + commentFrame->setCommentText(str); + //move的位置参数是相对于父窗体中的坐标 + commentFrame->move(visualRect(index).topRight() - commentFrame->rect().topRight()/*+ viewport()->pos()*/); + adjustChildWidgetPos(commentFrame); + if (!currentReportMode()) + { + commentFrame->setParent(this); + } + else if (m_shellTree) + { + commentFrame->setParent(m_shellTree); + } + commentFrame->show(); + commentFrame->m_arrow->hide(); + //定时消失 + QTimer::singleShot(m_hintExistSeconds * 1000, commentFrame, SLOT(hide())); + } + else + { + commentFrame->hide(); + } + } +} + +bool GLDShellListView::adjustChildWidgetPos(QWidget *child) +{ + if (child->parentWidget() != this) + return false; + else + { + QRect posRect = child->geometry(); + QRect hostRect = this->viewport()->rect(); + if (hostRect.contains(posRect)) + { + doNothingMacro(); + } + else + { + QPoint tl = posRect.topLeft(); + QPoint tr = posRect.topRight(); + QPoint bl = posRect.bottomLeft(); + QPoint br = posRect.bottomRight(); + if (!hostRect.contains(tl)) + { + child->move(0,0); + } + else if (!hostRect.contains(tr)) + { + child->move(qMax(0,(hostRect.width() - posRect.width())), 0); + } + else if (!hostRect.contains(bl)) + { + child->move(0, qMax((hostRect.height() - posRect.height()), 0)); + } + else if (!hostRect.contains(br)) + { + child->move(qMax((hostRect.width() - posRect.width()), 0) , + qMax((hostRect.height() - posRect.height()), 0)); + } + } + return true; + } +} + +QString GLDDirFilter::filePathByType(const QModelIndex ¤tIndex, GLDDirFilter::DirName dirType) const +{ + QString tmp; + if (AbsoluteName == dirType) + { + QVariant path = currentIndex.data(GLDCustomFileSystemModel::FilePathRole); + tmp = path.toString(); + } + else + { + QVariant name = currentIndex.data(GLDCustomFileSystemModel::FileNameRole); + tmp = name.toString(); + } + return tmp; +} + +GLDDirFilter::ISDIR GLDDirFilter::getTheIndexDirType(const QModelIndex &index, const GLDCustomFileSystemModel *pModel) const +{ + if (index.isValid()) + { + if (pModel->isDir(index)) + return GLDShellListView::ISFOLDER; + else + return GLDShellListView::ISFILE; + } + else + return GLDShellListView::NOITEMSELECTED; +} + +void GLDDirFilter::doSetNameFilters(QAbstractItemModel *model, const QStringList &filters) +{ + if (model) + { + GLDFileSystemModel *pModel = dynamic_cast(model); + if (pModel == NULL) + { + GLDCustomFileSystemModel *pMutilModel = dynamic_cast(model); + pModel = pMutilModel->fileSystemModel(); + } + if (pModel != NULL) + { + QDir::Filters filter = pModel->filter(); + if (filters.count() > 0) + { + filter |= QDir::AllDirs; + pModel->setFilter(filter); + } + pModel->setNameFilters(filters); + } + } +} + +QStringList GLDDirFilter::doNameFilters(QAbstractItemModel *model) const +{ + if (model) + { + if (GLDFileSystemModel *pModel = dynamic_cast(model)) + { + return pModel->nameFilters(); + } + } + return QStringList(); +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDSpinBox.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDSpinBox.cpp new file mode 100644 index 00000000..708c8bc6 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDSpinBox.cpp @@ -0,0 +1,374 @@ +#include "GLDWidget_Global.h" +#include "GLDSpinBox.h" +#include "GLDFileUtils.h" + +#include +#include +#include +#include +#include + +const GString c_sSpinBoxQssFile = ":/qsses/GLDSpinBoxEx.qss"; +const GString c_sDoubleSpinBoxQssFile = ":/qsses/GLDSpinBoxEx.qss"; + +G_GLODON_BEGIN_NAMESPACE + +GLDSpinBox::GLDSpinBox(QWidget *parent) : + QSpinBox(parent), m_wheelEnable(true), m_upAndDownEnable(true) +{ + setMaximum(MaxInt); + setMinimum(MinInt); + setButtonSymbols(NoButtons); + + connect(lineEdit(), SIGNAL(cursorPositionChanged(int, int)), + this, SLOT(doCursorPositionChanged(int, int))); + connect(lineEdit(), SIGNAL(selectionChanged()), + this, SLOT(doSelectionChanged())); +} + +bool GLDSpinBox::hasSelectedText() +{ + return lineEdit()->hasSelectedText(); +} + +void GLDSpinBox::keyPressEvent(QKeyEvent *event) +{ + if (!m_upAndDownEnable) + { + switch (event->key()) + { + case Qt::Key_Up: + case Qt::Key_Down: + case Qt::Key_PageUp: + case Qt::Key_PageDown: + return event->accept(); + default: + break; + } + } + QSpinBox::keyPressEvent(event); +} + +void GLDSpinBox::mouseReleaseEvent(QMouseEvent *event) +{ + QSpinBox::mouseReleaseEvent(event); +} + +#ifndef QT_NO_WHEELEVENT +void GLDSpinBox::wheelEvent(QWheelEvent *event) +{ + if (!m_wheelEnable) + { + return event->accept(); + } + else + QSpinBox::wheelEvent(event); +} +#endif + +void GLDSpinBox::doSelectionChanged() +{ + emit selectionChanged(); +} + +void GLDSpinBox::doCursorPositionChanged(int, int) +{ + emit cursorPositionChanged(); +} + + +GLDDoubleSpinBox::GLDDoubleSpinBox(QWidget *parent) : + QDoubleSpinBox(parent), m_decimalsEnable(true), m_wheelEnable(true), m_upAndDownEnable(true), m_orgDecimals(2), + m_validator(NULL) +{ + setMinimum(MINDOUBLE); + setMaximum(MAXDOUBLE); + setButtonSymbols(NoButtons); + setDecimalsEnable(false); + + connect(lineEdit(), SIGNAL(cursorPositionChanged(int, int)), + this, SLOT(doCursorPositionChanged(int, int))); + connect(lineEdit(), SIGNAL(selectionChanged()), + this, SLOT(doSelectionChanged())); +} + +GLDDoubleSpinBox::~GLDDoubleSpinBox() +{ + if (m_validator) + delete m_validator;//freeAndNil(m_validator); +} + +QValidator::State GLDDoubleSpinBox::validate(QString &input, int &pos) const +{ + if (m_decimalsEnable && !input.contains(QLatin1Char('e'))) + return QDoubleSpinBox::validate(input, pos); + else + { + bool bOk = false; + input.toDouble(&bOk); + if (bOk) + return QValidator::Acceptable; + else //也许是输入e的特殊情形 + { + if (!m_validator) + { + m_validator = new QDoubleValidator(minimum(), maximum(), decimals(), NULL); + m_validator->setNotation(QDoubleValidator::ScientificNotation); + } + m_validator->setDecimals(decimals()); + QValidator::State tmp = m_validator->validate(input, pos); + return tmp; + } + } +} + +double GLDDoubleSpinBox::valueFromText(const QString &text) const +{ + if (m_decimalsEnable) + return QDoubleSpinBox::valueFromText(text); + else + return text.toDouble(); +} + +QString GLDDoubleSpinBox::textFromValue(double val) const +{ + if (m_decimalsEnable) + return QDoubleSpinBox::textFromValue(val); + else + { + QString tmp = QString::number(val, 'g', normalDecimals); + return tmp; + } +} + +void GLDDoubleSpinBox::setDecimalsEnable(bool value) +{ + if (value == m_decimalsEnable) + return; + m_decimalsEnable = value; + if (m_decimalsEnable) + setDecimals(m_orgDecimals); + else + { + m_orgDecimals = decimals(); + setDecimals(normalDecimals); + } +} + +bool GLDDoubleSpinBox::hasSelectedText() +{ + return lineEdit()->hasSelectedText(); +} + +void GLDDoubleSpinBox::cut() +{ + lineEdit()->cut(); +} + +void GLDDoubleSpinBox::keyPressEvent(QKeyEvent *event) +{ + if (!m_upAndDownEnable) + { + switch (event->key()) + { + case Qt::Key_Up: + case Qt::Key_Down: + case Qt::Key_PageUp: + case Qt::Key_PageDown: + return; + default: + break; + } + } + QDoubleSpinBox::keyPressEvent(event); +} + +#ifndef QT_NO_WHEELEVENT +void GLDDoubleSpinBox::wheelEvent(QWheelEvent *event) +{ + if (!m_wheelEnable) + { + return event->accept(); + } + else + QDoubleSpinBox::wheelEvent(event); +} +#endif + +void GLDDoubleSpinBox::setDecimals(int prec) +{ + QDoubleSpinBox::setDecimals(prec); +} + +void GLDDoubleSpinBox::doSelectionChanged() +{ + emit selectionChanged(); +} + +void GLDDoubleSpinBox::doCursorPositionChanged(int, int) +{ + emit cursorPositionChanged(); +} + +void GLDSpinBox::paste() +{ + lineEdit()->paste(); +} + +void GLDSpinBox::deleteSelectedText() +{ + if (hasSelectedText()) + { + lineEdit()->del(); + } +} + +void GLDSpinBox::copy() +{ + lineEdit()->copy(); +} + +void GLDSpinBox::cut() +{ + lineEdit()->cut(); +} + +void GLDDoubleSpinBox::paste() +{ + lineEdit()->paste(); +} + +void GLDDoubleSpinBox::deleteSelectedText() +{ + if (hasSelectedText()) + { + lineEdit()->del(); + } +} + +void GLDDoubleSpinBox::copy() +{ + lineEdit()->copy(); +} + +GLDSpinBoxEx::GLDSpinBoxEx(QWidget *parent) : + GLDSpinBox(parent) +{ + setObjectName("GLDSpinBoxEx"); + setButtonSymbols(UpDownArrows); + this->setStyleSheet(loadQssFile(c_sSpinBoxQssFile)); +} + +void GLDSpinBoxEx::setHasBorder(bool bHasBorder) +{ + if (bHasBorder) + { + setProperty("border", true); + } + else + { + setProperty("border", false); + } +} + +void GLDSpinBoxEx::enterEvent(QEvent *event) +{ + setProperty("UpDownBtnBorder", true); + this->setStyleSheet(loadQssFile(c_sSpinBoxQssFile)); + G_UNUSED(event); +} + +void GLDSpinBoxEx::leaveEvent(QEvent *event) +{ + setProperty("UpDownBtnBorder", false); + this->setStyleSheet(loadQssFile(c_sSpinBoxQssFile)); + G_UNUSED(event); +} + +void GLDSpinBoxEx::resizeEvent(QResizeEvent *event) +{ + updateEditFieldGeometry(); + G_UNUSED(event); +} + +void GLDSpinBoxEx::updateEditFieldGeometry() +{ + QStyleOptionSpinBox optSpinBox; + optSpinBox.init(this); + optSpinBox.subControls = QStyle::SC_SpinBoxFrame | QStyle::SC_SpinBoxEditField; + + QRect rect = style()->subControlRect(QStyle::CC_SpinBox, &optSpinBox, QStyle::SC_SpinBoxEditField, this); + if (buttonSymbols() == QAbstractSpinBox::NoButtons) + { + rect = rect.adjusted(0, 0, 22, 0); + } + else{ + rect = rect.adjusted(0, 0, 6, 0); + } + + lineEdit()->setMinimumSize(rect.width(), rect.height()); + lineEdit()->setMaximumSize(rect.width(), rect.height()); + lineEdit()->setGeometry(rect); +} + +GLDDoubleSpinBoxEx::GLDDoubleSpinBoxEx(QWidget *parent) : + GLDDoubleSpinBox(parent) +{ + setObjectName("GLDDoubleSpinBoxEx"); + setButtonSymbols(UpDownArrows); + this->setStyleSheet(loadQssFile(c_sDoubleSpinBoxQssFile)); +} + +void GLDDoubleSpinBoxEx::setHasBorder(bool bHasBorder) +{ + if (bHasBorder) + { + setProperty("border", true); + } + else + { + setProperty("border", false); + } +} + +void GLDDoubleSpinBoxEx::enterEvent(QEvent *event) +{ + setProperty("UpDownBtnBorder", true); + this->setStyleSheet(loadQssFile(c_sDoubleSpinBoxQssFile)); + G_UNUSED(event); +} + +void GLDDoubleSpinBoxEx::leaveEvent(QEvent *event) +{ + setProperty("UpDownBtnBorder", false); + this->setStyleSheet(loadQssFile(c_sDoubleSpinBoxQssFile)); + G_UNUSED(event); +} + +void GLDDoubleSpinBoxEx::resizeEvent(QResizeEvent *event) +{ + updateEditFieldGeometry(); + G_UNUSED(event); +} + +void GLDDoubleSpinBoxEx::updateEditFieldGeometry() +{ + QStyleOptionSpinBox optSpinBox; + optSpinBox.init(this); + optSpinBox.subControls = QStyle::SC_SpinBoxFrame | QStyle::SC_SpinBoxEditField; + + QRect rect = style()->subControlRect(QStyle::CC_SpinBox, &optSpinBox, QStyle::SC_SpinBoxEditField, this); + if (buttonSymbols() == QAbstractSpinBox::NoButtons) + { + rect = rect.adjusted(0, 0, 22, 0); + } + else{ + rect = rect.adjusted(0, 0, 6, 0); + } + + lineEdit()->setMinimumSize(rect.width(), rect.height()); + lineEdit()->setMaximumSize(rect.width(), rect.height()); + lineEdit()->setGeometry(rect); +} + +G_GLODON_END_NAMESPACE diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDSplitter.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDSplitter.cpp new file mode 100644 index 00000000..dbaedeea --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDSplitter.cpp @@ -0,0 +1,1821 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtWidgets module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "GLDSplitter.h" +#include "GLDSplitter_p.h" +#ifndef QT_NO_SPLITTER + +#include "qapplication.h" +#include "qcursor.h" +#include "qdrawutil.h" +#include "qevent.h" +#include "qlayout.h" +//#include "qlist.h" +#include "qpainter.h" +#include "qrubberband.h" +#include "qstyle.h" +#include "qstyleoption.h" +#include "qtextstream.h" +#include "qvarlengtharray.h" +#include "qvector.h" +#include "private/qlayoutengine_p.h" + +#include "qtimer.h" +#ifdef GLDSPLITTER_DEBUG +#include "qdebug.h" +#endif +#include + +#include + +//G_GLODON_BEGIN_NAMESPACE + +//#define GLDSPLITTER_DEBUG + + +int GLDSplitterLayoutStruct::getWidgetSize(Qt::Orientation orient) +{ + if (sizer == -1) + { + QSize s = widget->sizeHint(); + const int presizer = pick(s, orient); + const int realsize = pick(widget->size(), orient); + + if (!s.isValid() || (widget->testAttribute(Qt::WA_Resized) && (realsize > presizer))) + { + sizer = pick(widget->size(), orient); + } + else + { + sizer = presizer; + } + + QSizePolicy p = widget->sizePolicy(); + int sf = (orient == Qt::Horizontal) ? p.horizontalStretch() : p.verticalStretch(); + + if (sf > 1) + { + sizer *= sf; + } + } + + return sizer; +} + +int GLDSplitterLayoutStruct::getHandleSize(Qt::Orientation orient) +{ + return pick(handle->sizeHint(), orient); +} + +void GLDSplitterPrivate::init() +{ + Q_Q(GLDSplitter); + QSizePolicy sp(QSizePolicy::Expanding, QSizePolicy::Preferred); + + if (orient == Qt::Vertical) + { + sp.transpose(); + } + + q->setSizePolicy(sp); + q->setAttribute(Qt::WA_WState_OwnSizePolicy, false); +} + +void GLDSplitterPrivate::recalc(bool update) +{ + Q_Q(GLDSplitter); + int n = list.count(); + /* + Splitter handles before the first visible widget or right + before a hidden widget must be hidden. + */ + bool first = true; + bool allInvisible = n != 0; + + for (int i = 0; i < n ; ++i) + { + GLDSplitterLayoutStruct *s = list.at(i); + bool widgetHidden = s->widget->isHidden(); + + if (allInvisible && !widgetHidden && !s->collapsed) + { + allInvisible = false; + } + + s->handle->setHidden(first || widgetHidden); + + if (!widgetHidden) + { + first = false; + } + } + + if (allInvisible) + for (int i = 0; i < n ; ++i) + { + GLDSplitterLayoutStruct *s = list.at(i); + + if (!s->widget->isHidden()) + { + s->collapsed = false; + break; + } + } + + int fi = 2 * q->frameWidth(); + int maxl = fi; + int minl = fi; + int maxt = QWIDGETSIZE_MAX; + int mint = fi; + /* + calculate min/max sizes for the whole splitter + */ + bool empty = true; + + for (int j = 0; j < n; j++) + { + GLDSplitterLayoutStruct *s = list.at(j); + + if (!s->widget->isHidden()) + { + empty = false; + + if (!s->handle->isHidden()) + { + minl += s->getHandleSize(orient); + maxl += s->getHandleSize(orient); + } + + QSize minS = qSmartMinSize(s->widget); + minl += pick(minS); + maxl += pick(s->widget->maximumSize()); + mint = qMax(mint, trans(minS)); + int tm = trans(s->widget->maximumSize()); + + if (tm > 0) + { + maxt = qMin(maxt, tm); + } + } + } + + if (empty) + { + if (dynamic_cast(parent)) + { + // nested splitters; be nice + maxl = maxt = 0; + } + else + { + // GLDSplitter with no children yet + maxl = QWIDGETSIZE_MAX; + } + } + else + { + maxl = qMin(maxl, QWIDGETSIZE_MAX); + } + + if (maxt < mint) + { + maxt = mint; + } + + if (update) + { + if (orient == Qt::Horizontal) + { + q->setMaximumSize(maxl, maxt); + + if (q->isWindow()) + { + q->setMinimumSize(minl, mint); + } + } + else + { + q->setMaximumSize(maxt, maxl); + + if (q->isWindow()) + { + q->setMinimumSize(mint, minl); + } + } + + doResize(); + q->updateGeometry(); + } + else + { + firstShow = true; + } +} + +void GLDSplitterPrivate::doResize(const QList *pSizes) +{ + Q_Q(GLDSplitter); + QRect r = q->contentsRect(); + int n = list.count(); + QVector a(n * 2); + int i; + + bool noStretchFactorsSet = true; + + for (i = 0; i < n; ++i) + { + QSizePolicy p = list.at(i)->widget->sizePolicy(); + int sf = orient == Qt::Horizontal ? p.horizontalStretch() : p.verticalStretch(); + + if (sf != 0) + { + noStretchFactorsSet = false; + break; + } + } + + int j = 0; + + for (i = 0; i < n; ++i) + { + GLDSplitterLayoutStruct *s = list.at(i); + int nSizeWanted = -1; + + if (pSizes) + { + nSizeWanted = pSizes->at(i); + } + +#ifdef GLDSPLITTER_DEBUG + qDebug("widget %d hidden: %d collapsed: %d handle hidden: %d", i, s->widget->isHidden(), + s->collapsed, s->handle->isHidden()); +#endif + + a[j].init(); + + if (s->handle->isHidden()) + { + a[j].maximumSize = 0; + } + else + { + a[j].sizeHint = a[j].minimumSize = a[j].maximumSize = s->getHandleSize(orient); + a[j].empty = false; + } + + ++j; + + a[j].init(); + + if (s->widget->isHidden() || s->collapsed) + { + a[j].maximumSize = 0; + } + else + { + a[j].minimumSize = pick(qSmartMinSize(s->widget)); + a[j].maximumSize = pick(s->widget->maximumSize()); + a[j].empty = false; + + bool stretch = noStretchFactorsSet; + + if (!stretch) + { + QSizePolicy p = s->widget->sizePolicy(); + int sf = orient == Qt::Horizontal ? p.horizontalStretch() : p.verticalStretch(); + stretch = (sf != 0); + } + + if (stretch) + { + a[j].stretch = s->getWidgetSize(orient); + a[j].sizeHint = a[j].minimumSize; + a[j].expansive = true; + } + else + { + a[j].sizeHint = qMax(s->getWidgetSize(orient), a[j].minimumSize); + } + + if (nSizeWanted > 0 && nSizeWanted != a[j].sizeHint) + { + a[j].sizeHint = nSizeWanted; + + if (nSizeWanted > a[j].minimumSize) + { + a[j].minimumSize = nSizeWanted; + } + else if (nSizeWanted < a[j].minimumSize) + { + a[j].minimumSize = nSizeWanted; + } + } + } + + ++j; + } + + qGeomCalc(a, 0, n * 2, pick(r.topLeft()), pick(r.size()), 0); + +#ifdef GLDSPLITTER_DEBUG + + for (i = 0; i < n * 2; ++i) + { + qDebug("%*s%d: stretch %d, sh %d, minS %d, maxS %d, exp %d, emp %d -> %d, %d", + i, "", i, + a[i].stretch, + a[i].sizeHint, + a[i].minimumSize, + a[i].maximumSize, + a[i].expansive, + a[i].empty, + a[i].pos, + a[i].size); + } + +#endif + + for (i = 0; i < n; ++i) + { + GLDSplitterLayoutStruct *s = list.at(i); + setGeo(s, a[i * 2 + 1].pos, a[i * 2 + 1].size, false); + } +} + +void GLDSplitterPrivate::storeSizes() +{ + for (int i = 0; i < list.size(); ++i) + { + GLDSplitterLayoutStruct *sls = list.at(i); + sls->sizer = pick(sls->rect.size()); + } +} + +void GLDSplitterPrivate::addContribution(int index, int *min, int *max, bool mayCollapse) const +{ + GLDSplitterLayoutStruct *s = list.at(index); + + if (!s->widget->isHidden()) + { + if (!s->handle->isHidden()) + { + *min += s->getHandleSize(orient); + *max += s->getHandleSize(orient); + } + + if (mayCollapse || !s->collapsed) + { + *min += pick(qSmartMinSize(s->widget)); + } + + *max += pick(s->widget->maximumSize()); + } +} + +int GLDSplitterPrivate::findWidgetJustBeforeOrJustAfter(int index, int delta, int &collapsibleSize) const +{ + if (delta < 0) + { + index += delta; + } + + do + { + QWidget *w = list.at(index)->widget; + + if (!w->isHidden()) + { + if (collapsible(list.at(index))) + { + collapsibleSize = pick(qSmartMinSize(w)); + } + + return index; + } + + index += delta; + } + while (index >= 0 && index < list.count()); + + return -1; +} + +/* + For the splitter handle with index \a index, \a min and \a max give the range without collapsing any widgets, + and \a farMin and farMax give the range with collapsing included. +*/ +void GLDSplitterPrivate::getRange(int index, int *farMin, int *min, int *max, int *farMax) const +{ + Q_Q(const GLDSplitter); + int n = list.count(); + + if (index <= 0 || index >= n) + { + return; + } + + int collapsibleSizeBefore = 0; + int idJustBefore = findWidgetJustBeforeOrJustAfter(index, -1, collapsibleSizeBefore); + + int collapsibleSizeAfter = 0; + int idJustAfter = findWidgetJustBeforeOrJustAfter(index, +1, collapsibleSizeAfter); + + int minBefore = 0; + int minAfter = 0; + int maxBefore = 0; + int maxAfter = 0; + int i; + + for (i = 0; i < index; ++i) + { + addContribution(i, &minBefore, &maxBefore, i == idJustBefore); + } + + for (i = index; i < n; ++i) + { + addContribution(i, &minAfter, &maxAfter, i == idJustAfter); + } + + QRect r = q->contentsRect(); + int farMinVal; + int minVal; + int maxVal; + int farMaxVal; + + int smartMinBefore = qMax(minBefore, pick(r.size()) - maxAfter); + int smartMaxBefore = qMin(maxBefore, pick(r.size()) - minAfter); + + minVal = pick(r.topLeft()) + smartMinBefore; + maxVal = pick(r.topLeft()) + smartMaxBefore; + + farMinVal = minVal; + + if (minBefore - collapsibleSizeBefore >= pick(r.size()) - maxAfter) + { + farMinVal -= collapsibleSizeBefore; + } + + farMaxVal = maxVal; + + if (pick(r.size()) - (minAfter - collapsibleSizeAfter) <= maxBefore) + { + farMaxVal += collapsibleSizeAfter; + } + + if (farMin) + { + *farMin = farMinVal; + } + + if (min) + { + *min = minVal; + } + + if (max) + { + *max = maxVal; + } + + if (farMax) + { + *farMax = farMaxVal; + } +} + +int GLDSplitterPrivate::adjustPos(int pos, int index, int *farMin, int *min, int *max, int *farMax) const +{ + const int Threshold = 40; + + getRange(index, farMin, min, max, farMax); + + if (pos >= *min) + { + if (pos <= *max) + { + return pos; + } + else + { + int delta = pos - *max; + int width = *farMax - *max; + + if (delta > width / 2 && delta >= qMin(Threshold, width)) + { + return *farMax; + } + else + { + return *max; + } + } + } + else + { + int delta = *min - pos; + int width = *min - *farMin; + + if (delta > width / 2 && delta >= qMin(Threshold, width)) + { + return *farMin; + } + else + { + return *min; + } + } +} + +bool GLDSplitterPrivate::collapsible(GLDSplitterLayoutStruct *s) const +{ + if (s->collapsible != Default) + { + return (bool)s->collapsible; + } + else + { + return childrenCollapsible; + } +} + +void GLDSplitterPrivate::updateHandles() +{ + Q_Q(GLDSplitter); + recalc(q->isVisible()); +} + +void GLDSplitterPrivate::setSizes_helper(const QList &sizes, bool clampNegativeSize) +{ + int j = 0; + + for (int i = 0; i < list.size(); ++i) + { + GLDSplitterLayoutStruct *s = list.at(i); + + s->collapsed = false; + s->sizer = sizes.value(j++); + + if (clampNegativeSize && s->sizer < 0) + { + s->sizer = 0; + } + + int smartMinSize = pick(qSmartMinSize(s->widget)); + + // Make sure that we reset the collapsed state. + if (s->sizer == 0) + { + if (collapsible(s) && smartMinSize > 0) + { + s->collapsed = true; + } + else + { + s->sizer = smartMinSize; + } + } + else + { + if (s->sizer < smartMinSize) + { + s->sizer = smartMinSize; + } + } + } + + doResize(&sizes); +} + +void GLDSplitterPrivate::setGeo(GLDSplitterLayoutStruct *sls, int p, int s, bool allowCollapse) +{ + Q_Q(GLDSplitter); + QWidget *w = sls->widget; + QRect r; + QRect contents = q->contentsRect(); + + //TODO + if (p < 0) + { + p = 0; + } + + if (s > (q->orientation() == Qt::Horizontal ? q->rect().width() : q->rect().height())) + { + s = (q->orientation() == Qt::Horizontal ? q->rect().width() : q->rect().height()); + } + + if (orient == Qt::Horizontal) + { + r.setRect(p, contents.y(), s, contents.height()); + } + else + { + r.setRect(contents.x(), p, contents.width(), s); + } + + sls->rect = r; + + int minSize = pick(qSmartMinSize(w)); + + if (orient == Qt::Horizontal && q->isRightToLeft()) + { + r.moveRight(contents.width() - r.left()); + } + + if (allowCollapse) + { + sls->collapsed = s <= 0 && minSize > 0 && !w->isHidden(); + } + + // Hide the child widget, but without calling hide() so that + // the splitter handle is still shown. + if (sls->collapsed) + { + r.moveTopLeft(QPoint(-r.width() - 1, -r.height() - 1)); + } + + w->setGeometry(r); + + if (!sls->handle->isHidden()) + { + GLDSplitterHandle *h = sls->handle; + QSize hs = h->sizeHint(); + int left, top, right, bottom; + h->getContentsMargins(&left, &top, &right, &bottom); + + if (orient == Qt::Horizontal) + { + if (q->isRightToLeft()) + { + p = contents.width() - p + hs.width(); + } + + h->setGeometry(p - hs.width() - left, contents.y(), hs.width() + left + right, contents.height()); + } + else + { + h->setGeometry(contents.x(), p - hs.height() - top, contents.width(), hs.height() + top + bottom); + } + } +} + +void GLDSplitterPrivate::doMove(bool backwards, int hPos, int index, int delta, bool mayCollapse, + int *positions, int *widths) +{ + if (index < 0 || index >= list.count()) + { + return; + } + +#ifdef GLDSPLITTER_DEBUG + qDebug() << "GLDSplitterPrivate::doMove" << backwards << hPos << index << delta << mayCollapse; +#endif + + GLDSplitterLayoutStruct *s = list.at(index); + QWidget *w = s->widget; + + int nextId = backwards ? index - delta : index + delta; + + if (w->isHidden()) + { + doMove(backwards, hPos, nextId, delta, collapsible(nextId), positions, widths); + } + else + { + int hs = s->handle->isHidden() ? 0 : s->getHandleSize(orient); + + int ws = backwards ? hPos - pick(s->rect.topLeft()) + : pick(s->rect.bottomRight()) - hPos - hs + 1; + + if (ws > 0 || (!s->collapsed && !mayCollapse)) + { + ws = qMin(ws, pick(w->maximumSize())); + ws = qMax(ws, pick(qSmartMinSize(w))); + } + else + { + ws = 0; + } + + positions[index] = backwards ? hPos - ws : hPos + hs; + widths[index] = ws; + doMove(backwards, backwards ? hPos - ws - hs : hPos + hs + ws, nextId, delta, + collapsible(nextId), positions, widths); + } + +} + +GLDSplitterLayoutStruct *GLDSplitterPrivate::findWidget(QWidget *w) const +{ + for (int i = 0; i < list.size(); ++i) + { + if (list.at(i)->widget == w) + { + return list.at(i); + } + } + + return 0; +} + + +/*! + \internal +*/ +void GLDSplitterPrivate::insertWidget_helper(int index, QWidget *widget, bool show) +{ + Q_Q(GLDSplitter); + QBoolBlocker b(blockChildAdd); + bool needShow = show && q->isVisible() && + !(widget->isHidden() && widget->testAttribute(Qt::WA_WState_ExplicitShowHide)); + + if (widget->parentWidget() != q) + { + widget->setParent(q); + } + + if (needShow) + { + widget->show(); + } + + insertWidget(index, widget); + recalc(q->isVisible()); +} + +/* + Inserts the widget \a w at position \a index in the splitter's list of widgets. + + If \a w is already in the splitter, it will be moved to the new position. +*/ + +GLDSplitterLayoutStruct *GLDSplitterPrivate::insertWidget(int index, QWidget *w) +{ + Q_Q(GLDSplitter); + GLDSplitterLayoutStruct *sls = 0; + int i; + int last = list.count(); + + for (i = 0; i < list.size(); ++i) + { + GLDSplitterLayoutStruct *s = list.at(i); + + if (s->widget == w) + { + sls = s; + --last; + break; + } + } + + if (index < 0 || index > last) + { + index = last; + } + + if (sls) + { + list.move(i, index); + } + else + { + GLDSplitterHandle *newHandle = 0; + sls = new GLDSplitterLayoutStruct; + QString tmp = QLatin1String("qt_splithandle_"); + tmp += w->objectName(); + newHandle = q->createHandle(); + newHandle->setObjectName(tmp); + sls->handle = newHandle; + sls->widget = w; + w->lower(); + list.insert(index, sls); + + if (newHandle && q->isVisible()) + { + newHandle->show(); // will trigger sending of post events + } + + } + + return sls; +} + +/*! + \class GLDSplitter + \brief The GLDSplitter class implements a splitter widget. + + \ingroup organizers + \inmodule QtWidgets + + + A splitter lets the user control the size of child widgets by dragging the + boundary between them. Any number of widgets may be controlled by a + single splitter. The typical use of a GLDSplitter is to create several + widgets and add them using insertWidget() or addWidget(). + + The following example will show a QListView, QTreeView, and + QTextEdit side by side, with two splitter handles: + + \snippet splitter/splitter.cpp 0 + + If a widget is already inside a GLDSplitter when insertWidget() or + addWidget() is called, it will move to the new position. This can be used + to reorder widgets in the splitter later. You can use indexOf(), + widget(), and count() to get access to the widgets inside the splitter. + + A default GLDSplitter lays out its children horizontally (side by side); you + can use setOrientation(Qt::Vertical) to lay its + children out vertically. + + By default, all widgets can be as large or as small as the user + wishes, between the \l minimumSizeHint() (or \l minimumSize()) + and \l maximumSize() of the widgets. + + GLDSplitter resizes its children dynamically by default. If you + would rather have GLDSplitter resize the children only at the end of + a resize operation, call setOpaqueResize(false). + + The initial distribution of size between the widgets is determined by + multiplying the initial size with the stretch factor. + You can also use setSizes() to set the sizes + of all the widgets. The function sizes() returns the sizes set by the user. + Alternatively, you can save and restore the sizes of the widgets from a + QByteArray using saveState() and restoreState() respectively. + + When you hide() a child, its space will be distributed among the + other children. It will be reinstated when you show() it again. + + \note Adding a QLayout to a GLDSplitter is not supported (either through + setLayout() or making the GLDSplitter a parent of the QLayout); use addWidget() + instead (see example above). + + \sa GLDSplitterHandle, QHBoxLayout, QVBoxLayout, QTabWidget +*/ + + +/*! + Constructs a horizontal splitter with the \a parent + argument passed on to the QFrame constructor. + + \sa setOrientation() +*/ +GLDSplitter::GLDSplitter(QWidget *parent) + : QFrame(*new GLDSplitterPrivate, parent) +{ + Q_D(GLDSplitter); + d->orient = Qt::Horizontal; + d->init(); +} + + +/*! + Constructs a splitter with the given \a orientation and \a parent. + + \sa setOrientation() +*/ +GLDSplitter::GLDSplitter(Qt::Orientation orientation, QWidget *parent) + : QFrame(*new GLDSplitterPrivate, parent) +{ + Q_D(GLDSplitter); + d->orient = orientation; + d->init(); +} + + +/*! + Destroys the splitter. All children are deleted. +*/ + +GLDSplitter::~GLDSplitter() +{ + Q_D(GLDSplitter); + delete d->rubberBand; + + while (!d->list.isEmpty()) + { + delete d->list.takeFirst(); + } +} + +/*! + Updates the splitter's state. You should not need to call this + function. +*/ +void GLDSplitter::refresh() +{ + Q_D(GLDSplitter); + d->recalc(true); +} + +/*! + \property GLDSplitter::orientation + \brief the orientation of the splitter + + By default, the orientation is horizontal (i.e., the widgets are + laid out side by side). The possible orientations are + Qt::Horizontal and Qt::Vertical. + + \sa GLDSplitterHandle::orientation() +*/ + +void GLDSplitter::setOrientation(Qt::Orientation orientation) +{ + Q_D(GLDSplitter); + + if (d->orient == orientation) + { + return; + } + + if (!testAttribute(Qt::WA_WState_OwnSizePolicy)) + { + QSizePolicy sp = sizePolicy(); + sp.transpose(); + setSizePolicy(sp); + setAttribute(Qt::WA_WState_OwnSizePolicy, false); + } + + d->orient = orientation; + + for (int i = 0; i < d->list.size(); ++i) + { + GLDSplitterLayoutStruct *s = d->list.at(i); + s->handle->setOrientation(orientation); + } + + d->recalc(isVisible()); +} + +Qt::Orientation GLDSplitter::orientation() const +{ + Q_D(const GLDSplitter); + return d->orient; +} + +/*! + \property GLDSplitter::childrenCollapsible + \brief whether child widgets can be resized down to size 0 by the user + + By default, children are collapsible. It is possible to enable + and disable the collapsing of individual children using + setCollapsible(). + + \sa setCollapsible() +*/ + +void GLDSplitter::setChildrenCollapsible(bool collapse) +{ + Q_D(GLDSplitter); + d->childrenCollapsible = collapse; +} + +bool GLDSplitter::childrenCollapsible() const +{ + Q_D(const GLDSplitter); + return d->childrenCollapsible; +} + +/*! + Sets whether the child widget at \a index is collapsible to \a collapse. + + By default, children are collapsible, meaning that the user can + resize them down to size 0, even if they have a non-zero + minimumSize() or minimumSizeHint(). This behavior can be changed + on a per-widget basis by calling this function, or globally for + all the widgets in the splitter by setting the \l + childrenCollapsible property. + + \sa childrenCollapsible +*/ + +void GLDSplitter::setCollapsible(int index, bool collapse) +{ + Q_D(GLDSplitter); + + if (index < 0 || index >= d->list.size()) + { + qWarning("GLDSplitter::setCollapsible: Index %d out of range", index); + return; + } + + d->list.at(index)->collapsible = collapse ? 1 : 0; +} + +/*! + Returns true if the widget at \a index is collapsible, otherwise returns false. +*/ +bool GLDSplitter::isCollapsible(int index) const +{ + Q_D(const GLDSplitter); + + if (index < 0 || index >= d->list.size()) + { + qWarning("GLDSplitter::isCollapsible: Index %d out of range", index); + return false; + } + + return d->list.at(index)->collapsible; +} + +/*! + \reimp +*/ +void GLDSplitter::resizeEvent(QResizeEvent *) +{ + Q_D(GLDSplitter); + d->doResize(); +} + +/*! + Adds the given \a widget to the splitter's layout after all the other + items. + + If \a widget is already in the splitter, it will be moved to the new position. + + \sa insertWidget(), widget(), indexOf() +*/ +void GLDSplitter::addWidget(QWidget *widget) +{ + Q_D(GLDSplitter); + insertWidget(d->list.count(), widget); +} + +/*! + Inserts the \a widget specified into the splitter's layout at the + given \a index. + + If \a widget is already in the splitter, it will be moved to the new position. + + if \a index is an invalid index, then the widget will be inserted at the end. + + \sa addWidget(), indexOf(), widget() +*/ +void GLDSplitter::insertWidget(int index, QWidget *widget) +{ + Q_D(GLDSplitter); + d->insertWidget_helper(index, widget, true); +} + +/*! + \fn int GLDSplitter::indexOf(QWidget *widget) const + + Returns the index in the splitter's layout of the specified \a widget. This + also works for handles. + + Handles are numbered from 0. There are as many handles as there + are child widgets, but the handle at position 0 is always hidden. + + + \sa count(), widget() +*/ +int GLDSplitter::indexOf(QWidget *w) const +{ + Q_D(const GLDSplitter); + + for (int i = 0; i < d->list.size(); ++i) + { + GLDSplitterLayoutStruct *s = d->list.at(i); + + if (s->widget == w || s->handle == w) + { + return i; + } + } + + return -1; +} + +/*! + Returns the widget at the given \a index in the splitter's layout. + + \sa count(), handle(), indexOf(), insertWidget() +*/ +QWidget *GLDSplitter::widget(int index) const +{ + Q_D(const GLDSplitter); + + if (index < 0 || index >= d->list.size()) + { + return 0; + } + + return d->list.at(index)->widget; +} + +/*! + Returns the number of widgets contained in the splitter's layout. + + \sa widget(), handle() +*/ +int GLDSplitter::count() const +{ + Q_D(const GLDSplitter); + return d->list.count(); +} + +/*! + \reimp + + Tells the splitter that the child widget described by \a c has been + inserted or removed. + + This method is also used to handle the situation where a widget is created + with the splitter as a parent but not explicitly added with insertWidget() + or addWidget(). This is for compatibility and not the recommended way of + putting widgets into a splitter in new code. Please use insertWidget() or + addWidget() in new code. + + \sa addWidget(), insertWidget() +*/ + +void GLDSplitter::childEvent(QChildEvent *c) +{ + Q_D(GLDSplitter); + + if (!c->child()->isWidgetType()) + { + if (c->type() == QEvent::ChildAdded && dynamic_cast(c->child())) + { + qWarning("Adding a QLayout to a GLDSplitter is not supported."); + } + + return; + } + + QWidget *w = static_cast(c->child()); + + if (c->added() && !d->blockChildAdd && !w->isWindow() && !d->findWidget(w)) + { + d->insertWidget_helper(d->list.count(), w, false); + } + else if (c->polished() && !d->blockChildAdd) + { + if (isVisible() && !(w->isHidden() && w->testAttribute(Qt::WA_WState_ExplicitShowHide))) + { + w->show(); + } + } + else if (c->type() == QEvent::ChildRemoved) + { + for (int i = 0; i < d->list.size(); ++i) + { + GLDSplitterLayoutStruct *s = d->list.at(i); + + if (s->widget == w) + { + d->list.removeAt(i); + delete s; + d->recalc(isVisible()); + return; + } + } + } +} + + +/*! + Displays a rubber band at position \a pos. If \a pos is negative, the + rubber band is removed. +*/ + +void GLDSplitter::setRubberBand(int pos) +{ + Q_D(GLDSplitter); + + if (pos < 0) + { + if (d->rubberBand) + { + d->rubberBand->deleteLater(); + } + + return; + } + + QRect r = contentsRect(); + const int rBord = 3; // customizable? + int hw = handleWidth(); + + if (!d->rubberBand) + { + QBoolBlocker b(d->blockChildAdd); + d->rubberBand = new QRubberBand(QRubberBand::Line, this); + // For accessibility to identify this special widget. + d->rubberBand->setObjectName(QLatin1String("qt_rubberband")); + } + + const QRect newGeom = d->orient == Qt::Horizontal ? QRect(QPoint(pos + hw / 2 - rBord, r.y()), QSize(2 * rBord, r.height())) + : QRect(QPoint(r.x(), pos + hw / 2 - rBord), QSize(r.width(), 2 * rBord)); + d->rubberBand->setGeometry(newGeom); + d->rubberBand->show(); +} + +/*! + \reimp +*/ + +bool GLDSplitter::event(QEvent *e) +{ + Q_D(GLDSplitter); + + switch (e->type()) + { + case QEvent::Hide: + + // Reset firstShow to false here since things can be done to the splitter in between + if (!d->firstShow) + { + d->firstShow = true; + } + + break; + + case QEvent::Show: + if (!d->firstShow) + { + break; + } + + d->firstShow = false; + + // fall through + case QEvent::HideToParent: + case QEvent::ShowToParent: + case QEvent::LayoutRequest: + d->recalc(isVisible()); + break; + + default: + ; + } + + return QWidget::event(e); +} + +/*! + \fn GLDSplitter::splitterMoved(int pos, int index) + + This signal is emitted when the splitter handle at a particular \a + index has been moved to position \a pos. + + For right-to-left languages such as Arabic and Hebrew, the layout + of horizontal splitters is reversed. \a pos is then the + distance from the right edge of the widget. + + \sa moveSplitter() +*/ + +/*! + Moves the left or top edge of the splitter handle at \a index as + close as possible to position \a pos, which is the distance from the + left or top edge of the widget. + + For right-to-left languages such as Arabic and Hebrew, the layout + of horizontal splitters is reversed. \a pos is then the distance + from the right edge of the widget. + + \sa splitterMoved(), closestLegalPosition(), getRange() +*/ +void GLDSplitter::moveSplitter(int pos, int index) +{ + Q_D(GLDSplitter); + GLDSplitterLayoutStruct *s = d->list.at(index); + int farMin; + int min; + int max; + int farMax; + int adjustedPos; + +#ifdef GLDSPLITTER_DEBUG + int debugp = pos; +#endif + + pos = adjustedPos = d->adjustPos(pos, index, &farMin, &min, &max, &farMax); + +#ifdef GLDSPLITTER_DEBUG + qDebug() << "GLDSplitter::moveSplitter" + << "" + << "" + << "" + << ""; +#endif + + int oldP = d->pick(s->rect.topLeft()); + +#ifdef GLDSPLITTER_DEBUG + qDebug() << "GLDSplitter::moveSplitter" << debugp << index << "adjusted" << pos << "oldP" << oldP; +#endif + + QVarLengthArray poss(d->list.count()); + QVarLengthArray ws(d->list.count()); + bool upLeft; + + if(d->collapsedLength != -1) + { + if(d->collapsedLength > adjustedPos) + { + adjustedPos = farMin; + } + + if(d->collapsedLength > farMax - adjustedPos) + { + adjustedPos = farMax; + } + } + + d->doMove(false, adjustedPos, index, +1, (d->collapsible(s) && (adjustedPos > max)), poss.data(), ws.data()); + d->doMove(true, adjustedPos, index - 1, +1, (d->collapsible(index - 1) && (adjustedPos < min)), poss.data(), ws.data()); + upLeft = (adjustedPos < oldP); + + int wid, delta, count = d->list.count(); + + if (upLeft) + { + wid = 0; + delta = 1; + } + else + { + wid = count - 1; + delta = -1; + } + +#ifdef GLDSPLITTER_DEBUG + qDebug() << "GLDSplitter::moveSplitter" << pos << index << endl; +#endif + + for (; wid >= 0 && wid < count; wid += delta) + { + GLDSplitterLayoutStruct *sls = d->list.at(wid); + + if (!sls->widget->isHidden()) + { + d->setGeo(sls, poss[wid], ws[wid], true); +#ifdef GLDSPLITTER_DEBUG + qDebug() << "GLDSplitter::moveSplitter...setGeo" << (int)poss[wid] << (int)ws[wid]; +#endif + } + } + + d->storeSizes(); + + emit splitterMoved(pos, index); +} + + +/*! + Returns the valid range of the splitter at \a index in + *\a{min} and *\a{max} if \a min and \a max are not 0. +*/ + +void GLDSplitter::getRange(int index, int *min, int *max) const +{ + Q_D(const GLDSplitter); + d->getRange(index, min, 0, 0, max); +} + + +/*! + Returns the closest legal position to \a pos of the widget at \a index. + + For right-to-left languages such as Arabic and Hebrew, the layout + of horizontal splitters is reversed. Positions are then measured + from the right edge of the widget. + + \sa getRange() +*/ + +int GLDSplitter::closestLegalPosition(int pos, int index) +{ + Q_D(GLDSplitter); + int x, i, n, u; + return d->adjustPos(pos, index, &u, &n, &i, &x); +} + +/*! + \property GLDSplitter::opaqueResize + \brief whether resizing is opaque + + Opaque resizing is on by default. +*/ + +bool GLDSplitter::opaqueResize() const +{ + Q_D(const GLDSplitter); + return d->opaque; +} + + +void GLDSplitter::setOpaqueResize(bool on) +{ + Q_D(GLDSplitter); + d->opaque = on; +} + + +/*! + \reimp +*/ +QSize GLDSplitter::sizeHint() const +{ + Q_D(const GLDSplitter); + ensurePolished(); + int l = 0; + int t = 0; + + for (int i = 0; i < d->list.size(); ++i) + { + QWidget *w = d->list.at(i)->widget; + + if (w->isHidden()) + { + continue; + } + + QSize s = w->sizeHint(); + + if (s.isValid()) + { + l += d->pick(s); + t = qMax(t, d->trans(s)); + } + } + + return orientation() == Qt::Horizontal ? QSize(l, t) : QSize(t, l); +} + + +/*! + \reimp +*/ + +QSize GLDSplitter::minimumSizeHint() const +{ + Q_D(const GLDSplitter); + ensurePolished(); + int l = 0; + int t = 0; + + for (int i = 0; i < d->list.size(); ++i) + { + GLDSplitterLayoutStruct *s = d->list.at(i); + + if (!s || !s->widget) + { + continue; + } + + if (s->widget->isHidden()) + { + continue; + } + + QSize widgetSize = qSmartMinSize(s->widget); + + if (widgetSize.isValid()) + { + l += d->pick(widgetSize); + t = qMax(t, d->trans(widgetSize)); + } + + if (!s->handle || s->handle->isHidden()) + { + continue; + } + + QSize splitterSize = s->handle->sizeHint(); + + if (splitterSize.isValid()) + { + l += d->pick(splitterSize); + t = qMax(t, d->trans(splitterSize)); + } + } + + return orientation() == Qt::Horizontal ? QSize(l, t) : QSize(t, l); +} + + +/*! + Returns a list of the size parameters of all the widgets in this splitter. + + If the splitter's orientation is horizontal, the list contains the + widgets width in pixels, from left to right; if the orientation is + vertical, the list contains the widgets' heights in pixels, + from top to bottom. + + Giving the values to another splitter's setSizes() function will + produce a splitter with the same layout as this one. + + Note that invisible widgets have a size of 0. + + \sa setSizes() +*/ + +QList GLDSplitter::sizes() const +{ + Q_D(const GLDSplitter); + ensurePolished(); + + QList list; + + for (int i = 0; i < d->list.size(); ++i) + { + GLDSplitterLayoutStruct *s = d->list.at(i); + list.append(d->pick(s->rect.size())); + } + + return list; +} + +/*! + Sets the child widgets' respective sizes to the values given in the \a list. + + If the splitter is horizontal, the values set the width of each + widget in pixels, from left to right. If the splitter is vertical, the + height of each widget is set, from top to bottom. + + Extra values in the \a list are ignored. If \a list contains too few + values, the result is undefined, but the program will still be well-behaved. + + The overall size of the splitter widget is not affected. + Instead, any additional/missing space is distributed amongst the + widgets according to the relative weight of the sizes. + + If you specify a size of 0, the widget will be invisible. The size policies + of the widgets are preserved. That is, a value smaller than the minimal size + hint of the respective widget will be replaced by the value of the hint. + + \sa sizes() +*/ + +void GLDSplitter::setSizes(const QList &list) +{ + Q_D(GLDSplitter); + d->setSizes_helper(list, true); +} + +/*! + \property GLDSplitter::handleWidth + \brief the width of the splitter handles + + By default, this property contains a value that depends on the user's platform + and style preferences. + + If you set handleWidth to 1 or 0, the actual grab area will grow to overlap a + few pixels of its respective widgets. +*/ + +int GLDSplitter::handleWidth() const +{ + Q_D(const GLDSplitter); + + if (d->handleWidth >= 0) + { + return d->handleWidth; + } + else + { + return style()->pixelMetric(QStyle::PM_SplitterWidth, 0, this); + } +} + +void GLDSplitter::setHandleWidth(int width) +{ + Q_D(GLDSplitter); + + d->handleWidth = width; + d->updateHandles(); +} + +int GLDSplitter::collapsedLength() const +{ + Q_D(const GLDSplitter); + + if (d->collapsedLength >= 0) + { + return d->collapsedLength; + } + else + { + return 0; + } +} + +void GLDSplitter::setCollapsedLength(int length) +{ + Q_D(GLDSplitter); + + d->collapsedLength = length; +} + +/*! + \reimp +*/ +void GLDSplitter::changeEvent(QEvent *ev) +{ + Q_D(GLDSplitter); + + if (ev->type() == QEvent::StyleChange) + { + d->updateHandles(); + } + + QFrame::changeEvent(ev); +} + +static const qint32 SplitterMagic = 0xff; + +/*! + Saves the state of the splitter's layout. + + Typically this is used in conjunction with QSettings to remember the size + for a future session. A version number is stored as part of the data. + Here is an example: + + \snippet splitter/splitter.cpp 1 + + \sa restoreState() +*/ +QByteArray GLDSplitter::saveState() const +{ + Q_D(const GLDSplitter); + int version = 0; + QByteArray data; + QDataStream stream(&data, QIODevice::WriteOnly); + + stream << qint32(SplitterMagic); + stream << qint32(version); + QList list; + + for (int i = 0; i < d->list.size(); ++i) + { + GLDSplitterLayoutStruct *s = d->list.at(i); + list.append(s->sizer); + } + + stream << list; + stream << childrenCollapsible(); + stream << qint32(handleWidth()); + stream << opaqueResize(); + stream << qint32(orientation()); + return data; +} + +/*! + Restores the splitter's layout to the \a state specified. + Returns true if the state is restored; otherwise returns false. + + Typically this is used in conjunction with QSettings to restore the size + from a past session. Here is an example: + + Restore the splitter's state: + + \snippet splitter/splitter.cpp 2 + + A failure to restore the splitter's layout may result from either + invalid or out-of-date data in the supplied byte array. + + \sa saveState() +*/ +bool GLDSplitter::restoreState(const QByteArray &state) +{ + Q_D(GLDSplitter); + int version = 0; + QByteArray sd = state; + QDataStream stream(&sd, QIODevice::ReadOnly); + QList list; + bool b; + qint32 i; + qint32 marker; + qint32 v; + + stream >> marker; + stream >> v; + + if (marker != SplitterMagic || v != version) + { + return false; + } + + stream >> list; + d->setSizes_helper(list, false); + + stream >> b; + setChildrenCollapsible(b); + + stream >> i; + setHandleWidth(i); + + stream >> b; + setOpaqueResize(b); + + stream >> i; + setOrientation(Qt::Orientation(i)); + d->doResize(); + + return true; +} + +/*! + Updates the size policy of the widget at position \a index to + have a stretch factor of \a stretch. + + \a stretch is not the effective stretch factor; the effective + stretch factor is calculated by taking the initial size of the + widget and multiplying it with \a stretch. + + This function is provided for convenience. It is equivalent to + + \snippet code/src_gui_widgets_qsplitter.cpp 0 + + \sa setSizes(), widget() +*/ +void GLDSplitter::setStretchFactor(int index, int stretch) +{ + Q_D(GLDSplitter); + + if (index <= -1 || index >= d->list.count()) + { + return; + } + + QWidget *widget = d->list.at(index)->widget; + QSizePolicy sp = widget->sizePolicy(); + sp.setHorizontalStretch(stretch); + sp.setVerticalStretch(stretch); + widget->setSizePolicy(sp); +} + +/*! + \relates GLDSplitter + \obsolete + + Use \a ts << \a{splitter}.saveState() instead. +*/ + +QTextStream &operator<<(QTextStream &ts, const GLDSplitter &splitter) +{ + ts << splitter.saveState() << endl; + return ts; +} + +/*! + \relates GLDSplitter + \obsolete + + Use \a ts >> \a{splitter}.restoreState() instead. +*/ + +QTextStream &operator>>(QTextStream &ts, GLDSplitter &splitter) +{ + QString line = ts.readLine(); + line = line.simplified(); + line.replace(QLatin1Char(' '), QString()); + line = line.toUpper(); + + splitter.restoreState(line.toLatin1()); + return ts; +} + +//G_GLODON_END_NAMESPACE + +#endif // QT_NO_SPLITTER diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDSplitterHandle.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDSplitterHandle.cpp new file mode 100644 index 00000000..1d57500c --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDSplitterHandle.cpp @@ -0,0 +1,274 @@ +#include + +#include "GLDSplitter.h" +#include "GLDSplitter_p.h" +#include "GLDSplitterHandle.h" + +GLDSplitterHandle::GLDSplitterHandle(Qt::Orientation orientation, GLDSplitter *parent) + : QWidget(*new GLDSplitterHandlePrivate, parent, 0) +{ + Q_D(GLDSplitterHandle); + d->s = parent; + setOrientation(orientation); +} + +/*! + Destructor. +*/ +GLDSplitterHandle::~GLDSplitterHandle() +{ +} + +/*! + Sets the orientation of the splitter handle to \a orientation. + This is usually propagated from the GLDSplitter. + + \sa GLDSplitter::setOrientation() +*/ +void GLDSplitterHandle::setOrientation(Qt::Orientation orientation) +{ + Q_D(GLDSplitterHandle); + d->orient = orientation; +#ifndef QT_NO_CURSOR + setCursor(orientation == Qt::Horizontal ? Qt::SplitHCursor : Qt::SplitVCursor); +#endif +} + +/*! + Returns the handle's orientation. This is usually propagated from the GLDSplitter. + + \sa GLDSplitter::orientation() +*/ +Qt::Orientation GLDSplitterHandle::orientation() const +{ + Q_D(const GLDSplitterHandle); + return d->orient; +} + + +/*! + Returns true if widgets are resized dynamically (opaquely), otherwise + returns false. This value is controlled by the GLDSplitter. + + \sa GLDSplitter::opaqueResize() + +*/ +bool GLDSplitterHandle::opaqueResize() const +{ + Q_D(const GLDSplitterHandle); + return d->s->opaqueResize(); +} + + +/*! + Returns the splitter associated with this splitter handle. + + \sa GLDSplitter::handle() +*/ +GLDSplitter *GLDSplitterHandle::splitter() const +{ + return d_func()->s; +} + +/*! + Tells the splitter to move this handle to position \a pos, which is + the distance from the left or top edge of the widget. + + Note that \a pos is also measured from the left (or top) for + right-to-left languages. This function will map \a pos to the + appropriate position before calling GLDSplitter::moveSplitter(). + + \sa GLDSplitter::moveSplitter(), closestLegalPosition() +*/ +void GLDSplitterHandle::moveSplitter(int pos) +{ + Q_D(GLDSplitterHandle); + if (d->s->isRightToLeft() && d->orient == Qt::Horizontal) + pos = d->s->contentsRect().width() - pos; + d->s->moveSplitter(pos, d->s->indexOf(this)); +} + +/*! + Returns the closest legal position to \a pos of the splitter + handle. The positions are measured from the left or top edge of + the splitter, even for right-to-left languages. + + \sa GLDSplitter::closestLegalPosition(), moveSplitter() +*/ + +int GLDSplitterHandle::closestLegalPosition(int pos) +{ + Q_D(GLDSplitterHandle); + GLDSplitter *s = d->s; + if (s->isRightToLeft() && d->orient == Qt::Horizontal) { + int w = s->contentsRect().width(); + return w - s->closestLegalPosition(w - pos, s->indexOf(this)); + } + return s->closestLegalPosition(pos, s->indexOf(this)); +} + +/*! + \reimp +*/ +QSize GLDSplitterHandle::sizeHint() const +{ + Q_D(const GLDSplitterHandle); + int hw = d->s->handleWidth(); + QStyleOption opt(0); + opt.init(d->s); + opt.state = QStyle::State_None; + return parentWidget()->style()->sizeFromContents(QStyle::CT_Splitter, &opt, QSize(hw, hw), d->s) + .expandedTo(QApplication::globalStrut()); +} + +/*! + \reimp +*/ +void GLDSplitterHandle::resizeEvent(QResizeEvent *event) +{ + Q_D(const GLDSplitterHandle); + + // When splitters are only 1 or 0 pixel large we increase the + // actual grab area to five pixels + + // Note that GLDSplitter uses contentsRect for layouting + // and ensures that handles are drawn on top of widgets + // We simply use the contents margins for draggin and only + // paint the mask area + bool useTinyMode = (d->s->handleWidth() <= 1); + setAttribute(Qt::WA_MouseNoMask, useTinyMode); + if (useTinyMode) { + if (orientation() == Qt::Horizontal) + setContentsMargins(2, 0, 2, 0); + else + setContentsMargins(0, 2, 0, 2); + setMask(QRegion(contentsRect())); + } + + QWidget::resizeEvent(event); +} + +/*! + \reimp +*/ +bool GLDSplitterHandle::event(QEvent *event) +{ + Q_D(GLDSplitterHandle); + switch(event->type()) { + case QEvent::HoverEnter: + d->hover = true; + update(); + break; + case QEvent::HoverLeave: + d->hover = false; + update(); + break; + default: + break; + } + return QWidget::event(event); +} + +/*! + \reimp +*/ +void GLDSplitterHandle::mouseMoveEvent(QMouseEvent *e) +{ + Q_D(GLDSplitterHandle); + if (!(e->buttons() & Qt::LeftButton)) + return; + int pos = d->pick(parentWidget()->mapFromGlobal(e->globalPos())) + - d->mouseOffset; + if (opaqueResize()) { + moveSplitter(pos); + } else { + d->s->setRubberBand(closestLegalPosition(pos)); + } +} + +/*! + \reimp +*/ +void GLDSplitterHandle::mousePressEvent(QMouseEvent *e) +{ + Q_D(GLDSplitterHandle); + if (e->button() == Qt::LeftButton) { + d->mouseOffset = d->pick(e->pos()); + d->pressed = true; + update(); + } +} + +/*! + \reimp +*/ +void GLDSplitterHandle::mouseReleaseEvent(QMouseEvent *e) +{ + Q_D(GLDSplitterHandle); + if (!opaqueResize() && e->button() == Qt::LeftButton) { + int pos = d->pick(parentWidget()->mapFromGlobal(e->globalPos())) + - d->mouseOffset; + d->s->setRubberBand(-1); + moveSplitter(pos); + } + if (e->button() == Qt::LeftButton) { + d->pressed = false; + update(); + } +} + +/*! + \reimp +*/ +void GLDSplitterHandle::paintEvent(QPaintEvent *) +{ + Q_D(GLDSplitterHandle); + QPainter p(this); + QStyleOption opt(0); + opt.rect = contentsRect(); + opt.palette = palette(); + if (orientation() == Qt::Horizontal) + opt.state = QStyle::State_Horizontal; + else + opt.state = QStyle::State_None; + if (d->hover) + opt.state |= QStyle::State_MouseOver; + if (d->pressed) + opt.state |= QStyle::State_Sunken; + if (isEnabled()) + opt.state |= QStyle::State_Enabled; + parentWidget()->style()->drawControl(QStyle::CE_Splitter, &opt, &p, d->s); +} + +/*! + Returns a new splitter handle as a child widget of this splitter. + This function can be reimplemented in subclasses to provide support + for custom handles. + + \sa handle(), indexOf() +*/ +GLDSplitterHandle *GLDSplitter::createHandle() +{ + Q_D(GLDSplitter); + return new GLDSplitterHandle(d->orient, this); +} + +/*! + Returns the handle to the left (or above) for the item in the + splitter's layout at the given \a index. The handle at index 0 is + always hidden. + + For right-to-left languages such as Arabic and Hebrew, the layout + of horizontal splitters is reversed. The handle will be to the + right of the widget at \a index. + + \sa count(), widget(), indexOf(), createHandle(), setHandleWidth() +*/ +GLDSplitterHandle *GLDSplitter::handle(int index) const +{ + Q_D(const GLDSplitter); + if (index < 0 || index >= d->list.size()) + return 0; + return d->list.at(index)->handle; +} + diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDStylePaintUtils.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDStylePaintUtils.cpp new file mode 100644 index 00000000..05ba6415 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDStylePaintUtils.cpp @@ -0,0 +1,55 @@ +#include +#include +#include +#include +#include +#include "GLDEllipsis.h" +#include "GLDStylePaintUtils.h" + +void GLDStylePaintUtils::initComboBoxOpt(QStyleOptionComboBox &opt, const QRect &rect) +{ + QStyleOptionComboBox optTmp; + + opt.editable = true; + opt.frame = optTmp.frame; + opt.subControls = (QStyle::SubControls)5;//opt.subControls; + opt.activeSubControls = optTmp.activeSubControls; + opt.state = optTmp.state; + opt.state |= QStyle::State_Enabled; + opt.rect = rect; +} + +void GLDStylePaintUtils::initPushButtonOpt(QStyleOptionButton &opt, const QRect &rect, const QString &btnText) +{ + static QPushButton s_btn; + QPushButton *pBtn = &s_btn; + { + opt.initFrom(pBtn); + opt.features = QStyleOptionButton::None; + opt.text = btnText; + opt.fontMetrics = s_btn.fontMetrics(); + opt.direction = Qt::LeftToRight; + } + QRect hostRect = rect; + int nTargetBtnWidth = qMax(c_MinButtonEditBtnWidth, opt.fontMetrics.width(" ...")); + opt.rect = QRect(hostRect.right() - nTargetBtnWidth + 1, + hostRect.top() - 1, nTargetBtnWidth, hostRect.height() + 2); + opt.state |= QStyle::State_Enabled; +} + +void GLDStylePaintUtils::initSpinBoxOpt(QStyleOptionSpinBox &opt, const QRect &rect) +{ + static QSpinBox s_pinBox; + QWidget *target = &s_pinBox; + opt.initFrom(target); + opt.activeSubControls = QStyle::SC_SpinBoxUp | QStyle::SC_SpinBoxDown; + opt.subControls |= QStyle::SC_SpinBoxUp | QStyle::SC_SpinBoxDown; + opt.state |= QStyle::State_Enabled; + opt.stepEnabled = QAbstractSpinBox::StepDownEnabled | QAbstractSpinBox::StepUpEnabled; + opt.frame = false;//target->frameSize() + opt.rect = rect; +} + +GLDStylePaintUtils::GLDStylePaintUtils() +{ +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDTabDockContainer.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDTabDockContainer.cpp new file mode 100644 index 00000000..21e9ce56 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDTabDockContainer.cpp @@ -0,0 +1,942 @@ +#include "GLDTabDockContainer.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "GLDUIUtils.h" +#include "GLDException.h" +#include "GLDWidget_Global.h" +////////////////////////////////////////////////////////////////////////// + +GLDTabDockContainerTitleWidget::GLDTabDockContainerTitleWidget(QWidget *parent) + : QWidget(parent) + , m_dockerWidget(NULL) +{ + m_toolBar = new QToolBar(this); + m_title = new QLabel(this); + m_anchorButton = new GLDTabDockContainerWidgetAnchorButton(this); + m_layout = new QHBoxLayout(this); + m_toolBar->setToolButtonStyle(Qt::ToolButtonIconOnly); + m_toolBar->setFixedHeight(25); + m_userToolBar = new QToolBar(this); + + m_title->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); + + m_toolBar->addWidget(m_anchorButton); + + m_layout->setMargin(2); + m_layout->setContentsMargins(5, 0, 0, 0); + m_layout->addWidget(m_title); + m_layout->addStretch(); + m_layout->addWidget(m_userToolBar); + m_layout->addWidget(m_toolBar); + + + setLayout(m_layout); +} + +void GLDTabDockContainerTitleWidget::mouseMoveEvent(QMouseEvent *event) +{ + if (m_dockerWidget == NULL) + { + GLDTabDockContainerWidget *widget = qobject_cast(parent()); + + if (widget != NULL) + { + m_dockerWidget = widget; + } + } + + if (m_dockerWidget != NULL) + { + if (!m_dockerWidget->isAnchored()) + { + event->accept(); + return; + } + } + + event->ignore(); +} + +void GLDTabDockContainerTitleWidget::setDockWidget(GLDTabDockContainerWidget *dockerWidget) +{ + m_dockerWidget = dockerWidget; +} + +GLDTabDockContainerWidgetAnchorButton *GLDTabDockContainerTitleWidget::addAnchorButton() +{ + GLDTabDockContainerWidgetAnchorButton *anchorButton = new GLDTabDockContainerWidgetAnchorButton(this); + anchorButton->setFixedSize(QSize(15, 15)); + m_userToolBar->setMinimumWidth(m_userToolBar->minimumWidth() + 22); + m_action = m_userToolBar->insertWidget(m_action, anchorButton); + + return anchorButton; +} + +QToolBar *GLDTabDockContainerTitleWidget::toolBar() +{ + return m_userToolBar; +} + +////////////////////////////////////////////////////////////////////////// +//GLDTabDockContainerWidget +GLDTabDockContainerWidget::GLDTabDockContainerWidget(const QString &title, QWidget *parent /*= 0*/) + : QDockWidget(title, parent) + , m_anchordIcon(":/icons/TabDockContainerAnchor.png") + , m_notAnchoredIcon(":/icons/TabDockContainerNotAnchor.png") + , m_currentAnchoredState(true) + , m_floatable(true) + , m_closable(false) + , m_autoFillHeight(true) + , m_anchoredToolTip(getGLDi18nStr(g_rsAutoHide)) + , m_notAnchoredToolTip(getGLDi18nStr(g_rsLocked)) + , m_timerID(0) + , m_bisEntered(false) + , m_bisHide(false) + , m_bisFloating(false) + , m_interval(500) +{ + m_titleWidget = new GLDTabDockContainerTitleWidget(this); + m_titleWidget->m_anchorButton->setIconSize(QSize(15, 15)); + m_titleWidget->m_anchorButton->setFixedSize(QSize(15, 15)); + m_titleWidget->m_anchorButton->setIcon(m_anchordIcon); + m_titleWidget->m_anchorButton->setToolTip(m_currentAnchoredState ? m_anchoredToolTip : m_notAnchoredToolTip); + setTitle(title); + setTitleBarWidget(m_titleWidget); + updateFloatAndCloseState(); + connect(m_titleWidget->m_anchorButton, SIGNAL(clicked()), this, SLOT(anchorButtonClicked())); +} + +GLDTabDockContainerWidget::GLDTabDockContainerWidget(QWidget *parent /*= 0*/) + : QDockWidget(parent) + , m_anchordIcon(":/icons/TabDockContainerAnchor.png") + , m_notAnchoredIcon(":/icons/TabDockContainerNotAnchor.png") + , m_currentAnchoredState(true) + , m_floatable(true) + , m_closable(false) + , m_autoFillHeight(true) + , m_anchoredToolTip(getGLDi18nStr(g_rsAutoHide)) + , m_notAnchoredToolTip(getGLDi18nStr(g_rsLocked)) + , m_timerID(0) + , m_bisEntered(false) + , m_bisHide(false) + , m_bisFloating(false) + , m_interval(500) +{ + m_titleWidget = new GLDTabDockContainerTitleWidget(this); + m_titleWidget->m_anchorButton->setIconSize(QSize(15, 15)); + m_titleWidget->m_anchorButton->setFixedSize(QSize(15, 15)); + m_titleWidget->m_anchorButton->setIcon(m_anchordIcon); + m_titleWidget->m_anchorButton->setToolTip(m_currentAnchoredState ? m_anchoredToolTip : m_notAnchoredToolTip); + setTitleBarWidget(m_titleWidget); + updateFloatAndCloseState(); + connect(m_titleWidget->m_anchorButton, SIGNAL(clicked()), this, SLOT(anchorButtonClicked())); +} + +QToolBar *GLDTabDockContainerWidget::titleToolBar() +{ + return m_titleWidget->toolBar(); +} + +void GLDTabDockContainerWidget::setFloatable(bool floatable) +{ + m_floatable = floatable; + updateFloatAndCloseState(); +} + +bool GLDTabDockContainerWidget::isFloatable() const +{ + return m_floatable; +} + +void GLDTabDockContainerWidget::setAnchoredIcon(const QIcon &anchoredIcon) +{ + m_anchordIcon = anchoredIcon; + updateFloatAndCloseState(); +} + +void GLDTabDockContainerWidget::setNotAnchoredIcon(const QIcon ¬AnchoredIcon) +{ + m_notAnchoredIcon = notAnchoredIcon; + updateFloatAndCloseState(); +} + +QIcon GLDTabDockContainerWidget::anchoredIcon() const +{ + return m_anchordIcon; +} + +QIcon GLDTabDockContainerWidget::notAnchoredIcon() const +{ + return m_notAnchoredIcon; +} + +void GLDTabDockContainerWidget::showWidget() +{ + if (m_currentAnchoredState) + { + show(); + } +} + +void GLDTabDockContainerWidget::hideWidget() +{ + if (m_currentAnchoredState) + { + hide(); + } +} + +bool GLDTabDockContainerWidget::isAnchored() const +{ + return m_currentAnchoredState; +} + +void GLDTabDockContainerWidget::setAnchorToolTip(const QString &anchoredToolTip, const QString ¬AnchoredToolTip) +{ + m_anchoredToolTip = anchoredToolTip; + m_notAnchoredToolTip = notAnchoredToolTip; +} + +void GLDTabDockContainerWidget::anchorToolTip(QString &anchoredToolTip, QString ¬AnchoredToolTip) const +{ + anchoredToolTip = m_anchoredToolTip; + notAnchoredToolTip = m_notAnchoredToolTip; +} + +void GLDTabDockContainerWidget::setAnchored(bool anchored) +{ + m_currentAnchoredState = anchored; + + if (m_currentAnchoredState) + { + m_titleWidget->m_anchorButton->setIcon(m_anchordIcon); + m_titleWidget->m_anchorButton->setToolTip(m_anchoredToolTip); + } + else + { + m_titleWidget->m_anchorButton->setIcon(m_notAnchoredIcon); + m_titleWidget->m_anchorButton->setToolTip(m_notAnchoredToolTip); + } + + m_bisFloating = !m_currentAnchoredState; + emit anchorChanged(m_currentAnchoredState); + m_bisFloating = m_currentAnchoredState; + +} + +void GLDTabDockContainerWidget::pauseTimer() +{ + killTimer(m_timerID); +} + +void GLDTabDockContainerWidget::resumeTimer() +{ + m_timerID = startTimer(m_interval); +} + +void GLDTabDockContainerWidget::anchorButtonClicked() +{ + setAnchored(!m_currentAnchoredState); +} + +void GLDTabDockContainerWidget::leaveHide() +{ + hide(); +} + +void GLDTabDockContainerWidget::setLeaved(bool isLeaved) +{ + m_bisHide = isLeaved; +} + +void GLDTabDockContainerWidget::updateFloatAndCloseState() +{ + if (m_closable) + { + setFeatures(features() | QDockWidget::DockWidgetClosable); + } + else + { + setFeatures(features() & ~QDockWidget::DockWidgetClosable); + } + + if (m_floatable) + { + setFeatures(features() | QDockWidget::DockWidgetFloatable); + } + else + { + setFeatures(features() & ~QDockWidget::DockWidgetFloatable); + } +} + +void GLDTabDockContainerWidget::enterEvent(QEvent *) +{ + m_bisEntered = true; + + if (m_timerID != 0) + { + killTimer(m_timerID); + m_timerID = 0; + } + + if (m_bisHide) + { + emit setHideAndEntered(m_bisHide, m_bisEntered); + m_bisEntered = false; + } +} + +void GLDTabDockContainerWidget::leaveEvent(QEvent *) +{ + if (!m_currentAnchoredState) + { + if (m_timerID != 0) + { + killTimer(m_timerID); + m_timerID = 0; + } + + if (!m_bisFloating) + { + m_timerID = startTimer(m_interval); + } + } +} + +void GLDTabDockContainerWidget::setTimerInterval(int interval) +{ + m_interval = interval; +} + +int GLDTabDockContainerWidget::timerInterval() +{ + return m_interval; +} + +void GLDTabDockContainerWidget::timerEvent(QTimerEvent *e) +{ + if (!m_currentAnchoredState) + { + if (e->timerId() == m_timerID) + { + QPoint mousePoint = QCursor::pos(); + + mousePoint = mapFromGlobal(mousePoint); + + if (!rect().contains(mousePoint)) + { + hide(); + killTimer(m_timerID); + m_timerID = 0; + } + } + } +} + +void GLDTabDockContainerWidget::setAutoFillHeight(bool autoHeight) +{ + m_autoFillHeight = autoHeight; +} + +bool GLDTabDockContainerWidget::isAutoFillHeight() const +{ + return m_autoFillHeight; +} + +void GLDTabDockContainerWidget::setTitle(const QString &title) +{ + m_titleWidget->m_title->setText(title); +} + +QString GLDTabDockContainerWidget::title() const +{ + return m_titleWidget->m_title->text(); +} + +GLDTabDockContainerTabBar::GLDTabDockContainerTabBar(QWidget *parent) + : QTabBar(parent), m_curIndex(-1), m_textOrientation(Qt::Horizontal), m_timerID(0) + , m_bisHide(false), m_bisEntered(false), m_interval(500) +{ + setMouseTracking(true); +} + +void GLDTabDockContainerTabBar::mouseMoveEvent(QMouseEvent *event) +{ + QPoint pt = event->pos(); + int ndx = tabAt(pt); + m_preIndex = m_curIndex; + + if (ndx != m_curIndex) + { + m_curIndex = ndx; + + if (m_curIndex != -1) + { + setCurrentIndex(m_curIndex); + } + } + + emit tabChanged(m_curIndex, m_preIndex); +} + +void GLDTabDockContainerTabBar::leaveEvent(QEvent *) +{ + m_bisHide = true; + + if (m_timerID != 0) + { + killTimer(m_timerID); + } + + m_timerID = startTimer(m_interval); + emit setLeaved(m_bisHide); +} + +void GLDTabDockContainerTabBar::setTimerInterval(int interval) +{ + m_interval = interval; +} + +void GLDTabDockContainerTabBar::timerEvent(QTimerEvent *e) +{ + if (e->timerId() == m_timerID) + { + if (true == m_bisHide && false == m_bisEntered) + { + emit tabLeave(); + } + + killTimer(m_timerID); + m_timerID = 0; + m_bisHide = false; + m_bisEntered = false; + } +} + +void GLDTabDockContainerTabBar::setHideAndEntered(bool isHide, bool isEntered) +{ + m_bisHide = isHide; + m_bisEntered = isEntered; +} + +static QString verticalString(const QString &str) +{ + QChar buffer[255]; + int nChar = 0; + + for (int i = 0; i < str.count(); ++i) + { + buffer[nChar] = str[i]; + buffer[++nChar] = '\n'; + ++nChar; + } + + if (nChar > 0) + { + buffer[nChar - 1] = '\0'; + } + + return QString(buffer); +} + +void GLDTabDockContainerTabBar::paintEvent(QPaintEvent *event) +{ + + G_UNUSED(event); + for (int i = 0; i < count(); i++) + { + QStylePainter painter(this); + QStyleOptionTabV3 tab; + initStyleOption(&tab, i); + + if (m_textOrientation == Qt::Vertical) + { + QString strOldText = tab.text; + tab.text = ""; + painter.drawControl(QStyle::CE_TabBarTab, tab); + + tab.text = verticalString(strOldText); + + QTextOption opt; + opt.setAlignment(Qt::AlignCenter); + painter.setPen(tab.palette.color(QPalette::WindowText)); + painter.drawText(tab.rect, tab.text, opt); + } + else + { + painter.drawControl(QStyle::CE_TabBarTab, tab); + } + } +} + +///////////////////////////////////////////////////////////////////////// +//ContainerBar + + +GLDTabDockContainerBar::GLDTabDockContainerBar(QWidget *parent /*= 0*/) + : QWidget(parent), m_timerLong(0) +{ + m_dockToolBar = new QToolBar("dockToolBar", this); + m_tabBar = new GLDTabDockContainerTabBar(this); + m_dockToolBar->addWidget(m_tabBar); + m_dockToolBar->setVisible(false); + m_dockToolBar->setMovable(false); + m_dockToolBar->setFloatable(false); + connect(m_tabBar, SIGNAL(tabChanged(int, int)), this, SLOT(currentTabChanged(int, int))); +} + +void GLDTabDockContainerBar::selectTab(int idx) +{ + if (idx != -1) + { + assert(idx < m_dockWidgets.size()); + m_dockWidgets[idx]->setAnchored(false); + } +} + +void GLDTabDockContainerBar::addDockWidget(GLDTabDockContainerWidget *widget) +{ + + if (m_dockWidgets.empty()) + { + int ndx = m_tabBar->addTab(widget->title()); + m_dockWidgets.append(widget); + m_tabIndexes.append(ndx); + assert(ndx < m_dockWidgets.size()); + connect(m_dockWidgets[ndx], SIGNAL(setHideAndEntered(bool, bool)), + m_tabBar, SLOT(setHideAndEntered(bool, bool))); + } + else + { + QList::const_iterator itr = qFind(m_dockWidgets, widget); + + if (itr == m_dockWidgets.end()) + { + int ndx = m_tabBar->addTab(widget->title()); + m_dockWidgets.append(widget); + m_tabIndexes.append(ndx); + assert(ndx < m_dockWidgets.size()); + connect(m_dockWidgets[ndx], SIGNAL(setHideAndEntered(bool, bool)), + m_tabBar, SLOT(setHideAndEntered(bool, bool))); + } + } + + connect(m_tabBar, SIGNAL(tabLeave()), widget, SLOT(leaveHide())); + connect(m_tabBar, SIGNAL(setLeaved(bool)), widget, SLOT(setLeaved(bool))); + + m_dockToolBar->show(); +} + +void GLDTabDockContainerBar::removeDockWidget(GLDTabDockContainerWidget *widget) +{ + int ndx = -1; + + for (int i = 0; i < m_tabIndexes.size(); ++i) + { + if (m_dockWidgets[i] == widget) + { + ndx = i; + break; + } + } + + if (ndx != -1) + { + m_tabBar->removeTab(ndx); + m_dockWidgets.removeAt(ndx); + m_tabIndexes.removeAt(ndx); + } + + if (m_tabIndexes.empty()) + { + m_dockToolBar->hide(); + } +} + +void GLDTabDockContainerBar::currentTabChanged(int cur, int pre) +{ + if (cur != pre) + { + if (cur == -1 && pre < m_dockWidgets.size()) + { + m_dockWidgets[pre]->hide(); + } + else + { + if (pre != -1 && pre < m_dockWidgets.size()) + { + m_dockWidgets[pre]->hide(); + } + + if (cur < m_dockWidgets.size()) + { + assert(cur >= 0); + m_dockWidgets[cur]->setAnchored(false); + } + } + } + else + { + if (cur != -1 && cur < m_dockWidgets.size()) + { + assert(cur >= 0); + + if (!m_dockWidgets[cur]->isVisible()) + { + m_dockWidgets[cur]->setAnchored(false); + } + } + } + + if (cur >= 0 && cur < m_dockWidgets.size()) + { + int ntimervalue = m_dockWidgets[cur]->timerInterval(); + m_tabBar->setTimerInterval(ntimervalue); + } +} + +////////////////////////////////////////////////////////////////////////// +//GLDTabDockContainer +static Qt::ToolBarArea dockAreaToToolBarArea(Qt::DockWidgetArea area) +{ + if (area == Qt::LeftDockWidgetArea) + { + return Qt::LeftToolBarArea; + } + + if (area == Qt::RightDockWidgetArea) + { + return Qt::RightToolBarArea; + } + + if (area == Qt::TopDockWidgetArea) + { + return Qt::TopToolBarArea; + } + + if (area == Qt::BottomDockWidgetArea) + { + return Qt::BottomToolBarArea; + } + +#ifdef _DEBUG + else + { + assert(false); + } + +#endif + return Qt::BottomToolBarArea; +} + +static QTabBar::Shape dockAreaToTabBarShape(Qt::DockWidgetArea area) +{ + if (area == Qt::LeftDockWidgetArea) + { + return QTabBar::RoundedWest; + } + + if (area == Qt::RightDockWidgetArea) + { + return QTabBar::RoundedEast; + } + + if (area == Qt::TopDockWidgetArea) + { + return QTabBar::RoundedNorth; + } + + if (area == Qt::BottomDockWidgetArea) + { + return QTabBar::RoundedSouth; + } + +#ifdef _DEBUG + else + { + assert(false); + } + +#endif + return QTabBar::RoundedWest; +} + +GLDTabDockContainer::GLDTabDockContainer(Qt::DockWidgetArea dockArea, QMainWindow *mainWindow, QWidget *parent) + : QWidget(parent) + , m_dockArea(dockArea) + , m_mainWindow(mainWindow) + , m_textForceVertical(false) + , m_interval(500) +{ + parent->setContextMenuPolicy(Qt::NoContextMenu); +#ifdef _DEBUG + + if (dockArea != Qt::LeftDockWidgetArea && dockArea != Qt::RightDockWidgetArea + && dockArea != Qt::TopDockWidgetArea && dockArea != Qt::BottomDockWidgetArea) + { + assert(false); + } + +#endif +// QMainWindow *mw = qobject_cast(parent); +// if (mw != NULL) +// { +// m_mainWindow = mw; +// } + m_bar = new GLDTabDockContainerBar(this); + m_bar->m_tabBar->setShape(dockAreaToTabBarShape(m_dockArea)); + + if (m_mainWindow != NULL) + { + Qt::ToolBarArea area = dockAreaToToolBarArea(m_dockArea); + m_mainWindow->addToolBarBreak(area); + m_mainWindow->addToolBar(area, m_bar->m_dockToolBar); + } +} + +void GLDTabDockContainer::addTabDockContainerWidget(GLDTabDockContainerWidget *widget) +{ + //if main window is null,try to examine the parent widget. + if (m_mainWindow == NULL) + { + QMainWindow *mw = qobject_cast(parent()); + + if (NULL != mw) + { + m_mainWindow = mw; + } + } + + assert(NULL != m_mainWindow); + + widget->setParent(this); + widget->setAllowedAreas(m_dockArea); + connect(widget, SIGNAL(anchorChanged(bool)), this, SLOT(anchorChanged(bool))); + bool bisAnchored = widget->isAnchored(); + + if (bisAnchored == false) + { + widget->setAnchored(true); + QApplication::processEvents(); + } + + widget->setAnchored(bisAnchored); + + if (!widget->isAnchored()) + { + widget->hide(); + } + + m_dockWidgets.append(widget); + updateAllWidget(); +} + +void GLDTabDockContainer::hideWidget() +{ + for (int i = 0; i < m_dockWidgets.size(); ++i) + { + m_dockWidgets[i]->hideWidget(); + } + + m_bar->m_dockToolBar->hide(); + m_bar->hide(); +} + +void GLDTabDockContainer::showWidget() +{ + for (int i = 0; i < m_dockWidgets.size(); ++i) + { + m_dockWidgets[i]->showWidget(); + } + + if (!m_bar->m_tabIndexes.empty()) + { + m_bar->m_dockToolBar->show(); + } + + m_bar->show(); +} + +void GLDTabDockContainer::setTimerInterval(int interval) +{ + m_interval = interval; + updateAllWidget(); +} + +void GLDTabDockContainer::anchorChanged(bool anchored) +{ + GLDTabDockContainerWidget *widget = qobject_cast(sender()); + + if (NULL != widget) + { + if (m_bar->m_tabBar->textOrientation() == Qt::Horizontal && m_textForceVertical) + { + if (m_dockArea == Qt::LeftDockWidgetArea || m_dockArea == Qt::RightDockWidgetArea) + { + m_bar->m_tabBar->setTextOrientation(Qt::Vertical); + } + } + + if (anchored) + { + widget->setFeatures(widget->features() | QDockWidget::DockWidgetMovable); + m_mainWindow->addDockWidget(m_dockArea, widget); + m_bar->removeDockWidget(widget); + widget->setFloating(false); + widget->show(); + } + else + { + m_mainWindow->removeDockWidget(widget); + widget->setFloating(true); + widget->setFeatures(widget->features() & ~QDockWidget::DockWidgetMovable); + m_bar->addDockWidget(widget); + widget->resize(widget->sizeHint()); + QApplication::processEvents(); + + QPoint pt; + QWidget *centerWidget = m_mainWindow->centralWidget(); + + if (centerWidget == NULL) + { + //TODO need some functions to deal with the situation!.... + return ; + } + + if (m_dockArea == Qt::LeftDockWidgetArea) + { + //pt = centerWidget->rect().topLeft(); + if (m_bar->isVisible()) + { + pt = m_bar->m_dockToolBar->rect().topRight(); + } + else + { + pt = m_bar->m_dockToolBar->rect().topLeft(); + } + + pt = m_bar->m_dockToolBar->mapToGlobal(pt); + + if (widget->isAutoFillHeight()) + { + widget->resize(widget->width(), centerWidget->height()); + } + } + else if (m_dockArea == Qt::RightDockWidgetArea) + { + //pt = centerWidget->rect().topRight() ; + if (m_bar->isVisible()) + { + pt = m_bar->m_dockToolBar->rect().topLeft(); + } + else + { + pt = m_bar->m_dockToolBar->rect().topRight(); + } + + pt = m_bar->m_dockToolBar->mapToGlobal(pt); + pt.setX(pt.x() - widget->rect().width()); + + if (widget->isAutoFillHeight()) + { + widget->resize(widget->width(), centerWidget->height()); + } + + } + else if (m_dockArea == Qt::TopDockWidgetArea) + { + //pt = centerWidget->rect().topRight(); + if (m_bar->isVisible()) + { + pt = m_bar->m_dockToolBar->rect().bottomLeft(); + } + else + { + pt = m_bar->m_dockToolBar->rect().topLeft(); + } + + pt = m_bar->m_dockToolBar->mapToGlobal(pt); + + if (widget->isAutoFillHeight()) + { + widget->resize(centerWidget->width(), widget->height()); + } + } + else if (m_dockArea == Qt::BottomDockWidgetArea) + { + if (!m_bar->isVisible()) + { + pt = m_bar->m_dockToolBar->rect().bottomLeft(); + } + else + { + pt = m_bar->m_dockToolBar->rect().topLeft(); + } + + pt = m_bar->m_dockToolBar->mapToGlobal(pt); + //pt = centerWidget->rect().bottomLeft(); + pt.setY(pt.y() - widget->rect().height()); + + if (widget->isAutoFillHeight()) + { + widget->resize(centerWidget->width(), widget->height()); + } + } + +#ifdef _DEBUG + else + { + //see the constructor description. + assert(false); + } + +#endif + + pt = m_mainWindow->mapFromGlobal(pt); + pt = m_mainWindow->mapToGlobal(pt); + widget->move(pt); + widget->show(); + widget->activateWindow(); + } + } +} + +void GLDTabDockContainer::setMainWindow(QMainWindow *mainWindow) +{ + m_mainWindow = mainWindow; + + if (m_mainWindow != NULL) + { + m_mainWindow->addToolBar(dockAreaToToolBarArea(m_dockArea), m_bar->m_dockToolBar); + } +} + +void GLDTabDockContainer::updateAllWidget() +{ + for (int i = 0; i < m_dockWidgets.size(); ++i) + { + m_dockWidgets[i]->setTimerInterval(m_interval); + } +} + +void GLDTabDockContainer::setTabTextForceVertical(bool isTextVertical) +{ + m_textForceVertical = isTextVertical; +} + +bool GLDTabDockContainer::isTabTextForceVertical() const +{ + return m_textForceVertical; +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDTableCornerButton.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDTableCornerButton.cpp new file mode 100644 index 00000000..f1a282f1 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDTableCornerButton.cpp @@ -0,0 +1,77 @@ +#include +#include + +#include "GLDTableCornerButton.h" +#include "GLDAbstractItemModel.h" + +GTableCornerbutton::GTableCornerbutton(QWidget *parent) + : QAbstractButton(parent) +{ +} + +void GTableCornerbutton::paintEvent(QPaintEvent *) +{ + QStyleOptionHeader opt; + opt.initFrom(this); + QStyle::State state = QStyle::State_None | QStyle::State_Raised; + + if (isEnabled()) + { + state |= QStyle::State_Enabled; + } + + if (isActiveWindow()) + { + state |= QStyle::State_Active; + } + + if (isDown()) + { + state |= QStyle::State_Sunken; + } + + QModelIndex index = m_model->index(0, 0); + + Qt::Alignment align = static_cast(index.data(gidrConerTextAlignmentRole).toInt()); + opt.textAlignment = align; + opt.text = index.data(gidrConerDataRole).toString(); + opt.state = state; + opt.rect = rect(); + opt.position = QStyleOptionHeader::OnlyOneSection; + + QPainter painter(this); + style()->drawControl(QStyle::CE_Header, &opt, &painter, this); +} + +void GTableCornerbuttonGraphicsEffect::draw(QPainter *painter) +{ + QPoint offset; + QPixmap pixmap = sourcePixmap(Qt::LogicalCoordinates, &offset); +// || ((this->size().rwidth() - e->pos().y() > 1) && (this->size().rheight() - e->pos().x() > 1))) + QPainter p(&pixmap); + p.setBrush(Qt::NoBrush); + + QRect rt = pixmap.rect(); + int x1 = 0; + int x2 = rt.width(); + + int y = rt.height() - m_shadowHeight; + p.setPen(m_clrStart); + p.drawLine(QPoint(x1, y), QPoint(x2, y)); + + ++y; + p.setPen(m_clrMid); + p.drawLine(QPoint(x1, y), QPoint(x2, y)); + + ++y; + p.setPen(m_clrEnd); + p.drawLine(QPoint(x1, y), QPoint(x2, y)); + + painter->drawPixmap(offset, pixmap); +} +QRectF GTableCornerbuttonGraphicsEffect::boundingRectFor(const QRectF &rect) const +{ + QRectF rectF = QGraphicsEffect::boundingRectFor(rect); + rectF.setHeight(rectF.height() + m_shadowHeight); + return rectF; +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDTableView.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDTableView.cpp new file mode 100644 index 00000000..ee2e9690 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDTableView.cpp @@ -0,0 +1,1320 @@ +#include +#include + +#include + +#include "GLDTableView.h" +#include "GLDTableView_p.h" +#include "GLDTreeDrawInfo.h" +#include "GLDTreeModel.h" +#include "GLDGroupHeaderView.h" +#include "GLDGroupModel.h" +#include "GLDGlobal.h" +#include "GLDFileUtils.h" + +bool GlodonTableViewPrivate::drawTree(QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index) +{ + Q_Q(GlodonTableView); + + if (m_treeDecorationStyle == NoDecoration) + return false; + + if (q->visualIndex(index).column() != m_treeColumn) + return false; + + const GTreeViewItem &oViewItem = m_drawInfo->m_viewItems.at(index.row()); + + if (oViewItem.parentIndex == -1 && oViewItem.hasChildren == 0) + return false; + + if (m_treeDecorationStyle == OSStyle) + { + drawOSStyle(painter, option, index, oViewItem); + } + else + { + drawNormalStyle(painter, option, index, oViewItem); + } + + return true; +} + +bool GlodonTableViewPrivate::expandOrCollapseItemAtPos(const QPoint &pos) +{ + Q_Q(GlodonTableView); + + // we want to handle mousePress in EditingState (persistent editors) + if ((m_state != GlodonAbstractItemView::NoState + && m_state != GlodonAbstractItemView::EditingState) + || !viewport->rect().contains(pos)) + { + return true; + } + + int nItem = itemDecorationAt(pos); + + if ((nItem != -1) && 0 != m_drawInfo->m_viewItems.at(nItem).hasChildren) + { + if (m_drawInfo->m_viewItems.at(nItem).expanded) + { + collapse(nItem, true); + } + else + { + expand(nItem, true); + } + + if (!isAnimating()) + { + q->updateGeometries(); + viewport->update(); + } + + return true; + } + + return false; +} + +int GlodonTableViewPrivate::itemDecorationAt(const QPoint &pos) +{ + int nx = pos.x(); + int ncolumn = m_horizontalHeader->visualIndexAt(nx); + + if (ncolumn != m_treeColumn) + { + return -1; + } + + int ny = pos.y(); + int nrow = m_verticalHeader->logicalIndexAt(ny); + + QRect returning = itemDecorationRect(nrow); + + if (!returning.contains(pos)) + { + return -1; + } + + return nrow; +} + +QRect GlodonTableViewPrivate::itemDecorationRect(int row) +{ + Q_Q(GlodonTableView); + + if (row == -1) + { + return QRect(); + } + + int nitemIndentation = CON_INDENT * (m_drawInfo->m_viewItems[row].treeLevel + 1); + + int nposition = m_horizontalHeader->sectionVisualPosition(m_treeColumn); + + QRect rect; + rect = QRect(nposition + nitemIndentation - CON_INDENT + 2, q->rowVisualPosition(row), + CON_INDENT + 2, q->rowHeight(row) + 2); + return rect; +} + +void GlodonTableViewPrivate::expand(int item, bool emitSignal) +{ + doExpand(item, emitSignal); + viewport->update(); + m_state = GLDTableView::NoState; +} + +void GlodonTableViewPrivate::collapse(int item, bool emitSignal) +{ + doCollapse(item, emitSignal); + viewport->update(); + m_state = GLDTableView::NoState; +} + +void GlodonTableViewPrivate::doExpand(int item, bool emitSignal) +{ + Q_Q(GlodonTableView); + + // 不是树形结构,不需要展开 + // 展开的点不合法,不需要展开 + // 已经展开,不需要展开 + if (!m_isTree || item <= -1 || m_drawInfo->m_viewItems.at(item).expanded || m_drawInfo->m_viewItems.count() <= item ) + { + return; + } + + q->setState(GlodonAbstractItemView::ExpandingState); + m_drawInfo->expandItem(item); + q->afterExpandedChanged(item, true, emitSignal); + // TODO wangdd-a: 展开折叠后,没必要刷整个界面,刷后面的格子就可以了 + q->refreshDisplayColRow(); + // TODO chensf : 展开后,需要重新计算批注框的显示位置 + q->resetCommentPosition(); +} + +void GlodonTableViewPrivate::doCollapse(int item, bool emitSignal) +{ + Q_Q(GlodonTableView); + + if (!m_isTree || item <= -1 || m_drawInfo->m_viewItems.count() <= item || 0 == m_drawInfo->m_viewItems.at(item).expanded) + { + return; + } + + q->setState(GlodonAbstractItemView::CollapsingState); + m_drawInfo->collapseItem(item); + q->afterExpandedChanged(item, false, emitSignal); + q->refreshDisplayColRow(); + // TODO chensf : 收起时,隐藏相应节点的批注框,同时重新计算批注框的显示位置 + hideCommentWhenCollapse(); + q->resetCommentPosition(); +} + +void GlodonTableViewPrivate::drawBranch( + QPainter *painter, const QRect &rect, const QModelIndex &index, const GTreeViewItem &viewItem) +{ + Q_Q(GlodonTableView); + QStyleOptionViewItem opt = q->viewOptions(); + QStyle::State extraFlags = QStyle::State_None; + + if (q->isEnabled()) + { + extraFlags |= QStyle::State_Enabled; + } + + if (q->window()->isActiveWindow()) + { + extraFlags |= QStyle::State_Active; + } + + QPoint oldBO = painter->brushOrigin(); + + if (q->verticalScrollMode() == GlodonAbstractItemView::ScrollPerPixel) + { + painter->setBrushOrigin(QPoint(0, q->verticalOffset())); + } + + if (m_selectionModel->isSelected(index)) + { + extraFlags |= QStyle::State_Selected; + } + + opt.rect = rect; + const bool c_bExpanded = (0 != viewItem.expanded); + const bool c_bChildren = (0 != viewItem.hasChildren); + const bool c_bMoreSiblings = (0 != viewItem.hasMoreSiblings); + + opt.state = QStyle::State_Item | extraFlags + | (c_bMoreSiblings ? QStyle::State_Sibling : QStyle::State_None) + | (c_bChildren ? QStyle::State_Children : QStyle::State_None) + | (c_bExpanded ? QStyle::State_Open : QStyle::State_None); + + q->style()->drawPrimitive(QStyle::PE_IndicatorBranch, &opt, painter, q); + painter->setBrushOrigin(oldBO); +} + +void GlodonTableViewPrivate::drawOSStyle( + QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index, const GTreeViewItem &viewItem) +{ + Q_Q(GlodonTableView); + int nXPos = option.rect.left(); + int nWidth = option.rect.width(); + int nHeight = option.rect.height(); + int nYPos = option.rect.y(); + + q->style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &option, painter, q); + + int nDecorationWidth = CON_INDENT * (viewItem.treeLevel + 1) + c_nTreeDecorationLeftMargin; + QRect oBeforeText(nXPos, nYPos, nDecorationWidth, nHeight); + option.rect = oBeforeText; + + //处理树形结构显示的时候,格子实际内容之前部分的选中效果 + GlodonDefaultItemDelegate *pItemDelegate = q->itemDelegate(index); + + pItemDelegate->drawBackground(painter, option, index); + + option.rect.setRect( + nDecorationWidth + nXPos, nYPos, nWidth - nDecorationWidth, nHeight); + + pItemDelegate->paint(painter, option, index); + + QRect oBranch(nXPos + CON_INDENT * viewItem.treeLevel + c_nTreeDecorationLeftMargin, nYPos, CON_INDENT, nHeight); + drawBranch(painter, oBranch, index, viewItem); +} + +void GlodonTableViewPrivate::drawNormalStyleLines( + const GTreeViewItem &viewItem, int ngridWidth, QPoint levelCenter, const QModelIndex &index, + QRect rect, QPainter *painter) +{ + /* + * -- A + * | + * | + * (1) + * | + * |-(2)- A1 + * | | + * (3) |---- A11 + * | + * |--(4)-- A2 + */ + if (viewItem.parentIndex != -1) + { + + // 父节点到自己的垂直方向连线,如图所示(1) + painter->drawLine(levelCenter.x() - CON_INDENT, rect.top(), + levelCenter.x() - CON_INDENT, levelCenter.y()); + + // 连接到自己的水平方向连线,如图所示(2) + painter->drawLine(levelCenter.x() - CON_INDENT, levelCenter.y(), + levelCenter.x() - CON_HALF_DECORATION_WIDTH - 1, levelCenter.y()); + + // 如果有兄弟节点,绘制垂直方向,到兄弟节点的连线,如图所示(3),是(1)的延长线 + if (1 == viewItem.hasMoreSiblings) + { + painter->drawLine(levelCenter.x() - CON_INDENT, rect.bottom() + ngridWidth, + levelCenter.x() - CON_INDENT, levelCenter.y()); + } + } + + if (0 == viewItem.hasChildren) + { + // 没有孩子,有父亲,绘制叶子节点水平方向连线,如图所示(4), 是(2)的延长线 + if (viewItem.parentIndex != -1) + { + painter->drawLine(levelCenter.x() - CON_HALF_DECORATION_WIDTH, levelCenter.y(), + levelCenter.x() + CON_HALF_DECORATION_WIDTH + 1, levelCenter.y()); + } + } + else + { + if (0 != viewItem.expanded) + { + painter->drawLine(levelCenter.x(), levelCenter.y() + CON_HALF_DECORATION_WIDTH + 1, + levelCenter.x(), rect.bottom() + ngridWidth); + } + } + + int nlevel = viewItem.treeLevel; + int nrowIndex = index.row(); + + while (nlevel > 0) + { + nrowIndex = m_drawInfo->m_viewItems[nrowIndex].parentIndex; + + if (nrowIndex == -1) + { + nlevel = -1; + } + else + { + nlevel = m_drawInfo->m_viewItems[nrowIndex].treeLevel; + + if (nlevel > 0 && 1 == m_drawInfo->m_viewItems[nrowIndex].hasMoreSiblings) + { + painter->drawLine(rect.left() + CON_INDENT * nlevel - CON_HALF_DECORATION_WIDTH + 4, + rect.top() - 1, + rect.left() + CON_INDENT * nlevel - CON_HALF_DECORATION_WIDTH + 4, + rect.bottom()); + } + } + } +} + +QPen GlodonTableViewPrivate::normalStylePen(QStyleOptionViewItem &option) +{ + Q_Q(GlodonTableView); + + const int c_gridHint = q->style()->styleHint(QStyle::SH_Table_GridLineColor, &option, q); + const QColor c_gridColor = static_cast(c_gridHint); + return QPen(c_gridColor, 0, m_gridStyle); +} + +QRect GlodonTableViewPrivate::beforeTextRect(const QRect &cellRect, int indentation) +{ + int nBeforeTextWidth = + c_nTreeDecorationLeftMargin + indentation + + CON_HALF_DECORATION_WIDTH * 2 + c_nTreeDecorationRightMargin; + + return QRect(cellRect.left(), cellRect.top(), + qMin(nBeforeTextWidth, cellRect.width()), cellRect.height()); +} + +void GlodonTableViewPrivate::drawNormalStyle( + QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index, const GTreeViewItem &viewItem) +{ + Q_Q(GlodonTableView); + + q->style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &option, painter, q); + + QRect oCellRect = option.rect; + int nIndentation = CON_INDENT * viewItem.treeLevel; + + //处理树形结构显示的时候,格子实际内容之前部分的选中效果 + GlodonDefaultItemDelegate *pItemDelegate = q->itemDelegate(index); + + pItemDelegate->drawBackground(painter, option, index); + + QStyle::State oldState = option.state; + option.state &= ~QStyle::State_Selected; + + painter->save(); + painter->setPen(normalStylePen(option)); + + QRect oBeforeTextRect = beforeTextRect(oCellRect, nIndentation); + painter->setClipRect(oBeforeTextRect); + + QPoint oDecorationCenter = decorationCenter(oCellRect, nIndentation); + + // 绘制树形结构样式 + if (1 == viewItem.hasChildren) + { + drawNormalStyleTreeDecoration(painter, decorationRect(oDecorationCenter), 0 != viewItem.expanded, option); + } + + int nGridWidth = m_showGrid ? 0 : 1; + if (m_treeDecorationStyle == NormalStyle) + { + drawNormalStyleLines(viewItem, nGridWidth, oDecorationCenter, index, oCellRect, painter); + } + + painter->restore(); + + option.rect = afterDecorationRect(oDecorationCenter, oCellRect, oBeforeTextRect); + option.state = oldState; + + // TODO liurx 此处应该统一计算树形结构偏移,不应该计算两次,再调整差异 + //保持与minTextHeight处一致 + { + const int c_offset = q->treeCellDisplayHorizontalOffset(index.row(), m_treeColumn, false); + QStyle *sty = q->style(); + const int c_textMargin = sty->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, q_func()) - 1;// + 1; + const int c_autoSuitRowHeightWidth = m_horizontalHeader->sectionSize(index.column()) + + c_textMargin - c_offset - c_rightSelectedDashLineWidth;//此处同minTextHeight + + if (option.rect.width() < c_autoSuitRowHeightWidth) + { + option.rect.setWidth(c_autoSuitRowHeightWidth); + const int c_displayRectOffset = (option.rect.right() - option.rect.right()); + + if (c_displayRectOffset < 0) + { + option.rect.adjust(c_displayRectOffset, 0, c_displayRectOffset, 0); + } + } + } + pItemDelegate->paint(painter, option, index); +} + +void GlodonTableViewPrivate::drawNormalStyleTreeDecoration( + QPainter *painter, const QRect &rect, bool expanded, + const QStyleOptionViewItem &option) +{ + QStyleOptionViewItem opt = option; + opt.rect = rect; + opt.state = opt.state & ~QStyle::State_HasFocus; + opt.state |= QStyle::State_Off; + + painter->save(); + QPen decorationPen = painter->pen(); + +#ifndef __APPLE__ + const QWidget *widget = option.widget; + QStyle *style = widget ? widget->style() : QApplication::style(); + style->drawPrimitive(QStyle::PE_IndicatorViewItemCheck, &opt, painter, widget); +#else + decorationPen.setColor(QColor(125, 125, 125)); + painter->setPen(decorationPen); + painter->fillRect(rect, QColor(255, 255, 255)); + painter->drawRect(rect); +#endif + + decorationPen.setStyle(Qt::SolidLine); + decorationPen.setColor(Qt::black); + painter->setPen(decorationPen); + QPoint center = rect.center(); + painter->drawLine(center.x() - 3, center.y(), center.x() + 3, center.y()); + + if (!expanded) + { + painter->drawLine(center.x(), center.y() - 3, center.x(), center.y() + 3); + } + + painter->restore(); +} + +void GlodonTableViewPrivate::doSelect( + const QModelIndex &tl, const QModelIndex &br, QItemSelectionModel::SelectionFlags command, bool isRowSelect) +{ + Q_Q(GlodonTableView); + + QItemSelection selection(tl, br); + + m_oTopLeftSelectIndex = tl; + m_oBottomRightSelectIndex = br; + + if (m_addChildInSelection && m_isTree) + { + q->setChildSelection(tl, br, selection, isRowSelect); + } + + m_selectionModel->select(selection, command); +} + +void GlodonTableViewPrivate::hideCommentWhenCollapse() +{ + QMap::iterator iter = m_oCommentFrames.begin(); + while (iter != m_oCommentFrames.end()) + { + if (m_drawInfo->m_viewItems[iter.key().row()].hidden) + { + iter.value()->hide(); + } + iter++; + } +} + +void GlodonTableViewPrivate::itemDelegatePaint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) +{ + QStyleOptionViewItem opt = option; + + if (m_isTree) + { + if (GlodonTableViewPrivate::drawTree(painter, opt, index)) + return; + } + + GLDTableViewPrivate::itemDelegatePaint(painter, opt, index); +} + +void GlodonTableView::groupChanged(QVector newGroup) +{ + // 将树形交给现存的最靠前的列 + Q_D(GlodonTableView); + + int nTreeCol = 0; + + for (int nCol = 0; nCol < d->m_horizontalHeader->count(); ++nCol) + { + for (int nGroup = 0; nGroup < newGroup.size(); ++nGroup) + { + if (nCol == newGroup.at(nGroup) && nCol <= nTreeCol) + { + nTreeCol++; + break; + } + } + } + + d->m_treeColumn = nTreeCol; +} + +void GlodonTableView::hideRow(int row) +{ + Q_D(GlodonTableView); + + if (d->m_isTree || d->m_isGroupMode) + { + return; + } + + GLDTableView::hideRow(row); +} + +void GlodonTableView::setRootIndex(const QModelIndex &index) +{ + Q_D(GlodonTableView); + + if (index == d->m_root) + { + viewport()->update(); + + return; + } + + d->m_verticalHeader->setRootIndex(index); + d->m_horizontalHeader->setRootIndex(index); + + GlodonAbstractItemView::setRootIndex(index); +} + +QModelIndex GlodonTableView::treeIndex(const QModelIndex &index) const +{ + Q_D(const GlodonTableView); + + if (d->m_isGroupMode) + { + return QModelIndex(); + } + + if (d->m_isTree) + { + return static_cast(d->m_model)->treeIndex(index); + } + + return index; +} + +QModelIndex GlodonTableView::dataIndex(const QModelIndex &index) const +{ + Q_D(const GlodonTableView); + + if (d->m_isGroupMode) + { + QModelIndex treeIndex = static_cast(d->m_model)->dataIndex(index); + QAbstractItemModel *itemModel = const_cast(treeIndex.model()); + + return static_cast(itemModel)->dataIndex(treeIndex); + } + + if (d->m_isTree) + { + if (index.model() == d->m_model) + { + QModelIndex treeIndex = static_cast(d->m_model)->dataIndex(index); + const GlodonGroupModel *groupModel = dynamic_cast(treeIndex.model()); + + if (groupModel) + { + return groupModel->dataIndex(treeIndex); + } + else + { + return treeIndex; + } + } + } + + return index; +} + +QModelIndex GlodonTableView::currentDataIndex() const +{ + Q_D(const GlodonTableView); + + if (d->m_isTree) + { + const QModelIndex c_index = currentIndex(); + GlodonTreeModel *treeModel = static_cast(d->m_model); + return treeModel->dataIndex(c_index); + } + + return QModelIndex(); +} + +void GlodonTableView::setIsTree(bool value) +{ + Q_D(GlodonTableView); + + if ((d->m_isTree == value) || (d->m_isGroupMode)) + { + return; + } + + doSetIsTree(value); + + if (value) + { + if (!d->m_dataModel) + { + doSetModel(d->m_model); + } + } + else + { + doSetModel(d->m_dataModel); + setDataModel(0); + } + + d->viewport->update(); +} + +bool GlodonTableView::isTree() const +{ + Q_D(const GlodonTableView); + + return d->m_isTree; +} + +void GlodonTableView::setIsGroupMode(bool groupModeEnable) +{ + Q_D(GlodonTableView); + + if ((groupModeEnable == d->m_isGroupMode) || isDisplayFilter() || totalRowAtFooter()) + { + return; + } + + d->m_isGroupMode = groupModeEnable; + + if (groupModeEnable) + { + //切换model时如果处于编辑状态,强制退出 + if (d->m_oEditorIndex.isValid()) + { + forceCloseEditor(); + } + + GlodonGroupHeaderView *cxHeader = new GlodonGroupHeaderView(this); + setHorizontalHeader(cxHeader); + doSetModel(d->m_model); + + if (!cxHeader->isVisible()) + { + cxHeader->show(); + } + } + else + { + GlodonHeaderView *header = new GlodonHeaderView(Qt::Horizontal, this); + setHorizontalHeader(header); + doSetModel(d->m_dataModel); + + if (!header->isVisible()) + { + header->show(); + } + } +} + +bool GlodonTableView::isGroupMode() const +{ + Q_D(const GlodonTableView); + return d->m_isGroupMode; +} + +void GlodonTableView::setChildSelection(const QModelIndex &topLeft, const QModelIndex &bottomRight, + QItemSelection &selection, bool isRowSelect) +{ + Q_D(GlodonTableView); + + if (!isRowSelect) + { + return; + } + + if (!selection.isEmpty()) + { + selection.clear(); + } + + QModelIndex tl; + QModelIndex br; + for (int row = topLeft.row(); row <= bottomRight.row(); ++row) + { + int nbottomRow = d->m_drawInfo->lastChildRow(row); + tl = d->m_model->index(row, topLeft.column(), d->m_root); + br = d->m_model->index(nbottomRow, bottomRight.column(), d->m_root); + + if (!selection.contains(tl) && !selection.contains(br)) + { + selection.append(QItemSelectionRange(tl, br)); + } + } + + d->m_oTopLeftSelectIndex = topLeft; + d->m_oBottomRightSelectIndex = br; +} + +void GlodonTableView::setTreeDecorationStyle(TreeDecorationStyle style) +{ + Q_D(GlodonTableView); + + if (d->m_treeDecorationStyle != style) + { + d->m_treeDecorationStyle = style; + d->viewport->update(); + } +} + +TreeDecorationStyle GlodonTableView::treeDecorationStyle() const +{ + Q_D(const GlodonTableView); + return d->m_treeDecorationStyle; +} + +void GlodonTableView::setTreeDrawInfo(GlodonTreeDrawInfo *tableViewDrawInfo) +{ + Q_D(GlodonTableView); + + if (d->m_drawInfo == tableViewDrawInfo) + { + return; + } + else if (!d->m_drawInfo) + { + d->m_drawInfo = tableViewDrawInfo; + d->m_drawInfo->m_header = d->m_verticalHeader; + d->m_drawInfo->setModel(d->m_model); + } +} + +GlodonTreeDrawInfo *GlodonTableView::treeDrawInfo() +{ + Q_D(GlodonTableView); + return d->m_drawInfo; +} + +bool GlodonTableView::isAddChildToSelection() +{ + Q_D(GlodonTableView); + return d->m_addChildInSelection; +} + +void GlodonTableView::setAddChildToSelection(bool value) +{ + Q_D(GlodonTableView); + d->m_addChildInSelection = value; +} + +void GlodonTableView::setTreeColumn(int column) +{ + Q_D(GlodonTableView); + d->m_treeColumn = column; +} + +int GlodonTableView::treeColumn() +{ + Q_D(GlodonTableView); + return d->m_treeColumn; +} + +void GlodonTableView::expand(int row, bool emitSignal) +{ + Q_D(GlodonTableView); + d->expand(row, emitSignal); +} + +void GlodonTableView::collapse(int row, bool emitSignal) +{ + Q_D(GlodonTableView); + d->collapse(row, emitSignal); +} + +bool GlodonTableView::isRowExpanded(int row) +{ + Q_D(GlodonTableView); + Q_ASSERT(row >= 0); + return 0 != d->m_drawInfo->m_viewItems[row].expanded; +} + +void GlodonTableView::expandAll() +{ + Q_D(GlodonTableView); + + if (d->m_isTree) + { + setState(GlodonAbstractItemView::ExpandingState); + + try + { + QSet oExpandItems; + for (int row = 0; row < d->m_drawInfo->m_viewItems.count(); row++) + { + if (d->m_drawInfo->m_viewItems.at(row).expanded) + { + continue; + } + d->m_drawInfo->doExpandItem(row, oExpandItems); + afterExpandedChanged(row, true, true); + } + d->m_verticalHeader->batchSetSectionHidden(oExpandItems, false); + } + catch (...) + { + d->m_state = GLDTableView::NoState; + throw; + } + + d->m_state = GLDTableView::NoState; + refreshDisplayColRow(); + + d->viewport->update(); + QSize oViewportSize = d->viewport->size(); + updateHorizontalScrollBar(oViewportSize); + updateVerticalScrollBar(oViewportSize); + } +} + +void GlodonTableView::collapseAll() +{ + Q_D(GlodonTableView); + + if (d->m_isTree) + { + setState(GlodonAbstractItemView::CollapsingState); + + try + { + QSet oCollapseRows; + for (int row = 0; row < d->m_drawInfo->m_viewItems.count(); row++) + { + if (!d->m_drawInfo->m_viewItems.at(row).expanded) + { + continue; + } + d->m_drawInfo->doCollapseItem(row, oCollapseRows); + afterExpandedChanged(row, false, true); + } + d->m_verticalHeader->batchSetSectionHidden(oCollapseRows, true); + } + catch (...) + { + d->m_state = GLDTableView::NoState; + throw; + } + + d->m_state = GLDTableView::NoState; + refreshDisplayColRow(); + + d->viewport->update(); + QSize oViewportSize = d->viewport->size(); + updateHorizontalScrollBar(oViewportSize); + updateVerticalScrollBar(oViewportSize); + } +} + +void GlodonTableView::reBuildTree() +{ + Q_D(GlodonTableView); + + d->m_drawInfo->init(false); + d->viewport->update(); + d->m_horizontalHeader->update(); + d->m_verticalHeader->update(); +} + +void GlodonTableView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, + const QVector &roles) +{ + Q_D(GlodonTableView); + + if (roles.contains(gidrRowExpandedRole)) + { + if ((-1 == topLeft.row()) || (-1 == bottomRight.row())) + { + return; + } + + for (int i = topLeft.row(); i <= bottomRight.row(); i++) + { + QModelIndex oIndex = model()->index(i, 0); + QVariant varExpanded = model()->data(oIndex, gidrRowExpandedRole); + + if (qvariant_cast(varExpanded)) + { + d->doExpand(i, true); + } + else + { + d->doCollapse(i, true); + } + } + + d->viewport->update(); + + setState(NoState); + } + else + { + GLDTableView::dataChanged(topLeft, bottomRight, roles); + } +} + +GlodonTableView::GlodonTableView(QWidget *parent) : + GLDTableView(*new GlodonTableViewPrivate, parent) +{ + this->setStyleSheet(loadQssFile(c_sTableViewQssFile)); +} + +GlodonTableView::GlodonTableView(GlodonTableViewPrivate &dd, QWidget *parent) : + GLDTableView(dd, parent) +{ + +} + +GlodonTableView::~GlodonTableView() +{ + +} + +void GlodonTableView::doSetIsTree(bool value) +{ + Q_D(GlodonTableView); + + //切换model时如果处于编辑状态, 强制退出 + if (d->m_oEditorIndex.isValid()) + { + forceCloseEditor(); + } + + d->m_isTree = value; + d->m_verticalHeader->setIsTree(value); + d->m_horizontalHeader->setIsTree(value); + + if (value) + { + if (!d->m_drawInfo) + { + GlodonTreeDrawInfo *treeDrawInfo = new GlodonTreeDrawInfo(this); + treeDrawInfo->setTreeColumn(d->m_treeColumn); + setTreeDrawInfo(treeDrawInfo); + } + } + else + { + d->m_drawInfo = NULL; + } +} + +void GlodonTableView::doSetModel(QAbstractItemModel *model) +{ + Q_D(GlodonTableView); + + if (d->m_isGroupMode) + { + if (!dynamic_cast(model)) + { + GlodonGroupModel *cxModel; + + if (d->m_isTree) + { + GlodonTreeModel *treeModel = dynamic_cast(model); + cxModel = new GlodonGroupModel(treeModel->model, this); + d->m_dataModel = treeModel->model; + treeModel->model = cxModel; + d->m_drawInfo->setModel(cxModel); + model = treeModel; + } + else + { + cxModel = new GlodonGroupModel(model, this); + d->m_model = cxModel; + doSetIsTree(true); + GlodonTreeModel *treeModel = new GlodonTreeModel(cxModel, this); + treeModel->drawInfo = d->m_drawInfo; + d->m_dataModel = model; + model = treeModel; + } + + connect(dynamic_cast(d->m_horizontalHeader), SIGNAL(groupChanged(QVector)), + cxModel, SLOT(groupChanged(QVector))); + connect(dynamic_cast(d->m_horizontalHeader), SIGNAL(groupChanged(QVector)), + this, SLOT(groupChanged(QVector))); + connect(cxModel, SIGNAL(modelRebuild()), this, SLOT(reBuildTree())); + + } + } + else if (d->m_isTree) + { + if (d->m_drawInfo->model != model) + { + d->m_drawInfo->setModel(model); + } + + d->m_dataModel = model; + GlodonTreeModel *treeModel = new GlodonTreeModel(model, this); + treeModel->drawInfo = d->m_drawInfo; + model = treeModel; + } + + if (model == d->m_model) + { + return; + } + + //let's disconnect from the old model + if (d->m_model && d->m_model != QAbstractItemModelPrivate::staticEmptyModel()) + { + disconnect(d->m_model, SIGNAL(rowsInserted(QModelIndex, int, int)), + this, SLOT(_q_updateSpanInsertedRows(QModelIndex, int, int))); + disconnect(d->m_model, SIGNAL(columnsInserted(QModelIndex, int, int)), + this, SLOT(_q_updateSpanInsertedColumns(QModelIndex, int, int))); + disconnect(d->m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), + this, SLOT(_q_updateSpanRemovedRows(QModelIndex, int, int))); + disconnect(d->m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)), + this, SLOT(_q_updateSpanRemovedColumns(QModelIndex, int, int))); + disconnect(d->m_verticalHeader, SIGNAL(scrolled(int)), + this, SLOT(onScrolled(int))); + disconnect(d->m_horizontalHeader, SIGNAL(scrolled(int)), + this, SLOT(onScrolled(int))); + disconnect(d->m_verticalHeader, &GlodonHeaderView::sectionResizing, + this, &GlodonTableView::showSectionResizingInfoFrame); + disconnect(d->m_horizontalHeader, &GlodonHeaderView::sectionResizing, + this, &GlodonTableView::showSectionResizingInfoFrame); + } + + if (model) //and connect to the new one + { + connect(model, SIGNAL(rowsInserted(QModelIndex, int, int)), + this, SLOT(_q_updateSpanInsertedRows(QModelIndex, int, int))); + connect(model, SIGNAL(columnsInserted(QModelIndex, int, int)), + this, SLOT(_q_updateSpanInsertedColumns(QModelIndex, int, int))); + connect(model, SIGNAL(rowsRemoved(QModelIndex, int, int)), + this, SLOT(_q_updateSpanRemovedRows(QModelIndex, int, int))); + connect(model, SIGNAL(columnsRemoved(QModelIndex, int, int)), + this, SLOT(_q_updateSpanRemovedColumns(QModelIndex, int, int))); + connect(d->m_verticalHeader, SIGNAL(scrolled(int)), + this, SLOT(onScrolled(int))); + connect(d->m_horizontalHeader, SIGNAL(scrolled(int)), + this, SLOT(onScrolled(int))); + connect(d->m_verticalHeader, &GlodonHeaderView::sectionResizing, + this, &GlodonTableView::showSectionResizingInfoFrame); + connect(d->m_horizontalHeader, &GlodonHeaderView::sectionResizing, + this, &GlodonTableView::showSectionResizingInfoFrame); + } + + d->m_verticalHeader->setModel(model); + d->m_horizontalHeader->setModel(model); + + GTableCornerWidget *cornerWidget = dynamic_cast(d->m_cornerWidget); + + if (cornerWidget) + { + cornerWidget->setModel(model); + } + + GlodonAbstractItemView *gView = dynamic_cast(d->m_cornerWidget); + + if (gView) + { + gView->setModel(model); + } + + QAbstractItemView *qView = dynamic_cast(d->m_cornerWidget); + + if (qView) + { + qView->setModel(model); + } + + GlodonAbstractItemView::setModel(model); + GLDTableView::doSetModel(model); + + updateGeometries(); +} + +int GlodonTableView::treeCellDisplayHorizontalOffset(int row, int col, bool isOldMinTextHeightCalWay) const +{ + int nOffset = 0; + + if (isTree() && col == d_func()->m_treeColumn) + { + if (isOldMinTextHeightCalWay) + { + GlodonTreeModel *treeModel = dynamic_cast(model()); + nOffset = (treeModel->drawInfo->m_viewItems.at(row).treeLevel + 1) * c_Indent + 2 * c_HalfWidth; + } + else + { + const GTreeViewItem &viewItem = d_func()->m_drawInfo->m_viewItems[row]; + const int c_levelCenterOffset = CON_INDENT * viewItem.treeLevel + CON_HALF_DECORATION_WIDTH + 2; + nOffset = qMin((c_levelCenterOffset + CON_HALF_DECORATION_WIDTH + 3), + d_func()->m_horizontalHeader->sectionSize(col)); + } + } + + return nOffset; +} + +void GlodonTableView::onBoolCellPress(QMouseEvent *event) +{ +// Q_D(GlodonTableView); + + QModelIndex currIndex = indexAt(event->pos()); + QRect rect = visualRect(currIndex); + QRect boolRect(rect.center().rx() - 6, + rect.center().ry() - 6, + 13, 13); + +// if (d->m_isTree && currIndex.column() == d->m_treeColumn) +// { +// //如果是第一级且没有子的情况下,应与非树形结构时区域一致 +// const GTreeViewItem &viewItem = d->m_drawInfo->m_viewItems.at(currIndex.row()); + +// if (!((viewItem.parentIndex == -1) && viewItem.hasChildren != 1)) +// { +// QRect textRect(rect.left() + CON_INDENT * (viewItem.treeLevel + 1) + 2, rect.top(), +// rect.width() - CON_INDENT * (viewItem.treeLevel + 1) - 2, rect.height()); +// boolRect = QRect(textRect.center().rx() - 6, textRect.center().ry() - 6, 13, 13); +// } +// } + + if ((event->button() & Qt::LeftButton) && boolRect.contains(event->pos())) + { + setBoolEditValue(currIndex); + } +} + +void GlodonTableView::onMousePress(QMouseEvent *event) +{ + Q_D(GlodonTableView); + + if (d->m_isTree) + { + +#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) + + if (event->type() == QEvent::MouseButtonPress) +#else + if (style()->styleHint(QStyle::SH_Q3ListViewExpand_SelectMouseType, 0, this) == QEvent::MouseButtonPress) +#endif + { + bool bhandled = d->expandOrCollapseItemAtPos(event->pos()); + if (bhandled) + { + return; + } + } + + QModelIndex currIndex = indexAt(event->pos()); + int nChildCount = -1; + if (currIndex.isValid()) + { + nChildCount = d->m_drawInfo->m_viewItems[currIndex.row()].hasChildren; + } + + if (-1 != nChildCount && d->itemDecorationAt(event->pos()) != -1) + { + return; + } + } + + GLDTableView::onMousePress(event); +} + +bool GlodonTableView::event(QEvent *event) +{ + GLDEvent *gldEvent = dynamic_cast(event); + + if (gldEvent == NULL) + { + return GLDTableView::event(event); + } + + bool result = GlodonAbstractItemView::event(event); + + switch (gldEvent->type()) + { + case GM_EXPAND: + { + doGMExpand(gldEvent); + break; + } + + case GM_QUERYEXPAND: + { + doGMQueryExpand(gldEvent); + break; + } + + case GM_COLLAPSE: + { + doGMCollapse(gldEvent); + break; + } + + case GM_QUERYCOLLAPSE: + { + doGMQueryCollapse(gldEvent); + break; + } + + case GM_EXPANDALL: + { + doGMExpandAll(gldEvent); + break; + } + + case GM_QUERYEXPANDALL: + { + doGMQueryExpandAll(gldEvent); + break; + } + + case GM_COLLAPSEALL: + { + doGMCollapseAll(gldEvent); + break; + } + + case GM_QUERYCOLLAPSEALL: + { + doGMQueryCollapseAll(gldEvent); + break; + } + + default: + { + // nothing + break; + } + } + + return result; +} + +QAbstractItemModel *GlodonTableView::itemModel() +{ + Q_D(GlodonTableView); + + QAbstractItemModel *dm = GLDTableView::itemModel(); + + if (d->m_isTree) + { + dm = dataModel(); + } + + return dm; +} + +void GlodonTableView::doGMExpand(GLDEvent *event) +{ + expand(currentIndex().row(), true); + G_UNUSED(event); +} + +void GlodonTableView::doGMQueryExpand(GLDEvent *event) +{ + Q_D(GlodonTableView); + event->setResult(d->m_model->rowCount(currentIndex()) > 0); + G_UNUSED(event); +} + +void GlodonTableView::doGMCollapse(GLDEvent *event) +{ + collapse(currentIndex().row(), true); + G_UNUSED(event); +} + +void GlodonTableView::doGMQueryCollapse(GLDEvent *event) +{ + Q_D(GlodonTableView); + event->setResult(d->m_model->rowCount(currentIndex()) > 0); + G_UNUSED(event); +} + +void GlodonTableView::doGMExpandAll(GLDEvent *event) +{ + expandAll(); + G_UNUSED(event); +} + +void GlodonTableView::doGMQueryExpandAll(GLDEvent *event) +{ + event->setResult(isTree()); + G_UNUSED(event); +} + +void GlodonTableView::doGMCollapseAll(GLDEvent *event) +{ + collapseAll(); + G_UNUSED(event); +} + +void GlodonTableView::doGMQueryCollapseAll(GLDEvent *event) +{ + event->setResult(isTree()); + G_UNUSED(event); +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDTableViewBasic.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDTableViewBasic.cpp new file mode 100644 index 00000000..b2e54fd5 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDTableViewBasic.cpp @@ -0,0 +1,10510 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "GLDTableViewBasic.h" +#include "GLDTableViewBasic_p.h" +#include "GLDHeaderView_p.h" +#include "GLDMultiHeaderView.h" +#include "GLDTreeModel.h" +#include "GLDGroupHeaderView.h" +#include "GLDAbstractItemModel.h" +#include "GLDGlobal.h" +#include "GLDStrUtils.h" +#include "GLDScrollStyle.h" +#include "GLDEllipsis.h" + +const int c_rightSelectedDashLineWidth = 1; +const int c_nCommentTriangleRightLength = 5; // 批注直角三角形,直角边长 +const int c_nResizeHandlerOffset = 4; +const int c_nEmptyRectWidth = 5; +const int c_nFillHandleWidth = 4; + +struct GlodonTableViewPainterInfo +{ + GlodonTableViewPainterInfo( + int top, int bottom, int left, int right, int fVisualRow, + int fVisualColumn, int lVisualColumn, bool alternateBase) + : m_nDirtyAreaTop(top), m_nDirtyAreaBottom(bottom), m_nDirtyAreaLeft(left), + m_nDirtyAreaRight(right), m_nFirstVisualRow(fVisualRow), m_nFirstVisualColumn(fVisualColumn), + m_nLastVisualColumn(lVisualColumn), m_bAlternateBase(alternateBase) + { + + } + int m_nDirtyAreaTop; + int m_nDirtyAreaBottom; + int m_nDirtyAreaLeft; + int m_nDirtyAreaRight; + int m_nFirstVisualRow; + int m_nFirstVisualColumn; + int m_nLastVisualColumn; + bool m_bAlternateBase; +}; + +void GSpanCollection::addSpan(GSpanCollection::GSpan *span) +{ + spans.append(span); + Index::iterator it_y = m_nIndex.lowerBound(-span->top()); + + if (it_y == m_nIndex.end() || it_y.key() != -span->top()) + { + //there is no spans that starts with the row in the index, so create a sublist for it. + SubIndex sub_index; + + if (it_y != m_nIndex.end()) + { + //the previouslist is the list of spans that sarts _before_ the row of the span. + // and which may intersect this row. + const SubIndex c_previousList = it_y.value(); + foreach(GSpan * s, c_previousList) + { + //If a subspans intersect the row, we need to split it into subspans + if (s->bottom() >= span->top()) + { + sub_index.insert(-s->left(), s); + } + } + } + + it_y = m_nIndex.insert(-span->top(), sub_index); + //we will insert span to *it_y in the later loop + } + + //insert the span as supspan in all the lists that intesects the span + while (-it_y.key() <= span->bottom()) + { + (*it_y).insert(-span->left(), span); + + if (it_y == m_nIndex.begin()) + { + break; + } + + --it_y; + } +} + +void GSpanCollection::updateSpan(GSpanCollection::GSpan *span, int old_height) +{ + if (old_height < span->height()) + { + //add the span as subspan in all the lists that intersect the new covered columns + Index::iterator it_y = m_nIndex.lowerBound(-(span->top() + old_height - 1)); + Q_ASSERT(it_y != m_nIndex.end()); //it_y must exist since the span is in the list + + while (-it_y.key() <= span->bottom()) + { + (*it_y).insert(-span->left(), span); + + if (it_y == m_nIndex.begin()) + { + break; + } + + --it_y; + } + } + else if (old_height > span->height()) + { + //remove the span from all the subspans lists that intersect the columns not covered anymore + Index::iterator it_y = m_nIndex.lowerBound(-qMax(span->bottom(), span->top())); //qMax useful if height is 0 + Q_ASSERT(it_y != m_nIndex.end()); //it_y must exist since the span is in the list + + while (-it_y.key() <= span->top() + old_height - 1) + { + if (-it_y.key() > span->bottom()) + { + int nremoved = (*it_y).remove(-span->left()); + Q_ASSERT(nremoved == 1); + Q_UNUSED(nremoved); + + if (it_y->isEmpty()) + { + it_y = m_nIndex.erase(it_y); + } + } + + if (it_y == m_nIndex.begin()) + { + break; + } + + --it_y; + } + } + + if (span->width() == 0 && span->height() == 0) + { + spans.removeOne(span); + delete span; + } +} + +/** \internal + * \return a spans that spans over cell x,y (column,row) or 0 if there is none. + */ +GSpanCollection::GSpan *GSpanCollection::spanAt(int x, int y) const +{ + Index::const_iterator it_y = m_nIndex.lowerBound(-y); + + if (it_y == m_nIndex.end()) + { + return 0; + } + + SubIndex::const_iterator it_x = (*it_y).lowerBound(-x); + + if (it_x == (*it_y).end()) + { + return 0; + } + + GSpan *span = *it_x; + + if (span->right() >= x && span->bottom() >= y) + { + return span; + } + + return 0; +} + +/** \internal +* remove and deletes all spans inside the collection +*/ +void GSpanCollection::clear() +{ + m_nIndex.clear(); + qDeleteAll(spans); + spans.clear(); +} + +/** \internal + * return a list to all the spans that spans over cells in the given rectangle + */ +QList GSpanCollection::spansInRect(int x, int y, int w, int h) const +{ + QSet list; + Index::const_iterator it_y = m_nIndex.lowerBound(-y); + + if (it_y == m_nIndex.end()) + { + --it_y; + } + + while (-it_y.key() <= y + h) + { + SubIndex::const_iterator it_x = (*it_y).lowerBound(-x); + + if (it_x == (*it_y).end()) + { + --it_x; + } + + while (-it_x.key() <= x + w) + { + GSpan *pSpan = *it_x; + + if (pSpan->bottom() >= y && pSpan->right() >= x) + { + list << pSpan; + } + + if (it_x == (*it_y).begin()) + { + break; + } + + --it_x; + } + + if (it_y == m_nIndex.begin()) + { + break; + } + + --it_y; + } + + return list.toList(); +} + +#undef DEBUG_SPAN_UPDATE + +#ifdef DEBUG_SPAN_UPDATE +QDebug operator<<(QDebug str, const GSpanCollection::GSpan &span) +{ + str << "(" << span.top() << "," << span.left() << "," << span.bottom() << "," << span.right() << ")"; + return str; +} +#endif + +/** \internal +* Updates the span collection after row insertion. +*/ +void GSpanCollection::updateInsertedRows(int start, int end) +{ +#ifdef DEBUG_SPAN_UPDATE + qDebug() << Q_FUNC_INFO; + qDebug() << start << end; + qDebug() << index; +#endif + + if (spans.isEmpty()) + { + return; + } + + int ndelta = end - start + 1; +#ifdef DEBUG_SPAN_UPDATE + qDebug("Before"); +#endif + + for (SpanList::iterator it = spans.begin(); it != spans.end(); ++it) + { + GSpan *span = *it; +#ifdef DEBUG_SPAN_UPDATE + qDebug() << span << *span; +#endif + + if (span->m_bottom < start) + { + continue; + } + + if (span->m_top >= start) + { + span->m_top += ndelta; + } + + span->m_bottom += ndelta; + } + +#ifdef DEBUG_SPAN_UPDATE + qDebug("After"); + foreach(GSpanCollection::GSpan * span, spans) + qDebug() << span << *span; +#endif + + for (Index::iterator it_y = m_nIndex.begin(); it_y != m_nIndex.end();) + { + int ny = -it_y.key(); + + if (ny < start) + { + ++it_y; + continue; + } + + m_nIndex.insert(-ny - ndelta, it_y.value()); + it_y = m_nIndex.erase(it_y); + } + +#ifdef DEBUG_SPAN_UPDATE + qDebug() << index; +#endif +} + +/** \internal +* Updates the span collection after column insertion. +*/ +void GSpanCollection::updateInsertedColumns(int start, int end) +{ +#ifdef DEBUG_SPAN_UPDATE + qDebug() << Q_FUNC_INFO; + qDebug() << start << end; + qDebug() << index; +#endif + + if (spans.isEmpty()) + { + return; + } + + int ndelta = end - start + 1; +#ifdef DEBUG_SPAN_UPDATE + qDebug("Before"); +#endif + + for (SpanList::iterator it = spans.begin(); it != spans.end(); ++it) + { + GSpan *span = *it; +#ifdef DEBUG_SPAN_UPDATE + qDebug() << span << *span; +#endif + + if (span->m_right < start) + { + continue; + } + + if (span->m_left >= start) + { + span->m_left += ndelta; + } + + span->m_right += ndelta; + } + +#ifdef DEBUG_SPAN_UPDATE + qDebug("After"); + foreach(GSpanCollection::GSpan * span, spans) + qDebug() << span << *span; +#endif + + for (Index::iterator it_y = m_nIndex.begin(); it_y != m_nIndex.end(); ++it_y) + { + SubIndex &subindex = it_y.value(); + + for (SubIndex::iterator it = subindex.begin(); it != subindex.end();) + { + int nx = -it.key(); + + if (nx < start) + { + ++it; + continue; + } + + subindex.insert(-nx - ndelta, it.value()); + it = subindex.erase(it); + } + } + +#ifdef DEBUG_SPAN_UPDATE + qDebug() << index; +#endif +} + +/** \internal +* Cleans a subindex from to be deleted spans. The update argument is used +* to move the spans inside the subindex, in case their anchor changed. +* \return true if no span in this subindex starts at y, and should thus be deleted. +*/ +bool GSpanCollection::cleanSpanSubIndex(GSpanCollection::SubIndex &subindex, int y, bool update) +{ + if (subindex.isEmpty()) + { + return true; + } + + bool bshould_be_deleted = true; + SubIndex::iterator it = subindex.end(); + + do + { + --it; + int nx = -it.key(); + GSpan *span = it.value(); + + if (span->will_be_deleted) + { + it = subindex.erase(it); + continue; + } + + if (update && span->m_left != nx) + { + subindex.insert(-span->m_left, span); + it = subindex.erase(it); + } + + if (bshould_be_deleted && span->m_top == y) + { + bshould_be_deleted = false; + } + } + while (it != subindex.begin()); + + return bshould_be_deleted; +} + +/** \internal +* Updates the span collection after row removal. +*/ +void GSpanCollection::updateRemovedRows(int start, int end) +{ +#ifdef DEBUG_SPAN_UPDATE + qDebug() << Q_FUNC_INFO; + qDebug() << start << end; + qDebug() << index; +#endif + + if (spans.isEmpty()) + { + return; + } + + SpanList spansToBeDeleted; + int ndelta = end - start + 1; +#ifdef DEBUG_SPAN_UPDATE + qDebug("Before"); +#endif + + for (SpanList::iterator it = spans.begin(); it != spans.end();) + { + GSpan *span = *it; +#ifdef DEBUG_SPAN_UPDATE + qDebug() << span << *span; +#endif + + if (span->m_bottom < start) + { + ++it; + continue; + } + + if (span->m_top < start) + { + if (span->m_bottom <= end) + { + span->m_bottom = start - 1; + } + else + { + span->m_bottom -= ndelta; + } + } + else + { + if (span->m_bottom > end) + { + if (span->m_top <= end) + { + span->m_top = start; + } + else + { + span->m_top -= ndelta; + } + + span->m_bottom -= ndelta; + } + else + { + span->will_be_deleted = true; + } + } + + if (span->m_top == span->m_bottom && span->m_left == span->m_right) + { + span->will_be_deleted = true; + } + + if (span->will_be_deleted) + { + spansToBeDeleted.append(span); + it = spans.erase(it); + } + else + { + ++it; + } + } + +#ifdef DEBUG_SPAN_UPDATE + qDebug("After"); + foreach(GSpanCollection::GSpan * span, spans) + qDebug() << span << *span; +#endif + + if (spans.isEmpty()) + { + qDeleteAll(spansToBeDeleted); + m_nIndex.clear(); + return; + } + + Index::iterator it_y = m_nIndex.end(); + + do + { + --it_y; + int ny = -it_y.key(); + SubIndex &subindex = it_y.value(); + + if (ny < start) + { + if (cleanSpanSubIndex(subindex, ny)) + { + it_y = m_nIndex.erase(it_y); + } + } + else if (ny >= start && ny <= end) + { + bool bspan_at_start = false; + SubIndex spansToBeMoved; + + for (SubIndex::iterator it = subindex.begin(); it != subindex.end(); ++it) + { + GSpan *span = it.value(); + + if (span->will_be_deleted) + { + continue; + } + + if (!bspan_at_start && span->m_top == start) + { + bspan_at_start = true; + } + + spansToBeMoved.insert(it.key(), span); + } + + if (ny == start && bspan_at_start) + { + subindex.clear(); + } + else + { + it_y = m_nIndex.erase(it_y); + } + + if (bspan_at_start) + { + Index::iterator it_start; + + if (ny == start) + { + it_start = it_y; + } + else + { + it_start = m_nIndex.find(-start); + + if (it_start == m_nIndex.end()) + { + it_start = m_nIndex.insert(-start, SubIndex()); + } + } + + SubIndex &start_subindex = it_start.value(); + + for (SubIndex::iterator it = spansToBeMoved.begin(); it != spansToBeMoved.end(); ++it) + { + start_subindex.insert(it.key(), it.value()); + } + } + } + else + { + if (ny == end + 1) + { + Index::iterator it_top = m_nIndex.find(-ny + ndelta); + + if (it_top == m_nIndex.end()) + { + it_top = m_nIndex.insert(-ny + ndelta, SubIndex()); + } + + for (SubIndex::iterator it = subindex.begin(); it != subindex.end();) + { + GSpan *span = it.value(); + + if (!span->will_be_deleted) + { + it_top.value().insert(it.key(), span); + } + + ++it; + } + } + else + { + m_nIndex.insert(-ny + ndelta, subindex); + } + + it_y = m_nIndex.erase(it_y); + } + } + while (it_y != m_nIndex.begin()); + +#ifdef DEBUG_SPAN_UPDATE + qDebug() << index; + qDebug("Deleted"); + foreach(GSpanCollection::GSpan * span, spansToBeDeleted) + qDebug() << span << *span; +#endif + qDeleteAll(spansToBeDeleted); +} + +/** \internal +* Updates the span collection after column removal. +*/ +void GSpanCollection::updateRemovedColumns(int start, int end) +{ +#ifdef DEBUG_SPAN_UPDATE + qDebug() << Q_FUNC_INFO; + qDebug() << start << end; + qDebug() << index; +#endif + + if (spans.isEmpty()) + { + return; + } + + SpanList toBeDeleted; + int ndelta = end - start + 1; +#ifdef DEBUG_SPAN_UPDATE + qDebug("Before"); +#endif + + for (SpanList::iterator it = spans.begin(); it != spans.end();) + { + GSpan *span = *it; +#ifdef DEBUG_SPAN_UPDATE + qDebug() << span << *span; +#endif + + if (span->m_right < start) + { + ++it; + continue; + } + + if (span->m_left < start) + { + if (span->m_right <= end) + { + span->m_right = start - 1; + } + else + { + span->m_right -= ndelta; + } + } + else + { + if (span->m_right > end) + { + if (span->m_left <= end) + { + span->m_left = start; + } + else + { + span->m_left -= ndelta; + } + + span->m_right -= ndelta; + } + else + { + span->will_be_deleted = true; + } + } + + if (span->m_top == span->m_bottom && span->m_left == span->m_right) + { + span->will_be_deleted = true; + } + + if (span->will_be_deleted) + { + toBeDeleted.append(span); + it = spans.erase(it); + } + else + { + ++it; + } + } + +#ifdef DEBUG_SPAN_UPDATE + qDebug("After"); + foreach(GSpanCollection::GSpan * span, spans) + qDebug() << span << *span; +#endif + + if (spans.isEmpty()) + { + qDeleteAll(toBeDeleted); + m_nIndex.clear(); + return; + } + + for (Index::iterator it_y = m_nIndex.begin(); it_y != m_nIndex.end();) + { + int ny = -it_y.key(); + + if (cleanSpanSubIndex(it_y.value(), ny, true)) + { + it_y = m_nIndex.erase(it_y); + } + else + { + ++it_y; + } + } + +#ifdef DEBUG_SPAN_UPDATE + qDebug() << index; + qDebug("Deleted"); + foreach(GSpanCollection::GSpan * span, toBeDeleted) + qDebug() << span << *span; +#endif + qDeleteAll(toBeDeleted); +} + +#ifdef QT_BUILD_INTERNAL +/*! + \internal + Checks whether the span index structure is self-consistent, and consistent with the spans list. +*/ +/* +bool GSpanCollection::checkConsistency() const +{ + for (Index::const_iterator it_y = index.begin(); it_y != index.end(); ++it_y) + { + int y = -it_y.key(); + const SubIndex &subIndex = it_y.value(); + for (SubIndex::const_iterator it = subIndex.begin(); it != subIndex.end(); ++it) + { + int x = -it.key(); + Span *span = it.value(); + if (!spans.contains(span) || span->left() != x + || y < span->top() || y > span->bottom()) + { + return false; + } + } + } + + foreach (const Span *span, spans) + { + if (span->width() < 1 || span->height() < 1 + || (span->width() == 1 && span->height() == 1)) + { + return false; + } + for (int y = span->top(); y <= span->bottom(); ++y) + { + Index::const_iterator it_y = index.find(-y); + if (it_y == index.end()) + { + if (y == span->top()) + { + return false; + } + else + { + continue; + } + } + const SubIndex &subIndex = it_y.value(); + SubIndex::const_iterator it = subIndex.find(-span->left()); + if (it == subIndex.end() || it.value() != span) + { + return false; + } + } + } + return true; +} +*/ +#endif + +GLDTableViewPrivate::~GLDTableViewPrivate() +{ + m_oCommentFrames.clear(); +} + +void GLDTableViewPrivate::init() +{ + Q_Q(GLDTableView); + + q->setEditTriggers(m_editTriggers | GlodonAbstractItemView::AnyKeyPressed | GlodonAbstractItemView::SelectedClicked); + + GlodonHeaderView *vertical = new GlodonVHeaderView(q); + vertical->setClickable(true); + vertical->setHighlightSections(true); + q->setVerticalHeader(vertical); + + GlodonHeaderView *horizontal = new GlodonHHeaderView(q); + horizontal->setClickable(true); + horizontal->setHighlightSections(true); + q->setHorizontalHeader(horizontal); + + m_bTabKeyNavigation = true; + + m_cornerWidget = new GTableCornerbutton(q); + m_cornerWidget->setFocusPolicy(Qt::NoFocus); + QObject::connect(m_cornerWidget, SIGNAL(clicked()), q, SLOT(selectAll())); + + // override GlodonAbstractItemView default QStyledItemDelegate + q->setItemDelegate(new GlodonDefaultItemDelegate(q)); + + GlodonScrollBar *pHScrollBar = new GlodonScrollBar(Qt::Horizontal, q); + GlodonScrollBar *pVScrollBar = new GlodonScrollBar(Qt::Vertical, q); + + q->setHorizontalScrollBar(pHScrollBar); + q->setVerticalScrollBar(pVScrollBar); + + QObject::connect(pVScrollBar, SIGNAL(actionTriggered(int)), + q, SLOT(verticalScrollbarAction(int))); + QObject::connect(pHScrollBar, SIGNAL(actionTriggered(int)), + q, SLOT(horizontalScrollbarAction(int))); + QObject::connect(pVScrollBar, SIGNAL(valueChanged(int)), + q, SLOT(verticalScrollbarValueChanged(int))); + QObject::connect(pHScrollBar, SIGNAL(valueChanged(int)), + q, SLOT(horizontalScrollbarValueChanged(int))); + + q->setProperty("TableView", "GLDTableView"); + GLDScrollStyle *scrollStyle = new GLDScrollStyle(q, false); + scrollStyle->setIsShowArrow(false); + q->horizontalScrollBar()->setStyle(scrollStyle); + q->verticalScrollBar()->setStyle(scrollStyle); +} + +/*! + \internal + Trims away indices that are hidden in the treeview due to hidden horizontal or vertical sections. +*/ +void GLDTableViewPrivate::trimHiddenSelections(QItemSelectionRange *range) const +{ + Q_ASSERT(range && range->isValid()); + + int ntop = range->top(); + int nleft = range->left(); + int nbottom = range->bottom(); + int nright = range->right(); + + while (nbottom >= ntop && m_verticalHeader->isSectionHidden(nbottom)) + { + --nbottom; + } + + while (nright >= nleft && m_horizontalHeader->isSectionHidden(nright)) + { + --nright; + } + + if (ntop > nbottom || nleft > nright) // everything is hidden + { + *range = QItemSelectionRange(); + return; + } + + while (m_verticalHeader->isSectionHidden(ntop) && ntop <= nbottom) + { + ++ntop; + } + + while (m_horizontalHeader->isSectionHidden(nleft) && nleft <= nright) + { + ++nleft; + } + + if (ntop > nbottom || nleft > nright) // everything is hidden + { + *range = QItemSelectionRange(); + return; + } + + QModelIndex bottomRight = m_model->index(nbottom, nright, range->parent()); + QModelIndex topLeft = m_model->index(ntop, nleft, range->parent()); + *range = QItemSelectionRange(topLeft, bottomRight); +} + +/*! + \internal + Sets the span for the cell at (\a row, \a column). +*/ +void GLDTableViewPrivate::setSpan(int row, int column, int rowSpan, int columnSpan) +{ + if (row < 0 || column < 0 || rowSpan <= 0 || columnSpan <= 0) + { + qWarning() << "GLDTableView::setSpan: invalid span given: (" << row << ',' << column << + ',' << rowSpan << ',' << columnSpan << ')'; + return; + } + + GSpanCollection::GSpan *sp = m_spans.spanAt(column, row); + + if (sp) + { + if (sp->top() != row || sp->left() != column) + { +// qWarning() << "GLDTableView::setSpan: span cannot overlap"; + return; + } + + if (rowSpan == 1 && columnSpan == 1) + { + rowSpan = columnSpan = 0; + } + + const int c_old_height = sp->height(); + sp->m_bottom = row + rowSpan - 1; + sp->m_right = column + columnSpan - 1; + m_spans.updateSpan(sp, c_old_height); + return; + } + else if (rowSpan == 1 && columnSpan == 1) + { + qWarning() << "GLDTableView::setSpan: single cell span won't be added"; + return; + } + + sp = new GSpanCollection::GSpan(row, column, rowSpan, columnSpan); + m_spans.addSpan(sp); +} + +/*! + \internal + Gets the span information for the cell at (\a row, \a column). +*/ +GSpanCollection::GSpan GLDTableViewPrivate::span(int row, int column) const +{ + GSpanCollection::GSpan *sp = m_spans.spanAt(column, row); + + if (sp) + { + return *sp; + } + + return GSpanCollection::GSpan(row, column, 1, 1); +} + +/*! + \internal + Returns the logical index of the last section that's part of the span. +*/ +int GLDTableViewPrivate::sectionSpanEndLogical(const GlodonHeaderView *header, int logical, int span) const +{ + int nVisual = header->visualIndex(logical); + + for (int i = 1; i < span;) + { + if (++nVisual >= header->count()) + { + break; + } + + logical = header->logicalIndex(nVisual); + ++i; + } + + return logical; +} + +/*! + \internal + Returns the size of the span starting at logical index \a logical + and spanning \a span sections. +*/ +int GLDTableViewPrivate::sectionSpanSize(const GlodonHeaderView *header, int logical, int span) const +{ + int nendLogical = sectionSpanEndLogical(header, logical, span); + return header->sectionPosition(nendLogical) + - header->sectionPosition(logical) + + header->sectionSize(nendLogical); +} + +/*! + \internal + Returns true if the section at logical index \a logical is part of the span + starting at logical index \a spanLogical and spanning \a span sections; + otherwise, returns false. +*/ +bool GLDTableViewPrivate::spanContainsSection(const GlodonHeaderView *header, int logical, + int spanLogical, int span) const +{ + if (logical == spanLogical) + { + return true; // it's the start of the span + } + + int nVisual = header->visualIndex(spanLogical); + + for (int i = 1; i < span;) + { + if (++nVisual >= header->count()) + { + break; + } + + spanLogical = header->logicalIndex(nVisual); + + if (logical == spanLogical) + { + return true; + } + + ++i; + } + + return false; +} + +/*! + \internal + Returns the visual rect for the given \a span. +*/ +QRect GLDTableViewPrivate::visualSpanRect(const GSpanCollection::GSpan &span) const +{ + Q_Q(const GLDTableView); + + int nRow; + int nColumn; + spanTopRowLeftColumn(span, nRow, nColumn); + + QModelIndex oTopLeftIndex = m_model->index(nRow, nColumn, m_root); + QVariant oBoundLine = oTopLeftIndex.data(gidrBoundLineRole); + + QRect oVisualSpanRect = visualSpanRectIncludeBoundingLineWidth(span); + oVisualSpanRect.setWidth(oVisualSpanRect.width() - q->borderLineSubtractGridLineWidth(oBoundLine, true)); + oVisualSpanRect.setHeight(oVisualSpanRect.height() - q->borderLineSubtractGridLineWidth(oBoundLine, false)); + + return oVisualSpanRect; +} + +QRect GLDTableViewPrivate::visualSpanRectIncludeBoundingLineWidth(const GSpanCollection::GSpan &span) const +{ + int nRow; + int nColumn; + spanTopRowLeftColumn(span, nRow, nColumn); + + int nRowP = m_verticalHeader->sectionViewportPosition(nRow); + int nRowH = rowSpanHeight(nRow, span.height()); + + int nColP = m_horizontalHeader->sectionViewportPosition(nColumn); + int nColW = columnSpanWidth(nColumn, span.width()); + + return QRect(nColP, nRowP, nColW, nRowH); +} + +QRect GLDTableViewPrivate::visualRectIncludeBoundingLineWidth(const QModelIndex &index) const +{ + Q_Q(const GLDTableView); + + int nRowP = q->rowViewportPosition(index.row()); + int nRowH = q->rowHeight(index.row()); + int nColP = q->columnViewportPosition(index.column()); + int nColW = q->columnWidth(index.column()); + + return QRect(nColP, nRowP, nColW, nRowH); +} + +void GLDTableViewPrivate::spanTopRowLeftColumn(const GSpanCollection::GSpan &span, int &row, int &column) const +{ + Q_Q(const GLDTableView); + // vertical + row = span.top(); + + // horizontal + column = span.left(); + + if (q->isRightToLeft()) + { + column = span.right(); + } +} + +QRect GLDTableViewPrivate::viewportScrollArea(Qt::Orientation orientation) +{ + if (orientation == Qt::Horizontal) + { + int nleft = 0; + +// for (int i = 0; i < m_fixedColCount; i++) +// { +// nleft += m_horizontalHeader->sectionSize(i); +// } + + return QRect(nleft, 0, viewport->width() - nleft, viewport->height()); + } + else + { + int ntop = 0; + +// for (int i = 0; i < m_fixedRowCount; i++) +// { +// ntop += m_verticalHeader->sectionSize(i); +// } + + return QRect(0, ntop, viewport->width(), viewport->height() - ntop); + } +} + +QList GLDTableViewPrivate::getVisibleSpansAccordingToIsSectionMove( + int firstVisualRow, int firstVisualColumn, int lastVisualRow, int lastVisualColumn) +{ + QList visibleSpans; + bool bSectionMoved = m_verticalHeader->sectionsMoved() || m_horizontalHeader->sectionsMoved(); + + if (!bSectionMoved) + { + visibleSpans = m_spans.spansInRect(logicalColumn(firstVisualColumn), logicalRow(firstVisualRow), + lastVisualColumn - firstVisualColumn + 1, lastVisualRow - firstVisualRow + 1); + } + else + { + QSet set; + + for (int i = firstVisualColumn; i <= lastVisualColumn; i++) + { + for (int j = firstVisualRow; j <= lastVisualRow; j++) + { + set.insert(m_spans.spanAt(i, j)); + } + } + + set.remove(0); + visibleSpans = set.toList(); + } + + return visibleSpans; +} + +void GLDTableViewPrivate::adjustOptionAlternateFeature(QStyleOptionViewItem &opt, bool bAlternateBase) +{ + if (bAlternateBase) + { + opt.features |= QStyleOptionViewItem::Alternate; + } + else + { + opt.features &= ~QStyleOptionViewItem::Alternate; + } +} + +bool GLDTableViewPrivate::isRangeFillingHandleSelected(const QPoint &p) +{ + // 如果处于多选状态,则不允许拖拽复制 + if (isInMutiSelect() || m_selectionModel.isNull()) + { + return false; + } + + return m_oRangeFillHandleRect.contains(p); +} + +bool GLDTableViewPrivate::isInMutiSelect() const +{ + return m_bIsInMultiSelect; +} + +void GLDTableViewPrivate::drawComment(const QPersistentModelIndex &index) +{ + Q_Q(GLDTableView); + + // 显示注释内容 + if (q->state() == GlodonAbstractItemView::DragSelectingState) + return; + + if (m_pCommentFrame == NULL) + { + m_pCommentFrame = new GCommentFrame(q); + } + + if (index.isValid()) + { + GString sComment = q->model()->data(index, gidrCommentRole).toString(); + + if (sComment.isEmpty()) + { + m_pCommentFrame->hide(); + } + else + { + m_pCommentFrame->setCommentText(sComment); + m_pCommentFrame->move(q->visualRect(index).topRight() + q->viewport()->pos()); + m_pCommentFrame->show(); + } + } + else + { + m_pCommentFrame->hide(); + } +} + +void GLDTableViewPrivate::hideCommentFrame() +{ + if (m_pCommentFrame != NULL) + { + m_pCommentFrame->hide(); + } +} + +void GLDTableViewPrivate::setGridLineWidthToHorizontalHeader(int gridLineWidth) +{ + if (m_horizontalHeader == NULL) + return; + + m_horizontalHeader->setGridLineWidth(gridLineWidth); +} + +void GLDTableViewPrivate::setGridLineWidthToVertialHeader(int gridLineWidth) +{ + if (m_verticalHeader == NULL) + return; + + m_verticalHeader->setGridLineWidth(gridLineWidth); +} + +int GLDTableViewPrivate::heightHintForIndex(const QModelIndex &index, int nHint, QStyleOptionViewItem &option) const +{ + Q_Q(const GLDTableView); + + QWidget *editor = editorForIndex(index).widget.data(); + + if (editor && m_persistent.contains(editor)) + { + nHint = qMax(nHint, editor->sizeHint().height()); + int nMin = editor->minimumSize().height(); + int nMax = editor->maximumSize().height(); + nHint = qBound(nMin, nHint, nMax); + } + + if (m_bWrapItemText) // for wrapping boundaries + { + option.rect.setY(q->rowViewportPosition(index.row())); + + int nHeight = q->rowHeight(index.row()); + // if the option.height == 0 then q->itemDelegate(index)->sizeHint(option, index) will be wrong. + // The option.height == 0 is used to conclude that the text is not wrapped, and hence it will + // (exactly like widthHintForIndex) return a QSize with a long width (that we don't use) - + // and the height of the text if it was/is on one line. + // What we want is a height hint for the current width (and we know that this section is not hidden) + // Therefore we catch this special situation with: + if (nHeight == 0) + nHeight = 1; + + option.rect.setHeight(nHeight); + option.rect.setX(q->columnViewportPosition(index.column())); + option.rect.setWidth(q->columnWidth(index.column())); + } + + adjustRectWidthByTreeColumn(index, option.rect); + adjustRectWidthBySpan(index, option.rect); + // 水平margin的处理放到了delegate中 + + const int c_vertMargin = q->cellMargin(index, TopMargin); + return qMax(nHint, q->itemDelegate(index)->sizeHint(option, index).height() + c_vertMargin * 2); +} + +int GLDTableViewPrivate::calcSizeHintForRow(int row, const QList &oNeedCalcSizeHintCols) const +{ + Q_Q(const GLDTableView); + + if (!q->model()) + return -1; + + q->ensurePolished(); + + QStyleOptionViewItem option = viewOptionsV4(); + + int nHint = 0; + QModelIndex index; + + for (int i = 0; i < oNeedCalcSizeHintCols.count(); ++i) + { + int nLogicalColumn = m_horizontalHeader->logicalIndex(oNeedCalcSizeHintCols.at(i)); + + if (m_horizontalHeader->isSectionHidden(nLogicalColumn)) + { + continue; + } + + index = m_model->index(row, nLogicalColumn, m_root); + nHint = heightHintForIndex(index, nHint, option); + } + + return nHint; +} + +int GLDTableViewPrivate::widthHintForIndex(const QModelIndex &index, int hint, const QStyleOptionViewItem &option) const +{ + Q_Q(const GLDTableView); + + QWidget *editor = editorForIndex(index).widget.data(); + + if (editor && m_persistent.contains(editor)) + { + hint = qMax(hint, editor->sizeHint().width()); + int nMin = editor->minimumSize().width(); + int nMax = editor->maximumSize().width(); + hint = qBound(nMin, hint, nMax); + } + + //如果是树形结构显示,则因加上树形结构偏移 + const int c_nTreeOffset = q->treeCellDisplayHorizontalOffset(index.row(), index.column()); + hint = qMax(hint, q->itemDelegate(index)->sizeHint(option, index).width() + c_nTreeOffset); + return hint; +} + +int GLDTableViewPrivate::widthHintForIndex( + int visualRow, int column, int hint, const QStyleOptionViewItem &option) const +{ + int nLogicalRow = m_verticalHeader->logicalIndex(visualRow); + + if (m_verticalHeader->isSectionHidden(nLogicalRow)) + { + return hint; + } + + QModelIndex index = m_model->index(nLogicalRow, column, m_root); + return widthHintForIndex(index, hint, option); +} + +int GLDTableViewPrivate::sizeHintForColumn(int column, bool calcAllRows) const +{ + Q_Q(const GLDTableView); + + if (!q->model()) + { + return -1; + } + + q->ensurePolished(); + + QStyleOptionViewItem option = viewOptionsV4(); + + int nHint = 0; + for (int row = 0; row < m_nFixedRowCount; ++row) + { + nHint = widthHintForIndex(row, column, nHint, option); + } + + int nTop = q->firstVisualRow(); + int nBottom = q->lastVisualRow(); + + if (calcAllRows) + { + nTop = 0; + nBottom = m_verticalHeader->count() - 1; + } + else + { + q->adjustVisualRow(nTop, nBottom); + } + + if (!q->isVisible() || nBottom == -1) // the table don't have enough rows to fill the viewport + { + nBottom = m_verticalHeader->count() - 1; + } + + for (int row = nTop; row <= nBottom; ++row) + { + nHint = widthHintForIndex(row, column, nHint, option); + } + + return nHint; +} + +void GLDTableViewPrivate::calcFixedColSuitWidth(bool &shouldResetCommentPosition) +{ + QMap oUpdateFixedColWidths; + if (m_nFixedColCount > 0) + { + for (int nCol = 0; nCol < m_nFixedColCount; ++nCol) + { + if (isColumnHidden(nCol) || !m_oSuitColWidthCols.contains(nCol)) + continue; + + oUpdateFixedColWidths.insert(nCol, calcSuitWidth(nCol, m_bCalcAllRows)); + shouldResetCommentPosition = true; + } + + if (oUpdateFixedColWidths.count() > 0) + { + m_horizontalHeader->batchResizeSection(oUpdateFixedColWidths); + } + } +} + +void GLDTableViewPrivate::calcNormalColSuitWidth(bool &shouldResetCommentPosition) +{ + Q_Q(GLDTableView); + + int nCurVisualCol = q->firstVisualCol(); + + // dousp 当前第一可见列小于0时,不进行操作 + if (nCurVisualCol < 0) + { + return; + } + + int nColCount = m_horizontalHeader->count(); + + int nViewportWidth = viewport->width(); + + int nVisualColWidthTotal = 0; + + QMap oUpdateColWidths; + + // TODO liurx 如果最后一列是合适列宽列,且倒数第二列的列宽超过viewport的宽度时,最后一列合适列宽不会计算。这是一个bug + while ((nVisualColWidthTotal <= nViewportWidth) && (nCurVisualCol < nColCount)) + { + int nCurLogicalCol = m_horizontalHeader->logicalIndex(nCurVisualCol); + + if (isColumnHidden(nCurLogicalCol)) + { + nCurVisualCol++; + continue; + } + + int nCurOldColWidth = q->columnWidth(nCurLogicalCol); + + if (m_oSuitColWidthCols.indexOf(nCurLogicalCol) < 0) + { + nVisualColWidthTotal += nCurOldColWidth; + nCurVisualCol++; + continue; + } + + const int nMaxWidth = calcSuitWidth(nCurLogicalCol, m_bCalcAllRows); + if (nMaxWidth != nCurOldColWidth) + { + shouldResetCommentPosition = true; + oUpdateColWidths.insert(nCurLogicalCol, nMaxWidth); + m_columnsToUpdate.append(nCurLogicalCol); + } + + nVisualColWidthTotal += nMaxWidth; + nCurVisualCol++; + } + + m_horizontalHeader->batchResizeSection(oUpdateColWidths); +} + +void GLDTableViewPrivate::calcFixedRowSuitHeight(const QList &oNeedCalcHeightCols, bool &shouldResetCommentPosition) +{ + Q_Q(GLDTableView); + + QMap oUpdateRowHeights; + for (int nRow = 0; nRow < m_nFixedRowCount; ++nRow) + { + int nCurLogicalRow = m_verticalHeader->logicalIndex(nRow); + + if (q->isRowHidden(nCurLogicalRow)) + continue; + + const int nMaxRowHeight = calcSuitHeight(oNeedCalcHeightCols, nCurLogicalRow); + + if (nMaxRowHeight != q->rowHeight(nCurLogicalRow)) + { + shouldResetCommentPosition = true; + oUpdateRowHeights.insert(nCurLogicalRow, nMaxRowHeight); + m_rowsToUpdate.append(nCurLogicalRow); + } + } + m_verticalHeader->batchResizeSection(oUpdateRowHeights); +} + +void GLDTableViewPrivate::calcNormalRowSuitHeight(const QList &oNeedCalcHeightCols, bool &shouldResetCommentPosition) +{ + Q_Q(GLDTableView); + + int nTotalRowHeight = 0; + int nCurVisualRow = q->firstVisualRow(); + + int nRowCount = m_verticalHeader->count(); + QMap oUpdateRowHeights; + + while ((nTotalRowHeight <= viewport->height()) && (nCurVisualRow < nRowCount)) + { + int nCurLogicalRow = m_verticalHeader->logicalIndex(nCurVisualRow); + + if (q->isRowHidden(nCurLogicalRow)) + { + nCurVisualRow++; + continue; + } + + const int nMaxRowHeight = calcSuitHeight(oNeedCalcHeightCols, nCurLogicalRow); + + if (nMaxRowHeight != q->rowHeight(nCurLogicalRow)) + { + shouldResetCommentPosition = true; + oUpdateRowHeights.insert(nCurLogicalRow, nMaxRowHeight); + m_rowsToUpdate.append(nCurLogicalRow); + } + + nTotalRowHeight += nMaxRowHeight + q->currentGridLineWidth(); + nCurVisualRow++; + } + + m_verticalHeader->batchResizeSection(oUpdateRowHeights); +} + +int GLDTableViewPrivate::calcSuitWidth(int nCol, bool calcAllRows) +{ + Q_Q(GLDTableView); + + int nHorizontalHeaderSectionSizeHint = m_horizontalHeader->sectionSizeHint(nCol); + QModelIndex oCurIndex = q->model()->index(0, nCol); + + const int nDefaultColWidth = q->dataIndex(oCurIndex).data(gidrColWidthRole).toInt(); + int nCalcColWidth = sizeHintForColumn(nCol, calcAllRows); + nCalcColWidth = qMax(nHorizontalHeaderSectionSizeHint, nCalcColWidth); + + return qMax(nCalcColWidth, nDefaultColWidth); +} + +int GLDTableViewPrivate::calcSuitHeight(const QList &oNeedCalcHeightCols, int nLogicalRow) +{ + Q_Q(GLDTableView); + + QModelIndex oCurIndex = q->model()->index(nLogicalRow, 0); + + const int nCalcRowHeight = calcSizeHintForRow(nLogicalRow, oNeedCalcHeightCols); + const int nDefaultRowHeight = defaultRowHeight(oCurIndex); + + return qMax(nDefaultRowHeight, nCalcRowHeight); +} + +void GLDTableViewPrivate::adjustRectWidthByTreeColumn(const QModelIndex &index, QRect &rect) const +{ + Q_Q(const GLDTableView); + rect.setWidth(rect.width() - q->treeCellDisplayHorizontalOffset(index.row(), index.column(), false)); +} + +void GLDTableViewPrivate::adjustRectWidthBySpan(const QModelIndex &index, QRect &rect) const +{ + Q_Q(const GLDTableView); + int nColumnSpanCount = columnSpan(index.row(), index.column()); + + int nSpanExtraWidth = 0; + for (int i = 1; i < nColumnSpanCount; ++i) + { + nSpanExtraWidth += (q->columnWidth(index.column() + i) + q->gridLineWidth()); + } + rect.setWidth(rect.width() + nSpanExtraWidth); +} + +QColor GLDTableViewPrivate::getPenColor() +{ + Q_Q(GLDTableView); + + if (q->hasFocus()) + { + return m_selectBoundLineColor; + } + else + { + if (q->isEditing()) + { + return m_selectBoundLineColor; + } + else + { + return m_oNoFocusSelectedBoundLineColor; + } + } +} + +bool GLDTableViewPrivate::isNearHorizontalGridLine(QMouseEvent *event) +{ + return m_horizontalHeader->getSectionHandleAt(event->x()) != -1; +} + +bool GLDTableViewPrivate::isNearVerticalGridLine(QMouseEvent *event) +{ + return m_verticalHeader->getSectionHandleAt(event->y()) != -1; +} + +void GLDTableViewPrivate::doAdjustColWidths(int currentResizeCol) +{ + GIntList oOriginColWidths = getOriginColWidthsFromView(); + + // 如果没有列时,直接返回 + if (oOriginColWidths.size() == 0) + { + return; + } + + m_nCurrentResizeCol = currentResizeCol; + // 计算合适列宽 + adjustFitColWidths(oOriginColWidths); +} + +void GLDTableViewPrivate::adjustFitColWidths(GIntList &originColWidths) +{ + int nCurrentResizeColWidth = 0; + if (m_nCurrentResizeCol != -1) + { + nCurrentResizeColWidth = m_currResizeWidth; + } + + // 获取设置了合适列宽列的宽度 + GIntList oAdjustedColsWidth = getAdjustedColWidths(originColWidths, nCurrentResizeColWidth); + + // 获取现有全部列的列宽.(如果当前正在调整某列宽度,就用调整后的宽度计算) + const int nOriginTotalColWidth = getTotalColWidth(originColWidths, nCurrentResizeColWidth); + // 比较是否需要计算合适列宽时,合适列宽列应该用默认列宽计算 + int nMinOriginTotalColWidth = getMinTotalColWidth(originColWidths, nOriginTotalColWidth); + + const int nViewportWidth = viewport->width(); + + // 如果现在列的宽度已经大于viewport的宽度了,那就不需要计算了 + if (nMinOriginTotalColWidth >= nViewportWidth) + { + if (m_nCurrentResizeCol != -1) + { + originColWidths.replace(m_nCurrentResizeCol, nCurrentResizeColWidth); + } + + applyAdjustFitColsWidth(originColWidths, oAdjustedColsWidth); + } + else + { + int nOldAdjustColsTotalWidth = 0; + int nCurrentResizeColIndexInFitCols = -1; + + // 先计算合适列宽的列的总宽度(除当前正在调整列宽的列) + calcOldAdjustColsTotalWidth(oAdjustedColsWidth, nOldAdjustColsTotalWidth, nCurrentResizeColIndexInFitCols); + + int nNewAdjustColsTotalWidth = 0; + int nAvailableAdjustWidth = nViewportWidth - nOriginTotalColWidth; + + // 调整合适列宽每列的宽度,使屏幕充满 + calcAdjustColsWidth(nAvailableAdjustWidth, nOldAdjustColsTotalWidth, oAdjustedColsWidth, nNewAdjustColsTotalWidth); + + // 当前调整列宽的列为合适列宽的列 + if (nCurrentResizeColIndexInFitCols != -1) + { + // TODO liurx, 既然是合适列宽的列,宽度总是需要调整的,为什么还需要特殊处理并写回到originWidths + adjustOriginColWidthWhenResizeColIsInFitCols( + oAdjustedColsWidth, nCurrentResizeColIndexInFitCols, + nCurrentResizeColWidth, originColWidths); + } + else if (m_nCurrentResizeCol != -1) + { + originColWidths.replace(m_nCurrentResizeCol, nCurrentResizeColWidth); + } + + // 把计算的误差,加到最后一个合适列宽列上 + nAvailableAdjustWidth = nOldAdjustColsTotalWidth + nAvailableAdjustWidth - nNewAdjustColsTotalWidth; + oAdjustedColsWidth.replace(oAdjustedColsWidth.size() - 1, oAdjustedColsWidth.last() + nAvailableAdjustWidth); + + applyAdjustFitColsWidth(originColWidths, oAdjustedColsWidth); + } +} + +void GLDTableViewPrivate::mergeOriginColsWidthAndAdjustColsWidth( + GIntList &colWidths, const GIntList &originColsWidth, const GIntList &adjustColsWidth) +{ + for (int i = 0; i < originColsWidth.size(); ++i) + { + if (i != m_nCurrentResizeCol) + { + colWidths.append(originColsWidth.at(i)); + } + else + { + colWidths.append(m_currResizeWidth); + } + } + + for (int i = 0; i < m_oFitColWidthCols.size(); ++i) + { + if (colWidths.at(m_oFitColWidthCols.at(i)) != 0) + { + colWidths.replace(m_oFitColWidthCols.at(i), adjustColsWidth.at(i));//自动列宽调整 + } + } +} + +void GLDTableViewPrivate::applyAdjustFitColsWidth( + const GIntList &originColsWidth, const GIntList &adjustColsWidth) +{ + Q_ASSERT(adjustColsWidth.size() == m_oFitColWidthCols.size()); + + GIntList colWidths; + mergeOriginColsWidthAndAdjustColsWidth(colWidths, originColsWidth, adjustColsWidth); + + QMap oUpdateColsWidth; + for (int i = 0; i < originColsWidth.size(); ++i) + { + oUpdateColsWidth.insert(i, colWidths.at(i)); + } + m_horizontalHeader->batchResizeSection(oUpdateColsWidth); +} + +GIntList GLDTableViewPrivate::getAdjustedColWidths( + const GIntList &originColWidths, int currentResizeColWidth) +{ + GIntList oAdjustedColWidths; + + for (int i = 0; i < m_oFitColWidthCols.size(); ++i) + { + if (m_oFitColWidthCols.at(i) != m_nCurrentResizeCol) + { + oAdjustedColWidths.append(originColWidths.at(m_oFitColWidthCols.at(i))); + } + else + { + oAdjustedColWidths.append(currentResizeColWidth); + } + } + + return oAdjustedColWidths; +} + +void GLDTableViewPrivate::adjustOriginColWidthWhenResizeColIsInFitCols( + const GIntList &adjustedColWidths, int currentResizeColIndexInFitCols, int currentResizeColWidth, + GIntList &originColWidths) +{ + if ((m_oFitColWidthCols.size() == 1)) + { + if (m_nCurrentResizeCol != -1) + { + originColWidths.replace(m_nCurrentResizeCol, currentResizeColWidth); + } + } + else + { + int nIndex = 0; + + for (int i = 0; i < m_oFitColWidthCols.size(); ++i) + { + if (m_oFitColWidthCols.at(i) != m_nCurrentResizeCol) + { + nIndex = i; + break; + } + } + + if (adjustedColWidths.at(nIndex) != 0) + { + currentResizeColWidth = (int)(originColWidths.at(m_oFitColWidthCols.at(nIndex)) + * adjustedColWidths.at(currentResizeColIndexInFitCols) / adjustedColWidths.at(nIndex)); + } + + originColWidths.replace(m_nCurrentResizeCol, currentResizeColWidth); + } +} + +void GLDTableViewPrivate::calcOldAdjustColsTotalWidth( + const GIntList &oAdjustedColsWidth, int &nOldAdjustColsTotalWidth, int &nCurrentResizeColIndexInFitCols) +{ + Q_Q(GLDTableView); + + for (int i = 0; i < m_oFitColWidthCols.size(); ++i) + { + int nCurrentCol = m_oFitColWidthCols.at(i); + if (nCurrentCol != m_nCurrentResizeCol) + { + nOldAdjustColsTotalWidth += oAdjustedColsWidth.at(i) + (isColumnHidden(nCurrentCol) ? 0 : q->currentGridLineWidth()); + } + else + { + nCurrentResizeColIndexInFitCols = i; + } + } +} + +void GLDTableViewPrivate::calcAdjustColsWidth( + const int nAvailableAdjustWidth, const int nOldAdjustColsTotalWidth, GIntList &oAdjustedColsWidth, + int &nNewAdjustColsTotalWidth) +{ + Q_Q(GLDTableView); + + double dAdjustFactor = 0; + + if (nOldAdjustColsTotalWidth != 0) + { + dAdjustFactor = (nOldAdjustColsTotalWidth + nAvailableAdjustWidth) * 1.0 / nOldAdjustColsTotalWidth; + } + else + { + dAdjustFactor = 0; + } + + for (int i = 0; i < oAdjustedColsWidth.size(); ++i) + { + if (m_oFitColWidthCols.at(i) != m_nCurrentResizeCol) + { + oAdjustedColsWidth.replace(i, (int)(oAdjustedColsWidth.at(i) * dAdjustFactor)); + nNewAdjustColsTotalWidth += oAdjustedColsWidth.at(i) + (oAdjustedColsWidth.at(i) == 0 ? 0 : q->currentGridLineWidth()); + } + } +} + +int GLDTableViewPrivate::getTotalColWidth(const GIntList &originColsWidth, int nColWidth) +{ + Q_Q(GLDTableView); + + int nOriginTotalColWidth = 0; + + for (int i = 0; i < originColsWidth.size(); ++i) + { + nOriginTotalColWidth += originColsWidth.at(i) + (isColumnHidden(i) ? 0 : q->currentGridLineWidth()); + } + + if (m_nCurrentResizeCol != -1) + { + nOriginTotalColWidth = nOriginTotalColWidth - originColsWidth.at(m_nCurrentResizeCol) + nColWidth; + } + + return nOriginTotalColWidth; +} + +GIntList GLDTableViewPrivate::getOriginColWidthsFromView() +{ + GIntList oOriginColWidths; + + // TODO liurx delphi获取originColWidth时,如果是合适列宽列的话获取的是calcedWidth,否则获取的是displayWidth + for (int i = 0; i < m_horizontalHeader->count(); ++i) + { + int nColWidth = m_horizontalHeader->sectionSize(i); + oOriginColWidths.push_back(nColWidth); + } + + return oOriginColWidths; +} + +int GLDTableViewPrivate::getMinTotalColWidth(const GIntList &originColWidths, const int nOriginTotalColWidth) +{ + int nMinOriginTotalColWidth = nOriginTotalColWidth; + for (int i = 0; i < originColWidths.count(); ++i) + { + if ((i != m_nCurrentResizeCol) && m_oFitColWidthCols.contains(i)) + { + int nDefaultColWidth = getDefaultColWidth(i); + // 当合适列宽列的宽度小于默认值时,取实际宽度即可,否则差值会被加到其他合适列宽列上 + // 导致其他合适列宽列的宽度大于默认值时,就会出现滚动条 + if (nDefaultColWidth < originColWidths.at(i)) + { + nMinOriginTotalColWidth = nMinOriginTotalColWidth - originColWidths.at(i) + nDefaultColWidth; + } + } + } + return nMinOriginTotalColWidth; +} + +int GLDTableViewPrivate::getDefaultColWidth(int col) +{ + Q_Q(GLDTableView); + + QModelIndex oIndex = q->model()->index(0, col); + QVariant oColWidth = oIndex.data(gidrColWidthRole); + + int nColWidth = -1; + if (oColWidth.isValid()) + { + nColWidth = oColWidth.toInt(); + } + else + { + nColWidth = m_horizontalHeader->defaultSectionSize(); + } + + return nColWidth; +} + +bool GLDTableViewPrivate::isVisibleIndex(const QModelIndex &visualIndex) +{ + Q_Q(GLDTableView); + + bool bIsVisibleInHorizontal = (visualIndex.column() >= q->firstVisualCol()) && (visualIndex.column() <= q->lastVisualCol()); + if (m_nFixedColCount > 0) + { + bIsVisibleInHorizontal = bIsVisibleInHorizontal || (visualIndex.column() >= 0 && visualIndex.column() < m_nFixedColCount); + } + + bool bIsVisibleInVertical = (visualIndex.row() >= q->firstVisualRow()) && (visualIndex.row() <= q->lastVisualRow()); + if (m_nFixedRowCount > 0) + { + bIsVisibleInVertical = bIsVisibleInVertical || (visualIndex.row() >= 0 && visualIndex.row() < m_nFixedRowCount); + } + + return bIsVisibleInHorizontal && bIsVisibleInVertical; +} + +int GLDTableViewPrivate::defaultRowHeight(const QModelIndex &logicalIndex) +{ + int nDefaultRowHeight = m_verticalHeader->defaultSectionSize(); + QVariant oDefaultRowHeight = logicalIndex.data(gidrRowHeightRole); + if (oDefaultRowHeight.isValid()) + { + nDefaultRowHeight = oDefaultRowHeight.toInt(); + } + + return nDefaultRowHeight; +} + +bool GLDTableViewPrivate::isInTableView(QMouseEvent *event) +{ + QPoint oGlobalBottomRight = viewport->mapToGlobal(viewport->rect().bottomRight()); + QPoint oMousePoint = QCursor::pos(); + bool bInViewport = oGlobalBottomRight.x() > oMousePoint.x() && oGlobalBottomRight.y() > oMousePoint.y(); + + return bInViewport; +} + +QPoint GLDTableViewPrivate::calcResizeInfoLineFramePosition(Qt::Orientation direction) +{ + QPoint oDestPoint; + if (direction == Qt::Horizontal) + { + oDestPoint = viewport->mapToGlobal( + QPoint(m_horizontalHeader->mousePosition().x(), 0)); + } + else + { + oDestPoint = viewport->mapToGlobal( + QPoint(0, m_verticalHeader->mousePosition().y())); + } + + return oDestPoint; +} + +void GLDTableViewPrivate::fillSuitColWidthCols() +{ + Q_Q(GLDTableView); + + if (m_bAllColumnsResizeToContents) + { + m_oSuitColWidthCols.clear(); + for (int nCol = 0; nCol < q->model()->columnCount(); ++nCol) + { + m_oSuitColWidthCols << nCol; + } + } +} + +void GLDTableViewPrivate::fillSuitRowHeightCols() +{ + Q_Q(GLDTableView); + + if (m_bAllRowsResizeToContents) + { + m_oSuitRowHeightAccordingCols.clear(); + for (int nCol = 0; nCol < q->model()->columnCount(); ++nCol) + { + m_oSuitRowHeightAccordingCols << nCol; + } + } +} + +/*! + \internal + Draws the spanning cells within rect \a area, and clips them off as + preparation for the main drawing loop. + \a drawn is a QBitArray of visualRowCountxvisualCoulumnCount which say if particular cell has been drawn +*/ +void GLDTableViewPrivate::drawAndClipSpans(const QRegion &area, QPainter *painter, + const QStyleOptionViewItem &option, QBitArray *drawn, + int firstVisualRow, int lastVisualRow, int firstVisualColumn, + int lastVisualColumn) +{ + Q_Q(GLDTableView); + + bool bAlternateBase = false; + QRegion excludeSpansRegion = viewport->rect(); + + QList visibleSpans = getVisibleSpansAccordingToIsSectionMove( + firstVisualRow, firstVisualColumn, lastVisualRow, lastVisualColumn); + + foreach(GSpanCollection::GSpan * span, visibleSpans) + { + int row = span->top(); + int col = span->left(); + + if (m_verticalHeader->isSectionHidden(row) || m_horizontalHeader->isSectionHidden(col)) + { + continue; + } + + QModelIndex index = m_model->index(row, col, m_root); + + if (!index.isValid()) + { + continue; + } + + QRect rect = visualSpanRect(*span); + rect.translate(m_scrollDelayOffset); + + if (isCoverByFixedColumn(index.column(), rect.right(), false) || !area.intersects(rect)) + { + continue; + } + + if (isCoverByFixedRow(index.row(), rect.bottom(), false) || !area.intersects(rect)) + { + continue; + } + + QStyleOptionViewItem opt = option; + opt.rect = rect; + + // 如果合并格被固定列覆盖了一部分,那应该只绘制未被覆盖的部分 + QRect oPainterRect = rect; + if (rect.left() < m_nFixedColWidth && rect.right() > m_nFixedColWidth) + { + oPainterRect.setLeft(m_nFixedColWidth); + } + + // 如果合并格被固定行覆盖了一部分,那应该只绘制未被覆盖的部分 + if (rect.top() < m_nFixedRowHeight && rect.bottom() > m_nFixedRowHeight) + { + oPainterRect.setTop(m_nFixedRowHeight); + } + + bAlternateBase = m_bAlternatingColors && (1 == (span->top() & 1)); + adjustOptionAlternateFeature(opt, bAlternateBase); + + painter->setClipRect(oPainterRect); + + drawCell(painter, opt, index); + + //合并单元格的计算貌似在水平方向差了一个像素,安装着急发版,先这么处理下,后续需要找一下这一像素的差距的原因 + //bug GQI-40275 + if(m_horizontalHeader->isSectionHidden(span->right())) + oPainterRect.adjust(0, 0, - q->gridLineWidth(), 0); + if(m_verticalHeader->isSectionHidden(span->bottom())) + oPainterRect.adjust(0, 0, 0, - q->gridLineWidth()); + + excludeSpansRegion -= oPainterRect; + + for (int row = span->top(); row <= span->bottom(); ++row) + { + const int c_vr = visualRow(row); + + if (c_vr < firstVisualRow || c_vr > lastVisualRow) + { + continue; + } + + for (int col = span->left(); col <= span->right(); ++col) + { + const int c_vc = visualColumn(col); + + if (c_vc < firstVisualColumn || c_vc > lastVisualColumn) + { + continue; + } + + drawn->setBit((c_vr - firstVisualRow) * (lastVisualColumn - firstVisualColumn + 1) + + c_vc - firstVisualColumn); + } + } + } + painter->setClipRegion(excludeSpansRegion); +} + +void GLDTableViewPrivate::_q_updateSpanInsertedRows(const QModelIndex &parent, int start, int end) +{ + Q_UNUSED(parent) + m_spans.updateInsertedRows(start, end); +} + +void GLDTableViewPrivate::_q_updateSpanInsertedColumns(const QModelIndex &parent, int start, int end) +{ + Q_UNUSED(parent) + m_spans.updateInsertedColumns(start, end); +} + +void GLDTableViewPrivate::_q_updateSpanRemovedRows(const QModelIndex &parent, int start, int end) +{ + Q_UNUSED(parent) + m_spans.updateRemovedRows(start, end); +} + +void GLDTableViewPrivate::_q_updateSpanRemovedColumns(const QModelIndex &parent, int start, int end) +{ + Q_UNUSED(parent) + m_spans.updateRemovedColumns(start, end); +} + +void GLDTableViewPrivate::drawTriangles(QRect rect, QPainter *painter) +{ + // TODO liurx 绘制得有点瑕疵,和excel不一样 + QPolygon oPoints; + oPoints.append(QPoint(rect.right() - c_nCommentTriangleRightLength, rect.top())); + oPoints.append(QPoint(rect.right(), rect.top())); + oPoints.append(QPoint(rect.right(), rect.top() + c_nCommentTriangleRightLength)); + + painter->save(); + + QColor color = Qt::red; + + QPen pen(color); + painter->setPen(pen); + + QBrush brush(color); + painter->setBrush(brush); + + painter->drawConvexPolygon(oPoints); + + painter->restore(); +} + +void GLDTableViewPrivate::drawTriangles(QPainter *painter, const QStyleOptionViewItem &opt, const QModelIndex &index) +{ + GString str = m_model->data(index, gidrCommentRole).toString(); + + if (str.length() > 0) + { + drawTriangles(opt.rect, painter); + } +} + +void GLDTableViewPrivate::itemDelegatePaint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) +{ + Q_Q(GLDTableView); + + q->style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &option, painter, q); + q->itemDelegate(index)->paint(painter, option, index); +} + +void GLDTableViewPrivate::setOptionSelectedState(QStyleOptionViewItem& opt, const QModelIndex &index) +{ + Q_Q(GLDTableView); + + if (m_selectionModel) + { + if(m_selectionModel->isSelected(index) || m_selectionModel->isRowSelected(index.row(), index.parent())) + { + opt.state |= QStyle::State_Selected; + } + } + + if (m_alwaysShowRowSelectedColor) + { + if (index.row() == q->currentIndex().row()) + { + opt.state |= QStyle::State_Selected; + } + } +} + +void GLDTableViewPrivate::setOptionEnabledState(QStyleOptionViewItem& opt, const QModelIndex &index) +{ + if (opt.state & QStyle::State_Enabled) + { + QPalette::ColorGroup cg; + + if ((m_model->flags(index) & Qt::ItemIsEnabled) == 0) + { + opt.state &= ~QStyle::State_Enabled; + cg = QPalette::Disabled; + } + else + { + cg = QPalette::Normal; + } + + opt.palette.setCurrentColorGroup(cg); + } +} + +void GLDTableViewPrivate::setOptionMouseOverState(const QModelIndex &index, QStyleOptionViewItem& opt) +{ + if (index == m_hover) + { + opt.state |= QStyle::State_MouseOver; + } +} + +void GLDTableViewPrivate::setOptionHasFocusState(const QModelIndex &index, QStyleOptionViewItem& opt) +{ + Q_Q(GLDTableView); + + if (index == q->currentIndex()) + { + const bool c_focus = (q->hasFocus() || viewport->hasFocus()) && q->currentIndex().isValid(); + + if (c_focus) + { + opt.state |= QStyle::State_HasFocus; + } + + if (index.row() == m_oEditorIndex.row()) + { + opt.state |= QStyle::State_HasFocus; + opt.state |= QStyle::State_Active; + opt.showDecorationSelected = true; + } + } +} + +QItemSelection GLDTableViewPrivate::getItemSelectionAccordingToSelectState() +{ + Q_Q(GLDTableView); + + QItemSelection selection; + + // 如果选择区域有多个,那么就只绘制currentIndex的选择边框线 + if (isInMutiSelect()) + { + selection = QItemSelection(q->currentIndex(), q->currentIndex()); + } + else + { + selection = m_selectionModel.data()->selection(); + } + + return selection; +} + +void GLDTableViewPrivate::adjustSelectionBoundingRectAccordingToFixedColumn(const QRegion &bordingRegion, QRect &srcRect) +{ + Q_Q(GLDTableView); + + // 如果选择的区域有一部分在固定列中,当滚动条滚动,使不在固定列中的选中区域,被固定列覆盖时,就应该只绘制在固定列部分的选中区域边框线 + if (m_oTopLeftSelectIndex.column() < m_nFixedColCount && m_oBottomRightSelectIndex.column() >= m_nFixedColCount) + { + // 非固定列区域被覆盖一部分 + if (srcRect.left() < m_nFixedColWidth && srcRect.right() > m_nFixedColWidth) + { + srcRect.setLeft(m_horizontalHeader->sectionVisualPosition(m_oTopLeftSelectIndex.column())); + } + // 非固定列区域完全被固定列区域覆盖时 + else if (srcRect.right() <= m_nFixedColWidth) + { + srcRect.setRight(m_nFixedColWidth - q->currentGridLineWidth()); + srcRect.setLeft(m_horizontalHeader->sectionVisualPosition(m_oTopLeftSelectIndex.column())); + + // bordingRegion为空,是因为上层的visualRegionForSelection方法计算出的Rect的right比left小,有固定列,把滚动条拉到最后时会出现 + // 导致转换出来的QRegion无效,此时,应该重新计算top和bottom,保证绘制正确 + if (bordingRegion.isEmpty()) + { + int nTop = q->rowViewportPosition(m_oTopLeftSelectIndex.row()); + int nBottom = q->rowViewportPosition(m_oBottomRightSelectIndex.row()) + q->rowHeight(m_oBottomRightSelectIndex.row()); + srcRect.setTop(nTop); + srcRect.setBottom(nBottom); + } + } + } + else if (m_oTopLeftSelectIndex.column() >= m_nFixedColCount) + { + if (srcRect.right() <= m_nFixedColWidth) + { + srcRect = QRect(); + } + else if (srcRect.right() > m_nFixedColWidth && srcRect.left() < m_nFixedColWidth) + { + srcRect.setLeft(m_nFixedColWidth); + } + } +} + +void GLDTableViewPrivate::adjustSelectionBoundingRectAccordingToFixedRow(const QRegion &bordingRegion, QRect &srcRect) +{ + Q_Q(GLDTableView); + if (m_oTopLeftSelectIndex.row() < m_nFixedRowCount && m_oBottomRightSelectIndex.row() >= m_nFixedRowCount) + { + if (srcRect.top() < m_nFixedRowHeight && srcRect.bottom() > m_nFixedRowHeight) + { + srcRect.setTop(m_verticalHeader->sectionVisualPosition(m_oTopLeftSelectIndex.row())); + } + else if (srcRect.bottom() <= m_nFixedRowHeight) + { + srcRect.setBottom(m_nFixedRowHeight - q->currentGridLineWidth()); + srcRect.setTop(m_verticalHeader->sectionVisualPosition(m_oTopLeftSelectIndex.row())); + + if (bordingRegion.isEmpty()) + { + int nLeft = q->columnViewportPosition(m_oTopLeftSelectIndex.column()); + int nRight = q->columnViewportPosition(m_oBottomRightSelectIndex.column()) + q->columnWidth(m_oBottomRightSelectIndex.column()); + + srcRect.setLeft(nLeft); + srcRect.setRight(nRight); + } + } + } + else if (m_oTopLeftSelectIndex.row() >= m_nFixedRowCount) + { + if (srcRect.bottom() <= m_nFixedRowHeight) + { + srcRect = QRect(); + } + else if (srcRect.bottom() > m_nFixedRowHeight && srcRect.top() < m_nFixedRowHeight) + { + srcRect.setTop(m_nFixedRowHeight); + } + } +} + +void GLDTableViewPrivate::drawNormalSelectionBoundingLine(QPainter &painter, QRect rect) +{ + painter.save(); + + QPen oLinePen = painter.pen(); + oLinePen.setColor(getPenColor()); + oLinePen.setWidth(m_selectBoundLineWidth); + painter.setPen(oLinePen); + + // 当m_selectBoundLineWidth为3像素时,绘制要求为,格线外占一像素,格线内占一像素 + if (m_selectBoundLineWidth == (int)ThreePixel) + { + rect.setRight(rect.right() - 1); + rect.setBottom(rect.bottom() - 1); + } + + painter.drawLine(rect.topLeft(), rect.topRight()); + painter.drawLine(rect.bottomLeft(), rect.bottomRight()); + + painter.drawLine(rect.topLeft(), rect.bottomLeft()); + painter.drawLine(rect.topRight(), rect.bottomRight()); + + painter.restore(); +} + +void GLDTableViewPrivate::drawBorderWithFillHandle(QPainter &painter, QRect rect) +{ + painter.save(); + + QPen linePen = painter.pen(); + QColor oPenColor = getPenColor(); + linePen.setColor(oPenColor); + linePen.setWidth(3); + painter.setPen(linePen); + + // 绘制要求,格线外占一像素,格线内占一像素 + rect.setRight(rect.right() - 1); + rect.setBottom(rect.bottom() - 1); + + painter.drawLine(rect.topLeft(), rect.topRight()); + painter.drawLine(rect.topLeft(), rect.bottomLeft()); + painter.drawLine(rect.bottomRight(), rect.topRight()); + painter.drawLine(rect.bottomRight(), rect.bottomLeft()); + + QRect oEmptyRect; + switch (m_rangeFillHandlePositon) + { + case RightBottom: + { + oEmptyRect = QRect(rect.right() - 2, rect.bottom() - 2, c_nEmptyRectWidth, c_nEmptyRectWidth); + m_oRangeFillHandleRect = QRect(rect.right() - 1, rect.bottom() - 1, + c_nFillHandleWidth, c_nFillHandleWidth); + break; + } + case LeftBottom: + { + oEmptyRect = QRect(rect.left() + 1, rect.bottom() - 2, c_nEmptyRectWidth, c_nEmptyRectWidth); + m_oRangeFillHandleRect = QRect(rect.left() + 1, rect.bottom() - 1, + c_nFillHandleWidth, c_nFillHandleWidth); + break; + } + case RightTop: + { + oEmptyRect = QRect(rect.right() - 2, rect.top() + 1, c_nEmptyRectWidth, c_nEmptyRectWidth); + m_oRangeFillHandleRect = QRect(rect.right() - 1, rect.top() + 1, + c_nFillHandleWidth, c_nFillHandleWidth); + break; + } + default: + break; + } + + // 先绘制一个白色的矩形,把右下角多余的格线给去掉 + painter.fillRect(oEmptyRect, Qt::white); + // 再填充一个有颜色的矩形 + painter.fillRect(m_oRangeFillHandleRect, oPenColor); + + painter.restore(); +} + +void GLDTableViewPrivate::adjustStyleOption(QStyleOptionViewItem& opt, const QModelIndex &index) +{ + setOptionSelectedState(opt, index); + setOptionMouseOverState(index, opt); + setOptionEnabledState(opt, index); + setOptionHasFocusState(index, opt); +} + +bool GLDTableViewPrivate::nothingToDraw() +{ + return m_horizontalHeader->count() == 0 || m_verticalHeader->count() == 0 || !m_itemDelegate; +} + +bool GLDTableViewPrivate::currentCellDrawn( + GlodonTableViewPainterInfo &info, int nVisualCol, QBitArray &drawn, int nColumnCount, int nVisualRow) +{ + int nCurrentBit = (nVisualRow - info.m_nFirstVisualRow) * nColumnCount + nVisualCol - info.m_nFirstVisualColumn; + + if (nCurrentBit < 0 || nCurrentBit >= drawn.size() || drawn.testBit(nCurrentBit)) + { + return true; + } + + drawn.setBit(nCurrentBit); + return false; +} + +bool GLDTableViewPrivate::isCoverByFixedRow(int row, int rowYEndPos, bool addGridLineWidth) +{ + Q_Q(GLDTableView); + // 如果是绘制格线时,判断是否被固定列覆盖,则应该加载格线的宽度 + int nRowYEndPos = addGridLineWidth ? rowYEndPos + q->currentGridLineWidth() : rowYEndPos; + if ((row > m_nFixedRowCount - 1) && (nRowYEndPos <= m_nFixedRowHeight)) + { + return true; + } + + return false; +} + +bool GLDTableViewPrivate::isCoverByFixedColumn(int column, int columnXEndPos, bool addGridLineWidth) +{ + Q_Q(GLDTableView); + // 如果是绘制格线时,判断是否被固定列覆盖,则应该加载格线的宽度 + int nColumnXEndPos = addGridLineWidth ? columnXEndPos + q->currentGridLineWidth() : columnXEndPos; + if ((column > m_nFixedColCount - 1) && (nColumnXEndPos <= m_nFixedColWidth)) + { + return true; + } + + return false; +} + +void GLDTableViewPrivate::setOptionFeaturesAlternateProperty(bool bAlternateBase, bool balternate, QStyleOptionViewItem &option) +{ + if (!balternate) + return; + + if (bAlternateBase) + { + option.features |= QStyleOptionViewItem::Alternate; + } + else + { + option.features &= ~QStyleOptionViewItem::Alternate; + } +} + +QRect GLDTableViewPrivate::cellPainterRect(QRect srcRect, int visualRow, int visualCol) +{ + QRect oCellPainterRect(srcRect); + + if ((visualCol >= m_nFixedColCount) && (m_nFixedColWidth > 0)) + { + if ((srcRect.left() < m_nFixedColWidth) && (srcRect.right() >= m_nFixedColWidth)) + { + int nCoverByFixedColWidth = m_nFixedColWidth - srcRect.left(); + oCellPainterRect.adjust(nCoverByFixedColWidth, 0, 0, 0); + } + } + + if ((visualRow >= m_nFixedRowCount) && (m_nFixedRowHeight > 0)) + { + if ((srcRect.top() < m_nFixedRowHeight) && (srcRect.bottom() >= m_nFixedRowHeight)) + { + int nCoverByFixedRowHeight = m_nFixedRowHeight - srcRect.top(); + oCellPainterRect.adjust(0, nCoverByFixedRowHeight, 0, 0); + } + } + return oCellPainterRect; +} + +void GLDTableViewPrivate::calculateFixedRegion() +{ + calculateFixedColumnWidth(); + calculateFixedRowHeight(); +} + +void GLDTableViewPrivate::calculateFixedColumnWidth() const +{ + Q_Q(const GLDTableView); + + m_nFixedColWidth = 0; + for (int nCol = 0; nCol < m_nFixedColCount; ++nCol) + { + if (!m_horizontalHeader->isSectionHidden(nCol)) + { + m_nFixedColWidth += q->columnWidth(nCol) + q->currentGridLineWidth(); + } + } +} + +void GLDTableViewPrivate::calculateFixedRowHeight() const +{ + Q_Q(const GLDTableView); + + m_nFixedRowHeight = 0; + for (int nRow = 0; nRow < m_nFixedRowCount; ++nRow) + { + if (!m_verticalHeader->isSectionHidden(nRow)) + { + m_nFixedRowHeight += q->rowHeight(nRow) + q->currentGridLineWidth(); + } + } +} + +void GLDTableViewPrivate::drawCell(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) +{ + QStyleOptionViewItem opt = option; + opt.index = index; + + adjustStyleOption(opt, index); + + itemDelegatePaint(painter, opt, index); + drawTriangles(painter, opt, index); +} + + +GLDTableView::GLDTableView(QWidget *parent) + : GlodonAbstractItemView(*new GLDTableViewPrivate, parent), m_bShowCurCellBackgroundColor(false) +{ + Q_D(GLDTableView); + + d->init(); +} + +GLDTableView::GLDTableView(GLDTableViewPrivate &dd, QWidget *parent) + : GlodonAbstractItemView(dd, parent), m_bShowCurCellBackgroundColor(false) +{ + Q_D(GLDTableView); + + d->init(); + + connect(this, SIGNAL(canShowComment(const QModelIndex &, bool &)), + this, SLOT(onDrawComment(const QModelIndex &, bool &))); +} + +void GLDTableView::doSetModel(QAbstractItemModel *) +{ + Q_D(GLDTableView); + d->fillSuitColWidthCols(); + d->fillSuitRowHeightCols(); +} + +bool GLDTableView::canRangeFill(const QRect &) +{ + return true; +} + +bool GLDTableView::doCanRangeFill(const QRect & rect) +{ + return allowRangeFilling() && !(d_func()->isInMutiSelect()) + && rect.isValid() && canRangeFill(rect); +} + +GLDTableView::~GLDTableView() +{ +} + +void GLDTableView::setModel(QAbstractItemModel *model) +{ + Q_D(GLDTableView); + + //每次setModel时,把正处于编辑状态的格子强制关闭 + if (d->m_oEditorIndex.isValid()) + { + forceCloseEditor(); + } + + doSetModel(model); +} + +void GLDTableView::doItemsLayout() +{ + Q_D(GLDTableView); + + GlodonAbstractItemView::doItemsLayout(); + + if (verticalScrollMode() == GlodonAbstractItemView::ScrollPerItem) + { + d->m_verticalHeader->setOffsetToSectionPosition(verticalScrollBar()->value()); + } + else + { + d->m_verticalHeader->setOffset(verticalScrollBar()->value()); + } + + if (!d->m_verticalHeader->updatesEnabled()) + { + d->m_verticalHeader->setUpdatesEnabled(true); + } +} + +void GLDTableView::paint(QPainter &painter, const QRegion &drawRegion) +{ + Q_D(GLDTableView); + + QStyleOptionViewItem oOption = d->viewOptionsV4(); + + const GlodonHeaderView *pVerticalHeader = d->m_verticalHeader; + const GlodonHeaderView *pHorizontalHeader = d->m_horizontalHeader; + + if (d->nothingToDraw()) + return; + + // 获取可见行,列 + int nFirstVisualRow = pVerticalHeader->visualIndexAt(0); + int nLastVisualRow = lastVisualRow(); + + int nFirstVisualColumn = pHorizontalHeader->visualIndexAt(0); + int nLastVisualColumn = pHorizontalHeader->visualIndexAt(pHorizontalHeader->viewport()->width()); + adjustColumnByLayoutDirection(nFirstVisualColumn, nLastVisualColumn); + + // 计算固定行,固定列区域 + d->calculateFixedRegion(); + + QBitArray drawn((nLastVisualRow - nFirstVisualRow + 1) * (nLastVisualColumn - nFirstVisualColumn + 1)); + QRegion toBeDrawn(d->viewport->rect()); + + QPen gridPen = currentGridPen(); + + // 绘制合并格(合并格只初始化了可见区域) + const QRegion c_scrollDelayReigon = drawRegion.translated(d->m_scrollDelayOffset); + if (d->hasSpans()) + { + painter.save(); + + painter.setPen(gridPen); + d->drawAndClipSpans(c_scrollDelayReigon, &painter, oOption, &drawn, + nFirstVisualRow, nLastVisualRow, + nFirstVisualColumn, nLastVisualColumn); + toBeDrawn = painter.clipRegion(); + + painter.restore(); + } + + // 开始绘制除合并格之外的格子 + int nGridLineWidth = currentGridLineWidth(); + uint horizontalRight = pHorizontalHeader->length() - pHorizontalHeader->offset() - (isRightToLeft() ? 0 : nGridLineWidth); + uint verticalBottom = pVerticalHeader->length() - pVerticalHeader->offset() - nGridLineWidth; + + const QVector c_rects = c_scrollDelayReigon.rects(); + for (int i = 0; i < c_rects.size(); ++i) + { + m_dirtyArea = c_rects.at(i); + adjustCurrentDirtyArea(verticalBottom, horizontalRight); + + // 获取当前Dirty区域的边界行列 + int nLeft = pHorizontalHeader->visualIndexAt(m_dirtyArea.left()); + int nRight = pHorizontalHeader->visualIndexAt(m_dirtyArea.right()); + adjustColumnByLayoutDirection(nLeft, nRight); + + int nBottom = lastVisualRowInDirtyArea(pVerticalHeader); + + int nTop = 0; + bool alternateBase = false; + calcTopRowAndAlternateBase(nBottom, nTop, alternateBase); + + if (nTop == -1 || nTop > nBottom) + { + continue; + } + + GlodonTableViewPainterInfo oPainterParams( + nTop, nBottom, nLeft, nRight, nFirstVisualRow, nFirstVisualColumn, nLastVisualColumn, alternateBase); + drawGridCellFromRowToColumn(painter, oPainterParams, drawn, oOption); + + if (d->m_showGrid) + { + QRect oCurrentDirtyAreaRect(QPoint(nLeft, nTop), QPoint(nRight, nBottom)); + drawCellBorderLines(painter, oCurrentDirtyAreaRect, toBeDrawn, oOption); + } + + painter.save(); + drawSelectionBorderLines(painter, d->m_scrollDelayOffset); + painter.restore(); + } + +#ifndef QT_NO_DRAGANDDROP + // Paint the dropIndicator + d->paintDropIndicator(&painter); +#endif +} + +int GLDTableView::currentGridLineWidth() const +{ + Q_D(const GLDTableView); + + if (d->m_gridStyle == Qt::NoPen) + return 0; + + if (d->m_bIsCustomStyle) + { + return d->m_showGrid ? d->m_gridLineWidth : 0; + } + else + { + return d->m_showGrid ? 1 : 0; + } +} + +QPen GLDTableView::currentGridPen() +{ + Q_D(GLDTableView); + + if (d->m_bIsCustomStyle) + { + const int nGridLineWidth = currentGridLineWidth(); + return QPen(d->m_gridLineColor, nGridLineWidth, d->m_gridStyle); + } + + const QStyleOptionViewItem option = d->viewOptionsV4(); + const int gridHint = style()->styleHint(QStyle::SH_Table_GridLineColor, &option, this); + const QColor c_gridColor = static_cast(gridHint); + return QPen(c_gridColor, 0, d->m_gridStyle); +} + +bool GLDTableView::edit(const QModelIndex &index, GlodonAbstractItemView::EditTrigger trigger, QEvent *event) +{ + Q_D(GLDTableView); + + bool bEditResult = GlodonAbstractItemView::edit(index, trigger, event); + + if (bEditResult) + { + if (d->m_bEnterJump) + { + d->m_prevState = GlodonAbstractItemView::Editting; + } + } + + return bEditResult; +} + +void GLDTableView::syncStateToDelegate(GlodonDefaultItemDelegate *pNewDelegate) +{ + Q_D(GLDTableView); + + GlodonAbstractItemView::syncStateToDelegate(pNewDelegate); + + pNewDelegate->setIsEnterJump(d->m_bEnterJump); + pNewDelegate->setIsEnterJumpPro(d->m_bEnterJumpPro); + pNewDelegate->setCloseEditorOnFocusOut(d->m_bCloseEditorOnFocusOut, d->m_ignoreActiveWindowFocusReason); + pNewDelegate->setUseBlendColor(d->m_bUseBlendColor); + pNewDelegate->setUseComboBoxCompleter(d->m_bUseComboBoxCompleter); + pNewDelegate->setSelectedCellBackgroundColor(d->m_oSelectedCellBackgroundColor); +} + +int GLDTableView::lastVisualRowInDirtyArea(const GlodonHeaderView *verticalHeader) const +{ + int nBottom = verticalHeader->visualIndexAt(m_dirtyArea.bottom()); + + if (nBottom == -1) + { + nBottom = verticalHeader->count() - 1; + } + + return nBottom; +} + +void GLDTableView::calcTopRowAndAlternateBase(int bottom, int &top, bool &alternateBase) +{ + Q_D(GLDTableView); + + if (d->m_bAlternatingColors && d->m_verticalHeader->sectionsHidden()) + { + uint verticalOffset = d->m_verticalHeader->offset(); + int row = d->m_verticalHeader->logicalIndex(top); + + for (int j = 0; ((uint)(j += d->m_verticalHeader->sectionSize(top) + d->m_gridLineWidth) <= verticalOffset) && (top < bottom); ++top) + { + row = d->m_verticalHeader->logicalIndex(top); + + if (d->m_bAlternatingColors && !d->m_verticalHeader->isSectionHidden(row)) + { + alternateBase = !alternateBase; + } + } + + if (fixedRowCount() > 0) + { + top = 0; + } + + } + else + { + top = d->m_verticalHeader->visualIndexAt(m_dirtyArea.top()); + alternateBase = (1 == (top & 1)) && d->m_bAlternatingColors; + } +} + +void GLDTableView::adjustCurrentDirtyArea(uint verticalBottom, uint horizontalRight) +{ + if (int(verticalBottom) < m_dirtyArea.bottom()) + { + m_dirtyArea.setBottom(int(verticalBottom)); + } + + if (int(horizontalRight) < m_dirtyArea.right()) + { + m_dirtyArea.setRight(int(horizontalRight)); + } + + //修改GTJ-4250Bug + if (int(horizontalRight) < m_dirtyArea.left()) + { + m_dirtyArea.setLeft(int(horizontalRight)); + } +} + +void GLDTableView::adjustColumnByLayoutDirection(int &firstVisualColumn, int &lastVisualColumn) +{ + if (isRightToLeft()) + { + qSwap(firstVisualColumn, lastVisualColumn); + } + + if (firstVisualColumn == -1) + { + firstVisualColumn = 0; + } + + if (lastVisualColumn == -1) + { + lastVisualColumn = horizontalHeader()->count() - 1; + } +} + +void GLDTableView::drawGridCellFromRowToColumn( + QPainter &painter, GlodonTableViewPainterInfo &info, QBitArray &drawn, + QStyleOptionViewItem &option) +{ + Q_D(GLDTableView); + + const QPoint offset = d->m_scrollDelayOffset; + const int c_nGridSize = currentGridLineWidth(); + bool bAlternateBase = info.m_bAlternateBase; + + d->m_borderLines.clear(); + + bool balternate = d->m_bAlternatingColors; + + int nColumnCount = info.m_nLastVisualColumn - info.m_nFirstVisualColumn + 1; + + // 绘制行 + for (int nVisualRow = info.m_nDirtyAreaTop; nVisualRow <= info.m_nDirtyAreaBottom; ++nVisualRow) + { + int nLogicalRow = d->m_verticalHeader->logicalIndex(nVisualRow); + + if (d->m_verticalHeader->isSectionHidden(nLogicalRow)) + { + continue; + } + + int nRowY = rowViewportPosition(nLogicalRow) + offset.y(); + int nRowh = rowHeight(nLogicalRow); + + if (d->isCoverByFixedRow(nVisualRow, nRowY + nRowh, false)) + { + continue; + } + + // 绘制列 + for (int nVisualCol = info.m_nDirtyAreaLeft; nVisualCol <= info.m_nDirtyAreaRight; ++nVisualCol) + { + if (d->currentCellDrawn(info, nVisualCol, drawn, nColumnCount, nVisualRow)) + { + continue; + } + + int nLogicalCol = d->m_horizontalHeader->logicalIndex(nVisualCol); + + if (d->m_horizontalHeader->isSectionHidden(nLogicalCol)) + { + continue; + } + + int nColp = columnViewportPosition(nLogicalCol) + offset.x(); + int nColw = columnWidth(nLogicalCol); + + if (d->isCoverByFixedColumn(nVisualCol, nColp + nColw, false)) + { + continue; + } + + QModelIndex index = d->m_model->index(nLogicalRow, nLogicalCol, d->m_root); + + if (!index.isValid()) + { + continue; + } + + QVariant oBoundLine = index.data(gidrBoundLineRole); + d->m_borderLines.insert(index, oBoundLine); + + option.rect = QRect(nColp + (d->m_showGrid && isRightToLeft() ? c_nGridSize : 0), nRowY, + nColw - borderLineSubtractGridLineWidth(oBoundLine, true), + nRowh - borderLineSubtractGridLineWidth(oBoundLine, false)); + + // 根据固定行,固定列,获取绘制的区域,主要是被固定行或固定列覆盖了一部分的区域 + QRect oCellPainterRect = d->cellPainterRect(option.rect, nVisualRow, nVisualCol); + + d->setOptionFeaturesAlternateProperty(bAlternateBase, balternate, option); + + painter.save(); + painter.setClipRect(oCellPainterRect); + + // TODO liurx 按像素滚动时,树形结构区域绘制还有问题 + d->drawCell(&painter, option, index); + painter.restore(); + } + + bAlternateBase = !bAlternateBase && balternate; + } +} + +void GLDTableView::drawCellBorderLines(QPainter &painter, const QRect ¶ms, QRegion &spans, + QStyleOptionViewItem &option) +{ + Q_D(GLDTableView); + + painter.save(); + painter.setPen(currentGridPen()); + + if (d->m_bDrawBoundLine) + { + drawBorderLinesByRow(painter, params, spans, option); + } + else + { + drawGridLines(painter, params, spans); + } + + if (d->m_bDrawTopAndLeftBorderLine) + { + drawTopAndLeftBorderLine(painter); + } + painter.restore(); +} + +void GLDTableView::drawBorderLinesByRow( + QPainter &painter, const QRect ¶ms, QRegion &spans, + QStyleOptionViewItem &option) +{ + Q_D(GLDTableView); + + int nTop = params.top(); + int nBottom = params.bottom(); + + for (int nVisualRowIndex = nTop; nVisualRowIndex <= nBottom; ++nVisualRowIndex) + { + int row = d->m_verticalHeader->logicalIndex(nVisualRowIndex); + + if (d->m_verticalHeader->isSectionHidden(row)) + { + continue; + } + + drawBorderLinesByCol(painter, params, spans, option, row); + } +} + +void GLDTableView::drawBorderLinesByCol( + QPainter &painter, const QRect ¶ms, QRegion &spans, + QStyleOptionViewItem &option, int row) +{ + Q_D(GLDTableView); + + int nLeft = params.left(); + int nRight = params.right(); + + for (int nVisualColumnIndex = nLeft; nVisualColumnIndex <= nRight; ++nVisualColumnIndex) + { + int nCol = d->m_horizontalHeader->logicalIndex(nVisualColumnIndex); + + if (d->m_horizontalHeader->isSectionHidden(nCol) + || 0 == d->m_horizontalHeader->sectionSize(nCol)) + { + continue; + } + + QModelIndex index = d->m_model->index(row, nCol, d->m_root); + option.index = index; + + QRect oCellRect = visualRectIncludeBoundingLineWidth(index); + + if (d->isCoverByFixedRow(row, oCellRect.bottom(), true)) + { + continue; + } + + if (d->isCoverByFixedColumn(nVisualColumnIndex, oCellRect.right(), true)) + { + continue; + } + + drawCellBorderLine(painter, oCellRect, spans, index); + } +} + +void GLDTableView::drawSelectionBorderLines(QPainter &painter, const QPoint &offset) +{ + Q_D(GLDTableView); + + drawSelectionBorderLines(painter); + + switch (d->m_state) + { + case RangeFillingState: + { + drawRangeFillingState(painter, offset); + break; + } + case RangeMovingState: + { + drawRangeMovingState(painter); + break; + } + } +} + +void GLDTableView::drawCellBorderLine( + QPainter &painter, const QRect &cellRect, const QRegion &spans, + const QModelIndex &index) +{ + Q_D(GLDTableView); + + // 得到设置的格线宽度 + QVariant oBoundLine = d->m_borderLines.value(index); + + if (oBoundLine.isNull() || !oBoundLine.isValid()) + { + oBoundLine = index.data(gidrBoundLineRole); + } + + int nGridLineWidth = currentGridLineWidth(); + drawCellBorderLine( + painter, cellRect, spans, + nGridLineWidth, borderLineWidth(oBoundLine, false), index.data(gidrBottomBoundLineColor), + Qt::Horizontal); + + drawCellBorderLine( + painter, cellRect, spans, + nGridLineWidth, borderLineWidth(oBoundLine, true), index.data(gidrRightBoundLineColor), + Qt::Vertical); +} + +void GLDTableView::drawCellBorderLine( + QPainter &painter, const QRect &cellRect, const QRegion &spans, int gridLineWidth, + int borderLineWidth, const QVariant &borderLineColor, Qt::Orientation direction) +{ + Q_D(GLDTableView); + + QPen borderLinePen = painter.pen(); + + borderLinePen.setWidth(qMax(borderLineWidth, gridLineWidth)); + borderLinePen.setColor(borderLineColor.isValid() ? borderLineColor.value() : d->m_gridLineColor); + + if (borderLinePen.width() == 0) + { + return; + } + + painter.save(); + painter.setPen(borderLinePen); + + int rowY = cellRect.y(); + int rowH = cellRect.height(); + int colX = cellRect.x(); + int colW = cellRect.width(); + + // 根据QPainter的pen宽度,调整绘制位置,格线大于边框线时,需要向外扩 + // 格线小于边框线时,需要向内扩 + if (gridLineWidth >= borderLineWidth) + { + // 由于QPainter在绘制的时候,根据像素不一样,距离中心线有不同的偏移 + // 经验数据,需要做除2处理,以保证格线绘制在一条线上,且占用的是格子内部 + // 其他类似操作同理 + rowY += gridLineWidth / 2; + colX += gridLineWidth / 2; + } + else + { + int nDrawOffset = (borderLineWidth - gridLineWidth) / 2; + + rowY += nDrawOffset; + colX += nDrawOffset; + + rowH -= 2 * nDrawOffset; + colW -= 2 * nDrawOffset; + } + + QRect viewportRect = d->viewport->rect(); + + painter.setClipRect(viewportRect); + painter.setClipRegion(spans, Qt::IntersectClip); + + // 画线 + if (direction == Qt::Horizontal) + { + QLine hLine(colX, rowY + rowH, colX + colW, rowY + rowH); + drawCellBorderLine(painter, hLine, d->m_bShowHorizontalGridLine); + } + else + { + QLine vLine(colX + colW, rowY, colX + colW, rowY + rowH); + drawCellBorderLine(painter, vLine, d->m_bShowVerticalGridLine); + } + + painter.restore(); +} + +void GLDTableView::drawCellBorderLine( + QPainter &painter, const QLine &line, bool needDraw) +{ + if (needDraw) + { + painter.drawLine(line); + } +} + +void GLDTableView::drawEachRow(QPainter &painter, QRegion &spans, const QRect ¶ms) +{ + Q_D(GLDTableView); + + const GlodonHeaderView *verticalHeader = d->m_verticalHeader; + // Paint each row + painter.setClipRect(d->viewport->rect()); + painter.setClipRegion(spans, Qt::IntersectClip); + + int nTop = params.top(); + int nBottom = params.bottom(); + + const QPoint offset = d->m_scrollDelayOffset; + + for (int nVisualIndex = nTop; nVisualIndex <= nBottom; ++nVisualIndex) + { + int nRow = verticalHeader->logicalIndex(nVisualIndex); + + if (verticalHeader->isSectionHidden(nRow)) + { + continue; + } + + int nRowY = rowViewportPosition(nRow) + offset.y(); + nRowY += rowHeight(nRow); + + int nDrawY = nRowY + currentGridLineWidth() / 2; + + if (d->isCoverByFixedRow(nRow, nRowY, true)) + { + continue; + } + + painter.drawLine(m_dirtyArea.left(), nDrawY, m_dirtyArea.right(), nDrawY); + } +} + +void GLDTableView::drawEachColumn(QPainter &painter, QRegion &spans, const QRect ¶ms) +{ + Q_D(GLDTableView); + + const GlodonHeaderView *horizontalHeader = d->m_horizontalHeader; + // Paint each column + painter.setClipRect(d->viewport->rect()); + painter.setClipRegion(spans, Qt::IntersectClip); + + int nLeft = params.left(); + int nRight = params.right(); + + const QPoint offset = d->m_scrollDelayOffset; + + for (int i = nLeft; i <= nRight; ++i) + { + int col = horizontalHeader->logicalIndex(i); + + if (horizontalHeader->isSectionHidden(col)) + { + continue; + } + + int nColX = columnViewportPosition(col) + offset.x(); + nColX += columnWidth(col); + + int nDrawX = nColX + currentGridLineWidth() / 2; + + if (d->isCoverByFixedColumn(col, nColX, true)) + { + continue; + } + + painter.drawLine(nDrawX, m_dirtyArea.top(), nDrawX, m_dirtyArea.bottom()); + } +} + +void GLDTableView::drawTopAndLeftBorderLine(QPainter &painter) +{ + Q_D(GLDTableView); + + painter.save(); + + QPen pen = painter.pen(); + pen.setColor(d->m_oFrameLineColor); + painter.setPen(pen); + + // TODO liurx 绘制边框线时,是否需要把画笔的宽度除2,需要结合headerView统一考虑,是把线画全盖住内容? + // 还是把线画不全,还是把整个表格向右偏移,不占用格子的内容 + if (horizontalHeader()->isHidden() && verticalScrollMode() == ScrollPerItem) + { + const QLine topFrameLine(m_dirtyArea.left(), painter.pen().width() / 2, + m_dirtyArea.right(), painter.pen().width() / 2); + painter.drawLine(topFrameLine); + } + + // TODO liurx,在满足绘制整个表格边框线情况下,数据只有一行,并且把这一行隐藏,会出现黑点 + if (verticalHeader()->isHidden() && horizontalScrollMode() == ScrollPerItem) + { + const QLine leftFrameLine(painter.pen().width() / 2, m_dirtyArea.top(), + painter.pen().width() / 2, m_dirtyArea.bottom()); + painter.drawLine(leftFrameLine); + } + + painter.restore(); +} + +void GLDTableView::adjustCommonBorder(const QLine &line, QList &rectVisablelBorders) +{ + if (!rectVisablelBorders.contains(line)) + { + rectVisablelBorders.append(line); + } + else + { + rectVisablelBorders.removeOne(line); + } +} + +void GLDTableView::adjustCommonBorder(const QLine &lineTopOfCell, QList &rectVisablelBorders, + const QLine &adjustedLineTopOfCell) +{ + if (!rectVisablelBorders.contains(adjustedLineTopOfCell)) + { + rectVisablelBorders.append(lineTopOfCell); + } + else + { + rectVisablelBorders.removeOne(lineTopOfCell); + rectVisablelBorders.removeOne(adjustedLineTopOfCell); + } +} + +void GLDTableView::adjustCommonBorder(const QRect &rect, QList &rectVisablelBorders) +{ + QLine lineLeftOfCell(rect.left(), rect.top(), rect.left(), rect.bottom()); + QPoint lineLeftStart(lineLeftOfCell.x1() + 1, lineLeftOfCell.y1()); + QPoint lineLeftEnd(lineLeftOfCell.x2() + 1, lineLeftOfCell.y2()); + QLine adjustedLineLeftOfCell(lineLeftStart, lineLeftEnd); + adjustCommonBorder(lineLeftOfCell, rectVisablelBorders, adjustedLineLeftOfCell); + + QLine lineTopOfCell(rect.left(), rect.top(), rect.right(), rect.top()); + QPoint lineTopStart(lineTopOfCell.x1(), lineTopOfCell.y1() + 1); + QPoint lineTopEnd(lineTopOfCell.x2(), lineTopOfCell.y2() + 1); + QLine adjustedLineTopOfCell(lineTopStart, lineTopEnd); + adjustCommonBorder(lineTopOfCell, rectVisablelBorders, adjustedLineTopOfCell); + + QLine lineRight(rect.right(), rect.top(), rect.right(), rect.bottom()); + adjustCommonBorder(lineRight, rectVisablelBorders); + + QLine lineBottom(rect.left(), rect.bottom(), rect.right(), rect.bottom()); + adjustCommonBorder(lineBottom, rectVisablelBorders); +} + +QModelIndex GLDTableView::calculationRightBottomIndex(QModelIndex drawIndex) +{ + int rowCount = rowSpan(drawIndex.row(), drawIndex.column()); + int columnCount = columnSpan(drawIndex.row(), drawIndex.column()); + QModelIndex rightBottom; + + if (rowCount != 1 || columnCount != 1) + { + rightBottom = model()->index(drawIndex.row() + rowCount - 1, + drawIndex.column() + columnCount - 1); + } + else + { + rightBottom = drawIndex; + } + + return rightBottom; +} + +void GLDTableView::drawSelectionBorderLines(QPainter &painter) +{ + Q_D(GLDTableView); + + QItemSelection selection = d->getItemSelectionAccordingToSelectState(); + + if (selection.isEmpty()) + { + return; + } + + QRegion region = visualRegionForSelection(selection); + + QRect rect = region.boundingRect(); + + d->adjustSelectionBoundingRectAccordingToFixedColumn(region, rect); + if (rect.isEmpty()) + return; + + d->adjustSelectionBoundingRectAccordingToFixedRow(region, rect); + if (rect.isEmpty()) + return; + + // 选择边框线需要向外扩一像素 + rect.adjust(-1, -1, 1, 1); + + if (doCanRangeFill(visualRectForSelection())) + { + d->drawBorderWithFillHandle(painter, rect); + } + else + { + d->drawNormalSelectionBoundingLine(painter, rect); + } +} + +void GLDTableView::drawGridLines(QPainter &painter, const QRect ¶ms, QRegion &spans) +{ + Q_D(GLDTableView); + + int nGridLineWidth = currentGridLineWidth(); + if (nGridLineWidth <= 0) + return; + + QPen oPen = painter.pen(); + oPen.setWidth(nGridLineWidth); + + painter.save(); + painter.setPen(oPen); + + if (d->m_bShowHorizontalGridLine) + { + drawEachRow(painter, spans, params); + } + if (d->m_bShowVerticalGridLine) + { + drawEachColumn(painter, spans, params); + } + + painter.restore(); +} + +int GLDTableView::firstVisableColumn() +{ + Q_D(GLDTableView); + + int nFirstVisableColumn = 0; + + for (int i = 0; i < d->m_horizontalHeader->count(); i++) + { + if (!isColumnHidden(i) && columnWidth(i) != 0) + { + nFirstVisableColumn = i; + break; + } + } + + return nFirstVisableColumn; +} + +int GLDTableView::firstVisableRow() +{ + Q_D(GLDTableView); + + int nFirstVisableRow = 0; + + for (int i = 0; i < d->m_verticalHeader->count(); i++) + { + if (!isRowHidden(i) && rowHeight(i) != 0) + { + nFirstVisableRow = i; + break; + } + } + + return nFirstVisableRow; +} + +void GLDTableView::appendHideCellBorder(const QRect &rect, QList &rectHideBorder) +{ + QLine lineLeft(rect.left(), rect.top(), rect.left(), rect.bottom()); + QLine lineTop(rect.left(), rect.top(), rect.right(), rect.top()); + QLine lineRight(rect.right(), rect.top(), rect.right(), rect.bottom()); + QLine lineBottom(rect.left(), rect.bottom(), rect.right(), rect.bottom()); + + rectHideBorder.append(lineLeft); + rectHideBorder.append(lineTop); +// rectHideBorder.append(QLine(QPoint(lineLeft.x1() + 1, lineLeft.y1()), QPoint(lineLeft.x2() + 1, lineLeft.y2()))); +// rectHideBorder.append(); + rectHideBorder.append(lineRight); + rectHideBorder.append(lineBottom); +} + +void GLDTableView::drawRangeFillingState(QPainter &painter, const QPoint &offset) +{ + Q_D(GLDTableView); + + painter.save(); + painter.setClipRect(d->viewport->rect()); + + QPen oLinePen = painter.pen(); + oLinePen.setColor(d->m_selectBoundLineColor); + oLinePen.setWidth(3); + oLinePen.setStyle(Qt::DotLine); + painter.setPen(oLinePen); + + int nSrcLeft = columnVisualPosition(m_oRangeSrc.left()) + offset.x(); + int nSrcRight = columnVisualPosition(m_oRangeSrc.right()) + offset.x() + visualColumnWidth(m_oRangeSrc.right()); + int nSrcTop = rowVisualPosition(m_oRangeSrc.top()) + offset.y(); + int nSrcBottom = rowVisualPosition(m_oRangeSrc.bottom()) + offset.y() + visualRowHeight(m_oRangeSrc.bottom()); + + // 向上拖拉 + if (m_nRangeCurRow < m_oRangeSrc.top()) + { + int nCurRowLeft = nSrcLeft - oLinePen.width() / 2; + int nCurRowTop = rowVisualPosition(m_nRangeCurRow) + offset.y(); + painter.drawLine(nCurRowLeft, nSrcTop, nCurRowLeft, nCurRowTop); + painter.drawLine(nSrcRight, nSrcTop, nSrcRight, nCurRowTop); + painter.drawLine(nCurRowLeft, nCurRowTop, nSrcRight, nCurRowTop); + } + // 向下拖拉 + else if (m_nRangeCurRow > m_oRangeSrc.bottom()) + { + int nCurRowLeft = nSrcLeft - oLinePen.width() / 2; + int nCurRowBottom = rowVisualPosition(m_nRangeCurRow) + offset.y() + visualRowHeight(m_nRangeCurRow); + painter.drawLine(nCurRowLeft, nSrcBottom, nCurRowLeft, nCurRowBottom); + painter.drawLine(nSrcRight, nSrcBottom, nSrcRight, nCurRowBottom); + painter.drawLine(nCurRowLeft, nCurRowBottom, nSrcRight, nCurRowBottom); + } + // 向左拖拉 + else if (m_nRangeCurCol < m_oRangeSrc.left()) + { + int nCurColTop = nSrcTop - oLinePen.width() / 2; + int nCurColLeft = columnVisualPosition(m_nRangeCurCol) + offset.x(); + painter.drawLine(nSrcLeft, nCurColTop, nCurColLeft, nCurColTop); + painter.drawLine(nSrcLeft, nSrcBottom, nCurColLeft, nSrcBottom); + painter.drawLine(nCurColLeft, nSrcBottom, nCurColLeft, nCurColTop); + } + // 向右拖拉 + else if (m_nRangeCurCol > m_oRangeSrc.right()) + { + int nCurColTop = nSrcTop - oLinePen.width() / 2; + int nCurColRight = columnVisualPosition(m_nRangeCurCol) + offset.x() + visualColumnWidth(m_nRangeCurCol); + painter.drawLine(nSrcRight, nCurColTop, nCurColRight, nCurColTop); + painter.drawLine(nSrcRight, nSrcBottom, nCurColRight, nSrcBottom); + painter.drawLine(nCurColRight, nSrcBottom, nCurColRight, nCurColTop); + } + + painter.restore(); +} + +void GLDTableView::drawRangeMovingState(QPainter &painter) +{ + Q_D(GLDTableView); + painter.save(); + painter.setClipRect(d->viewport->rect()); + + QPen oLinePen = painter.pen(); + oLinePen.setColor(d->m_selectBoundLineColor); + oLinePen.setWidth(3); + painter.setPen(oLinePen); + + int nOffset = oLinePen.width() / 2; + int nLeft = m_tempRangeRect.left() - nOffset; + int nRight = m_tempRangeRect.right(); + int nTop = m_tempRangeRect.top() - nOffset; + int nBottom = m_tempRangeRect.bottom(); + + painter.drawLine(nLeft, nTop, nRight, nTop); + painter.drawLine(nLeft, nBottom, nRight, nBottom); + painter.drawLine(nLeft, nTop, nLeft, nBottom); + painter.drawLine(nRight, nTop, nRight, nBottom); + + painter.restore(); +} + +void GLDTableView::print() +{ + //TODO +} + +void GLDTableView::setDrawBoundLine(bool drawBoundLine) +{ + Q_D(GLDTableView); + d->m_bDrawBoundLine = drawBoundLine; +} + +bool GLDTableView::drawBoundLine() +{ + Q_D(GLDTableView); + return d->m_bDrawBoundLine; +} + +void GLDTableView::edit(const QModelIndex &index) +{ + Q_D(GLDTableView); + + if (!d->isIndexValid(index)) + { + qWarning("edit: index was invalid"); + } + + // 优先处理行或列上的delegate,因为行或列上的delegate优先级高于ItemDelegate + GlodonDefaultItemDelegate* pDelegate = d->delegateForIndex(index); + + pDelegate->setCurrTreeEditting(index); + + bool breadOnly = false; + GEditStyle es = pDelegate->editStyle(dataIndex(index), breadOnly); + + if (es == esNone || es == esBool) + { + return; + } + + //设置NoEditTrigger后不让进入编辑 + if (0 == (d->m_editTriggers & AllEditTriggers)) + { + return; + } + + if (!edit(index, AllEditTriggers, 0)) + { + qWarning("edit: editing failed"); + } +} + +void GLDTableView::setSelectionModel(QItemSelectionModel *selectionModel) +{ + Q_D(GLDTableView); + Q_ASSERT(selectionModel); + d->m_verticalHeader->setSelectionModel(selectionModel); + d->m_horizontalHeader->setSelectionModel(selectionModel); + GlodonAbstractItemView::setSelectionModel(selectionModel); +} + +GlodonHeaderView *GLDTableView::horizontalHeader() const +{ + Q_D(const GLDTableView); + return d->m_horizontalHeader; +} + +GlodonHeaderView *GLDTableView::verticalHeader() const +{ + Q_D(const GLDTableView); + return d->m_verticalHeader; +} + +void GLDTableView::setHorizontalHeader(GlodonHeaderView *header) +{ + Q_D(GLDTableView); + + if (!header || header == d->m_horizontalHeader) + { + return; + } + + if (d->m_horizontalHeader && d->m_horizontalHeader->parent() == this) + { + freeAndNil(d->m_horizontalHeader); + } + + d->m_horizontalHeader = header; + d->m_horizontalHeader->setParent(this); + + if (!d->m_horizontalHeader->model()) + { + d->m_horizontalHeader->setModel(d->m_model); + + if (d->m_selectionModel) + { + d->m_horizontalHeader->setSelectionModel(d->m_selectionModel); + } + } + + d->m_horizontalHeader->setFixedCount(d->m_nFixedColCount); + + connect(d->m_horizontalHeader, SIGNAL(sectionResized(int, int, int, bool)), + this, SLOT(columnResized(int, int, int, bool))); + connect(d->m_horizontalHeader, SIGNAL(canSectionMove(int, int, bool &)), + this, SLOT(canColumnMoved(int, int, bool &))); + connect(d->m_horizontalHeader, SIGNAL(sectionMoved(int, int, int)), + this, SLOT(columnMoved(int, int, int))); + connect(d->m_horizontalHeader, SIGNAL(sectionCountChanged(int, int)), + this, SLOT(columnCountChanged(int, int))); + connect(d->m_horizontalHeader, SIGNAL(sectionPressed(int)), this, SLOT(selectColumn(int))); + connect(d->m_horizontalHeader, SIGNAL(sectionEntered(int)), this, SLOT(_q_selectColumn(int))); + connect(d->m_horizontalHeader, SIGNAL(sectionHandleDoubleClicked(int)), + this, SLOT(resizeColumnToContents(int))); + connect(d->m_horizontalHeader, SIGNAL(geometriesChanged()), this, SLOT(updateGeometries())); + connect(d->m_verticalHeader, SIGNAL(scrolled(int)), this, SLOT(onScrolled(int))); + connect(d->m_horizontalHeader, SIGNAL(scrolled(int)), this, SLOT(onScrolled(int))); + + connect(d->m_horizontalHeader, &GlodonHeaderView::sectionResizing, + this, &GLDTableView::showSectionResizingInfoFrame); + + //update the sorting enabled states on the new header + //强制执行setSortingEnabled + bool bsortEnabled = d->m_sortingEnabled; + d->m_sortingEnabled = !bsortEnabled; + setSortingEnabled(bsortEnabled); + + if (GlodonMultiHeaderView *horizontalHeader = dynamic_cast(d->m_horizontalHeader)) + { + connect(horizontalHeader, SIGNAL(headerSpanPressed(int, int, int, int)), + this, SLOT(_q_selectColumns(int, int, int, int))); + } + else if (GlodonGroupHeaderView *horizontalHeader = dynamic_cast(d->m_horizontalHeader)) + { + connect(horizontalHeader, SIGNAL(cgFrameChanged()), this, SLOT(updateGeometries())); + } +} + +void GLDTableView::setVerticalHeader(GlodonHeaderView *header) +{ + Q_D(GLDTableView); + + if (!header || header == d->m_verticalHeader) + { + return; + } + + if (d->m_verticalHeader && d->m_verticalHeader->parent() == this) + { + delete d->m_verticalHeader; + } + + d->m_verticalHeader = header; + d->m_verticalHeader->setParent(this); + + if (!d->m_verticalHeader->model()) + { + d->m_verticalHeader->setModel(d->m_model); + + if (d->m_selectionModel) + { + d->m_verticalHeader->setSelectionModel(d->m_selectionModel); + } + } + + d->m_verticalHeader->setFixedCount(d->m_nFixedRowCount); + + connect(d->m_verticalHeader, SIGNAL(sectionResized(int, int, int, bool)), + this, SLOT(rowResized(int, int, int, bool))); + connect(d->m_verticalHeader, SIGNAL(canSectionMove(int, int, bool &)), + this, SLOT(canRowMoved(int, int, bool &))); + connect(d->m_verticalHeader, SIGNAL(sectionMoved(int, int, int)), + this, SLOT(rowMoved(int, int, int))); + connect(d->m_verticalHeader, SIGNAL(sectionCountChanged(int, int)), + this, SLOT(rowCountChanged(int, int))); + connect(d->m_verticalHeader, SIGNAL(sectionPressed(int)), this, SLOT(selectRow(int))); + connect(d->m_verticalHeader, SIGNAL(sectionEntered(int)), this, SLOT(_q_selectRow(int))); + connect(d->m_verticalHeader, SIGNAL(sectionHandleDoubleClicked(int)), + this, SLOT(resizeRowToContents(int))); + connect(d->m_verticalHeader, SIGNAL(geometriesChanged()), this, SLOT(updateGeometries())); + + connect(d->m_verticalHeader, &GlodonHeaderView::sectionResizing, + this, &GLDTableView::showSectionResizingInfoFrame); + + if (GlodonMultiHeaderView *verticalHeader = dynamic_cast(d->m_verticalHeader)) + { + connect(verticalHeader, SIGNAL(headerSpanPressed(int, int, int, int)), this, SLOT(_q_selectRows(int, int, int, int))); + } +} + +void GLDTableView::setShowEllipsisButton(bool value) +{ + Q_D(GLDTableView); + d->m_showEllipsisButton = value; + + if (NULL == d->m_ellipsisButton) + { + QPixmap pixMap(":/icons/EllipsisButton_Normal"); + d->m_ellipsisButton = new QPushButton(this); + d->m_ellipsisButton->setFixedSize(pixMap.size()); + d->m_ellipsisButton->setStyleSheet("QPushButton{ border-image: url(:/icons/EllipsisButton_Normal);} \ + QPushButton:hover { border-image: url(:/icons/EllipsisButton_Hover);} \ + QPushButton:pressed {border-image: url(:/icons/EllipsisButton_Click);}"); + d->m_ellipsisButton->setFixedSize(pixMap.size()); + connect(d->m_ellipsisButton, SIGNAL(clicked()), this, SIGNAL(onEllipsisButtonClick())); + } + + if (value) + { + resetEllipsisButtonLocation(); + d->m_ellipsisButton->setVisible(true); + } + else + { + d->m_ellipsisButton->setVisible(false); + } +} + +bool GLDTableView::isShowEllipsisButton() +{ + Q_D(GLDTableView); + return d->m_showEllipsisButton; +} + + +GlodonAbstractItemView::EditStyleDrawType GLDTableView::editStyleDrawType() const +{ + Q_D(const GLDTableView); + return d->m_editStyleDrawType; +} + +void GLDTableView::setEditStyleDrawType(GlodonAbstractItemView::EditStyleDrawType drawType) +{ + Q_D(GLDTableView); + + if (d->m_editStyleDrawType == drawType) + { + return; + } + + d->m_editStyleDrawType = drawType; + + update(currentIndex()); +} + +void GLDTableView::scrollContentsBy(int dx, int dy) +{ + Q_D(GLDTableView); + + d->m_delayedAutoScroll.stop(); + + scrollHorizontalContentsBy(dx); + scrollVerticalContentsBy(dy); + + // TODO wangdd-a,这个方法不是很懂,注释掉没有看出来有啥问题。。。 + updateFirstLine(dx, dy); + + resetEllipsisButtonLocation(); +// resetCommentPosition(true, dx, dy); +} + +bool GLDTableView::isEditorInFixedColAfterHScroll() +{ + Q_D(GLDTableView); + + if (!isEditing()) + { + return false; + } + + QModelIndex oCurIndex = currentIndex(); + const int nCurLogicalColumn = oCurIndex.column(); + const int nCurIndexHorizontalPos = columnViewportPosition(nCurLogicalColumn); + const int nCurIndexColumnWidth = columnWidth(nCurLogicalColumn); + const int nColumnXEndPos = nCurIndexHorizontalPos + nCurIndexColumnWidth; + + // 如果当前处于编辑状态,当editing的列被可编辑固定列覆盖掉时,应该把edit隐藏,并且不需要调用外层的d->scrollContentsBy(dx, 0); + // 不在可编辑固定列上,且当前被遮挡 + if (d->isCoverByFixedColumn(nCurLogicalColumn, nColumnXEndPos, false)) + { + if (d->m_currentEditor->isVisible()) + { + d->m_currentEditor->hide(); + } + } + // 不在可编辑固定列上,且当前没有被遮挡 + else if (nColumnXEndPos > d->m_nFixedColWidth) + { + if (d->m_currentEditor->isHidden()) + { + d->m_currentEditor->show(); + } + } + // 在可编辑固定列上,永远不会被遮挡 + else + { + return true; + } + + return false; +} + +bool GLDTableView::isEditorInFixedRowAfterVScroll() +{ + Q_D(GLDTableView); + + if (!isEditing()) + { + return false; + } + + QModelIndex oCurIndex = currentIndex(); + const int nCurLogicalRow = oCurIndex.row(); + const int nCurIndexVerticalPos = rowViewportPosition(nCurLogicalRow); + const int nCurIndexRowHeight = rowHeight(nCurLogicalRow); + const int nRowYEndPos = nCurIndexVerticalPos + nCurIndexRowHeight; + + // 如果当前处于编辑状态,当editing的列被可编辑固定列覆盖掉时,应该把edit隐藏,并且不需要调用外层的d->scrollContentsBy(dx, 0); + // 不在可编辑固定行上,且当前被遮挡 + if (d->isCoverByFixedRow(nCurLogicalRow, nRowYEndPos, false)) + { + if (d->m_currentEditor->isVisible()) + { + d->m_currentEditor->hide(); + } + } + // 不在可编辑固定行上,且当前没有被遮挡 + else if (nRowYEndPos > d->m_nFixedRowHeight) + { + if (d->m_currentEditor->isHidden()) + { + d->m_currentEditor->show(); + } + } + // 在可编辑固定行上,永远不会被遮挡 + else + { + return true; + } + + return false; +} + +QStyleOptionViewItem GLDTableView::viewOptions() const +{ + QStyleOptionViewItem option = GlodonAbstractItemView::viewOptions(); + option.showDecorationSelected = true; + return option; +} + +void GLDTableView::paintEvent(QPaintEvent *event) +{ + Q_D(GLDTableView); + QStylePainter painter(d->viewport); + QRegion region = event->region(); + paint(painter, region); +} + +QModelIndex GLDTableView::indexAt(const QPoint &pos) const +{ + Q_D(const GLDTableView); + d->executePostedLayout(); + int nRow = rowAt(pos.y()); + int nColumn = columnAt(pos.x()); + + if (nRow < 0 || nColumn < 0) + { + return QModelIndex(); + } + + if (d->hasSpans()) + { + GSpanCollection::GSpan span = d->span(nRow, nColumn); + nRow = span.top(); + nColumn = span.left(); + } + return d->m_model->index(nRow, nColumn, d->m_root); +} + +int GLDTableView::horizontalOffset() const +{ + Q_D(const GLDTableView); + return d->m_horizontalHeader->offset(); +} + +int GLDTableView::verticalOffset() const +{ + Q_D(const GLDTableView); + return d->m_verticalHeader->offset(); +} + +QModelIndex GLDTableView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers) +{ + Q_D(GLDTableView); + + // make sure that bottom is the bottommost *visible* row + int nBottom = getBottomVisibleRow(); + int nRight = getRightVisibleCol(); + if (nBottom == -1 || nRight == -1) + { + return QModelIndex(); // model is empty + } + + // 如果当前没有焦点Index,则找出左上角第一个可见格子,并返回index + QModelIndex oCurIndex = currentIndex(); + if (!oCurIndex.isValid()) + { + return leftTopVisualIndex(nRight, nBottom); + } + + // Update visual cursor if current index has changed. + updateVisualCursor(); + + int nLastVisualRow = getLastVisualRow(nBottom); + int nLastVisualCol = getLastVisualCol(nRight); + + adjustRightToLeftCursorAction(cursorAction); + + switch (cursorAction) + { + case MoveUp: + { + dealWithMoveUp(nLastVisualRow, nLastVisualCol); + break; + } + case MoveDown: + { + dealWithMoveDown(nLastVisualRow, nLastVisualCol, nBottom); + break; + } + case MovePrevious: + case MoveLeft: + { + // Ctrl + Left 向左滚动一屏 + if (modifiers & Qt::CTRL && cursorAction == MoveLeft) + { + return getLeftPageCursorIndex(); + } + + dealWithMoveLeft(nLastVisualRow, nLastVisualCol, nRight, nBottom, cursorAction); + break; + } + case MoveNext: + case MoveRight: + { + // Ctrl + Right 向右滚动一屏 + if (modifiers & Qt::CTRL && cursorAction == MoveRight) + { + return getRightPageCursorIndex(nRight); + } + + dealWithMoveRight(nLastVisualRow, nLastVisualCol, nRight, nBottom, cursorAction); + break; + } + case MoveHome: + { + // Home 定位到当前行开头 + // Ctrl + Home 定位到左上角Index + dealWithMoveHome(nLastVisualRow, nLastVisualCol, nRight, nBottom, modifiers); + break; + } + case MoveEnd: + { + // End 定位到当前行结束 + // Ctrl + End 定位到右下角Index + dealWithMoveEnd(nLastVisualRow, nLastVisualCol, nRight, nBottom, modifiers); + break; + } + case MovePageUp: + { + return getUpPageCursorIndex(); + } + case MovePageDown: + { + return getDownPageCursorIndex(nBottom); + } + } + + d->m_visualCursor = QPoint(nLastVisualCol, nLastVisualRow); + return getCursorIndex(nLastVisualRow, nLastVisualCol); +} + +void GLDTableView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags command) +{ + Q_D(GLDTableView); + + QModelIndex tl = indexAt( + QPoint(isRightToLeft() ? qMax(rect.left(), rect.right()) + : qMin(rect.left(), rect.right()), qMin(rect.top(), rect.bottom()))); + QModelIndex br = indexAt( + QPoint(isRightToLeft() ? qMin(rect.left(), rect.right()) + : qMax(rect.left(), rect.right()), qMax(rect.top(), rect.bottom()))); + QModelIndexList list = selectionModel()->selectedIndexes(); + + if (!d->m_selectionModel || !tl.isValid() || !br.isValid() || !d->isIndexEnabled(tl) || !d->isIndexEnabled(br)) + { + return; + } + + if ((rect.left() < d->m_pressedPosition.x() && rect.right() > d->m_pressedPosition.x()) || + (rect.top() < d->m_pressedPosition.x() && rect.bottom() > d->m_pressedPosition.y())) + { + if (list.contains(tl)) + { + d->m_oTopLeftSelectIndex = tl; + } + } + else + { + d->m_oTopLeftSelectIndex = tl; + } + + d->m_oBottomRightSelectIndex = br; + + d->m_rangeFillHandlePositon = RightBottom; + +// setSelectionByIndex(visualIndex(tl), visualIndex(br), command); + setSelectionByIndex(visualIndex(d->m_oTopLeftSelectIndex), visualIndex(br), command); +} + +void GLDTableView::setSelectionByIndex(const QModelIndex &tl, const QModelIndex &br, + QItemSelectionModel::SelectionFlags command) +{ + Q_D(GLDTableView); + + if (!d->m_selectionModel || !tl.isValid() || !br.isValid() || !d->isIndexEnabled(tl) || !d->isIndexEnabled(br)) + { + return; + } + + bool bverticalMoved = verticalHeader()->sectionsMoved(); + bool bhorizontalMoved = horizontalHeader()->sectionsMoved(); + + QItemSelection selection; + + int ntop = tl.row(); + int nleft = tl.column(); + int nbottom = br.row(); + int nright = br.column(); + + if (d->hasSpans()) + { + bool bexpanded(false); + + do + { + bexpanded = false; + foreach(GSpanCollection::GSpan * it, d->m_spans.spans) + { + const GSpanCollection::GSpan &span = *it; + int nt = d->visualRow(span.top()); + int nl = d->visualColumn(span.left()); + int nb = d->visualRow(d->rowSpanEndLogical(span.top(), span.height())); + int nr = d->visualColumn(d->columnSpanEndLogical(span.left(), span.width())); + + if ((nt > nbottom) || (nl > nright) || (ntop > nb) || (nleft > nr)) + { + continue; // no intersect + } + + if (nt < ntop) + { + ntop = nt; + bexpanded = true; + } + + if (nl < nleft) + { + nleft = nl; + bexpanded = true; + } + + if (nb > nbottom) + { + nbottom = nb; + bexpanded = true; + } + + if (nr > nright) + { + nright = nr; + bexpanded = true; + } + + if (bexpanded) + { + break; + } + } + } + while (bexpanded); + + for (int nhorizontal = nleft; nhorizontal <= nright; ++nhorizontal) + { + int col = d->logicalColumn(nhorizontal); + + for (int nvertical = ntop; nvertical <= nbottom; ++nvertical) + { + int row = d->logicalRow(nvertical); + + if (d->isRowHidden(row)) + { + continue; + } + + QModelIndex index = d->m_model->index(row, col, d->m_root); + selection.append(QItemSelectionRange(index)); + } + } + } + else if (bverticalMoved && bhorizontalMoved) + { + for (int nhorizontal = nleft; nhorizontal <= nright; ++nhorizontal) + { + int col = d->logicalColumn(nhorizontal); + + for (int nvertical = ntop; nvertical <= nbottom; ++nvertical) + { + int row = d->logicalRow(nvertical); + + if (d->isRowHidden(row)) + { + continue; + } + + QModelIndex index = d->m_model->index(row, col, d->m_root); + selection.append(QItemSelectionRange(index)); + } + } + } + else if (bhorizontalMoved) + { + for (int nVisual = nleft; nVisual <= nright; ++nVisual) + { + int col = d->logicalColumn(nVisual); + + if (d->isColumnHidden(col)) + { + continue; + } + + QModelIndex topLeft = d->m_model->index(tl.row(), col, d->m_root); + QModelIndex bottomRight = d->m_model->index(br.row(), col, d->m_root); + selection.append(QItemSelectionRange(topLeft, bottomRight)); + } + } + else if (bverticalMoved) + { + for (int nVisual = ntop; nVisual <= nbottom; ++nVisual) + { + int row = d->logicalRow(nVisual); + + if (d->isRowHidden(row)) + { + continue; + } + + QModelIndex topLeft = d->m_model->index(row, tl.column(), d->m_root); + QModelIndex bottomRight = d->m_model->index(row, br.column(), d->m_root); + selection.append(QItemSelectionRange(topLeft, bottomRight)); + } + } + else + { + // nothing moved + QItemSelectionRange range(tl, br); + + if (!range.isEmpty()) + { + selection.append(range); + } + } + + d->m_selectionModel->select(selection, command); +} + +QRegion GLDTableView::visualRegionForSelection(const QItemSelection &selection) const +{ + Q_D(const GLDTableView); + + if (selection.isEmpty()) + { + return QRegion(); + } + + QRegion selectionRegion; + const QRect &viewportRect = d->viewport->rect(); + bool bVerticalMoved = verticalHeader()->sectionsMoved(); + bool bHorizontalMoved = horizontalHeader()->sectionsMoved(); + + if ((bVerticalMoved && bHorizontalMoved) || (d->hasSpans() && (bVerticalMoved || bHorizontalMoved))) + { + for (int i = 0; i < selection.count(); ++i) + { + QItemSelectionRange range = selection.at(i); + + if (range.parent() != d->m_root || !range.isValid()) + { + continue; + } + + for (int row = range.top(); row <= range.bottom(); ++row) + { + for (int col = range.left(); col <= range.right(); ++col) + { + const QRect &rangeRect = visualRect(d->m_model->index(row, col, d->m_root)); + + if (viewportRect.intersects(rangeRect)) + { + selectionRegion += rangeRect; + } + } + } + } + } + else if (bHorizontalMoved) + { + for (int i = 0; i < selection.count(); ++i) + { + QItemSelectionRange range = selection.at(i); + + if (range.parent() != d->m_root || !range.isValid()) + { + continue; + } + + int ntop = rowViewportPosition(range.top()); + int nbottom = rowViewportPosition(range.bottom()) + rowHeight(range.bottom()); + + if (ntop > nbottom) + { + qSwap(ntop, nbottom); + } + + int nheight = nbottom - ntop; + + for (int col = range.left(); col <= range.right(); ++col) + { + const QRect rangeRect(columnViewportPosition(col), ntop, columnWidth(col), nheight); + + if (viewportRect.intersects(rangeRect)) + { + selectionRegion += rangeRect; + } + } + } + } + else if (bVerticalMoved) + { + for (int i = 0; i < selection.count(); ++i) + { + QItemSelectionRange range = selection.at(i); + + if (range.parent() != d->m_root || !range.isValid()) + { + continue; + } + + int nLeft = columnViewportPosition(range.left()); + int nRight = columnViewportPosition(range.right()) + columnWidth(range.right()); + + if (nLeft > nRight) + { + qSwap(nLeft, nRight); + } + + int nWidth = nRight - nLeft; + + for (int row = range.top(); row <= range.bottom(); ++row) + { + const QRect c_rangeRect(nLeft, rowViewportPosition(row), nWidth, rowHeight(row)); + + if (viewportRect.intersects(c_rangeRect)) + { + selectionRegion += c_rangeRect; + } + } + } + } + else // nothing moved + { + for (int i = 0; i < selection.count(); ++i) + { + QItemSelectionRange range = selection.at(i); + + if (range.parent() != d->m_root || !range.isValid()) + { + continue; + } + + d->trimHiddenSelections(&range); + + const int c_rtop = rowViewportPosition(range.top()); + const int c_rbottom = rowViewportPosition(range.bottom()) + rowHeight(range.bottom()); + int nrleft; + int nrright; + + if (isLeftToRight()) + { + nrleft = columnViewportPosition(range.left()); + nrright = columnViewportPosition(range.right()) + columnWidth(range.right()); + } + else + { + nrleft = columnViewportPosition(range.right()); + nrright = columnViewportPosition(range.left()) + columnWidth(range.left()); + } + + const QRect c_rangeRect(QPoint(nrleft, c_rtop), + QPoint(nrright, c_rbottom)); + + if (viewportRect.intersects(c_rangeRect)) + { + selectionRegion += c_rangeRect; + } + + if (d->hasSpans()) + { + foreach(GSpanCollection::GSpan * s, + d->m_spans.spansInRect(range.left(), range.top(), range.width(), range.height())) + { + if (range.contains(s->top(), s->left(), range.parent())) + { + const QRect &visualSpanRect = d->visualSpanRect(*s); + + if (viewportRect.intersects(visualSpanRect)) + { + selectionRegion += visualSpanRect; + } + } + } + } + } + } + + return selectionRegion; +} + +QRegion GLDTableView::visualRegionForSelectionWithSelectionBounding(const QItemSelection &selection) const +{ + QRegion oVisualRegion = visualRegionForSelection(selection); + + QRegion oContainSelectionBorderRegion; + QVector oVisualRects = oVisualRegion.rects(); + for (int i = 0; i < oVisualRects.count(); ++i) + { + oContainSelectionBorderRegion += oVisualRects[i].adjusted(-3, -3, 3, 3); + } + return oContainSelectionBorderRegion; +} + + +QModelIndexList GLDTableView::selectedIndexes() const +{ + Q_D(const GLDTableView); + QModelIndexList viewSelected; + QModelIndexList modelSelected; + + if (d->m_selectionModel) + { + modelSelected = d->m_selectionModel->selectedIndexes(); + } + + for (int i = 0; i < modelSelected.count(); ++i) + { + QModelIndex index = modelSelected.at(i); + + if (!isIndexHidden(index) && index.parent() == d->m_root) + { + viewSelected.append(index); + } + } + + return viewSelected; +} + +QModelIndexList GLDTableView::indexesFromRect(QRect rect, int &rowCount, int &columnCount) +{ + Q_D(GLDTableView); + + rowCount = rect.bottom() - rect.top() + 1; + columnCount = rect.right() - rect.left() + 1; + + QModelIndexList indexes; + for (int r = rect.top(); r <= rect.bottom(); ++r) + { + for (int c = rect.left(); c <= rect.right(); ++c) + { + indexes.push_back(dataIndex(d->m_model->index(r, c))); + } + } + + return indexes; +} + +void GLDTableView::rowCountChanged(int oldCount, int newCount) +{ + Q_D(GLDTableView); + + //when removing rows, we need to disable updates for the header until the geometries have been + //updated and the offset has been adjusted, or we risk calling paintSection for all the sections + if (newCount < oldCount) + { + d->m_verticalHeader->setUpdatesEnabled(false); + } + else if (newCount > oldCount && d->m_showEllipsisButton) + { + updateGeometries(); + } + + d->doDelayedItemsLayout(); +} + +void GLDTableView::columnCountChanged(int oldCount, int newCount) +{ + Q_D(GLDTableView); + G_UNUSED(newCount); + + // 当列发生变化的时候,应该清除自动行高等缓存, oldCount为0时不应该清除,应该可能还在初始化 + // TODO liurx 列变化的时候,情况了自动行高,自动列宽,之后怎么处理? + if (oldCount != 0) + { + d->m_oFitColWidthCols.clear(); + d->m_oSuitColWidthCols.clear(); + d->m_oSuitRowHeightAccordingCols.clear(); + } + + d->fillSuitColWidthCols(); + d->fillSuitRowHeightCols(); + + updateGeometries(); + + if (horizontalScrollMode() == GlodonAbstractItemView::ScrollPerItem) + { + d->m_horizontalHeader->setOffsetToSectionPosition(horizontalScrollBar()->value()); + } + else + { + d->m_horizontalHeader->setOffset(horizontalScrollBar()->value()); + } + + d->viewport->update(); +} + +void GLDTableView::showSectionResizingInfoFrame( + const QPoint &mousePostion, Qt::Orientation direction, GlodonHeaderView::ResizeState state) +{ + Q_D(GLDTableView); + + if (!d->m_isShowResizeInfoFrame) + { + return; + } + + initResizeInfoFrames(direction); + + if (state == GlodonHeaderView::Press) + { + QPoint oDestPoint = d->calcResizeInfoLineFramePosition(direction); + d->m_pResizeInfoLineFrame->move(oDestPoint); + + d->m_pResizeInfoLineFrame->show(); + + initSectionResizingInfoFrame(mousePostion, direction); + d->m_infoFrame->show(); + } + else if (state == GlodonHeaderView::Move) + { + QPoint oDestPoint = d->calcResizeInfoLineFramePosition(direction); + d->m_pResizeInfoLineFrame->move(oDestPoint); + + updateSectionResizingInfoFrameText(direction); + } + else + { + d->m_pResizeInfoLineFrame->hide(); + d->m_infoFrame->hide(); + } +} + +void GLDTableView::updateGeometries() +{ + Q_D(GLDTableView); + + if (d->m_geometryRecursionBlock) + { + return; + } + d->m_geometryRecursionBlock = true; + + int nVerticalHeaderWidth = d->m_verticalHeader->drawWidth(); + int nHorizontalHeaderHeight = d->m_horizontalHeader->drawWidth(); + + setViewportMargins(nVerticalHeaderWidth, nHorizontalHeaderHeight, 0, 0); + + // update headers + updateVerticalHeaderGeometry(nVerticalHeaderWidth); + updateHorizontalHeaderGeometry(nHorizontalHeaderHeight); + + // update cornerWidget + updateConrnerWidgetGeometry(nVerticalHeaderWidth, nHorizontalHeaderHeight); + + // update scroll bars + // ### move this block into the if + QSize oViewportSize = d->viewport->size(); + QSize oMaxViewportSize = maximumViewportSize(); + uint nHorizontalHeaderLength = d->m_horizontalHeader->length(); + uint nVerticalHeaderLength = d->m_verticalHeader->length(); + + if ((uint)oMaxViewportSize.width() >= nHorizontalHeaderLength + && (uint)oMaxViewportSize.height() >= nVerticalHeaderLength) + { + oViewportSize = oMaxViewportSize; + } + + updateHorizontalScrollBar(oViewportSize); + updateVerticalScrollBar(oViewportSize); + + d->m_geometryRecursionBlock = false; + GlodonAbstractItemView::updateGeometries(); +} + +int GLDTableView::sizeHintForRow(int row) const +{ + Q_D(const GLDTableView); + + int nLeft = firstVisualCol(); + int nRight = lastVisualCol(); + + adjustVisualCol(nLeft, nRight); + + QSet oNeedCalcSizeHintCols; + + for (int i = 0; i < d->m_nFixedColCount; ++i) + { + oNeedCalcSizeHintCols.insert(i); + } + + for (int i = nLeft; i <= nRight; ++i) + { + oNeedCalcSizeHintCols.insert(i); + } + + return d->calcSizeHintForRow(row, oNeedCalcSizeHintCols.toList()); +} + +int GLDTableView::sizeHintForColumn(int column) const +{ + Q_D(const GLDTableView); + + return d->sizeHintForColumn(column, false); +} + +int GLDTableView::calcSuitHeight(const QList &oNeedCalcHeightCols, int nLogicalRow) +{ + Q_D(GLDTableView); + return d->calcSuitHeight(oNeedCalcHeightCols, nLogicalRow); +} + +int GLDTableView::calcSuitWidth(int nLogicalCol) +{ + Q_D(GLDTableView); + return d->calcSuitWidth(nLogicalCol, true); +} + +int GLDTableView::rowViewportPosition(int row) const +{ + Q_D(const GLDTableView); + return d->m_verticalHeader->sectionViewportPosition(row); +} + +int GLDTableView::rowVisualPosition(int visualRow) const +{ + Q_D(const GLDTableView); + return d->m_verticalHeader->sectionVisualPosition(visualRow) - d->m_verticalHeader->offset(); +} + +int GLDTableView::rowAt(int y) const +{ + Q_D(const GLDTableView); + return d->m_verticalHeader->logicalIndexAt(y); +} + +int GLDTableView::visualRowAt(int y) const +{ + Q_D(const GLDTableView); + return d->m_verticalHeader->visualIndexAt(y); +} + +/*! + \since 4.1 + + Sets the height of the given \a row to be \a height. +*/ +void GLDTableView::setRowHeight(int row, int height, bool isManual) +{ + Q_D(const GLDTableView); + d->m_verticalHeader->resizeSection(row, height, true, isManual); +} + +int GLDTableView::rowHeight(int row) const +{ + Q_D(const GLDTableView); + return d->m_verticalHeader->sectionSize(row); +} + +int GLDTableView::visualRowHeight(int visualRow) const +{ + Q_D(const GLDTableView); + return d->m_verticalHeader->visualSectionSize(visualRow); +} + +int GLDTableView::columnViewportPosition(int column) const +{ + Q_D(const GLDTableView); + return d->m_horizontalHeader->sectionViewportPosition(column); +} + +int GLDTableView::columnVisualPosition(int visualColumn) const +{ + Q_D(const GLDTableView); + return d->m_horizontalHeader->sectionVisualPosition(visualColumn) - d->m_horizontalHeader->offset(); +} + +int GLDTableView::columnAt(int x) const +{ + Q_D(const GLDTableView); + return d->m_horizontalHeader->logicalIndexAt(x); +} + +int GLDTableView::visualColumnAt(int x) const +{ + Q_D(const GLDTableView); + return d->m_horizontalHeader->visualIndexAt(x); +} + +void GLDTableView::setColumnWidth(int column, int width) +{ + Q_D(const GLDTableView); + d->m_horizontalHeader->resizeSection(column, width); +} + +int GLDTableView::columnWidth(int column) const +{ + Q_D(const GLDTableView); + return d->m_horizontalHeader->sectionSize(column); +} + +int GLDTableView::visualColumnWidth(int visualColumn) const +{ + Q_D(const GLDTableView); + return d->m_horizontalHeader->visualSectionSize(visualColumn); +} + +bool GLDTableView::isRowHidden(int row) const +{ + Q_D(const GLDTableView); + return d->m_verticalHeader->isSectionHidden(row); +} + +void GLDTableView::setRowHidden(int row, bool hide) +{ + Q_D(GLDTableView); + + if (row < 0 || row >= d->m_verticalHeader->count()) + { + return; + } + + d->m_verticalHeader->setSectionHidden(row, hide); +} + +bool GLDTableView::isColumnHidden(int column) const +{ + Q_D(const GLDTableView); + return d->m_horizontalHeader->isSectionHidden(column); +} + +void GLDTableView::setColumnHidden(int column, bool hide) +{ + Q_D(GLDTableView); + + if (column < 0 || column >= d->m_horizontalHeader->count()) + { + return; + } + + d->m_horizontalHeader->setSectionHidden(column, hide); +} + +void GLDTableView::setSortingEnabled(bool enable) +{ + Q_D(GLDTableView); + + if (d->m_sortingEnabled != enable) + { + d->m_sortingEnabled = enable; + horizontalHeader()->setSortIndicatorShown(enable); + + if (enable) + { + disconnect(d->m_horizontalHeader, SIGNAL(sectionEntered(int)), + this, SLOT(_q_selectColumn(int))); + disconnect(horizontalHeader(), SIGNAL(sectionPressed(int)), + this, SLOT(selectColumn(int))); + + if (GlodonMultiHeaderView *horizontalHeader = dynamic_cast(d->m_horizontalHeader)) + disconnect(horizontalHeader, SIGNAL(headerSpanPressed(int, int, int, int)), + this, SLOT(_q_selectColumns(int, int, int, int))); + + connect(horizontalHeader(), SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)), + this, SLOT(sortByColumn(int)), Qt::UniqueConnection); + + sortByColumn(horizontalHeader()->sortIndicatorSection(), + horizontalHeader()->sortIndicatorOrder()); + } + else + { + connect(d->m_horizontalHeader, SIGNAL(sectionEntered(int)), + this, SLOT(_q_selectColumn(int)), Qt::UniqueConnection); + connect(horizontalHeader(), SIGNAL(sectionPressed(int)), + this, SLOT(selectColumn(int)), Qt::UniqueConnection); + + if (GlodonMultiHeaderView *horizontalHeader = dynamic_cast(d->m_horizontalHeader)) + connect(horizontalHeader, SIGNAL(headerSpanPressed(int, int, int, int)), + this, SLOT(_q_selectColumns(int, int, int, int))); + + disconnect(horizontalHeader(), SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)), + this, SLOT(sortByColumn(int))); + } + } +} + +bool GLDTableView::isSortingEnabled() const +{ + Q_D(const GLDTableView); + return d->m_sortingEnabled; +} + +void GLDTableView::forceCloseEditor() +{ + Q_D(GLDTableView); + bool bCanCloseEditor = true; + closeEditor(d->delegateForIndex(d->m_oEditorIndex)->curEditor(), + bCanCloseEditor, GlodonDefaultItemDelegate::RevertModelCache); +} + +void GLDTableView::setDisplayResizeInfoFrame(bool value) +{ + Q_D(GLDTableView); + d->m_isShowResizeInfoFrame = value; +} + +GCustomCommentFrame *GLDTableView::addComment(const QModelIndex &index, QString value) +{ + Q_D(GLDTableView); + GCustomCommentFrame *pCommentFrame = findOrCreateCommentFrame(index); + d->m_model->setData(index, value, gidrCommentRole); + pCommentFrame->setCommentText(value); + pCommentFrame->show(); + return pCommentFrame; +} + +GCustomCommentFrame *GLDTableView::editComment(const QModelIndex &index) +{ + Q_D(GLDTableView); + + if (GCustomCommentFrame *pCommentFrame = findOrCreateCommentFrame(index)) + { + pCommentFrame->setCommentText(d->m_model->data(index, gidrCommentRole).toString()); + pCommentFrame->show(); + return pCommentFrame; + } + else + { + return NULL; + } +} + +bool GLDTableView::isShowComment(const QModelIndex &index) +{ + if (GCustomCommentFrame *pCommentFrame = findOrCreateCommentFrame(index, false)) + { + return pCommentFrame->isVisible(); + } + else + { + return false; + } +} + +GCustomCommentFrame *GLDTableView::showOrHideCommentPersistent(const QModelIndex &index, bool isShow) +{ + Q_D(GLDTableView); + + if (GCustomCommentFrame *pCommentFrame = findOrCreateCommentFrame(index)) + { + if (isShow) + { + pCommentFrame->setCommentText(d->m_model->data(index, gidrCommentRole).toString()); + pCommentFrame->show(true); + } + else + { + pCommentFrame->hide(); + } + + return pCommentFrame; + } + else + { + return NULL; + } +} + +void GLDTableView::deleteComment(const QModelIndex &index) +{ + Q_D(GLDTableView); + d->m_oCommentFrames.value(index)->deleteLater(); + d->m_oCommentFrames.remove(index); +} + +void GLDTableView::showOrHideAllCommentPersistent(bool isShow) +{ + Q_D(GLDTableView); + QMap::iterator it = d->m_oCommentFrames.begin(); + + while (it != d->m_oCommentFrames.end()) + { + if (isShow) + { + it.value()->show(true); + } + else + { + it.value()->hide(); + } + + it++; + } +} + +const GCustomCommentFrame *GLDTableView::findComment(const QModelIndex &index) const +{ + Q_D(const GLDTableView); + + return d->m_oCommentFrames.value(index); +} + +void GLDTableView::setBoolEditValue(QModelIndex &currIndex) +{ + Q_D(GLDTableView); + + if (Qt::ItemIsEditable == (d->m_model->flags(currIndex) & Qt::ItemIsEditable)) + { + bool breadOnly = false; + + GlodonDefaultItemDelegate *pDelegate = d->delegateForIndex(currIndex); + pDelegate->setCurrTreeEditting(currIndex); + + GEditStyle editStyle = pDelegate->editStyle(dataIndex(currIndex), breadOnly); + + if (editStyle == esNone) + { + breadOnly = true; + } + + if (!breadOnly) + { + bool bvalue = currIndex.data(Qt::DisplayRole).toBool(); + model()->setData(currIndex, !bvalue); + } + } +} + +void GLDTableView::setAllowCopy(bool allowCopy) +{ + Q_D(GLDTableView); + d->m_allowCopy = allowCopy; +} + +bool GLDTableView::allowCopy() const +{ + Q_D(const GLDTableView); + return d->m_allowCopy; +} + +void GLDTableView::setAllowPaste(bool allowPaste) +{ + Q_D(GLDTableView); + d->m_allowPaste = allowPaste; +} + +bool GLDTableView::allowPaste() const +{ + Q_D(const GLDTableView); + return d->m_allowPaste; +} + +bool GLDTableView::isEditing() const +{ + Q_D(const GLDTableView); + + if (d->m_state == GlodonAbstractItemView::EditingState) + { + return true; + } + else + { + return false; + } +} + +bool GLDTableView::cellCanGetEdit(int row, int column) +{ + // 只要设置了NoEditTrigger,就是不能编辑的 + if (editTriggers() == NoEditTriggers) + { + return false; + } + + QModelIndex index = dataIndex(model()->index(row, column)); + if (!index.isValid()) + { + return false; + } + + GlodonDefaultItemDelegate *pItemDelegate = itemDelegate(); + if (!pItemDelegate->editable(index)) + { + return false; + } + + bool bResdOnly = true; + if (pItemDelegate->editStyle(index, bResdOnly) == esNone) + { + return false; + } + + return true; +} + +bool GLDTableView::isDisplayFilter() +{ + return false; +} + +bool GLDTableView::totalRowAtFooter() const +{ + return false; +} + +bool GLDTableView::showGrid() const +{ + Q_D(const GLDTableView); + return d->m_showGrid; +} + +void GLDTableView::setDrawTopAndLeftBorderLine(bool value) +{ + Q_D(GLDTableView); + d->m_bDrawTopAndLeftBorderLine = value; +} + +bool GLDTableView::drawTopAndLeftBorderLine() +{ + Q_D(const GLDTableView); + return d->m_bDrawTopAndLeftBorderLine; +} + +void GLDTableView::setShowGrid(bool show) +{ + Q_D(GLDTableView); + + if (d->m_showGrid == show) + return; + + d->m_showGrid = show; + + d->setGridLineWidthToHorizontalHeader(show ? d->m_gridLineWidth : 0); + d->setGridLineWidthToVertialHeader(show ? d->m_gridLineWidth : 0); + + d->viewport->update(); +} + +void GLDTableView::selectColumns(int start, int end) +{ + Q_D(GLDTableView); + d->selectColumns(start, end, true); +} + +void GLDTableView::selectRows(int start, int end) +{ + Q_D(GLDTableView); + d->selectRows(start, end, true); +} + +void GLDTableView::setCurrentIndex(const QModelIndex &dataIndex) +{ + QModelIndex index = treeIndex(dataIndex); + Q_ASSERT(index.model() == model()); + GlodonAbstractItemView::setCurrentIndex(index); +} + +void GLDTableView::setCurrentIndex(int row, int column) +{ + Q_D(GLDTableView); + QModelIndex index = d->m_model->index(row, column); + GlodonAbstractItemView::setCurrentIndex(index); +} + +void GLDTableView::setSuitRowHeights(const GIntList &accordingCols) +{ + Q_D(GLDTableView); + + d->m_oSuitRowHeightAccordingCols = accordingCols; + + if (isVisible()) + { + setGridDisplayRowHeights(); + } +} + +GIntList GLDTableView::suitRowHeights() +{ + Q_D(GLDTableView); + + return d->m_oSuitRowHeightAccordingCols; +} + +void GLDTableView::setSuitColWidths(const GIntList &suitColWidthCols) +{ + Q_D(GLDTableView); + + d->m_oSuitColWidthCols = suitColWidthCols; + + if (isVisible()) + { + setGridDisplayColWidths(); + } +} + +GIntList GLDTableView::suitColWidths() +{ + Q_D(GLDTableView); + + return d->m_oSuitColWidthCols; +} + +void GLDTableView::setFitColWidths(const GIntList &fitColWidthsCols) +{ + Q_D(GLDTableView); + + d->m_oFitColWidthCols = fitColWidthsCols; + + if (isVisible()) + { + adjustColWidths(-1); + } +} + +GIntList GLDTableView::fitColWidths() +{ + Q_D(GLDTableView); + + return d->m_oFitColWidthCols; +} + +void GLDTableView::onScrolled(int offset) +{ + Q_UNUSED(offset); + refreshDisplayColRow(); +} + +void GLDTableView::beforeReset() +{ + d_func()->m_bIsInReset = true; + GlodonAbstractItemView::beforeReset(); +} + +void GLDTableView::doReset() +{ + Q_D(GLDTableView); + d->m_legalData = true; + d->m_prevState = GlodonAbstractItemView::FirstFocus; + GlodonAbstractItemView::doReset(); +} + +void GLDTableView::afterReset() +{ + d_func()->m_bIsInReset = false; + + refreshDisplayColRow(); + GlodonAbstractItemView::afterReset(); +} + +void GLDTableView::canRowMoved(int from, int to, bool &canMove) +{ + Q_D(GLDTableView); + + for (int col = 0; col < horizontalHeader()->count(); ++col) + { + GSpanCollection::GSpan *fromSpan = d->m_spans.spanAt(col, from); + GSpanCollection::GSpan *toSpan = d->m_spans.spanAt(col, to); + + if ((NULL != fromSpan) || (NULL != toSpan)) + { + canMove = false; + } + } + + if (!canMove) + { + d->viewport->update(); + } +} + +Qt::PenStyle GLDTableView::gridStyle() const +{ + Q_D(const GLDTableView); + return d->m_gridStyle; +} + +void GLDTableView::setGridStyle(Qt::PenStyle style) +{ + Q_D(GLDTableView); + + if (d->m_gridStyle == style) + return; + + d->m_gridStyle = style; + + d->setGridLineWidthToHorizontalHeader((style == Qt::NoPen) ? 0 : d->m_gridLineWidth); + d->setGridLineWidthToVertialHeader((style == Qt::NoPen) ? 0 : d->m_gridLineWidth); + + d->viewport->update(); +} + +void GLDTableView::setWordWrap(bool on) +{ + Q_D(GLDTableView); + + if (d->m_bWrapItemText == on) + { + return; + } + + d->m_bWrapItemText = on; + QMetaObject::invokeMethod(d->m_verticalHeader, "resizeSections"); + QMetaObject::invokeMethod(d->m_horizontalHeader, "resizeSections"); +} + +bool GLDTableView::wordWrap() const +{ + Q_D(const GLDTableView); + return d->m_bWrapItemText; +} + +void GLDTableView::setCornerButtonEnabled(bool enable) +{ + Q_D(GLDTableView); + d->m_cornerWidget->setEnabled(enable); +} + +bool GLDTableView::isCornerButtonEnabled() const +{ + Q_D(const GLDTableView); + return d->m_cornerWidget->isEnabled(); +} + +QWidget *GLDTableView::cornerWidget() const +{ + Q_D(const GLDTableView); + return d->m_cornerWidget; +} + +void GLDTableView::setCornerWidget(QWidget *widget) +{ + Q_D(GLDTableView); + + QWidget *oldWidget = d->m_cornerWidget; + + if (oldWidget != widget) + { + if (oldWidget) + { + oldWidget->hide(); + oldWidget->deleteLater(); + } + + d->m_cornerWidget = widget; + + if (widget && widget->parentWidget() != this) + { + widget->setParent(this); + } + + d->layoutChildren(); + + if (widget) + { + widget->show(); + } + } + else + { + d->m_cornerWidget = widget; + d->layoutChildren(); + } + + GTableCornerWidget *cornerWidget = dynamic_cast(d->m_cornerWidget); + + if (cornerWidget) + { + cornerWidget->setModel(d->m_model); + } + + GlodonAbstractItemView *gView = dynamic_cast(d->m_cornerWidget); + + if (gView) + { + gView->setModel(d->m_model); + } + + QAbstractItemView *qView = dynamic_cast(d->m_cornerWidget); + + if (qView) + { + qView->setModel(d->m_model); + } +} + +void GLDTableView::setAllowRangeFilling(bool enable) +{ + Q_D(GLDTableView); + + if (d->m_allowRangeFilling != enable) + { + d->m_allowRangeFilling = enable; + d->viewport->update(); + } +} + +bool GLDTableView::allowRangeFilling() const +{ + Q_D(const GLDTableView); + return d->m_allowRangeFilling; +} + +void GLDTableView::setRangeFillingStyle(RangeFillingStyle style) +{ + Q_D(GLDTableView); + d->m_rangeFillingStyle = style; +} + +RangeFillingStyle GLDTableView::rangeFillingStyle() +{ + Q_D(GLDTableView); + return d->m_rangeFillingStyle; +} + +bool GLDTableView::highlightSections() const +{ + Q_D(const GLDTableView); + return d->m_verticalHeader->highlightSections(); +} + +void GLDTableView::setHighlightSections(bool value) +{ + Q_D(GLDTableView); + d->m_verticalHeader->setHighlightSections(value); + d->m_horizontalHeader->setHighlightSections(value); +} + +int GLDTableView::gridLineWidth() const +{ + Q_D(const GLDTableView); + return d->m_gridLineWidth; +} + +void GLDTableView::setGridLineWidth(int value) +{ + Q_D(GLDTableView); + if (d->m_gridLineWidth == value) + return; + + if (!d->m_bIsCustomStyle) + { + setIsCustomStyle(true); + } + + d->m_gridLineWidth = value; + + if (d->m_showGrid) + { + d->setGridLineWidthToHorizontalHeader(value); + d->setGridLineWidthToVertialHeader(value); + } + + d->viewport->update(); +} + +QColor GLDTableView::gridLineColor() const +{ + Q_D(const GLDTableView); + return d->m_gridLineColor; +} + +void GLDTableView::setFrameLineColor(QColor value) +{ + Q_D(GLDTableView); + d->m_oFrameLineColor = value; +} + +QColor GLDTableView::frameLineColor() const +{ + Q_D(const GLDTableView); + return d->m_oFrameLineColor; +} + +void GLDTableView::setGridLineColor(QColor value) +{ + Q_D(GLDTableView); + + if (!d->m_bIsCustomStyle) + { + setIsCustomStyle(true); + } + + d->m_gridLineColor = value; + + if (d->m_horizontalHeader) + { + d->m_horizontalHeader->setGridLineColor(value); + } + + if (d->m_verticalHeader) + { + d->m_verticalHeader->setGridLineColor(value); + } + + d->viewport->update(); +} + +bool GLDTableView::showVerticalGridLine() const +{ + Q_D(const GLDTableView); + return d->m_bShowVerticalGridLine; +} + +void GLDTableView::setShowVerticalGridLine(bool value) +{ + Q_D(GLDTableView); + + if (d->m_bShowVerticalGridLine != value) + { + d->m_bShowVerticalGridLine = value; + + if (value) + { + d->m_horizontalHeader->setGridLineWidth(d->m_gridLineWidth); + } + else + { + d->m_horizontalHeader->setGridLineWidth(0); + } + + d->viewport->update(); + } +} + +bool GLDTableView::showHorizontalGridLine() const +{ + Q_D(const GLDTableView); + return d->m_bShowHorizontalGridLine; +} + +void GLDTableView::setShowHorizontalGridLine(bool value) +{ + Q_D(GLDTableView); + + if (d->m_bShowHorizontalGridLine != value) + { + d->m_bShowHorizontalGridLine = value; + + if (value) + { + d->m_verticalHeader->setGridLineWidth(d->m_gridLineWidth); + } + else + { + d->m_verticalHeader->setGridLineWidth(0); + } + } + + d->viewport->update(); +} + +bool GLDTableView::allowSelectRow() const +{ + Q_D(const GLDTableView); + return d->m_allowSelectRow; +} + +void GLDTableView::setAllowSelectRow(bool value) +{ + Q_D(GLDTableView); + d->m_allowSelectRow = value; +} + +bool GLDTableView::allowSelectCol() const +{ + Q_D(const GLDTableView); + return d->m_allowSelectCol; +} + +void GLDTableView::setAllowSelectCol(bool value) +{ + Q_D(GLDTableView); + d->m_allowSelectCol = value; +} + +bool GLDTableView::cellFillEditField() const +{ + Q_D(const GLDTableView); + return d->m_cellFillEditField; +} + +void GLDTableView::setCellFillEditField(bool value) +{ + Q_D(GLDTableView); + d->m_cellFillEditField = value; +} + +void GLDTableView::setGridColor(QColor value) +{ + Q_D(GLDTableView); + + if (!d->m_bIsCustomStyle) + { + setIsCustomStyle(true); + } + + d->m_horizontalHeader->setGridColor(value); + d->m_verticalHeader->setGridColor(value); + + GlodonAbstractItemView::setGridColor(value); +} + +void GLDTableView::setFixedColCount(int fixedColCount) +{ + Q_D(GLDTableView); + d->m_nFixedColCount = fixedColCount; + d->m_horizontalHeader->setFixedCount(fixedColCount); + + d->m_horizontalHeader->viewport()->update(); + d->viewport->update(); +} + +int GLDTableView::fixedColCount() const +{ + Q_D(const GLDTableView); + return d->m_nFixedColCount; +} + +void GLDTableView::setFixedRowCount(int fixedRowCount) +{ + Q_D(GLDTableView); + d->m_nFixedRowCount = fixedRowCount; + d->m_verticalHeader->setFixedCount(fixedRowCount); + + d->m_verticalHeader->viewport()->update(); + d->viewport->update(); +} + +int GLDTableView::fixedRowCount() const +{ + Q_D(const GLDTableView); + return d->m_nFixedRowCount; +} + +bool GLDTableView::isCustomStyle() const +{ + Q_D(const GLDTableView); + return d->m_bIsCustomStyle; +} + +void GLDTableView::setIsCustomStyle(bool value) +{ + Q_D(GLDTableView); + + if (d->m_bIsCustomStyle != value) + { + horizontalHeader()->setFixedCellEvent(value); + verticalHeader()->setFixedCellEvent(value); + d->m_bIsCustomStyle = value; + } +} + +void GLDTableView::zoomTableView(double factor) +{ + Q_D(GLDTableView); + + int nPrevSize = horizontalHeader()->sectionSize(horizontalHeader()->count() - 1); + double dPrevWidth = horizontalHeader()->width(); + + horizontalHeader()->zoomInSection(factor); + verticalHeader()->zoomInSection(factor); + + horizontalHeader()->setInZoomingSection(true); + + if (dPrevWidth > 1) + { + GlodonDefaultItemDelegate *delegate = itemDelegate(); + double dRate = horizontalHeader()->width() / dPrevWidth; + + if (delegate->m_factor > 0.1) + { + dRate = factor / delegate->m_factor; + } + + delegate->m_factor = factor; + + horizontalHeader()->resizeSection(horizontalHeader()->count() - 1, dRate * nPrevSize); + } + + horizontalHeader()->setInZoomingSection(false); + + // QTimer::singleShot(0, horizontalHeader(), SLOT(resizeSections())); + // d->m_horizontalHeader->setInZoomingSection(true); + // qDebug()<< QMetaObject::invokeMethod(d->m_horizontalHeader, "resizeSections"); + // d->m_horizontalHeader->setInZoomingSection(false); + if (d->m_model->rowCount() <= 0) + { + return; + } + + d->viewport->update(d->viewport->rect()); +} + +void GLDTableView::setAlwaysShowRowSelectedBgColor(bool isShow) +{ + Q_D(GLDTableView); + d->m_alwaysShowRowSelectedColor = isShow; +} + +bool GLDTableView::alwaysShowRowSelectedBgColor() +{ + Q_D(GLDTableView); + return d->m_alwaysShowRowSelectedColor; +} + +QRect GLDTableView::visualRect(const QModelIndex &index) const +{ + Q_D(const GLDTableView); + + if (!d->isIndexValid(index) + || (!d->hasSpans() && isIndexHidden(index))) + { + return QRect(); + } + + d->executePostedLayout(); + + if (d->hasSpans()) + { + GSpanCollection::GSpan span = d->span(index.row(), index.column()); + return d->visualSpanRect(span); + } + + QVariant oBoundLine = index.data(gidrBoundLineRole); + + QRect oVisualRect = d->visualRectIncludeBoundingLineWidth(index); + oVisualRect.setWidth(oVisualRect.width() - borderLineSubtractGridLineWidth(oBoundLine, true)); + oVisualRect.setHeight(oVisualRect.height() - borderLineSubtractGridLineWidth(oBoundLine, false)); + return oVisualRect; +} + +QRect GLDTableView::visualRectIncludeBoundingLineWidth(const QModelIndex &index) const +{ + Q_D(const GLDTableView); + + if (!d->isIndexValid(index) + || (!d->hasSpans() && isIndexHidden(index))) + { + return QRect(); + } + + d->executePostedLayout(); + + if (d->hasSpans()) + { + GSpanCollection::GSpan span = d->span(index.row(), index.column()); + return d->visualSpanRectIncludeBoundingLineWidth(span); + } + + return d->visualRectIncludeBoundingLineWidth(index); +} + +int GLDTableView::getBottomVisibleRow() +{ + Q_D(GLDTableView); + int nBottom = d->m_model->rowCount(d->m_root) - 1; + while (nBottom >= 0 && isRowHidden(d->logicalRow(nBottom))) + { + --nBottom; + } + + return nBottom; +} + +int GLDTableView::getRightVisibleCol() +{ + Q_D(GLDTableView); + int nRight = d->m_model->columnCount(d->m_root) - 1; + while (nRight >= 0 && isColumnHidden(d->logicalColumn(nRight))) + { + --nRight; + } + + return nRight; +} + +int GLDTableView::getLastVisualRow(int nBottom) +{ + Q_D(GLDTableView); + int nVisualRow = d->m_visualCursor.y(); + if (nVisualRow > nBottom) + { + nVisualRow = nBottom; + } + Q_ASSERT(nVisualRow != -1); + + return nVisualRow; +} + +int GLDTableView::getLastVisualCol(int nRight) +{ + Q_D(GLDTableView); + int nVisualColumn = d->m_visualCursor.x(); + if (nVisualColumn > nRight) + { + nVisualColumn = nRight; + } + Q_ASSERT(nVisualColumn != -1); + + return nVisualColumn; +} + +QModelIndex GLDTableView::leftTopVisualIndex(int nRight, int nBottom) +{ + Q_D(GLDTableView); + + // 找出最左边的可见列 + int nLeftColumn = 0; + while (nLeftColumn < nRight && isColumnHidden(d->logicalColumn(nLeftColumn))) + { + ++nLeftColumn; + } + + // 找出最上面的可见行 + int nTopRow = 0; + while (isRowHidden(d->logicalRow(nTopRow)) && nTopRow < nBottom) + { + ++nTopRow; + } + + d->m_visualCursor = QPoint(nLeftColumn, nTopRow); + return d->m_model->index(d->logicalRow(nTopRow), d->logicalColumn(nLeftColumn), d->m_root); +} + +void GLDTableView::updateVisualCursor() +{ + Q_D(GLDTableView); + + QModelIndex oCurIndex = currentIndex(); + QPoint oVisualCurrent(d->visualColumn(oCurIndex.column()), d->visualRow(oCurIndex.row())); + if (oVisualCurrent != d->m_visualCursor) + { + // 如果当前焦点Index处于合并格中,并且原来的m_visualCursor不在合并格中 + // 直接将m_visualCursor设置为Current + // 否则改变m_visualCursor + if (d->hasSpans()) + { + GSpanCollection::GSpan span = d->span(oCurIndex.row(), oCurIndex.column()); + if (span.top() > d->m_visualCursor.y() || d->m_visualCursor.y() > span.bottom() + || span.left() > d->m_visualCursor.x() || d->m_visualCursor.x() > span.right()) + { + d->m_visualCursor = oVisualCurrent; + } + } + else + { + d->m_visualCursor = oVisualCurrent; + } + } +} + +void GLDTableView::adjustRightToLeftCursorAction(GlodonAbstractItemView::CursorAction cursorAction) +{ + if (isRightToLeft()) + { + if (cursorAction == MoveLeft) + { + cursorAction = MoveRight; + } + else if (cursorAction == MoveRight) + { + cursorAction = MoveLeft; + } + } +} + +void GLDTableView::dealWithMoveUp(int &nLastVisualRow, int &nLastVisualCol) +{ + Q_D(GLDTableView); + + int nOriginalRow = nLastVisualRow; + +#ifdef QT_KEYPAD_NAVIGATION + if (QApplication::keypadNavigationEnabled() && nLastVisualRow == 0) + { + nLastVisualRow = d->visualRow(model()->rowCount() - 1) + 1; + } + // FIXME? visualRow = bottom + 1; +#endif + + int nLogicalRow = d->logicalRow(nLastVisualRow); + int nLogicalCol = d->logicalColumn(nLastVisualCol); + if (nLogicalRow != -1 && d->hasSpans()) + { + GSpanCollection::GSpan span = d->span(nLogicalRow, nLogicalCol); + if (span.width() > 1 || span.height() > 1) + { + nLastVisualRow = d->visualRow(span.top()); + } + } + + // 找到向上最近的可见的并且可选择的行 + while (nLastVisualRow >= 0) + { + --nLastVisualRow; + nLogicalRow = d->logicalRow(nLastVisualRow); + nLogicalCol = d->logicalColumn(nLastVisualCol); + if (nLogicalRow == -1 || (!isRowHidden(nLogicalRow) && d->isCellEnabledAndSelectabled(nLogicalRow, nLogicalCol))) + { + break; + } + } + + if (nLastVisualRow < 0) + { + nLastVisualRow = nOriginalRow; + } +} + +void GLDTableView::dealWithMoveDown(int &nLastVisualRow, int &nLastVisualCol, int nBottom) +{ + Q_D(GLDTableView); + + int nOriginalRow = nLastVisualRow; + QModelIndex oCurIndex = currentIndex(); + if (d->hasSpans()) + { + GSpanCollection::GSpan span = d->span(oCurIndex.row(), oCurIndex.column()); + nLastVisualRow = d->visualRow(d->rowSpanEndLogical(span.top(), span.height())); + } + +#ifdef QT_KEYPAD_NAVIGATION + if (QApplication::keypadNavigationEnabled() && nLastVisualRow >= nBottom) + { + nLastVisualRow = -1; + } +#endif + + int nLogicalRow = d->logicalRow(nLastVisualRow); + int nLogicalCol = d->logicalColumn(nLastVisualCol); + if (nLogicalRow != -1 && d->hasSpans()) + { + GSpanCollection::GSpan span = d->span(nLogicalRow, nLogicalCol); + if (span.width() > 1 || span.height() > 1) + { + nLastVisualRow = d->visualRow(d->rowSpanEndLogical(span.top(), span.height())); + } + } + + // 找到向下的最近一个可见,并且可选中的行 + while (nLastVisualRow <= nBottom) + { + ++nLastVisualRow; + nLogicalRow = d->logicalRow(nLastVisualRow); + nLogicalCol = d->logicalColumn(nLastVisualCol); + if (nLogicalRow == -1 || (!isRowHidden(nLogicalRow) && d->isCellEnabledAndSelectabled(nLogicalRow, nLogicalCol))) + { + break; + } + } + + if (nLastVisualRow > nBottom) + { + nLastVisualRow = nOriginalRow; + } +} + +QModelIndex GLDTableView::getLeftPageCursorIndex() +{ + Q_D(GLDTableView); + QModelIndex oCurIndex = currentIndex(); + int nNewColumn = columnAt(visualRect(oCurIndex).right() - d->viewport->width()); + if (nNewColumn == -1) + { + nNewColumn = d->logicalRow(0); + } + return d->m_model->index(oCurIndex.row(), nNewColumn, d->m_root); +} + +void GLDTableView::dealWithMoveLeft(int &nLastVisualRow, int &nLastVisualCol, int nRight, int nBottom, CursorAction cursorAction) +{ + Q_D(GLDTableView); + + int nOriginalRow = nLastVisualRow; + int nOriginalColumn = nLastVisualCol; + bool bFirstTime = true; + bool bLooped = false; + bool bWrapped = false; + + do + { + int nRow = d->logicalRow(nLastVisualRow); + int nCol = d->logicalColumn(nLastVisualCol); + if (bFirstTime && nCol != -1 && d->hasSpans()) + { + bFirstTime = false; + GSpanCollection::GSpan span = d->span(nRow, nCol); + if (span.width() > 1 || span.height() > 1) + { + nLastVisualCol = d->visualColumn(span.left()); + } + } + + while (nLastVisualCol >= 0) + { + --nLastVisualCol; + nRow = d->logicalRow(nLastVisualRow); + nCol = d->logicalColumn(nLastVisualCol); + if (nRow == -1 || nCol == -1 + || (!isRowHidden(nRow) && !isColumnHidden(nCol) + && d->isCellEnabledAndSelectabled(nRow, nCol))) + { + break; + } + + if (bWrapped && (nOriginalRow < nLastVisualRow + || (nOriginalRow == nLastVisualRow && nOriginalColumn <= nLastVisualCol))) + { + bLooped = true; + break; + } + } + + if (cursorAction == MoveLeft || nLastVisualCol >= 0) + { + break; + } + + nLastVisualCol = nRight + 1; + if (nLastVisualRow == 0) + { + bWrapped = true; + nLastVisualRow = nBottom; + } + else + { + --nLastVisualRow; + } + } while (!bLooped); + + if (nLastVisualCol < 0) + { + nLastVisualCol = nOriginalColumn; + } +} + +QModelIndex GLDTableView::getRightPageCursorIndex(int nRight) +{ + Q_D(GLDTableView); + QModelIndex oCurIndex = currentIndex(); + int nNewColumn = columnAt(visualRect(oCurIndex).left() + d->viewport->width()); + if (nNewColumn == -1) + { + nNewColumn = d->logicalRow(nRight); + } + return d->m_model->index(oCurIndex.row(), nNewColumn, d->m_root); +} + +void GLDTableView::dealWithMoveRight(int &nLastVisualRow, int &nLastVisualCol, int nRight, int nBottom, GlodonAbstractItemView::CursorAction cursorAction) +{ + Q_D(GLDTableView); + + int nOriginalRow = nLastVisualRow; + int nOriginalColumn = nLastVisualCol; + bool bFirstTime = true; + bool bLooped = false; + bool bWrapped = false; + do + { + int nRow = d->logicalRow(nLastVisualRow); + int nCol = d->logicalColumn(nLastVisualCol); + if (bFirstTime && nCol != -1 && d->hasSpans()) + { + bFirstTime = false; + GSpanCollection::GSpan span = d->span(nRow, nCol); + if (span.width() > 1 || span.height() > 1) + { + nLastVisualCol = d->visualColumn(d->columnSpanEndLogical(span.left(), span.width())); + } + } + + while (nLastVisualCol <= nRight) + { + ++nLastVisualCol; + nRow = d->logicalRow(nLastVisualRow); + nCol = d->logicalColumn(nLastVisualCol); + if (nRow == -1 || nCol == -1 + || (!isRowHidden(nRow) && !isColumnHidden(nCol) && d->isCellEnabledAndSelectabled(nRow, nCol))) + { + break; + } + + if (bWrapped && (nOriginalRow > nLastVisualRow + || (nOriginalRow == nLastVisualRow && nOriginalColumn >= nLastVisualCol)) + && (!isRowHidden(nRow) && !isColumnHidden(nCol) + && d->isCellEnabledAndSelectabled(nRow, nCol))) + { + bLooped = true; + break; + } + } + + if (cursorAction == MoveRight || nLastVisualCol <= nRight) + { + break; + } + + nLastVisualCol = -1; + if (nLastVisualRow == nBottom) + { + bWrapped = true; + nLastVisualRow = 0; + } + else + { + ++nLastVisualRow; + } + } while (!bLooped); + + if (nLastVisualCol > nRight) + { + nLastVisualCol = nOriginalColumn; + } +} + +void GLDTableView::dealWithMoveHome(int &nLastVisualRow, int &nLastVisualCol, int nRight, int nBottom, Qt::KeyboardModifiers modifiers) +{ + Q_D(GLDTableView); + + nLastVisualCol = 0; + while (nLastVisualCol < nRight + && d->isVisualColumnHiddenOrDisabled(nLastVisualRow, nLastVisualCol)) + { + ++nLastVisualCol; + } + + if (modifiers & Qt::ControlModifier) + { + nLastVisualRow = 0; + while (nLastVisualRow < nBottom + && d->isVisualRowHiddenOrDisabled(nLastVisualRow, nLastVisualCol)) + { + ++nLastVisualRow; + } + } +} + +QModelIndex GLDTableView::getUpPageCursorIndex() +{ + Q_D(GLDTableView); + QModelIndex oCurIndex = currentIndex(); + int nNewRow = rowAt(visualRect(oCurIndex).bottom() - d->viewport->height()); + if (nNewRow == -1) + { + nNewRow = d->logicalRow(0); + } + return d->m_model->index(nNewRow, oCurIndex.column(), d->m_root); +} + +QModelIndex GLDTableView::getDownPageCursorIndex(int nBottom) +{ + Q_D(GLDTableView); + QModelIndex oCurIndex = currentIndex(); + int nNewRow = rowAt(visualRect(oCurIndex).top() + d->viewport->height()); + if (nNewRow == -1) + { + nNewRow = d->logicalRow(nBottom); + } + return d->m_model->index(nNewRow, oCurIndex.column(), d->m_root); +} + +void GLDTableView::dealWithMoveEnd(int &nLastVisualRow, int &nLastVisualCol, int nRight, int nBottom, Qt::KeyboardModifiers modifiers) +{ + nLastVisualCol = nRight; + if (modifiers & Qt::ControlModifier) + { + nLastVisualRow = nBottom; + } +} + +QModelIndex GLDTableView::getCursorIndex(int nLastVisualRow, int nLastVisualCol) +{ + Q_D(GLDTableView); + + int nLogicalRow = d->logicalRow(nLastVisualRow); + int nLogicalColumn = d->logicalColumn(nLastVisualCol); + if (!d->m_model->hasIndex(nLogicalRow, nLogicalColumn, d->m_root)) + { + return QModelIndex(); + } + + QModelIndex oResultIndex = d->m_model->index(nLastVisualRow, nLogicalColumn, d->m_root); + if (!d->isRowHidden(nLastVisualRow) && !d->isColumnHidden(nLogicalColumn) && d->isIndexEnabled(oResultIndex)) + { + return oResultIndex; + } + + return QModelIndex(); +} + +bool GLDTableView::copyOrPastOperation(QKeyEvent *event) +{ +#if !defined(QT_NO_CLIPBOARD) && !defined(QT_NO_SHORTCUT) + Q_D(GLDTableView); + if (event->matches(QKeySequence::Copy) && (d->m_allowCopy)) + { + copyTextFromSelections(); + event->accept(); + return true; + } + else if (event->matches(QKeySequence::Paste) && (d->m_allowPaste)) + { + pasteFromClipboard(); + event->accept(); + return true; + } +#endif + return false; +} + +bool GLDTableView::openEditOrScrollContent(QKeyEvent *event) +{ + // alt + down,进入编辑状态,有下拉的弹出下拉 + if (event->modifiers() & Qt::AltModifier) + { + edit(currentIndex(), GlodonAbstractItemView::AnyKeyPressed, event); + return true; + } + else + { + resetEnterJumpPreState(); + // ctrl + down,纵向滚动条向下滚动一行 + if (event->modifiers() & Qt::ControlModifier) + { + int nChangeValue = event->key() == Qt::Key_Down ? 1 : -1; + verticalScrollBar()->setValue(verticalScrollBar()->value() + nChangeValue); + return true; + } + return false; + } +} + +void GLDTableView::dealWithKeyEnterPress(QKeyEvent *event) +{ + Q_D(GLDTableView); + QPersistentModelIndex oNewCurrent; + // if control is pressed and just get focus(not in edit state) ,do nothing + if (event->modifiers() & Qt::ControlModifier) + { + return; + } + + CursorAction direction = MoveNext; + bool bIndexValide = currentIndex().isValid(); + + GlodonAbstractItemView::EditTrigger oEditTrigger = GlodonAbstractItemView::AllEditTriggers; + if (editTriggers() == GlodonAbstractItemView::NoEditTriggers) + { + oEditTrigger = GlodonAbstractItemView::NoEditTriggers; + } + + // 回车跳格没有开启时 + if (!d->m_bEnterJump) + { + if (bIndexValide) + { + // 说明不是从delegate中的edit传送过来的enter消息 + if (EditingState != state()) + { + edit(currentIndex()); + } + } + return; + } + else if (d->isEnterJump()) + { + if (d->m_prevState == GlodonAbstractItemView::LastFocus) + { + emit onPressEnter(direction); + oNewCurrent = moveCursor(direction, event->modifiers()); + d->m_prevState = GlodonAbstractItemView::FirstFocus; + } + else if (d->m_prevState == GlodonAbstractItemView::FirstFocus) + { + if (bIndexValide) + { + if (!edit(currentIndex(), oEditTrigger, event)) + { + //未能进入编辑状态 + emit onPressEnter(direction); + oNewCurrent = moveCursor(direction, event->modifiers()); + } + } + } + } + else if (d->isEnterJumpPro()) + { + bool bIsFromClose = false; + + // LastFocus只会在CloseEditor的时候设置 + // 因此这里通过LastFocus,判断是否是通过关闭编辑状态执行到此处的 + // 如果是,则在下一个格子不能进入编辑状态时,不再移动焦点 + if (d->m_prevState == GlodonAbstractItemView::LastFocus) + { + bIsFromClose = true; + d->m_prevState = GlodonAbstractItemView::FirstFocus; + } + + if (d->m_prevState == GlodonAbstractItemView::FirstFocus) + { + if (bIndexValide && !edit(currentIndex(), oEditTrigger, event)) + { + // 未能进入编辑状态,则不改变焦点 + if (bIsFromClose) + { + event->accept(); + } + else + { + emit onPressEnter(direction); + oNewCurrent = moveCursor(direction, event->modifiers()); + GlodonAbstractItemView::setCurrentIndex(oNewCurrent); + edit(currentIndex(), oEditTrigger, event); + } + return; + } + } + } + setNewCurrentSelection(event, oNewCurrent); +} + +void GLDTableView::clickEditorButtonAccordingToEditStyleDrawType(QModelIndex index, QMouseEvent *event) +{ + // 如果当前格子是处于非编辑状态显示编辑方式(是指并没有进入编辑状态,但是将编辑方式的按钮画上) + // 只要显示编辑方式,再次单击编辑方式区域时,应该进入编辑状态,并且触发对应的编辑方式 + // 因此这里只需要触发编辑方式,而不需要处理SelectionModel + if (!shouldDoEditorDraw(index)) + { + return; + } + + GlodonDefaultItemDelegate *pDelegate = itemDelegate(); + + if (pDelegate->isInSubControlRect(index, event->pos())) + { + edit(index, DoubleClicked, event); + pDelegate->clickSubControl(index); + } +} + +void GLDTableView::processEnterJumpAfterCloseEdit(GlodonDefaultItemDelegate::EndEditHint hint) +{ + Q_D(GLDTableView); + bool bFlagForTabMove = false; + switch (hint) + { + case GlodonDefaultItemDelegate::EditNextItem: + { + if (currentIndex().isValid()) + { + if ((currentIndex().flags() & Qt::ItemIsEditable) == Qt::ItemIsEditable + && (!(editTriggers() & GlodonAbstractItemView::CurrentChanged))) + { + bFlagForTabMove = true; + } + } + + break; + } + + case GlodonDefaultItemDelegate::EditPreviousItem: + { + if (currentIndex().isValid()) + { + if ((currentIndex().flags() & Qt::ItemIsEditable) == Qt::ItemIsEditable + && (!(editTriggers() & GlodonAbstractItemView::CurrentChanged))) + { + bFlagForTabMove = true; + } + } + + break; + } + case GlodonDefaultItemDelegate::RevertModelCache: + { + //如果是回车跳格状态,按ESC键时,要把状态置为FirstFocus,否则会不能进入编辑状态,直接跳到下一格 + resetEnterJumpPreState(); + break; + } + } + + if (d->isEnterJump()) + { + if (bFlagForTabMove) + { + d->m_prevState = GlodonAbstractItemView::FirstFocus; + } + else + { + d->m_prevState = GlodonAbstractItemView::LastFocus; + } + } + else if (d->isEnterJumpPro() && hint != GlodonDefaultItemDelegate::RevertModelCache) + { + QEvent *pEvent = d->m_itemDelegate.data()->m_closeEditEvent; + if (pEvent == NULL || pEvent->type() != QEvent::KeyPress) + { + resetEnterJumpPreState(); + return; + } + + QKeyEvent *pKeyEvent = static_cast(pEvent); + if (pKeyEvent->key() == Qt::Key_Enter || pKeyEvent->key() == Qt::Key_Return) + { + CursorAction direction = MoveNext; + emit onPressEnter(direction); + d->m_prevState = GlodonAbstractItemView::LastFocus; + QModelIndex index = moveCursor(direction, Qt::NoModifier); + + if (index.isValid()) + { + QPersistentModelIndex persistent(index); + GlodonAbstractItemView::setCurrentIndex(persistent); + } + } + } +} + +void GLDTableView::resetEnterJumpPreState() +{ + Q_D(GLDTableView); + if (d->m_bEnterJump) + { + d->m_prevState = FirstFocus; + } +} + +bool GLDTableView::shouldDoEditorDraw(const QModelIndex &testIndex) const +{ + Q_D(const GLDTableView); + + if (!testIndex.isValid()) + { + return false; + } + + bool bResult = false; + + switch (d->m_editStyleDrawType) + { + case GlodonAbstractItemView::SdtCurrentCell: + if (currentIndex().isValid() && testIndex == currentIndex()) + { + bResult = true; + } + break; + case GlodonAbstractItemView::SdtCurrentRow: + if (currentIndex().isValid() && testIndex.row() == currentIndex().row()) + { + bResult = true; + } + break; + case GlodonAbstractItemView::SdtCurrentCol: + if (currentIndex().isValid() && testIndex.column() == currentIndex().column()) + { + bResult = true; + } + break; + case GlodonAbstractItemView::SdtAll: + bResult = true; + break; + default: + bResult = false; + break; + } + + return bResult; +} + +int GLDTableView::firstVisualIndexAfterHorizontalScroll(const QModelIndex &index, GlodonAbstractItemView::ScrollHint &hint, int nCellWidth) +{ + Q_D(GLDTableView); + + int nHorizontalIndex = d->m_horizontalHeader->visualIndex(index.column()); + int nViewportWidth = d->viewport->width(); + int nHorizontalOffset = d->m_horizontalHeader->offset(); + int nHorizontalPosition = d->m_horizontalHeader->sectionPosition(index.column()); + + bool bPositionAtRight = (nHorizontalPosition - nHorizontalOffset + nCellWidth > nViewportWidth); + if (hint == PositionAtCenter || bPositionAtRight) + { + int nW = (hint == PositionAtCenter) ? nViewportWidth / 2 : nViewportWidth; + int nX = nCellWidth + currentGridLineWidth() + d->m_nFixedColWidth; + + while (nHorizontalIndex > 0) + { + if (d->m_oSuitColWidthCols.contains(nHorizontalIndex - 1)) + { + nX += d->calcSuitWidth(nHorizontalIndex - 1) + currentGridLineWidth(); + } + else + { + nX += columnWidth(d->m_horizontalHeader->logicalIndex(nHorizontalIndex - 1)) + currentGridLineWidth(); + } + + // 当nX>nW时,说明当前的列如果被显示的话,需要滚动到的列就显示不全了 + // 因此应该多滚动一个格子,让需要滚动到的格子显示完整 + if (nX > nW) + { + break; + } + nHorizontalIndex--; + } + } + + return nHorizontalIndex; +} + +int GLDTableView::getHorizontalHiddenSectionCountBeforeIndex(int nHorizontalIndex) +{ + Q_D(GLDTableView); + + int nHiddenSections = 0; + if (d->m_horizontalHeader->sectionsHidden()) + { + for (int nHiter = nHorizontalIndex - 1; nHiter >= 0; --nHiter) + { + int nColumn = d->m_horizontalHeader->logicalIndex(nHiter); + + if (d->m_horizontalHeader->isSectionHidden(nColumn)) + { + ++nHiddenSections; + } + } + } + + return nHiddenSections; +} + +bool GLDTableView::isPositionAtTopForRowExchange(int nVerticalPosition, int nVerticalOffset) +{ + Q_D(GLDTableView); + + bool bPositionAtTopForRowExchange = (0 == nVerticalPosition - nVerticalOffset); + + if (bPositionAtTopForRowExchange) + { + bool bHeaderIndicatorExist = d->m_horizontalHeader + && d->m_horizontalHeader->d_func() + && d->m_horizontalHeader->d_func()->sectionIndicator; + if (bHeaderIndicatorExist) + { + bPositionAtTopForRowExchange = !d->m_horizontalHeader->d_func()->sectionIndicator->isHidden(); + } + } + + return bPositionAtTopForRowExchange; +} + +int GLDTableView::firstVisualIndexAfterVerticalScroll(const QModelIndex &index, GlodonAbstractItemView::ScrollHint &hint, int nCellHeight) +{ + Q_D(GLDTableView); + + int nVerticalIndex = d->m_verticalHeader->visualIndex(index.row()); + int nViewportHeight = d->viewport->height(); + + if (hint == PositionAtCenter || hint == PositionAtBottom) + { + int nH = (hint == PositionAtCenter ? nViewportHeight / 2 : nViewportHeight); + int nY = nCellHeight + currentGridLineWidth() + d->m_nFixedRowHeight; + + QList oNeedCalcHeightCols = needCalcSuitRowHeightColsInViewport(); + + while (nVerticalIndex > 0) + { + if (oNeedCalcHeightCols.count() == 0) + { + nY += rowHeight(d->m_verticalHeader->logicalIndex(nVerticalIndex - 1)) + currentGridLineWidth(); + } + else + { + nY += d->calcSuitHeight(oNeedCalcHeightCols, nVerticalIndex - 1) + currentGridLineWidth(); + } + + // 当nY>nW时,说明当前的列如果被显示的话,需要滚动到的列就显示不全了 + // 因此应该多滚动一个格子,让需要滚动到的格子显示完整 + if (nY > nH) + { + break; + } + nVerticalIndex--; + } + } + + return nVerticalIndex; +} + +int GLDTableView::getVerticalHiddenSectionCountBeforeIndex(int nVerticalIndex) +{ + Q_D(GLDTableView); + + int nHiddenSections = 0; + if (d->m_verticalHeader->sectionsHidden()) + { + for (int nSIndex = nVerticalIndex - 1; nSIndex >= 0; --nSIndex) + { + int row = d->m_verticalHeader->logicalIndex(nSIndex); + if (d->m_verticalHeader->isSectionHidden(row)) + { + ++nHiddenSections; + } + } + } + + return nHiddenSections; +} + +void GLDTableView::setSpan(int row, int column, int rowSpan, int columnSpan) +{ + Q_D(GLDTableView); + + if (row < 0 || column < 0 || rowSpan < 0 || columnSpan < 0) + { + return; + } + + d->setSpan(row, column, rowSpan, columnSpan); + d->viewport->update(); +} + +void GLDTableView::clearSpans() +{ + Q_D(GLDTableView); + d->m_spans.clear(); + d->viewport->update(); +} + +void GLDTableView::processScrollBarAfterCanNotCloseEditor() +{ + Q_D(GLDTableView); + +#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) + QMouseEvent *event = new QMouseEvent(QEvent::MouseButtonRelease, QPointF(), + Qt::LeftButton, 0, 0); +#else + QMouseEvent *event = new QMouseEvent(QEvent::MouseButtonRelease, QPoint(), + Qt::LeftButton, 0, 0); +#endif + QCoreApplication::postEvent(d->vbar, event); + d->vbar->setEnabled(false); + d->hbar->setEnabled(false); + GLDEvent *pScrollBarStep = new GLDEvent(GM_SetScrollBarStep, (int)gsbtAll, 1); + QCoreApplication::postEvent(this, pScrollBarStep); +} + +void GLDTableView::scrollHorizontalContentsBy(int dx) +{ + Q_D(GLDTableView); + + dx = isRightToLeft() ? -dx : dx; + + if (0 != dx) + { + if (horizontalScrollMode() == GlodonAbstractItemView::ScrollPerItem) + { + int nOldOffset = d->m_horizontalHeader->offset(); +// d->m_horizontalHeader->d_func()->setScrollOffset(horizontalScrollBar(), horizontalScrollMode()); + d->m_horizontalHeader->setOffsetToSectionPosition(horizontalScrollBar()->value()); + + int nNewOffset = d->m_horizontalHeader->offset(); + dx = isRightToLeft() ? nNewOffset - nOldOffset : nOldOffset - nNewOffset; + } + else + { + d->m_horizontalHeader->setOffset(horizontalScrollBar()->value()); + } + + if (isEditorInFixedColAfterHScroll()) + { + return; + } + + d->scrollContentsBy(dx, 0); + } +} + +void GLDTableView::scrollVerticalContentsBy(int dy) +{ + Q_D(GLDTableView); + + if (0 != dy) + { + if (verticalScrollMode() == GlodonAbstractItemView::ScrollPerItem) + { + int nOldOffset = d->m_verticalHeader->offset(); +// d->m_verticalHeader->d_func()->setScrollOffset(verticalScrollBar(), verticalScrollMode()); + d->m_verticalHeader->setOffsetToSectionPosition(verticalScrollBar()->value()); + + int nNewOffset = d->m_verticalHeader->offset(); + dy = nOldOffset - nNewOffset; + } + else + { + d->m_verticalHeader->setOffset(verticalScrollBar()->value()); + } + + if (isEditorInFixedRowAfterVScroll()) + { + return; + } + + d->scrollContentsBy(0, dy); + } +} + +void GLDTableView::updateFirstLine(int dx, int dy) +{ + Q_D(GLDTableView); + + if (d->m_showGrid) + { + //we need to update the first line of the previous top item in the view + //because it has the grid drawn if the header is invisible. + //It is strictly related to what's done at then end of the paintEvent + if (dy > 0 && d->m_horizontalHeader->isHidden() && d->m_verticalScrollMode == ScrollPerItem) + { + d->viewport->update(0, dy, d->viewport->width(), dy); + } + + if (dx > 0 && d->m_verticalHeader->isHidden() && d->m_horizontalScrollMode == ScrollPerItem) + { + d->viewport->update(dx, 0, dx, d->viewport->height()); + } + } +} + +bool GLDTableView::commitDataAndCloseEditorInIngnoreFocusOut() +{ + if (!closeEditorOnFocusOut()) + { + return commitDataAndCloseEditor(); + } + + return true; +} + +void GLDTableView::dealWithSpecialMousePressOperations(const QModelIndex &index, QMouseEvent *event) +{ + Q_D(GLDTableView); + + // 处理拖拉复制 + if (shouldDoRangeFill(event)) + { + initRangeAction(); + d->m_state = RangeFillingState; + } + // 处理超链接单元格操作 + else if (inLinkCell(event->pos())) + { + QString strvalue = index.data().toString(); + QUrl url(strvalue); + QDesktopServices::openUrl(url); + } + // 处理框选拖拽 + else if (shouldDoRangeMove(event)) + { + initRangeAction(); + d->m_state = RangeMovingState; + } + // 处理拖拽格线改变行高列宽 + else if (shoudDoResizeCellByDragGridLine(event)) + { + dealWithResizeCellWhenPressGridLine(event); + } + // 处理Bool单元格操作 + else if (inBoolCell(event->pos())) + { + onBoolCellPress(event); + } +} + +void GLDTableView::dealWithResizeCellWhenPressGridLine(QMouseEvent *event) +{ + Q_D(GLDTableView); + + d->m_pressedPosition = event->pos(); + d->m_state = DragResizingState; + + if (cursor().shape() == Qt::SplitHCursor) + { + d->m_horizontalHeader->setMousePosition(event->pos()); + showSectionResizingInfoFrame(event->screenPos().toPoint(), Qt::Horizontal, GlodonHeaderView::Press); + } + else if (cursor().shape() == Qt::SplitVCursor) + { + d->m_verticalHeader->setMousePosition(event->pos()); + showSectionResizingInfoFrame(event->screenPos().toPoint(), Qt::Vertical, GlodonHeaderView::Press); + } +} + +bool GLDTableView::shouldDoRangeFill(QMouseEvent *event) +{ + Q_D(GLDTableView); + return d->m_state == NoState + && doCanRangeFill(visualRectForSelection()) + && d->isRangeFillingHandleSelected(event->pos()); +} + +bool GLDTableView::shouldDoRangeMove(QMouseEvent *event) +{ + Q_D(GLDTableView); + return d->m_state == NoState + && d->m_bRangeMoving + && inRangeMovingRegion(event->pos()); +} + +bool GLDTableView::shoudDoResizeCellByDragGridLine(QMouseEvent *event) +{ + Q_D(GLDTableView); + return d->m_allowToResizeCellByDragGridLine + && event->button() == Qt::LeftButton + && (cursor().shape() == Qt::SplitHCursor || cursor().shape() == Qt::SplitVCursor); +} + +bool GLDTableView::shouldSetRangeFillMouseShape(const QPoint &pos) +{ + Q_D(GLDTableView); + // 非编辑状态、非多选状态,鼠标移动到拖拉复制的黑点时,设置鼠标形状 + return d->m_state != EditingState + && !d->isInMutiSelect() + && doCanRangeFill(visualRectForSelection()) + && d->isRangeFillingHandleSelected(pos); +} + +void GLDTableView::setRangeFillMouseShape(bool bHasCursor) +{ + // 鼠标没有设置过形状,或者设置过调整大小的形状时,将其设置为拖拉复制形状 + if (!bHasCursor || cursor().shape() == Qt::SplitHCursor || cursor().shape() == Qt::SplitVCursor) + { + QPixmap cursorPixmap(":/icons/rangeFillingCursor"); + + if (!cursorPixmap.isNull()) + { + setCursor(QCursor(cursorPixmap)); + } + else + { + setCursor(Qt::CrossCursor); + } + } +} + +void GLDTableView::getRangeFillingCurRowAndCol(int nOldRow, int nOldColumn, const QPoint &pos) +{ + Q_D(GLDTableView); + + setCurRangeRowAndCol(pos); + + switch (d->m_rangeFillingStyle) { + case rfsVertical: + { + if (m_nRangeCurCol != nOldColumn) + { + m_nRangeCurCol = nOldColumn; + } + break; + } + case rfsHorizontal: + { + if (m_nRangeCurRow != nOldRow) + { + m_nRangeCurRow = nOldRow; + } + break; + } + default: + break; + } +} + +bool GLDTableView::shouldSetRangeMoveMouseShape(const QPoint &pos) +{ + Q_D(GLDTableView); + // 如果处于非编辑状态,并且可以框选拖拽 + return d->m_state != EditingState + && d->m_bRangeMoving + && inRangeMovingRegion(pos); +} + +void GLDTableView::setRangeMoveMouseShape(bool bHasCursor) +{ + if (!bHasCursor) + { + QPixmap cursorPixmap(":/icons/rangeMoveCursor"); + + if (!cursorPixmap.isNull()) + { + setCursor(QCursor(cursorPixmap)); + } + else + { + setCursor(Qt::SizeAllCursor); + } + } +} + +void GLDTableView::updateTempRangeRect() +{ + Q_D(GLDTableView); + + if (m_nRangeCurRow != -1 && m_nRangeCurCol != -1) + { + m_preTempRangeRect = m_tempRangeRect; + m_tempRangeRect = calcRangeMovingRegion(); + QRect updateRect = m_tempRangeRect.united(m_preTempRangeRect); + updateRect.adjust(-3, -3, 3, 3); + + d->viewport->update(updateRect); + } +} + +bool GLDTableView::shouldSetResizeCellByDragGridLineMouseShape(QMouseEvent *event) +{ + Q_D(GLDTableView); + // 如果没有点击鼠标键,如果是在格线附近,要改变鼠标形状为可拖拽 + return d->m_state != EditingState + && d->m_allowToResizeCellByDragGridLine + && event->buttons() == Qt::NoButton + && (d->isNearHorizontalGridLine(event) || d->isNearVerticalGridLine(event)); +} + +void GLDTableView::setResizeCellByDragGridLineMouseShape(QMouseEvent *event) +{ + Q_D(GLDTableView); + + bool bInTableView = d->isInTableView(event); + + if (d->isNearHorizontalGridLine(event) && bInTableView) + { + setCursor(Qt::SplitHCursor); + } + else if (d->isNearVerticalGridLine(event) && bInTableView) + { + setCursor(Qt::SplitVCursor); + } + + if (!d->viewport->rect().contains(event->pos()) || !bInTableView) + { + unsetCursor(); + } +} + +void GLDTableView::dealWithResizeCellWhenDragGridLine(QMouseEvent *event) +{ + Q_D(GLDTableView); + + if (cursor().shape() == Qt::SplitHCursor) + { + d->m_horizontalHeader->setMousePosition(event->pos()); + showSectionResizingInfoFrame(event->windowPos().toPoint(), Qt::Horizontal, GlodonHeaderView::Move); + } + else if (cursor().shape() == Qt::SplitVCursor) + { + d->m_verticalHeader->setMousePosition(event->pos()); + showSectionResizingInfoFrame(event->windowPos().toPoint(), Qt::Vertical, GlodonHeaderView::Move); + } +} + +void GLDTableView::recoverCursor() +{ + unsetCursor(); + // If no cursor has been set, or after a call to unsetCursor(), the parent's cursor is used + QWidget *widget = dynamic_cast(this->parent()); + + if (widget->cursor().shape() != Qt::ArrowCursor) + { + setCursor(Qt::ArrowCursor); + } +} + +void GLDTableView::dealWithCurCommet(const QPoint &pos) +{ + Q_D(GLDTableView); + + QPersistentModelIndex oCurIndex = indexAt(pos); + bool showComment = true; + emit canShowComment(oCurIndex, showComment); + + if (showComment) + { + d->drawComment(oCurIndex); + } +} + +void GLDTableView::dealWithRangeFillingOnMouseMove(bool bHasCursor, const QPoint &pos) +{ + doAutoScroll(); + + if (!bHasCursor) + { + setCursor(Qt::CrossCursor); + } + + int nOldRow = m_nRangeCurRow; + int nOldColumn = m_nRangeCurCol; + getRangeFillingCurRowAndCol(nOldRow, nOldColumn, pos); + updateRangeFillingRect(nOldRow, nOldColumn); +} + +void GLDTableView::dealWithRangeMovingOnMouseMove(const QPoint &pos) +{ + //选择移动时,先计算出移动的区域,再刷新计算出的区域和之前的区域 + doAutoScroll(); + setCurRangeRowAndCol(pos); + updateTempRangeRect(); +} + +bool GLDTableView::isInRangeFilling() +{ + Q_D(GLDTableView); + // 如果正在拖拉复制,且不是多选状态 + return d->m_state == RangeFillingState && !d->isInMutiSelect(); +} + +bool GLDTableView::isInRangeMoving() +{ + Q_D(GLDTableView); + // 如果处于框选拖拽状态,并且不是在多选 + return d->m_state == RangeMovingState && !d->isInMutiSelect(); +} + +bool GLDTableView::isInResizingCellByDragGridLine(QMouseEvent *event) +{ + Q_D(GLDTableView); + // 如果是拖拽 + return d->m_allowToResizeCellByDragGridLine + && d->m_state == DragResizingState + && event->buttons() == Qt::LeftButton; +} + +void GLDTableView::updateRangeFillingRect(int nOldRow, int nOldColumn) +{ + Q_D(GLDTableView); + + if (m_nRangeCurRow == -1 || m_nRangeCurCol == -1) + { + return; + } + if (m_nRangeCurRow == nOldRow && m_nRangeCurCol == nOldColumn) + { + return; + } + + QRect rect = m_oRangeSrc; + rect.setTop(qMin(m_nRangeCurRow, qMin(nOldRow, m_oRangeSrc.top()))); + rect.setBottom(qMax(m_nRangeCurRow, qMax(nOldRow, m_oRangeSrc.bottom()))); + rect.setLeft(qMin(m_nRangeCurCol, qMin(nOldColumn, m_oRangeSrc.left()))); + rect.setRight(qMax(m_nRangeCurCol, qMax(nOldColumn, m_oRangeSrc.right()))); + + d->viewport->update(visualRectForRowColNo(rect).adjusted(-3, -3, 3, 3)); +} + +void GLDTableView::completeRangeFilling() +{ + initRangeFillingDest(); + + try + { + doRangeFill(); + } + catch (...) + { + initRangeValuesAndUpdateViewport(); + throw; + } + + QRect oSelectionRect = m_oRangeSrc.united(m_oRangeDest); + setSelectionByIndex(topLeftIndex(oSelectionRect), + bottomRightIndex(oSelectionRect), + QItemSelectionModel::SelectCurrent); + initRangeValuesAndUpdateViewport(); +} + +void GLDTableView::completeRangeMoving() +{ + Q_D(GLDTableView); + + if (initRangeMovingDest()) + { + doRangeMoving(m_oRangeSrc, m_oRangeDest); + } + else + { + m_oRangeDest = m_oRangeSrc; + } + + setSelectionByIndex(topLeftIndex(m_oRangeDest), + bottomRightIndex(m_oRangeDest), QItemSelectionModel::SelectCurrent); + d->viewport->update(); + d->m_state = NoState; +} + +void GLDTableView::completeResizeCellByDragGridLine(QMouseEvent *event) +{ + Q_D(GLDTableView); + + if (cursor().shape() == Qt::SplitHCursor) + { + int nColumn = columnAt(d->m_pressedPosition.x() - c_nResizeHandlerOffset); + int nColWidth = event->pos().x() - d->m_pressedPosition.x() + columnWidth(nColumn); + int nMinColWidth = d->m_horizontalHeader->minimumSectionSize(); + + if (nColWidth < nMinColWidth) + { + nColWidth = nMinColWidth; + } + + d->m_horizontalHeader->resizeSection(nColumn, nColWidth, true, true); + showSectionResizingInfoFrame(event->pos(), Qt::Horizontal, GlodonHeaderView::Finish); + } + else if (cursor().shape() == Qt::SplitVCursor) + { + int nRow = rowAt(d->m_pressedPosition.y() - c_nResizeHandlerOffset); + int nRowHeight = event->pos().y() - d->m_pressedPosition.y() + rowHeight(nRow); + int nMinRowHeight = d->m_verticalHeader->minimumSectionSize(); + + if (nRowHeight < nMinRowHeight) + { + nRowHeight = nMinRowHeight; + } + + d->m_verticalHeader->resizeSection(nRow, nRowHeight, true, true); + showSectionResizingInfoFrame(event->pos(), Qt::Vertical, GlodonHeaderView::Finish); + } + + unsetCursor(); + d->m_state = NoState; +} + +void GLDTableView::initRangeValuesAndUpdateViewport() +{ + Q_D(GLDTableView); + + m_oRangeSrc = QRect(); + m_nRangeCurRow = -1; + m_nRangeCurCol = -1; + d->m_state = NoState; + d->viewport->update(); +} + +bool GLDTableView::doRangeFillHandled() +{ + bool bHandled = false; + emit rangeFill(m_oRangeSrc, m_oRangeDest, bHandled); + + int srcRowCount = -1; + int srcColumnCount = -1; + int destRowCount = -1; + int destColumnCount = -1; + QModelIndexList srcModelIndexList = indexesFromRect(m_oRangeSrc, srcRowCount, srcColumnCount); + QModelIndexList destModelIndexList = indexesFromRect(m_oRangeDest, destRowCount, destColumnCount); + emit rangeFill(srcModelIndexList, destModelIndexList, srcRowCount, destRowCount, bHandled); + + if (bHandled) + { + return true; + } + + return false; +} + +void GLDTableView::doRangeFillToTop() +{ + Q_D(GLDTableView); + + for (int nDestRow = m_oRangeSrc.top() - 1; nDestRow >= m_nRangeCurRow; --nDestRow) + { + for (int nDestCol = m_oRangeSrc.left(); nDestCol <= m_oRangeSrc.right(); ++nDestCol) + { + QModelIndex oDestLogicalIndex = logicalIndex(d->m_model->index(nDestRow, nDestCol)); + + int nSrcRow = m_oRangeSrc.top() + (m_oRangeSrc.top() - nDestRow) % m_oRangeSrc.height(); + QModelIndex oSrcLogicalIndex = logicalIndex(d->m_model->index(nSrcRow, nDestCol)); + + setSrcIndexDataToDestIndex(oSrcLogicalIndex, oDestLogicalIndex); + } + } +} + +void GLDTableView::doRangeFillToBottom() +{ + Q_D(GLDTableView); + + for (int nDestRow = m_oRangeSrc.bottom() + 1; nDestRow <= m_nRangeCurRow; ++nDestRow) + { + for (int nDestCol = m_oRangeSrc.left(); nDestCol <= m_oRangeSrc.right(); ++nDestCol) + { + QModelIndex oDestLogicalIndex = logicalIndex(d->m_model->index(nDestRow, nDestCol)); + + int nSrcRow = m_oRangeSrc.top() + (nDestRow - m_oRangeSrc.bottom() - 1) % m_oRangeSrc.height(); + QModelIndex oSrcLogicalIndex = logicalIndex(d->m_model->index(nSrcRow, nDestCol)); + + setSrcIndexDataToDestIndex(oSrcLogicalIndex, oDestLogicalIndex); + } + } +} + +void GLDTableView::doRangeFillToLeft() +{ + Q_D(GLDTableView); + + for (int nDestCol = m_oRangeSrc.right() - 1; nDestCol >= m_nRangeCurCol; --nDestCol) + { + for (int nDestRow = m_oRangeSrc.top(); nDestRow <= m_oRangeSrc.bottom(); ++nDestRow) + { + QModelIndex oDestLogicalIndex = logicalIndex(d->m_model->index(nDestRow, nDestCol)); + + int nSrcColumn = m_oRangeSrc.left() + (m_oRangeSrc.left() - nDestCol) % m_oRangeSrc.width(); + QModelIndex oSrcLogicalIndex = logicalIndex(d->m_model->index(nDestRow, nSrcColumn)); + + setSrcIndexDataToDestIndex(oSrcLogicalIndex, oDestLogicalIndex); + } + } +} + +void GLDTableView::doRangeFillToRight() +{ + Q_D(GLDTableView); + + for (int nDestCol = m_oRangeSrc.right() + 1; nDestCol <= m_nRangeCurCol; ++nDestCol) + { + for (int nDestRow = m_oRangeSrc.top(); nDestRow <= m_oRangeSrc.bottom(); ++nDestRow) + { + QModelIndex oDestLogicalIndex = logicalIndex(d->m_model->index(nDestRow, nDestCol)); + + int nSrcColumn = m_oRangeSrc.left() + (nDestCol - m_oRangeSrc.right() - 1) % m_oRangeSrc.width(); + QModelIndex oSrcLogicalIndex = logicalIndex(d->m_model->index(nDestRow, nSrcColumn)); + + setSrcIndexDataToDestIndex(oSrcLogicalIndex, oDestLogicalIndex); + } + } +} + +void GLDTableView::setSrcIndexDataToDestIndex(const QModelIndex &oSrcLogicalIndex, QModelIndex &oDestLogicalIndex) +{ + Q_D(GLDTableView); + + QRect rect(oDestLogicalIndex.column(), oDestLogicalIndex.row(), 1, 1); + + if(!canRangeFill(rect)) + { + return; + } + + if (d->m_cellFillEditField) + { + d->m_model->setData(oDestLogicalIndex, d->m_model->data(oSrcLogicalIndex, Qt::EditRole)); + } + else + { + d->m_model->setData(oDestLogicalIndex, d->m_model->data(oSrcLogicalIndex)); + } +} + +void GLDTableView::initSectionResizingInfoFrame(const QPoint &mousePostion, Qt::Orientation direction) +{ + Q_D(GLDTableView); + + if (direction == Qt::Vertical) + { + //此时的mousePosition是鼠标在屏幕中的绝对位置 + d->m_infoFrame->move(mousePostion); + setResizeStartPosition(Qt::Vertical); + d->m_infoFrame->setText(resizeInfoText(QPoint(mousePostion.x(), d->m_nResizeCellEndPosition), Qt::Vertical)); + } + else + { + d->m_infoFrame->move(mousePostion); + setResizeStartPosition(Qt::Horizontal); + d->m_infoFrame->setText(resizeInfoText(QPoint(d->m_nResizeCellEndPosition, mousePostion.y()), Qt::Horizontal)); + + } +} + +void GLDTableView::updateSectionResizingInfoFrameText(Qt::Orientation direction) +{ + Q_D(GLDTableView); + + if (direction == Qt::Vertical) + { + d->m_infoFrame->setText(resizeInfoText(d->m_verticalHeader->mousePosition(), Qt::Vertical)); + } + else + { + d->m_infoFrame->setText(resizeInfoText(d->m_horizontalHeader->mousePosition(), Qt::Horizontal)); + } +} + +void GLDTableView::adjustVisualRect(int &nFirstVisualRow, int &nFirstVisualCol, int &nLastVisualRow, int &nLastVisualCol) +{ + adjustVisualRow(nFirstVisualRow, nLastVisualRow); + adjustVisualCol(nFirstVisualCol, nLastVisualCol); +} + +void GLDTableView::adjustVisualRow(int &nFirstVisualRow, int &nLastVisualRow) const +{ + Q_D(const GLDTableView); + + if (nFirstVisualRow > 0) + { + nFirstVisualRow--; + } + + if (nLastVisualRow < d->m_verticalHeader->count() - 1) + { + nLastVisualRow++; + } +} + +void GLDTableView::adjustVisualCol(int &nFirstVisualCol, int &nLastVisualCol) const +{ + Q_D(const GLDTableView); + + if (nFirstVisualCol > 0) + { + nFirstVisualCol--; + } + + if (nLastVisualCol < d->m_horizontalHeader->count() - 1) + { + nLastVisualCol++; + } +} + +void GLDTableView::setMergeCellState(int nRow, int nSpanRow, int nCol, int nSpanCol, QVector &oCellMergeState) +{ + for (int nSpanMergedRow = nRow; nSpanMergedRow <= nSpanRow; ++nSpanMergedRow) + { + for (int nSpanMergedCol = nCol; nSpanMergedCol <= nSpanCol; ++nSpanMergedCol) + { + oCellMergeState[nSpanMergedRow].setBit(nSpanMergedCol, true); + } + } +} + +void GLDTableView::initMergeCellState( + const int nFirstVisualRow, const int nLastVisualRow, const int nFirstVisualCol, + const int nLastVisualCol, QVector &oCellMergeState) +{ + for (int i = nFirstVisualRow; i <= nLastVisualRow; ++i) + { + QBitArray row; + row.resize(nLastVisualCol - nFirstVisualCol + 1); + row.fill(false); + oCellMergeState.append(row); + } +} + +void GLDTableView::calcAndSetSpan( + const int nFirstVisualRow, const int nLastVisualRow, const int nFirstVisualCol, const int nLastVisualCol) +{ + Q_D(GLDTableView); + + if ((nFirstVisualRow > nLastVisualRow) || (nFirstVisualCol > nLastVisualCol)) + return; + + QVector oCellMergeState; + initMergeCellState(nFirstVisualRow, nLastVisualRow, nFirstVisualCol, nLastVisualCol, oCellMergeState); + + QAbstractItemModel *pDataModel = itemModel(); + + for (int nRow = nFirstVisualRow; nRow <= nLastVisualRow; ++nRow) + { + int nCurVisualRow = nRow; + int nCurLogicalRow = d->logicalRow(nCurVisualRow); + + int nCol = nFirstVisualCol; + while (nCol <= nLastVisualCol) + { + int nCurVisualCol = nCol; + int nCurLogicalCol = d->logicalColumn(nCurVisualCol); + + // 如果当前格子被标识为true,说明已经处理过,不需要再做处理 + if (oCellMergeState.at(nRow - nFirstVisualRow).at(nCol - nFirstVisualCol)) + { + ++nCol; + continue; + } + + QModelIndex index = dataIndex(d->m_model->index(nCurLogicalRow, nCurLogicalCol)); + + int nCurMergeID = pDataModel->data(index, gidrMergeIDRole).toInt(); + // MergeID是0,说明不需要合并 + if (nCurMergeID == 0) + { + oCellMergeState[nRow - nFirstVisualRow].setBit(nCol - nFirstVisualCol, true); + } + else + { + // 如果MergeID不是0,则需要向后找到第一个与MergeID不同的格子 + int nLastSpanRow = findLastSpanRow(nCurMergeID, nRow, nLastVisualRow, nCurLogicalCol); + int nLastSpanCol = findLastSpanCol(nCurMergeID, nCol, nLastVisualCol, nCurLogicalRow); + + // 找到后,要判断合并格的个数是大于1的,并且将最大的矩形区域合并 + if (nLastSpanRow - nRow < 1 && nLastSpanCol - nCol < 1) + { + ++nCol; + continue; + } + + setMergeCellState( + nRow - nFirstVisualRow, nLastSpanRow - nFirstVisualRow, + nCol - nFirstVisualCol, nLastSpanCol - nFirstVisualCol, oCellMergeState); + + // 合并单元格 + setSpan(nCurVisualRow, nCurVisualCol, nLastSpanRow - nRow + 1, nLastSpanCol - nCol + 1); + + // 遍历过的格子,不需要再遍历 + nCol = nLastSpanCol; + } + ++nCol; + } + } +} + +int GLDTableView::findLastSpanRow( + const int nCurMergeID, const int nRow, const int nLastVisualRow, + const int nCurLogicalCol) +{ + Q_D(GLDTableView); + + QAbstractItemModel *pDataModel = itemModel(); + + int nSpanRow = nRow + 1; + while (true) + { + if (nSpanRow > nLastVisualRow) + { + --nSpanRow; + break; + } + + QModelIndex oRowSpanIndex = dataIndex( + d->m_model->index(d->logicalRow(nSpanRow), nCurLogicalCol)); + + int nSpanRowMergeID = pDataModel->data(oRowSpanIndex, gidrMergeIDRole).toInt(); + + if (nSpanRowMergeID != nCurMergeID) + { + --nSpanRow; + break; + } + + ++nSpanRow; + } + + return nSpanRow; +} + +int GLDTableView::findLastSpanCol( + const int nCurMergeID, const int nCol, const int nLastVisualCol, const int nCurLogicalRow) +{ + Q_D(GLDTableView); + + QAbstractItemModel *pDataModel = itemModel(); + + int nSpanCol = nCol + 1; + + while (true) + { + if (nSpanCol > nLastVisualCol) + { + --nSpanCol; + break; + } + + QModelIndex spancIndex = dataIndex( + d->m_model->index(nCurLogicalRow, d->logicalColumn(nSpanCol))); + + int nSpanColMergeID = pDataModel->data(spancIndex, gidrMergeIDRole).toInt(); + + if (nSpanColMergeID != nCurMergeID) + { + --nSpanCol; + break; + } + + ++nSpanCol; + } + + return nSpanCol; +} + +void GLDTableView::initResizeInfoFrames(Qt::Orientation direction) +{ + Q_D(GLDTableView); + + if (NULL == d->m_pResizeInfoLineFrame) + { + d->m_pResizeInfoLineFrame = new QFrame(this); + + // 去掉Frame的外边框 + d->m_pResizeInfoLineFrame->setFrameShape(Panel); + // 去掉最小化,关闭按钮 + d->m_pResizeInfoLineFrame->setWindowFlags(Qt::ToolTip); + + // 设置背景Frame背景色 + QPalette oPalette = d->m_pResizeInfoLineFrame->palette(); + oPalette.setColor(QPalette::Window, QColor(255, 255, 225)); + + d->m_pResizeInfoLineFrame->setPalette(oPalette); + } + + if (direction == Qt::Horizontal) + { + d->m_pResizeInfoLineFrame->resize(1, viewport()->height()); + } + else + { + d->m_pResizeInfoLineFrame->resize(viewport()->width(), 1); + } + + if (d->m_infoFrame == NULL) + { + d->m_infoFrame = new GInfoFrame(this); + } + + d->m_infoFrame->setOrientation(direction); +} + +void GLDTableView::updateVerticalHeaderGeometry(int nVerticalHeaderWidth) +{ + Q_D(GLDTableView); + + QRect oViewportGeometry = d->viewport->geometry(); + int nVerticalLeft = oViewportGeometry.left() - nVerticalHeaderWidth; + + d->m_verticalHeader->setGeometry( + nVerticalLeft, oViewportGeometry.top(), + nVerticalHeaderWidth, oViewportGeometry.height()); + + if (d->m_verticalHeader->isHidden()) + { + QMetaObject::invokeMethod(d->m_verticalHeader, "updateGeometries"); + } +} + +void GLDTableView::updateHorizontalHeaderGeometry(int nHorizontalHeaderHeight) +{ + Q_D(GLDTableView); + + QRect oViewportGeometry = d->viewport->geometry(); + int nHorizontalTop = oViewportGeometry.top() - nHorizontalHeaderHeight; + + d->m_horizontalHeader->setGeometry( + oViewportGeometry.left(), nHorizontalTop, + oViewportGeometry.width(), nHorizontalHeaderHeight); + + if (d->m_horizontalHeader->isHidden()) + { + QMetaObject::invokeMethod(d->m_horizontalHeader, "updateGeometries"); + } +} + +void GLDTableView::updateConrnerWidgetGeometry(int nVerticalHeaderWidth, int nHorizontalHeaderHeight) +{ + Q_D(GLDTableView); + + QRect oViewportGeometry = d->viewport->geometry(); + int nHorizontalTop = oViewportGeometry.top() - nHorizontalHeaderHeight; + int nVerticalLeft = oViewportGeometry.left() - nVerticalHeaderWidth; + + if (d->m_horizontalHeader->isHidden() || d->m_verticalHeader->isHidden()) + { + d->m_cornerWidget->setHidden(true); + } + else + { + d->m_cornerWidget->setHidden(false); + d->m_cornerWidget->setGeometry(nVerticalLeft, nHorizontalTop, nVerticalHeaderWidth, nHorizontalHeaderHeight); + } +} + +void GLDTableView::updateHorizontalScrollBar(const QSize &oViewportSize) +{ + Q_D(GLDTableView); + + //there must be always at least 1 column + int nColumnsInViewport = qMax(colCountBackwardsInViewPort(oViewportSize), 1); + + if (horizontalScrollMode() == GlodonAbstractItemView::ScrollPerItem) + { + const int c_nColumnCount = d->m_horizontalHeader->count(); + const int c_visibleColumns = c_nColumnCount - d->m_horizontalHeader->hiddenSectionCount(); + + int nFixHiddenColCount = 0; + for (int nIndex = 0; nIndex < d->m_nFixedColCount; ++nIndex) + { + if (this->horizontalHeader()->isSectionHidden(nIndex)) + { + ++nFixHiddenColCount; + } + } + + horizontalScrollBar()->setRange(0, c_visibleColumns - nColumnsInViewport - (d->m_nFixedColCount - nFixHiddenColCount)); + horizontalScrollBar()->setPageStep(nColumnsInViewport); + + if (nColumnsInViewport >= c_visibleColumns && c_nColumnCount != 0) + { + d->m_horizontalHeader->setOffset(0); + } + horizontalScrollBar()->setSingleStep(1); + } + else // ScrollPerPixel + { + uint nHorizontalHeaderLength = d->m_horizontalHeader->length(); + + horizontalScrollBar()->setPageStep(oViewportSize.width()); + horizontalScrollBar()->setRange(0, nHorizontalHeaderLength - oViewportSize.width()); + horizontalScrollBar()->setSingleStep(qMax(oViewportSize.width() / (nColumnsInViewport + 1), 2)); + } +} + +void GLDTableView::updateVerticalScrollBar(const QSize &oViewportSize) +{ + Q_D(GLDTableView); + + //there must be always at least 1 row + int nRowsInViewport = qMax(rowCountBackwardsInViewPort(oViewportSize), 1); + + if (verticalScrollMode() == GlodonAbstractItemView::ScrollPerItem) + { + const int c_nRowCount = d->m_verticalHeader->count(); + const int c_nVisibleRows = c_nRowCount - d->m_verticalHeader->hiddenSectionCount(); + + int nFixHiddenRowCount = 0; + for (int nIndex = 0; nIndex < d->m_nFixedRowCount; ++nIndex) + { + if (this->verticalHeader()->isSectionHidden(nIndex)) + { + ++nFixHiddenRowCount; + } + } + + if (d->m_showEllipsisButton && verticalScrollBar()->isVisible()) + { + verticalScrollBar()->setRange(0, c_nVisibleRows - nRowsInViewport - (d->m_nFixedRowCount - nFixHiddenRowCount) + 1); + } + else + { + verticalScrollBar()->setRange(0, c_nVisibleRows - nRowsInViewport - (d->m_nFixedRowCount - nFixHiddenRowCount)); + } + + verticalScrollBar()->setPageStep(nRowsInViewport); + if (nRowsInViewport >= c_nVisibleRows && c_nRowCount != 0) + { + d->m_verticalHeader->setOffset(0); + } + verticalScrollBar()->setSingleStep(1); + } + else // ScrollPerPixel + { + uint nVerticalHeaderLength = d->m_verticalHeader->length(); + verticalScrollBar()->setPageStep(oViewportSize.height()); + + if (d->m_showEllipsisButton && verticalScrollBar()->isVisible()) + { + verticalScrollBar()->setRange(0, nVerticalHeaderLength - oViewportSize.height() + d->m_ellipsisButton->height()); + } + else + { + verticalScrollBar()->setRange(0, nVerticalHeaderLength - oViewportSize.height()); + } + + verticalScrollBar()->setSingleStep(qMax(oViewportSize.height() / (nRowsInViewport + 1), 2)); + } +} + +int GLDTableView::colCountBackwardsInViewPort(const QSize &oViewportSize) +{ + Q_D(GLDTableView); + + // 滚动条控制的应该是除了固定列区域之外的部分 + d->calculateFixedColumnWidth(); + + // 计算range时,应该是【总列数-固定列数-最后一屏的列数】 + const int c_nColumnCount = d->m_horizontalHeader->count(); + const int c_nViewportWidth = oViewportSize.width() - d->m_nFixedColWidth; + + int nWidth = 0; + int nColumnsInViewport = 0; + // 计算最后一屏的列数 + for (int nColumn = c_nColumnCount - 1; nColumn >= 0; --nColumn) + { + int nLogical = d->m_horizontalHeader->logicalIndex(nColumn); + if (!d->m_horizontalHeader->isSectionHidden(nLogical)) + { + if (d->m_oSuitColWidthCols.contains(nLogical)) + { + nWidth += calcSuitWidth(nLogical) + currentGridLineWidth(); + } + else + { + nWidth += d->m_horizontalHeader->sectionSize(nLogical) + currentGridLineWidth(); + } + + if (nWidth > c_nViewportWidth) + { + break; + } + ++nColumnsInViewport; + } + } + + return nColumnsInViewport; +} + +int GLDTableView::rowCountBackwardsInViewPort(const QSize &oViewportSize) +{ + Q_D(GLDTableView); + + // 滚动条控制的应该是除了固定行区域之外的部分 + d->calculateFixedRowHeight(); + + // vertical scroll bar + const int c_nRowCount = d->m_verticalHeader->count(); + const int c_nViewportHeight = oViewportSize.height() - d->m_nFixedRowHeight; + + GIntList oNeedCalcSuitRowHeightCols = needCalcSuitRowHeightColsInViewport(); + + // 计算最后一屏的行数 + int nHeight = 0; + int nRowsInViewport = 0; + for (int nRow = c_nRowCount - 1; nRow >= 0; --nRow) + { + int nLogical = d->m_verticalHeader->logicalIndex(nRow); + if (!d->m_verticalHeader->isSectionHidden(nLogical)) + { + if (oNeedCalcSuitRowHeightCols.count() > 0) + { + nHeight += d->calcSuitHeight(oNeedCalcSuitRowHeightCols, nRow) + currentGridLineWidth(); + } + else + { + nHeight += d->m_verticalHeader->sectionSize(nLogical) + currentGridLineWidth(); + } + + if (nHeight > c_nViewportHeight) + { + break; + } + ++nRowsInViewport; + } + } + + return nRowsInViewport; +} + +void GLDTableView::scrollTo(const QModelIndex &index, ScrollHint hint) +{ + Q_D(GLDTableView); + + // check if we really need to do anything + if (!d->isIndexValid(index) + || (d->m_model->parent(index) != d->m_root) + || isRowHidden(index.row()) + || isColumnHidden(index.column())) + { + return; + } + + d->calculateFixedRegion(); + + GSpanCollection::GSpan span; + if (d->hasSpans()) + { + span = d->span(index.row(), index.column()); + } + + int nCellWidth = d->hasSpans() + ? d->columnSpanWidth(index.column(), span.width()) + : d->m_horizontalHeader->sectionSize(index.column()); + + if (d->m_oSuitColWidthCols.contains(index.column())) + { + nCellWidth = d->calcSuitWidth(index.column()); + } + + // Adjust horizontal position + scrollHorizontalTo(index, hint, nCellWidth); + + int nCellHeight = d->hasSpans() ? d->rowSpanHeight(index.row(), span.height()) + : d->m_verticalHeader->sectionSize(index.row()); + + QList oNeedCalcHeightCols = needCalcSuitRowHeightColsInViewport(); + if (oNeedCalcHeightCols.count() == 0) + { + nCellHeight = d->calcSuitHeight(oNeedCalcHeightCols, index.row()) + currentGridLineWidth(); + } + + // Adjust vertical position + scrollVerticalTo(index, hint, nCellHeight); + update(index); +} + +void GLDTableView::scrollHorizontalTo(const QModelIndex &index, ScrollHint &hint, int nCellWidth) +{ + if (horizontalScrollMode() == GlodonAbstractItemView::ScrollPerItem) + { + scrollHorizontalPerItemTo(index, hint, nCellWidth); + } + else // ScrollPerPixel + { + scrollHorizontalPerPixelTo(index, hint, nCellWidth); + } +} + +void GLDTableView::scrollHorizontalPerItemTo(const QModelIndex &index, ScrollHint &hint, int nCellWidth) +{ + Q_D(GLDTableView); + + // 当需要滚动到固定列时,由于固定列从来没改变过位置,因此不需要 + if (index.column() < d->m_nFixedColCount) + { + return; + } + + int nViewportWidth = d->viewport->width(); + int nHorizontalOffset = d->m_horizontalHeader->offset(); + int nHorizontalPosition = d->m_horizontalHeader->sectionPosition(index.column()); + + bool bPositionAtLeft = (nHorizontalPosition - nHorizontalOffset < d->m_nFixedColWidth); + bool bPositionAtRight = (nHorizontalPosition - nHorizontalOffset + nCellWidth > nViewportWidth); + + int nHorizontalIndex = firstVisualIndexAfterHorizontalScroll(index, hint, nCellWidth); + + // 下面是做滚动操作 + if (bPositionAtRight || hint == PositionAtCenter || bPositionAtLeft) + { + int nHiddenSections = getHorizontalHiddenSectionCountBeforeIndex(nHorizontalIndex); + // 因为固定可编辑列不需要滚动,也就是不占滚动步数 + // 所以设置的滚动步数时,应该是【前面计算出来的步数 - 隐藏的列数 - 固定可编辑列数】 + int nValue = nHorizontalIndex - nHiddenSections - d->m_nFixedColCount; + horizontalScrollBar()->setValue(nValue); + // 解决updateHorizontalScrollBar等地方中setOffset(0)而没有将滚动条复位而导致的滚动条和水平表头不能同步刷新问题 + if ((0 == d->m_horizontalHeader->offset()) && (0 != nValue)) + { + d->m_horizontalHeader->setOffsetToSectionPosition(horizontalScrollBar()->value()); + } + } +} + +void GLDTableView::scrollHorizontalPerPixelTo(const QModelIndex &index, GlodonAbstractItemView::ScrollHint &hint, int nCellWidth) +{ + Q_D(GLDTableView); + + int nViewportWidth = d->viewport->width(); + int nHorizontalOffset = d->m_horizontalHeader->offset(); + int nHorizontalPosition = d->m_horizontalHeader->sectionPosition(index.column()); + + if (hint == PositionAtCenter) + { + horizontalScrollBar()->setValue(nHorizontalPosition - ((nViewportWidth - nCellWidth) / 2)); + } + else + { + if (nHorizontalPosition - nHorizontalOffset < 0 || nCellWidth > nViewportWidth) + { + horizontalScrollBar()->setValue(nHorizontalPosition); + } + else if (nHorizontalPosition - nHorizontalOffset + nCellWidth > nViewportWidth) + { + horizontalScrollBar()->setValue(nHorizontalPosition - nViewportWidth + nCellWidth); + } + } +} + +bool GLDTableView::checkSelectionCopyEnable(const QModelIndexList &indexList) const +{ + //判断选择部分是否可以复制----同excel + int nRowNumber = indexList.last().row() - indexList.first().row() + 1; + int nColNumber = indexList.last().column() - indexList.first().column() + 1; + + bool bIsColumnSelectEnable = (indexList.count() % nRowNumber != 0); + bool bHasRowSpan = (indexList.first().row() + nRowNumber - 1 < indexList.last().row()); + bool bHasColSpan = (indexList.first().column() + nColNumber - 1 < indexList.last().column()); + bool bHasMultiRow = nRowNumber > 1; + bool bHasMultiCol = nColNumber > 1; + + return !(bIsColumnSelectEnable || (bHasMultiRow && bHasRowSpan) || (bHasMultiCol && bHasColSpan)); +} + +GString GLDTableView::getContentsFromOrderedIndexList(const QModelIndexList &indexList) +{ + Q_D(GLDTableView); + + GString result = ""; + + for(int i = 0; i < indexList.count(); ++i) + { + QVariant variant = d->m_model->data(indexList.at(i)); + GString cellText = ""; + + if (!variant.isNull()) + { + try + { + if (variant.type() == GVariant::DateTime) + { + GDateTime datatime = variant.toDateTime(); + cellText = dateTimeToStr(datatime); + } + else + { + cellText = variant.toString(); + } + } + catch (...) + { + cellText = ""; + } + } + + cellText = stringReplace(cellText, "\t", " "); + + result += cellText; + + if(indexList.at(i).column() < indexList.last().column()) + { + result += "\t"; + } + else if(indexList.at(i).column() == indexList.last().column() + && indexList.at(i).row() < indexList.last().row()) + { + result += sLineBreak; + } + } + + return result; +} + +void GLDTableView::fillCellsOnClipBoardText(const QModelIndexList &indexList, GString &sClipBoardText, + int &nPasteRowCount, int &nPasteColCount) +{ + Q_D(GLDTableView); + + // 从Excel粘贴过来的文本是以"\n"结尾 + // 暂时不考虑从excel粘贴出来的格子里有自动换行的情况,相当复杂 // todo + if (sClipBoardText.endsWith("\n")) + { + sClipBoardText = stringReplace(leftStr(sClipBoardText, sClipBoardText.length() - 1), "\n", sLineBreak); + } + + QStringList stringList = sClipBoardText.split(sLineBreak); + + for (int i = 0; i < stringList.count(); ++i) + { + int nRow = i + indexList.first().row(); + + if (d->m_model->rowCount() <= nRow) + { + break; + } + + QStringList oCells = stringList.at(i).split("\t"); + nPasteColCount = 0; + + for (int j = 0; j < oCells.size(); ++j) + { + int nCol = j + indexList.first().column(); + + if (d->m_model->columnCount() <= nCol) + { + break; + } + + QModelIndex curIndex = d->m_model->index(nRow, nCol, d->m_root); + setCellData(curIndex, oCells.at(j)); + ++nPasteColCount; + } + + ++nPasteRowCount; + } +} + +void GLDTableView::setNewSelection(const QModelIndexList &indexList, int &nPasteRowCount, int &nPasteColCount) +{ + Q_D(GLDTableView); + + QItemSelection newSelection; + + QModelIndex tl = d->m_model->index(indexList.first().row(), + indexList.first().column(), d->m_root); + + QModelIndex br = d->m_model->index(tl.row() + nPasteRowCount - 1, + tl.column() + nPasteColCount - 1, + d->m_root); + + newSelection.append(QItemSelectionRange(tl, br)); + d->m_selectionModel->select(newSelection, QItemSelectionModel::ClearAndSelect); +} + +void GLDTableView::setCellData(const QModelIndex &index, const QVariant &variant) +{ + Q_D(GLDTableView); + + GlodonDefaultItemDelegate *pGlodonDelegate = d->delegateForIndex(index); + QModelIndex oDataIndex = pGlodonDelegate->dataIndex(index); + + if (pGlodonDelegate->editable(oDataIndex)) + { + bool bReadOnly = false; + GEditStyle editStyle = pGlodonDelegate->editStyle(oDataIndex, bReadOnly); + + if ((d->m_editTriggers != NoEditTriggers) && !bReadOnly && editStyle != esNone) + { + d->m_model->setData(index, variant, Qt::EditRole); + } + } +} + +void GLDTableView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector &roles) +{ + Q_D(GLDTableView); + + if (topLeft == bottomRight && topLeft.isValid()) + { + QModelIndex oVisualIndex = visualIndex(topLeft); + if (!d->isVisibleIndex(oVisualIndex)) + return; + + refreshDisplayColRow(); + + d->updateNoStaticEditorData(topLeft); + + if (isVisible() && !d->m_delayedPendingLayout) + { + // otherwise the items will be update later anyway + update(topLeft); + } + } + else + { + GlodonAbstractItemView::dataChanged(topLeft, bottomRight, roles); + } +} + +void GLDTableView::scrollVerticalTo(const QModelIndex &index, ScrollHint &hint, int nCellHeight) +{ + Q_D(GLDTableView); + + // 当需要滚动到固定列时,由于固定列从来没改变过位置,因此不需要 + if (index.row() < d->m_nFixedRowCount) + { + return; + } + + int nViewportHeight = d->viewport->height(); + int nVerticalOffset = d->m_verticalHeader->offset(); + int nVerticalPosition = d->m_verticalHeader->sectionPosition(index.row()); + + bool bPositionAtTop = (nVerticalPosition - nVerticalOffset < d->m_nFixedRowHeight); + bool bPositionAtBottom = (nVerticalPosition - nVerticalOffset + nCellHeight > nViewportHeight); + + if (bPositionAtTop) + { + if (hint == EnsureVisible) + { + hint = PositionAtTop; + } + } else if (bPositionAtBottom) + { + if (hint == EnsureVisible) + { + hint = PositionAtBottom; + } + } + + if (verticalScrollMode() == GlodonAbstractItemView::ScrollPerItem) + { + scrollVerticalPerItemTo(index, hint, nCellHeight); + } + else // ScrollPerPixel + { + scrollVerticalPerPixelTo(index, hint, nCellHeight); + } +} + +void GLDTableView::scrollVerticalPerItemTo(const QModelIndex &index, GlodonAbstractItemView::ScrollHint &hint, int nCellHeight) +{ + Q_D(GLDTableView); + + // 下面是做滚动操作 + int nVerticalIndex = firstVisualIndexAfterVerticalScroll(index, hint, nCellHeight); + if (hint == PositionAtBottom || hint == PositionAtCenter || hint == PositionAtTop) + { + int nHiddenSections = getVerticalHiddenSectionCountBeforeIndex(nVerticalIndex); + // 因为固定可编辑列不需要滚动,也就是不占滚动步数 + // 所以设置的滚动步数时,应该是【前面计算出来的步数 - 隐藏的行数 - 固定可编辑行数】 + int nValue = nVerticalIndex - nHiddenSections - d->m_nFixedRowCount; + verticalScrollBar()->setValue(nValue); + } +} + +void GLDTableView::scrollVerticalPerPixelTo(const QModelIndex &index, GlodonAbstractItemView::ScrollHint &hint, int nCellHeight) +{ + Q_D(GLDTableView); + + int nViewportHeight = d->viewport->height(); + int nVerticalPosition = d->m_verticalHeader->sectionPosition(index.row()); + + if (hint == PositionAtTop) + { + verticalScrollBar()->setValue(nVerticalPosition); + } + else if (hint == PositionAtBottom) + { + verticalScrollBar()->setValue(nVerticalPosition - nViewportHeight + nCellHeight); + } + else if (hint == PositionAtCenter) + { + verticalScrollBar()->setValue(nVerticalPosition - ((nViewportHeight - nCellHeight) / 2)); + } +} + +/*! + This slot is called to change the height of the given \a row. The + old height is specified by \a oldHeight, and the new height by \a + newHeight. + + \sa columnResized() +*/ +void GLDTableView::rowResized(int row, int, int newHeight, bool isManual) +{ + Q_D(GLDTableView); + + if (isManual) + { + afterManualChangedRowHeight(row, newHeight); + resetCommentPosition(); + } + + d->m_rowsToUpdate.append(row); + + if (d->m_rowResizeTimerID == 0) + { + d->m_rowResizeTimerID = startTimer(0); + } + + resetEllipsisButtonLocation(); +} + +void GLDTableView::columnResized(int column, int oldWidth, int newWidth, bool isManual) +{ + Q_D(GLDTableView); + + if (d->m_bIsInAdjustFitCols) + { + return; + } + + if (isManual) + { + afterManualChangedColWidth(column, newWidth); + resetCommentPosition(); + } + + d->m_currResizeWidth = newWidth; + + // 自动列宽处理 + if (d->m_oSuitColWidthCols.contains(column) && (newWidth < oldWidth)) + { + oldWidth = sizeHintForColumn(column); + + if (newWidth < oldWidth && isManual) + { + d->m_horizontalHeader->resizeSection(column, oldWidth); + return; + } + } + + // 合适列宽处理 + if (d->m_oFitColWidthCols.size() != 0) + { + adjustColWidths(column); + + //设置完合适列宽后,将不是当前调整的合适列宽列手动刷新 + for (int i = 0; i < d->m_oFitColWidthCols.size(); ++i) + { + int nupdateCol = d->m_oFitColWidthCols.at(i); + + if (nupdateCol != column) + { + d->m_columnsToUpdate.append(nupdateCol); + } + } + } + + // 自动行高处理 + if (d->m_oSuitRowHeightAccordingCols.size() != 0) + { + bindMergeCell(); + + setGridDisplayRowHeights(); + } + + // Timer 刷新处理 + d->m_columnsToUpdate.append(column); + + if (d->m_columnResizeTimerID == 0) + { + d->m_columnResizeTimerID = startTimer(0); + } + + // 更多按钮位置处理 + resetEllipsisButtonLocation(); +} + +void GLDTableView::timerEvent(QTimerEvent *event) +{ + Q_D(GLDTableView); + + if (event->timerId() == d->m_columnResizeTimerID) + { + updateGeometries(); + killTimer(d->m_columnResizeTimerID); + d->m_columnResizeTimerID = 0; + + QRect rect; + int nviewportHeight = d->viewport->height(); + int nviewportWidth = d->viewport->width(); + + if (d->hasSpans()) + { + rect = QRect(0, 0, nviewportWidth, nviewportHeight); + } + else + { + for (int i = d->m_columnsToUpdate.size() - 1; i >= 0; --i) + { + int ncolumn = d->m_columnsToUpdate.at(i); + int nX = columnViewportPosition(ncolumn); + + if (isRightToLeft()) + { + rect |= QRect(0, 0, nX + columnWidth(ncolumn), nviewportHeight); + } + else + { + rect |= QRect(nX, 0, nviewportWidth - nX, nviewportHeight); + } + } + } + + d->viewport->update(rect.normalized()); + d->m_columnsToUpdate.clear(); + refreshDisplayRows(); + } + + if (event->timerId() == d->m_rowResizeTimerID) + { + updateGeometries(); + killTimer(d->m_rowResizeTimerID); + d->m_rowResizeTimerID = 0; + + int nviewportHeight = d->viewport->height(); + int nviewportWidth = d->viewport->width(); + int ntop; + + if (d->hasSpans()) + { + ntop = 0; + } + else + { + ntop = nviewportHeight; + + for (int i = d->m_rowsToUpdate.size() - 1; i >= 0; --i) + { + int nY = rowViewportPosition(d->m_rowsToUpdate.at(i)); + ntop = qMin(ntop, nY); + } + } + + d->viewport->update(QRect(0, ntop, nviewportWidth, nviewportHeight - ntop)); + d->m_rowsToUpdate.clear(); + refreshDisplayRows(); + } + + GlodonAbstractItemView::timerEvent(event); +} + +void GLDTableView::onBoolCellPress(QMouseEvent *event) +{ + // TODO: delete + G_UNUSED(event); +} + +void GLDTableView::onMousePress(QMouseEvent *event) +{ + GlodonAbstractItemView::mousePressEvent(event); +} + +void GLDTableView::mousePressEvent(QMouseEvent *event) +{ + Q_D(GLDTableView); + + // 单击表格CommitData + if ((event->button() & Qt::LeftButton) && !commitDataAndCloseEditorInIngnoreFocusOut()) + { + return; + } + + //如果当前正在编辑的格子数据commitData时失败,则单击无效 + if (!d->m_legalData) + { + return; + } + + QModelIndex index = indexAt(event->pos()); + + clickEditorButtonAccordingToEditStyleDrawType(index, event); + resetEnterJumpPreState(); + + // todo: 需要先调整选择模型,然后才能保证填充和选区移动计算时,参考选区正确计算。 + onMousePress(event); + + dealWithSpecialMousePressOperations(index, event); +} + +bool GLDTableView::viewportEvent(QEvent *event) +{ + Q_D(GLDTableView); + + if (event->type() == QEvent::Leave) + { + d->hideCommentFrame(); + } + + return GlodonAbstractItemView::viewportEvent(event); +} + +void GLDTableView::mouseMoveEvent(QMouseEvent *event) +{ + bool bHasCursor = testAttribute(Qt::WA_SetCursor); + QPoint pos = event->pos(); + + // 在超链接格子时,鼠标需要变为小手 + if (inLinkCell(pos)) + { + if (!bHasCursor) + { + setCursor(Qt::PointingHandCursor); + } + } + else if (shouldSetRangeFillMouseShape(pos)) + { + setRangeFillMouseShape(bHasCursor); + } + else if (isInRangeFilling()) + { + dealWithRangeFillingOnMouseMove(bHasCursor, pos); + } + else if (shouldSetRangeMoveMouseShape(pos)) + { + setRangeMoveMouseShape(bHasCursor); + } + else if (isInRangeMoving()) + { + dealWithRangeMovingOnMouseMove(pos); + } + else if (shouldSetResizeCellByDragGridLineMouseShape(event)) + { + setResizeCellByDragGridLineMouseShape(event); + } + else if (isInResizingCellByDragGridLine(event)) + { + dealWithResizeCellWhenDragGridLine(event); + } + else if (bHasCursor) + { + recoverCursor(); + } + else + { + GlodonAbstractItemView::mouseMoveEvent(event); + } + + // 批注框 + dealWithCurCommet(pos); +} + +void GLDTableView::mouseDoubleClickEvent(QMouseEvent *event) +{ + if (inBoolCell(event->pos())) + { + mousePressEvent(event); + } + else + { + GlodonAbstractItemView::mouseDoubleClickEvent(event); + } +} + +void GLDTableView::mouseReleaseEvent(QMouseEvent *event) +{ + Q_D(GLDTableView); + + // 结束拖拉复制 + if (d->m_state == RangeFillingState) + { + completeRangeFilling(); + } + // 结束框选拖拽 + else if (d->m_state == RangeMovingState) + { + completeRangeMoving(); + } + // 结束拖拽格线调整行高列宽 + else if (d->m_allowToResizeCellByDragGridLine + && event->button() == Qt::LeftButton + && d->m_state == DragResizingState) + { + completeResizeCellByDragGridLine(event); + } + else + { + GlodonAbstractItemView::mouseReleaseEvent(event); + } + + d->hideCommentFrame(); +} + +void GLDTableView::keyPressEvent(QKeyEvent *event) +{ + Q_D(GLDTableView); + + if (copyOrPastOperation(event)) + return; + + switch (event->key()) + { + case Qt::Key_Down: + case Qt::Key_Up: + { + if (openEditOrScrollContent(event)) + return; + break; + } + case Qt::Key_Left: + case Qt::Key_Right: + case Qt::Key_Escape: + { + resetEnterJumpPreState(); + break; + } + case Qt::Key_Return: + case Qt::Key_Enter: + { + dealWithKeyEnterPress(event); + return; + } + case Qt::Key_Backspace: + { + if (currentIndex().isValid() && state() != EditingState && (NoEditTriggers != d->m_editTriggers)) + { + QKeyEvent keyEventBackspace(QEvent::KeyPress, Qt::Key_Backspace, Qt::NoModifier); + edit(currentIndex(), AnyKeyPressed, &keyEventBackspace); + event->accept(); + return; + } + break; + } + case Qt::Key_F2: + case Qt::Key_Space: + { + QModelIndex index = currentIndex(); + if (index.isValid() && index.data(Qt::DisplayRole).type() == QVariant::Bool) + { + setBoolEditValue(index); + return; + } + break; + } + } + GlodonAbstractItemView::keyPressEvent(event); +} + +void GLDTableView::resizeEvent(QResizeEvent *event) +{ + GlodonAbstractItemView::resizeEvent(event); + + const bool isToggleHScrollBar = event->size().height() - event->oldSize().height() == horizontalScrollBar()->height(); + const bool isToggleVScrollBar = event->size().width() - event->oldSize().width() == verticalScrollBar()->width(); + + if (!isToggleHScrollBar && !isToggleVScrollBar) + { + refreshDisplayColRow(); + } +} + +void GLDTableView::leaveEvent(QEvent *event) +{ + Q_D(GLDTableView); + + d->hideCommentFrame(); + + GlodonAbstractItemView::leaveEvent(event); +} + +void GLDTableView::wheelEvent(QWheelEvent *event) +{ + Q_D(GLDTableView); + + QPersistentModelIndex index = indexAt(event->pos()); + + // TODO liurx 逻辑有点问题,待整理comment功能时再详细看 + if ((d->m_pCommentFrame == NULL) || (state() != DragSelectingState)) + { + d->drawComment(index); + } + else + { + d->m_pCommentFrame->hide(); + } + + GlodonAbstractItemView::wheelEvent(event); +} + +void GLDTableView::focusOutEvent(QFocusEvent *event) +{ + Q_D(GLDTableView); + + d->hideCommentFrame(); + + GlodonAbstractItemView::focusOutEvent(event); +} + +void GLDTableView::showEvent(QShowEvent *event) +{ + GlodonAbstractItemView::showEvent(event); + refreshDisplayColRow(); +} + +QRect GLDTableView::visualRectForRowColNo(const QRect &rowColNo) +{ + Q_D(GLDTableView); + + if (!rowColNo.isValid()) + return QRect(); + + QModelIndex oTopLeftIndex = d->m_model->index(rowColNo.top(), rowColNo.left()); + QModelIndex oBottomRightIndex = d->m_model->index(rowColNo.bottom(), rowColNo.right()); + QRect oTopLeftRect = visualRect(logicalIndex(oTopLeftIndex)); + QRect oBottomRightRect = visualRect(logicalIndex(oBottomRightIndex)); + return QRect(oTopLeftRect.left(), + oTopLeftRect.top(), + oBottomRightRect.right() - oTopLeftRect.left(), + oBottomRightRect.bottom() - oTopLeftRect.top()); +} + +void GLDTableView::closeEditor(QWidget *editor, bool &canCloseEditor, GlodonDefaultItemDelegate::EndEditHint hint) +{ + Q_D(GLDTableView); + + //如果commitData失败,就不能退出编辑状态 + if (d->m_inCommitData + || ((!d->m_legalData) && (hint != GlodonDefaultItemDelegate::RevertModelCache))) + { + return; + } + + // Close the editor + //关闭编辑控件之前也需要判断控件是否为静态 + QModelIndex index = d->indexForEditor(editor); + + if (editor && !d->m_indexEditorHash.value(index).isStatic) + { + GlodonDefaultItemDelegate *pDelegate = d->delegateForIndex(index); + + QVariant data = pDelegate->currentEditorData(index, editor); + emit onCloseEditor(dataIndex(index), data, canCloseEditor); + + if (!canCloseEditor) + { + d->m_legalData = false; + editor->setFocus(); + return; + } + + d->m_legalData = true; + pDelegate->setCurEditor(NULL); + + //退出编辑时,如果设置了行选,把固定行的格子选中-byHuangp + if (d->m_selectionModel->isRowSelected(index.row(), QModelIndex())) + { + GlodonMultiHeaderView *oMultiHeaderView = dynamic_cast(d->m_verticalHeader); + + if (NULL != oMultiHeaderView) + { + oMultiHeaderView->setSpansSelected(index.row(), true); + } + } + } + + GlodonAbstractItemView::closeEditor(editor, canCloseEditor, hint); + + processEnterJumpAfterCloseEdit(hint); +} + +void GLDTableView::commitData(QWidget *editor, bool &canCloseEditor) +{ + Q_D(GLDTableView); + + if (!editor || !d->m_itemDelegate || d->m_pCurCommittingEditor || d->m_inCommitData) + { + return; + } + + d->m_inCommitData = true; + + QModelIndex index = d->indexForEditor(editor); + + if (!index.isValid()) + { + d->m_inCommitData = false; + return; + } + + GlodonDefaultItemDelegate *pGlodonDelegate = d->delegateForIndex(index); + + try + { + QVariant data = pGlodonDelegate->currentEditorData(index, editor); + emit onCommitEditor(dataIndex(index), data, canCloseEditor); + + if (!canCloseEditor) + { + d->m_legalData = false; + d->m_inCommitData = false; + editor->setFocus(); + processScrollBarAfterCanNotCloseEditor(); + return; + } + else + { + d->m_legalData = true; + } + + GlodonAbstractItemView::commitData(editor, canCloseEditor); + } + catch (...) + { + if (pGlodonDelegate->m_bCloseEditorOnFocusOut) + { + pGlodonDelegate->m_bRepeatCommit = true; + } + d->m_inCommitData = false; + + throw; + } + + d->m_inCommitData = false; +} + +void GLDTableView::rowMoved(int, int oldIndex, int newIndex) +{ + Q_D(GLDTableView); + + updateGeometries(); + int nlogicalOldIndex = d->m_verticalHeader->logicalIndex(oldIndex); + int nlogicalNewIndex = d->m_verticalHeader->logicalIndex(newIndex); + + if (d->hasSpans()) + { + d->viewport->update(); + } + else + { + int noldTop = rowViewportPosition(nlogicalOldIndex); + int newTop = rowViewportPosition(nlogicalNewIndex); + int noldBottom = noldTop + rowHeight(nlogicalOldIndex); + int newBottom = newTop + rowHeight(nlogicalNewIndex); + int ntop = qMin(noldTop, newTop); + int nbottom = qMax(noldBottom, newBottom); + int nheight = nbottom - ntop; + d->viewport->update(0, ntop, d->viewport->width(), nheight); + } + +// QMap::iterator it = d->m_commentFrame.begin(); +// while (it != d->m_commentFrame.end()) +// { +// if (it.key().column() == oldIndex) +// { +// it.value()->setFramePosition(visualRect(it.key()).topRight()); +// } +// ++it; +// } +} + +void GLDTableView::canColumnMoved(int from, int to, bool &canMove) +{ + Q_D(GLDTableView); + + for (int row = 0; row < verticalHeader()->count(); ++row) + { + GSpanCollection::GSpan *fromSpan = d->m_spans.spanAt(from, row); + GSpanCollection::GSpan *toSpan = d->m_spans.spanAt(to, row); + + if ((NULL != fromSpan) || (NULL != toSpan)) + { + canMove = false; + } + } + + if (!canMove) + { + d->viewport->update(); + } +} + +void GLDTableView::columnMoved(int, int oldIndex, int newIndex) +{ + Q_D(GLDTableView); + + updateGeometries(); +// int logicalOldIndex = d->horizontalHeader->logicalIndex(oldIndex); +// int logicalNewIndex = d->horizontalHeader->logicalIndex(newIndex); +// if (d->hasSpans()) +// { + //列移动时,算刷新区域的效率,和刷全部区域的效率差不多,而且算出来的区域偏小,开启填充功能时,会有黑点 + d->viewport->update(); +// } +// else +// { +// int oldLeft = columnViewportPosition(logicalOldIndex); +// int newLeft = columnViewportPosition(logicalNewIndex); +// int oldRight = oldLeft + columnWidth(logicalOldIndex); +// int newRight = newLeft + columnWidth(logicalNewIndex); +// int left = qMin(oldLeft, newLeft); +// int right = qMax(oldRight, newRight); +// int width = right - left; +// d->viewport->update(left, 0, width, d->viewport->height()); +// } +// QMap::iterator it = d->m_commentFrame.begin(); +// while (it != d->m_commentFrame.end()) +// { +// if (it.key().column() == oldIndex || it.key().column() == newIndex) +// { +// QModelIndex visual = visualIndex(it.key()); +// it.value()->setFramePosition(visualRect(visual).topRight()); +// } +// ++it; +// } + Q_UNUSED(oldIndex); + Q_UNUSED(newIndex); +} + +void GLDTableView::selectRow(int row) +{ + Q_D(GLDTableView); + + if (d->m_allowSelectRow) + { + d->selectRow(row, true); + } +} + +void GLDTableView::selectColumn(int column) +{ + Q_D(GLDTableView); + + if (d->m_allowSelectCol) + { + d->selectColumn(column, true); + } +} + +void GLDTableView::hideRow(int row) +{ + Q_D(GLDTableView); + + d->m_verticalHeader->hideSection(row); +} + +void GLDTableView::hideColumn(int column) +{ + Q_D(GLDTableView); + d->m_horizontalHeader->hideSection(column); +} + +void GLDTableView::showRow(int row) +{ + Q_D(GLDTableView); + d->m_verticalHeader->showSection(row); +} + +void GLDTableView::showColumn(int column) +{ + Q_D(GLDTableView); + d->m_horizontalHeader->showSection(column); +} + +void GLDTableView::resizeRowToContents(int row) +{ + Q_D(GLDTableView); + + int nContent = sizeHintForRow(row); + int nHeaderSize = d->m_verticalHeader->sectionSizeHint(row); + + int nNewHeight = qMax(nContent, nHeaderSize); + d->m_verticalHeader->resizeSection(row, nNewHeight); + + afterManualChangedRowHeight(row, nNewHeight); + resetCommentPosition(); +} + +void GLDTableView::resizeRowsToContents() +{ + Q_D(GLDTableView); + + QList oAllColumns; + for (int i = 0; i < model()->columnCount(); ++i) + { + oAllColumns.append(i); + } + + QMap oResizeSections; + for (int i = 0; i < model()->rowCount(); ++i) + { + oResizeSections.insert(i, qMax(d->calcSizeHintForRow(i, oAllColumns), d->m_verticalHeader->sectionSizeHint(i))); + } + d->m_verticalHeader->batchResizeSection(oResizeSections); + updateAll(); + + resetCommentPosition(); +} + +void GLDTableView::resizeColumnToContents(int column) +{ + Q_D(GLDTableView); + + int nContent = sizeHintForColumn(column); + int nHeaderSize = d->m_horizontalHeader->sectionSizeHint(column); + + int nNewWidth = qMax(nContent, nHeaderSize); + d->m_horizontalHeader->resizeSection(column, nNewWidth); + + afterManualChangedColWidth(column, nNewWidth); + + resetCommentPosition(); +} + +void GLDTableView::resizeColumnsToContents() +{ + Q_D(GLDTableView); + + QMap oResizeSections; + for (int i = 0; i < model()->columnCount(); ++i) + { + oResizeSections.insert(i, qMax(d->sizeHintForColumn(i, true), d->m_horizontalHeader->sectionSizeHint(i))); + } + + d->m_horizontalHeader->batchResizeSection(oResizeSections); + updateAll(); +} + +void GLDTableView::setSuitRowHeightForAll(bool value, bool calcAllColumns) +{ + Q_D(GLDTableView); + d->m_bCalcAllColumns = calcAllColumns; + d->m_bAllRowsResizeToContents = value; + d->fillSuitRowHeightCols(); +} + +void GLDTableView::setSuitColWidthForAll(bool value, bool calcAllRows) +{ + Q_D(GLDTableView); + d->m_bCalcAllRows = calcAllRows; + d->m_bAllColumnsResizeToContents = value; + + d->fillSuitColWidthCols(); +} + +void GLDTableView::setAllowResizeCellByDragGridLine(bool canResize) +{ + Q_D(GLDTableView); + d->m_allowToResizeCellByDragGridLine = canResize; +} + +bool GLDTableView::allowResizeCellByDragGridLine() +{ + Q_D(GLDTableView); + return d->m_allowToResizeCellByDragGridLine; +} + +bool GLDTableView::enterJump() const +{ + Q_D(const GLDTableView); + return d->m_bEnterJump; +} + +void GLDTableView::setEnterJump(bool value) +{ + Q_D(GLDTableView); + + if (!value) + { + setEnterJumpPro(value); + } + + if (d->m_bEnterJump != value) + { + d->m_itemDelegate.data()->setIsEnterJump(value); + d->m_bEnterJump = value; + } +} + +bool GLDTableView::enterJumpPro() const +{ + Q_D(const GLDTableView); + return d->m_bEnterJumpPro; +} + +void GLDTableView::setEnterJumpPro(bool value) +{ + Q_D(GLDTableView); + + // 开启高级回车跳格,默认开启回车跳格 + if (value) + { + setEnterJump(true); + } + + if (d->m_bEnterJumpPro != value) + { + d->m_itemDelegate.data()->setIsEnterJumpPro(value); + d->m_bEnterJumpPro = value; + } +} + +void GLDTableView::setUseBlendColor(bool value) +{ + Q_D(GLDTableView); + + if (d->m_bUseBlendColor != value) + { + d->m_itemDelegate.data()->setUseBlendColor(value); + d->m_bUseBlendColor = value; + + d->viewport->update(); + } +} + +bool GLDTableView::useBlendColor() const +{ + Q_D(const GLDTableView); + return d->m_bUseBlendColor; +} + +QColor GLDTableView::selectedCellBackgroundColor() const +{ + Q_D(const GLDTableView); + return d->m_oSelectedCellBackgroundColor; +} + +void GLDTableView::setSelectedCellBackgroundColor(QColor value) +{ + Q_D(GLDTableView); + + if (d->m_oSelectedCellBackgroundColor != value) + { + d->m_itemDelegate.data()->setSelectedCellBackgroundColor(value); + d->m_oSelectedCellBackgroundColor = value; + + d->viewport->update(); + } +} + +void GLDTableView::setSelectedBoundLineColor(QColor value) +{ + Q_D(GLDTableView); + d->m_selectBoundLineColor = value; +} + +QColor GLDTableView::selectedBoundLineColor() const +{ + Q_D(const GLDTableView); + return d->m_selectBoundLineColor; +} + +void GLDTableView::setSelectedBoundLineWidth(SelectBorderWidth lineWidth) +{ + Q_D(GLDTableView); + d->m_selectBoundLineWidth = (int)lineWidth; +} + +int GLDTableView::selectedBoundLineWidth() const +{ + Q_D(const GLDTableView); + return d->m_selectBoundLineWidth; +} + +void GLDTableView::setNoFocusSelectedBoundLineColor(QColor value) +{ + Q_D(GLDTableView); + d->m_oNoFocusSelectedBoundLineColor = value; +} + +QColor GLDTableView::NoFocusSelectedBoundLineColor() const +{ + Q_D(const GLDTableView); + return d->m_oNoFocusSelectedBoundLineColor; +} + +void GLDTableView::sortByColumn(int column) +{ + Q_D(GLDTableView); + + if (column == -1) + { + return; + } + + d->m_horizontalHeader->setSortIndicatorSection(column); + + d->m_model->sort(column, d->m_horizontalHeader->sortIndicatorOrder()); +} + +void GLDTableView::sortByColumn(int column, Qt::SortOrder order) +{ + Q_D(GLDTableView); + d->m_horizontalHeader->setSortIndicator(column, order); + sortByColumn(column); +} + +void GLDTableView::verticalScrollbarAction(int action) +{ + GlodonAbstractItemView::verticalScrollbarAction(action); +} + +void GLDTableView::horizontalScrollbarAction(int action) +{ + GlodonAbstractItemView::horizontalScrollbarAction(action); +} + +bool GLDTableView::isIndexHidden(const QModelIndex &index) const +{ + Q_D(const GLDTableView); + Q_ASSERT(d->isIndexValid(index)); + + if (isRowHidden(index.row()) || isColumnHidden(index.column())) + { + return true; + } + + if (d->hasSpans()) + { + GSpanCollection::GSpan span = d->span(index.row(), index.column()); + return !((span.top() == index.row()) && (span.left() == index.column())); + } + + return false; +} + +bool GLDTableView::inBoolCell(const QPoint pos) const +{ + Q_D(const GLDTableView); + QModelIndex index = indexAt(pos); + + if (index.isValid()) + { + GlodonDefaultItemDelegate *pIndexDelegate = d->delegateForIndex(index); + + pIndexDelegate->setCurrTreeEditting(index); + return index.data().type() == QVariant::Bool; + } + + return false; +} + +int GLDTableView::rowSpan(int row, int column) const +{ + Q_D(const GLDTableView); + return d->rowSpan(row, column); +} + +int GLDTableView::columnSpan(int row, int column) const +{ + Q_D(const GLDTableView); + return d->columnSpan(row, column); +} + +QModelIndex GLDTableView::spanAt(int row, int column) +{ + Q_D(const GLDTableView); + GSpanCollection::GSpan *span = d->m_spans.spanAt(column, row); + + if (NULL == span) + { + return QModelIndex(); + } + else + { + return d->m_model->index(span->left(), span->top()); + } +} + +void GLDTableViewPrivate::_q_selectRow(int row) +{ + selectRow(row, false); +} + +void GLDTableViewPrivate::_q_selectColumn(int column) +{ + selectColumn(column, false); +} + +void GLDTableViewPrivate::_q_selectRows(int left, int top, int right, int bottom) +{ + Q_UNUSED(left); + Q_UNUSED(right); + selectRows(top, bottom, true); +} + +void GLDTableViewPrivate::_q_selectColumns(int left, int top, int right, int bottom) +{ + Q_UNUSED(top); + Q_UNUSED(bottom); + selectColumns(left, right, true); +} + +void GLDTableViewPrivate::doSelect( + const QModelIndex &tl, const QModelIndex &br, QItemSelectionModel::SelectionFlags command, bool) +{ + QItemSelection selection(tl, br); + + m_selectionModel->select(selection, command); +} + +void GLDTableViewPrivate::selectRow(int row, bool anchor) +{ + Q_Q(GLDTableView); + + if (selectRows(row, row, anchor)) + { + QModelIndex currentScrollToIndex = m_model->index(row, q->currentIndex().column(), m_root); + q->scrollTo(currentScrollToIndex); + } +} + +void GLDTableViewPrivate::selectColumn(int column, bool anchor) +{ + Q_Q(GLDTableView); + + if (selectColumns(column, column, anchor)) + { + QModelIndex currentScrollToIndex = m_model->index(q->currentIndex().row(), column, m_root); + q->scrollTo(currentScrollToIndex); + } +} + +bool GLDTableViewPrivate::selectColumns(int start, int end, bool anchor) +{ + Q_Q(GLDTableView); + + if ((start > end) || (start < 0) || (end >= m_horizontalHeader->count())) + return false; + + if (q->selectionBehavior() == GLDTableView::SelectRows + || (q->selectionMode() == GLDTableView::SingleSelection + && q->selectionBehavior() == GLDTableView::SelectItems)) + { + return false; + } + + m_rangeFillHandlePositon = RightTop; + + int row = m_verticalHeader->logicalIndexAt(0); + QModelIndex index = m_model->index(row, start, m_root); + + QItemSelectionModel::SelectionFlags command = q->selectionCommand(index); + + m_bIsInMultiSelect = command & QItemSelectionModel::Toggle ? true : false; + + bool bShouldSelect = true; + + if (anchor) + { + if (q->currentIndex().isValid()) + { + if (!q->commitDataAndCloseEditorInIngnoreFocusOut()) + return false; + + bShouldSelect = q->moveCurrent(q->currentIndex(), + m_model->index(q->currentIndex().row(), start, m_root), + command, mrProgram); + } + else + { + bShouldSelect = q->moveCurrent(q->currentIndex(), index, command, mrProgram); + } + } + + if ((anchor && !(command & QItemSelectionModel::Current)) + || (q->selectionMode() == GLDTableView::SingleSelection)) + { + m_columnSectionAnchor = start; + } + + if (q->selectionMode() != GLDTableView::SingleSelection + && command.testFlag(QItemSelectionModel::Toggle)) + { + if (anchor) + { + m_ctrlDragSelectionFlag = m_verticalHeader->selectionModel()->selectedColumns().contains(index) + ? QItemSelectionModel::Deselect : QItemSelectionModel::Select; + } + + command &= ~QItemSelectionModel::Toggle; + command |= m_ctrlDragSelectionFlag; + + if (!anchor) + { + command |= QItemSelectionModel::Current; + } + } + + QModelIndex tl = m_model->index(0, qMin(m_columnSectionAnchor, start), m_root); + QModelIndex br = m_model->index(m_model->rowCount(m_root) - 1, + qMax(m_columnSectionAnchor, end), m_root); + + + if (bShouldSelect) + { + if ((m_horizontalHeader->sectionsMoved() && tl.column() != br.column()) + || m_verticalHeader->sectionsMoved()) + { + m_oTopLeftSelectIndex = q->visualIndex(tl); + m_oBottomRightSelectIndex = q->visualIndex(br); + q->setSelectionByIndex(m_oTopLeftSelectIndex, m_oBottomRightSelectIndex, command); + } + else + { + doSelect(tl, br, command, false); + } + return true; + } + + return false; +} + +bool GLDTableViewPrivate::selectRows(int start, int end, bool anchor) +{ + Q_Q(GLDTableView); + + if ((start > end) || (start < 0) || end >= m_verticalHeader->count()) + return false; + + if (q->selectionBehavior() == GLDTableView::SelectColumns + || (q->selectionMode() == GLDTableView::SingleSelection + && q->selectionBehavior() == GLDTableView::SelectItems)) + { + return false; + } + + m_rangeFillHandlePositon = LeftBottom; + + int ncolumn = m_horizontalHeader->logicalIndexAt(q->isRightToLeft() ? viewport->width() : 0); + QModelIndex index = m_model->index(start, ncolumn, m_root); + + QItemSelectionModel::SelectionFlags command = q->selectionCommand(index); + + m_bIsInMultiSelect = command & QItemSelectionModel::Toggle ? true : false; + + bool bShouldSelect = true; + + if (anchor) + { + if (q->currentIndex().isValid()) + { + if (!q->commitDataAndCloseEditorInIngnoreFocusOut()) + { + return false; + } + + bShouldSelect = q->moveCurrent(q->currentIndex(), + m_model->index(start, q->currentIndex().column(), m_root), + command, mrProgram); + } + else + { + bShouldSelect = q->moveCurrent(q->currentIndex(), index, command, mrProgram); + } + } + + if ((anchor && !(command & QItemSelectionModel::Current)) + || (q->selectionMode() == GLDTableView::SingleSelection)) + { + m_rowSectionAnchor = start; + } + + if (q->selectionMode() != GLDTableView::SingleSelection + && command.testFlag(QItemSelectionModel::Toggle)) + { + if (anchor) + { + m_ctrlDragSelectionFlag = m_verticalHeader->selectionModel()->selectedRows().contains(index) + ? QItemSelectionModel::Deselect : QItemSelectionModel::Select; + } + + command &= ~QItemSelectionModel::Toggle; + command |= m_ctrlDragSelectionFlag; + + if (!anchor) + { + command |= QItemSelectionModel::Current; + } + } + + QModelIndex tl = m_model->index(qMin(m_rowSectionAnchor, start), 0, m_root); + QModelIndex br = m_model->index(qMax(m_rowSectionAnchor, end), m_model->columnCount(m_root) - 1, m_root); + + if (bShouldSelect) + { + if ((m_verticalHeader->sectionsMoved() && tl.row() != br.row()) + || m_horizontalHeader->sectionsMoved()) + { + m_oTopLeftSelectIndex = q->visualIndex(tl); + m_oBottomRightSelectIndex = q->visualIndex(br); + q->setSelectionByIndex(m_oTopLeftSelectIndex, m_oBottomRightSelectIndex, command); + } + else + { + doSelect(tl, br, command, true); + } + return true; + } + + return false; +} + +void GLDTableView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) +{ + GlodonAbstractItemView::currentChanged(current, previous); + + afterCurrentChanged(dataIndex(current), dataIndex(previous)); +} + +bool GLDTableView::isLegalData() +{ + Q_D(GLDTableView); + return d->m_legalData; +} + +void GLDTableView::setLegalData(bool value) +{ + Q_D(GLDTableView); + d->m_legalData = value; +} + +bool GLDTableView::event(QEvent *event) +{ + bool result = GlodonAbstractItemView::event(event); + + switch (event->type()) + { + case QEvent::StyleChange: + { + if (isCustomStyle()) + { + const_cast(palette()).setColor(QPalette::Window, gridColor()); + setBackgroundRole(QPalette::Window); + setGridColor(gridColor()); + } + + break; + } + + default: + break; + } + + return result; +} + +int GLDTableView::firstVisualRow() const +{ + Q_D(const GLDTableView); + + if (d->m_nFixedRowCount > 0) + { + d->calculateFixedRowHeight(); + // 为了获取固定行的后一行,所以增加一个像素 + return d->m_verticalHeader->visualIndexAt(d->m_nFixedRowHeight + 1); + } + + return qMax(d->m_verticalHeader->visualIndexAt(0), 0); +} + +int GLDTableView::lastVisualRow() const +{ + Q_D(const GLDTableView); + + int nLastVisualRow = d->m_verticalHeader->visualIndexAt(d->viewport->height()); + + if (nLastVisualRow == -1) + { + nLastVisualRow = d->m_verticalHeader->count() - 1; + } + + return nLastVisualRow; +} + +int GLDTableView::firstVisualCol() const +{ + Q_D(const GLDTableView); + + if (d->m_nFixedColCount > 0) + { + d->calculateFixedColumnWidth(); + // 为了获取固定列的后一列,所以增加一个像素 + return d->m_horizontalHeader->visualIndexAt(d->m_nFixedColWidth + 1); + } + + return d->m_horizontalHeader->visualIndexAt(0); +} + +int GLDTableView::lastVisualCol() const +{ + Q_D(const GLDTableView); + + int nViewPortWidth = viewport()->width(); + int nlastVisualCol = d->m_horizontalHeader->visualIndexAt(nViewPortWidth); + + if (nlastVisualCol != -1) + { + int nLastVisualColPosition = d->m_horizontalHeader->sectionVisualPosition(nlastVisualCol); + + if (nLastVisualColPosition + columnWidth(nlastVisualCol) > nViewPortWidth) + { + nlastVisualCol = nlastVisualCol - 1; + } + } + else + { + if (firstVisualCol() != -1) + { + nlastVisualCol = d->m_horizontalHeader->count() - 1; + } + } + + return nlastVisualCol; +} + +GIntList GLDTableView::needCalcSuitRowHeightColsInViewport() +{ + Q_D(GLDTableView); + + QSet oNeedCalcHeightCols; + for (int i = 0; i < d->m_nFixedColCount; ++i) + { + if (d->m_oSuitRowHeightAccordingCols.contains(i)) + { + oNeedCalcHeightCols.insert(i); + } + } + + int nLeft; + int nRight; + + if (d->m_bCalcAllColumns) + { + nLeft = 0; + nRight = model()->columnCount(); + } + else + { + nLeft = firstVisualCol(); + nRight = lastVisualCol(); + + adjustVisualCol(nLeft, nRight); + } + + for (int i = nLeft; i <= nRight; ++i) + { + if (d->m_oSuitRowHeightAccordingCols.contains(i)) + { + oNeedCalcHeightCols.insert(i); + } + } + return oNeedCalcHeightCols.toList(); +} + +QModelIndex GLDTableView::topLeftIndex(const QRect &rowColRect) const +{ + Q_D(const GLDTableView); + return d->m_model->index(rowColRect.top(), rowColRect.left(), d->m_root); +} + +QModelIndex GLDTableView::bottomRightIndex(const QRect &rowColRect) const +{ + Q_D(const GLDTableView); + return d->m_model->index(rowColRect.bottom(), rowColRect.right(), d->m_root); +} + +void GLDTableView::bindMergeCell() +{ + Q_D(GLDTableView); + + QAbstractItemModel *pDataModel = itemModel(); + if ((pDataModel == NULL) || (pDataModel->rowCount() == 0)) + { + return; + } + + clearSpans(); + + int nFirstVisualCol = firstVisualCol(); + int nLastVisualCol = lastVisualCol(); + int nFirstVisualRow = firstVisualRow(); + int nLastVisualRow = lastVisualRow(); + + // 把可见行的区域都扩大,防止,出现在计算过程中,出现本来是合并个却因这一行或这一列未完全显示,导致没有计算情况 + adjustVisualRect(nFirstVisualRow, nFirstVisualCol, nLastVisualRow, nLastVisualCol); + if (nFirstVisualRow == -1 || nLastVisualRow == -1 || nFirstVisualCol == -1 || nLastVisualCol == -1) + { + return; + } + + // 对于可编辑固定行和可编辑固定列,需特殊处理,因此,不支持一个合并格跨了固定区域和非固定区域 + calcAndSetSpan(nFirstVisualRow, nLastVisualRow, 0, d->m_nFixedColCount - 1); + calcAndSetSpan(0, d->m_nFixedRowCount - 1, nFirstVisualCol, nLastVisualCol); + calcAndSetSpan(0, d->m_nFixedRowCount - 1, 0, d->m_nFixedColCount - 1); + + calcAndSetSpan(nFirstVisualRow, nLastVisualRow, nFirstVisualCol, nLastVisualCol); +} + +void GLDTableView::afterCurrentChanged(const QModelIndex ¤t, const QModelIndex &previous) +{ + Q_UNUSED(current); + Q_UNUSED(previous); + // do nothing +} + +void GLDTableView::afterExpandedChanged(int index, bool expand, bool emitSignal) +{ + if (emitSignal) + { + if (expand) + { + emit expanded(index); + } + else + { + emit collapsed(index); + } + } +} + +void GLDTableView::afterManualChangedRowHeight(int index, int rowHeight) +{ + G_UNUSED(index); + G_UNUSED(rowHeight); +} + +void GLDTableView::afterManualChangedColWidth(int index, int colWidth) +{ + G_UNUSED(index); + G_UNUSED(colWidth); +} + +void GLDTableView::selectionChanged( + const QItemSelection &selected, const QItemSelection &deselected) +{ + Q_D(GLDTableView); + G_UNUSED(selected); + + if (d->m_alwaysShowRowSelectedColor && isVisible() && updatesEnabled()) + { + d->viewport->update(); + } + else + { + if (isVisible() && updatesEnabled()) + { + // 按着ctrl键进行选择时,需要把原来的选择区域的边框线刷掉,所以此处不能在用selected参数 + d->viewport->update(visualRegionForSelectionWithSelectionBounding(deselected) + | visualRegionForSelectionWithSelectionBounding(d->m_selectionModel.data()->selection())); + } + } +} + +QRect GLDTableView::initRangeFillingDest() +{ + QRect oRangeFillingRect = m_oRangeSrc; + m_oRangeDest = m_oRangeSrc; + + // 向上拖拽 + if (m_nRangeCurRow < m_oRangeSrc.top()) + { + oRangeFillingRect.setTop(m_nRangeCurRow); + m_oRangeDest.setTop(m_nRangeCurRow); + m_oRangeDest.setBottom(m_oRangeSrc.top() - 1); + } + // 向下拖拽 + else if (m_nRangeCurRow > m_oRangeSrc.bottom()) + { + oRangeFillingRect.setBottom(m_nRangeCurRow); + m_oRangeDest.setBottom(m_nRangeCurRow); + m_oRangeDest.setTop(m_oRangeSrc.bottom() + 1); + } + // 向左拖拽 + else if (m_nRangeCurCol < m_oRangeSrc.left()) + { + oRangeFillingRect.setLeft(m_nRangeCurCol); + m_oRangeDest.setLeft(m_nRangeCurCol); + m_oRangeDest.setRight(m_oRangeSrc.left() - 1); + } + // 向右拖拽 + else if (m_nRangeCurCol > m_oRangeSrc.right()) + { + oRangeFillingRect.setRight(m_nRangeCurCol); + m_oRangeDest.setRight(m_nRangeCurCol); + m_oRangeDest.setLeft(m_oRangeSrc.right() + 1); + } + + return oRangeFillingRect; +} + +bool GLDTableView::inRangeMovingRegion(const QPoint &p) +{ + Q_D(GLDTableView); + + if (d->isInMutiSelect())//如果处于多选, 则不允许移动 + { + return false; + } + + QRect srcRect = visualRectForRowColNo(visualRectForSelection()); + + if (srcRect.isValid()) + { + QRect bigRect = srcRect; + bigRect.adjust(-1, -1, 1, 1); + QRect smallRect = srcRect; + smallRect.adjust(3, 3, -3, -3); + QRect rangeMovingHandleRect(QPoint(bigRect.right() - 5, bigRect.bottom() - 5), QSize(5, 5)); + return bigRect.contains(p) && !smallRect.contains(p) && !rangeMovingHandleRect.contains(p); + } + + return false; +} + +bool GLDTableView::initRangeMovingDest() +{ + Q_D(GLDTableView); + int noffsetRow = 0; + int noffsetCol = 0; + m_oRangeDest = m_oRangeSrc; + + if (m_nRangeCurRow < m_oRangeSrc.top()) + { + noffsetRow = m_nRangeCurRow - m_oRangeSrc.top(); + m_oRangeDest.setTop(m_nRangeCurRow); + m_oRangeDest.setBottom(m_oRangeSrc.bottom() + noffsetRow); + } + else if (m_nRangeCurRow >= m_oRangeSrc.bottom()) + { + noffsetRow = m_nRangeCurRow - m_oRangeSrc.bottom(); + m_oRangeDest.setTop(noffsetRow + m_oRangeSrc.top()); + m_oRangeDest.setBottom(m_nRangeCurRow); + } + + if (m_nRangeCurCol < m_oRangeSrc.left()) + { + noffsetCol = m_nRangeCurCol - m_oRangeSrc.left(); + m_oRangeDest.setLeft(m_nRangeCurCol); + m_oRangeDest.setRight(m_oRangeSrc.right() + noffsetCol); + } + else if (m_nRangeCurCol > m_oRangeSrc.right()) + { + noffsetCol = m_nRangeCurCol - m_oRangeSrc.right(); + m_oRangeDest.setLeft(m_oRangeSrc.left() + noffsetCol); + m_oRangeDest.setRight(m_nRangeCurCol); + } + + bool bcanRangeMoving = true; + + for (int row = m_oRangeSrc.top(); row <= m_oRangeSrc.bottom(); ++row) + { + for (int col = m_oRangeSrc.left(); col <= m_oRangeSrc.right(); ++col) + { + GSpanCollection::GSpan *srcSpan = d->m_spans.spanAt(col, row); + GSpanCollection::GSpan *destSpan = d->m_spans.spanAt(col + noffsetCol, row + noffsetRow); + + //当src和dest都存在合并个且合并格的高度宽度相等时,或则都不含有合并个时,允许选择移动,此外其他情况都不允许 + if (((NULL != srcSpan) && (NULL != destSpan) && (srcSpan->width() == destSpan->width()) + && (srcSpan->height() == destSpan->height())) || (NULL == srcSpan && NULL == destSpan)) + { + continue; + } + else + { + bcanRangeMoving = false; + } + } + } + + return bcanRangeMoving; +} + +QRect GLDTableView::visualRectForSelection() +{ + Q_D(GLDTableView); + if (!d->m_oTopLeftSelectIndex.isValid() || !d->m_oBottomRightSelectIndex.isValid()) + return QRect(); + + int nTop = d->m_oTopLeftSelectIndex.row(); + int nLeft = d->m_oTopLeftSelectIndex.column(); + int nBottom = d->m_oBottomRightSelectIndex.row(); + int nRight = d->m_oBottomRightSelectIndex.column(); + + return QRect(nLeft, nTop, nRight - nLeft + 1, nBottom - nTop + 1); +} + +void GLDTableView::initRangeAction() +{ + Q_D(GLDTableView); + QItemSelection selection = d->m_selectionModel.data()->selection(); + + if (selection.count() > 0) + { + m_oRangeSrc = visualRectForSelection(); + m_nRangeCurRow = m_oRangeSrc.bottom(); + m_nRangeCurCol = m_oRangeSrc.right(); + } +} + +QRect GLDTableView::calcRangeMovingRegion() +{ + Q_D(GLDTableView); + + const QPoint c_offset = d->m_scrollDelayOffset; + + int nSrcTop = rowVisualPosition(m_oRangeSrc.top()) + c_offset.y(); + int nSrcBottom = rowVisualPosition(m_oRangeSrc.bottom()) + c_offset.y() + visualRowHeight(m_oRangeSrc.bottom()); + int nSrcLeft = columnVisualPosition(m_oRangeSrc.left()) + c_offset.x(); + int nSrcRight = columnVisualPosition(m_oRangeSrc.right()) + c_offset.x() + visualColumnWidth(m_oRangeSrc.right()); + + int nDestTop = nSrcTop; + int nDestBottom = nSrcBottom; + int nDestLeft = nSrcLeft; + int nDestRight = nSrcRight; + + // CurrentRow和Col是指离原始位置最远的那个格子 + // 向上拖拽 + if (m_nRangeCurRow < m_oRangeSrc.top()) + { + int nDestBottomRow = m_nRangeCurRow + m_oRangeSrc.height() - 1; + nDestTop = rowVisualPosition(m_nRangeCurRow) + c_offset.y(); + nDestBottom = rowVisualPosition(nDestBottomRow) + visualRowHeight(nDestBottomRow) + c_offset.y(); + } + // 向下拖拽 + else if (m_nRangeCurRow >= m_oRangeSrc.bottom()) + { + int nDestTopRow = m_nRangeCurRow - m_oRangeSrc.height() + 1; + nDestTop = rowVisualPosition(nDestTopRow) + c_offset.y(); + nDestBottom = rowVisualPosition(m_nRangeCurRow) + visualRowHeight(m_nRangeCurRow) + c_offset.y(); + } + + // 向左拖拽 + if (m_nRangeCurCol < m_oRangeSrc.left()) + { + int nDestRightCol = m_nRangeCurCol + m_oRangeSrc.width() - 1; + nDestLeft = columnVisualPosition(m_nRangeCurCol) + c_offset.x(); + nDestRight = columnVisualPosition(nDestRightCol) + visualColumnWidth(nDestRightCol) + c_offset.x(); + } + // 向右拖拽 + else if (m_nRangeCurCol > m_oRangeSrc.right()) + { + int nDestLeftCol = m_nRangeCurCol - m_oRangeSrc.width() + 1; + nDestLeft = columnVisualPosition(nDestLeftCol) + c_offset.x(); + nDestRight = columnVisualPosition(m_nRangeCurCol) + visualColumnWidth(m_nRangeCurCol) + c_offset.x(); + } + + return QRect(QPoint(nDestLeft, nDestTop), QPoint(nDestRight, nDestBottom)); +} + +void GLDTableView::setCurRangeRowAndCol(QPoint pos) +{ + Q_D(GLDTableView); + + m_nRangeCurRow = visualRowAt(pos.y()); + if (m_nRangeCurRow == -1) + { + if (pos.y() < 0) + { + m_nRangeCurRow = 0; + } + else + { + m_nRangeCurRow = d->m_verticalHeader->count() - 1; + } + } + + m_nRangeCurCol = visualColumnAt(pos.x()); + if (m_nRangeCurCol == -1) + { + if (pos.x() < 0) + { + m_nRangeCurCol = 0; + } + else + { + m_nRangeCurCol = d->m_horizontalHeader->count() - 1; + } + } +} + +void GLDTableView::addNewRow(int newRowCount) +{ + Q_D(GLDTableView); + QModelIndexList indexList = selectionModel()->selectedIndexes(); + QModelIndex index1 = indexList.at(0); + QModelIndex index2 = indexList.at(indexList.size() - 1); + + d->m_model->insertRows(qMax(index1.row(), index2.row()), newRowCount); +} + +QString GLDTableView::resizeInfoText(QPoint mousePosition, Qt::Orientation direction) +{ + Q_D(GLDTableView); + + QString sInfoText = ""; + + const QString sWidth = tr("width:"); + const QString sHeight = tr("height:"); + const QString sPixel = tr("pixel("); + const QString sMilliMetre = tr("millimetre)"); + + if (direction == Qt::Horizontal) + { + int nResizeOffset = mousePosition.x() - d->m_nResizeCellStartPosition; + //通过logicalDpiX获取dpi,把像素转换为厘米 + float fMillimetre = nResizeOffset * 1.0 / logicalDpiX() * 25.4; + sInfoText = sWidth + QString::number(nResizeOffset, 10) + sPixel + + QString::number(fMillimetre, 'f', 1) + sMilliMetre; + } + else + { + int nResizeOffset = mousePosition.y() - d->m_nResizeCellStartPosition; + float fMillimetre = nResizeOffset * 1.0 / logicalDpiX() * 25.4; + sInfoText = sHeight + QString::number(nResizeOffset, 10) + sPixel + + QString::number(fMillimetre, 'f', 1) + sMilliMetre; + } + + return sInfoText; +} + +void GLDTableView::setResizeStartPosition(Qt::Orientation direction) +{ + Q_D(GLDTableView); + + int nResizeIndex; + if (direction == Qt::Horizontal) + { + int nBeforeIndex = d->m_horizontalHeader->visualIndexAt(d->m_horizontalHeader->mousePosition().x() - c_nResizeHandlerOffset); + int nAfterIndex = d->m_horizontalHeader->visualIndexAt(d->m_horizontalHeader->mousePosition().x() + c_nResizeHandlerOffset); + + if (nAfterIndex == -1) + { + nAfterIndex = nBeforeIndex; + } + + nResizeIndex = qMin(nBeforeIndex, nAfterIndex); + d->m_nResizeCellStartPosition = d->m_horizontalHeader->sectionViewportPosition(nResizeIndex); + d->m_nResizeCellEndPosition = d->m_nResizeCellStartPosition + columnWidth(nResizeIndex); + } + else + { + int nBeforeIndex = d->m_verticalHeader->visualIndexAt(d->m_verticalHeader->mousePosition().y() - c_nResizeHandlerOffset); + int nAfterIndex = d->m_verticalHeader->visualIndexAt(d->m_verticalHeader->mousePosition().y() + c_nResizeHandlerOffset); + + if (nAfterIndex == -1) + { + nAfterIndex = nBeforeIndex; + } + + nResizeIndex = qMin(nBeforeIndex, nAfterIndex); + d->m_nResizeCellStartPosition = d->m_verticalHeader->sectionViewportPosition(nResizeIndex); + d->m_nResizeCellEndPosition = d->m_nResizeCellStartPosition + rowHeight(nResizeIndex); + } +} + +void GLDTableView::doRangeFill() +{ + if (doRangeFillHandled()) + { + return; + } + + // 向上拖拽 + if (m_nRangeCurRow < m_oRangeSrc.top()) + { + doRangeFillToTop(); + } + // 向下拖拽 + else if (m_nRangeCurRow > m_oRangeSrc.bottom()) + { + doRangeFillToBottom(); + } + // 向左拖拽 + else if (m_nRangeCurCol < m_oRangeSrc.left()) + { + doRangeFillToLeft(); + } + // 向右拖拽 + else if (m_nRangeCurCol > m_oRangeSrc.right()) + { + doRangeFillToRight(); + } +} + +void GLDTableView::doRangeMoving(QRect src, QRect dest) +{ + Q_D(GLDTableView); + bool bIsSetCurrentIndex = false; + + for (int sc = src.left(), dc = dest.left(); sc <= src.right() && dc <= dest.right(); ++sc, ++dc) + { + for (int sr = src.top(), dr = dest.top(); sr <= src.bottom() && dr <= dest.bottom(); ++sr, ++dr) + { + QModelIndex scurr = logicalIndex(d->m_model->index(sr, sc)); + QModelIndex dcurr = logicalIndex(d->m_model->index(dr, dc)); + + if (scurr == dcurr) + { + continue; + } + + if (!bIsSetCurrentIndex && scurr == currentIndex()) + { + bIsSetCurrentIndex = true; + setCurrentIndex(dataIndex(dcurr)); + } + + d->m_model->setData(dcurr, d->m_model->data(scurr)); + d->m_model->setData(scurr, QVariant()); + } + } +} + +// todo litz-a 此方法可能会在拖拽填充功能中给外部使用,暂不删除,后期修改易用性时再做处理 +QList GLDTableView::rangeToList(QRect rect) +{ + Q_D(GLDTableView); + + QList modelIndexList; + + for (int i = rect.top(); i <= rect.bottom(); ++i) + { + for (int j = rect.left(); j <= rect.right(); ++j) + { + modelIndexList.append((d->m_model->index(i, j))); + } + } + + return modelIndexList; +} + +void GLDTableView::setGridDisplayColWidths() +{ + Q_D(GLDTableView); + + if (d->m_oSuitColWidthCols.size() == 0) + { + return; + } + + bool bShouldResetCommentPosition = false; + + d->calcFixedColSuitWidth(bShouldResetCommentPosition); + d->calcNormalColSuitWidth(bShouldResetCommentPosition); + + if (d->m_columnResizeTimerID == 0) + { + d->m_columnResizeTimerID = startTimer(0); + } + + if (bShouldResetCommentPosition) + { + resetCommentPosition(); + } +} + +void GLDTableView::refreshDisplayRows() +{ + GLDList arrRows; + refreshDisplayRows(arrRows); + rebuildGridRows(arrRows); +} + +void GLDTableView::refreshDisplayColRow() +{ + if (!isVisible()) + { + return; + } + + bindMergeCell(); + + // 自动列宽可能会导致可见列的变化,影响自动行高计算 + setGridDisplayColWidths(); + + setGridDisplayRowHeights(); + + // 合适列宽影响最大,先计算合适列宽 + adjustColWidths(-1); + + refreshDisplayRows(); + resetEllipsisButtonLocation(); +} + +void GLDTableView::refreshDisplayRows(GLDList &arrRows) +{ + Q_D(GLDTableView); + + int nFirstVisualRow = firstVisualRow(); + int nLastVisualRow = lastVisualRow(); + + if (NULL == model() || nLastVisualRow == -1) + { + return; + } + + for (int i = 0; i < d->m_nFixedRowCount; ++i) + { + if (isRowHidden(i)) + { + continue; + } + + QModelIndex modelIndex = model()->index(i, 0); + arrRows.append(dataIndex(modelIndex)); + } + + for (int i = nFirstVisualRow; i <= nLastVisualRow; ++i) + { + if (isRowHidden(i)) + { + continue; + } + + QModelIndex modelIndex = model()->index(i, 0); + arrRows.append(dataIndex(modelIndex)); + } +} + +void GLDTableView::rebuildGridRows(const GLDList &arrRows) +{ + // donothing + G_UNUSED(arrRows) +} + +int GLDTableView::treeCellDisplayHorizontalOffset(int row, int col, bool isOldMinTextHeightCalWay) const +{ + G_UNUSED(isOldMinTextHeightCalWay); + G_UNUSED(row); + G_UNUSED(col); + return 0; +} + +void GLDTableView::doMoveCurrent(const QModelIndex &oldIndex, const QModelIndex &newIndex, + QItemSelectionModel::SelectionFlags command, + MoveReason moveReason) +{ + Q_D(GLDTableView); + GlodonAbstractItemView::doMoveCurrent(oldIndex, newIndex, command, moveReason); + + if (newIndex.isValid() && d->hasSpans()) + { + GSpanCollection::GSpan oSpan = d->span(newIndex.row(), newIndex.column()); + QModelIndex topLeftIndex = newIndex.model()->index(oSpan.top(), oSpan.left(), newIndex.parent()); + QModelIndex bottomRightIndex = newIndex.model()->index(oSpan.bottom(), oSpan.right(), newIndex.parent()); + QItemSelection itemSelection(topLeftIndex, bottomRightIndex); + d->m_selectionModel->select(itemSelection, QItemSelectionModel::SelectCurrent); + } +} + +void GLDTableView::setGridDisplayRowHeights() +{ + Q_D(GLDTableView); + + if (d->m_oSuitRowHeightAccordingCols.size() == 0) + return; + + QList oNeedCalcHeightCols = needCalcSuitRowHeightColsInViewport(); + if (oNeedCalcHeightCols.count() == 0) + return; + + bool bShouldResetCommentPosition = false; + + d->calcFixedRowSuitHeight(oNeedCalcHeightCols, bShouldResetCommentPosition); + d->calcNormalRowSuitHeight(oNeedCalcHeightCols, bShouldResetCommentPosition); + + if (d->m_rowResizeTimerID == 0) + { + d->m_rowResizeTimerID = startTimer(0); + } + + //滚动条滚动的时候,会触发自动行高,但是这时候,如果发生行号的改变,会错误重置备注框的位置 + if (bShouldResetCommentPosition) + { + resetCommentPosition(); + } +} + +// col不为-1时,说明是在调整列宽 +void GLDTableView::adjustColWidths(int currentResizeCol) +{ + Q_D(GLDTableView); + + if (d->m_oFitColWidthCols.size() == 0) + { + return; + } + + d->m_bIsInAdjustFitCols = true; + + d->doAdjustColWidths(currentResizeCol); + + d->m_bIsInAdjustFitCols = false; + + resetCommentPosition(); +} + +int GLDTableView::cellMargin(const QModelIndex &modelIndex, Margin margin) const +{ + switch (margin) + { + case TopMargin: + { + return (model()->data(modelIndex, gidrCellMargin).toInt() & 0x000000FF); + } + + case BottomMargin: + { + return (model()->data(modelIndex, gidrCellMargin).toInt() & 0x0000FF00) >> 8; + } + + case LeftMargin: + { + return (model()->data(modelIndex, gidrCellMargin).toInt() & 0x00FF0000) >> 16; + } + + case RightMargin: + { + return (model()->data(modelIndex, gidrCellMargin).toInt() & 0xFF000000) >> 24; + } + + default: + return 0; + } +} + +void GLDTableView::resetEllipsisButtonLocation() +{ + Q_D(GLDTableView); + + if (d->m_showEllipsisButton && NULL != d->m_ellipsisButton) + { + int nX = d->m_horizontalHeader->length() - d->m_horizontalHeader->offset(); + int nY = d->m_verticalHeader->length() - d->m_verticalHeader->offset(); + + nX = nX - d->m_ellipsisButton->width() + d->m_verticalHeader->drawWidth() + 2; + nY = nY + d->m_horizontalHeader->drawWidth(); + d->m_ellipsisButton->move(nX, nY); + } +} + +GCustomCommentFrame *GLDTableView::findOrCreateCommentFrame(const QModelIndex &index, bool createCommentIfNotFind) +{ + Q_D(GLDTableView); + GCustomCommentFrame *commentFrame = d->m_oCommentFrames.value(index); + + if (NULL == commentFrame && createCommentIfNotFind) + { + commentFrame = new GCustomCommentFrame(viewport(), visualRect(index).topRight()); + + connect(commentFrame, SIGNAL(textChanged(QString)), this, SLOT(writeComment(QString))); + d->m_oCommentFrames.insert(index, commentFrame); + } + + return commentFrame; +} + +int GLDTableView::borderLineWidth(const QVariant& borderLine, bool isRightBorderLine) const +{ + int nBorderLineWidth = currentGridLineWidth(); + + if (borderLine.isValid()) + { + typedef GBorderLineWidthHelper BorderLine; + BorderLine brdLine; + brdLine.widths = borderLine.toInt(); + + if (isRightBorderLine) + { + nBorderLineWidth = brdLine.lineWiths[BorderLine::right]; + } + else + { + nBorderLineWidth = brdLine.lineWiths[BorderLine::bottom]; + } + + return nBorderLineWidth; + } + + return nBorderLineWidth; +} + +int GLDTableView::borderLineSubtractGridLineWidth(const QVariant &boundLine, bool isRightBoundLine) const +{ + Q_D(const GLDTableView); + + if (!d->m_bDrawBoundLine) + return 0; + + int nBorderLineWidth = borderLineWidth(boundLine, isRightBoundLine); + int nGridLineWidth = currentGridLineWidth(); + + // 如果边框线宽度大于格线宽度时,计算边框线的宽度为 边框线宽度 - 格线宽度 + if (d->m_bShowVerticalGridLine && isRightBoundLine) + { + if (nBorderLineWidth >= nGridLineWidth) + { + nBorderLineWidth = nBorderLineWidth - nGridLineWidth; + } + } + else if (d->m_bShowHorizontalGridLine && !isRightBoundLine) + { + if (nBorderLineWidth >= nGridLineWidth) + { + nBorderLineWidth = nBorderLineWidth - nGridLineWidth; + } + } + + return nBorderLineWidth; +} + +void GLDTableView::_q_selectRow(int row) +{ + d_func()->_q_selectRow(row); +} + +void GLDTableView::_q_selectColumn(int column) +{ + d_func()->_q_selectColumn(column); +} + +void GLDTableView::_q_selectRows(int left, int top, int right, int bottom) +{ + d_func()->_q_selectRows(left, top, right, bottom); +} + +void GLDTableView::_q_selectColumns(int left, int top, int right, int bottom) +{ + d_func()->_q_selectColumns(left, top, right, bottom); +} + +void GLDTableView::_q_updateSpanInsertedRows(const QModelIndex &parent, int start, int end) +{ + d_func()->_q_updateSpanInsertedRows(parent, start, end); + resetEllipsisButtonLocation(); + resetCommentPosition(); +} + +void GLDTableView::_q_updateSpanInsertedColumns(const QModelIndex &parent, int start, int end) +{ + d_func()->_q_updateSpanInsertedColumns(parent, start, end); + resetEllipsisButtonLocation(); + resetCommentPosition(); +} + +void GLDTableView::_q_updateSpanRemovedRows(const QModelIndex &parent, int start, int end) +{ + d_func()->_q_updateSpanRemovedRows(parent, start, end); + resetEllipsisButtonLocation(); + resetCommentPosition(); +} + +void GLDTableView::_q_updateSpanRemovedColumns(const QModelIndex &parent, int start, int end) +{ + d_func()->_q_updateSpanRemovedColumns(parent, start, end); + resetEllipsisButtonLocation(); +// resetCommentPosition(); +} + +void GLDTableView::writeComment(const QString &value) +{ + Q_D(GLDTableView); + GCustomCommentFrame *pCurrentFrame = dynamic_cast(QObject::sender()); + d->m_model->setData(d->m_oCommentFrames.key(pCurrentFrame), value, gidrCommentRole); +} + +void GLDTableView::onDrawComment(const QModelIndex &index, bool &canShow) +{ + GCustomCommentFrame *pCommentFrame = findOrCreateCommentFrame(index, false); + + if (NULL != pCommentFrame && pCommentFrame->isVisible()) + { + canShow = false; + } +} + +void GLDTableView::setCommentsUpdatesEnabled(bool enable) +{ + Q_D(GLDTableView); + QMap::iterator it = d->m_oCommentFrames.begin(); + + while (it != d->m_oCommentFrames.end()) + { + it.value()->setUpdatesEnabled(enable); + ++it; + } + + if (enable) + { + resetCommentPosition(); + } +} + +bool GLDTableView::closeEditorOnFocusOut() +{ + Q_D(GLDTableView); + return d->m_bCloseEditorOnFocusOut; +} + +void GLDTableView::setCloseEditorOnFocusOut(bool value, bool ignoreActiveWindowFocusReason) +{ + Q_D(GLDTableView); + + if (d->m_bCloseEditorOnFocusOut != value) + { + d->m_itemDelegate.data()->setCloseEditorOnFocusOut(value, ignoreActiveWindowFocusReason); + d->m_bCloseEditorOnFocusOut = value; + d->m_ignoreActiveWindowFocusReason = ignoreActiveWindowFocusReason; + } +} + +void GLDTableView::setUseComboBoxCompleter(bool value) +{ + Q_D(GLDTableView); + + if (d->m_bUseComboBoxCompleter != value) + { + d->m_itemDelegate.data()->setUseComboBoxCompleter(value); + d->m_bUseComboBoxCompleter = value; + } +} + +bool GLDTableView::useComboBoxCompleter() const +{ + Q_D(const GLDTableView); + return d->m_bUseComboBoxCompleter; +} + +void GLDTableView::resetCommentPosition(bool isMove, int dx, int dy) +{ + Q_D(GLDTableView); + + if (d->m_bIsInReset) + return; + + QMap::iterator it = d->m_oCommentFrames.begin(); + + while (it != d->m_oCommentFrames.end()) + { + if (isMove) + { + it.value()->move(it.value()->pos().x() + dx, it.value()->pos().y() + dy); + } + else + { + QPoint point = visualRect(it.key()).topRight(); + it.value()->moveTo(point); + } + + ++it; + } +} + +void GLDTableView::setResizeDelay(bool delay) +{ + Q_D(GLDTableView); + d->m_verticalHeader->setResizeDelay(delay); + d->m_horizontalHeader->setResizeDelay(delay); +} + +void GLDTableView::setAllowRangeMoving(bool value) +{ + Q_D(GLDTableView); + + d->m_bRangeMoving = value; +} + +bool GLDTableView::allowRangeMoving() const +{ + Q_D(const GLDTableView); + return d->m_bRangeMoving; +} + +QModelIndex GLDTableView::logicalIndex(QModelIndex visualIndex) +{ + Q_D(GLDTableView); + return d->m_model->index(d->logicalRow(visualIndex.row()), + d->logicalColumn(visualIndex.column()), visualIndex.parent()); +} + +QModelIndex GLDTableView::visualIndex(const QModelIndex &logicalIndex) +{ + Q_D(GLDTableView); + return d->m_model->index(d->visualRow(logicalIndex.row()), + d->visualColumn(logicalIndex.column()), logicalIndex.parent()); +} + +void GLDTableView::updateModelIndex(const QModelIndex &logicIndex) +{ + update(logicIndex); +} + +void GLDTableView::update(const QModelIndex &logicalIndex) +{ + Q_D(GLDTableView); + + if (!logicalIndex.isValid()) + { + return; + } + + // 非编辑状态,显示当前行、当前列编辑方式,需要刷新整行整列 + QRect oUpdateRect; + switch (d->m_editStyleDrawType) + { + + case GlodonAbstractItemView::SdtCurrentRow: + oUpdateRect = QRect(0, + d->m_verticalHeader->sectionViewportPosition(logicalIndex.row()), + viewport()->width(), + rowHeight(logicalIndex.row())); + break; + case GlodonAbstractItemView::SdtCurrentCol: + oUpdateRect = QRect(d->m_horizontalHeader->sectionViewportPosition(logicalIndex.column()), + 0, + columnWidth(logicalIndex.column()), + viewport()->width()); + break; + + case GlodonAbstractItemView::SdtAll: + oUpdateRect = viewport()->rect(); + break; + case GlodonAbstractItemView::SdtCurrentCell: + default: + oUpdateRect = visualRect(logicalIndex); + break; + } + + const QRect c_rect = oUpdateRect.adjusted(-3, -3, 3, 3); + if (d->viewport->rect().intersects(c_rect)) + { + d->viewport->update(c_rect); + } +} + +void GLDTableView::updateCol(int col) +{ + Q_D(GLDTableView); + d->viewport->update(columnVisualPosition(col), 0, columnWidth(col), d->m_verticalHeader->height()); + + if (GlodonMultiHeaderView *horizonHeader = dynamic_cast(d->m_horizontalHeader)) + { + horizonHeader->updateSpan(col); + } + else + { + d->m_horizontalHeader->updateSection(col); + } +} + +void GLDTableView::updateRow(int row) +{ + Q_D(GLDTableView); + d->viewport->update(0, rowVisualPosition(row), d->m_horizontalHeader->width(), rowHeight(row)); + + if (GlodonMultiHeaderView *verticalHeader = dynamic_cast(d->m_verticalHeader)) + { + verticalHeader->updateSpan(row); + } + else + { + d->m_verticalHeader->updateSection(row); + } +} + +void GLDTableView::updateAll() +{ + Q_D(GLDTableView); + d->viewport->update(); + + if (GlodonMultiHeaderView *verticalHeader = dynamic_cast(d->m_verticalHeader)) + { + verticalHeader->resetSpan(); + } + else + { + d->m_verticalHeader->viewport()->update(); + } + + if (GlodonMultiHeaderView *horizonHeader = dynamic_cast(d->m_horizontalHeader)) + { + horizonHeader->resetSpan(); + } + else + { + d->m_verticalHeader->viewport()->update(); + } +} + +void GLDTableView::updateHeaderView(const UpdateHeaderViewType updateType) +{ + Q_D(GLDTableView); + + switch (updateType) + { + case uhVertical: + { + d->m_verticalHeader->viewport()->update(); + break; + } + + case uhHorizontal: + { + d->m_horizontalHeader->viewport()->update(); + break; + } + + case uhBoth: + { + d->m_verticalHeader->viewport()->update(); + d->m_horizontalHeader->viewport()->update(); + break; + } + + default: + { + } + } +} + +QModelIndex GLDTableView::treeIndex(const QModelIndex &index) const +{ + return index; +} + +QModelIndex GLDTableView::dataIndex(const QModelIndex &index) const +{ + return index; +} + +GString GLDTableView::copyTextFromSelections(bool *bCanCopyText) +{ + Q_D(GLDTableView); + + if (!d->m_model || 0 == selectionModel()->selection().size()) + { + return GString(); + } + + QModelIndexList indexList = selectionModel()->selectedIndexes(); + qSort(indexList.begin(), indexList.end()); + + bool bCanCopy = checkSelectionCopyEnable(indexList); + + if (bCanCopyText) + { + bCanCopyText = &bCanCopy; + } + + if (!bCanCopy) + { + return ""; + } + + GString result = getContentsFromOrderedIndexList(indexList); + + if (result.length() > 0) + { + QApplication::clipboard()->clear(); + QApplication::clipboard()->setText(result); + } + + return result; +} + +bool GLDTableView::pasteFromClipboard() +{ + Q_D(GLDTableView); + + if (!d->m_model || 1 != selectionModel()->selection().size()) + { + return false; + } + + GString sClipBoardText = QApplication::clipboard()->text(); + + if (sClipBoardText.length() == 0) + { + return false; + } + + QModelIndexList indexList = selectionModel()->selectedIndexes(); + qSort(indexList.begin(), indexList.end()); + + int nPasteRowCount = 0; + int nPasteColCount = 0; + + fillCellsOnClipBoardText(indexList, sClipBoardText, nPasteRowCount, nPasteColCount); + + setNewSelection(indexList, nPasteRowCount, nPasteColCount); + + return true; +} + + +GlodonScrollBar::GlodonScrollBar(QWidget *parent) : QScrollBar(parent), + m_pParent(parent) +{ + +} + +GlodonScrollBar::GlodonScrollBar(Qt::Orientation orientation, QWidget *parent) + : QScrollBar(orientation, parent), + m_pParent(parent) +{ + +} + +void GlodonScrollBar::enterEvent(QEvent *event) +{ + QScrollBar::enterEvent(event); + bool bHasCursor = m_pParent->testAttribute(Qt::WA_SetCursor); + if (bHasCursor) + { + m_pParent->unsetCursor(); + } +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDTextEdit.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDTextEdit.cpp new file mode 100644 index 00000000..e7e0e78b --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDTextEdit.cpp @@ -0,0 +1,165 @@ +#include "GLDWindowComboBoxEx.h" + +#include +#include +#include + +#include "GLDTextEdit.h" +#include "GLDFileUtils.h" + +const GString c_sLineEditQssFile = ":/qsses/GLDCustomLineEdit.qss"; +const GString c_sPlainTextEditQssFile = ":/qsses/GLDPlainTextEditEx.qss"; + +GLDPlainTextEdit::GLDPlainTextEdit(QWidget *parent) : + QPlainTextEdit(parent) +{ + m_isFouseKeepInLineEdit = false; + setContentsMargins(0, 0, 0, 0); + document()->setDocumentMargin(0); + connect(this, SIGNAL(textChanged()), this, SLOT(onTextChanged())); +} + +bool GLDPlainTextEdit::hasSelectedText() +{ + return textCursor().hasSelection(); +} + +QString GLDPlainTextEdit::text() +{ + return toPlainText(); +} + +void GLDPlainTextEdit::setText(QString text) +{ + setPlainText(text); +} + +QString GLDPlainTextEdit::placeholderText() const +{ + return m_placeholderText; +} + +void GLDPlainTextEdit::setPlaceholderText(const QString &placeholderText) +{ + if (m_placeholderText != placeholderText) { + m_placeholderText = placeholderText; + if (!hasFocus()) + update(); + } +} + +void GLDPlainTextEdit::mousePressEvent(QMouseEvent *e) +{ + QPlainTextEdit::mousePressEvent(e); + e->accept(); + GLDWindowComboBoxEx *combox = dynamic_cast(parentWidget()); + if (NULL == combox) + { + return; + } + + else if (!combox->isHidePopupOnEdit()) + { + if (e->buttons() & Qt::LeftButton) + { + combox->showPopup(); + } + } +} + +void GLDPlainTextEdit::paintEvent(QPaintEvent *e) +{ + QPlainTextEdit::paintEvent(e); + QPainter p(viewport()); + QPalette pal = palette(); + + QFontMetrics fm = fontMetrics(); + int nLeft, nRight, nBottom, nTop = 0; + getContentsMargins(&nLeft, &nTop, &nRight, &nBottom); + + QRect r = rect(); + + int minLB = qMax(0, - fm.minLeftBearing()); + + QRect lineRect(cursorRect().left(), cursorRect().top(), r.width() - nLeft - nRight, cursorRect().height()); + + if (document()->toPlainText().isEmpty()) { + if (!m_placeholderText.isEmpty()) { + QColor col = pal.text().color(); + col.setAlpha(128); + QPen oldpen = p.pen(); + p.setPen(col); + QRect ph = lineRect.adjusted(minLB, 0, 0, 0); + QString elidedText = fm.elidedText(m_placeholderText, Qt::ElideRight, ph.width()); + p.drawText(ph, Qt::AlignVCenter | Qt::AlignLeft, elidedText); + p.setPen(oldpen); + } + } + if (m_isFouseKeepInLineEdit) + { + setFocus(); + } +} + +void GLDPlainTextEdit::deleteSelectedText() +{ + textCursor().removeSelectedText();} + +void GLDPlainTextEdit::onTextChanged() +{ + if (m_text == toPlainText()) + { + return; + } + else + { + m_text = toPlainText(); + emit textChanged(m_text); + } +} + +GLDCustomLineEdit::GLDCustomLineEdit(QWidget *parent) : + QLineEdit(parent), + m_hasBorder(true) +{ + this->setStyleSheet(loadQssFile(c_sLineEditQssFile)); +} + +void GLDCustomLineEdit::setHasBorder(bool bValue) +{ + if (bValue != m_hasBorder) + { + m_hasBorder = bValue; + } + + if (!m_hasBorder) + { + setProperty("border", "noBorder"); + } + this->setStyleSheet(loadQssFile(c_sLineEditQssFile)); +} + +void GLDCustomLineEdit::deleteSelectedText() +{ + if (hasSelectedText()) + this->del(); +} + +void GLDPlainTextEdit::forceSelectColorToBlue() +{ + QPalette palette = this->palette(); + palette.setColor(QPalette::Highlight, QColor(70, 150, 255)); + palette.setColor(QPalette::HighlightedText, QColor(255, 255, 255)); + setPalette(palette); +} + +void GLDPlainTextEdit::setFouseIsKeepInLineEdit(bool isAddFouseSetting) +{ + m_isFouseKeepInLineEdit = isAddFouseSetting; +} + +GLDPlainTextEditEx::GLDPlainTextEditEx(QWidget *parent) : + GLDPlainTextEdit(parent) +{ + this->setStyleSheet(loadQssFile(c_sPlainTextEditQssFile)); +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDToolBox.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDToolBox.cpp new file mode 100644 index 00000000..6a93e84e --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDToolBox.cpp @@ -0,0 +1,1421 @@ +#include "GLDToolBox.h" + +#include +#include +#include +#include +#include +#include + +#include "GLDWidget_Global.h" +#include "GLDFileUtils.h" +#include "GLDException.h" + +//const int c_nMargin = 1; +//const int c_nToolBoxNavigatorWidth = 250; +const int c_nToolBoxButtonHeight = 32; +const int c_nLayOutMargin = 1; +class GLDToolBoxTreeItem; + +const GString c_sToolBoxQssFile = ":/qsses/GLDToolBox.qss"; + +/* GLDToolBoxButton */ +GLDToolBoxButton::GLDToolBoxButton(QWidget *parent) + : QAbstractButton(parent), m_bSelected(false), m_nIndexInPage(-1) +{ + setFixedHeight(c_nToolBoxButtonHeight); + setBackgroundRole(QPalette::Window); + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); + setFocusPolicy(Qt::NoFocus); +} + +QSize GLDToolBoxButton::sizeHint() const +{ + QSize iconSize(8, 8); + if (!icon().isNull()) + { + int ncone = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, parentWidget() /* GLDToolBox */); + iconSize += QSize(ncone + 2, ncone); + } + QSize textSize = fontMetrics().size(Qt::TextShowMnemonic, text()) + QSize(0, 8); + + QSize total(iconSize.width() + textSize.width(), qMax(iconSize.height(), textSize.height())); + return total.expandedTo(QApplication::globalStrut()); +} + +QSize GLDToolBoxButton::minimumSizeHint() const +{ + if (icon().isNull()) + { + return QSize(); + } + int ncone = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, parentWidget() /* GLDToolBox */); + return QSize(ncone + 8, ncone + 8); +} + +void GLDToolBoxButton::initStyleOption(QStyleOptionToolBox *option) const +{ + if (!option) + { + return; + } + option->initFrom(this); + if (m_bSelected) + { + option->state |= QStyle::State_Selected; + } + if (isDown()) + { + option->state |= QStyle::State_Sunken; + } + option->text = text(); + option->icon = icon(); + + if (QStyleOptionToolBoxV2 *optionV2 = qstyleoption_cast(option)) + { + GLDToolBox *toolBox = static_cast(parentWidget()); // I know I'm in a tool box. + int nWidgetsCount = toolBox->count(); + int nCurrIndex = toolBox->currentIndex(); + if (nWidgetsCount == 1) + { + optionV2->position = QStyleOptionToolBoxV2::OnlyOneTab; + } + else if (m_nIndexInPage == 0) + { + optionV2->position = QStyleOptionToolBoxV2::Beginning; + } + else if (m_nIndexInPage == nWidgetsCount - 1) + { + optionV2->position = QStyleOptionToolBoxV2::End; + } + else + { + optionV2->position = QStyleOptionToolBoxV2::Middle; + } + if (nCurrIndex == m_nIndexInPage - 1) + { + optionV2->selectedPosition = QStyleOptionToolBoxV2::PreviousIsSelected; + } + else if (nCurrIndex == m_nIndexInPage + 1) + { + optionV2->selectedPosition = QStyleOptionToolBoxV2::NextIsSelected; + } + else + { + optionV2->selectedPosition = QStyleOptionToolBoxV2::NotAdjacent; + } + } +} + +void GLDToolBoxButton::paintEvent(QPaintEvent *) +{ + QPainter paint(this); +// QString text = QAbstractButton::text(); + QPainter *painter = &paint; + QStyleOptionToolBoxV2 opt; + initStyleOption(&opt); + style()->drawControl(QStyle::CE_ToolBoxTab, &opt, painter, parentWidget()); +} + +/* GLDIconList */ +GLDIconList::GLDIconList(const QIcon &icon) + : QList() +{ + append(icon); +} + +GLDIconList::GLDIconList() + : QList() +{ +} + +class GLDTreeWidgetItem : public QTreeWidgetItem +{ +public: + explicit GLDTreeWidgetItem(const QStringList &strings, GLDToolBoxTreeItem *owner, int type = Type); + ~GLDTreeWidgetItem(); +public: + GLDTreeWidgetItem* insertItem(int index, const GLDIconList &icon, const QStringList &text); + GLDTreeWidgetItem* insertItem(int index, const QStringList &text); + GLDTreeWidgetItem* addItem(const GLDIconList &icon, const QStringList &text); + GLDTreeWidgetItem* addItem(const QStringList &text); + GLDTreeWidgetItem *childItem(int index) const; + GLDToolBoxTreeItem *owner() const { return m_owner; } + +private: + GLDToolBoxTreeItem *m_owner; +}; + +/* GLDTreeWidgetItem */ +GLDTreeWidgetItem::GLDTreeWidgetItem(const QStringList &strings, GLDToolBoxTreeItem *owner, int type) + : QTreeWidgetItem(strings, type), m_owner(owner) +{ + +} + +GLDTreeWidgetItem::~GLDTreeWidgetItem() +{ + +} + +GLDTreeWidgetItem *GLDTreeWidgetItem::insertItem(int index, const GLDIconList &icon, const QStringList &text) +{ + assert(icon.count() <= text.count()); + GLDTreeWidgetItem *item = new GLDTreeWidgetItem(text, m_owner); + for (int i = 0; i < icon.count(); ++i) + { + item->setIcon(i, icon.at(i)); + } + if ((index < 0) || (index > childCount())) + { + addChild(item); + } + else + { + insertChild(index, item); + } + return item; +} + +GLDTreeWidgetItem *GLDTreeWidgetItem::insertItem(int index, const QStringList &text) +{ + return insertItem(index, GLDIconList(QIcon()), text); +} + +GLDTreeWidgetItem *GLDTreeWidgetItem::addItem(const GLDIconList &icon, const QStringList &text) +{ + return insertItem(-1, icon, text); +} + +GLDTreeWidgetItem *GLDTreeWidgetItem::addItem(const QStringList &text) +{ + return insertItem(-1, GLDIconList(QIcon()), text); +} + +GLDTreeWidgetItem *GLDTreeWidgetItem::childItem(int index) const +{ + QTreeWidgetItem *item = child(index); + if (item) + { + return dynamic_cast(item); + } + return NULL; +} + +/* GLDToolBoxItem */ +GLDToolBoxItem::GLDToolBoxItem(GLDToolBox *toolBox, GLDToolBoxItem *parent) + : m_toolBox(toolBox), m_parent(parent), m_name(""), m_tag(0) +{ + +} + +GLDToolBoxItem::~GLDToolBoxItem() +{ + +} + +GLDToolBoxItem *GLDToolBoxItem::insertItem(int index, const QString &text, const QIcon &icon) +{ + GLDToolBoxItem *item = createItem(); + item->setText(text); + item->setIcon(icon); + if ((index < 0) || (index > m_items.count())) + { + m_items.append(item); + } + else + { + m_items.insert(index, item); + } + return item; +} + +void GLDToolBoxItem::updateItem(int index, const QString &text, const QIcon &icon) +{ + if ((index < 0) || (index >= m_items.count())) + { + return; + } + else + { + setText(index, text); + setIcon(index, icon); + } +} + +void GLDToolBoxItem::deleteItem(int index) +{ + if ((index < 0) || (index >= m_items.count())) + { + return; + } + m_items.Delete(index); +} + +void GLDToolBoxItem::removeItem(GLDToolBoxItem *item) +{ + m_items.remove(item); + freeAndNil(item); +} + +void GLDToolBoxItem::setText(int index, const QString &text) +{ + if ((index < 0) || (index >= m_items.count())) + { + return; + } + items(index)->setText(text); + if ((int)ListWidget == (int)this->header()->itemMode()) + { + header()->listWidget()->item(index)->setText(text); + } + else if ((int)TreeWidget == (int)this->header()->itemMode()) + { + GLDToolBoxTreeItem *pTreeItem = dynamic_cast(this); + if (NULL != pTreeItem) + { + pTreeItem->item()->child(index)->setText(0, text); + } + else + { + header()->treeWidget()->topLevelItem(index)->setText(0, text); + } + } +} + +void GLDToolBoxItem::setIcon(int index, const QIcon &icon) +{ + if ((index < 0) || (index >= m_items.count())) + { + return; + } + items(index)->setIcon(icon); + if ((int)ListWidget == (int)this->header()->itemMode()) + { + header()->listWidget()->item(index)->setIcon(icon); + } + else if ((int)TreeWidget == (int)this->header()->itemMode()) + { + GLDToolBoxTreeItem *pTreeItem = dynamic_cast(this); + if (NULL != pTreeItem) + { + pTreeItem->item()->child(index)->setIcon(0, icon); + } + else + { + header()->treeWidget()->topLevelItem(index)->setIcon(0, icon); + } + } +} + +GLDToolBoxItem *GLDToolBoxItem::items(int index) const +{ + if ((index < 0) || (index >= count())) + { + return NULL; + } + return m_items[index]; +} + +GLDToolBoxHeader *GLDToolBoxItem::header() +{ + GLDToolBoxItem *item = this; + GLDToolBoxType toolBoxType = item->type(); + while ((toolBoxType != gtbtHeader) && (item->parent() != NULL)) + { + item = item->parent(); + toolBoxType = item->type(); + } + return dynamic_cast(item); +} + +void GLDToolBoxItem::clearItems() +{ + for (int i = m_items.count() - 1; i >= 0; --i) + { + deleteItem(i); + } +} + +/* GLDToolBoxListItem */ +class GLDToolBoxListItem : public GLDToolBoxItem +{ +public: + explicit GLDToolBoxListItem(GLDToolBox *toolBox, GLDToolBoxItem *parent); + ~GLDToolBoxListItem(); + GLDToolBoxItem *insertItem(int index, const QString &text, const QIcon &icon = QIcon()); + GLDToolBoxType type() const; + void deleteItem(int index); + void removeItem(GLDToolBoxItem *item); + + QListWidgetItem *item() { return m_item; } + +protected: + GLDToolBoxItem *createItem(); +private: + QListWidgetItem *m_item; +}; + +GLDToolBoxListItem::GLDToolBoxListItem(GLDToolBox *toolBox, GLDToolBoxItem *parent) + : GLDToolBoxItem(toolBox, parent), m_item(new QListWidgetItem()) +{ + +} + +GLDToolBoxListItem::~GLDToolBoxListItem() +{ +} + +GLDToolBoxItem *GLDToolBoxListItem::insertItem(int index, const QString &text, const QIcon &icon) +{ + assert(false); + return NULL; + G_UNUSED(index); + G_UNUSED(text); + G_UNUSED(icon); +} + +GLDToolBoxType GLDToolBoxListItem::type() const +{ + return gtbtItem; +} + +void GLDToolBoxListItem::deleteItem(int index) +{ + assert(false); + G_UNUSED(index) +} + +void GLDToolBoxListItem::removeItem(GLDToolBoxItem *item) +{ + assert(false); + G_UNUSED(item) +} + +GLDToolBoxItem *GLDToolBoxListItem::createItem() +{ + assert(false); + return NULL; +} + +/* GLDToolBoxTreeItem */ +GLDToolBoxTreeItem::GLDToolBoxTreeItem(GLDToolBox *toolBox, GLDToolBoxItem *parent) + : GLDToolBoxItem(toolBox, parent), m_item(new GLDTreeWidgetItem(QStringList(""), this)) +{ + +} + +GLDToolBoxTreeItem::~GLDToolBoxTreeItem() +{ + +} + +GLDToolBoxItem *GLDToolBoxTreeItem::insertItem(int index, const QString &text, const QIcon &icon) +{ + GLDToolBoxTreeItem *result = (GLDToolBoxTreeItem *)GLDToolBoxItem::insertItem(index, text); + GLDTreeWidgetItem *item = result->item(); + item->setText(0, text); + item->setIcon(0, icon); + if ((index < 0) || (index >= m_item->childCount())) + { + m_item->addChild(item); + } + else + { + m_item->insertChild(index, item); + } + + return result; +} + +GLDToolBoxType GLDToolBoxTreeItem::type() const +{ + return gtbtItem; +} + +void GLDToolBoxTreeItem::deleteItem(int index) +{ + QTreeWidgetItem *item = m_item->takeChild(index); + if (item) + { + freeAndNil(item); + GLDToolBoxItem::deleteItem(index); + } +} + +void GLDToolBoxTreeItem::removeItem(GLDToolBoxItem *item) +{ + QTreeWidgetItem *removeItem + = m_item->takeChild(m_item->indexOfChild((dynamic_cast(item)->item()))); + if (removeItem) + { + freeAndNil(removeItem); + GLDToolBoxItem::removeItem(item); + } +} + +GLDToolBoxItem *GLDToolBoxTreeItem::createItem() +{ + return new GLDToolBoxTreeItem(toolBox(), this); +} + +/* GLDToolBoxHeader */ +GLDToolBoxHeader::GLDToolBoxHeader(GLDToolBox *toolBox, GLDToolBoxItem *parent) + : GLDToolBoxItem(toolBox, parent), m_button(NULL), m_sv(NULL), m_widget(NULL), + m_itemMode(TreeWidget), m_useOwnWidget(false) +{ + +} + +GLDToolBoxHeader::~GLDToolBoxHeader() +{ +} + +void GLDToolBoxHeader::deleteItem(int index) +{ + checkCanUseThisMethod(); + switch (m_itemMode) + { + case ListWidget: + { + QListWidget *listWidget = dynamic_cast(m_widget); + QListWidgetItem *item = listWidget->takeItem(index); + freeAndNil(item); + break; + } + case TreeWidget: + { + QTreeWidget *treeWidget = dynamic_cast(m_widget); + QTreeWidgetItem *item = treeWidget->takeTopLevelItem(index); + freeAndNil(item); + break; + } + default: + break; + } + GLDToolBoxItem::deleteItem(index); +} + +void GLDToolBoxHeader::removeItem(GLDToolBoxItem *item) +{ + checkCanUseThisMethod(); + switch (m_itemMode) + { + case ListWidget: + { + QListWidget *listWidget = dynamic_cast(m_widget); + QListWidgetItem *deleteItem = listWidget->takeItem(listWidget->row(((GLDToolBoxListItem*)(item))->item())); + freeAndNil(deleteItem); + break; + } + case TreeWidget: + { + QTreeWidget *treeWidget = dynamic_cast(m_widget); + QTreeWidgetItem *deleteItem + = treeWidget->takeTopLevelItem(treeWidget->indexOfTopLevelItem(((GLDToolBoxTreeItem*)(item))->item())); + freeAndNil(deleteItem); + break; + } + default: + break; + } + GLDToolBoxItem::removeItem(item); +} + +void GLDToolBoxHeader::setWidget(QWidget *value) +{ + if (m_widget) + { + assert(false); // 不允许重新赋值 + } + else + { + if (dynamic_cast(value)) + { + m_itemMode = ListWidget; + } + else if (dynamic_cast(value)) + { + m_itemMode = TreeWidget; + } + m_widget = value; + } +} + +#ifndef QT_NO_TOOLTIP +void GLDToolBoxHeader::setToolTip(const QString &tip) +{ + m_button->setToolTip(tip); +} + +QString GLDToolBoxHeader::toolTip() const +{ + return m_button->toolTip(); +} + +#endif + +GLDToolBoxItem *GLDToolBoxHeader::insertItem(int index, const QString &text, const QIcon &icon) +{ + checkCanUseThisMethod(); + switch (m_itemMode) + { + case ListWidget: + { + QListWidget *listWidget = dynamic_cast(m_widget); + if (listWidget) + { + GLDToolBoxListItem *result = (GLDToolBoxListItem *)GLDToolBoxItem::insertItem(index, text, icon); + result->item()->setText(text); + result->item()->setIcon(icon); + if ((index < 0) || (index >= listWidget->count())) + { + listWidget->addItem(result->item()); + } + else + { + listWidget->insertItem(index, result->item()); + } + return result; + } + break; + } + case TreeWidget: + { + return insertItem(index, GLDIconList(icon), QStringList(text)); + } + default: + assert(false); + break; + } + return NULL; +} + +GLDToolBoxType GLDToolBoxHeader::type() const +{ + return gtbtHeader; +} + +void GLDToolBoxHeader::setCurrentItem(GLDToolBoxItem *item) +{ + switch (m_itemMode) + { + case ListWidget: + listWidget()->setCurrentItem(dynamic_cast(item)->item()); + break; + case TreeWidget: + treeWidget()->setCurrentItem(dynamic_cast(item)->item()); + break; + default: + break; + } +} + +GLDToolBoxItem *GLDToolBoxHeader::createItem() +{ + checkCanUseThisMethod(); + switch (m_itemMode) + { + case ListWidget: + return new GLDToolBoxListItem(toolBox(), this); + case TreeWidget: + return new GLDToolBoxTreeItem(toolBox(), this); + default: + assert(false); + break; + } + return NULL; +} + +void GLDToolBoxHeader::checkCanUseThisMethod() +{ + if (m_useOwnWidget) + { + gldError(tr("Custom widget classes should not invode this function"));//TRANS_STRING("自定义widget不能调用此方法")); + } +} + +GLDToolBoxItem *GLDToolBoxHeader::insertItem(int index, const QIcon &icon, const QString &text) +{ + return insertItem(index, text, icon); +} + +//GLDToolBoxItem *GLDToolBoxHeader::insertItem(int index, const QString &text) +//{ +// return insertItem(index, QIcon(), text); +//} + +GLDToolBoxItem *GLDToolBoxHeader::addItem(const QIcon &icon, const QString &text) +{ + return insertItem(-1, icon, text); +} + +GLDToolBoxItem *GLDToolBoxHeader::addItem(const QString &text) +{ + return insertItem(-1, QIcon(), text); +} + +GLDToolBoxItem *GLDToolBoxHeader::insertItem(int index, const GLDIconList &icon, const QStringList &text) +{ + checkCanUseThisMethod(); + switch (m_itemMode) + { + case ListWidget: + { + return insertItem(index, icon.at(0), text.at(0)); + } + case TreeWidget: + { + assert(icon.count() <= text.count()); + QTreeWidget *treeWidget = dynamic_cast(m_widget); + if (treeWidget) + { + GLDToolBoxTreeItem *result + = (GLDToolBoxTreeItem *)GLDToolBoxItem::insertItem(index, text.at(0), icon.at(0)); + result->item()->setText(0, text.at(0)); + result->item()->setIcon(0, icon.at(0)); + // GLDTreeWidgetItem *item = new GLDTreeWidgetItem(QStringList(text)); + // for (int i = 0; i < icon.count(); ++i) + // { + // result->setIcon(i, icon.at(i)); + // } + int nChildCount = treeWidget->topLevelItemCount(); + if ((index < 0) || (index >= nChildCount)) + { + treeWidget->addTopLevelItem(result->item()); + index = nChildCount; + } + else + { + treeWidget->insertTopLevelItem(index, result->item()); + } + // // 增加头的列数 + // for (int i = 0; i < text.count(); ++i) + // { + // treeWidget->headerItem()->setText(i, "header"); + // } + return result; + } + break; + } + default: + assert(false); + break; + } + return 0; +} + +GLDToolBoxItem *GLDToolBoxHeader::insertItem(int index, const QStringList &text) +{ + return insertItem(index, GLDIconList(QIcon()), text); +} + +GLDToolBoxItem *GLDToolBoxHeader::addItem(const GLDIconList &icon, const QStringList &text) +{ + return insertItem(-1, icon, text); +} + +GLDToolBoxItem *GLDToolBoxHeader::addItem(const QStringList &text) +{ + return insertItem(-1, GLDIconList(QIcon()), text); +} + +bool GLDToolBoxHeader::useOwnWidget() const +{ + return m_useOwnWidget; +} + +void GLDToolBoxHeader::setUseOwnWidget(bool useOwnWidget) +{ + m_useOwnWidget = useOwnWidget; +} + +//GLDTreeWidgetItem *GLDToolBoxHeader::treeWidgetItem(int index) +//{ +// QTreeWidget *treeWidget = dynamic_cast(m_widget); +// if (treeWidget) +// { +// int nChildCount = treeWidget->topLevelItemCount(); +// if ((index < 0) || (index >= nChildCount)) +// { +// return NULL; +// } +// GLDTreeWidgetItem *item = dynamic_cast(treeWidget->topLevelItem(index)); +// return item; +// } +// return NULL; +//} + +void GLDToolBoxHeader::setViewMode(QListView::ViewMode value) +{ + checkCanUseThisMethod(); + switch (m_itemMode) + { + case ListWidget: + { + QListWidget *listWidget = dynamic_cast(m_widget); + if (listWidget) + { + listWidget->setViewMode(value); + listWidget->setDragEnabled(false); + } + break; + } + case TreeWidget: + assert(false); + break; + default: + assert(false); + break; + } +} + +void GLDToolBoxHeader::expandAll() +{ + checkCanUseThisMethod(); + switch (m_itemMode) + { + case ListWidget: + break; + case TreeWidget: + dynamic_cast(m_widget)->expandAll(); + break; + default: + assert(false); + break; + } +} + +GLDToolBoxItem *GLDToolBoxHeader::find(QListWidgetItem *value) +{ + if (!value) + { + return NULL; + } + QListWidget *widget = listWidget(); + if (widget && (widget == value->listWidget())) + { + for (int i = 0; i < widget->count(); ++i) + { + if (widget->item(i) == value) + { + return items(i); + } + } + } + return NULL; +} + +/* GLDToolBox */ +GLDToolBox::GLDToolBox(QWidget *parent) + : QScrollArea(parent), m_currentListWidgetItem(NULL), m_currentTreeWidgetItem(NULL), + m_itemMode(TreeWidget), m_pCurrentPage(0), m_useOwnWidget(true) +{ + //setFixedWidth(nToolBoxNavigatorWidth + nMargin + 2); + setFrameShape(QScrollArea::NoFrame); + m_layout = new QVBoxLayout(this); + m_layout->setMargin(0); + m_layout->setSpacing(0); + m_layout->setContentsMargins(0, 0, 0, 0); + setBackgroundRole(QPalette::Button); + this->setStyleSheet(loadQssFile(c_sToolBoxQssFile)); +} + +GLDToolBox::~GLDToolBox() +{ + +} + +GLDToolBoxHeader *GLDToolBox::page(QWidget *widget) const +{ + if (!widget) + { + return NULL; + } + + for (int i = 0; i < m_pageList.count(); ++i) + { + if (m_pageList.at(i)->widget() == widget) + { + return m_pageList.at(i); + } + } + + return NULL; +} + +GLDToolBoxHeader *GLDToolBox::page(int index) +{ + if (index >= 0 && index < m_pageList.count()) + { + return m_pageList[index]; + } + return NULL; +} + +GLDToolBoxHeader *GLDToolBox::page(const GString &name) +{ + for (int i = 0; i < m_pageList.count(); ++i) + { + if (compareText(name, m_pageList.at(i)->name()) == 0) + { + return m_pageList[i]; + } + } + return NULL; +} + +const GLDToolBoxHeader *GLDToolBox::page(int index) const +{ + if (index >= 0 && index < m_pageList.count()) + { + return m_pageList.at(index); + } + return NULL; +} + +void GLDToolBox::updateTabs() +{ + GLDToolBoxButton *lastButton = m_pCurrentPage ? m_pCurrentPage->button() : 0; + bool bAfter = false; + int nindex = 0; + for (nindex = 0; nindex < m_pageList.count(); ++nindex) + { + const GLDToolBoxHeader *page = m_pageList.at(nindex); + GLDToolBoxButton *tB = page->button(); + // update indexes, since the updates are delayed, the indexes will be correct + // when we actually paint. + tB->setIndex(nindex); + QWidget *tW = page->widget(); + if (bAfter) + { + QPalette palette = tB->palette(); + palette.setColor(tB->backgroundRole(), tW->palette().color(tW->backgroundRole())); + tB->setPalette(palette); + tB->update(); + } + else if (tB->backgroundRole() != QPalette::Window) + { + tB->setBackgroundRole(QPalette::Window); + tB->update(); + } + bAfter = tB == lastButton; + } +} + +void GLDToolBox::setItemMode(GLDToolBox::ItemMode mode) +{ + m_itemMode = mode; +} + +GLDToolBoxHeader* GLDToolBox::addItem(QWidget *item, const QString &text) +{ + return insertItem(-1, item, QIcon(), text); +} + +GLDToolBoxHeader* GLDToolBox::addItem(QWidget *item, const QIcon &iconSet, const QString &text) +{ + return insertItem(-1, item, iconSet, text); +} + +QWidget* GLDToolBox::newItem() +{ + m_useOwnWidget = false; + QWidget* item = NULL; + switch (m_itemMode) + { + case ListWidget: + item = new QListWidget(); + connect(item, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)), + this, SLOT(itemChanging(QListWidgetItem*, QListWidgetItem*))); +// connect(item, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*))); +// connect(item, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*))); + connect(item, SIGNAL(itemPressed(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*))); + break; + case TreeWidget: + { + QTreeWidget *treeWidget = new QTreeWidget(); + treeWidget->setSelectionMode(QTreeWidget::SingleSelection); + connect(treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), + this, SLOT(itemChanging(QTreeWidgetItem*, QTreeWidgetItem*))); +// connect(treeWidget, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(itemChanged(QTreeWidgetItem *, int))); +// connect(treeWidget, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(itemChanged(QTreeWidgetItem *, int))); + connect(treeWidget, SIGNAL(itemPressed(QTreeWidgetItem *, int)), + this, SLOT(itemChanged(QTreeWidgetItem *, int))); + // 自适应宽度 + treeWidget->header()->setSectionResizeMode(QHeaderView::ResizeToContents); + // 隐藏标题 + treeWidget->setHeaderHidden(true); + item = treeWidget; + break; + } + default: + assert(false); + break; + } + return item; +} + +GLDToolBoxHeader* GLDToolBox::addItem(const QString &text) +{ + QWidget* item = newItem(); + return insertItem(-1, item, QIcon(), text); +} + +GLDToolBoxHeader* GLDToolBox::addItem(const QIcon &iconSet, const QString &text) +{ + QWidget* item = newItem(); + return insertItem(-1, item, iconSet, text); +} + +GLDToolBoxHeader* GLDToolBox::insertItem(int index, QWidget *item, const QString &text) +{ + return insertItem(index, item, QIcon(), text); +} + +GLDToolBoxHeader* GLDToolBox::insertItem(int index, const QString &text) +{ + QWidget* item = newItem(); + return insertItem(index, item, QIcon(), text); +} + +GLDToolBoxHeader* GLDToolBox::insertItem(int index, const QIcon &icon, const QString &text) +{ + QWidget* item = newItem(); + return insertItem(index, item, icon, text); +} + +GLDToolBoxHeader* GLDToolBox::insertItem(int index, QWidget *widget, const QIcon &icon, const QString &text) +{ + if (!widget) + { + m_useOwnWidget = true; + return NULL; + } + + connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(_q_widgetDestroyed(QObject*))); + + GLDToolBoxHeader *pHeader = new GLDToolBoxHeader(this, NULL); + pHeader->setUseOwnWidget(m_useOwnWidget); + m_useOwnWidget = true; + pHeader->setWidget(widget); + pHeader->setButton(new GLDToolBoxButton(this)); + pHeader->button()->setObjectName(QLatin1String("GLD_toolbox_toolboxbutton")); + connect(pHeader->button(), SIGNAL(clicked()), this, SLOT(_q_buttonClicked())); + QScrollArea *area = new QScrollArea(this); + area->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + area->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + pHeader->setSv(area); + pHeader->sv()->setWidget(widget); + pHeader->sv()->setWidgetResizable(true); + pHeader->sv()->hide(); + pHeader->sv()->setFrameStyle(inherited::NoFrame); + + pHeader->setButtonText(text); + pHeader->setButtonIcon(icon); + + if (index < 0 || index >= (int)m_pageList.count()) + { + index = m_pageList.count(); + m_pageList.append(pHeader); + m_layout->addWidget(pHeader->button()); + m_layout->addWidget(pHeader->sv()); + if (index == 0) + { + setCurrentIndex(index); + } + } + else + { + m_pageList.insert(index, pHeader); + relayout(); + if (m_pCurrentPage) + { + QWidget *current = m_pCurrentPage->widget(); + int nOldindex = indexOf(current); + if (index <= nOldindex) + { + m_pCurrentPage = 0; // trigger change + setCurrentIndex(nOldindex); + } + } + } + + pHeader->button()->show(); + + updateTabs(); + itemInserted(index); + return pHeader; +} + +void GLDToolBox::_q_buttonClicked() +{ + GLDToolBoxButton *tb = dynamic_cast(sender()); + QWidget* item = NULL; + for (int i = 0; i < m_pageList.count(); ++i) + { + if (m_pageList.at(i)->button() == tb) + { + item = m_pageList.at(i)->widget(); + break; + } + } + setCurrentIndex(indexOf(item)); +} + +int GLDToolBox::count() const +{ + return m_pageList.count(); +} + +int GLDToolBox::indexOf(const GString &name) +{ + for (int i = 0; i < m_pageList.count(); ++i) + { + if (compareText(name, m_pageList.at(i)->name()) == 0) + { + return i; + } + } + return -1; +} + +GLDToolBoxHeader *GLDToolBox::header(int index) +{ + return page(index); +} + +GLDToolBoxHeader *GLDToolBox::header(const GString &name) +{ + return page(name); +} + +void GLDToolBox::setCurrentIndex(int index) +{ + bool bCanChange = true; + GLDToolBoxHeader *pHeader = page(index); + + if (!pHeader || m_pCurrentPage == pHeader) + { + return; + } + emit headerChanging(m_pCurrentPage, pHeader, bCanChange); + if (!bCanChange) + { + return; + } + GLDToolBoxHeader *oldPage = m_pCurrentPage; + pHeader->button()->setSelected(true); + if (m_pCurrentPage) + { + m_pCurrentPage->sv()->hide(); + m_pCurrentPage->button()->setSelected(false); + m_pCurrentPage->button()->setProperty("GLDCurrentBtn", "NoSelected"); + } + pHeader->button()->setProperty("GLDCurrentBtn", "Selected"); + this->setStyleSheet(loadQssFile(c_sToolBoxQssFile)); + m_pCurrentPage = pHeader; + m_pCurrentPage->sv()->show(); + updateTabs(); + emit currentChanged(index); + emit headerChanged(oldPage, pHeader); +} + +void GLDToolBox::relayout() +{ + delete m_layout; + m_layout = new QVBoxLayout(this); + m_layout->setMargin(c_nLayOutMargin); + m_layout->setSpacing(0); + for (int i = 0; i < m_pageList.count(); ++i) + { + m_layout->addWidget(m_pageList.at(i)->button()); + m_layout->addWidget(m_pageList.at(i)->sv()); + } +} + +void GLDToolBox::_q_widgetDestroyed(QObject *object) +{ + // no verification - vtbl corrupted already + QWidget *pWidget = (QWidget*)object; + + GLDToolBoxHeader *pHeader = page(pWidget); + if (!pWidget || !pHeader) + return; + + m_layout->removeWidget(pHeader->sv()); + m_layout->removeWidget(pHeader->button()); + pHeader->sv()->deleteLater(); // page might still be a child of sv + delete pHeader->button(); + + bool bRemoveCurrent = pHeader == m_pCurrentPage; + m_pageList.remove(pHeader); + + if (0 == m_pageList.count()) + { + m_pCurrentPage = 0; + emit currentChanged(-1); + } + else if (bRemoveCurrent) + { + m_pCurrentPage = 0; + setCurrentIndex(0); + } +} + +void GLDToolBox::removeItem(int index) +{ + if (QWidget *pWidget = widget(index)) + { + disconnect(pWidget, SIGNAL(destroyed(QObject*)), this, SLOT(_q_widgetDestroyed(QObject*))); + pWidget->setParent(this); + // destroy internal data + _q_widgetDestroyed(pWidget); + itemRemoved(index); + } +} + +int GLDToolBox::currentIndex() const +{ + return m_pCurrentPage ? indexOf(m_pCurrentPage->widget()) : -1; +} + +QWidget * GLDToolBox::currentWidget() const +{ + return m_pCurrentPage ? m_pCurrentPage->widget() : 0; +} + +void GLDToolBox::setCurrentWidget(QWidget *widget) +{ + int nIndex = indexOf(widget); + if (nIndex >= 0) + setCurrentIndex(nIndex); + else + qWarning("GLDToolBox::setCurrentWidget: widget not contained in tool box"); +} + +void GLDToolBox::itemChanging(QListWidgetItem *current, QListWidgetItem *previous) +{ + if (!current) + { + return; + } + QListWidget *listWidget = m_pCurrentPage->listWidget(); + GLDToolBoxItem *itemCurrent = m_pCurrentPage->find(current); + GLDToolBoxItem *itemPrevious = m_pCurrentPage->find(previous); + disconnect(listWidget, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)), + this, SLOT(itemChanging(QListWidgetItem*, QListWidgetItem*))); + + if (previous) + { + listWidget->setCurrentItem(previous); + m_currentListWidgetItem = previous; + } + + bool bCanChanged = true; + emit itemChanging(itemPrevious, itemCurrent, bCanChanged); + + if (bCanChanged) + { + listWidget->setCurrentItem(current); + m_currentListWidgetItem = current; + emit itemChanged(itemPrevious, itemCurrent); + } + connect(listWidget, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)), + this, SLOT(itemChanging(QListWidgetItem*, QListWidgetItem*))); +} + +void GLDToolBox::itemChanged(QListWidgetItem *item) +{ + QListWidget *listWidget = m_pCurrentPage->listWidget(); + if (listWidget && m_currentListWidgetItem) + { + listWidget->setCurrentItem(m_currentListWidgetItem); + m_currentListWidgetItem = NULL; + } + G_UNUSED(item) +} + +void GLDToolBox::itemChanging(QTreeWidgetItem *current, QTreeWidgetItem *previous) +{ + if (!current) + { + return; + } + + QTreeWidget *treeWidget = m_pCurrentPage->treeWidget(); + if ((treeWidget != NULL) && (treeWidget == current->treeWidget())) + { + GLDToolBoxTreeItem *itemCurrent = dynamic_cast(current)->owner(); + GLDToolBoxTreeItem *itemPrevious = NULL; + if (previous) + { + itemPrevious = dynamic_cast(previous)->owner(); + } + disconnect(treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), + this, SLOT(itemChanging(QTreeWidgetItem*, QTreeWidgetItem*))); + + if (previous) + { + treeWidget->setCurrentItem(previous); + m_currentTreeWidgetItem = previous; + } + + bool bCanChanged = true; + emit itemChanging(itemPrevious, itemCurrent, bCanChanged); + + if (bCanChanged) + { + treeWidget->setCurrentItem(current); + m_currentTreeWidgetItem = current; + emit itemChanged(itemPrevious, itemCurrent); + } + connect(treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), + this, SLOT(itemChanging(QTreeWidgetItem*, QTreeWidgetItem*))); + } +} + +void GLDToolBox::itemChanged(QTreeWidgetItem *item, int column) +{ + QTreeWidget *treeWidget = m_pCurrentPage->treeWidget(); + if (treeWidget && m_currentTreeWidgetItem) + { + treeWidget->setCurrentItem(m_currentTreeWidgetItem); + m_currentTreeWidgetItem = NULL; + } + G_UNUSED(item); + G_UNUSED(column) +} + +QWidget *GLDToolBox::widget(int index) const +{ + if (index < 0 || index >= (int) m_pageList.size()) + return 0; + return m_pageList.at(index)->widget(); +} + +int GLDToolBox::indexOf(QWidget *widget) const +{ + GLDToolBoxHeader *pHeader = (widget ? page(widget) : 0); + return pHeader ? m_pageList.indexOf(pHeader) : -1; +} + +void GLDToolBox::setItemEnabled(int index, bool enabled) +{ + GLDToolBoxHeader *pHeader = page(index); + if (!pHeader) + { + return; + } + + pHeader->button()->setEnabled(enabled); + if (!enabled && pHeader == m_pCurrentPage) + { + int nCurIndexUp = index; + int nCurIndexDown = nCurIndexUp; + const int c_nCount = m_pageList.count(); + while (nCurIndexUp > 0 || nCurIndexDown < c_nCount - 1) + { + if (nCurIndexDown < c_nCount - 1) + { + if (page(++nCurIndexDown)->button()->isEnabled()) + { + index = nCurIndexDown; + break; + } + } + if (nCurIndexUp > 0) + { + if (page(--nCurIndexUp)->button()->isEnabled()) + { + index = nCurIndexUp; + break; + } + } + } + setCurrentIndex(index); + } +} + +void GLDToolBox::setItemText(int index, const QString &text) +{ + GLDToolBoxHeader *pHeader = page(index); + if (pHeader) + { + pHeader->setButtonText(text); + } +} + +void GLDToolBox::setItemIcon(int index, const QIcon &icon) +{ + GLDToolBoxHeader *pHeader = page(index); + if (pHeader) + { + pHeader->setButtonIcon(icon); + } +} + +#ifndef QT_NO_TOOLTIP +void GLDToolBox::setItemToolTip(int index, const QString &toolTip) +{ + GLDToolBoxHeader *pHeader = page(index); + if (pHeader) + { + pHeader->setToolTip(toolTip); + } +} + +QString GLDToolBox::itemToolTip(int index) const +{ + const GLDToolBoxHeader *pHeader = page(index); + return (pHeader ? pHeader->toolTip() : QString()); +} + +#endif // QT_NO_TOOLTIP + +bool GLDToolBox::isItemEnabled(int index) const +{ + const GLDToolBoxHeader *pHeader = page(index); + return pHeader && pHeader->button()->isEnabled(); +} + +QString GLDToolBox::itemText(int index) const +{ + const GLDToolBoxHeader *pHeader = page(index); + return (pHeader ? pHeader->buttonText() : QString()); +} + +QIcon GLDToolBox::itemIcon(int index) const +{ + const GLDToolBoxHeader *pHeader = page(index); + return (pHeader ? pHeader->buttonIcon() : QIcon()); +} + +void GLDToolBox::showEvent(QShowEvent *e) +{ + inherited::showEvent(e); +} + +void GLDToolBox::changeEvent(QEvent *ev) +{ + if (ev->type() == QEvent::StyleChange) + { + updateTabs(); + } + inherited::changeEvent(ev); +} + +void GLDToolBox::itemInserted(int index) +{ + Q_UNUSED(index) +} + +void GLDToolBox::itemRemoved(int index) +{ + Q_UNUSED(index) +} + +bool GLDToolBox::event(QEvent *e) +{ + return inherited::event(e); +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDTreeDrawInfo.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDTreeDrawInfo.cpp new file mode 100644 index 00000000..8acbdda9 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDTreeDrawInfo.cpp @@ -0,0 +1,943 @@ +#include +#include +#include "GLDGlobal.h" +#include "GLDTreeDrawInfo.h" +#include "GLDAbstractItemModel.h" + +void GlodonTreeDrawInfo::setModel(QAbstractItemModel *newModel) +{ + model = newModel; + init(); +} + +int GlodonTreeDrawInfo::rowNo(QModelIndex index) +{ + if (!index.isValid()) + { + return -1; + } + + const int nCount = m_viewItems.count(); + for (int i = 0; i < nCount; ++i) + { + if (m_viewItems.at(i).modelIndex == index) + { + return i; + } + } + + return -2; +} + +void GlodonTreeDrawInfo::setTreeColumn(int value) +{ + m_treeColumn = value; +} + +int GlodonTreeDrawInfo::treeColumn() +{ + return m_treeColumn; +} + +int GlodonTreeDrawInfo::lastChildRow(int parentRow) +{ + int nRow = parentRow; + + const int nCount = m_viewItems.count(); + do + { + ++nRow; + } + while ((nRow < nCount) && (m_viewItems.at(nRow).treeLevel > m_viewItems.at(parentRow).treeLevel)); + + return nRow - 1; +} + +void GlodonTreeDrawInfo::reset() +{ + m_viewItems.clear(); + m_viewItems.resize(modelSectionCount()); + + transformModelFromTreeToLine(); + buildTree(true); +} + +GlodonTreeDrawInfo::~GlodonTreeDrawInfo() +{ +} + +int GlodonTreeDrawInfo::modelSectionCount() const +{ + return model->rowCount() + childRowCount(); +} + +void GlodonTreeDrawInfo::init(bool expandAllLevel) +{ + int nOldCount = m_viewItems.count(); + int nNewCount = modelSectionCount(); + + if (m_header != NULL && nNewCount < nOldCount) + { + m_header->resetForGroup(); + } + + m_viewItems.clear(); + m_viewItems.resize(nNewCount); + + transformModelFromTreeToLine(); + + buildTree(expandAllLevel, nNewCount >= nOldCount && !expandAllLevel); + + if (!expandAllLevel) + { + QVector hiddenNodeIndexs; + + const int nCount = m_viewItems.count(); + for (int i = 0; i < nCount; ++i) + { + if (0 == m_viewItems.at(i).hidden) + { + hiddenNodeIndexs.append(i); + } + } + + if (m_header != NULL) + { + m_header->resetAfterTreeBuild(hiddenNodeIndexs); + } + } + + if (m_header != NULL) + { + m_header->viewport()->update(); + } +} + +void GlodonTreeDrawInfo::expandAll() +{ + const int nCount = m_viewItems.count(); + for (int row = 0; row < nCount; ++row) + { + if (!m_viewItems.at(row).expanded) + { + expandItem(row); + } + } +} + +void GlodonTreeDrawInfo::collapseAll() +{ + const int nCount = m_viewItems.count(); + for (int row = 0; row < nCount; ++row) + { + if (m_viewItems.at(row).expanded) + { + collapseItem(row); + } + } +} + +int GlodonTreeDrawInfo::childRowCount(QModelIndex parentIndex) const +{ + int nSumCount = 0; + + int nChildRowCount = model->rowCount(parentIndex); + + for (int i = 0; i < nChildRowCount; ++i) + { + QModelIndex childIndex = model->index(i, m_treeColumn, parentIndex); + + nSumCount += model->rowCount(childIndex) + childRowCount(childIndex); + } + + return nSumCount; +} + +void GlodonTreeDrawInfo::transformModelFromTreeToLine() +{ + QModelIndex rootIndex; + + int nIndex = 0; + int nModelSectionCount = modelSectionCount(); + + while (nIndex < nModelSectionCount) + { + transformTreeByLevel(nIndex, rootIndex, 0); + } +} + +void GlodonTreeDrawInfo::transformTreeByLevel(int &nIndex, const QModelIndex &parentIndex, int sectionLevel) +{ + int nChildRowCount = model->rowCount(parentIndex); + + for (int i = 0; i < nChildRowCount; i++) + { + QModelIndex index = model->index(i, m_treeColumn, parentIndex); + + m_viewItems[nIndex].treeLevel = sectionLevel; + m_viewItems[nIndex].modelIndex = index; + + ++nIndex; + + if (model->rowCount(index) > 0) + { + transformTreeByLevel(nIndex, index, sectionLevel + 1); + } + } +} + +void GlodonTreeDrawInfo::switchNodeExpandState( + bool buildHeaderLater, bool shouldExpandAllLevel, int i, + QSet &hiddenSections, QSet &visibleSections) +{ + if (shouldExpandAllLevel) + { + if (m_header != NULL && !buildHeaderLater) + { + visibleSections.insert(i); + } + + m_viewItems[i].expanded = true; + } + else + { + m_viewItems[i].expanded = false; + + if (m_viewItems.at(i).treeLevel == 0) + { + if (m_header != NULL && !buildHeaderLater) + { + visibleSections.insert(i); + } + } + else + { + if (m_header != NULL && !buildHeaderLater) + { + hiddenSections.insert(i); + } + + m_viewItems[i].hidden = true; + } + } +} + +void GlodonTreeDrawInfo::buildTree(bool shouldExpandAllLevel, bool buildHeaderLater) +{ + if (m_viewItems.count() <= 1) + { + return; + } + + QSet oHiddenSections; + QSet oVisibleSections; + + QStack parentStack; + + const int nCount = m_viewItems.count(); + for (int i = 0; i < nCount - 1; ++i) + { + Q_ASSERT(m_viewItems.at(i + 1).treeLevel <= (m_viewItems.at(i).treeLevel + 1)); + + switchNodeExpandState(buildHeaderLater, shouldExpandAllLevel, i, oHiddenSections, oVisibleSections); + + if (parentStack.count() == 0) + { + m_viewItems[i].parentIndex = -1; + } + else + { + m_viewItems[i].parentIndex = parentStack.last(); + } + + if (m_viewItems.at(i).treeLevel < m_viewItems.at(i + 1).treeLevel) + { + m_viewItems[i].hasChildren = true; + + parentStack.push_back(i); + } + else if (m_viewItems.at(i).treeLevel == m_viewItems.at(i + 1).treeLevel) + { + m_viewItems[i].hasMoreSiblings = true; + } + else + { + int nindex = parentStack.last(); + + while (true) + { + if (m_viewItems.at(nindex).treeLevel == m_viewItems.at(i + 1).treeLevel) + { + m_viewItems[nindex].hasMoreSiblings = true; + m_viewItems[nindex].childCount = i - nindex; + parentStack.pop_back(); + break; + } + else if (m_viewItems.at(nindex).treeLevel > m_viewItems.at(i + 1).treeLevel) + { + m_viewItems[nindex].hasMoreSiblings = false; + m_viewItems[nindex].childCount = i - nindex; + parentStack.pop_back(); + nindex = parentStack.last(); + } + } + } + } + + int nlast = m_viewItems.count() - 1; + + m_viewItems[nlast].expanded = shouldExpandAllLevel; + + if (parentStack.count() == 0) + { + m_viewItems[nlast].parentIndex = -1; + } + else + { + m_viewItems[nlast].parentIndex = parentStack.last(); + + if (shouldExpandAllLevel) + { + switchNodeExpandState(buildHeaderLater, shouldExpandAllLevel, nlast, oHiddenSections, oVisibleSections); + } + else + { + m_viewItems[nlast].hidden = true; + + if (m_header != NULL && !buildHeaderLater) + { + oHiddenSections.insert(nlast); + } + } + + while (parentStack.count() != 0) + { + m_viewItems[parentStack.last()].childCount = nlast - parentStack.last(); + parentStack.pop_back(); + } + } + + m_header->batchSetSectionHidden(oHiddenSections, true); + m_header->batchSetSectionHidden(oVisibleSections, false); +} + +void GlodonTreeDrawInfo::doExpandItem(int row, QSet &oExpandRows) +{ + QVector vecIndexRecord; + int nItem = row; + while (true) + { + vecIndexRecord.append(nItem); + nItem = m_viewItems.at(nItem).parentIndex; + if (-1 == nItem || m_viewItems.at(nItem).expanded) + { + break; + } + } + + for (int nTemp = vecIndexRecord.count() - 1; nTemp >= 0; --nTemp) + { + m_viewItems[vecIndexRecord[nTemp]].expanded = true; + if (m_viewItems.at(vecIndexRecord[nTemp]).hasChildren) + { + // TODO,wangdd-a:觉得不应该同步展开子,递归遍历中会设置Section的显示隐藏,影响效率 + setChildItemsExpand(oExpandRows, vecIndexRecord[nTemp]); + } + } +} + +void GlodonTreeDrawInfo::expandItem(int row) +{ + QSet oExpandRows; + + doExpandItem(row, oExpandRows); + + if (m_header != NULL) + { + m_header->batchSetSectionHidden(oExpandRows, false); + } +} + +int GlodonTreeDrawInfo::doCollapseItem(int row, QSet &oCollapseRows) +{ + m_viewItems[row].expanded = false; + int result = row + 1; + + if (m_viewItems.at(row).hasChildren) + { + // TODO,wangdd-a:觉得不应该同步折叠子,递归遍历中会设置Section的显示隐藏,影响效率 + result = setChildItemsCollapse(row, oCollapseRows); + } + + return result; +} + +int GlodonTreeDrawInfo::collapseItem(int row) +{ + QSet oCollapseRows; + + int result = doCollapseItem(row, oCollapseRows); + + if (m_header != NULL) + { + m_header->batchSetSectionHidden(oCollapseRows, true); + } + return result; +} + +void GlodonTreeDrawInfo::setChildItemsExpand(QSet &oExpandRows, int row) +{ + int nChildRow = row + 1; + + while (nChildRow < m_viewItems.count()) + { + if (m_viewItems.at(nChildRow).treeLevel <= m_viewItems.at(row).treeLevel) + { + break; + } + else if (m_viewItems.at(nChildRow).expanded && m_viewItems.at(row).hasChildren) + { + bool bExpanded = model->data(m_viewItems[nChildRow].modelIndex, gidrRowExpandedRole).toBool(); + + if (bExpanded) + { + setChildItemsExpand(oExpandRows, nChildRow); + } + else + { + m_viewItems[nChildRow].expanded = false; + } + } + + m_viewItems[nChildRow].hidden = false; + + oExpandRows << nChildRow; + + nChildRow += m_viewItems[nChildRow].childCount + 1; + } +} + +int GlodonTreeDrawInfo::setChildItemsCollapse(int row, QSet &oCollapseRows) +{ + int nChildRow; + + for (nChildRow = row + 1; nChildRow < m_viewItems.count(); ++nChildRow) + { + if (m_viewItems.at(nChildRow).treeLevel <= m_viewItems.at(row).treeLevel) + { + break; + } + + m_viewItems[nChildRow].hidden = true; + + if (m_header != NULL) + { + oCollapseRows << nChildRow; + } + } + + return nChildRow; +} + +int GlodonTreeDrawInfo::insertViewItem(int parent, QModelIndex index) +{ + int nchildRowNo = 0; + int npos = parent + 1; + + while (true) + { + if (nchildRowNo == index.row()) + { + break; + } + else + { + npos += m_viewItems[npos].childCount + 1; + nchildRowNo++; + } + } + + GTreeViewItem item; + item.parentIndex = parent; + item.childCount = 0; + item.modelIndex = index; + m_viewItems.insert(npos, item); + + if (-1 == parent) + { + m_viewItems[npos].treeLevel = 0; + m_viewItems[npos].hasMoreSiblings = (index.row() < model->rowCount() - 1); + } + else + { + m_viewItems[npos].hasMoreSiblings = (index.row() < model->rowCount(m_viewItems[parent].modelIndex) - 1); + m_viewItems[npos].treeLevel = m_viewItems[parent].treeLevel + 1; + + int temp = parent; + while (-1 != temp) + { + ++m_viewItems[temp].childCount; + temp = m_viewItems[temp].parentIndex; + } + + m_viewItems[parent].hasChildren = true; + } + + for (int i = npos + 1; i < m_viewItems.count(); i++) + { + if (m_viewItems.at(i).parentIndex >= npos) + { + m_viewItems[i].parentIndex++; + } + } + + int ni = parent + 1; + + while (ni < npos) + { + if ((m_viewItems.at(ni).parentIndex == parent) && (0 == m_viewItems.at(ni).hasMoreSiblings)) + { + m_viewItems[ni].hasMoreSiblings = true; + } + + ni += (m_viewItems[ni].childCount + 1); + } + + refreshModelIndexAfterInsertOrRemove(npos, parent, true); + + return npos; +} + +void GlodonTreeDrawInfo::removeViewItem(int row) +{ + int ndelCount = m_viewItems[row].childCount + 1; + int noldParent = m_viewItems[row].parentIndex; + + for (int i = row + 1; i < m_viewItems.count(); i++) + { + if (m_viewItems.at(i).parentIndex > row) + { + m_viewItems[i].parentIndex = m_viewItems[i].parentIndex - ndelCount; + } + } + + int ni = noldParent; + + while (ni != -1) + { + m_viewItems[ni].childCount = m_viewItems[ni].childCount - ndelCount; + + if (m_viewItems.at(ni).childCount == 0) + { + m_viewItems[ni].hasChildren = false; + } + + ni = m_viewItems[ni].parentIndex; + } + + ni = noldParent + 1; + + if (0 == m_viewItems.at(row).hasMoreSiblings) + { + while (true) + { + if ((ni + (uint)m_viewItems.at(ni).childCount + 1) >= (uint)row) + { + break; + } + + ni += (m_viewItems[ni].childCount + 1); + } + + m_viewItems[ni].hasMoreSiblings = false; + } + + m_viewItems.remove(row, m_viewItems[row].childCount + 1); + + refreshModelIndexAfterInsertOrRemove(row, noldParent, false); +} + +void GlodonTreeDrawInfo::moveViewItem(int parent, int first, int last, int destinationParent, int row) +{ + if (parent == destinationParent && first == row) + { + return; + } + + int nparentLevel = (parent == -1) ? -1 : m_viewItems[parent].treeLevel; + int ndestinationParentLevel = (destinationParent == -1) ? -1 : m_viewItems[destinationParent].treeLevel; + + int nfirstRow = parent + 1; + int ni = 0; + + while (ni != first) + { + nfirstRow += m_viewItems[nfirstRow].childCount + 1; + ni++; + } + + int nlastRow = nfirstRow; + ni = first; + + while (ni != last) + { + nlastRow += m_viewItems[nlastRow].childCount + 1; + ni++; + } + + int nlastMovedRow = nlastRow + m_viewItems[nlastRow].childCount; + + int ndestinationRow = destinationParent + 1; + ni = 0; + + while (ni != row) + { + ndestinationRow += m_viewItems[ndestinationRow].childCount + 1; + ni++; + } + + Q_ASSERT(ndestinationRow < nfirstRow || ndestinationRow > nlastMovedRow); + + if (destinationParent != -1) + { + if (0 == m_viewItems.at(destinationParent).hasChildren) + { + m_viewItems[destinationParent].hasChildren = true; + } + else if (ndestinationRow > destinationParent + (int)m_viewItems.at(destinationParent).childCount) + { + int nlastRowBeforeMove = destinationParent + 1; + ni = 0; + + while (ni != row - 1) + { + nlastRowBeforeMove += m_viewItems[nlastRowBeforeMove].childCount + 1; + ni++; + } + + m_viewItems[nlastRowBeforeMove].hasMoreSiblings = true; + } + else if (destinationParent == parent) + { + int nlastRowBeforeMove = destinationParent + 1; + + while (nlastRowBeforeMove < m_viewItems.count()) + { + if (0 == m_viewItems.at(nlastRowBeforeMove).hasMoreSiblings) + { + break; + } + + nlastRowBeforeMove += m_viewItems[nlastRowBeforeMove].childCount + 1; + } + + if (nlastRowBeforeMove < ndestinationRow) + { + m_viewItems[nlastRowBeforeMove].hasMoreSiblings = true; + } + } + + if (destinationParent != parent) + { + m_viewItems[destinationParent].childCount += (nlastMovedRow + m_viewItems[nlastMovedRow].childCount - nfirstRow + 1); + } + } + else + { + int nlastRowBeforeMove = destinationParent + 1; + + while (nlastRowBeforeMove < m_viewItems.count()) + { + if (0 == m_viewItems.at(nlastRowBeforeMove).hasMoreSiblings) + { + break; + } + + nlastRowBeforeMove += m_viewItems[nlastRowBeforeMove].childCount + 1; + } + + if (ndestinationRow > nlastRowBeforeMove) + { + m_viewItems[nlastRowBeforeMove].hasMoreSiblings = true; + } + } + + if (parent != -1) + { + m_viewItems[parent].childCount -= (nlastMovedRow - nfirstRow + 1); + + if (m_viewItems.at(parent).childCount == 0) + { + m_viewItems[parent].hasChildren = false; + } + else + { + if (0 == m_viewItems.at(nlastRow).hasMoreSiblings) + { + int newLastRow = parent + 1; + ni = 0; + + while (ni != first - 1) + { + newLastRow += m_viewItems[newLastRow].childCount + 1; + ni++; + } + + m_viewItems[newLastRow].hasMoreSiblings = false; + } + } + } + else + { + int nlastRowBeforeMove = parent + 1; + + while (nlastRowBeforeMove < m_viewItems.count()) + { + if (0 == m_viewItems.at(nlastRowBeforeMove).hasMoreSiblings) + { + break; + } + + nlastRowBeforeMove += m_viewItems[nlastRowBeforeMove].childCount + 1; + } + + if (ndestinationRow > nlastRowBeforeMove) + { + m_viewItems[nlastRowBeforeMove].hasMoreSiblings = true; + } + } + + if (ndestinationRow < nfirstRow) + { + for (int i = 0; i <= nlastMovedRow - nfirstRow; i++) + { + GTreeViewItem item = m_viewItems.at(nfirstRow + i); + m_viewItems.remove(nfirstRow + i); + m_viewItems.insert(ndestinationRow + i, item); + + if (m_viewItems.at(ndestinationRow + i).parentIndex == parent) + { + m_viewItems[ndestinationRow + i].parentIndex = destinationParent; + } + else + { + m_viewItems[ndestinationRow + i].parentIndex -= (nfirstRow - ndestinationRow); + } + + m_viewItems[ndestinationRow + i].treeLevel -= (nparentLevel - ndestinationParentLevel); + } + + if (ndestinationRow + nlastMovedRow - nfirstRow + 1 >= m_viewItems.count()) + { + m_viewItems[ndestinationRow + nlastRow - nfirstRow].hasMoreSiblings = false; + } + else if (m_viewItems.at(ndestinationRow + nlastMovedRow - nfirstRow + 1).treeLevel == ndestinationParentLevel + 1) + { + m_viewItems[ndestinationRow + nlastRow - nfirstRow].hasMoreSiblings = true; + } + else + { + m_viewItems[ndestinationRow + nlastRow - nfirstRow].hasMoreSiblings = false; + } + + for (int i = ndestinationRow + nlastMovedRow - nfirstRow + 1; i <= nlastMovedRow; i++) + { + if (i >= m_viewItems.count()) + { + break; + } + + if (m_viewItems.at(i).parentIndex != -1) + { + m_viewItems[i].parentIndex += (nlastMovedRow - nfirstRow + 1); + } + } + } + else + { + for (int i = 0; i <= nlastMovedRow - nfirstRow; i++) + { + GTreeViewItem item = m_viewItems.at(nfirstRow); + m_viewItems.remove(nfirstRow); + m_viewItems.insert(ndestinationRow - 1, item); + + if (m_viewItems.at(ndestinationRow - 1).parentIndex == parent) + { + m_viewItems[ndestinationRow - 1].parentIndex = destinationParent; + } + else + { + m_viewItems[ndestinationRow - 1].parentIndex -= (nfirstRow - ndestinationRow + 2); + } + + m_viewItems[ndestinationRow - 1].treeLevel -= (nparentLevel - ndestinationParentLevel); + } + + if (ndestinationRow == m_viewItems.count()) + { + m_viewItems[ndestinationRow + nlastRow - nlastMovedRow - 1].hasMoreSiblings = false; + } + else if (m_viewItems.at(ndestinationRow + nlastRow - nlastMovedRow - 1).treeLevel == ndestinationParentLevel + 1) + { + m_viewItems[ndestinationRow + nlastRow - nlastMovedRow - 1].hasMoreSiblings = true; + } + else + { + m_viewItems[ndestinationRow + nlastRow - nlastMovedRow - 1].hasMoreSiblings = false; + } + + for (int i = nfirstRow; i < ndestinationRow; i++) + { + if (i >= m_viewItems.count()) + { + break; + } + + if (m_viewItems.at(i).parentIndex != -1) + { + m_viewItems[i].parentIndex -= (nlastMovedRow - nfirstRow + 1); + } + } + } + + //TODO:优化刷新 + refreshModelIndexAfterMove(parent, nfirstRow); + refreshModelIndexAfterMove(destinationParent, ndestinationRow); +} + +void GlodonTreeDrawInfo::refreshModelIndexAfterInsertOrRemove(int row, int parent, bool insert) +{ + int nindex = parent + 1; + int ncurrNo = 0; + + while (nindex < m_viewItems.count()) + { + if (nindex < row || (insert && nindex == row)) + { + nindex += m_viewItems[nindex].childCount + 1; + ncurrNo++; + continue; + } + + if (parent != -1) + { + if (m_viewItems.at(nindex).treeLevel <= m_viewItems.at(parent).treeLevel) + { + break; + } + else + { + m_viewItems[nindex].modelIndex = model->index(ncurrNo, 0, m_viewItems[parent].modelIndex); + + if (0 != m_viewItems.at(nindex).hasChildren) + { + refreshChildModelIndex(nindex); + } + + nindex += m_viewItems[nindex].childCount + 1; + ncurrNo++; + } + } + else + { + m_viewItems[nindex].modelIndex = model->index(ncurrNo, 0); + + if (0 != m_viewItems.at(nindex).hasChildren) + { + refreshChildModelIndex(nindex); + } + + nindex += m_viewItems[nindex].childCount + 1; + ncurrNo++; + } + } +} + +void GlodonTreeDrawInfo::refreshChildModelIndex(int parent) +{ + int nindex = parent + 1; + int ncurrNo = 0; + + while (nindex < m_viewItems.count()) + { + if (parent != -1) + { + if (m_viewItems.at(nindex).treeLevel <= m_viewItems.at(parent).treeLevel) + { + break; + } + else + { + m_viewItems[nindex].modelIndex = model->index(ncurrNo, 0, m_viewItems[parent].modelIndex); + + if (0 != m_viewItems.at(nindex).hasChildren) + { + refreshChildModelIndex(nindex); + } + + nindex += m_viewItems[nindex].childCount + 1; + ncurrNo++; + } + } + else + { + m_viewItems[nindex].modelIndex = model->index(ncurrNo, 0); + + if (0 != m_viewItems.at(nindex).hasChildren) + { + refreshChildModelIndex(nindex); + } + + nindex += m_viewItems[nindex].childCount + 1; + ncurrNo++; + } + } +} + +void GlodonTreeDrawInfo::refreshModelIndexAfterMove(int parent, int row) +{ + int nindex = parent + 1; + int ncurrNo = 0; + + while (nindex < m_viewItems.count()) + { + if (nindex < row) + { + nindex += m_viewItems[nindex].childCount + 1; + ncurrNo++; + continue; + } + + if (parent != -1) + { + if (m_viewItems.at(nindex).treeLevel <= m_viewItems.at(parent).treeLevel) + { + break; + } + else + { + m_viewItems[nindex].modelIndex = model->index(ncurrNo, 0, m_viewItems[parent].modelIndex); + + if (0 != m_viewItems.at(nindex).hasChildren) + { + refreshChildModelIndex(nindex); + } + + nindex += m_viewItems[nindex].childCount + 1; + ncurrNo++; + } + } + else + { + m_viewItems[nindex].modelIndex = model->index(ncurrNo, 0); + + if (0 != m_viewItems.at(nindex).hasChildren) + { + refreshChildModelIndex(nindex); + } + + nindex += m_viewItems[nindex].childCount + 1; + ncurrNo++; + } + } +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDTreeView.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDTreeView.cpp new file mode 100644 index 00000000..dc2b1ce9 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDTreeView.cpp @@ -0,0 +1,393 @@ +#include +#include +#include +#include +#include "GLDTreeView.h" +#include "GLDGlobal.h" +#include "GLDException.h" + +GlodonTreeView::GlodonTreeView(QWidget *parent) : QTreeView(parent), m_rowDragable(false), m_ptStart(-1, -1), + m_pIndicator(NULL), m_indexFrom(QModelIndexList()), m_dragStyle(DotLineStyle), m_state(NONE), m_canSectionMove(true), + m_autoResetScrollBarAfterExpand(false), m_errCode(-1), m_errMessage("") +{ + init(); +} + +void GlodonTreeView::setAutoResetScrollBarAfterExpand(bool value) +{ + if (m_autoResetScrollBarAfterExpand == value) + { + return; + } + + m_autoResetScrollBarAfterExpand = value; + if (value) + { + connect(this, SIGNAL(expanded(QModelIndex)), this, SLOT(autoResetScrollBarOnExpand(QModelIndex))); + } + else + { + disconnect(this, SIGNAL(expanded(QModelIndex)), this, SLOT(autoResetScrollBarOnExpand(QModelIndex))); + } +} + +void GlodonTreeView::reset() +{ + QTreeView::reset(); + m_indexFrom = QModelIndexList(); + m_ptStart = QPoint(-1000, -1000); +} + +bool GlodonTreeView::viewportEvent(QEvent *event) +{ + switch (event->type()) + { + case QEvent::HoverEnter: + case QEvent::HoverLeave: + case QEvent::HoverMove: + { + if (m_state == DragSection) + { + return true; + } + } + break; + default: + break; + } + return QAbstractItemView::viewportEvent(event); +} + +void GlodonTreeView::mousePressEvent(QMouseEvent *event) +{ + QTreeView::mousePressEvent(event); + if (m_rowDragable) + { + QModelIndex index = indexAt(event->pos()); + if (index.isValid()) + { + setupIndexIndicator(selectionModel()->selectedIndexes(), event->pos()); + } + else + { + setupIndexIndicator(QModelIndexList(), QPoint(-1000, -1000)); + } + } +} + +void GlodonTreeView::mouseMoveEvent(QMouseEvent *event) +{ + if (m_rowDragable) + { + startAutoScroll(); + bool bShouldUpdate = false; + if (m_state == DragSection) + { + bShouldUpdate = true; + } + else if ((event->pos() - m_ptStart).manhattanLength() >= QApplication::startDragDistance()) + { + if (NULL == m_pIndicator) + { + m_pIndicator = new QLabel(this); + m_pIndicator->hide(); + } + bShouldUpdate = true; + } + if (bShouldUpdate) + { + m_state = DragSection; + updateIndexIndicator(event->pos()); + QModelIndex indexTo = indexAt(event->pos()); + m_canSectionMove = true; + QCursor cursor; + canDrag(m_indexFrom, indexTo, event->modifiers(), m_canSectionMove, cursor); + setCursor(cursor); + } + event->accept(); + return; + } + QTreeView::mouseMoveEvent(event); +} + +void GlodonTreeView::mouseReleaseEvent(QMouseEvent *event) +{ + if (m_rowDragable) + { + if (m_state == DragSection) + { + QModelIndex indexTo = indexAt(event->pos()); + + if (m_canSectionMove) + { + moveIndex(m_indexFrom, indexTo, event->modifiers()); + } + unsetCursor(); + m_ptStart = QPoint(-1, -1); + m_pIndicator->hide(); + m_state = NONE; + } + } + QTreeView::mouseReleaseEvent(event); +} + +QStyleOptionViewItem GlodonTreeView::initOption() +{ + QStyleOptionViewItem option; + option.init(this); + option.state &= ~QStyle::State_MouseOver; + option.font = font(); + +#ifndef Q_WS_MAC + // On mac the focus appearance follows window activation + // not widget activation + if (!hasFocus()) + option.state &= ~QStyle::State_Active; +#endif + + option.state &= ~QStyle::State_HasFocus; + if (iconSize().isValid()) + { + option.decorationSize = iconSize(); + } + else + { + int nPm = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this); + option.decorationSize = QSize(nPm, nPm); + } + option.decorationPosition = QStyleOptionViewItem::Left; + option.decorationAlignment = Qt::AlignCenter; + option.displayAlignment = Qt::AlignLeft | Qt::AlignVCenter; + option.textElideMode = textElideMode(); + option.rect = QRect(); + option.showDecorationSelected = (0 != style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, 0, this)); + option.features = QStyleOptionViewItem::WrapText; + option.locale = locale(); + option.locale.setNumberOptions(QLocale::OmitGroupSeparator); + option.widget = this; + return option; +} + +void GlodonTreeView::afterExpandedChanged(const QModelIndex &index, bool expanded) +{ + G_UNUSED(index); + G_UNUSED(expanded); +} + +void GlodonTreeView::canDrag(QModelIndexList from, QModelIndex to, + Qt::KeyboardModifiers keyModifiers, bool &canMove, QCursor &cursor) +{ + emit canSectionMove(from, to, keyModifiers, canMove, cursor); +} + +void GlodonTreeView::moveIndex(QModelIndexList from, QModelIndex to, Qt::KeyboardModifiers keyModifiers) +{ + emit sectionMove(from, to, keyModifiers); + Q_UNUSED(from); + Q_UNUSED(to); + Q_UNUSED(keyModifiers); + //todo 改变from对应的data中关于index的值到indexTo中对应的data的index +} + +void GlodonTreeView::doExpanded(const QModelIndex &index) +{ +// if (!isExpanded(index)) +// { +// expand(index); + afterExpandedChanged(index, true); +// } +} + +void GlodonTreeView::doCollapsed(const QModelIndex &index) +{ +// if (isExpanded(index)) +// { +// collapse(index); + afterExpandedChanged(index, false); +// } +} + +void GlodonTreeView::autoResetScrollBarOnExpand(const QModelIndex &index) +{ + m_expandIndex = index; + QModelIndex nextIndex = findLastModelIndex(index, index.parent(), 0); + scrollTo(nextIndex); +} + +void GlodonTreeView::afterCloseEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint) +{ + G_UNUSED(editor); + G_UNUSED(hint); + if ((m_errCode > 0) || (m_errMessage.length() > 0)) + { + QString strMessage = m_errMessage; + int nErrCode = m_errCode; + m_errCode = -1; + m_errMessage = ""; + throw GLDException(strMessage, nErrCode); + } +} + +void GlodonTreeView::init() +{ + GLDTreeDefaultDelegaet *pDelegate = new GLDTreeDefaultDelegaet(this); + setItemDelegate(pDelegate); + connect(pDelegate, SIGNAL(closeEditor(QWidget*, QAbstractItemDelegate::EndEditHint)), this, SLOT(afterCloseEditor(QWidget*, QAbstractItemDelegate::EndEditHint))); + connect(this, SIGNAL(expanded(QModelIndex)), this, SLOT(doExpanded(QModelIndex))); + connect(this, SIGNAL(collapsed(QModelIndex)), this, SLOT(doCollapsed(QModelIndex))); +} + +void GlodonTreeView::setupIndexIndicator(QModelIndexList indexs, QPoint pt) +{ + m_indexFrom = indexs; + m_ptStart = pt; +} + +void GlodonTreeView::updateIndexIndicator(QPoint pt) +{ + QModelIndex targetIndex = indexAt(pt); + if (m_pIndicator->isHidden()) + { + QStyleOptionViewItem opt = initOption(); + opt.rect = visualRect(targetIndex); + if (m_dragStyle == DotLineStyle) + { + QPixmap pm(this->viewport()->width(), 1); + pm.fill(Qt::transparent); + QPainter painter(&pm); + QPen pen = painter.pen(); + pen.setWidth(1); + pen.setColor(Qt::black); + pen.setStyle(Qt::DotLine); + painter.setPen(pen); + painter.drawLine(0, 0, pm.width(), pm.height()); + painter.end(); + m_pIndicator->setPixmap(pm); + } + else if (m_dragStyle == LabelStyle) + { + QPixmap pm(opt.rect.size()); + pm.fill(QColor(0, 0, 0, 45)); + opt.rect.adjust(0, -opt.rect.top(), 0, -opt.rect.top()); + + QPainter painter(&pm); + painter.setOpacity(0.6); + + int nPrevIndentation = indentation(); + if (nPrevIndentation > 0) + { + setIndentation(0); + } + drawRow(&painter, opt, m_indexFrom.at(0)); + if (nPrevIndentation > 0) + { + setIndentation(nPrevIndentation); + } + painter.end(); + + m_pIndicator->resize(opt.rect.width(), opt.rect.height()); + m_pIndicator->setPixmap(pm); + } + m_pIndicator->show(); + } + if (m_dragStyle == DotLineStyle) + { + QRect targetRect = visualRect(targetIndex); + m_pIndicator->move(targetRect.bottomLeft()); + } + else if (m_dragStyle == LabelStyle) + { + m_pIndicator->move(0, pt.y() - 10); + } +} + +QModelIndex GlodonTreeView::findLastModelIndex(const QModelIndex &index, const QModelIndex &parentIndex, int nCurrentHeight) +{ + //如果当前高度已经操作了viewport,就返回上一个节点 + if (nCurrentHeight + rowHeight(index) > viewport()->height()) + { + return model()->index(index.row() - 1, 0, index.parent()); + } + //如果当前节点已经是无效,且父是为即将要展开的节点,而且当前高度还超过viewport,那么就应该找当前展开节点的兄弟,或者父的兄弟 + else if (!index.isValid() && parentIndex == m_expandIndex + && (nCurrentHeight < viewport()->height())) + { + QModelIndex nextValidSiblingIndex = index; + QModelIndex currentParentIndex = parentIndex; + while (true) + { + nextValidSiblingIndex = model()->index(currentParentIndex.row() + 1, 0, currentParentIndex.parent()); + currentParentIndex = currentParentIndex.parent(); + if (nextValidSiblingIndex.isValid() || currentParentIndex == QModelIndex()) + { + break; + } + } + if ((nCurrentHeight + rowHeight(nextValidSiblingIndex) > viewport()->height()) + || (!currentParentIndex.isValid() && !nextValidSiblingIndex.isValid())) + { + return model()->index(model()->rowCount(parentIndex) - 1, 0, parentIndex); + } + else + { + return nextValidSiblingIndex; + } + } + else + { + //如果有子且为展开状态,则从第一个子开始找,否则,就找下一个兄弟 + if (model()->hasChildren(index)) + { + if (isExpanded(index)) + { + if (nCurrentHeight + rowHeight(index) > viewport()->height()) + { + return index; + } + else + { + return findLastModelIndex(model()->index(0, 0, index), index, nCurrentHeight + rowHeight(index)); + } + } + } + QModelIndex currentIndex = model()->index(index.row() + 1, 0, index.parent()); + return findLastModelIndex(currentIndex, index.parent(), rowHeight(index) + nCurrentHeight); + } +} + +void GlodonTreeView::setErrorMessage(int errCode, const QString &errMessage) +{ + m_errCode = errCode; + m_errMessage = errMessage; +} + +GLDTreeDefaultDelegaet::GLDTreeDefaultDelegaet(QObject *parent) + : QStyledItemDelegate(parent) +{ +} + +void GLDTreeDefaultDelegaet::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const +{ + const_cast(this)->doSetModelData(editor, model, index); +} + +/*! + * \brief 在设置值的时候不允许抛出任何异常,暂时先将异常延后抛出。 + * \param editor + * \param model + * \param index + */ +void GLDTreeDefaultDelegaet::doSetModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) +{ + try + { + QStyledItemDelegate::setModelData(editor, model, index); + } + catch (const GLDException &e) + { + dynamic_cast(parent())->setErrorMessage(e.errorCode(), e.message()); + } + catch (...) + { + } +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDTreeViewEx.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDTreeViewEx.cpp new file mode 100644 index 00000000..362812b0 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDTreeViewEx.cpp @@ -0,0 +1,180 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "GLDFileUtils.h" +#include "GLDTreeViewEx.h" +#include "GLDScrollStyle.h" + +const QString c_sTreeViewQssFile = ":/qsses/GlodonTreeViewEx.qss"; + +const int c_itemIndentation = 17; +const QString c_addIconPath = ":/icons/GlodonTreeView-add.png"; +const QString c_subIconPath = ":/icons/GlodonTreeView-sub.png"; +const QString c_bottomIconPath = ":/icons/GlodonTreeView-bottom.png"; +const QString c_hoverIconPath = ":/icons/GlodonTreeView-hover.png"; +const QFont c_rootFont = QFont("Simsun", 12, QFont::Bold); +const QFont c_otherFont = QFont("Simsun", 12); + +GlodonTreeViewEx::GlodonTreeViewEx(QWidget *parent) + : GlodonTreeView(parent), + m_defaultDelegate(NULL) +{ + init(); +} + +void GlodonTreeViewEx::init() +{ + setIndentation(c_itemIndentation); + setExpandsOnDoubleClick(true); + setMouseTracking(true); + + this->setStyleSheet(loadQssFile(c_sTreeViewQssFile)); + setStyle(new GLDScrollStyle(this)); + connect(this, SIGNAL(expanded(QModelIndex)), + this, SLOT(doAfterExpand(QModelIndex))); + + m_defaultDelegate = new GlodonTreeDelegateEx(this); + setItemDelegate(m_defaultDelegate); +} + +void GlodonTreeViewEx::doAfterExpand(const QModelIndex &index) +{ + m_expandedIndex = index; +} + +void GlodonTreeViewEx::setModel(QAbstractItemModel *model) +{ + GlodonTreeView::setModel(model); +} + +QModelIndex GlodonTreeViewEx::topParentIndex(const QModelIndex &index) +{ + QModelIndex modelIndex = index; + if (!modelIndex.isValid()) + { + return QModelIndex(); + } + + while(modelIndex.parent().isValid()) + { + modelIndex = modelIndex.parent(); + } + return modelIndex; +} + +int GlodonTreeViewEx::currentIndexlLevel(const QModelIndex &index) +{ + QModelIndex modelIndex = index; + if (!modelIndex.isValid()) + { + return -1; + } + + int level = 0; + for ( ; modelIndex.parent().isValid(); ++level ) + { + modelIndex = modelIndex.parent(); + } + return level; +} + +QModelIndex GlodonTreeViewEx::expandedIndex() +{ + return m_expandedIndex; +} + +GlodonTreeDelegateEx::GlodonTreeDelegateEx(GlodonTreeViewEx *parent) + : QStyledItemDelegate(parent) + , m_pTreeView(parent) + , m_rootFont(c_rootFont) + , m_otherFont(c_otherFont) +{ +} + +void GlodonTreeDelegateEx::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + QStyleOptionViewItem optionItem = option; + QRect rect = optionItem.rect; + + if (m_pTreeView->currentIndexlLevel(index) == 0) + { + // 第一层缩进为5像素 + rect.adjust(5, 0, 0, 0); + } + // 右侧距离边线或者滚动条8像素 + rect.adjust(0, 0, -8, 0); + optionItem.rect = rect; + QPixmap image = decorationIcon(index); + int nPosx = rect.x() - 14; + int nPosy = rect.y() + rect.height() / 2 - image.height() / 2; + painter->drawPixmap(nPosx, nPosy, image.width(), image.height(), image); + + QVariant value = fontSize(index); + if (value.isValid() && !value.isNull()) + { + optionItem.font = qvariant_cast(value).resolve(optionItem.font); + optionItem.fontMetrics = QFontMetrics(optionItem.font); + } + + QStyledItemDelegate::paint(painter, optionItem, index); +} + +QFont GlodonTreeDelegateEx::fontSize(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return QFont(); + } + + QModelIndex currentIndex = m_pTreeView->expandedIndex(); + if (!currentIndex.isValid() && m_pTreeView->topParentIndex(currentIndex) == index) + { + return m_rootFont; + } + return m_otherFont; +} + +QPixmap GlodonTreeDelegateEx::decorationIcon(const QModelIndex &index) const +{ + if (!index.isValid()) + { + return QPixmap(); + } + + QModelIndex currentIndex = m_pTreeView->expandedIndex(); + + if (index.model()->hasChildren(index)) + { + if (m_pTreeView->isExpanded(index)) + { + return QPixmap(c_subIconPath); + } + else + { + return QPixmap(c_addIconPath); + } + } + else + { + if (currentIndex.isValid() && index.parent() == currentIndex) + { + return QPixmap(c_hoverIconPath); + } + else + { + return QPixmap(c_bottomIconPath); + } + } + return QPixmap(); +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDTreeWidget.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDTreeWidget.cpp new file mode 100644 index 00000000..7627c1c8 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDTreeWidget.cpp @@ -0,0 +1 @@ +#include "GLDTreeWidget.h" diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDWAbstractspinbox.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDWAbstractspinbox.cpp new file mode 100644 index 00000000..e9ea2dd7 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDWAbstractspinbox.cpp @@ -0,0 +1,2162 @@ +#include +#include +#include +#include +#include "GLDWAbstractspinbox.h" +#include "GLDTextEdit.h" + +#ifndef QT_NO_SPINBOX + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef GLDWAbstractSpinBox_QSBDEBUG +#include +#endif +#ifndef QT_NO_ACCESSIBILITY +# include +#endif + + +//#define GLDWAbstractSpinBox_QSBDEBUG +#ifdef GLDWAbstractSpinBox_QSBDEBUG +# define QASBDEBUG qDebug +#else +# define QASBDEBUG if (false) qDebug +#endif + + +#if (QT_VERSION > QT_VERSION_CHECK(5, 1, 1)) +#define QDATETIMEEDIT_TIME_MIN QTime(0, 0, 0, 0) +#define QDATETIMEEDIT_TIME_MAX QTime(23, 59, 59, 999) +#define QDATETIMEEDIT_DATE_MIN QDate(100, 1, 1) +#define QDATETIMEEDIT_COMPAT_DATE_MIN QDate(1752, 9, 14) +#define QDATETIMEEDIT_DATE_MAX QDate(7999, 12, 31) +#define QDATETIMEEDIT_DATETIME_MIN QDateTime(QDATETIMEEDIT_DATE_MIN, QDATETIMEEDIT_TIME_MIN) +#define QDATETIMEEDIT_COMPAT_DATETIME_MIN QDateTime(QDATETIMEEDIT_COMPAT_DATE_MIN, QDATETIMEEDIT_TIME_MIN) +#define QDATETIMEEDIT_DATETIME_MAX QDateTime(QDATETIMEEDIT_DATE_MAX, QDATETIMEEDIT_TIME_MAX) +#define QDATETIMEEDIT_DATE_INITIAL QDate(2000, 1, 1) +#endif + +const int c_FixedPlaintEditText = 25; + +GLDWAbstractSpinBox::GLDWAbstractSpinBox(QWidget *parent) + : QWidget(*new GLDWAbstractSpinBoxPrivate, parent, 0) +{ + Q_D(GLDWAbstractSpinBox); + d->init(); + setObjectName("GLDWAbstractSpinBox"); +} + +/*! + \internal +*/ +GLDWAbstractSpinBox::GLDWAbstractSpinBox(GLDWAbstractSpinBoxPrivate &dd, QWidget *parent) + : QWidget(dd, parent, 0) +{ + Q_D(GLDWAbstractSpinBox); + d->init(); +} + +/*! + Called when the GLDWAbstractSpinBox is destroyed. +*/ + +GLDWAbstractSpinBox::~GLDWAbstractSpinBox() +{ +} + +/*! + \enum GLDWAbstractSpinBox::ButtonSymbols + + This enum type describes the symbols that can be displayed on the buttons + in a spin box. + + \inlineimage qspinbox-updown.png + \inlineimage qspinbox-plusminus.png + + \value UpDownArrows Little arrows in the classic style. + \value PlusMinus \b{+} and \b{-} symbols. + \value NoButtons Don't display buttons. + + \sa GLDWAbstractSpinBox::buttonSymbols +*/ + +/*! + \property GLDWAbstractSpinBox::buttonSymbols + + \brief the current button symbol mode + + The possible values can be either \c UpDownArrows or \c PlusMinus. + The default is \c UpDownArrows. + + Note that some styles might render PlusMinus and UpDownArrows + identically. + + \sa ButtonSymbols +*/ + +QAbstractSpinBox::ButtonSymbols GLDWAbstractSpinBox::buttonSymbols() const +{ + Q_D(const GLDWAbstractSpinBox); + return d->buttonSymbols; +} + +void GLDWAbstractSpinBox::setButtonSymbols(QAbstractSpinBox::ButtonSymbols buttonSymbols) +{ + Q_D(GLDWAbstractSpinBox); + + if (d->buttonSymbols != buttonSymbols) + { + d->buttonSymbols = buttonSymbols; + d->updateEditFieldGeometry(); + update(); + } +} + +/*! + \property GLDWAbstractSpinBox::text + + \brief the spin box's text, including any prefix and suffix + + There is no default text. +*/ + +QString GLDWAbstractSpinBox::text() const +{ + return lineEdit()->toPlainText(); +} + +/*! + \property GLDWAbstractSpinBox::specialValueText + \brief the special-value text + + If set, the spin box will display this text instead of a numeric + value whenever the current value is equal to minimum(). Typical use + is to indicate that this choice has a special (default) meaning. + + For example, if your spin box allows the user to choose a scale factor + (or zoom level) for displaying an image, and your application is able + to automatically choose one that will enable the image to fit completely + within the display window, you can set up the spin box like this: + + \snippet widgets/spinboxes/window.cpp 3 + + The user will then be able to choose a scale from 1% to 1000% + or select "Auto" to leave it up to the application to choose. Your code + must then interpret the spin box value of 0 as a request from the user + to scale the image to fit inside the window. + + All values are displayed with the prefix and suffix (if set), \e + except for the special value, which only shows the special value + text. This special text is passed in the QSpinBox::valueChanged() + signal that passes a QString. + + To turn off the special-value text display, call this function + with an empty string. The default is no special-value text, i.e. + the numeric value is shown as usual. + + If no special-value text is set, specialValueText() returns an + empty string. +*/ + +QString GLDWAbstractSpinBox::specialValueText() const +{ + Q_D(const GLDWAbstractSpinBox); + return d->specialValueText; +} + +void GLDWAbstractSpinBox::setSpecialValueText(const QString &specialValueText) +{ + Q_D(GLDWAbstractSpinBox); + + d->specialValueText = specialValueText; + d->cachedSizeHint = QSize(); // minimumSizeHint doesn't care about specialValueText + d->clearCache(); + d->updateEdit(); +} + +/*! + \property GLDWAbstractSpinBox::wrapping + + \brief whether the spin box is circular. + + If wrapping is true stepping up from maximum() value will take you + to the minimum() value and vica versa. Wrapping only make sense if + you have minimum() and maximum() values set. + + \snippet code/src_gui_widgets_GLDWAbstractSpinBox.cpp 0 + + \sa QSpinBox::minimum(), QSpinBox::maximum() +*/ + +bool GLDWAbstractSpinBox::wrapping() const +{ + Q_D(const GLDWAbstractSpinBox); + return 0 != d->wrapping; +} + +void GLDWAbstractSpinBox::setWrapping(bool wrapping) +{ + Q_D(GLDWAbstractSpinBox); + d->wrapping = wrapping; +} + +/*! + \property GLDWAbstractSpinBox::readOnly + \brief whether the spin box is read only. + + In read-only mode, the user can still copy the text to the + clipboard, or drag and drop the text; + but cannot edit it. + + The QLineEdit in the GLDWAbstractSpinBox does not show a cursor in + read-only mode. + + \sa QLineEdit::readOnly +*/ + +bool GLDWAbstractSpinBox::isReadOnly() const +{ + Q_D(const GLDWAbstractSpinBox); + return 0 != d->readOnly; +} + +void GLDWAbstractSpinBox::setReadOnly(bool enable) +{ + Q_D(GLDWAbstractSpinBox); + d->readOnly = enable; + d->edit->setReadOnly(enable); + update(); +} + +/*! + \property GLDWAbstractSpinBox::keyboardTracking + \brief whether keyboard tracking is enabled for the spinbox. + \since 4.3 + + If keyboard tracking is enabled (the default), the spinbox + emits the valueChanged() signal while the new value is being + entered from the keyboard. + + E.g. when the user enters the value 600 by typing 6, 0, and 0, + the spinbox emits 3 signals with the values 6, 60, and 600 + respectively. + + If keyboard tracking is disabled, the spinbox doesn't emit the + valueChanged() signal while typing. It emits the signal later, + when the return key is pressed, when keyboard focus is lost, or + when other spinbox functionality is used, e.g. pressing an arrow + key. +*/ + +bool GLDWAbstractSpinBox::keyboardTracking() const +{ + Q_D(const GLDWAbstractSpinBox); + return 0 != d->keyboardTracking; +} + +void GLDWAbstractSpinBox::setKeyboardTracking(bool enable) +{ + Q_D(GLDWAbstractSpinBox); + d->keyboardTracking = enable; +} + +/*! + \property GLDWAbstractSpinBox::frame + \brief whether the spin box draws itself with a frame + + If enabled (the default) the spin box draws itself inside a frame, + otherwise the spin box draws itself without any frame. +*/ + +bool GLDWAbstractSpinBox::hasFrame() const +{ + Q_D(const GLDWAbstractSpinBox); + return 0 != d->frame; +} + +void GLDWAbstractSpinBox::setFrame(bool enable) +{ + Q_D(GLDWAbstractSpinBox); + d->frame = enable; + update(); + d->updateEditFieldGeometry(); +} + +/*! + \property GLDWAbstractSpinBox::accelerated + \brief whether the spin box will accelerate the frequency of the steps when + pressing the step Up/Down buttons. + \since 4.2 + + If enabled the spin box will increase/decrease the value faster + the longer you hold the button down. +*/ + +void GLDWAbstractSpinBox::setAccelerated(bool accelerate) +{ + Q_D(GLDWAbstractSpinBox); + d->accelerate = accelerate; + +} + +bool GLDWAbstractSpinBox::isAccelerated() const +{ + Q_D(const GLDWAbstractSpinBox); + return 0 != d->accelerate; +} + +/*! + \enum GLDWAbstractSpinBox::CorrectionMode + + This enum type describes the mode the spinbox will use to correct + an \l{QValidator::}{Intermediate} value if editing finishes. + + \value CorrectToPreviousValue The spinbox will revert to the last + valid value. + + \value CorrectToNearestValue The spinbox will revert to the nearest + valid value. + + \sa correctionMode +*/ + +/*! + \property GLDWAbstractSpinBox::correctionMode + \brief the mode to correct an \l{QValidator::}{Intermediate} + value if editing finishes + \since 4.2 + + The default mode is GLDWAbstractSpinBox::CorrectToPreviousValue. + + \sa acceptableInput, validate(), fixup() +*/ +void GLDWAbstractSpinBox::setCorrectionMode(QAbstractSpinBox::CorrectionMode correctionMode) +{ + Q_D(GLDWAbstractSpinBox); + d->correctionMode = correctionMode; + +} + +QAbstractSpinBox::CorrectionMode GLDWAbstractSpinBox::correctionMode() const +{ + Q_D(const GLDWAbstractSpinBox); + return d->correctionMode; +} + +/*! + \property GLDWAbstractSpinBox::acceptableInput + \brief whether the input satisfies the current validation + \since 4.2 + + \sa validate(), fixup(), correctionMode +*/ + +bool GLDWAbstractSpinBox::hasAcceptableInput() const +{ +// Q_D(const GLDWAbstractSpinBox); + return true; +// return d->edit->hasAcceptableInput(); +} + +/*! + \property GLDWAbstractSpinBox::alignment + \brief the alignment of the spin box + + Possible Values are Qt::AlignLeft, Qt::AlignRight, and Qt::AlignHCenter. + + By default, the alignment is Qt::AlignLeft + + Attempting to set the alignment to an illegal flag combination + does nothing. + + \sa Qt::Alignment +*/ + +Qt::Alignment GLDWAbstractSpinBox::alignment() const +{ +// Q_D(const GLDWAbstractSpinBox); + return Qt::AlignLeft; +// return (Qt::Alignment)d->edit->alignment(); +} + +void GLDWAbstractSpinBox::setAlignment(Qt::Alignment flag) +{ +// Q_D(GLDWAbstractSpinBox); + Q_UNUSED(flag) +// d->edit->setAlignment(flag); +} + +/*! + Selects all the text in the spinbox except the prefix and suffix. +*/ + +void GLDWAbstractSpinBox::selectAll() +{ + Q_D(GLDWAbstractSpinBox); + + d->edit->selectAll(); +} + +/*! + Clears the lineedit of all text but prefix and suffix. +*/ + +void GLDWAbstractSpinBox::clear() +{ + Q_D(GLDWAbstractSpinBox); + + d->edit->setPlainText(d->prefix + d->suffix); +// d->edit->setCursorPosition(d->prefix.size()); + d->cleared = true; +} + +GLDPlainTextEdit *GLDWAbstractSpinBox::lineEdit() const +{ + Q_D(const GLDWAbstractSpinBox); + + return d->edit; +} + +void GLDWAbstractSpinBox::setLineEdit(GLDPlainTextEdit *lineEdit) +{ + Q_D(GLDWAbstractSpinBox); + + if (!lineEdit) + { + Q_ASSERT(lineEdit); + return; + } + + delete d->edit; + d->edit = lineEdit; +// if (!d->edit->validator()) +// d->edit->setValidator(d->validator); + + if (d->edit->parent() != this) + { + d->edit->setParent(this); + } + +// d->edit->setFrame(false); + d->edit->setFocusProxy(this); + d->edit->setAcceptDrops(false); + + if (d->type != QVariant::Invalid) + { + connect(d->edit, SIGNAL(textChanged(QString)), + this, SLOT(_q_editorTextChanged(QString))); + connect(d->edit, SIGNAL(cursorPositionChanged(int, int)), + this, SLOT(_q_editorCursorPositionChanged(int, int))); + } + + d->updateEditFieldGeometry(); + d->edit->setContextMenuPolicy(Qt::NoContextMenu); + + if (isVisible()) + { + d->edit->show(); + } + + if (isVisible()) + { + d->updateEdit(); + } +} + +/*! + This function interprets the text of the spin box. If the value + has changed since last interpretation it will emit signals. +*/ + +void GLDWAbstractSpinBox::interpretText() +{ + Q_D(GLDWAbstractSpinBox); + d->interpret(EmitIfChanged); +} + +/* + Reimplemented in 4.6, so be careful. + */ +/*! + \reimp +*/ +QVariant GLDWAbstractSpinBox::inputMethodQuery(Qt::InputMethodQuery query) const +{ + Q_D(const GLDWAbstractSpinBox); + return d->edit->inputMethodQuery(query); +} + +/*! + \reimp +*/ + +bool GLDWAbstractSpinBox::event(QEvent *event) +{ + Q_D(GLDWAbstractSpinBox); + + switch (event->type()) + { + case QEvent::FontChange: + case QEvent::StyleChange: + d->cachedSizeHint = d->cachedMinimumSizeHint = QSize(); + break; + + case QEvent::ApplicationLayoutDirectionChange: + case QEvent::LayoutDirectionChange: + d->updateEditFieldGeometry(); + break; + + case QEvent::HoverEnter: + case QEvent::HoverLeave: + case QEvent::HoverMove: + if (const QHoverEvent *he = static_cast(event)) + { + d->updateHoverControl(he->pos()); + } + + break; + + case QEvent::ShortcutOverride: + if (d->edit->event(event)) + { + return true; + } + + break; +#ifdef QT_KEYPAD_NAVIGATION + + case QEvent::EnterEditFocus: + case QEvent::LeaveEditFocus: + if (QApplication::keypadNavigationEnabled()) + { + const bool b = d->edit->event(event); + d->edit->setSelection(d->edit->displayText().size() - d->suffix.size(), 0); + + if (event->type() == QEvent::LeaveEditFocus) + { + emit editingFinished(); + } + + if (b) + { + return true; + } + } + + break; +#endif + + case QEvent::InputMethod: + return d->edit->event(event); + + default: + break; + } + + return QWidget::event(event); +} + +/*! + \reimp +*/ + +void GLDWAbstractSpinBox::showEvent(QShowEvent *) +{ + Q_D(GLDWAbstractSpinBox); + d->reset(); + + if (0 != d->ignoreUpdateEdit) + { + d->ignoreUpdateEdit = false; + } + else + { + d->updateEdit(); + } +} + +/*! + \reimp +*/ + +void GLDWAbstractSpinBox::changeEvent(QEvent *event) +{ + Q_D(GLDWAbstractSpinBox); + + switch (event->type()) + { + case QEvent::StyleChange: + d->spinClickTimerInterval = style()->styleHint(QStyle::SH_SpinBox_ClickAutoRepeatRate, 0, this); + d->spinClickThresholdTimerInterval + = style()->styleHint(QStyle::SH_SpinBox_ClickAutoRepeatThreshold, 0, this); + d->reset(); + d->updateEditFieldGeometry(); + break; + + case QEvent::EnabledChange: + if (!isEnabled()) + { + d->reset(); + } + + break; + + case QEvent::ActivationChange: + if (!isActiveWindow()) + { + d->reset(); + + if (0 != d->pendingEmit) // pendingEmit can be true even if it hasn't changed. + { + d->interpret(EmitIfChanged); // E.g. 10 to 10.0 + } + } + + break; + + default: + break; + } + + QWidget::changeEvent(event); +} + +/*! + \reimp +*/ + +void GLDWAbstractSpinBox::resizeEvent(QResizeEvent *event) +{ + Q_D(GLDWAbstractSpinBox); + QWidget::resizeEvent(event); + + d->updateEditFieldGeometry(); + update(); +} + +/*! + \reimp +*/ + +QSize GLDWAbstractSpinBox::sizeHint() const +{ + Q_D(const GLDWAbstractSpinBox); + + if (d->cachedSizeHint.isEmpty()) + { + ensurePolished(); + + const QFontMetrics c_fm(fontMetrics()); + int nH = d->edit->sizeHint().height(); + int nW = 0; + QString strs; + QString strFixedContent = d->prefix + d->suffix + QLatin1Char(' '); + strs = d->textFromValue(d->minimum) + strFixedContent; + nW = qMax(nW, c_fm.width(strs)); + strs = d->textFromValue(d->maximum) + strFixedContent; + nW = qMax(nW, c_fm.width(strs)); + + if (d->specialValueText.size() > 0) + { + strs = d->specialValueText; + nW = qMax(nW, c_fm.width(strs)); + } + + nW += 2; // cursor blinking space + + QStyleOptionSpinBox opt; + initStyleOption(&opt); + QSize hint(nW, nH); + d->cachedSizeHint = style()->sizeFromContents(QStyle::CT_SpinBox, &opt, hint, this) + .expandedTo(QApplication::globalStrut()); + } + + d->cachedSizeHint.setHeight(c_FixedPlaintEditText); + return d->cachedSizeHint; +} + +/*! + \reimp +*/ + +QSize GLDWAbstractSpinBox::minimumSizeHint() const +{ + Q_D(const GLDWAbstractSpinBox); + + if (d->cachedMinimumSizeHint.isEmpty()) + { + //Use the prefix and range to calculate the minimumSizeHint + ensurePolished(); + + const QFontMetrics c_fm(fontMetrics()); + int nH = d->edit->minimumSizeHint().height(); + int nW = 0; + + QString strs; + QString strFixedContent = d->prefix + QLatin1Char(' '); + strs = d->textFromValue(d->minimum) + strFixedContent; + nW = qMax(nW, c_fm.width(strs)); + strs = d->textFromValue(d->maximum) + strFixedContent; + nW = qMax(nW, c_fm.width(strs)); + + if (d->specialValueText.size() > 0) + { + strs = d->specialValueText; + nW = qMax(nW, c_fm.width(strs)); + } + + nW += 2; // cursor blinking space + + QStyleOptionSpinBox opt; + initStyleOption(&opt); + QSize hint(nW, nH); + + d->cachedMinimumSizeHint = style()->sizeFromContents(QStyle::CT_SpinBox, &opt, hint, this) + .expandedTo(QApplication::globalStrut()); + } + + d->cachedMinimumSizeHint.setHeight(c_FixedPlaintEditText); + return d->cachedMinimumSizeHint; +} + +/*! + \reimp +*/ + +void GLDWAbstractSpinBox::paintEvent(QPaintEvent *) +{ + QStyleOptionSpinBox opt; + initStyleOption(&opt); + QStylePainter painter(this); + painter.drawComplexControl(QStyle::CC_SpinBox, opt); +} + +/*! + \reimp + + This function handles keyboard input. + + The following keys are handled specifically: + \table + \row \li Enter/Return + \li This will reinterpret the text and emit a signal even if the value has not changed + since last time a signal was emitted. + \row \li Up + \li This will invoke stepBy(1) + \row \li Down + \li This will invoke stepBy(-1) + \row \li Page up + \li This will invoke stepBy(10) + \row \li Page down + \li This will invoke stepBy(-10) + \endtable +*/ + + +void GLDWAbstractSpinBox::keyPressEvent(QKeyEvent *event) +{ + Q_D(GLDWAbstractSpinBox); + +// if (!event->toPlainText().isEmpty() && d->edit->cursorPosition() < d->prefix.size()) +// d->edit->setCursorPosition(d->prefix.size()); + + int nsteps = 1; + bool bisPgUpOrDown = false; + + switch (event->key()) + { + case Qt::Key_PageUp: + case Qt::Key_PageDown: + nsteps *= 10; + bisPgUpOrDown = true; + + case Qt::Key_Up: + case Qt::Key_Down: + { +#ifdef QT_KEYPAD_NAVIGATION + + if (QApplication::keypadNavigationEnabled()) + { + // Reserve up/down for nav - use left/right for edit. + if (!hasEditFocus() && (event->key() == Qt::Key_Up + || event->key() == Qt::Key_Down)) + { + event->ignore(); + return; + } + } + +#endif +// event->accept(); +// const bool up = (event->key() == Qt::Key_PageUp || event->key() == Qt::Key_Up); +//// if (!(stepEnabled() & (up ? StepUpEnabled : StepDownEnabled))) +//// return; +// if (!up) +// steps *= -1; +// if (style()->styleHint(QStyle::SH_SpinBox_AnimateButton, 0, this)) { +// d->buttonState = (Keyboard | (up ? Up : Down)); +// } +//// if (d->spinClickTimerId == -1) +//// stepBy(steps); +// if(event->isAutoRepeat() && !isPgUpOrDown) { +// if(d->spinClickThresholdTimerId == -1 && d->spinClickTimerId == -1) { +// d->updateState(up, true); +// } +// } +//#ifndef QT_NO_ACCESSIBILITY +// QAccessibleValueChangeEvent event(this, d->value); +// QAccessible::updateAccessibility(&event); +//#endif +// return; + break; + } + +#ifdef QT_KEYPAD_NAVIGATION + + case Qt::Key_Left: + case Qt::Key_Right: + if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) + { + event->ignore(); + return; + } + + break; + + case Qt::Key_Back: + if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) + { + event->ignore(); + return; + } + + break; +#endif + + case Qt::Key_Enter: + case Qt::Key_Return: + // todo +// d->edit->d_func()->control->clearUndo(); +// d->interpret(d->keyboardTracking ? AlwaysEmit : EmitIfChanged); +// selectAll(); +// event->ignore(); +// emit editingFinished(); +// emit d->edit->returnPressed(); + break; + +#ifdef QT_KEYPAD_NAVIGATION + + case Qt::Key_Select: + if (QApplication::keypadNavigationEnabled()) + { + // Toggles between left/right moving cursor and inc/dec. + setEditFocus(!hasEditFocus()); + } + + return; +#endif + + case Qt::Key_U: + if (Qt::ControlModifier == (event->modifiers() & Qt::ControlModifier) + && QGuiApplication::platformName() == QLatin1String("xcb")) // only X11 + { + event->accept(); + + if (!isReadOnly()) + { + clear(); + } + + return; + } + + break; + + case Qt::Key_End: + case Qt::Key_Home: +// if (event->modifiers() & Qt::ShiftModifier) { +// int currentPos = d->edit->cursorPosition(); +// const QString text = d->edit->displayText(); +// if (event->key() == Qt::Key_End) { +// if ((currentPos == 0 && !d->prefix.isEmpty()) || text.size() - d->suffix.size() <= currentPos) { +// break; // let lineedit handle this +// } else { +// d->edit->setSelection(currentPos, text.size() - d->suffix.size() - currentPos); +// } +// } else { +// if ((currentPos == text.size() && !d->suffix.isEmpty()) || currentPos <= d->prefix.size()) { +// break; // let lineedit handle this +// } else { +// d->edit->setSelection(currentPos, d->prefix.size() - currentPos); +// } +// } +// event->accept(); +// return; +// } + break; + + default: +#ifndef QT_NO_SHORTCUT + if (event == QKeySequence::SelectAll) + { + selectAll(); + event->accept(); + return; + } + +#endif + break; + } + + d->edit->event(event); + + if (!isVisible()) + { + d->ignoreUpdateEdit = true; + } +} + +/*! + \reimp +*/ + +void GLDWAbstractSpinBox::keyReleaseEvent(QKeyEvent *event) +{ + Q_D(GLDWAbstractSpinBox); + + if (d->buttonState & Keyboard && !event->isAutoRepeat()) + { + d->reset(); + } + else + { + d->edit->event(event); + } +} + +/*! + \reimp +*/ + +#ifndef QT_NO_WHEELEVENT +void GLDWAbstractSpinBox::wheelEvent(QWheelEvent *event) +{ + const int c_steps = (event->delta() > 0 ? 1 : -1); + Q_UNUSED(c_steps) //下断点用? +// if (stepEnabled() & (steps > 0 ? StepUpEnabled : StepDownEnabled)) +// stepBy(event->modifiers() & Qt::ControlModifier ? steps * 10 : steps); + event->accept(); +} + +#endif + +/*! + \reimp +*/ + +void GLDWAbstractSpinBox::focusInEvent(QFocusEvent *event) +{ + Q_D(GLDWAbstractSpinBox); + + d->edit->event(event); + + if (event->reason() == Qt::TabFocusReason || event->reason() == Qt::BacktabFocusReason) + { + selectAll(); + } + + QWidget::focusInEvent(event); +} + +/*! + \reimp +*/ + +void GLDWAbstractSpinBox::focusOutEvent(QFocusEvent *event) +{ + Q_D(GLDWAbstractSpinBox); + + if (0 != d->pendingEmit) + { + d->interpret(EmitIfChanged); + } + + d->reset(); + d->edit->event(event); + d->updateEdit(); + QWidget::focusOutEvent(event); + +#ifdef QT_KEYPAD_NAVIGATION + + // editingFinished() is already emitted on LeaveEditFocus + if (!QApplication::keypadNavigationEnabled()) +#endif + emit editingFinished(); +} + +/*! + \reimp +*/ + +void GLDWAbstractSpinBox::closeEvent(QCloseEvent *event) +{ + Q_D(GLDWAbstractSpinBox); + + d->reset(); + + if (0 != d->pendingEmit) + { + d->interpret(EmitIfChanged); + } + + QWidget::closeEvent(event); +} + +/*! + \reimp +*/ + +void GLDWAbstractSpinBox::hideEvent(QHideEvent *event) +{ + Q_D(GLDWAbstractSpinBox); + d->reset(); + + if (0 != d->pendingEmit) + { + d->interpret(EmitIfChanged); + } + + QWidget::hideEvent(event); +} + +/*! + \reimp +*/ + +void GLDWAbstractSpinBox::timerEvent(QTimerEvent *event) +{ + Q_D(GLDWAbstractSpinBox); + + bool bdoStep = false; + + if (event->timerId() == d->spinClickThresholdTimerId) + { + killTimer(d->spinClickThresholdTimerId); + d->spinClickThresholdTimerId = -1; + d->effectiveSpinRepeatRate = d->buttonState & Keyboard + ? qApp->styleHints()->keyboardAutoRepeatRate() + : d->spinClickTimerInterval; + d->spinClickTimerId = startTimer(d->effectiveSpinRepeatRate); + bdoStep = true; + } + else if (event->timerId() == d->spinClickTimerId) + { + if (0 != d->accelerate) + { + d->acceleration = d->acceleration + (int)(d->effectiveSpinRepeatRate * 0.05); + + if (d->effectiveSpinRepeatRate - d->acceleration >= 10) + { + killTimer(d->spinClickTimerId); + d->spinClickTimerId = startTimer(d->effectiveSpinRepeatRate - d->acceleration); + } + } + + bdoStep = true; + } + + if (bdoStep) + { +// const StepEnabled st = stepEnabled(); +// if (d->buttonState & Up) { +// if (!(st & StepUpEnabled)) { +// d->reset(); +// } else { +// stepBy(1); +// } +// } else if (d->buttonState & Down) { +// if (!(st & StepDownEnabled)) { +// d->reset(); +// } else { +// stepBy(-1); +// } +// } + return; + } + + QWidget::timerEvent(event); + return; +} + +/*! + \reimp +*/ + +void GLDWAbstractSpinBox::contextMenuEvent(QContextMenuEvent *event) +{ +#ifdef QT_NO_CONTEXTMENU + Q_UNUSED(event); +#else + Q_D(GLDWAbstractSpinBox); + + QPointer menu = d->edit->createStandardContextMenu(); + + if (!menu) + { + return; + } + + d->reset(); + + QAction *selAll = new QAction(tr("&Select All"), menu); + Q_UNUSED(selAll) +// menu->insertAction(d->edit->d_func()->selectAllAction, +// selAll); +// menu->removeAction(d->edit->d_func()->selectAllAction); + menu->addSeparator(); +// const uint se = stepEnabled(); + QAction *up = menu->addAction(tr("&Step up")); + Q_UNUSED(up) +// up->setEnabled(se & StepUpEnabled); + QAction *down = menu->addAction(tr("Step &down")); + Q_UNUSED(down) +// down->setEnabled(se & StepDownEnabled); + menu->addSeparator(); + +// const QPointer c_that = this; + const QPoint c_pos = (event->reason() == QContextMenuEvent::Mouse) + ? event->globalPos() : mapToGlobal(QPoint(event->pos().x(), 0)) + QPoint(width() / 2, height() / 2); + const QAction *action = menu->exec(c_pos); + Q_UNUSED(action) + delete static_cast(menu); +// if (that && action) { +// if (action == up) { +// stepBy(1); +// } else if (action == down) { +// stepBy(-1); +// } else if (action == selAll) { +// selectAll(); +// } +// } + event->accept(); +#endif // QT_NO_CONTEXTMENU +} + +/*! + \reimp +*/ + +void GLDWAbstractSpinBox::mouseMoveEvent(QMouseEvent *event) +{ + Q_D(GLDWAbstractSpinBox); + + d->updateHoverControl(event->pos()); + + // If we have a timer ID, update the state + if (d->spinClickTimerId != -1 && d->buttonSymbols != QAbstractSpinBox::NoButtons) + { +// const StepEnabled se = stepEnabled(); +// if ((se & StepUpEnabled) && d->hoverControl == QStyle::SC_SpinBoxUp) +// d->updateState(true); +// else if ((se & StepDownEnabled) && d->hoverControl == QStyle::SC_SpinBoxDown) +// d->updateState(false); +// else +// d->reset(); +// event->accept(); + } +} + +/*! + \reimp +*/ + +void GLDWAbstractSpinBox::mousePressEvent(QMouseEvent *event) +{ + Q_D(GLDWAbstractSpinBox); + + if (event->button() != Qt::LeftButton || d->buttonState != None) + { + return; + } + + d->updateHoverControl(event->pos()); + event->accept(); + +// const StepEnabled se = (d->buttonSymbols == QAbstractSpinBox::NoButtons) ? StepEnabled(StepNone) : stepEnabled(); +// if ((se & StepUpEnabled) && d->hoverControl == QStyle::SC_SpinBoxUp) { +// d->updateState(true); +// } else if ((se & StepDownEnabled) && d->hoverControl == QStyle::SC_SpinBoxDown) { +// d->updateState(false); +// } else { +// event->ignore(); +// } +} + +/*! + \reimp +*/ +void GLDWAbstractSpinBox::mouseReleaseEvent(QMouseEvent *event) +{ + Q_D(GLDWAbstractSpinBox); + + if ((d->buttonState & Mouse) != 0) + { + d->reset(); + } + + event->accept(); +} + +// --- GLDWAbstractSpinBoxPrivate --- + +/*! + \internal + Constructs a GLDWAbstractSpinBoxPrivate object +*/ + +GLDWAbstractSpinBoxPrivate::GLDWAbstractSpinBoxPrivate() + : edit(0), type(QVariant::Invalid), spinClickTimerId(-1), + spinClickTimerInterval(100), spinClickThresholdTimerId(-1), spinClickThresholdTimerInterval(-1), + effectiveSpinRepeatRate(1), buttonState(None), cachedText(QLatin1String("\x01")), + cachedState(QValidator::Invalid), pendingEmit(false), readOnly(false), wrapping(false), + ignoreCursorPositionChanged(false), frame(true), accelerate(false), keyboardTracking(true), + cleared(false), ignoreUpdateEdit(false), correctionMode(QAbstractSpinBox::CorrectToPreviousValue), + acceleration(0), hoverControl(QStyle::SC_None), buttonSymbols(QAbstractSpinBox::UpDownArrows) +{ +} + +/* + \internal + Called when the GLDWAbstractSpinBoxPrivate is destroyed +*/ +GLDWAbstractSpinBoxPrivate::~GLDWAbstractSpinBoxPrivate() +{ +} + +/*! + \internal + Updates the old and new hover control. Does nothing if the hover + control has not changed. +*/ +bool GLDWAbstractSpinBoxPrivate::updateHoverControl(const QPoint &pos) +{ + Q_Q(GLDWAbstractSpinBox); + QRect lastHoverRect = hoverRect; + QStyle::SubControl lastHoverControl = hoverControl; + bool bdoesHover = q->testAttribute(Qt::WA_Hover); + + if (lastHoverControl != newHoverControl(pos) && bdoesHover) + { + q->update(lastHoverRect); + q->update(hoverRect); + return true; + } + + return !bdoesHover; +} + +/*! + \internal + Returns the hover control at \a pos. + This will update the hoverRect and hoverControl. +*/ +QStyle::SubControl GLDWAbstractSpinBoxPrivate::newHoverControl(const QPoint &pos) +{ + Q_Q(GLDWAbstractSpinBox); + + QStyleOptionSpinBox opt; + q->initStyleOption(&opt); + opt.subControls = QStyle::SC_All; + hoverControl = q->style()->hitTestComplexControl(QStyle::CC_SpinBox, &opt, pos, q); + hoverRect = q->style()->subControlRect(QStyle::CC_SpinBox, &opt, hoverControl, q); + return hoverControl; +} + +/*! + \internal + Strips any prefix/suffix from \a text. +*/ + +QString GLDWAbstractSpinBoxPrivate::stripped(const QString &t, int *pos) const +{ + QString text = t; + + if (specialValueText.size() == 0 || text != specialValueText) + { + int nfrom = 0; + int nsize = text.size(); + bool bchanged = false; + + if (prefix.size() > 0 && text.startsWith(prefix)) + { + nfrom += prefix.size(); + nsize -= nfrom; + bchanged = true; + } + + if (suffix.size() > 0 && text.endsWith(suffix)) + { + nsize -= suffix.size(); + bchanged = true; + } + + if (bchanged) + { + text = text.mid(nfrom, nsize); + } + } + + const int c_size = text.size(); + text = text.trimmed(); + + if (pos) + { + (*pos) -= (c_size - text.size()); + } + + return text; + +} + +void GLDWAbstractSpinBoxPrivate::updateEditFieldGeometry() +{ + Q_Q(GLDWAbstractSpinBox); + QStyleOptionSpinBox opt; + q->initStyleOption(&opt); + opt.subControls = QStyle::SC_SpinBoxEditField; + edit->setGeometry(q->style()->subControlRect(QStyle::CC_SpinBox, &opt, + QStyle::SC_SpinBoxEditField, q)); +} + +/*! + \internal + Returns true if a specialValueText has been set and the current value is minimum. +*/ + +bool GLDWAbstractSpinBoxPrivate::specialValue() const +{ + return (value == minimum && !specialValueText.isEmpty()); +} + +/*! + \internal Virtual function that emits signals when the value + changes. Reimplemented in the different subclasses. +*/ + +void GLDWAbstractSpinBoxPrivate::emitSignals(EmitPolicy, const QVariant &) +{ +} + +/*! + \internal + + Slot connected to the line edit's textChanged(const QString &) + signal. +*/ + +void GLDWAbstractSpinBoxPrivate::_q_editorTextChanged(const QString &t) +{ +// Q_Q(GLDWAbstractSpinBox); + + if (0 != keyboardTracking) + { + QString tmp = t; +// int pos = edit->cursorPosition(); +// QValidator::State state = q->validate(tmp, pos); +// if (state == QValidator::Acceptable) + { + const QVariant var = valueFromText(tmp); + setValue(var, EmitIfChanged, tmp != t); + pendingEmit = false; + } +// else +// { +// pendingEmit = true; +// } + } + else + { + pendingEmit = true; + } +} + +/*! + \internal + + Virtual slot connected to the line edit's + cursorPositionChanged(int, int) signal. Will move the cursor to a + valid position if the new one is invalid. E.g. inside the prefix. + Reimplemented in Q[Date|Time|DateTime]EditPrivate to account for + the different sections etc. +*/ + +void GLDWAbstractSpinBoxPrivate::_q_editorCursorPositionChanged(int oldpos, int newpos) +{ + Q_UNUSED(oldpos) + Q_UNUSED(newpos) +// if (!edit->hasSelectedText() && !ignoreCursorPositionChanged && !specialValue()) { +// ignoreCursorPositionChanged = true; + +// bool allowSelection = true; +// int pos = -1; +// if (newpos < prefix.size() && newpos != 0) { +// if (oldpos == 0) { +// allowSelection = false; +// pos = prefix.size(); +// } else { +// pos = oldpos; +// } +// } else if (newpos > edit->toPlainText().size() - suffix.size() +// && newpos != edit->toPlainText().size()) { +// if (oldpos == edit->toPlainText().size()) { +// pos = edit->toPlainText().size() - suffix.size(); +// allowSelection = false; +// } else { +// pos = edit->toPlainText().size(); +// } +// } +// if (pos != -1) { +// const int selSize = edit->selectionStart() >= 0 && allowSelection +// ? (edit->selectedText().size() +// * (newpos < pos ? -1 : 1)) - newpos + pos +// : 0; + +// const bool wasBlocked = edit->blockSignals(true); +// if (selSize != 0) { +// edit->setSelection(pos - selSize, selSize); +// } else { +// edit->setCursorPosition(pos); +// } +// edit->blockSignals(wasBlocked); +// } +// ignoreCursorPositionChanged = false; +// } +} + +/*! + \internal + + Initialises the GLDWAbstractSpinBoxPrivate object. +*/ + +void GLDWAbstractSpinBoxPrivate::init() +{ + Q_Q(GLDWAbstractSpinBox); + + GLDPlainTextEdit *edit = new GLDPlainTextEdit(q); + edit->setContentsMargins(0, 0, 0, 0); + edit->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + edit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + edit->setFixedHeight(q->height()); + q->setLineEdit(edit); + edit->setObjectName(QLatin1String("GLDPlainTextEdit")); +// validator = new GLDWSpinBoxValidator(q, this); +// edit->setValidator(validator); + + QStyleOptionSpinBox opt; + q->initStyleOption(&opt); + spinClickTimerInterval = q->style()->styleHint(QStyle::SH_SpinBox_ClickAutoRepeatRate, &opt, q); + spinClickThresholdTimerInterval = q->style()->styleHint(QStyle::SH_SpinBox_ClickAutoRepeatThreshold, &opt, q); + q->setFocusPolicy(Qt::WheelFocus); + q->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, QSizePolicy::SpinBox)); + q->setAttribute(Qt::WA_InputMethodEnabled); + + q->setAttribute(Qt::WA_MacShowFocusRect); +} + +/*! + \internal + + Resets the state of the spinbox. E.g. the state is set to + (Keyboard|Up) if Key up is currently pressed. +*/ + +void GLDWAbstractSpinBoxPrivate::reset() +{ + Q_Q(GLDWAbstractSpinBox); + + buttonState = None; + + if (q) + { + if (spinClickTimerId != -1) + { + q->killTimer(spinClickTimerId); + } + + if (spinClickThresholdTimerId != -1) + { + q->killTimer(spinClickThresholdTimerId); + } + + spinClickTimerId = spinClickThresholdTimerId = -1; + acceleration = 0; + q->update(); + } +} + +/*! + \internal + + Updates the state of the spinbox. +*/ + +void GLDWAbstractSpinBoxPrivate::updateState(bool up, bool fromKeyboard /* = false */) +{ +// Q_Q(GLDWAbstractSpinBox); + Q_UNUSED(fromKeyboard) + + if ((up && (buttonState & Up)) || (!up && (buttonState & Down))) + { + return; + } + + reset(); +// if (q && (q->stepEnabled() & (up ? GLDWAbstractSpinBox::StepUpEnabled +// : GLDWAbstractSpinBox::StepDownEnabled))) { +// spinClickThresholdTimerId = q->startTimer(spinClickThresholdTimerInterval); +// buttonState = (up ? Up : Down) | (fromKeyboard ? Keyboard : Mouse); +// q->stepBy(up ? 1 : -1); +//#ifndef QT_NO_ACCESSIBILITY +// QAccessibleValueChangeEvent event(q, value); +// QAccessible::updateAccessibility(&event); +//#endif +// } +} + +/*! + Initialize \a option with the values from this QSpinBox. This method + is useful for subclasses when they need a QStyleOptionSpinBox, but don't want + to fill in all the information themselves. + + \sa QStyleOption::initFrom() +*/ + +void GLDWAbstractSpinBox::initStyleOption(QStyleOptionSpinBox *option) const +{ + if (!option) + { + return; + } + + Q_D(const GLDWAbstractSpinBox); + option->initFrom(this); + option->activeSubControls = QStyle::SC_None; + option->buttonSymbols = d->buttonSymbols; + option->subControls = QStyle::SC_SpinBoxFrame | QStyle::SC_SpinBoxEditField; + + if (d->buttonSymbols != QAbstractSpinBox::NoButtons) + { + option->subControls |= QStyle::SC_SpinBoxUp | QStyle::SC_SpinBoxDown; + + if (d->buttonState & Up) + { + option->activeSubControls = QStyle::SC_SpinBoxUp; + } + else if (d->buttonState & Down) + { + option->activeSubControls = QStyle::SC_SpinBoxDown; + } + } + + if (d->buttonState > 0) + { + option->state |= QStyle::State_Sunken; + } + else + { + option->activeSubControls = d->hoverControl; + } + +// option->stepEnabled = style()->styleHint(QStyle::SH_SpinControls_DisableOnBounds) +// ? stepEnabled() +// : (QAbstractSpinBox::StepDownEnabled | QAbstractSpinBox::StepUpEnabled); + + option->frame = (0 != d->frame); +} + +/*! + \internal + + Bounds \a val to be within minimum and maximum. Also tries to be + clever about setting it at min and max depending on what it was + and what direction it was changed etc. +*/ + +QVariant GLDWAbstractSpinBoxPrivate::bound(const QVariant &val, const QVariant &old, int steps) const +{ + QVariant var = val; + + if (0 == wrapping || steps == 0 || old.isNull()) + { + if (variantCompare(var, minimum) < 0) + { + var = (0 != wrapping) ? maximum : minimum; + } + + if (variantCompare(var, maximum) > 0) + { + var = (0 != wrapping) ? minimum : maximum; + } + } + else + { + const bool c_wasMin = old == minimum; + const bool c_wasMax = old == maximum; + const int c_oldcmp = variantCompare(var, old); + const int c_maxcmp = variantCompare(var, maximum); + const int c_mincmp = variantCompare(var, minimum); + const bool c_wrapped = (c_oldcmp > 0 && steps < 0) || (c_oldcmp < 0 && steps > 0); + + if (c_maxcmp > 0) + { + var = ((c_wasMax && !c_wrapped && steps > 0) || (steps < 0 && !c_wasMin && c_wrapped)) + ? minimum : maximum; + } + else if (c_wrapped && (c_maxcmp > 0 || c_mincmp < 0)) + { + var = ((c_wasMax && steps > 0) || (!c_wasMin && steps < 0)) ? minimum : maximum; + } + else if (c_mincmp < 0) + { + var = (!c_wasMax && !c_wasMin ? minimum : maximum); + } + } + + return var; +} + +/*! + \internal + + Sets the value of the spin box to \a val. Depending on the value + of \a ep it will also emit signals. +*/ + +void GLDWAbstractSpinBoxPrivate::setValue(const QVariant &val, EmitPolicy ep, + bool doUpdate) +{ + Q_Q(GLDWAbstractSpinBox); + const QVariant c_old = value; + value = bound(val); + pendingEmit = false; + cleared = false; + + if (doUpdate) + { + updateEdit(); + } + + q->update(); + + if (ep == AlwaysEmit || (ep == EmitIfChanged && c_old != value)) + { + emitSignals(ep, c_old); + } +} + +/*! + \internal + + Updates the line edit to reflect the current value of the spin box. +*/ + +void GLDWAbstractSpinBoxPrivate::updateEdit() +{ + Q_Q(GLDWAbstractSpinBox); + + if (type == QVariant::Invalid) + { + return; + } + + const QString c_newText = specialValue() ? specialValueText : prefix + textFromValue(value) + suffix; + + if (c_newText == edit->toPlainText() || 0 != cleared) + { + return; + } + + const bool c_empty = edit->toPlainText().isEmpty(); + Q_UNUSED(c_empty) +// int cursor = edit->cursorPosition(); +// int selsize = edit->selectedText().size(); + const bool c_sb = edit->blockSignals(true); + edit->setPlainText(c_newText); + +// if (!specialValue()) { +// cursor = qBound(prefix.size(), cursor, edit->displayText().size() - suffix.size()); + +// if (selsize > 0) { +// edit->setSelection(cursor, selsize); +// } else { +// edit->setCursorPosition(empty ? prefix.size() : cursor); +// } +// } + edit->blockSignals(c_sb); + q->update(); +} + +/*! + \internal + + Convenience function to set min/max values. +*/ + +void GLDWAbstractSpinBoxPrivate::setRange(const QVariant &min, const QVariant &max) +{ + Q_Q(GLDWAbstractSpinBox); + + clearCache(); + minimum = min; + maximum = (variantCompare(min, max) < 0 ? max : min); + cachedSizeHint = QSize(); + cachedMinimumSizeHint = QSize(); // minimumSizeHint cares about min/max + + reset(); + + if (!(bound(value) == value)) + { + setValue(bound(value), EmitIfChanged); + } + else if (value == minimum && !specialValueText.isEmpty()) + { + updateEdit(); + } + + q->updateGeometry(); +} + +/*! + \internal + + Convenience function to get a variant of the right type. +*/ + +QVariant GLDWAbstractSpinBoxPrivate::getZeroVariant() const +{ + QVariant ret; + + switch (type) + { + case QVariant::Int: + ret = QVariant((int)0); + break; + + case QVariant::Double: + ret = QVariant((double)0.0); + break; + + default: + break; + } + + return ret; +} + +/*! + \internal + + Virtual method called that calls the public textFromValue() + functions in the subclasses. Needed to change signature from + QVariant to int/double/QDateTime etc. Used when needing to display + a value textually. + + This method is reimeplemented in the various subclasses. +*/ + +QString GLDWAbstractSpinBoxPrivate::textFromValue(const QVariant &) const +{ + return QString(); +} + +/*! + \internal + + Virtual method called that calls the public valueFromText() + functions in the subclasses. Needed to change signature from + QVariant to int/double/QDateTime etc. Used when needing to + interpret a string as another type. + + This method is reimeplemented in the various subclasses. +*/ + +QVariant GLDWAbstractSpinBoxPrivate::valueFromText(const QString &) const +{ + return QVariant(); +} + +/*! + \internal + + Interprets text and emits signals. Called when the spinbox needs + to interpret the text on the lineedit. +*/ + +void GLDWAbstractSpinBoxPrivate::interpret(EmitPolicy ep) +{ +// Q_Q(GLDWAbstractSpinBox); + if (type == QVariant::Invalid || 0 != cleared) + { + return; + } + + QVariant var = getZeroVariant(); + bool bdoInterpret = true; + QString tmp = edit->toPlainText(); +// int pos = edit->cursorPosition(); +// const int oldpos = pos; + +// if (q->validate(tmp, pos) != QValidator::Acceptable) { +// const QString copy = tmp; +// q->fixup(tmp); +// QASBDEBUG() << "GLDWAbstractSpinBoxPrivate::interpret() text '" +// << edit->toPlainText() +// << "' >> '" << copy << '\'' +// << "' >> '" << tmp << '\''; + +// doInterpret = tmp != copy && (q->validate(tmp, pos) == QValidator::Acceptable); +// if (!doInterpret) { +// v = (correctionMode == QAbstractSpinBox::CorrectToNearestValue +// ? variantBound(minimum, v, maximum) : value); +// } +// } + if (bdoInterpret) + { + var = valueFromText(tmp); + } + + clearCache(); + setValue(var, ep, true); +// if (oldpos != pos) +// edit->setCursorPosition(pos); +} + +void GLDWAbstractSpinBoxPrivate::clearCache() const +{ + cachedText.clear(); + cachedValue.clear(); + cachedState = QValidator::Acceptable; +} + +// --- GLDWSpinBoxValidator --- + +/*! + \internal + Constructs a GLDWSpinBoxValidator object +*/ + +//GLDWSpinBoxValidator::GLDWSpinBoxValidator(GLDWAbstractSpinBox *qp, GLDWAbstractSpinBoxPrivate *dp) +// : QValidator(qp), qptr(qp), dptr(dp) +//{ +// setObjectName(QLatin1String("toPlainText_validator")); +//} + +// --- global --- + +/*! + \internal + Adds two variants together and returns the result. +*/ + +QVariant operator+(const QVariant &arg1, const QVariant &arg2) +{ + QVariant ret; + + if (arg1.type() != arg2.type()) + qWarning("GLDWAbstractSpinBox: Internal error: Different types (%s vs %s) (%s:%d)", + arg1.typeName(), arg2.typeName(), __FILE__, __LINE__); + + switch (arg1.type()) + { + case QVariant::Int: + { + const int c_int1 = arg1.toInt(); + const int c_int2 = arg2.toInt(); + + if (c_int1 > 0 && (c_int2 >= INT_MAX - c_int1)) + { + // The increment overflows + ret = QVariant(INT_MAX); + } + else if (c_int1 < 0 && (c_int2 <= INT_MIN - c_int1)) + { + // The increment underflows + ret = QVariant(INT_MIN); + } + else + { + ret = QVariant(c_int1 + c_int2); + } + + break; + } + + case QVariant::Double: + ret = QVariant(arg1.toDouble() + arg2.toDouble()); + break; + + case QVariant::DateTime: + { + QDateTime a2 = arg2.toDateTime(); + QDateTime a1 = arg1.toDateTime().addDays(QDATETIMEEDIT_DATETIME_MIN.daysTo(a2)); + a1.setTime(a1.time().addMSecs(QTime().msecsTo(a2.time()))); + ret = QVariant(a1); + } + + default: + break; + } + + return ret; +} + +/*! + \internal + Subtracts two variants and returns the result. +*/ + +QVariant operator-(const QVariant &arg1, const QVariant &arg2) +{ + QVariant ret; + + if (arg1.type() != arg2.type()) + qWarning("GLDWAbstractSpinBox: Internal error: Different types (%s vs %s) (%s:%d)", + arg1.typeName(), arg2.typeName(), __FILE__, __LINE__); + + switch (arg1.type()) + { + case QVariant::Int: + ret = QVariant(arg1.toInt() - arg2.toInt()); + break; + + case QVariant::Double: + ret = QVariant(arg1.toDouble() - arg2.toDouble()); + break; + + case QVariant::DateTime: + { + QDateTime a1 = arg1.toDateTime(); + QDateTime a2 = arg2.toDateTime(); + int ndays = a2.daysTo(a1); + int nsecs = a2.secsTo(a1); + int nmsecs = qMax(0, a1.time().msec() - a2.time().msec()); + + if (ndays < 0 || nsecs < 0 || nmsecs < 0) + { + ret = arg1; + } + else + { + QDateTime dt = a2.addDays(ndays).addSecs(nsecs); + + if (nmsecs > 0) + { + dt.setTime(dt.time().addMSecs(nmsecs)); + } + + ret = QVariant(dt); + } + } + + default: + break; + } + + return ret; +} + +/*! + \internal + Multiplies \a arg1 by \a multiplier and returns the result. +*/ + +QVariant operator*(const QVariant &arg1, double multiplier) +{ + QVariant ret; + + switch (arg1.type()) + { + case QVariant::Int: + ret = static_cast(qBound(INT_MIN, arg1.toInt() * multiplier, INT_MAX)); + break; + + case QVariant::Double: + ret = QVariant(arg1.toDouble() * multiplier); + break; + + case QVariant::DateTime: + { + double days = QDATETIMEEDIT_DATE_MIN.daysTo(arg1.toDateTime().date()) * multiplier; + int ndaysInt = (int)days; + days -= ndaysInt; + long lmsecs = (long)((QDATETIMEEDIT_TIME_MIN.msecsTo(arg1.toDateTime().time()) * multiplier) + + (days * (24 * 3600 * 1000))); + ret = QDateTime(QDate().addDays(int(days)), QTime().addMSecs(lmsecs)); + break; + } + + default: + ret = arg1; + break; + } + + return ret; +} + +double operator/(const QVariant &arg1, const QVariant &arg2) +{ + double da1 = 0; + double da2 = 0; + + switch (arg1.type()) + { + case QVariant::Int: + da1 = (double)arg1.toInt(); + da2 = (double)arg2.toInt(); + break; + + case QVariant::Double: + da1 = arg1.toDouble(); + da2 = arg2.toDouble(); + break; + + case QVariant::DateTime: + da1 = QDATETIMEEDIT_DATE_MIN.daysTo(arg1.toDate()); + da2 = QDATETIMEEDIT_DATE_MIN.daysTo(arg2.toDate()); + da1 += (double)QDATETIMEEDIT_TIME_MIN.msecsTo(arg1.toDateTime().time()) / (long)(3600 * 24 * 1000); + da2 += (double)QDATETIMEEDIT_TIME_MIN.msecsTo(arg2.toDateTime().time()) / (long)(3600 * 24 * 1000); + + default: + break; + } + + return (da1 != 0 && da2 != 0) ? (da1 / da2) : 0.0; +} + +int GLDWAbstractSpinBoxPrivate::variantCompare(const QVariant &arg1, const QVariant &arg2) +{ + switch (arg2.type()) + { + case QVariant::Date: + Q_ASSERT_X(arg1.type() == QVariant::Date, "GLDWAbstractSpinBoxPrivate::variantCompare", + qPrintable(QString::fromLatin1("Internal error 1 (%1)"). + arg(QString::fromLatin1(arg1.typeName())))); + + if (arg1.toDate() == arg2.toDate()) + { + return 0; + } + else if (arg1.toDate() < arg2.toDate()) + { + return -1; + } + else + { + return 1; + } + + case QVariant::Time: + Q_ASSERT_X(arg1.type() == QVariant::Time, "GLDWAbstractSpinBoxPrivate::variantCompare", + qPrintable(QString::fromLatin1("Internal error 2 (%1)"). + arg(QString::fromLatin1(arg1.typeName())))); + + if (arg1.toTime() == arg2.toTime()) + { + return 0; + } + else if (arg1.toTime() < arg2.toTime()) + { + return -1; + } + else + { + return 1; + } + + + case QVariant::DateTime: + if (arg1.toDateTime() == arg2.toDateTime()) + { + return 0; + } + else if (arg1.toDateTime() < arg2.toDateTime()) + { + return -1; + } + else + { + return 1; + } + + case QVariant::Int: + if (arg1.toInt() == arg2.toInt()) + { + return 0; + } + else if (arg1.toInt() < arg2.toInt()) + { + return -1; + } + else + { + return 1; + } + + case QVariant::Double: + if (arg1.toDouble() == arg2.toDouble()) + { + return 0; + } + else if (arg1.toDouble() < arg2.toDouble()) + { + return -1; + } + else + { + return 1; + } + + case QVariant::Invalid: + if (arg2.type() == QVariant::Invalid) + { + return 0; + } + + default: + Q_ASSERT_X(0, "GLDWAbstractSpinBoxPrivate::variantCompare", + qPrintable(QString::fromLatin1("Internal error 3 (%1 %2)"). + arg(QString::fromLatin1(arg1.typeName())). + arg(QString::fromLatin1(arg2.typeName())))); + } + + return -2; +} + +QVariant GLDWAbstractSpinBoxPrivate::variantBound(const QVariant &min, + const QVariant &value, + const QVariant &max) +{ + Q_ASSERT(variantCompare(min, max) <= 0); + + if (variantCompare(min, value) < 0) + { + const int c_compMax = variantCompare(value, max); + return (c_compMax < 0 ? value : max); + } + else + { + return min; + } +} + +#endif // QT_NO_SPINBOX diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDWebLogin.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDWebLogin.cpp new file mode 100644 index 00000000..da8e7841 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDWebLogin.cpp @@ -0,0 +1,437 @@ +#include +#include +#include +#include +#include + +#include "GLDStrings.h" +#include "GLDWebLogin.h" +#include "GLDFileUtils.h" +#include "GLDKeyboardInput.h" + +const int c_nEditWidth = 180; +const int c_nSpaces = 6; +const int c_nMinLabelHeight = 23; +const int c_nKeyBoardWidth = 16; +const int c_nKeyBoardHeight = 16; +const int c_nLoginButtonWidth = 90; +const int c_nLoginButtonHeight = 28; +const int c_nButtonTextSize = 12; +const int c_nKeyBoardInputeWidth = 359; +const int c_nKeyBoardInputeHeight = 107; +const int c_nMaxMainSize = 310; + +const QSize c_mainSize = QSize(370, 290); +const QSize c_loginTitleSize = QSize(370, 129); +const QSize c_closeButtonSize = QSize(40, 19); + +const QMargins c_userNameContentsMargins = QMargins(32, 15, 32, 0); +const QMargins c_rememberContentsMargins = QMargins(94, 15, 94, 0); +const QMargins c_textMargins = QMargins(5, 0, 5, 0); +const QMargins c_centerMargins = QMargins(0, 15, 0, 0); +const QMargins c_errorInfoMargins = QMargins(0, 10, 0, 5); +const QMargins c_loginButtonMargins = QMargins(0, 0, 0, 13); +const QMargins c_mainMargins = QMargins(0, 0, 0, 0); + +const GString c_sLoginQssFile = ":/qsses/GBTPurpleStyle.qss"; + +GLDWebLogin::GLDWebLogin(QWidget *parent) + : QDialog(parent), + m_sRegisterAccountURL(GString()), + m_sRetrievePasswordURL(GString()), + m_loginState(seUnknow) +{ + m_edtPassword = new QLineEdit(this); + m_edtAccount = new QLineEdit(this); + m_btnKeyboard = new QPushButton(m_edtPassword); + m_btnInfo = new QPushButton(this); + m_btnLogin = new QPushButton(getGLDi18nStr(g_rsLogin), this); + + this->setStyleSheet(loadQssFile(c_sLoginQssFile)); + setUpUI(); +} + +GLDWebLogin::~GLDWebLogin() +{ + +} + +void GLDWebLogin::setRegisterAccountURL(const GString ®isterAccountURL) +{ + m_sRegisterAccountURL = registerAccountURL; +} + +GString GLDWebLogin::registerAccountURL() +{ + return m_sRegisterAccountURL; +} + +void GLDWebLogin::setRetrievePasswordURL(const GString &retrievePasswordURL) +{ + m_sRetrievePasswordURL = retrievePasswordURL; +} + +GString GLDWebLogin::retrievePasswordURL() +{ + return m_sRetrievePasswordURL; +} + +void GLDWebLogin::setLoginState(GLDLoginState loginState) +{ + m_loginState = loginState; +} + +GLDLoginState GLDWebLogin::loginState() +{ + return m_loginState; +} + +void GLDWebLogin::addTitle(QVBoxLayout *pMainlayout) +{ + QHBoxLayout *pTitlelayout = new QHBoxLayout; + GLDLoginTitle *pLblTitle = new GLDLoginTitle(this); + pLblTitle->setObjectName("GLDLoginTitle"); + pTitlelayout->addWidget(pLblTitle, 0, Qt::AlignTop); + pMainlayout->addLayout(pTitlelayout); + connect(pLblTitle, SIGNAL(sigCloseClicked()), this, SLOT(close())); +} + +void GLDWebLogin::addUserName(QVBoxLayout *pCenterlayout) +{ + // 用户名区域布局 + QHBoxLayout *pAccountLayout = new QHBoxLayout; + pAccountLayout->setContentsMargins(c_userNameContentsMargins); + pAccountLayout->setSpacing(c_nSpaces); + + QLabel *pLblAccount = new QLabel(this); + pLblAccount->setText(getGLDi18nStr(g_rsAccount)); + pLblAccount->setMinimumHeight(c_nMinLabelHeight); + pAccountLayout->addWidget(pLblAccount); + + // 用户名输入框 + m_edtAccount->setObjectName("UserNameAndPassWord"); + m_edtAccount->setFixedWidth(c_nEditWidth); + m_edtAccount->setTextMargins(c_textMargins); + m_edtAccount->setMinimumHeight(c_nMinLabelHeight); + m_edtAccount->setFocus(); + pAccountLayout->addWidget(m_edtAccount); + + //注册用户按钮 + QPushButton *pBtnRegister = new QPushButton(NULL, this); + pBtnRegister->setObjectName("RegisterUser"); + pBtnRegister->setMinimumHeight(c_nMinLabelHeight); + pBtnRegister->setCursor(Qt::PointingHandCursor); + pBtnRegister->setText(getGLDi18nStr(g_rsRegisterAccount)); + pBtnRegister->setFlat(true); + pAccountLayout->addWidget(pBtnRegister); + pCenterlayout->addLayout(pAccountLayout); + connect(pBtnRegister, SIGNAL(clicked()), this, SLOT(registerAcc())); +} + +void GLDWebLogin::addPassword(QVBoxLayout *pCenterlayout) +{ + // 密码区域布局 + QHBoxLayout *pPassWordLayout = new QHBoxLayout; + pPassWordLayout->setContentsMargins(c_userNameContentsMargins); + pPassWordLayout->setSpacing(c_nSpaces); + + QLabel *pLblPassword = new QLabel(this); + pLblPassword->setText(getGLDi18nStr(g_rsPassword)); + pLblPassword->setMinimumHeight(c_nMinLabelHeight); + pPassWordLayout->addWidget(pLblPassword); + + // 密码输入框 + m_edtPassword->setObjectName("UserNameAndPassWord"); + m_edtPassword->setFixedWidth(c_nEditWidth); + m_edtPassword->setMinimumHeight(c_nMinLabelHeight); + m_edtPassword->setTextMargins(c_textMargins); + m_edtPassword->setEchoMode(QLineEdit::Password); + pPassWordLayout->addWidget(m_edtPassword); + + // 虚拟键盘,用于输入密码 + m_btnKeyboard->setFixedSize(c_nKeyBoardWidth, c_nKeyBoardHeight); + m_btnKeyboard->setMinimumHeight(c_nKeyBoardHeight); + m_btnKeyboard->setObjectName("VirtualKeyboard"); + m_btnKeyboard->setToolTip(getGLDi18nStr(g_rsOpenVirtualKeyboard)); + m_btnKeyboard->setFocusPolicy(Qt::NoFocus); + m_btnKeyboard->setCursor(Qt::PointingHandCursor); + connect(m_btnKeyboard, SIGNAL(clicked()), this, SLOT(openKeyboard())); + + // 找回密码按钮 + QPushButton *pBtnRetrievepassword = new QPushButton(NULL, this); + pBtnRetrievepassword->setMinimumHeight(c_nMinLabelHeight); + pBtnRetrievepassword->setObjectName("RetrivePassword"); + pBtnRetrievepassword->setCursor(Qt::PointingHandCursor); + pPassWordLayout->addWidget(pBtnRetrievepassword); + pBtnRetrievepassword->setText(getGLDi18nStr(g_rsGetBackPassword)); + pBtnRetrievepassword->setFlat(true); + pCenterlayout->addLayout(pPassWordLayout); + connect(pBtnRetrievepassword, SIGNAL(clicked()), this, SLOT(retrievePass())); +} + +void GLDWebLogin::addCheckBoxes(QVBoxLayout *pCenterlayout) +{ + QHBoxLayout *rememberAndloginLayout = new QHBoxLayout; + pCenterlayout->addLayout(rememberAndloginLayout); + rememberAndloginLayout->setContentsMargins(c_rememberContentsMargins); + + QCheckBox *pRemeberPass = new QCheckBox(this); + pRemeberPass->setObjectName("RememberPassWord"); + pRemeberPass->setMinimumHeight(c_nMinLabelHeight); + rememberAndloginLayout->addWidget(pRemeberPass, 0, Qt::AlignCenter); + pRemeberPass->setText(getGLDi18nStr(g_rsRemeberPassword)); + rememberAndloginLayout->addStretch(1); + + QCheckBox *pAutoLogin = new QCheckBox(this); + if(pAutoLogin->checkState() == Qt::Checked) + { + pRemeberPass->setChecked(true); + } + pAutoLogin->setObjectName("RememberPassWord"); + pAutoLogin->setMinimumHeight(c_nMinLabelHeight); + rememberAndloginLayout->addWidget(pAutoLogin, 0, Qt::AlignCenter); + pAutoLogin->setText(getGLDi18nStr(g_rsAutoLogin)); +} + +void GLDWebLogin::addCenter(QVBoxLayout *pMainlayout) +{ + QVBoxLayout *pCenterlayout = new QVBoxLayout(); + pCenterlayout->setContentsMargins(c_centerMargins); + pMainlayout->addLayout(pCenterlayout); + + // "用户名"区域水平布局 + addUserName(pCenterlayout); + // "密码"区域水平布局 + addPassword(pCenterlayout); + // 记住密码和自动登录 + addCheckBoxes(pCenterlayout); +} + +void GLDWebLogin::addErrorInfo(QVBoxLayout *pMainlayout) +{ + QHBoxLayout *pHlyInfo = new QHBoxLayout; + pMainlayout->addLayout(pHlyInfo); + pHlyInfo->setContentsMargins(c_errorInfoMargins); + + m_btnInfo->setFixedHeight(c_nMinLabelHeight); + m_btnInfo->setAttribute(Qt::WA_TranslucentBackground); + m_btnInfo->setObjectName("ErrorInformation"); + m_btnInfo->setFlat(true); + m_btnInfo->hide(); + + pHlyInfo->addStretch(); + pHlyInfo->addWidget(m_btnInfo); + pHlyInfo->addStretch(); +} + +void GLDWebLogin::addLoginButton(QVBoxLayout *pMainlayout) +{ + QHBoxLayout *pHlyButtonGroup = new QHBoxLayout; + pHlyButtonGroup->addStretch(); + pHlyButtonGroup->setContentsMargins(c_loginButtonMargins); + pMainlayout->addLayout(pHlyButtonGroup); + + m_btnLogin->setObjectName("Login"); + m_btnLogin->setFixedSize(c_nLoginButtonWidth, c_nLoginButtonHeight); + m_btnLogin->setFlat(true); + connect(m_btnLogin, SIGNAL(clicked()), this, SLOT(login())); + + //设置"登录"字体大小 + QFont font = m_btnLogin->font(); + font.setPointSize(c_nButtonTextSize); + m_btnLogin->setFont(font); + + pHlyButtonGroup->addWidget(m_btnLogin); + pHlyButtonGroup->addStretch(); + + pMainlayout->addLayout(pHlyButtonGroup); + setLayout(pMainlayout); +} + +void GLDWebLogin::setUpUI() +{ + //FramelessWindowHint去掉标题栏;WindowStaysOnTopHint设置窗体置顶 + setFixedSize(c_mainSize); + setObjectName("GLDWebLogin"); + setWindowFlags(windowFlags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); + + // 登录窗口主布局 + QVBoxLayout *pMainlayout = new QVBoxLayout(); + pMainlayout->setContentsMargins(c_mainMargins); + // 登录窗口标题布局 + addTitle(pMainlayout); + // 登录窗口中央布局 + addCenter(pMainlayout); + // 错误信息提示 + addErrorInfo(pMainlayout); + // 登录按钮 + addLoginButton(pMainlayout); +} + +void GLDWebLogin::mouseMoveEvent(QMouseEvent *event) +{ + if (event->buttons() == Qt::LeftButton) + { + move(event->globalPos() - m_dragPoint); + event->accept(); + } + else + { + QDialog::mouseMoveEvent(event); + } +} + +void GLDWebLogin::resizeEvent(QResizeEvent *event) +{ + QDialog::resizeEvent(event); + + if((NULL != m_edtPassword) && (NULL != m_btnKeyboard)) + { + m_btnKeyboard->move(m_edtPassword->width()-m_btnKeyboard->width()-2, + (m_edtPassword->height()-m_btnKeyboard->height())/2); + } +} + +void GLDWebLogin::mousePressEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) + { + m_dragPoint = event->globalPos() - frameGeometry().topLeft(); + + event->accept(); + } + else + { + QDialog::mousePressEvent(event); + } +} + +void GLDWebLogin::login() +{ + GString strAccount = m_edtAccount->text(); + GString strPassword = m_edtPassword->text(); + + if (NULL == strAccount || "" == strAccount) + { + showErrorNotifiy(seAccountError, getGLDi18nStr(g_rsAccountError)); + return; + } + + if (NULL == strPassword || "" == strPassword) + { + showErrorNotifiy(sePasswordError, getGLDi18nStr(g_rsAccountError)); + return; + } + + switch(loginState()) + { + case seSuccess: + { + emit loginSuccess(strAccount); + break; + } + + case seAccountError: + { + showErrorNotifiy(seAccountError, getGLDi18nStr(g_rsAccountError)); + break; + } + + case sePasswordError: + { + showErrorNotifiy(sePasswordError, getGLDi18nStr(g_rsAccountError)); + break; + } + + case seNetworkError: + { + showErrorNotifiy(seNetworkError, getGLDi18nStr(g_rsAccountError)); + break; + } + } + setUIEnable(false); +} + +void GLDWebLogin::registerAcc() +{ + QDesktopServices::openUrl(QUrl(registerAccountURL())); +} + +void GLDWebLogin::retrievePass() +{ + QDesktopServices::openUrl(QUrl(retrievePasswordURL())); +} + +void GLDWebLogin::showErrorNotifiy(GLDLoginState error, const GString &msg) +{ + if (seSuccess == error) + { + accept(); + } + else if (seNetworkError == error) + { + setFixedHeight(c_nMaxMainSize); + m_btnInfo->show(); + m_btnInfo->setIcon(QIcon(":/icons/webLog/ew.png")); + m_btnInfo->setText(msg); + } + else + { + setFixedHeight(c_nMaxMainSize); + m_btnInfo->show(); + m_btnInfo->setIcon(QIcon(":/icons/webLog/eroo.png")); + m_btnInfo->setText(msg); + } + + setUIEnable(true); +} + +void GLDWebLogin::setUIEnable(bool enable) +{ + m_btnLogin->setEnabled(enable); + m_edtAccount->setEnabled(enable); + m_edtPassword->setEnabled(enable); +} + + +void GLDWebLogin::openKeyboard() +{ + QPoint GlobalPoint(m_btnKeyboard->mapToGlobal(QPoint(0, 0))); + GLDKeyboardInput *pkeyboardinput = new GLDKeyboardInput(this); + pkeyboardinput->setGeometry(GlobalPoint.x() - c_nEditWidth, GlobalPoint.y() + c_nMinLabelHeight, + c_nKeyBoardInputeWidth, c_nKeyBoardInputeHeight); + pkeyboardinput->show(); + m_edtPassword->setFocus(); +} + +void GLDWebLogin::onClickedBtn(const QString &string) +{ + if (NULL != string) + { + m_password = m_edtPassword->text(); + m_password.append(string.simplified()); + m_edtPassword->setText(m_password); + } +} + +void GLDWebLogin::onClickedDeletebtn() +{ + m_edtPassword->backspace(); +} + +GLDLoginTitle::GLDLoginTitle(QWidget *parent) : QLabel(parent) +{ + buildUI(); +} + +void GLDLoginTitle::buildUI() +{ + setFixedSize(c_loginTitleSize); + QPushButton *pBtnClose = new QPushButton(this); + pBtnClose->setObjectName("LoginTitleCloseButton"); + pBtnClose->setFixedSize(c_closeButtonSize); + pBtnClose->setCursor(Qt::ArrowCursor); + pBtnClose->setGeometry(width() - pBtnClose->width(), 0, pBtnClose->width(), pBtnClose->height()); + connect(pBtnClose, SIGNAL(clicked()), this, SIGNAL(sigCloseClicked())); +} + diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDWindowComboBox.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDWindowComboBox.cpp new file mode 100644 index 00000000..4d67da66 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDWindowComboBox.cpp @@ -0,0 +1,1135 @@ +#include "GLDWindowComboBox.h" +#include "GLDGlobal.h" +#include "GLDTextEdit.h" +#include "private/qabstractspinbox_p.h" + +#include +#ifndef QT_NO_EFFECTS +#include +#endif +#include +#include +#include + +GLDWindowComboBox::GLDWindowComboBox(QWidget *parent) + : GLDWAbstractSpinBox(parent) +{ + setWrapping(true); + m_hasHadFocus = false; + m_framePopuped = false; + m_hidePopupOnEdit = true; + m_showPopupOnEnter = false; + m_hideEditOnExit = false; + m_editorNeedFocus = false; + m_arrowState = QStyle::State_None; + m_pComboxPopup = NULL; + m_buttonType = ComboBoxArrow; + m_animationPopup = true; + +#ifdef QT_KEYPAD_NAVIGATION + focusOnButton = false; +#endif + init(); + setObjectName("GLDWindowComboBox"); + + connect(getLineEdit(), SIGNAL(cursorPositionChanged()), + this, SLOT(doCursorPositionChanged())); + connect(getLineEdit(), SIGNAL(selectionChanged()), + this, SLOT(doSelectionChanged())); +} + +GLDWindowComboBox::~GLDWindowComboBox() +{ + freeAndNil(m_pComboxPopup); +} + +QWidget *GLDWindowComboBox::popupWidget() const +{ + if (!m_framePopuped || m_pComboxPopup == NULL) + { + return NULL; + } + + + return m_pComboxPopup->popupWidget(); +} + +void GLDWindowComboBox::setPopupWidget(QWidget *popup) +{ + if (!popup) + { + qWarning("GWindowComboBox::setPopupWidget: Cannot set a null popup widget"); + return; + } + + if (!m_framePopuped) + { + qWarning("GWindowComboBox::setPopupWidget: comboBoxPopup is set to false"); + return; + } + + initComboBoxPopup(popup); +} + +bool GLDWindowComboBox::framePopup() const +{ + return m_framePopuped; +} + +void GLDWindowComboBox::setFramePopup(bool enable) +{ + if (enable == m_framePopuped) + { + return; + } + + setAttribute(Qt::WA_MacShowFocusRect, !enable); + m_framePopuped = enable; +#ifdef QT_KEYPAD_NAVIGATION + + if (!enable) + { + focusOnButton = false; + } + +#endif + updateEditFieldGeometry(); + update(); +} + +void GLDWindowComboBox::setPopupScrollTime(int time) +{ + if (m_pComboxPopup != NULL) + { + m_pComboxPopup->setScrollTime(time); + } +} + +int GLDWindowComboBox::popupScrollTime() +{ + if (m_pComboxPopup != NULL) + { + return m_pComboxPopup->scrollTime(); + } + else + { + return -1; + } +} + +void GLDWindowComboBox::setResizeEnable(bool value) +{ + if (m_pComboxPopup != NULL) + { + m_pComboxPopup->setSizeGripEnabled(value); + } +} + +void GLDWindowComboBox::setPopupSize(QSize value) +{ + if (m_pComboxPopup != NULL) + { + m_pComboxPopup->setPopupSize(value); + } +} + +void GLDWindowComboBox::setPopupHeight(int value) +{ + if (m_pComboxPopup != NULL) + { + m_pComboxPopup->setPopupHeight(value); + } +} + +void GLDWindowComboBox::hidePopup() +{ + if (m_pComboxPopup->isVisible()) + { + m_pComboxPopup->hide(); + } +} + +void GLDWindowComboBox::setButtonTypes(GLDWindowComboBox::ButtonTypes type) +{ + if (type == None) + { + setButtonSymbols(QAbstractSpinBox::NoButtons); + } + + m_buttonType = type; +} + +GLDWindowComboBox::ButtonTypes GLDWindowComboBox::buttonType() +{ + return m_buttonType; +} + +bool GLDWindowComboBox::hasSelectedText() +{ + return lineEdit()->hasSelectedText(); +} + +void GLDWindowComboBox::showPopup() +{ + if (m_pComboxPopup != NULL && m_pComboxPopup->isVisible()) + { + return; + } + + updateArrow(QStyle::State_Sunken); + initComboBoxPopup(); + + QStyleOptionSpinBox opt; + initStyleOption(&opt); + + //Show the popup + m_pComboxPopup->show(); +} + +void GLDWindowComboBox::closePopup() +{ + if (m_pComboxPopup == NULL) + { + return; + } + + if (!m_pComboxPopup->isVisible()) + { + return; + } + + m_pComboxPopup->close(); + emit onManualColsePopup(); +} + +bool GLDWindowComboBox::isEditable() const +{ + return !lineEdit()->isReadOnly(); +} + +void GLDWindowComboBox::setEditable(bool editable) +{ + lineEdit()->setReadOnly(!editable); +} + +QString GLDWindowComboBox::editText() const +{ + return lineEdit()->toPlainText(); +} + +void GLDWindowComboBox::setEditText(const QString &text) +{ + lineEdit()->setPlainText(text); +} + +void GLDWindowComboBox::init() +{ +#ifdef QT_KEYPAD_NAVIGATION + + if (QApplication::keypadNavigationEnabled()) + { + setFramePopup(true); + } + +#endif + setInputMethodHints(Qt::ImhPreferNumbers); + setFramePopup(true); +} + +QStyle::SubControl GLDWindowComboBox::newHoverControl(const QPoint &pos) +{ + QStyleOptionComboBox optCombo; + optCombo.init(this); + optCombo.editable = true; + optCombo.subControls = QStyle::SC_All; + return style()->hitTestComplexControl(QStyle::CC_ComboBox, &optCombo, pos, this); +} + +void GLDWindowComboBox::updateEditFieldGeometry() +{ + QStyleOptionComboBox optCombo; + optCombo.init(this); + optCombo.editable = true; + optCombo.subControls = QStyle::SC_ComboBoxFrame | QStyle::SC_ComboBoxEditField; + + if (m_buttonType != None) + { + optCombo.subControls |= QStyle::SC_ComboBoxArrow; + // 原来获取rect的方式有问题,因此改为整个减去右侧的按钮的方式获取 + QRect comboBoxArrowRect = style()->subControlRect(QStyle::CC_ComboBox, &optCombo, + QStyle::SC_ComboBoxArrow, this); + QRect editRect = rect().adjusted(0, 0, -comboBoxArrowRect.width(), 0); + // 由于在setGeometry的时候,会再次计算并设置MinimumSize和MaximumSize + // 会出现区域改变的问题,因此在这里先设置好MinimumSize和MaximumSize + lineEdit()->setMinimumSize(editRect.width(), editRect.height()); + lineEdit()->setMaximumSize(editRect.width(), editRect.height()); + lineEdit()->setGeometry(editRect); + } + else + { + QRect editRect = rect().adjusted(1, 0, 0, -1); + lineEdit()->setMinimumSize(editRect.width(), editRect.height()); + lineEdit()->setMaximumSize(editRect.width(), editRect.height()); + } +} + +void GLDWindowComboBox::doPopupHide() +{ + updateArrow(QStyle::State_None); + emit onHide(); +} + +void GLDWindowComboBox::doSelectionChanged() +{ + emit selectionChanged(); +} + +void GLDWindowComboBox::doCursorPositionChanged() +{ + emit cursorPositionChanged(); +} + +void GLDWindowComboBox::updateArrow(QStyle::StateFlag state) +{ + if (m_arrowState == state) + { + return; + } + + m_arrowState = state; +// if (arrowState != QStyle::State_None) +// buttonState |= Mouse; +// else +// { +// buttonState = 0; +// hoverControl = QStyle::SC_ComboBoxFrame; +// } + update(); +} + +void GLDWindowComboBox::syncPopupWidget() +{ + if (m_pComboxPopup != NULL) + { + const bool c_sb = m_pComboxPopup->blockSignals(true); + m_pComboxPopup->blockSignals(c_sb); + m_pComboxPopup->setAnimationPopup(m_animationPopup); + } +} + +void GLDWindowComboBox::initComboBoxPopup(QWidget *cw) +{ + if (m_pComboxPopup == NULL) + { + m_pComboxPopup = new GLDComboBoxPopup(this, cw); + m_pComboxPopup->setObjectName(QLatin1String("GLDComboBoxPopup")); + + QObject::connect(m_pComboxPopup, SIGNAL(onHide()), + this, SLOT(doPopupHide())); + QObject::connect(m_pComboxPopup, SIGNAL(shouldShowPopup(bool &)), + this, SIGNAL(shouldShowPopup(bool &))); + + m_pComboxPopup->installEventFilter(this); + } + else if (cw != NULL) + { + m_pComboxPopup->setpopupWidget(cw); + } + + syncPopupWidget(); +} + +void GLDWindowComboBox::keyPressEvent(QKeyEvent *event) +{ + bool bhandled = false; + + emit keyPressType(Qt::Key(event->key()), bhandled); + + if (bhandled) + { + return; + } + + bool bSelect = true; + + switch (event->key()) + { + case Qt::Key_Enter: + case Qt::Key_Return: +// d->interpret(AlwaysEmit); + event->ignore(); + emit editingFinished(); + break; + + default: +#ifdef QT_KEYPAD_NAVIGATION + if (QApplication::keypadNavigationEnabled() && !hasEditFocus() + && !event->text().isEmpty() && event->text().at(0).isLetterOrNumber()) + { + setEditFocus(true); + + //hide cursor + lineEdit()->d_func()->setCursorVisible(false); + lineEdit()->d_func()->control->setCursorBlinkPeriod(0); + } + +#endif + + case Qt::Key_Left: + case Qt::Key_Right: + if (event->key() == Qt::Key_Left || event->key() == Qt::Key_Right) + { + if ( +#ifdef QT_KEYPAD_NAVIGATION + QApplication::keypadNavigationEnabled() && !hasEditFocus() + || !QApplication::keypadNavigationEnabled() && +#endif + !(event->modifiers() & Qt::ControlModifier)) + { + bSelect = false; + break; + } + +#ifdef Q_WS_MAC + else +#ifdef QT_KEYPAD_NAVIGATION + if (!QApplication::keypadNavigationEnabled()) +#endif + { + select = (event->modifiers() & Qt::ShiftModifier); + break; + } + +#endif + } + + // else fall through + } + + GLDWAbstractSpinBox::keyPressEvent(event); + G_UNUSED(bSelect) +} + +void GLDWindowComboBox::focusInEvent(QFocusEvent *event) +{ + GLDWAbstractSpinBox::focusInEvent(event); + const bool c_oldHasHadFocus = m_hasHadFocus; + m_hasHadFocus = true; + + switch (event->reason()) + { + case Qt::MouseFocusReason: + case Qt::PopupFocusReason: + return; + + case Qt::ActiveWindowFocusReason: + if (c_oldHasHadFocus) + { + return; + } + + case Qt::ShortcutFocusReason: + case Qt::TabFocusReason: + default: + break; + } + + if (m_showPopupOnEnter && !m_pComboxPopup->isVisible()) + { + showPopup(); + m_editorNeedFocus = true; + } +} + +void GLDWindowComboBox::mousePressEvent(QMouseEvent *event) +{ + if (!framePopup()) + { + GLDWAbstractSpinBox::mousePressEvent(event); + return; + } + + if (event->button() == Qt::LeftButton && m_buttonType != None) + { + QStyleOptionComboBox optCombo; + optCombo.init(this); + + QRect subRect = style()->proxy()->subControlRect(QStyle::CC_ComboBox, &optCombo, + QStyle::SC_ComboBoxArrow, this); + + if (subRect.contains(event->pos())) + { + event->accept(); + //if (isReadOnly()) return; + bool bValue = true; + emit shouldShowPopup(bValue); + + if (bValue) + { + showPopup(); + } + } + } + else + { + GLDWAbstractSpinBox::mousePressEvent(event); + } +} + +void GLDWindowComboBox::paintEvent(QPaintEvent *event) +{ + if (!m_framePopuped) + { + GLDWAbstractSpinBox::paintEvent(event); + return; + } + + QStyleOptionSpinBox opt; + initStyleOption(&opt); + + QStyleOptionComboBox optCombo; + + optCombo.init(this); + optCombo.editable = true; + optCombo.frame = opt.frame; + optCombo.subControls = opt.subControls; + optCombo.activeSubControls = opt.activeSubControls; + optCombo.state = opt.state; + + if (lineEdit()->isReadOnly()) + { + optCombo.state &= ~QStyle::State_Enabled; + } + + //鼠标位于箭头所在区域高亮,其他地方不高亮 + QPoint curPos = mapFromGlobal(QCursor::pos()); + QRect subRect = style()->proxy()->subControlRect(QStyle::CC_ComboBox, &optCombo, QStyle::SC_ComboBoxArrow, this); + + if (subRect.contains(curPos)) + { + optCombo.activeSubControls |= newHoverControl(curPos); + } + else + { + optCombo.activeSubControls &= newHoverControl(curPos); + } + + QPainter tmpPt(this); + + if (m_buttonType == ComboBoxArrow) + { + style()->drawComplexControl(QStyle::CC_ComboBox, &optCombo, &tmpPt, this); + } + else if (m_buttonType == Ellipsis) + { + QStyleOptionButton button; + button.rect = subRect; + style()->drawControl(QStyle::CE_PushButton, &button, &tmpPt); + + QPen pen = tmpPt.pen(); + pen.setColor(Qt::black); + tmpPt.setPen(pen); + + tmpPt.drawRect(subRect.left() + 2, subRect.height() / 2, 1, 1); + tmpPt.drawRect(subRect.center().x(), subRect.height() / 2, 1, 1); + tmpPt.drawRect(subRect.right() - 2, subRect.height() / 2, 1, 1); + + tmpPt.fillRect(lineEdit()->width(), lineEdit()->y(), + this->width() - lineEdit()->width() - subRect.width(), subRect.height() - 3, Qt::white); + } +} + +void GLDWindowComboBox::contextMenuEvent(QContextMenuEvent *event) +{ +#ifdef QT_NO_CONTEXTMENU + Q_UNUSED(event); +#else + QPointer menu = lineEdit()->createStandardContextMenu(); + + if (!menu) + { + return; + } + + const QPoint c_pos = (event->reason() == QContextMenuEvent::Mouse) + ? event->globalPos() : mapToGlobal(QPoint(event->pos().x(), 0)) + QPoint(width() / 2, height() / 2); + menu->exec(c_pos); + delete static_cast(menu); + event->accept(); +#endif // QT_NO_CONTEXTMENU +} + +void GLDWindowComboBox::initStyleOption(QStyleOptionSpinBox *option) const +{ + if (!option) + { + return; + } + + GLDWAbstractSpinBox::initStyleOption(option); + + if (m_framePopuped) + { + option->subControls = QStyle::SC_ComboBoxFrame | QStyle::SC_ComboBoxEditField + | QStyle::SC_ComboBoxArrow; + + if (m_arrowState == QStyle::State_Sunken) + { + option->state |= QStyle::State_Sunken; + } + else + { + option->state &= ~QStyle::State_Sunken; + } + } +} + +bool GLDWindowComboBox::eventFilter(QObject *object, QEvent *event) +{ + if (!m_hidePopupOnEdit) + { + GLDPlainTextEdit *pPlainTxtEdit = lineEdit(); + GLDComboBoxPopup *pComboxPopup = dynamic_cast(object); + + if (pComboxPopup != NULL) + { + switch (event->type()) + { + case QEvent::KeyPress: + if (pPlainTxtEdit->hasFocus() || pPlainTxtEdit->viewport()->hasFocus()) + { + keyPressEvent((QKeyEvent *)event); + return true; + } + + break; + + case QEvent::MouseButtonPress: + { + const QMouseEvent *pPopupMouseEvt = static_cast(event); + QPoint pt = pPlainTxtEdit->mapFromGlobal(pPopupMouseEvt->pos()); + + if (pPlainTxtEdit->rect().contains(pt)) + { + if (!pPlainTxtEdit->hasFocus()) + { + pPlainTxtEdit->setFocus(); + pPlainTxtEdit->cursor().setPos(pPopupMouseEvt->pos()); + } + + QScopedPointer mouseEvt(new QMouseEvent( + pPopupMouseEvt->type(), + pt, + pPopupMouseEvt->button(), + pPopupMouseEvt->buttons(), + pPopupMouseEvt->modifiers() + )); + + QApplication::sendEvent(pPlainTxtEdit->viewport(), mouseEvt.data()); + + event->accept(); + + return true; + } + else if (!m_pComboxPopup->rect().contains(m_pComboxPopup->mapFromGlobal(QCursor::pos()))) + { + if (QWidget *pParent = static_cast(parent())) + { + if (!pParent->rect().contains(m_pComboxPopup->mapFromGlobal(QCursor::pos()))) + { + if (m_hideEditOnExit) + { + emit onManualColsePopup(); + } + } + } + } + + break; + } + + case QEvent::MouseButtonRelease: + { + QPoint pt = pPlainTxtEdit->mapFromGlobal(QCursor::pos()); + + if (pPlainTxtEdit->rect().contains(pt)) + { + QApplication::sendEvent(pPlainTxtEdit, (QMouseEvent *)event); + event->accept(); + return true; + } + + break; + } + + case QEvent::MouseMove: + { + QPoint pt = pPlainTxtEdit->mapFromGlobal(QCursor::pos()); + + if (pPlainTxtEdit->rect().contains(pt)) + { + QApplication::sendEvent(pPlainTxtEdit, (QMouseEvent *)event); + event->accept(); + return true; + } + + break; + } + + default: + break; + } + } + } + + return GLDWAbstractSpinBox::eventFilter(object, event); +} + +void GLDWindowComboBox::resizeEvent(QResizeEvent *event) +{ + updateEditFieldGeometry(); + Q_UNUSED(event); +} + +void GLDWindowComboBox::moveEvent(QMoveEvent *) +{ + if (m_pComboxPopup != NULL) + { + m_pComboxPopup->hide(); + } +} + +void GLDWindowComboBox::setPopupFixedWidth(int width) +{ + m_pComboxPopup->setFixedWidth(width); +} + +void GLDWindowComboBox::cut() +{ + lineEdit()->cut(); +} + +void GLDWindowComboBox::copy() +{ + lineEdit()->copy(); +} + +void GLDWindowComboBox::paste() +{ + lineEdit()->paste(); +} + +void GLDComboBoxPopup::setpopupWidget(QWidget *cw) +{ + Q_ASSERT(cw); + QVBoxLayout *widgetLayout = dynamic_cast(layout()); + + if (!widgetLayout) + { + widgetLayout = new QVBoxLayout(this); + widgetLayout->setMargin(0); + widgetLayout->setSpacing(0); + widgetLayout->setContentsMargins(0, 0, 0, 0); + widgetLayout->setDirection(QBoxLayout::LeftToRight); + } + + delete m_popupWidget.data(); + m_popupWidget = QPointer(cw); + + widgetLayout->addWidget(cw); + cw->setFocus(); + setSizeGripEnabled(true); +} + +void GLDComboBoxPopup::setSizeGripEnabled(bool enabled) +{ + if (m_sizeGripEnabled == enabled) + { + return; + } + + m_sizeGripEnabled = enabled; + + if (!enabled != !m_resizer) + { + if (enabled) + { + m_resizer = new QSizeGrip(this); + m_resizer->resize(m_resizer->sizeHint()); + alignResizer(rect()); + m_resizer->raise(); + m_resizer->show(); + } + else + { + delete m_resizer; + m_resizer = 0; + } + } +} + +void GLDComboBoxPopup::setPopupSize(QSize value) +{ + if (value == m_popupSize) + { + return; + } + + m_popupSize = value; +} + +void GLDComboBoxPopup::setPopupHeight(int value) +{ + if (value == m_popupSize.height()) + { + return; + } + + m_popupSize.setHeight(value); +} + +int GLDComboBoxPopup::popuHeight() +{ + return m_popupSize.height(); +} + +QWidget *GLDComboBoxPopup::verifyPopupInstance() +{ + if (m_popupWidget.isNull()) + { + return NULL; + } + else + { + return m_popupWidget.data(); + } +} + +void GLDComboBoxPopup::setEdgeCursor() +{ + const int c_Hight = 3; + const int c_Width = 3; + + int nlx = rect().left(); + int nrx = rect().right(); + int nly = rect().top(); + int nry = rect().bottom(); + + const QSize c_defSize(c_Width, c_Hight); + + QRect bottomRight(QPoint(nrx - c_Width, nry - c_Hight), c_defSize); + QRect bottomLeft(QPoint(nlx, nry - c_Hight), c_defSize); + QRect topleft(QPoint(nlx, nly), c_defSize); + QRect topright(QPoint(nrx - c_Width, nly), c_defSize); + + QRect top(nlx + c_Width, nly, rect().width() - 2 * c_Width, c_Hight); + QRect bottom(nlx + c_Width, nry - c_Hight, rect().width() - 2 * c_Width, c_Hight); + QRect left(nlx, nly + c_Hight, c_Width, rect().height() - 2 * c_Hight); + QRect right(nrx - c_Width, nly + c_Hight, c_Width, rect().height() - 2 * c_Hight); + QPoint pos = mapFromGlobal(cursor().pos()); + + m_cursorChanged = true; + + if (bottomRight.contains(pos) || topleft.contains(pos)) + { + setCursor(Qt::SizeFDiagCursor); + } + else if (bottomLeft.contains(pos) || topright.contains(pos)) + { + setCursor(Qt::SizeBDiagCursor); + } + else if (top.contains(pos) || bottom.contains(pos)) + { + setCursor(Qt::SizeVerCursor); + } + else if (left.contains(pos) || right.contains(pos)) + { + setCursor(Qt::SizeHorCursor); + } + else + { + setCursor(Qt::ArrowCursor); + m_cursorChanged = false; + } +} + +void GLDComboBoxPopup::alignResizer(const QRect &rect) +{ + QPoint adjustEdge(0, 0); + + if (!QStyleFactory::keys().contains(qApp->style()->objectName(), Qt::CaseInsensitive)) + { + adjustEdge = QPoint(2, 0); + } + + if (m_isAtBottom) + { + if (isRightToLeft()) + { + m_resizer->move(rect.bottomLeft() - m_resizer->rect().bottomLeft() - adjustEdge); + } + else + { + m_resizer->move(rect.bottomRight() - m_resizer->rect().bottomRight() - adjustEdge); + } + } + else + { + if (isRightToLeft()) + { + m_resizer->move(rect.topLeft() - m_resizer->rect().topLeft() - adjustEdge); + } + else + { + m_resizer->move(rect.topRight() - m_resizer->rect().topRight() - adjustEdge); + } + } +} + +void GLDComboBoxPopup::initPopupSize() +{ + if (parent()) + { + QSize size = parentWidget()->size(); + + if (size.height() < 30) + { + size.setHeight(size.height() > 30 ? size.height() : 30); + } + + m_popupSize = size; + } + else + { + m_popupSize = QWidget::sizeHint(); + } +} + +GLDComboBoxPopup::GLDComboBoxPopup(QWidget *parent, QWidget *cw) + : QDialog(parent, Qt::Popup), + m_resizer(NULL), + m_sizeGripEnabled(false), + m_cursorChanged(false), + m_canDrag(false), + m_isAtBottom(true), + m_scrollTime(150), + m_animationPopup(true) +{ + setAttribute(Qt::WA_WindowPropagation); + + if (!cw) + { + verifyPopupInstance(); + } + else + { + setpopupWidget(cw); + } + + setFocusPolicy(Qt::ClickFocus); + initPopupSize(); +} + +void GLDComboBoxPopup::hideEvent(QHideEvent *) +{ + emit onHide(); +} + +void GLDComboBoxPopup::mousePressEvent(QMouseEvent *e) +{ + m_canDrag = false; + GLDWindowComboBox *combox = dynamic_cast(parentWidget()); + + if (combox) + { + QStyleOptionComboBox opt; + opt.init(combox); + QRect arrowRect = combox->style()->subControlRect(QStyle::CC_ComboBox, &opt, + QStyle::SC_ComboBoxArrow, combox); + arrowRect.moveTo(combox->mapToGlobal(arrowRect.topLeft())); + + if (arrowRect.contains(e->globalPos())) + { + setAttribute(Qt::WA_NoMouseReplay); + + bool value = true; + emit shouldShowPopup(value); + } + + if (rect().contains(e->pos()) && m_cursorChanged) + { + m_canDrag = true; + m_curPos = e->pos(); + } + } + + QWidget::mousePressEvent(e); +} + +void GLDComboBoxPopup::mouseReleaseEvent(QMouseEvent *) +{ + if (m_canDrag) + { + m_canDrag = false; + } + + emit onHide(); +} + +void GLDComboBoxPopup::resizeEvent(QResizeEvent *e) +{ + QWidget::resizeEvent(e); + + if (m_resizer && m_sizeGripEnabled) + { + alignResizer(rect()); + } +} + +void GLDComboBoxPopup::showEvent(QShowEvent *e) +{ + QWidget::showEvent(e); + QTimer::singleShot(10, this, SLOT(setEditorFocus())); +} + +void GLDComboBoxPopup::setEditorFocus() +{ + GLDWindowComboBox *box = dynamic_cast(parentWidget()); + + if (box) + { + if (box->m_editorNeedFocus && !box->lineEdit()->hasFocus()) + { + box->lineEdit()->setFocus(); + box->m_editorNeedFocus = false; + } + } +} + +void GLDComboBoxPopup::show() +{ + positionFramePopup(); + + if (m_animationPopup && QApplication::isEffectEnabled(Qt::UI_AnimateCombo) + /*&& !style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, this)*/ && + !window()->testAttribute(Qt::WA_DontShowOnScreen)) + { + qScrollEffect(this, true ? QEffects::DownScroll : QEffects::UpScroll, m_scrollTime); + } + + QWidget::show(); +} + +int GLDComboBoxPopup::exec() +{ + positionFramePopup(); + return QDialog::exec(); +} + +bool GLDComboBoxPopup::event(QEvent *e) +{ + return QWidget::event(e); +} + +bool GLDComboBoxPopup::eventFilter(QObject *object, QEvent *event) +{ + QWidget *widget = dynamic_cast(object); + + if (widget == NULL) + { + return false; + } + + if (event->type() == QEvent::MouseMove) + { + setEdgeCursor(); + return true; + } + else if (event->type() == QEvent::Leave) + { + if (underMouse()) + { + unsetCursor(); + return true; + } + } + + return QWidget::eventFilter(object, event); +} + +void GLDComboBoxPopup::positionFramePopup() +{ + QWidget *pParent = static_cast(parent()); + setAtBottom(true); + + QPoint pos = (pParent->layoutDirection() == Qt::RightToLeft) ? pParent->rect().bottomRight() + : pParent->rect().bottomLeft(); + QPoint pos2 = (pParent->layoutDirection() == Qt::RightToLeft) ? pParent->rect().topRight() + : pParent->rect().topLeft(); + pos = pParent->mapToGlobal(pos); + pos2 = pParent->mapToGlobal(pos2); + + QSize size(this->sizeHint().width(), this->sizeHint().height()); + QRect screen = QApplication::desktop()->availableGeometry(pos); + + //handle popup falling "off screen" + if (layoutDirection() == Qt::RightToLeft) + { + pos.setX(pos.x() - size.width()); + pos2.setX(pos2.x() - size.width()); + + if (pos.x() < screen.left()) + { + pos.setX(qMax(pos.x(), screen.left())); + } + else if (pos.x() + size.width() > screen.right()) + { + pos.setX(qMax(pos.x() - size.width(), screen.right() - size.width())); + } + } + else + { + if (pos.x() + size.width() > screen.right()) + { + pos.setX(screen.right() - size.width()); + } + + pos.setX(qMax(pos.x(), screen.left())); + } + + if (pos.y() + size.height() > screen.bottom()) + { + pos.setY(pos2.y() - size.height()); + setAtBottom(false); + } + else if (pos.y() < screen.top()) + { + pos.setY(screen.top()); + } + + if (pos.y() < screen.top()) + { + pos.setY(screen.top()); + } + + if (pos.y() + size.height() > screen.bottom()) + { + pos.setY(screen.bottom() - size.height()); + setAtBottom(false); + } + + move(pos); +} + +QSize GLDComboBoxPopup::sizeHint() const +{ + return m_popupSize; +} + +void GLDWindowComboBox::deleteSelectedText() +{ + if (hasSelectedText()) + { + lineEdit()->deleteSelectedText(); + } +} diff --git a/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDWindowComboBoxEx.cpp b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDWindowComboBoxEx.cpp new file mode 100644 index 00000000..f9f8c761 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Qt/Widgets/GLDWindowComboBoxEx.cpp @@ -0,0 +1,1271 @@ +#include "GLDWindowComboBoxEx.h" + +#include +#ifndef QT_NO_EFFECTS +#include +#endif +#include +#include +#include +#include "private/qabstractspinbox_p.h" + +#include "GLDWidget_Global.h" +#include "GLDShadow.h" +#include "GLDTextEdit.h" +#include "GLDFileUtils.h" +#include "GLDScrollStyle.h" + +const GString c_sWindowComboBoxQssFile = ":/qsses/GLDWindowComboBoxEx.qss"; + +GLDWindowComboBoxEx::GLDWindowComboBoxEx(QWidget *parent) + : GLDWAbstractSpinBox(parent), m_subIconRect(QRect()) +{ + setWrapping(true); + m_hasHadFocus = false; + m_framePopuped = false; + m_hidePopupOnEdit = true; + m_showPopupOnEnter = false; + m_hideEditOnExit = false; + m_editorNeedFocus = false; + m_arrowState = QStyle::State_None; + m_pComboxPopup = NULL; + m_buttonType = ComboBoxArrow; + m_animationPopup = true; + m_hasBorder = true; + m_isKeepFouseInLineEdit = false; + +#ifdef QT_KEYPAD_NAVIGATION + focusOnButton = false; +#endif + init(); + + connect(getLineEdit(), SIGNAL(cursorPositionChanged()), + this, SLOT(doCursorPositionChanged())); + connect(getLineEdit(), SIGNAL(selectionChanged()), + this, SLOT(doSelectionChanged())); +} + +GLDWindowComboBoxEx::~GLDWindowComboBoxEx() +{ + freeAndNil(m_pComboxPopup); +} + +QWidget *GLDWindowComboBoxEx::popupWidget() const +{ + if (!m_framePopuped || m_pComboxPopup == NULL) + { + return NULL; + } + return m_pComboxPopup->popupWidget(); +} + +void GLDWindowComboBoxEx::setPopupWidget(QWidget *popup) +{ + if (!popup) + { + qWarning("GWindowComboBox::setPopupWidget: Cannot set a null popup widget"); + return; + } + + if (!m_framePopuped) + { + qWarning("GWindowComboBox::setPopupWidget: comboBoxPopup is set to false"); + return; + } + + initComboBoxPopup(popup); +} + +bool GLDWindowComboBoxEx::framePopup() const +{ + return m_framePopuped; +} + +void GLDWindowComboBoxEx::setFramePopup(bool enable) +{ + if (enable == m_framePopuped) + { + return; + } + + setAttribute(Qt::WA_MacShowFocusRect, !enable); + m_framePopuped = enable; +#ifdef QT_KEYPAD_NAVIGATION + + if (!enable) + { + focusOnButton = false; + } + +#endif + updateEditFieldGeometry(); + update(); +} + +void GLDWindowComboBoxEx::setPopupScrollTime(int time) +{ + if (m_pComboxPopup != NULL) + { + m_pComboxPopup->setScrollTime(time); + } +} + +int GLDWindowComboBoxEx::popupScrollTime() +{ + if (m_pComboxPopup != NULL) + { + return m_pComboxPopup->scrollTime(); + } + else + { + return -1; + } +} + +void GLDWindowComboBoxEx::setResizeEnable(bool value) +{ + if (m_pComboxPopup != NULL) + { + m_pComboxPopup->setSizeGripEnabled(value); + } +} + +void GLDWindowComboBoxEx::setPopupSize(QSize value) +{ + if (m_pComboxPopup != NULL) + { + m_pComboxPopup->setPopupSize(value); + } +} + +void GLDWindowComboBoxEx::hidePopup() +{ + if (m_pComboxPopup->isVisible()) + { + m_pComboxPopup->hide(); + } +} + +void GLDWindowComboBoxEx::setButtonTypes(GLDWindowComboBoxEx::ButtonTypes type) +{ + if (type == None) + { + setButtonSymbols(QAbstractSpinBox::NoButtons); + } + + m_buttonType = type; + + setEditProperty(false); + this->setStyleSheet(loadQssFile(c_sWindowComboBoxQssFile)); +} + +GLDWindowComboBoxEx::ButtonTypes GLDWindowComboBoxEx::buttonType() +{ + return m_buttonType; +} + +bool GLDWindowComboBoxEx::hasSelectedText() +{ + return lineEdit()->hasSelectedText(); +} + +void GLDWindowComboBoxEx::setComboBoxPopupOffset(const int xOffset, const int yOffset) +{ + if (comboBoxPopup()) + { + comboBoxPopup()->setOffset(xOffset, yOffset); + } +} + +void GLDWindowComboBoxEx::showPopup() +{ + if (m_pComboxPopup != NULL && m_pComboxPopup->isVisible()) + { + return; + } + + updateArrow(QStyle::State_Sunken); + initComboBoxPopup(); + + QStyleOptionSpinBox opt; + initStyleOption(&opt); + + //Show the popup + m_pComboxPopup->show(); +} + +void GLDWindowComboBoxEx::closePopup() +{ + if (m_pComboxPopup == NULL) + { + return; + } + + if (!m_pComboxPopup->isVisible()) + { + return; + } + + m_pComboxPopup->close(); + emit onManualColsePopup(); +} + +bool GLDWindowComboBoxEx::isEditable() const +{ + return !lineEdit()->isReadOnly(); +} + +void GLDWindowComboBoxEx::setEditable(bool editable) +{ + lineEdit()->setReadOnly(!editable); +} + +QString GLDWindowComboBoxEx::editText() const +{ + QString strPlainText = lineEdit()->toPlainText(); +#ifdef WIN32 + strPlainText.replace("\n", "\r\n"); +#endif + return strPlainText; +} + +void GLDWindowComboBoxEx::setEditText(const QString &text) +{ + lineEdit()->setPlainText(text); +} + +void GLDWindowComboBoxEx::init() +{ +#ifdef QT_KEYPAD_NAVIGATION + + if (QApplication::keypadNavigationEnabled()) + { + setFramePopup(true); + } + +#endif + setInputMethodHints(Qt::ImhPreferNumbers); + setFramePopup(true); + + setStyle(new GLDScrollStyle(this)); + setHasBorder(true); + + setObjectName("GLDWindowComboBoxEx"); + setEditProperty(false); + this->setStyleSheet(loadQssFile(c_sWindowComboBoxQssFile)); + + // 移除阴影 + GLDShadow *pShadow = new GLDShadow(this); + pShadow->removeShadow(); +} + +QStyle::SubControl GLDWindowComboBoxEx::newHoverControl(const QPoint &pos) +{ + QStyleOptionComboBox optCombo; + optCombo.init(this); + optCombo.editable = true; + optCombo.subControls = QStyle::SC_All; + return style()->hitTestComplexControl(QStyle::CC_ComboBox, &optCombo, pos, this); +} + +void GLDWindowComboBoxEx::updateEditFieldGeometry() +{ + QStyleOptionComboBox optCombo; + optCombo.init(this); + optCombo.editable = true; + optCombo.subControls = QStyle::SC_ComboBoxFrame | QStyle::SC_ComboBoxEditField; + + if (m_buttonType != None) + { + optCombo.subControls |= QStyle::SC_ComboBoxArrow; + // Qss需要 + QRect editRect = rect().adjusted(0, 0, 0, 0); + // 由于在setGeometry的时候,会再次计算并设置MinimumSize和MaximumSize + // 会出现区域改变的问题,因此在这里先设置好MinimumSize和MaximumSize + lineEdit()->setMinimumSize(editRect.width(), editRect.height()); + lineEdit()->setMaximumSize(editRect.width(), editRect.height()); + lineEdit()->setGeometry(editRect); + } + else + { + QRect editRect = rect().adjusted(0, 0, 0, -1); + lineEdit()->setMinimumSize(editRect.width(), editRect.height()); + lineEdit()->setMaximumSize(editRect.width(), editRect.height()); + } +} + +void GLDWindowComboBoxEx::doPopupHide() +{ + updateArrow(QStyle::State_None); + emit onHide(); + // 添加状态,判断是它没有点击下拉框,将背景图片切换为向上的箭头 + setEditProperty(false); + this->setStyleSheet(loadQssFile(c_sWindowComboBoxQssFile)); + // 加载Qss后,会出现Edit错位问题,因此重新计算位置 + updateEditFieldGeometry(); +} + +void GLDWindowComboBoxEx::doSelectionChanged() +{ + emit selectionChanged(); +} + +void GLDWindowComboBoxEx::doCursorPositionChanged() +{ + emit cursorPositionChanged(); +} + +void GLDWindowComboBoxEx::updateArrow(QStyle::StateFlag state) +{ + if (m_arrowState == state) + { + return; + } + + m_arrowState = state; +// if (arrowState != QStyle::State_None) +// buttonState |= Mouse; +// else +// { +// buttonState = 0; +// hoverControl = QStyle::SC_ComboBoxFrame; +// } + update(); +} + +void GLDWindowComboBoxEx::syncPopupWidget() +{ + if (m_pComboxPopup != NULL) + { + const bool c_sb = m_pComboxPopup->blockSignals(true); + m_pComboxPopup->blockSignals(c_sb); + m_pComboxPopup->setAnimationPopup(m_animationPopup); + } +} + +void GLDWindowComboBoxEx::initComboBoxPopup(QWidget *cw) +{ + if (m_pComboxPopup == NULL) + { + m_pComboxPopup = new GLDComboBoxPopupEx(this, cw); + m_pComboxPopup->setObjectName(QLatin1String("GLDComboBoxPopupEx")); + + QObject::connect(m_pComboxPopup, SIGNAL(onHide()), this, SLOT(doPopupHide())); + QObject::connect(m_pComboxPopup, SIGNAL(shouldShowPopup(bool &)), this, SIGNAL(shouldShowPopup(bool &))); + + m_pComboxPopup->installEventFilter(this); + } + else if (cw != NULL) + { + m_pComboxPopup->setpopupWidget(cw); + } + + syncPopupWidget(); +} + +void GLDWindowComboBoxEx::keyPressEvent(QKeyEvent *event) +{ + bool bhandled = false; + + emit keyPressType(Qt::Key(event->key()), bhandled); + + if (bhandled) + { + return; + } + + bool bSelect = true; + + QWidget *popWidgetChild = NULL; + + if (m_isKeepFouseInLineEdit) + { + for (int i = 0; i < popupWidget()->children().count(); ++i) + { + if ((popWidgetChild = qobject_cast(popupWidget()->children().at(i)))) + { + break; + } + } + } + switch (event->key()) + { + if(m_isKeepFouseInLineEdit) + { + case Qt::Key_Up: + case Qt::Key_Down: + { + if(popWidgetChild) + { + popWidgetChild->setFocus(); + } + } + break; + } + case Qt::Key_Enter: + case Qt::Key_Return: +// d->interpret(AlwaysEmit); + event->ignore(); + emit editingFinished(); + break; + + default: + if (m_isKeepFouseInLineEdit) + { + getLineEdit()->setFocus(); + break; + } +#ifdef QT_KEYPAD_NAVIGATION + if (QApplication::keypadNavigationEnabled() && !hasEditFocus() + && !event->text().isEmpty() && event->text().at(0).isLetterOrNumber()) + { + setEditFocus(true); + + //hide cursor + lineEdit()->d_func()->setCursorVisible(false); + lineEdit()->d_func()->control->setCursorBlinkPeriod(0); + } + +#endif + + case Qt::Key_Left: + case Qt::Key_Right: + if (event->key() == Qt::Key_Left || event->key() == Qt::Key_Right) + { + if ( +#ifdef QT_KEYPAD_NAVIGATION + QApplication::keypadNavigationEnabled() && !hasEditFocus() + || !QApplication::keypadNavigationEnabled() && +#endif + !(event->modifiers() & Qt::ControlModifier)) + { + bSelect = false; + break; + } + +#ifdef Q_WS_MAC + else +#ifdef QT_KEYPAD_NAVIGATION + if (!QApplication::keypadNavigationEnabled()) +#endif + { + select = (event->modifiers() & Qt::ShiftModifier); + break; + } + +#endif + } + + // else fall through + } + + GLDWAbstractSpinBox::keyPressEvent(event); + G_UNUSED(bSelect) +} + +void GLDWindowComboBoxEx::focusInEvent(QFocusEvent *event) +{ + GLDWAbstractSpinBox::focusInEvent(event); + const bool c_oldHasHadFocus = m_hasHadFocus; + m_hasHadFocus = true; + + switch (event->reason()) + { + case Qt::MouseFocusReason: + case Qt::PopupFocusReason: + return; + + case Qt::ActiveWindowFocusReason: + if (c_oldHasHadFocus) + { + return; + } + + case Qt::ShortcutFocusReason: + case Qt::TabFocusReason: + default: + break; + } + + if (m_showPopupOnEnter && !m_pComboxPopup->isVisible()) + { + showPopup(); + m_editorNeedFocus = true; + } +} + +void GLDWindowComboBoxEx::mousePressEvent(QMouseEvent *event) +{ + if (!framePopup()) + { + GLDWAbstractSpinBox::mousePressEvent(event); + return; + } + + if (event->button() == Qt::LeftButton && m_buttonType != None) + { + QStyleOptionComboBox optCombo; + optCombo.init(this); + QRect subRect = style()->proxy()->subControlRect(QStyle::CC_ComboBox, &optCombo, + QStyle::SC_ComboBoxArrow, this); + + if (subRect.contains(event->pos())) + { + event->accept(); + //if (isReadOnly()) return; + bool bValue = true; + emit shouldShowPopup(bValue); + + if (bValue) + { + // 添加状态,判断是否点击了,重新载入QSS + setEditProperty(true); + this->setStyleSheet(loadQssFile(c_sWindowComboBoxQssFile)); + // 加载Qss后,会出现Edit错位问题,因此重新计算位置 + updateEditFieldGeometry(); + showPopup(); + } + } + } + else + { + GLDWAbstractSpinBox::mousePressEvent(event); + } +} + +void GLDWindowComboBoxEx::paintEvent(QPaintEvent *event) +{ + if (!m_framePopuped) + { + GLDWAbstractSpinBox::paintEvent(event); + return; + } + + QStyleOptionSpinBox opt; + initStyleOption(&opt); + + QStyleOptionComboBox optCombo; + + optCombo.init(this); + optCombo.editable = true; + optCombo.frame = opt.frame; + optCombo.subControls = opt.subControls; + optCombo.activeSubControls = opt.activeSubControls; + optCombo.state = opt.state; + + if (lineEdit()->isReadOnly()) + { + optCombo.state &= ~QStyle::State_Enabled; + } + + //鼠标位于箭头所在区域高亮,其他地方不高亮 + QPoint curPos = mapFromGlobal(QCursor::pos()); + QRect subRect = style()->proxy()->subControlRect(QStyle::CC_ComboBox, &optCombo, QStyle::SC_ComboBoxArrow, this); + m_subIconRect = subRect; + if (subRect.contains(curPos)) + { + optCombo.activeSubControls |= newHoverControl(curPos); + } + else + { + optCombo.activeSubControls &= newHoverControl(curPos); + } + + QPainter tmpPt(this); + + if (m_buttonType == ComboBoxArrow) + { + style()->drawComplexControl(QStyle::CC_ComboBox, &optCombo, &tmpPt, this); + } + else if (m_buttonType == Ellipsis) + { + QStyleOptionButton button; + button.rect = subRect; + style()->drawControl(QStyle::CE_PushButton, &button, &tmpPt); + + QPen pen = tmpPt.pen(); + pen.setColor(Qt::black); + tmpPt.setPen(pen); + tmpPt.drawRect(subRect.left() + 2, subRect.height() / 2, 1, 1); + tmpPt.drawRect(subRect.center().x(), subRect.height() / 2, 1, 1); + tmpPt.drawRect(subRect.right() - 2, subRect.height() / 2, 1, 1); + + tmpPt.fillRect(lineEdit()->width(), lineEdit()->y(), + this->width() - lineEdit()->width() - subRect.width(), subRect.height() - 3, Qt::white); + if (m_isKeepFouseInLineEdit) + { + getLineEdit()->setFocus(); + } + } +} + +void GLDWindowComboBoxEx::contextMenuEvent(QContextMenuEvent *event) +{ +#ifdef QT_NO_CONTEXTMENU + Q_UNUSED(event); +#else + QPointer menu = lineEdit()->createStandardContextMenu(); + + if (!menu) + { + return; + } + + const QPoint c_pos = (event->reason() == QContextMenuEvent::Mouse) + ? event->globalPos() : mapToGlobal(QPoint(event->pos().x(), 0)) + QPoint(width() / 2, + height() / 2); + menu->exec(c_pos); + delete static_cast(menu); + event->accept(); +#endif // QT_NO_CONTEXTMENU +} + +void GLDWindowComboBoxEx::initStyleOption(QStyleOptionSpinBox *option) const +{ + if (!option) + { + return; + } + + GLDWAbstractSpinBox::initStyleOption(option); + + if (m_framePopuped) + { + option->subControls = QStyle::SC_ComboBoxFrame | QStyle::SC_ComboBoxEditField + | QStyle::SC_ComboBoxArrow; + + if (m_arrowState == QStyle::State_Sunken) + { + option->state |= QStyle::State_Sunken; + } + else + { + option->state &= ~QStyle::State_Sunken; + } + } +} + +bool GLDWindowComboBoxEx::eventFilter(QObject *object, QEvent *event) +{ + if (!m_hidePopupOnEdit) + { + GLDPlainTextEdit *pPlainTxtEdit = lineEdit(); + GLDComboBoxPopupEx *pComboxPopup = dynamic_cast(object); + + if (pComboxPopup != NULL) + { + switch (event->type()) + { + case QEvent::KeyPress: + if (pPlainTxtEdit->hasFocus() || pPlainTxtEdit->viewport()->hasFocus()) + { + keyPressEvent((QKeyEvent *)event); + return true; + } + + break; + + case QEvent::MouseButtonPress: + { + const QMouseEvent *pPopupMouseEvt = static_cast(event); + QPoint pt = pPlainTxtEdit->mapFromGlobal(pPopupMouseEvt->pos()); + + if (pPlainTxtEdit->rect().contains(pt)) + { + if (!pPlainTxtEdit->hasFocus()) + { + pPlainTxtEdit->setFocus(); + pPlainTxtEdit->cursor().setPos(pPopupMouseEvt->pos()); + } + + QScopedPointer mouseEvt(new QMouseEvent( + pPopupMouseEvt->type(), + pt, + pPopupMouseEvt->button(), + pPopupMouseEvt->buttons(), + pPopupMouseEvt->modifiers() + )); + + QApplication::sendEvent(pPlainTxtEdit->viewport(), mouseEvt.data()); + + event->accept(); + + return true; + } + else if (!m_pComboxPopup->rect().contains(m_pComboxPopup->mapFromGlobal(QCursor::pos()))) + { + if (QWidget *pParent = static_cast(parent())) + { + if (!pParent->rect().contains(m_pComboxPopup->mapFromGlobal(QCursor::pos()))) + { + if (m_hideEditOnExit) + { + emit onManualColsePopup(); + } + } + } + } + + break; + } + + case QEvent::MouseButtonRelease: + { + QPoint pt = pPlainTxtEdit->mapFromGlobal(QCursor::pos()); + + if (pPlainTxtEdit->rect().contains(pt)) + { + QApplication::sendEvent(pPlainTxtEdit, (QMouseEvent *)event); + event->accept(); + return true; + } + + break; + } + + case QEvent::MouseMove: + { + QPoint pt = pPlainTxtEdit->mapFromGlobal(QCursor::pos()); + + if (pPlainTxtEdit->rect().contains(pt)) + { + QApplication::sendEvent(pPlainTxtEdit, (QMouseEvent *)event); + event->accept(); + return true; + } + + break; + } + + default: + break; + } + } + } + + return GLDWAbstractSpinBox::eventFilter(object, event); +} + +void GLDWindowComboBoxEx::resizeEvent(QResizeEvent *event) +{ + updateEditFieldGeometry(); + Q_UNUSED(event); +} + +void GLDWindowComboBoxEx::moveEvent(QMoveEvent *) +{ + if (m_pComboxPopup != NULL) + { + m_pComboxPopup->hide(); + } +} + +void GLDWindowComboBoxEx::setPopupFixedWidth(int width) +{ + m_pComboxPopup->setFixedWidth(width); +} + +void GLDWindowComboBoxEx::cut() +{ + lineEdit()->cut(); +} + +void GLDWindowComboBoxEx::copy() +{ + lineEdit()->copy(); +} + +void GLDWindowComboBoxEx::paste() +{ + lineEdit()->paste(); +} + +void GLDComboBoxPopupEx::setpopupWidget(QWidget *cw) +{ + Q_ASSERT(cw); + QVBoxLayout *widgetLayout = dynamic_cast(layout()); + + if (!widgetLayout) + { + widgetLayout = new QVBoxLayout(this); + widgetLayout->setMargin(0); + widgetLayout->setSpacing(0); + // 下面的拖拽的位置所占区域 + widgetLayout->setContentsMargins(0, 0, 0, 18); + widgetLayout->setDirection(QBoxLayout::LeftToRight); + } + + delete m_popupWidget.data(); + m_popupWidget = QPointer(cw); + widgetLayout->addWidget(cw); + cw->setFocus(); + setSizeGripEnabled(true); +} + +void GLDComboBoxPopupEx::setSizeGripEnabled(bool enabled) +{ + if (m_sizeGripEnabled == enabled) + { + return; + } + + m_sizeGripEnabled = enabled; + + if (!enabled != !m_resizer) + { + if (enabled) + { + m_resizer = new QSizeGrip(this); + m_resizer->resize(m_resizer->sizeHint()); + alignResizer(rect()); + m_resizer->raise(); + m_resizer->show(); + layout()->setContentsMargins(0, 0, 0, 18); + } + else + { + delete m_resizer; + m_resizer = 0; + layout()->setContentsMargins(0, 0, 0, 0); + } + } +} + +void GLDComboBoxPopupEx::setPopupSize(QSize value) +{ + if (value == m_popupSize) + { + return; + } + + m_popupSize = value; +} + +QWidget *GLDComboBoxPopupEx::verifyPopupInstance() +{ + if (m_popupWidget.isNull()) + { + return NULL; + } + else + { + return m_popupWidget.data(); + } +} + +void GLDComboBoxPopupEx::setEdgeCursor() +{ + const int c_Hight = 3; + const int c_Width = 3; + int nlx = rect().left(); + int nrx = rect().right(); + int nly = rect().top(); + int nry = rect().bottom(); + const QSize c_defSize(c_Width, c_Hight); + + QRect bottomRight(QPoint(nrx - c_Width, nry - c_Hight), c_defSize); + QRect bottomLeft(QPoint(nlx, nry - c_Hight), c_defSize); + QRect topleft(QPoint(nlx, nly), c_defSize); + QRect topright(QPoint(nrx - c_Width, nly), c_defSize); + + QRect top(nlx + c_Width, nly, rect().width() - 2 * c_Width, c_Hight); + QRect bottom(nlx + c_Width, nry - c_Hight, rect().width() - 2 * c_Width, c_Hight); + QRect left(nlx, nly + c_Hight, c_Width, rect().height() - 2 * c_Hight); + QRect right(nrx - c_Width, nly + c_Hight, c_Width, rect().height() - 2 * c_Hight); + QPoint pos = mapFromGlobal(cursor().pos()); + + m_cursorChanged = true; + + if (bottomRight.contains(pos) || topleft.contains(pos)) + { + setCursor(Qt::SizeFDiagCursor); + } + else if (bottomLeft.contains(pos) || topright.contains(pos)) + { + setCursor(Qt::SizeBDiagCursor); + } + else if (top.contains(pos) || bottom.contains(pos)) + { + setCursor(Qt::SizeVerCursor); + } + else if (left.contains(pos) || right.contains(pos)) + { + setCursor(Qt::SizeHorCursor); + } + else + { + setCursor(Qt::ArrowCursor); + m_cursorChanged = false; + } +} + +void GLDComboBoxPopupEx::alignResizer(const QRect &rect) +{ + if (m_isAtBottom) + { + if (isRightToLeft()) + { + m_resizer->move(rect.bottomLeft() - m_resizer->rect().bottomLeft()); + } + else + { + m_resizer->move(rect.bottomRight() - m_resizer->rect().bottomRight()); + } + } + else + { + if (isRightToLeft()) + { + m_resizer->move(rect.topLeft() - m_resizer->rect().topLeft()); + } + else + { + m_resizer->move(rect.topRight() - m_resizer->rect().topRight()); + } + } +} + +void GLDComboBoxPopupEx::initPopupSize() +{ + if (parent()) + { + QSize size = parentWidget()->size(); + + if (size.height() < 30) + { + size.setHeight(size.height() > 30 ? size.height() : 30); + } + + m_popupSize = size; + } + else + { + m_popupSize = QWidget::sizeHint(); + } +} + +GLDComboBoxPopupEx::GLDComboBoxPopupEx(QWidget *parent, QWidget *cw) + : QDialog(parent, Qt::Popup), m_resizer(NULL), m_sizeGripEnabled(false), + m_cursorChanged(false), m_canDrag(false), m_isAtBottom(true), m_scrollTime(150), m_animationPopup(true), + m_xOffset(0), m_yOffset(0) +{ + setAttribute(Qt::WA_WindowPropagation); + + if (!cw) + { + verifyPopupInstance(); + } + else + { + setpopupWidget(cw); + } + + setFocusPolicy(Qt::ClickFocus); + initPopupSize(); +} + +void GLDComboBoxPopupEx::hideEvent(QHideEvent *) +{ + emit onHide(); +} + +void GLDComboBoxPopupEx::mousePressEvent(QMouseEvent *e) +{ + m_canDrag = false; + GLDWindowComboBoxEx *combox = dynamic_cast(parentWidget()); + + if (!combox) + { + QDialog::mousePressEvent(e); + return; + } + + else + { + QStyleOptionComboBox opt; + opt.init(combox); + QRect arrowRect = combox->style()->subControlRect(QStyle::CC_ComboBox, &opt, + QStyle::SC_ComboBoxArrow, combox); + arrowRect.moveTo(combox->mapToGlobal(arrowRect.topLeft())); + + if (arrowRect.contains(e->globalPos())) + { + setAttribute(Qt::WA_NoMouseReplay); + + bool bValue = true; + emit shouldShowPopup(bValue); + } + + if (rect().contains(e->pos()) && m_cursorChanged) + { + m_canDrag = true; + m_curPos = e->pos(); + } + } + + if (!combox->m_hidePopupOnEdit) + { + e->ignore(); + if ((windowType() == Qt::Popup)) + { + e->accept(); + + // 关闭所有不在当前Widget里面的PopupWidget + QWidget* pPopupWidget; + while ((pPopupWidget = QApplication::activePopupWidget()) && pPopupWidget != this) + { + pPopupWidget->close(); + if (QApplication::activePopupWidget() == pPopupWidget) // widget does not want to disappear + { + pPopupWidget->hide(); // hide at least + } + } + + QRect rectPopUp(rect().left(), rect().top(), rect().right(), rect().bottom()); + QRect rectLineEdit = combox->lineEdit()->rect(); + rectLineEdit.adjust(0, -rectLineEdit.bottom() , -combox->subIconRect().width(), -rectLineEdit.bottom()); + if (!rectPopUp.contains(e->pos())) + { + if (!rectLineEdit.contains(e->pos())) + { + close(); + } + else + { + combox->lineEdit()->setFocus(); + } + } + } + } + else + { + QWidget::mousePressEvent(e); + } +} + +void GLDComboBoxPopupEx::mouseReleaseEvent(QMouseEvent *) +{ + if (m_canDrag) + { + m_canDrag = false; + } + + emit onHide(); +} + +void GLDComboBoxPopupEx::resizeEvent(QResizeEvent *e) +{ + QWidget::resizeEvent(e); + + if (m_resizer && m_sizeGripEnabled) + { + alignResizer(rect()); + } +} + +void GLDComboBoxPopupEx::showEvent(QShowEvent *e) +{ + QWidget::showEvent(e); + QTimer::singleShot(10, this, SLOT(setEditorFocus())); +} + +void GLDComboBoxPopupEx::setEditorFocus() +{ + GLDWindowComboBoxEx *box = dynamic_cast(parentWidget()); + + if (box) + { + if (box->m_editorNeedFocus && !box->lineEdit()->hasFocus()) + { + box->lineEdit()->setFocus(); + box->m_editorNeedFocus = false; + } + } +} + +void GLDComboBoxPopupEx::show() +{ + positionFramePopup(); + + if (m_animationPopup && QApplication::isEffectEnabled(Qt::UI_AnimateCombo) + /*&& !style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, this)*/ + && !window()->testAttribute(Qt::WA_DontShowOnScreen)) + { + qScrollEffect(this, true ? QEffects::DownScroll : QEffects::UpScroll, m_scrollTime); + } + + QWidget::show(); +} + +int GLDComboBoxPopupEx::exec() +{ + positionFramePopup(); + return QDialog::exec(); +} + +bool GLDComboBoxPopupEx::event(QEvent *e) +{ + return QWidget::event(e); +} + +bool GLDComboBoxPopupEx::eventFilter(QObject *object, QEvent *event) +{ + QWidget *widget = dynamic_cast(object); + + if (widget == NULL) + { + return false; + } + + if (event->type() == QEvent::MouseMove) + { + setEdgeCursor(); + return true; + } + else if (event->type() == QEvent::Leave) + { + if (underMouse()) + { + unsetCursor(); + return true; + } + } + + return QWidget::eventFilter(object, event); +} + +void GLDComboBoxPopupEx::positionFramePopup() +{ + QWidget *pParent = static_cast(parent()); + setAtBottom(true); + QPoint pos = (pParent->layoutDirection() == Qt::RightToLeft) ? pParent->rect().bottomRight() + : pParent->rect().bottomLeft(); + QPoint pos2 = (pParent->layoutDirection() == Qt::RightToLeft) ? pParent->rect().topRight() + : pParent->rect().topLeft(); + pos = pParent->mapToGlobal(pos); + pos2 = pParent->mapToGlobal(pos2); + QSize size = sizeHint(); + QRect screen = QApplication::desktop()->availableGeometry(pos); + + //handle popup falling "off screen" + if (layoutDirection() == Qt::RightToLeft) + { + pos.setX(pos.x() - size.width()); + pos2.setX(pos2.x() - size.width()); + + if (pos.x() < screen.left()) + { + pos.setX(qMax(pos.x(), screen.left())); + } + else if (pos.x() + size.width() > screen.right()) + { + pos.setX(qMax(pos.x() - size.width(), screen.right() - size.width())); + } + } + else + { + if (pos.x() + size.width() > screen.right()) + { + pos.setX(screen.right() - size.width()); + } + + pos.setX(qMax(pos.x(), screen.left())); + } + + if (pos.y() + size.height() > screen.bottom()) + { + pos.setY(pos2.y() - size.height()); + setAtBottom(false); + } + else if (pos.y() < screen.top()) + { + pos.setY(screen.top()); + } + + if (pos.y() < screen.top()) + { + pos.setY(screen.top()); + } + + if (pos.y() + size.height() > screen.bottom()) + { + pos.setY(screen.bottom() - size.height()); + setAtBottom(false); + } + pos.setX(pos.x() + m_xOffset); + pos.setY(pos.y() + m_yOffset); + move(pos); +} + +QSize GLDComboBoxPopupEx::sizeHint() const +{ + return m_popupSize; +} + +void GLDComboBoxPopupEx::setOffset(int xOffset, int yOffset) +{ + m_xOffset = xOffset; + m_yOffset = yOffset; +} + +void GLDWindowComboBoxEx::deleteSelectedText() +{ + if (hasSelectedText()) + { + lineEdit()->deleteSelectedText(); + } +} + +void GLDWindowComboBoxEx::setEditProperty(bool bShow) +{ + QString sProperty = QString(""); + if (m_buttonType == ComboBoxArrow) + { + sProperty = sProperty + QString("ComboBoxArrow"); + } + else if (m_buttonType == Ellipsis) + { + sProperty = sProperty + QString("Ellipsis"); + } + if (bShow) + { + sProperty = sProperty + QString("-show"); + } + else + { + sProperty = sProperty + QString("-hide"); + } + + getLineEdit()->setProperty( + "GLDPlainTextEditState", sProperty); +} + +bool GLDWindowComboBoxEx::isHidePopupOnEdit() +{ + return m_hidePopupOnEdit; +} + +void GLDWindowComboBoxEx::setIsHidePopupOnEdit(bool bIsHidePopupOnEdit) +{ + m_hidePopupOnEdit = bIsHidePopupOnEdit; +} + +void GLDWindowComboBoxEx::setFouseKeepInLineEdit(bool isKeepFouseInLineEdit) +{ + getLineEdit()->setFouseIsKeepInLineEdit(true); + m_isKeepFouseInLineEdit = isKeepFouseInLineEdit; +} + +void GLDWindowComboBoxEx::setHasBorder(bool hasBorder) +{ + if (m_hasBorder != hasBorder) + { + m_hasBorder = hasBorder; + } + + if (!m_hasBorder) + { + getLineEdit()->setProperty("borderStyle", "noBorder"); + this->setStyleSheet(loadQssFile(c_sWindowComboBoxQssFile)); + } +} diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/360skin.qrc b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/360skin.qrc new file mode 100644 index 00000000..500ed2f8 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/360skin.qrc @@ -0,0 +1,11 @@ + + + sysbutton/arrow_down.png + sysbutton/close.png + sysbutton/close_button.png + sysbutton/main_menu.png + sysbutton/max_button.png + sysbutton/min_button.png + sysbutton/skin_button.png + + diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/0.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/0.png new file mode 100644 index 00000000..4bf2fc5f Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/0.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/0_big.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/0_big.png new file mode 100644 index 00000000..e3d5553a Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/0_big.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/1.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/1.png new file mode 100644 index 00000000..10598103 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/1.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/10.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/10.png new file mode 100644 index 00000000..553c16e2 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/10.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/10_big.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/10_big.png new file mode 100644 index 00000000..018c7b6f Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/10_big.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/11.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/11.png new file mode 100644 index 00000000..ca238958 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/11.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/11_big.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/11_big.png new file mode 100644 index 00000000..241acde6 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/11_big.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/12.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/12.png new file mode 100644 index 00000000..7f914b73 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/12.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/12_big.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/12_big.png new file mode 100644 index 00000000..bebaf162 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/12_big.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/13.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/13.png new file mode 100644 index 00000000..66c3e7d0 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/13.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/13_big.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/13_big.png new file mode 100644 index 00000000..b52cf11d Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/13_big.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/14.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/14.png new file mode 100644 index 00000000..d36e6366 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/14.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/14_big.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/14_big.png new file mode 100644 index 00000000..d9d79158 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/14_big.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/15.jpg b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/15.jpg new file mode 100644 index 00000000..b6db0e60 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/15.jpg differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/15_big.jpg b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/15_big.jpg new file mode 100644 index 00000000..504491f2 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/15_big.jpg differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/16.jpg b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/16.jpg new file mode 100644 index 00000000..6136da65 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/16.jpg differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/16_big.jpg b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/16_big.jpg new file mode 100644 index 00000000..321bc2d1 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/16_big.jpg differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/17.jpg b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/17.jpg new file mode 100644 index 00000000..9d3253f1 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/17.jpg differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/17_big.jpg b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/17_big.jpg new file mode 100644 index 00000000..ea4de31f Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/17_big.jpg differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/18.jpg b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/18.jpg new file mode 100644 index 00000000..a6d66f19 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/18.jpg differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/18_big.jpg b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/18_big.jpg new file mode 100644 index 00000000..8ddda562 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/18_big.jpg differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/19.jpg b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/19.jpg new file mode 100644 index 00000000..f2da5590 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/19.jpg differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/19_big.jpg b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/19_big.jpg new file mode 100644 index 00000000..4462cbbc Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/19_big.jpg differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/1_big.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/1_big.png new file mode 100644 index 00000000..dfa3f376 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/1_big.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/2.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/2.png new file mode 100644 index 00000000..ec125d45 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/2.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/20.jpg b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/20.jpg new file mode 100644 index 00000000..e147b362 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/20.jpg differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/20_big.jpg b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/20_big.jpg new file mode 100644 index 00000000..d820d23d Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/20_big.jpg differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/21.jpg b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/21.jpg new file mode 100644 index 00000000..d3887729 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/21.jpg differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/21_big.jpg b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/21_big.jpg new file mode 100644 index 00000000..47ec7f1d Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/21_big.jpg differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/22.jpg b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/22.jpg new file mode 100644 index 00000000..183c73c3 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/22.jpg differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/22_big.jpg b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/22_big.jpg new file mode 100644 index 00000000..39b20f8a Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/22_big.jpg differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/23_big.jpg b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/23_big.jpg new file mode 100644 index 00000000..2e8d67a2 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/23_big.jpg differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/2_big.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/2_big.png new file mode 100644 index 00000000..2eef1532 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/2_big.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/3.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/3.png new file mode 100644 index 00000000..90b02f93 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/3.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/3_big.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/3_big.png new file mode 100644 index 00000000..0429333c Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/3_big.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/4.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/4.png new file mode 100644 index 00000000..921ad579 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/4.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/4_big.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/4_big.png new file mode 100644 index 00000000..85ed93a7 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/4_big.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/5.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/5.png new file mode 100644 index 00000000..152dd6e6 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/5.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/5_big.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/5_big.png new file mode 100644 index 00000000..e3026b3f Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/5_big.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/6.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/6.png new file mode 100644 index 00000000..1ba685c2 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/6.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/6_big.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/6_big.png new file mode 100644 index 00000000..1a9abad7 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/6_big.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/7.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/7.png new file mode 100644 index 00000000..53b578b7 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/7.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/7_big.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/7_big.png new file mode 100644 index 00000000..890d5497 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/7_big.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/8.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/8.png new file mode 100644 index 00000000..d1398f6c Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/8.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/8_big.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/8_big.png new file mode 100644 index 00000000..acd792cb Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/skin/8_big.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/sysbutton/arrow_down.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/sysbutton/arrow_down.png new file mode 100644 index 00000000..a59c1f40 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/sysbutton/arrow_down.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/sysbutton/close.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/sysbutton/close.png new file mode 100644 index 00000000..09c6b27d Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/sysbutton/close.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/sysbutton/close_button.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/sysbutton/close_button.png new file mode 100644 index 00000000..fcc84180 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/sysbutton/close_button.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/sysbutton/main_menu.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/sysbutton/main_menu.png new file mode 100644 index 00000000..7ce02494 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/sysbutton/main_menu.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/sysbutton/max_button.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/sysbutton/max_button.png new file mode 100644 index 00000000..ac5a6701 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/sysbutton/max_button.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/sysbutton/min_button.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/sysbutton/min_button.png new file mode 100644 index 00000000..2d3f89da Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/sysbutton/min_button.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/sysbutton/skin_button.png b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/sysbutton/skin_button.png new file mode 100644 index 00000000..658e11e7 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/360skin/sysbutton/skin_button.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/CLDCustomWaitingBox.png b/GCR/trunk/Glodon/src/GLD/Res/ico/CLDCustomWaitingBox.png new file mode 100644 index 00000000..7a168ef8 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/CLDCustomWaitingBox.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/CLDCustomWaitingBox_Gray.png b/GCR/trunk/Glodon/src/GLD/Res/ico/CLDCustomWaitingBox_Gray.png new file mode 100644 index 00000000..4cd0536c Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/CLDCustomWaitingBox_Gray.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/Close16.png b/GCR/trunk/Glodon/src/GLD/Res/ico/Close16.png new file mode 100644 index 00000000..ac73b5b6 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/Close16.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/EllipsisButton_Click.png b/GCR/trunk/Glodon/src/GLD/Res/ico/EllipsisButton_Click.png new file mode 100644 index 00000000..47817611 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/EllipsisButton_Click.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/EllipsisButton_Hover.png b/GCR/trunk/Glodon/src/GLD/Res/ico/EllipsisButton_Hover.png new file mode 100644 index 00000000..00288b25 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/EllipsisButton_Hover.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/EllipsisButton_Normal.png b/GCR/trunk/Glodon/src/GLD/Res/ico/EllipsisButton_Normal.png new file mode 100644 index 00000000..ede80bd7 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/EllipsisButton_Normal.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/FilterWidget_ClearText.png b/GCR/trunk/Glodon/src/GLD/Res/ico/FilterWidget_ClearText.png new file mode 100644 index 00000000..74133baf Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/FilterWidget_ClearText.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/Floating16.png b/GCR/trunk/Glodon/src/GLD/Res/ico/Floating16.png new file mode 100644 index 00000000..ba9a7ad4 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/Floating16.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GBQ-splitter-bottom.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GBQ-splitter-bottom.png new file mode 100644 index 00000000..b58b2ea1 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GBQ-splitter-bottom.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GBQ-splitter-hover-bottom.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GBQ-splitter-hover-bottom.png new file mode 100644 index 00000000..1e952946 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GBQ-splitter-hover-bottom.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GBQ-splitter-hover-left.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GBQ-splitter-hover-left.png new file mode 100644 index 00000000..86c86668 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GBQ-splitter-hover-left.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GBQ-splitter-hover-right.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GBQ-splitter-hover-right.png new file mode 100644 index 00000000..82e57e41 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GBQ-splitter-hover-right.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GBQ-splitter-hover-top.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GBQ-splitter-hover-top.png new file mode 100644 index 00000000..cdd6a3c4 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GBQ-splitter-hover-top.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GBQ-splitter-left.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GBQ-splitter-left.png new file mode 100644 index 00000000..ffe4ab3d Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GBQ-splitter-left.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GBQ-splitter-pressedH.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GBQ-splitter-pressedH.png new file mode 100644 index 00000000..e3e6b56e Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GBQ-splitter-pressedH.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GBQ-splitter-pressedV.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GBQ-splitter-pressedV.png new file mode 100644 index 00000000..d8b8ecd5 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GBQ-splitter-pressedV.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GBQ-splitter-right.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GBQ-splitter-right.png new file mode 100644 index 00000000..ffe4ab3d Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GBQ-splitter-right.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GBQ-splitter-top.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GBQ-splitter-top.png new file mode 100644 index 00000000..35686ac1 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GBQ-splitter-top.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GColorListEx-backgroundColor.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GColorListEx-backgroundColor.png new file mode 100644 index 00000000..d207b21b Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GColorListEx-backgroundColor.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GColorListEx-foreColor.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GColorListEx-foreColor.png new file mode 100644 index 00000000..0f04d10b Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GColorListEx-foreColor.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GColorListEx-moreColorIcon.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GColorListEx-moreColorIcon.png new file mode 100644 index 00000000..f232fa2c Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GColorListEx-moreColorIcon.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDComboBoxPopupEx-sizegrip.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDComboBoxPopupEx-sizegrip.png new file mode 100644 index 00000000..282dd01d Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDComboBoxPopupEx-sizegrip.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDComboBoxPopupEx-sizegriphover.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDComboBoxPopupEx-sizegriphover.png new file mode 100644 index 00000000..27649b06 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDComboBoxPopupEx-sizegriphover.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomComboBoxEx-downarrow.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomComboBoxEx-downarrow.png new file mode 100644 index 00000000..d269d4a3 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomComboBoxEx-downarrow.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomComboBoxEx-downarrowon.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomComboBoxEx-downarrowon.png new file mode 100644 index 00000000..b6457403 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomComboBoxEx-downarrowon.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Close.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Close.png new file mode 100644 index 00000000..fd51985e Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Close.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Close_Hover.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Close_Hover.png new file mode 100644 index 00000000..bac9cde5 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Close_Hover.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Close_Pressed.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Close_Pressed.png new file mode 100644 index 00000000..95c377a8 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Close_Pressed.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Max.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Max.png new file mode 100644 index 00000000..52587f25 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Max.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Max_Hover.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Max_Hover.png new file mode 100644 index 00000000..031465e0 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Max_Hover.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Max_Pressed.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Max_Pressed.png new file mode 100644 index 00000000..5f5fe1bf Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Max_Pressed.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Min.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Min.png new file mode 100644 index 00000000..4ed4f877 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Min.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Min_Hover.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Min_Hover.png new file mode 100644 index 00000000..be747686 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Min_Hover.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Min_Pressed.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Min_Pressed.png new file mode 100644 index 00000000..5ac6983f Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Min_Pressed.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Restore.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Restore.png new file mode 100644 index 00000000..be4ab700 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Restore.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Restore_Hover.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Restore_Hover.png new file mode 100644 index 00000000..1976cde0 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Restore_Hover.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Restore_Pressed.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Restore_Pressed.png new file mode 100644 index 00000000..101b568a Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDCustomTitleBar/Query_Restore_Pressed.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDDockPanel/bottom.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDDockPanel/bottom.png new file mode 100644 index 00000000..e37d8e82 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDDockPanel/bottom.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDDockPanel/center.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDDockPanel/center.png new file mode 100644 index 00000000..2d9d9ce3 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDDockPanel/center.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDDockPanel/left.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDDockPanel/left.png new file mode 100644 index 00000000..0e8e5389 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDDockPanel/left.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDDockPanel/right.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDDockPanel/right.png new file mode 100644 index 00000000..9a2ffa8e Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDDockPanel/right.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDDockPanel/top.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDDockPanel/top.png new file mode 100644 index 00000000..68b0df2d Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDDockPanel/top.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/Cancel.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/Cancel.png new file mode 100644 index 00000000..dcf3ec74 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/Cancel.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/MidIconMode.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/MidIconMode.png new file mode 100644 index 00000000..48b5ea27 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/MidIconMode.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/Open.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/Open.png new file mode 100644 index 00000000..beee6338 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/Open.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/SmallIconMode.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/SmallIconMode.png new file mode 100644 index 00000000..4c7dc67e Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/SmallIconMode.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/backward-press.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/backward-press.png new file mode 100644 index 00000000..d6727972 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/backward-press.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/backward.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/backward.png new file mode 100644 index 00000000..5df7af4e Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/backward.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/forward-press.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/forward-press.png new file mode 100644 index 00000000..9365809e Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/forward-press.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/forward.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/forward.png new file mode 100644 index 00000000..bb87b374 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/forward.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/new.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/new.png new file mode 100644 index 00000000..020a6b0d Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/new.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/refresh.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/refresh.png new file mode 100644 index 00000000..56465ce6 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/refresh.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/view.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/view.png new file mode 100644 index 00000000..1004ebdd Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFileDialog/view.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFontListEx-check_mark.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFontListEx-check_mark.png new file mode 100644 index 00000000..aa15a0a5 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFontListEx-check_mark.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFontListEx-true_type.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFontListEx-true_type.png new file mode 100644 index 00000000..a27eb42a Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDFontListEx-true_type.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDIcons.qrc b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDIcons.qrc new file mode 100644 index 00000000..26eb2754 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDIcons.qrc @@ -0,0 +1,195 @@ + + + GlodonTableView.ico + RangFillingCursor.png + RangMoveCursor.png + SDIAA.bmp + SDIAB.bmp + SDIABE.bmp + SDIABF.bmp + SDIABFE.bmp + SDIAC.bmp + SDIACE.bmp + SDIACF.bmp + SDIACFE.bmp + SDIAD.bmp + SDIAE.bmp + SDIAEEE.bmp + SDIAEF.bmp + SDIAEFE.bmp + SDIAG.bmp + SDIAL.bmp + SDIAN.bmp + SDIAY.bmp + FilterWidget_ClearText.png + EllipsisButton_Normal.png + EllipsisButton_Hover.png + EllipsisButton_Click.png + GLDNavigationItem_default.png + GLDNavigationItem_hover.png + 360skin/sysbutton/arrow_down.png + 360skin/sysbutton/close.png + 360skin/sysbutton/close_button.png + 360skin/sysbutton/main_menu.png + 360skin/sysbutton/max_button.png + 360skin/sysbutton/min_button.png + 360skin/sysbutton/skin_button.png + 360skin/skin/17_big.jpg + more.png + bottom-conter.png + bottom-left.png + bottom-right.png + right-conter.png + right-top.png + CLDCustomWaitingBox.png + CLDCustomWaitingBox_Gray.png + TabDockContainerAnchor.png + TabDockContainerNotAnchor.png + splitter-bottom.png + splitter-left.png + splitter-pressedH.png + splitter-pressedV.png + splitter-right.png + splitter-top.png + splitter-hover-bottom.png + splitter-hover-left.png + splitter-hover-right.png + splitter-hover-top.png + GLDNavigationItem_checdked.png + GLDCustomComboBoxEx-downarrow.png + GLDCustomComboBoxEx-downarrowon.png + scrolldownarrow.png + scrollleftarrow.png + scrollrightarrow.png + scrolluparrow.png + GLDComboBoxPopupEx-sizegrip.png + GLDComboBoxPopupEx-sizegriphover.png + GLDWindowComboBoxEx-downarrow.png + GLDWindowComboBoxEx-downarrowon.png + GLDLineButtonEditEx-ellipsis.png + GLDFontListEx-check_mark.png + GLDFontListEx-true_type.png + GLDWindowComboBoxEx-ellipsis.png + GLDWindowComboBoxEx-ellipsis-hover.png + GLDWindowComboBoxEx-ellipsis-press.png + GColorListEx-moreColorIcon.png + GColorListEx-backgroundColor.png + GColorListEx-foreColor.png + webLog/02.png + webLog/03.png + webLog/04.png + webLog/06.png + webLog/BIMLogin.png + webLog/black_checkbox_checked.png + webLog/black_checkbox_unchecked_hover.png + webLog/black_checkbox_unchecked_pressed.png + webLog/black_keyboard01.png + webLog/black_keyboard02.png + webLog/black_keyboard03.png + webLog/blue_checkbox_checked.png + webLog/blue_checkbox_unchecked_hover.png + webLog/blue_checkbox_unchecked_pressed.png + webLog/blue_keyboard01.png + webLog/blue_keyboard02.png + webLog/blue_keyboard03.png + webLog/close01.png + webLog/Close1.png + webLog/close02.png + webLog/Close2.png + webLog/Close3.png + webLog/common_checkbox_unchecked.png + webLog/darkblue_checkbox_checked.png + webLog/darkblue_checkbox_unchecked_hover.png + webLog/darkblue_checkbox_unchecked_pressed.png + webLog/darkblue_keyboard01.png + webLog/darkblue_keyboard02.png + webLog/darkblue_keyboard03.png + webLog/eroo.png + webLog/ew.png + webLog/green_checkbox_checked.png + webLog/green_checkbox_unchecked_hover.png + webLog/green_checkbox_unchecked_pressed.png + webLog/green_keyboard01.png + webLog/green_keyboard02.png + webLog/green_keyboard03.png + webLog/orange_checkbox_checked.png + webLog/orange_checkbox_unchecked_hover.png + webLog/orange_checkbox_unchecked_pressed.png + webLog/orange_keyboard01.png + webLog/orange_keyboard02.png + webLog/orange_keyboard03.png + webLog/purple_checkbox_checked.png + webLog/purple_checkbox_unchecked_hover.png + webLog/purple_checkbox_unchecked_pressed.png + webLog/purple_keyboard01.png + webLog/purple_keyboard02.png + webLog/purple_keyboard03.png + webLog/skin.png + hs.png + r-hover.png + right.png + rigjt02.png + z-hover.png + arrowdown.png + arrowdownhover.png + arrowleft.png + arrowright.png + arrowup.png + arrowuphover.png + arrowwithline.png + calendar.png + GLDLineWidthEx-line.png + GLDLineWidthEx-noline.png + GLDLineWidthEx-virtualLine.png + GlodonTreeView-add.png + GlodonTreeView-bottom.png + GlodonTreeView-hover.png + GlodonTreeView-sub.png + GLDSearchEdit_Clear_Hove.png + GLDSearchEdit_Clear_Norm.png + GLDSearchEdit_Clear_Press.png + GLDSearchEdit_Search.png + GLDCustomTitleBar/Query_Close.png + GLDCustomTitleBar/Query_Close_Hover.png + GLDCustomTitleBar/Query_Close_Pressed.png + GLDCustomTitleBar/Query_Max.png + GLDCustomTitleBar/Query_Max_Hover.png + GLDCustomTitleBar/Query_Max_Pressed.png + GLDCustomTitleBar/Query_Min.png + GLDCustomTitleBar/Query_Min_Hover.png + GLDCustomTitleBar/Query_Min_Pressed.png + GLDCustomTitleBar/Query_Restore.png + GLDCustomTitleBar/Query_Restore_Hover.png + GLDCustomTitleBar/Query_Restore_Pressed.png + GLDFileDialog/backward.png + GLDFileDialog/backward-press.png + GLDFileDialog/forward.png + GLDFileDialog/forward-press.png + GLDFileDialog/refresh.png + GLDFileDialog/view.png + GLDFileDialog/new.png + GLDFileDialog/Cancel.png + GLDFileDialog/Open.png + GLDSearchEdit_Clear_Hove_Focus.png + GLDSearchEdit_Clear_Norm_Focus.png + GLDSearchEdit_Clear_Press_Focus.png + GLDSearchEdit_Search_Focus.png + GLDFileDialog/MidIconMode.png + GLDFileDialog/SmallIconMode.png + GBQ-splitter-bottom.png + GBQ-splitter-hover-bottom.png + GBQ-splitter-hover-left.png + GBQ-splitter-hover-right.png + GBQ-splitter-hover-top.png + GBQ-splitter-left.png + GBQ-splitter-pressedH.png + GBQ-splitter-top.png + GBQ-splitter-pressedV.png + GBQ-splitter-right.png + GLDDockPanel/bottom.png + GLDDockPanel/center.png + GLDDockPanel/left.png + GLDDockPanel/right.png + GLDDockPanel/top.png + + diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDLineButtonEditEx-ellipsis.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDLineButtonEditEx-ellipsis.png new file mode 100644 index 00000000..0668bf8e Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDLineButtonEditEx-ellipsis.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDLineWidthEx-line.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDLineWidthEx-line.png new file mode 100644 index 00000000..9763afb3 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDLineWidthEx-line.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDLineWidthEx-noline.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDLineWidthEx-noline.png new file mode 100644 index 00000000..dc9f44e7 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDLineWidthEx-noline.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDLineWidthEx-virtualLine.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDLineWidthEx-virtualLine.png new file mode 100644 index 00000000..6d64f226 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDLineWidthEx-virtualLine.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDNavigationItem_checdked.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDNavigationItem_checdked.png new file mode 100644 index 00000000..befdafad Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDNavigationItem_checdked.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDNavigationItem_default.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDNavigationItem_default.png new file mode 100644 index 00000000..894d3e23 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDNavigationItem_default.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDNavigationItem_hover.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDNavigationItem_hover.png new file mode 100644 index 00000000..64d7c607 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDNavigationItem_hover.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDSearchEdit_Clear_Hove.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDSearchEdit_Clear_Hove.png new file mode 100644 index 00000000..77826e74 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDSearchEdit_Clear_Hove.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDSearchEdit_Clear_Hove_Focus.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDSearchEdit_Clear_Hove_Focus.png new file mode 100644 index 00000000..adf548ce Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDSearchEdit_Clear_Hove_Focus.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDSearchEdit_Clear_Norm.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDSearchEdit_Clear_Norm.png new file mode 100644 index 00000000..79a3009f Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDSearchEdit_Clear_Norm.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDSearchEdit_Clear_Norm_Focus.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDSearchEdit_Clear_Norm_Focus.png new file mode 100644 index 00000000..609b3d00 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDSearchEdit_Clear_Norm_Focus.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDSearchEdit_Clear_Press.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDSearchEdit_Clear_Press.png new file mode 100644 index 00000000..b4b7747b Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDSearchEdit_Clear_Press.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDSearchEdit_Clear_Press_Focus.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDSearchEdit_Clear_Press_Focus.png new file mode 100644 index 00000000..ace986b4 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDSearchEdit_Clear_Press_Focus.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDSearchEdit_Search.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDSearchEdit_Search.png new file mode 100644 index 00000000..03e75d7f Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDSearchEdit_Search.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDSearchEdit_Search_Focus.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDSearchEdit_Search_Focus.png new file mode 100644 index 00000000..9402613a Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDSearchEdit_Search_Focus.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDWindowComboBoxEx-downarrow.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDWindowComboBoxEx-downarrow.png new file mode 100644 index 00000000..251f756e Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDWindowComboBoxEx-downarrow.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDWindowComboBoxEx-downarrowon.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDWindowComboBoxEx-downarrowon.png new file mode 100644 index 00000000..484a793b Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDWindowComboBoxEx-downarrowon.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDWindowComboBoxEx-ellipsis-hover.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDWindowComboBoxEx-ellipsis-hover.png new file mode 100644 index 00000000..9a4298ef Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDWindowComboBoxEx-ellipsis-hover.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDWindowComboBoxEx-ellipsis-press.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDWindowComboBoxEx-ellipsis-press.png new file mode 100644 index 00000000..84aa5cd3 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDWindowComboBoxEx-ellipsis-press.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GLDWindowComboBoxEx-ellipsis.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDWindowComboBoxEx-ellipsis.png new file mode 100644 index 00000000..695929bf Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GLDWindowComboBoxEx-ellipsis.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GlodonTableView.ico b/GCR/trunk/Glodon/src/GLD/Res/ico/GlodonTableView.ico new file mode 100644 index 00000000..31cf3b46 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GlodonTableView.ico differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GlodonTreeView-add.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GlodonTreeView-add.png new file mode 100644 index 00000000..ec7715f9 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GlodonTreeView-add.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GlodonTreeView-bottom.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GlodonTreeView-bottom.png new file mode 100644 index 00000000..1514ebcd Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GlodonTreeView-bottom.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GlodonTreeView-hover.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GlodonTreeView-hover.png new file mode 100644 index 00000000..609ee27f Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GlodonTreeView-hover.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/GlodonTreeView-sub.png b/GCR/trunk/Glodon/src/GLD/Res/ico/GlodonTreeView-sub.png new file mode 100644 index 00000000..541b1edb Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/GlodonTreeView-sub.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/Locked16.png b/GCR/trunk/Glodon/src/GLD/Res/ico/Locked16.png new file mode 100644 index 00000000..f34ccc0e Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/Locked16.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/RangFillingCursor.png b/GCR/trunk/Glodon/src/GLD/Res/ico/RangFillingCursor.png new file mode 100644 index 00000000..0e3cfe8b Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/RangFillingCursor.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/RangMoveCursor.png b/GCR/trunk/Glodon/src/GLD/Res/ico/RangMoveCursor.png new file mode 100644 index 00000000..865476ec Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/RangMoveCursor.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAA.bmp b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAA.bmp new file mode 100644 index 00000000..61321599 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAA.bmp differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAB.bmp b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAB.bmp new file mode 100644 index 00000000..44c4b573 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAB.bmp differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/SDIABE.bmp b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIABE.bmp new file mode 100644 index 00000000..5380b007 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIABE.bmp differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/SDIABF.bmp b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIABF.bmp new file mode 100644 index 00000000..3d41c590 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIABF.bmp differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/SDIABFE.bmp b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIABFE.bmp new file mode 100644 index 00000000..bfa2d66d Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIABFE.bmp differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAC.bmp b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAC.bmp new file mode 100644 index 00000000..75620cc5 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAC.bmp differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/SDIACE.bmp b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIACE.bmp new file mode 100644 index 00000000..0d02e274 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIACE.bmp differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/SDIACF.bmp b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIACF.bmp new file mode 100644 index 00000000..c7939537 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIACF.bmp differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/SDIACFE.bmp b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIACFE.bmp new file mode 100644 index 00000000..a69a7da6 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIACFE.bmp differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAD.bmp b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAD.bmp new file mode 100644 index 00000000..8380af4d Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAD.bmp differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAE.bmp b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAE.bmp new file mode 100644 index 00000000..a8737287 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAE.bmp differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAEEE.bmp b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAEEE.bmp new file mode 100644 index 00000000..3cf3f9d9 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAEEE.bmp differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAEF.bmp b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAEF.bmp new file mode 100644 index 00000000..e849c121 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAEF.bmp differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAEFE.bmp b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAEFE.bmp new file mode 100644 index 00000000..924b3f18 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAEFE.bmp differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAG.bmp b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAG.bmp new file mode 100644 index 00000000..a5e4af21 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAG.bmp differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAL.bmp b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAL.bmp new file mode 100644 index 00000000..d6ec2775 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAL.bmp differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAN.bmp b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAN.bmp new file mode 100644 index 00000000..0d391c00 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAN.bmp differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAY.bmp b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAY.bmp new file mode 100644 index 00000000..9b781510 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/SDIAY.bmp differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/TabDockContainerAnchor.png b/GCR/trunk/Glodon/src/GLD/Res/ico/TabDockContainerAnchor.png new file mode 100644 index 00000000..bf9c5563 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/TabDockContainerAnchor.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/TabDockContainerNotAnchor.png b/GCR/trunk/Glodon/src/GLD/Res/ico/TabDockContainerNotAnchor.png new file mode 100644 index 00000000..8fa35f4b Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/TabDockContainerNotAnchor.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/arrowdown.png b/GCR/trunk/Glodon/src/GLD/Res/ico/arrowdown.png new file mode 100644 index 00000000..79956801 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/arrowdown.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/arrowdownhover.png b/GCR/trunk/Glodon/src/GLD/Res/ico/arrowdownhover.png new file mode 100644 index 00000000..f7cf490a Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/arrowdownhover.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/arrowleft.png b/GCR/trunk/Glodon/src/GLD/Res/ico/arrowleft.png new file mode 100644 index 00000000..51b2e212 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/arrowleft.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/arrowright.png b/GCR/trunk/Glodon/src/GLD/Res/ico/arrowright.png new file mode 100644 index 00000000..6779b19a Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/arrowright.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/arrowup.png b/GCR/trunk/Glodon/src/GLD/Res/ico/arrowup.png new file mode 100644 index 00000000..81567b2d Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/arrowup.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/arrowuphover.png b/GCR/trunk/Glodon/src/GLD/Res/ico/arrowuphover.png new file mode 100644 index 00000000..e2529930 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/arrowuphover.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/arrowwithline.png b/GCR/trunk/Glodon/src/GLD/Res/ico/arrowwithline.png new file mode 100644 index 00000000..dae9421d Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/arrowwithline.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/bottom-conter.png b/GCR/trunk/Glodon/src/GLD/Res/ico/bottom-conter.png new file mode 100644 index 00000000..49f37ee2 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/bottom-conter.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/bottom-left.png b/GCR/trunk/Glodon/src/GLD/Res/ico/bottom-left.png new file mode 100644 index 00000000..7f852b61 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/bottom-left.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/bottom-right.png b/GCR/trunk/Glodon/src/GLD/Res/ico/bottom-right.png new file mode 100644 index 00000000..35c91986 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/bottom-right.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/calendar.png b/GCR/trunk/Glodon/src/GLD/Res/ico/calendar.png new file mode 100644 index 00000000..49a99f92 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/calendar.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/hs.png b/GCR/trunk/Glodon/src/GLD/Res/ico/hs.png new file mode 100644 index 00000000..290dc34a Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/hs.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/more.png b/GCR/trunk/Glodon/src/GLD/Res/ico/more.png new file mode 100644 index 00000000..47e4297d Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/more.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/r-hover.png b/GCR/trunk/Glodon/src/GLD/Res/ico/r-hover.png new file mode 100644 index 00000000..384a1d12 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/r-hover.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/right-bottom.png b/GCR/trunk/Glodon/src/GLD/Res/ico/right-bottom.png new file mode 100644 index 00000000..d69e34f4 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/right-bottom.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/right-conter.png b/GCR/trunk/Glodon/src/GLD/Res/ico/right-conter.png new file mode 100644 index 00000000..60246907 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/right-conter.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/right-top.png b/GCR/trunk/Glodon/src/GLD/Res/ico/right-top.png new file mode 100644 index 00000000..d555d145 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/right-top.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/right.png b/GCR/trunk/Glodon/src/GLD/Res/ico/right.png new file mode 100644 index 00000000..8699c294 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/right.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/rigjt02.png b/GCR/trunk/Glodon/src/GLD/Res/ico/rigjt02.png new file mode 100644 index 00000000..a7170e1e Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/rigjt02.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/scrolldownarrow.png b/GCR/trunk/Glodon/src/GLD/Res/ico/scrolldownarrow.png new file mode 100644 index 00000000..a024fc16 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/scrolldownarrow.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/scrollleftarrow.png b/GCR/trunk/Glodon/src/GLD/Res/ico/scrollleftarrow.png new file mode 100644 index 00000000..6ed41bff Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/scrollleftarrow.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/scrollrightarrow.png b/GCR/trunk/Glodon/src/GLD/Res/ico/scrollrightarrow.png new file mode 100644 index 00000000..b043c735 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/scrollrightarrow.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/scrolluparrow.png b/GCR/trunk/Glodon/src/GLD/Res/ico/scrolluparrow.png new file mode 100644 index 00000000..647c1a1b Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/scrolluparrow.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/splitter-bottom.png b/GCR/trunk/Glodon/src/GLD/Res/ico/splitter-bottom.png new file mode 100644 index 00000000..6e43e920 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/splitter-bottom.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/splitter-hover-bottom.png b/GCR/trunk/Glodon/src/GLD/Res/ico/splitter-hover-bottom.png new file mode 100644 index 00000000..daaf9dda Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/splitter-hover-bottom.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/splitter-hover-left.png b/GCR/trunk/Glodon/src/GLD/Res/ico/splitter-hover-left.png new file mode 100644 index 00000000..164bd9b3 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/splitter-hover-left.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/splitter-hover-right.png b/GCR/trunk/Glodon/src/GLD/Res/ico/splitter-hover-right.png new file mode 100644 index 00000000..1a269f51 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/splitter-hover-right.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/splitter-hover-top.png b/GCR/trunk/Glodon/src/GLD/Res/ico/splitter-hover-top.png new file mode 100644 index 00000000..0e1f0451 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/splitter-hover-top.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/splitter-left.png b/GCR/trunk/Glodon/src/GLD/Res/ico/splitter-left.png new file mode 100644 index 00000000..73d224dd Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/splitter-left.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/splitter-pressedH.png b/GCR/trunk/Glodon/src/GLD/Res/ico/splitter-pressedH.png new file mode 100644 index 00000000..f5ce9c20 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/splitter-pressedH.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/splitter-pressedV.png b/GCR/trunk/Glodon/src/GLD/Res/ico/splitter-pressedV.png new file mode 100644 index 00000000..c1b811fc Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/splitter-pressedV.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/splitter-right.png b/GCR/trunk/Glodon/src/GLD/Res/ico/splitter-right.png new file mode 100644 index 00000000..c07b62d9 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/splitter-right.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/splitter-top.png b/GCR/trunk/Glodon/src/GLD/Res/ico/splitter-top.png new file mode 100644 index 00000000..2f9cf5ee Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/splitter-top.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/02.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/02.png new file mode 100644 index 00000000..a7242e91 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/02.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/03.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/03.png new file mode 100644 index 00000000..677e607e Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/03.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/04.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/04.png new file mode 100644 index 00000000..716a9fce Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/04.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/06.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/06.png new file mode 100644 index 00000000..2bd08fb0 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/06.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/BIMLogin.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/BIMLogin.png new file mode 100644 index 00000000..b0fdeed4 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/BIMLogin.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/Close1.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/Close1.png new file mode 100644 index 00000000..ba0fa918 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/Close1.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/Close2.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/Close2.png new file mode 100644 index 00000000..2fbb5bef Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/Close2.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/Close3.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/Close3.png new file mode 100644 index 00000000..38bde09f Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/Close3.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/black_checkbox_checked.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/black_checkbox_checked.png new file mode 100644 index 00000000..b22b2947 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/black_checkbox_checked.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/black_checkbox_unchecked_hover.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/black_checkbox_unchecked_hover.png new file mode 100644 index 00000000..1dcc24b6 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/black_checkbox_unchecked_hover.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/black_checkbox_unchecked_pressed.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/black_checkbox_unchecked_pressed.png new file mode 100644 index 00000000..f158cca5 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/black_checkbox_unchecked_pressed.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/black_keyboard01.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/black_keyboard01.png new file mode 100644 index 00000000..0ea72c8c Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/black_keyboard01.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/black_keyboard02.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/black_keyboard02.png new file mode 100644 index 00000000..017742e0 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/black_keyboard02.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/black_keyboard03.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/black_keyboard03.png new file mode 100644 index 00000000..0d0c0f7d Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/black_keyboard03.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/blue_checkbox_checked.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/blue_checkbox_checked.png new file mode 100644 index 00000000..468b4a79 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/blue_checkbox_checked.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/blue_checkbox_unchecked_hover.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/blue_checkbox_unchecked_hover.png new file mode 100644 index 00000000..526fbcd9 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/blue_checkbox_unchecked_hover.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/blue_checkbox_unchecked_pressed.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/blue_checkbox_unchecked_pressed.png new file mode 100644 index 00000000..f5eb3d08 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/blue_checkbox_unchecked_pressed.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/blue_keyboard01.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/blue_keyboard01.png new file mode 100644 index 00000000..0ea72c8c Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/blue_keyboard01.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/blue_keyboard02.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/blue_keyboard02.png new file mode 100644 index 00000000..c3019389 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/blue_keyboard02.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/blue_keyboard03.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/blue_keyboard03.png new file mode 100644 index 00000000..f720c453 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/blue_keyboard03.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/close01.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/close01.png new file mode 100644 index 00000000..b504916a Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/close01.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/close02.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/close02.png new file mode 100644 index 00000000..59ddf1cc Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/close02.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/common_checkbox_unchecked.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/common_checkbox_unchecked.png new file mode 100644 index 00000000..413819ad Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/common_checkbox_unchecked.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/darkblue_checkbox_checked.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/darkblue_checkbox_checked.png new file mode 100644 index 00000000..a5e38a0c Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/darkblue_checkbox_checked.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/darkblue_checkbox_unchecked_hover.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/darkblue_checkbox_unchecked_hover.png new file mode 100644 index 00000000..8d73b554 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/darkblue_checkbox_unchecked_hover.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/darkblue_checkbox_unchecked_pressed.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/darkblue_checkbox_unchecked_pressed.png new file mode 100644 index 00000000..47dfd210 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/darkblue_checkbox_unchecked_pressed.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/darkblue_keyboard01.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/darkblue_keyboard01.png new file mode 100644 index 00000000..0ea72c8c Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/darkblue_keyboard01.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/darkblue_keyboard02.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/darkblue_keyboard02.png new file mode 100644 index 00000000..8244f260 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/darkblue_keyboard02.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/darkblue_keyboard03.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/darkblue_keyboard03.png new file mode 100644 index 00000000..b9519e92 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/darkblue_keyboard03.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/eroo.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/eroo.png new file mode 100644 index 00000000..7524a715 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/eroo.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/ew.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/ew.png new file mode 100644 index 00000000..2de419ff Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/ew.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/green_checkbox_checked.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/green_checkbox_checked.png new file mode 100644 index 00000000..2446279f Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/green_checkbox_checked.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/green_checkbox_unchecked_hover.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/green_checkbox_unchecked_hover.png new file mode 100644 index 00000000..6cbc3e1f Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/green_checkbox_unchecked_hover.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/green_checkbox_unchecked_pressed.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/green_checkbox_unchecked_pressed.png new file mode 100644 index 00000000..77558222 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/green_checkbox_unchecked_pressed.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/green_keyboard01.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/green_keyboard01.png new file mode 100644 index 00000000..0ea72c8c Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/green_keyboard01.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/green_keyboard02.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/green_keyboard02.png new file mode 100644 index 00000000..4a50062b Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/green_keyboard02.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/green_keyboard03.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/green_keyboard03.png new file mode 100644 index 00000000..28c4f291 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/green_keyboard03.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/orange_checkbox_checked.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/orange_checkbox_checked.png new file mode 100644 index 00000000..5a2b0ef0 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/orange_checkbox_checked.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/orange_checkbox_unchecked_hover.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/orange_checkbox_unchecked_hover.png new file mode 100644 index 00000000..f48ff2d5 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/orange_checkbox_unchecked_hover.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/orange_checkbox_unchecked_pressed.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/orange_checkbox_unchecked_pressed.png new file mode 100644 index 00000000..ea092413 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/orange_checkbox_unchecked_pressed.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/orange_keyboard01.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/orange_keyboard01.png new file mode 100644 index 00000000..0ea72c8c Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/orange_keyboard01.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/orange_keyboard02.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/orange_keyboard02.png new file mode 100644 index 00000000..5e987907 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/orange_keyboard02.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/orange_keyboard03.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/orange_keyboard03.png new file mode 100644 index 00000000..ad3ec11b Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/orange_keyboard03.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/purple_checkbox_checked.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/purple_checkbox_checked.png new file mode 100644 index 00000000..7d5c0719 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/purple_checkbox_checked.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/purple_checkbox_unchecked_hover.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/purple_checkbox_unchecked_hover.png new file mode 100644 index 00000000..43809ae4 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/purple_checkbox_unchecked_hover.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/purple_checkbox_unchecked_pressed.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/purple_checkbox_unchecked_pressed.png new file mode 100644 index 00000000..e66c152a Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/purple_checkbox_unchecked_pressed.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/purple_keyboard01.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/purple_keyboard01.png new file mode 100644 index 00000000..0ea72c8c Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/purple_keyboard01.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/purple_keyboard02.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/purple_keyboard02.png new file mode 100644 index 00000000..ff92efc4 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/purple_keyboard02.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/purple_keyboard03.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/purple_keyboard03.png new file mode 100644 index 00000000..50aa1564 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/purple_keyboard03.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/skin.png b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/skin.png new file mode 100644 index 00000000..c5b25632 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/webLog/skin.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ico/z-hover.png b/GCR/trunk/Glodon/src/GLD/Res/ico/z-hover.png new file mode 100644 index 00000000..890b1bd7 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ico/z-hover.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ini/GColorListEx.ini b/GCR/trunk/Glodon/src/GLD/Res/ini/GColorListEx.ini new file mode 100644 index 00000000..f16cb32e --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/ini/GColorListEx.ini @@ -0,0 +1,131 @@ +[blockColor] +blockColor0 = #ffffff00 +blockColor1 = #d7d2d1 +blockColor2 = #c2c2c2 +blockColor3 = #c2c2c2 +blockColor4 = #86848c +blockColor5 = #707070 +blockColor6 = #5f5f5f +blockColor7 = #4f4e4e +blockColor8 = #000000 + +blockColor9 = #ff010f +blockColor10 = #f9865a +blockColor11 = #fedf7d +blockColor12 = #91d151 +blockColor13 = #37b64a +blockColor14 = #00b1f0 +blockColor15 = #0171c0 +blockColor16 = #005c7e +blockColor17 = #662d91 + +blockColor18 = #ffffff +blockColor19 = #ffd5aa +blockColor20 = #fcfecc +blockColor21 = #daffeb +blockColor22 = #a5e0dd +blockColor23 = #c9fefd +blockColor24 = #c6aae0 +blockColor25 = #f1b097 +blockColor26 = #ffabfe +blockColor27 = #d8d8d8 +blockColor28 = #feac54 +blockColor29 = #ffff00 +blockColor30 = #d1ebb7 +blockColor31 = #96e2dd +blockColor32 = #9fe0ef +blockColor33 = #bd99de +blockColor34 = #f38871 +blockColor35 = #b983f0 +blockColor36 = #bfbfbf +blockColor37 = #fe8100 +blockColor38 = #facb3a +blockColor39 = #7ec377 +blockColor40 = #16c0ba +blockColor41 = #4bc2e5 +blockColor42 = #9c7bbd +blockColor43 = #fb6f6b +blockColor44 = #8560a8 +blockColor45 = #a5a5a5 +blockColor46 = #bf6100 +blockColor47 = #feb500 +blockColor48 = #54c665 +blockColor49 = #2e9c94 +blockColor50 = #00aeee +blockColor51 = #7c589d +blockColor52 = #f31f17 +blockColor53 = #6c4d8c +blockColor54 = #7f7f7f +blockColor55 = #7a5102 +blockColor56 = #e9a61e +blockColor57 = #2d9c48 +blockColor58 = #00746a +blockColor59 = #0075ab +blockColor60 = #662b90 +blockColor61 = #9c450b +blockColor62 = #662d91 + +[edgeColor] +edgeColor0 = #979797 +edgeColor1 = #c2c2c2 +edgeColor2 = #a4a4a1 +edgeColor3 = #868d83 +edgeColor4 = #707070 +edgeColor5 = #464646 +edgeColor6 = #262626 +edgeColor7 = #000000 +edgeColor8 = #000000 +edgeColor9 = #a7302f +edgeColor10 = #c95f26 +edgeColor11 = #d5a927 +edgeColor12 = #00b150 +edgeColor13 = #187c2f +edgeColor14 = #0075ab +edgeColor15 = #005c7e +edgeColor16 = #0c4758 +edgeColor17 = #551a83 +edgeColor18 = #e2e5e7 +edgeColor19 = #feac56 +edgeColor20 = #e6ea89 +edgeColor21 = #a9e4a9 +edgeColor22 = #75ce9f +edgeColor23 = #6ed6f4 +edgeColor24 = #c7aade +edgeColor25 = #dd6045 +edgeColor26 = #ff57ff +edgeColor27 = #bfbfbf +edgeColor28 = #ff8000 +edgeColor29 = #e6e873 +edgeColor30 = #92d14f +edgeColor31 = #00aa9d +edgeColor32 = #01bff6 +edgeColor33 = #8560a8 +edgeColor34 = #de5f49 +edgeColor35 = #aa58ff +edgeColor36 = #a5a5a5 +edgeColor37 = #bf6001 +edgeColor38 = #ff9100 +edgeColor39 = #37b64a +edgeColor40 = #289f96 +edgeColor41 = #30a8d5 +edgeColor42 = #8560a8 +edgeColor43 = #f31f19 +edgeColor44 = #8361a8 +edgeColor45 = #7f7f7f +edgeColor46 = #bf6100 +edgeColor47 = #cb883c +edgeColor48 = #2c9e3d +edgeColor49 = #1e9087 +edgeColor50 = #0075ab +edgeColor51 = #652c90 +edgeColor52 = #ec6c64 +edgeColor53 = #642c90 +edgeColor54 = #626262 +edgeColor55 = #803f00 +edgeColor56 = #f8b258 +edgeColor57 = #187c2f +edgeColor58 = #005b51 +edgeColor59 = #005c7e +edgeColor60 = #532f6e +edgeColor61 = #ba1512 +edgeColor62 = #450f60 diff --git a/GCR/trunk/Glodon/src/GLD/Res/ini/GLDInis.qrc b/GCR/trunk/Glodon/src/GLD/Res/ini/GLDInis.qrc new file mode 100644 index 00000000..8979dd84 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/ini/GLDInis.qrc @@ -0,0 +1,6 @@ + + + scrollstyle.ini + GColorListEx.ini + + diff --git a/GCR/trunk/Glodon/src/GLD/Res/ini/scrollstyle.ini b/GCR/trunk/Glodon/src/GLD/Res/ini/scrollstyle.ini new file mode 100644 index 00000000..65f6cf1b --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/ini/scrollstyle.ini @@ -0,0 +1,26 @@ +#滚动柄的宽度 +sliderSize = 8 +#滚动柄的最小长度 +sliderMinLength = 15 +subSliderMinLength = 10 +#上下小箭头的宽度 +arrowWidth = 8 +arrowHeight = 4 +#滚动柄水平垂直位移宽度 +sliderX = 3 +sliderY = 3 +#小箭头水平垂直位移宽度 +arrowX = 3 +arrowY = 6 +#滚动条位移 +sliderAddOffset = 8 +sliderSubOffset = 4 + +#默认的滚动柄颜色 +scrollBarHandleColor = #7da6e4 +#鼠标滑过滚动柄颜色 +scrollBarHandleHoverColor = #648dd8 +#默认滚动条的背景颜色 +scrollBarTrackColor = #ffffff +#鼠标滑过滚动条的背景颜色 +scrollBarTrackHoverColor = #f4f4f4 diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/BIMBlackStyle.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/BIMBlackStyle.qss new file mode 100644 index 00000000..02cceb52 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/BIMBlackStyle.qss @@ -0,0 +1,137 @@ +/*登陆界面边框部分QSS*/ +QDialog#GLDWebLogin +{ + background-color: rgb(255, 255, 255); + border-width: 1px; + border-color: rgb(51,51,51); + border-style: solid; border-radius: 0px; +} + +/*登录标题背景图片QSS*/ +QLabel#GLDLoginTitle +{ + background-image: url(:/icons/webLog/BIMLogin.png) +} + +/*登录标题之关闭按钮QSS*/ +QPushButton#LoginTitleCloseButton +{ + background-image: url(:/icons/webLog/Close1.png); + border: 0px; +} +QPushButton#LoginTitleCloseButton:hover +{ + background-image: url(:/icons/webLog/Close2.png); + border: 0px; +} +QPushButton#LoginTitleCloseButton:pressed +{ + background-image: url(:/icons/webLog/Close3.png); + border: 0px; +} + +/*用户名和密码输入框QSS*/ +QLineEdit#UserNameAndPassWord +{ + border: 1px solid #c4c4c4; + border-radius: 0px; + selection-background-color: #616060; + font-family: Arial; + font-size: 9pt; +} + +QLineEdit#UserNameAndPassWord:hover +{ + border: 1px solid #616060; +} + +/*登陆界面注册按钮QSS*/ +QPushButton#RegisterUser +{ + color: rgb(80, 80, 80); + background-color: Transparent; + border-style: none; +} +QPushButton#RegisterUser:hover +{ + color: rgb(150, 150, 150); + background-color: Transparent; + border-style: none; +} +QPushButton#RegisterUser:pressed +{ + color: gray; + background-color: Transparent; + border-style :none; +} + +/*虚拟按键QSS*/ +QPushButton#VirtualKeyboard +{ + background-image: url(:/icons/webLog/black_keyboard01.png); + vertical-align: middle; + border: 0px; +} +QPushButton#VirtualKeyboard:hover +{ + background-image: url(:/icons/webLog/black_keyboard02.png); + vertical-align: middle; + border: 0px; +} +QPushButton#VirtualKeyboard:pressed +{ + background-image: url(:/icons/webLog/black_keyboard03.png); + vertical-align: middle; + border: 0px; +} + +/*登陆界面找回密码按钮QSS*/ +QPushButton#RetrivePassword +{ + color: rgb(80, 80, 80); + background-color: Transparent; + border-style: none; +} +QPushButton#RetrivePassword:hover +{ + color: rgb(150, 150, 150); + background-color: Transparent; + border-style: none; +} +QPushButton#RetrivePassword:pressed +{ + color: gray; + background-color: Transparent; + border-style :none; +} + +/*登陆界面记住密码和自动登录QSS*/ +QCheckBox#RememberPassWord::indicator:unchecked { + image: url(:/icons/webLog/common_checkbox_unchecked.png); +} + +QCheckBox#RememberPassWord::indicator:unchecked:hover { + image: url(:/icons/webLog/black_checkbox_unchecked_hover.png); +} + +QCheckBox#RememberPassWord::indicator:unchecked:pressed { + image: url(:/icons/webLog/black_checkbox_unchecked_pressed.png); +} + +QCheckBox#RememberPassWord::indicator:checked { + image: url(:/icons/webLog/black_checkbox_checked.png); +} + +/*登陆界面登陆按钮QSS*/ +QPushButton#Login +{ + color: rgb(255, 255, 255); + background-color: rgb(80, 80, 80); + border-radius: 0px; +} +QPushButton#Login:hover +{ + background-color: rgb(50, 50, 50); + border: 1px solid #F49078; + border-radius: 0px; +} diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/BIMBlueStyle.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/BIMBlueStyle.qss new file mode 100644 index 00000000..1360b861 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/BIMBlueStyle.qss @@ -0,0 +1,138 @@ +/*登录界面边框部分QSS*/ +QDialog#GLDWebLogin +{ + border-width: 1px; + border-radius: 0px; + border-style: solid; + border-color: rgb(6,119,225); + background-color: rgb(255, 255, 255); +} + +/*登录标题背景图片QSS*/ +QLabel#GLDLoginTitle +{ + background-image: url(:/icons/webLog/06.png); +} + +/*登录标题之关闭按钮QSS*/ +QPushButton#LoginTitleCloseButton +{ + background-image: url(:/icons/webLog/Close1.png); + border: 0px; +} +QPushButton#LoginTitleCloseButton:hover +{ + background-image: url(:/icons/webLog/Close2.png); + border: 0px; +} +QPushButton#LoginTitleCloseButton:pressed +{ + background-image: url(:/icons/webLog/Close3.png); + border: 0px; +} + +/*用户名和密码输入框QSS*/ +QLineEdit#UserNameAndPassWord +{ + border: 1px solid #c4c4c4; + border-radius: 0px; + selection-background-color: #7298D0; + font-family: Arial; + font-size: 9pt; +} + +QLineEdit#UserNameAndPassWord:hover +{ + border: 1px solid #7298D0; +} + +/*登陆界面注册按钮QSS*/ +QPushButton#RegisterUser +{ + color: rgb(87, 131, 197); + background-color: Transparent; + border-style: none; +} +QPushButton#RegisterUser:hover +{ + color: rgb(152, 180, 220); + background-color: Transparent; + border-style: none; +} +QPushButton#RegisterUser:pressed +{ + color: gray; + background-color: Transparent; + border-style :none; +} + +/*虚拟按键QSS*/ +QPushButton#VirtualKeyboard +{ + background-image: url(:/icons/webLog/darkblue_keyboard01.png); + vertical-align: middle; + border: 0px; +} +QPushButton#VirtualKeyboard:hover +{ + background-image: url(:/icons/webLog/darkblue_keyboard02.png); + vertical-align: middle; + border: 0px; +} +QPushButton#VirtualKeyboard:pressed +{ + background-image: url(:/icons/webLog/darkblue_keyboard03.png); + vertical-align: middle; + border: 0px; +} + +/*登陆界面找回密码按钮QSS*/ +QPushButton#RetrivePassword +{ + color: rgb(87, 131, 197); + background-color: Transparent; + border-style: none; +} +QPushButton#RetrivePassword:hover +{ + color: rgb(152, 180, 220); + background-color: Transparent; + border-style: none; +} +QPushButton#RetrivePassword:pressed +{ + color: gray; + background-color: Transparent; + border-style :none; +} + +/*登陆界面记住密码和自动登录QSS*/ +QCheckBox#RememberPassWord::indicator:unchecked { + image: url(:/icons/webLog/common_checkbox_unchecked.png); +} + +QCheckBox#RememberPassWord::indicator:unchecked:hover { + image: url(:/icons/webLog/blue_checkbox_unchecked_hover.png); +} + +QCheckBox#RememberPassWord::indicator:unchecked:pressed { + image: url(:/icons/webLog/blue_checkbox_unchecked_pressed.png); +} + +QCheckBox#RememberPassWord::indicator:checked { + image: url(:/icons/webLog/blue_checkbox_checked.png); +} + +/*登陆界面登陆按钮QSS*/ +QPushButton#Login +{ + color: rgb(255, 255, 255); + background-color: rgb(87,131,197); + border-radius: 0px; +} +QPushButton#Login:hover +{ + background-color: rgb(87,131,197); + border: 1px solid #333333; + border-radius: 0px; +} diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/BIMKeyboardBlackStyle.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/BIMKeyboardBlackStyle.qss new file mode 100644 index 00000000..c22f2804 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/BIMKeyboardBlackStyle.qss @@ -0,0 +1,96 @@ +/*键盘布局QSS*/ +QWidget#Keyboard +{ + border-width: 1px; + border-radius: 2px; + border-style: solid; + border-color: rgb(54, 112, 184); + background-color: rgb(124, 159, 211); +} +/*键盘关闭按钮QSS*/ +QPushButton#KeyboardCloseButton +{ + border-image: url(:/icons/webLog/close01.png); + border:0px; + border-style: 1px; +} +QPushButton#KeyboardCloseButton:hover +{ + border-image: url(:/icons/webLog/close02.png); + border:0px; + border-style: 1px; +} + +/*键盘shift按钮QSS*/ +QPushButton#KeyboardShift +{ + font-size: 10pt; + border-radius: 2px; + background-color: rgb(255, 255, 255); +} +QPushButton#KeyboardShift:hover +{ + border-radius: 2px; + background-color: rgb(222,222,222); +} +QPushButton#KeyboardShift:pressed +{ + border-radius: 2px; + background-color: rgb(174,174,174); +} + +/*键盘数字按键QSS*/ +QPushButton#KeyboardButton +{ + font-size: 10pt; + border-radius: 2px; + background-color: rgb(255, 255, 255); +} +QPushButton#KeyboardNumberButton:hover +{ + border-radius: 2px; + background-color: rgb(222,222,222); +} +QPushButton#KeyboardNumberButton:pressed +{ + border-radius: 2px; + background-color: rgb(174,174,174); +} + +/*键盘删除按键QSS*/ +QPushButton#KeyboardDeleteButton +{ + font-size: 10pt; + border-radius: 2px; + background-color: rgb(255, 255, 255); +} +QPushButton#KeyboardDeleteButton:hover +{ + border-radius: 2px; + background-color: rgb(222,222,222); +} +QPushButton#KeyboardDeleteButton:pressed +{ + border-radius: 2px; + background-color: rgb(174,174,174); +} + +/*键盘Caps按键QSS*/ +QPushButton#KeyboardCapsButton +{ + font-size: 10pt; + border-radius: 2px; + background-color: rgb(255, 255, 255); +} +QPushButton#KeyboardCapsButton:hover +{ + background-color: rgb(222,222,222); +} +QPushButton#KeyboardCapsButton:pressed +{ + background-color: rgb(174,174,174); +} +QPushButton#KeyboardCapsButton:checked +{ + background-color: rgb(174,174,174); +} diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/BIMKeyboardBlueStyle.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/BIMKeyboardBlueStyle.qss new file mode 100644 index 00000000..8ac7e87c --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/BIMKeyboardBlueStyle.qss @@ -0,0 +1,102 @@ +/*键盘布局QSS*/ +QWidget#Keyboard +{ + border-width: 1px; + border-radius: 2px; + border-style: solid; + border-color: rgb(54, 112, 184); + background-color: rgb(56, 132, 184); +} +/*键盘关闭按钮QSS*/ +QPushButton#KeyboardCloseButton +{ + border-image: url(:/icons/webLog/close01.png); + border:0px; + border-style: 1px; +} +QPushButton#KeyboardCloseButton:hover +{ + border-image: url(:/icons/webLog/close02.png); + border:0px; + border-style: 1px; +} + +/*键盘shift按钮QSS*/ +QPushButton#KeyboardShift +{ + font-size: 10pt; + border-radius: 2px; + background-color: rgb(255, 255, 255); +} +QPushButton#KeyboardShift:hover +{ + border-radius: 2px; + background-color: rgb(222,222,222); +} +QPushButton#KeyboardShift:pressed +{ + border-radius: 2px; + background-color: rgb(174,174,174); +} +QPushButton#KeyboardShift:checked +{ + background-color: rgb(174,174,174); +} + +/*键盘数字按键QSS*/ +QPushButton#KeyboardButton +{ + font-size: 10pt; + border-radius: 2px; + background-color: rgb(255, 255, 255); +} +QPushButton#KeyboardNumberButton:hover +{ + border-radius: 2px; + background-color: rgb(222,222,222); +} +QPushButton#KeyboardNumberButton:pressed +{ + border-radius: 2px; + background-color: rgb(174,174,174); +} + +/*键盘删除按键QSS*/ +QPushButton#KeyboardDeleteButton +{ + font-size: 10pt; + border-radius: 2px; + background-color: rgb(255, 255, 255); +} +QPushButton#KeyboardDeleteButton:hover +{ + border-radius: 2px; + background-color: rgb(222,222,222); +} +QPushButton#KeyboardDeleteButton:pressed +{ + border-radius: 2px; + background-color: rgb(174,174,174); +} + +/*键盘Caps按键QSS*/ +QPushButton#KeyboardCapsButton +{ + font-size: 10pt; + border-radius: 2px; + background-color: rgb(255, 255, 255); +} +QPushButton#KeyboardCapsButton:hover +{ + border-radius: 2px; + background-color: rgb(222,222,222); +} +QPushButton#KeyboardCapsButton:pressed +{ + border-radius: 2px; + background-color: rgb(174,174,174); +} +QPushButton#KeyboardCapsButton:checked +{ + background-color: rgb(174,174,174); +} diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/GBJBlueStyle.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/GBJBlueStyle.qss new file mode 100644 index 00000000..7d4f70cb --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/GBJBlueStyle.qss @@ -0,0 +1,138 @@ +/*登陆界面边框部分QSS*/ +QDialog#BordleLine +{ + border-width: 1px; + border-radius: 0px; + border-style: solid; + border-color: rgb(6, 119, 225); + background-color: rgb(255, 255, 255); +} + +/*登录标题背景图片QSS*/ +QLabel#GLDLoginTitle +{ + background-image: url(:/icons/webLog/skin.png); +} + +/*登录标题之关闭按钮QSS*/ +QPushButton#LoginTitleCloseButton +{ + background-image: url(:/icons/webLog/Close1.png); + border: 0px; +} +QPushButton#LoginTitleCloseButton:hover +{ + background-image: url(:/icons/webLog/Close2.png); + border: 0px; +} +QPushButton#LoginTitleCloseButton:pressed +{ + background-image: url(:/icons/webLog/Close3.png); + border: 0px; +} + +/*用户名和密码输入框QSS*/ +QLineEdit#UserNameAndPassWord +{ + border: 1px solid #c4c4c4; + border-radius: 0px; + selection-background-color: #54A8F3; + font-family: Arial; + font-size: 9pt; +} + +QLineEdit#UserNameAndPassWord:hover +{ + border: 1px solid #54A8F3; +} + +/*登陆界面注册按钮QSS*/ +QPushButton#RegisterUser +{ + color: rgb(10, 147, 247); + background-color: Transparent; + border-style: none; +} +QPushButton#RegisterUser:hover +{ + color: rgb(120, 186, 246); + background-color: Transparent; + border-style: none; +} +QPushButton#RegisterUser:pressed +{ + color: gray; + background-color: Transparent; + border-style :none; +} + +/*虚拟按键QSS*/ +QPushButton#VirtualKeyboard +{ + background-image: url(:/icons/webLog/blue_keyboard01.png); + vertical-align: middle; + border: 0px; +} +QPushButton#VirtualKeyboard:hover +{ + background-image: url(:/icons/webLog/blue_keyboard02.png); + vertical-align: middle; + border: 0px; +} +QPushButton#VirtualKeyboard:pressed +{ + background-image: url(:/icons/webLog/blue_keyboard03.png); + vertical-align: middle; + border: 0px; +} + +/*登陆界面找回密码按钮QSS*/ +QPushButton#RetrivePassword +{ + color: rgb(10, 147, 247); + background-color: Transparent; + border-style: none; +} +QPushButton#RetrivePassword:hover +{ + color: rgb(120, 186, 246); + background-color: Transparent; + border-style: none; +} +QPushButton#RetrivePassword:pressed +{ + color: gray; + background-color: Transparent; + border-style :none; +} + +/*登陆界面记住密码和自动登录QSS*/ +QCheckBox#RememberPassWord::indicator:unchecked { + image: url(:/icons/webLog/common_checkbox_unchecked.png); +} + +QCheckBox#RememberPassWord::indicator:unchecked:hover { + image: url(:/icons/webLog/darkblue_checkbox_unchecked_hover.png); +} + +QCheckBox#RememberPassWord::indicator:unchecked:pressed { + image: url(:/icons/webLog/darkblue_checkbox_unchecked_pressed.png); +} + +QCheckBox#RememberPassWord::indicator:checked { + image: url(:/icons/webLog/darkblue_checkbox_checked.png); +} + +/*登陆界面登陆按钮QSS*/ +QPushButton#Login +{ + color: rgb(255, 255, 255); + background-color: rgb(10, 147, 247); + border-radius: 0px; +} +QPushButton#Login:hover +{ + background-color: rgb(10, 147, 247); + border: 1px solid #333333; + border-radius: 0px; +} diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/GBJKeyboardBlueStyle.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/GBJKeyboardBlueStyle.qss new file mode 100644 index 00000000..b65474cd --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/GBJKeyboardBlueStyle.qss @@ -0,0 +1,102 @@ +/*键盘布局QSS*/ +QWidget#Keyboard +{ + border-width: 1px; + border-radius: 2px; + border-style: solid; + border-color: rgb(54, 112, 184); + background-color: rgb(23, 118, 183); +} +/*键盘关闭按钮QSS*/ +QPushButton#KeyboardCloseButton +{ + border-image: url(:/icons/webLog/close01.png); + border:0px; + border-style: 1px; +} +QPushButton#KeyboardCloseButton:hover +{ + border-image: url(:/icons/webLog/close02.png); + border:0px; + border-style: 1px +} + +/*键盘shift按钮QSS*/ +QPushButton#KeyboardShift +{ + font-size: 10pt; + border-radius: 2px; + background-color: rgb(255, 255, 255); +} +QPushButton#KeyboardShift:hover +{ + border-radius: 2px; + background-color: rgb(222,222,222); +} +QPushButton#KeyboardShift:pressed +{ + border-radius: 2px; + background-color: rgb(174,174,174); +} +QPushButton#KeyboardShift:checked +{ + background-color: rgb(174,174,174); +} + +/*键盘数字按键QSS*/ +QPushButton#KeyboardButton +{ + font-size: 10pt; + border-radius: 2px; + background-color: rgb(255, 255, 255); +} +QPushButton#KeyboardNumberButton:hover +{ + border-radius: 2px; + background-color: rgb(222,222,222); +} +QPushButton#KeyboardNumberButton:pressed +{ + border-radius: 2px; + background-color: rgb(174,174,174); +} + +/*键盘删除按键QSS*/ +QPushButton#KeyboardDeleteButton +{ + font-size: 10pt; + border-radius: 2px; + background-color: rgb(255, 255, 255); +} +QPushButton#KeyboardDeleteButton:hover +{ + border-radius: 2px; + background-color: rgb(222,222,222); +} +QPushButton#KeyboardDeleteButton:pressed +{ + border-radius: 2px; + background-color: rgb(174,174,174); +} + +/*键盘Caps按键QSS*/ +QPushButton#KeyboardCapsButton +{ + font-size: 10pt; + border-radius: 2px; + background-color: rgb(255, 255, 255); +} +QPushButton#KeyboardCapsButton:hover +{ + border-radius: 2px; + background-color: rgb(222,222,222); +} +QPushButton#KeyboardCapsButton:pressed,checked +{ + border-radius: 2px; + background-color: rgb(174,174,174); +} +QPushButton#KeyboardCapsButton:checked +{ + background-color: rgb(174,174,174); +} diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/GBQKeyboardOrangeStyle.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/GBQKeyboardOrangeStyle.qss new file mode 100644 index 00000000..7179cffb --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/GBQKeyboardOrangeStyle.qss @@ -0,0 +1,103 @@ +/*键盘布局QSS*/ +QWidget#Keyboard +{ + border-width: 1px; + border-radius: 2px; + border-style: solid; + border-color: rgb(54, 112, 184); + background-color: rgb(206, 149, 0); +} +/*键盘关闭按钮QSS*/ +QPushButton#KeyboardCloseButton +{ + border-image: url(:/icons/webLog/close01.png); + border:0px; + border-style: 1px; +} +QPushButton#KeyboardCloseButton:hover +{ + border-image: url(:/icons/webLog/close02.png); + border:0px; + border-style: 1px; +} + +/*键盘shift按钮QSS*/ +QPushButton#KeyboardShift +{ + font-size: 10pt; + border-radius: 2px; + background-color: rgb(255, 255, 255); +} +QPushButton#KeyboardShift:hover +{ + border-radius: 2px; + background-color: rgb(222,222,222); +} +QPushButton#KeyboardShift:pressed +{ + border-radius: 2px; + background-color: rgb(174,174,174); +} +QPushButton#KeyboardShift:checked +{ + background-color: rgb(174,174,174); +} + + +/*键盘数字按键QSS*/ +QPushButton#KeyboardButton +{ + font-size: 10pt; + border-radius: 2px; + background-color: rgb(255, 255, 255); +} +QPushButton#KeyboardNumberButton:hover +{ + border-radius: 2px; + background-color: rgb(222,222,222); +} +QPushButton#KeyboardNumberButton:pressed +{ + border-radius: 2px; + background-color: rgb(174,174,174); +} + +/*键盘删除按键QSS*/ +QPushButton#KeyboardDeleteButton +{ + font-size: 10pt; + border-radius: 2px; + background-color: rgb(255, 255, 255); +} +QPushButton#KeyboardDeleteButton:hover +{ + border-radius: 2px; + background-color: rgb(222,222,222); +} +QPushButton#KeyboardDeleteButton:pressed +{ + border-radius: 2px; + background-color: rgb(174,174,174); +} + +/*键盘Caps按键QSS*/ +QPushButton#KeyboardCapsButton +{ + font-size: 10pt; + border-radius: 2px; + background-color: rgb(255, 255, 255); +} +QPushButton#KeyboardCapsButton:hover +{ + border-radius: 2px; + background-color: rgb(222,222,222); +} +QPushButton#KeyboardCapsButton:pressed +{ + border-radius: 2px; + background-color: rgb(174,174,174); +} +QPushButton#KeyboardCapsButton:checked +{ + background-color: rgb(174,174,174); +} diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/GBQOrangeStyle.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/GBQOrangeStyle.qss new file mode 100644 index 00000000..f3436d58 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/GBQOrangeStyle.qss @@ -0,0 +1,138 @@ +/*登录界面边框部分QSS*/ +QDialog#GLDWebLogin +{ + border-width: 1px; + border-radius: 0px; + border-style: solid; + border-color: rgb(247,150,70); + background-color: rgb(255, 255, 255); +} + +/*登录标题背景图片QSS*/ +QLabel#GLDLoginTitle +{ + background-image: url(:/icons/webLog/03.png); +} + +/*登录标题之关闭按钮QSS*/ +QPushButton#LoginTitleCloseButton +{ + background-image: url(:/icons/webLog/Close1.png); + border: 0px; +} +QPushButton#LoginTitleCloseButton:hover +{ + background-image: url(:/icons/webLog/Close2.png); + border: 0px; +} +QPushButton#LoginTitleCloseButton:pressed +{ + background-image: url(:/icons/webLog/Close3.png); + border: 0px; +} + +/*用户名和密码输入框QSS*/ +QLineEdit#UserNameAndPassWord +{ + border: 1px solid #c4c4c4; + border-radius: 0px; + selection-background-color: #F1A05D; + font-family: Arial; + font-size: 9pt; +} + +QLineEdit#UserNameAndPassWord:hover { + border: 1px solid #F1A05D; +} + +/*登录界面注册按钮QSS*/ +QPushButton#RegisterUser +{ + color: rgb(235, 139, 60); + background-color: Transparent; + border-style: none; +} +QPushButton#RegisterUser:hover +{ + color: rgb(246, 186, 136); + background-color: Transparent; + border-style: none; +} +QPushButton#RegisterUser:pressed +{ + color: gray; + background-color: Transparent; + border-style :none; +} + +/*虚拟按键QSS*/ +QPushButton#VirtualKeyboard +{ + background-image: url(:/icons/webLog/orange_keyboard01.png); + vertical-align: middle; + border: 0px; +} +QPushButton#VirtualKeyboard:hover +{ + background-image: url(:/icons/webLog/orange_keyboard02.png); + vertical-align: middle; + border: 0px; +} +QPushButton#VirtualKeyboard:pressed +{ + background-image: url(:/icons/webLog/orange_keyboard03.png); + vertical-align: middle; + border: 0px; +} + +/*登录界面找回密码按钮QSS*/ +QPushButton#RetrivePassword +{ + color: rgb(235, 139, 60); + background-color: Transparent; + border-style: none; +} +QPushButton#RetrivePassword:hover +{ + color: rgb(246, 186, 136); + background-color: Transparent; + border-style: none; +} +QPushButton#RetrivePassword:pressed +{ + color: gray; + background-color: Transparent; + border-style :none; +} + +/*登陆界面记住密码和自动登录QSS*/ +QCheckBox#RememberPassWord::indicator:unchecked { + image: url(:/icons/webLog/common_checkbox_unchecked.png); +} + +QCheckBox#RememberPassWord::indicator:unchecked:hover { + image: url(:/icons/webLog/orange_checkbox_unchecked_hover.png); +} + +QCheckBox#RememberPassWord::indicator:unchecked:pressed { + image: url(:/icons/webLog/orange_checkbox_unchecked_pressed.png); +} + +QCheckBox#RememberPassWord::indicator:checked { + image: url(:/icons/webLog/orange_checkbox_checked.png); +} + + +/*登录界面登录按钮QSS*/ +QPushButton#Login +{ + color: rgb(255, 255, 255); + background-color: rgb(235,139,60); + border-radius: 0px; +} +QPushButton#Login:hover +{ + background-color: rgb(235, 139, 60); + border: 1px solid #333333; + border-radius: 0px; +} diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/GBTKeyboardPurpleStyle.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/GBTKeyboardPurpleStyle.qss new file mode 100644 index 00000000..e390c579 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/GBTKeyboardPurpleStyle.qss @@ -0,0 +1,101 @@ +/*键盘布局QSS*/ +QWidget#Keyboard +{ + border-width: 1px; + border-radius: 2px; + border-style: solid; + border-color: rgb(54, 112, 184); + background-color: rgb(109, 94, 172); +} +/*键盘关闭按钮QSS*/ +QPushButton#KeyboardCloseButton +{ + border-image: url(:/icons/webLog/close01.png); + border:0px; + border-style: 1px; +} +QPushButton#KeyboardCloseButton:hover +{ + border-image: url(:/icons/webLog/close02.png); + border:0px; + border-style: 1px; +} + +/*键盘shift按钮QSS*/ +QPushButton#KeyboardShift +{ + font-size: 10pt; + border-radius: 2px; + background-color: rgb(255, 255, 255); +} +QPushButton#KeyboardShift:hover +{ + border-radius: 2px; + background-color: rgb(222, 222, 222); +} +QPushButton#KeyboardShift:pressed +{ + border-radius: 2px; + background-color: rgb(174, 174, 174); +} +QPushButton#KeyboardShift:checked +{ + background-color: rgb(174, 174, 174); +} + +/*键盘数字按键QSS*/ +QPushButton#KeyboardButton +{ + font-size: 10pt; + border-radius: 2px; + background-color: rgb(255, 255, 255); +} +QPushButton#KeyboardButton:hover +{ + border-radius: 2px; + background-color: rgb(222,222,222); +} +QPushButton#KeyboardButton:pressed +{ + border-radius: 2px; + background-color: rgb(174,174,174); +} + +/*键盘删除按键QSS*/ +QPushButton#KeyboardDeleteButton +{ + font-size: 10pt; + border-radius: 2px; + background-color: rgb(255, 255, 255); +} +QPushButton#KeyboardDeleteButton:hover +{ + border-radius: 2px; + background-color: rgb(222,222,222); +} +QPushButton#KeyboardDeleteButton:pressed +{ + border-radius: 2px; + background-color: rgb(174,174,174); +} + +/*键盘Caps按键QSS*/ +QPushButton#KeyboardCapsButton +{ + font-size: 10pt; + border-radius: 2px; + background-color: rgb(255, 255, 255); +} +QPushButton#KeyboardCapsButton:hover +{ + background-color: rgb(222,222,222); +} +QPushButton#KeyboardCapsButton:pressed +{ + background-color: rgb(174,174,174); +} + +QPushButton#KeyboardCapsButton:checked +{ + background-color: rgb(174,174,174); +} diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/GBTPurpleStyle.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/GBTPurpleStyle.qss new file mode 100644 index 00000000..cc7df911 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/GBTPurpleStyle.qss @@ -0,0 +1,150 @@ +/*登录界面边框QSS*/ +QDialog#GLDWebLogin +{ + border-width: 1px; + border-radius: 0px; + border-style: solid; + border-color: rgb(124, 126, 221); + background-color: rgb(255, 255, 255); +} + +/*登录标题背景图片QSS*/ +QLabel#GLDLoginTitle +{ + background-image: url(:/icons/webLog/04.png); +} + +/*登录标题之关闭按钮QSS*/ +QPushButton#LoginTitleCloseButton +{ + background-image: url(:/icons/webLog/Close1.png); + border: 0px; +} +QPushButton#LoginTitleCloseButton:hover +{ + background-image: url(:/icons/webLog/Close2.png); + border: 0px; +} +QPushButton#LoginTitleCloseButton:pressed +{ + background-image: url(:/icons/webLog/Close3.png); + border: 0px; +} + +/*用户名和密码输入框QSS*/ +QLineEdit#UserNameAndPassWord +{ + border: 1px solid #c4c4c4; + border-radius: 0px; + selection-background-color: #8D8FE1; + font-family: Arial; + font-size: 9pt; +} + +QLineEdit#UserNameAndPassWord:hover +{ + border: 1px solid #8D8FE1; +} + +/*登陆界面注册按钮QSS*/ +QPushButton#RegisterUser +{ + color: rgb(124, 126, 221); + background-color: Transparent; + border-style: none; +} +QPushButton#RegisterUser:hover +{ + color: rgb(178, 182, 238); + background-color: Transparent; + border-style: none; +} +QPushButton#RegisterUser:pressed +{ + color: gray; + background-color: Transparent; + border-style :none; +} + +/*虚拟按键QSS*/ +QPushButton#VirtualKeyboard +{ + background-image: url(:/icons/webLog/purple_keyboard01.png); + vertical-align: middle; + border: 0px; +} +QPushButton#VirtualKeyboard:hover +{ + background-image: url(:/icons/webLog/purple_keyboard02.png); + vertical-align: middle; + border: 0px; +} +QPushButton#VirtualKeyboard:pressed +{ + background-image: url(:/icons/webLog/purple_keyboard03.png); + vertical-align: middle; + border: 0px; +} + +/*登陆界面找回密码按钮QSS*/ +QPushButton#RetrivePassword +{ + color: rgb(124, 126, 221); + background-color: Transparent; + border-style: none; +} +QPushButton#RetrivePassword:hover +{ + color: rgb(178, 182, 238); + background-color: Transparent; + border-style: none; +} +QPushButton#RetrivePassword:pressed +{ + color: gray; + background-color: Transparent; + border-style :none; +} + + +/*登陆界面记住密码和自动登录QSS*/ +QCheckBox#RememberPassWord::indicator:unchecked { + image: url(:/icons/webLog/common_checkbox_unchecked.png); +} + +QCheckBox#RememberPassWord::indicator:unchecked:hover { + image: url(:/icons/webLog/purple_checkbox_unchecked_hover.png); +} + +QCheckBox#RememberPassWord::indicator:unchecked:pressed { + image: url(:/icons/webLog/purple_checkbox_unchecked_pressed.png); +} + +QCheckBox#RememberPassWord::indicator:checked { + image: url(:/icons/webLog/purple_checkbox_checked.png); +} + +QPushButton#ErrorInformation +{ + color: rgb(255,102,0); + border: 1px solid #ff9999; + font-size: 12px; + font: Times New Roman; + icon-size: 16px 16px; + image-position: left center; + image: url(:/icons/webLog/eroo.png); +} + +/*登录界面登录按钮QSS*/ +QPushButton#Login +{ + color: rgb(255, 255, 255); + background-color: rgb(137, 139, 224); + border-radius: 0px; +} +QPushButton#Login:hover +{ + background-color: rgb(124, 126, 221); + border: 1px solid #333333; + border-radius: 0px; +} diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/GCLGreenStyle.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/GCLGreenStyle.qss new file mode 100644 index 00000000..53d332f4 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/GCLGreenStyle.qss @@ -0,0 +1,138 @@ +/*登录界面边框部分QSS*/ +QDialog#GLDWebLogin +{ + border-width: 1px; + border-radius: 0px; + border-style: solid; + border-color: rgb(23,175,41); + background-color: rgb(255, 255, 255); +} + +/*登录标题背景图片QSS*/ +QLabel#GLDLoginTitle +{ + background-image: url(:/icons/webLog/02.png); +} + +/*登录标题之关闭按钮QSS*/ +QPushButton#LoginTitleCloseButton +{ + background-image: url(:/icons/webLog/Close1.png); + border: 0px; +} +QPushButton#LoginTitleCloseButton:hover +{ + background-image: url(:/icons/webLog/Close2.png); + border: 0px; +} +QPushButton#LoginTitleCloseButton:pressed +{ + background-image: url(:/icons/webLog/Close3.png); + border: 0px; +} + +/*用户名和密码输入框QSS*/ +QLineEdit#UserNameAndPassWord +{ + border: 1px solid #c4c4c4; + border-radius: 0px; + selection-background-color: #7DD488; + font-family: Arial; + font-size: 9pt; +} + +QLineEdit#UserNameAndPassWord:hover +{ + border: 1px solid #7DD488; +} + +/*登录界面注册按钮QSS*/ +QPushButton#RegisterUser +{ + color: rgb(23, 175, 41); + background-color: Transparent; + border-style: none; +} +QPushButton#RegisterUser:hover +{ + color: rgb(137, 216, 146); + background-color: Transparent; + border-style: none; +} +QPushButton#RegisterUser:pressed +{ + color: gray; + background-color: Transparent; + border-style :none; +} + +/*虚拟按键QSS*/ +QPushButton#VirtualKeyboard +{ + background-image: url(:/icons/webLog/green_keyboard01.png); + vertical-align: middle; + border: 0px; +} +QPushButton#VirtualKeyboard:hover +{ + background-image: url(:/icons/webLog/green_keyboard02.png); + vertical-align: middle; + border: 0px; +} +QPushButton#VirtualKeyboard:pressed +{ + background-image: url(:/icons/webLog/green_keyboard03.png); + vertical-align: middle; + border: 0px; +} + +/*登录界面找回密码按钮QSS*/ +QPushButton#RetrivePassword +{ + color: rgb(23, 175, 41); + background-color: Transparent; + border-style: none; +} +QPushButton#RetrivePassword:hover +{ + color: rgb(137, 216, 146); + background-color: Transparent; + border-style: none; +} +QPushButton#RetrivePassword:pressed +{ + color: gray; + background-color: Transparent; + border-style :none; +} + +/*登陆界面记住密码和自动登录QSS*/ +QCheckBox#RememberPassWord::indicator:unchecked { + image: url(:/icons/webLog/common_checkbox_unchecked.png); +} + +QCheckBox#RememberPassWord::indicator:unchecked:hover { + image: url(:/icons/webLog/green_checkbox_unchecked_hover.png); +} + +QCheckBox#RememberPassWord::indicator:unchecked:pressed { + image: url(:/icons/webLog/green_checkbox_unchecked_pressed.png); +} + +QCheckBox#RememberPassWord::indicator:checked { + image: url(:/icons/webLog/green_checkbox_checked.png); +} + +/*登录界面登录按钮QSS*/ +QPushButton#Login +{ + color: rgb(255, 255, 255); + background-color: rgb(23, 175, 41); + border-radius: 0px; +} +QPushButton#Login:hover +{ + background-color: rgb(23,175,41); + border: 1px solid #333333; + border-radius: 0px; +} diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/GCLKeyboardGreenStyle.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/GCLKeyboardGreenStyle.qss new file mode 100644 index 00000000..1ea86ef4 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/GCLKeyboardGreenStyle.qss @@ -0,0 +1,102 @@ +/*键盘布局QSS*/ +QWidget#Keyboard +{ + border-width: 1px; + border-radius: 2px; + border-style: solid; + border-color: rgb(54, 112, 184); + background-color: rgb(29, 160, 52); +} +/*键盘关闭按钮QSS*/ +QPushButton#KeyboardCloseButton +{ + border-image: url(:/icons/webLog/close01.png); + border: 0px; + border-style: 1px; +} +QPushButton#KeyboardCloseButton:hover +{ + border-image: url(:/icons/webLog/close02.png); + border: 0px; + border-style: 1px; +} + +/*键盘shift按钮QSS*/ +QPushButton#KeyboardShift +{ + font-size: 10pt; + border-radius: 2px; + background-color: rgb(255, 255, 255); +} +QPushButton#KeyboardShift:hover +{ + border-radius: 2px; + background-color: rgb(222,222,222); +} +QPushButton#KeyboardShift:pressed +{ + border-radius: 2px; + background-color: rgb(174,174,174); +} +QPushButton#KeyboardShift:checked +{ + background-color: rgb(174,174,174); +} + +/*键盘数字按键QSS*/ +QPushButton#KeyboardButton +{ + font-size: 10pt; + border-radius: 2px; + background-color: rgb(255, 255, 255); +} +QPushButton#KeyboardNumberButton:hover +{ + border-radius: 2px; + background-color: rgb(222,222,222); +} +QPushButton#KeyboardNumberButton:pressed +{ + border-radius: 2px; + background-color: rgb(174,174,174); +} + +/*键盘删除按键QSS*/ +QPushButton#KeyboardDeleteButton +{ + font-size: 10pt; + border-radius: 2px; + background-color: rgb(255, 255, 255); +} +QPushButton#KeyboardDeleteButton:hover +{ + border-radius: 2px; + background-color: rgb(222,222,222); +} +QPushButton#KeyboardDeleteButton:pressed +{ + border-radius: 2px; + background-color: rgb(174,174,174); +} + +/*键盘Caps按键QSS*/ +QPushButton#KeyboardCapsButton +{ + font-size: 10pt; + border-radius: 2px; + background-color: rgb(255, 255, 255); +} +QPushButton#KeyboardCapsButton:hover +{ + border-radius: 2px; + background-color: rgb(222,222,222); +} +QPushButton#KeyboardCapsButton:pressed +{ + border-radius: 2px; + background-color: rgb(174,174,174); +} +QPushButton#KeyboardCapsButton:checked +{ + background-color: rgb(174,174,174); +} diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/GColorListEx.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/GColorListEx.qss new file mode 100644 index 00000000..40098086 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/GColorListEx.qss @@ -0,0 +1,119 @@ +/*GLDComboBox编辑框样式*/ +GColorListEx[ComboBoxBorder = "false"] +{ + border: 0px solid #c0c0c0; + padding: 0px 0px 0px 5px; +} + +GColorListEx[ComboBoxBorder = "true"]:hover, +GColorListEx[ComboBoxBorder = "true"]:focus, +GColorListEx[ComboBoxBorder = "true"]:on +{ + border: 1px solid #39a9d1; +} + +/*GLDComboBox编辑框样式*/ +GColorListEx[ComboBoxBorder = "true"] +{ + border: 1px solid #c0c0c0; + padding: 0px 0px 0px 5px; + height: 25px; +} + +/*GLDComboBox下拉框小图标样式*/ +GColorListEx::drop-down +{ + subcontrol-origin: margin; + subcontrol-position: center right; + image: url(:/icons/GLDWindowComboBoxEx-downarrow.png); + background-repeat: no-repeat; + background-color: white; + margin-right: 1px; +} + +/*QListView的边线*/ +GColorListEx QListView +{ + outline: 0px; +} + +/*QListView的Item选中边界*/ +GColorListEx QListView::item:selected +{ + border: 1px solid #f0f3f5; +} + +/*移动到QListView的Item的背景色*/ +GColorListEx QListView::item:hover +{ + background: #f0f3f5; +} + +/*QListView的Item被选中激活的背景色*/ +GColorListEx QListView::item:selected:active +{ + background: #f0f3f5; +} + +/*QListView的Item被选中激活的背景色*/ +GColorListEx QListView::item:clicked +{ + background: #f0f3f5; +} + +GLDColorTable[grayColorTab = "true"] +{ + background-color: #f0f3f5; + border-top: 1px solid #39a9d1; +} + +QListWidget +{ + border: 1px solid #39a9d1; +} + +/* QPushButton的边界调整为无边界*/ +QPushButton[GLDColorBlock = "true"] +{ + border: 0px solid #39a9d1; +} + +/* GLDColorTableTitle 样式 */ +QPushButton[GLDColorLabel = "true"] +{ + border: 0px solid #39a9d1; +} + +/*移动到GLDColorBlock的边线和背景样式*/ +QPushButton[colorBlock = "true"]:hover +{ + border: 1px solid #f19636; + border-radius: 2px; + background-color: #fbf2c2; +} + +/*GLDColorTable的标题样式*/ +QPushButton[tabTitle = "true"] +{ + text-align: left; + padding-top: 5px; + color: #356091; + font-family: "simsun"; + font-size: 12; +} + +/*更多颜色的样式*/ +QPushButton[moreBtn = "true"] +{ + text-align: left; + padding-left: 42px; + color: #455059; + font-family: "simsun"; + font-size: 12; + border-top: 1px solid #a6b8d3; + background-image: url(:/icons/GColorListEx-moreColorIcon.png); + background-repeat: no repeat; + background-position: left; + background-color: white; + height: 35px; +} diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/GLDColorGrid.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDColorGrid.qss new file mode 100644 index 00000000..4f77f4fe --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDColorGrid.qss @@ -0,0 +1,101 @@ +GColorGrid +{ + border: 1px solid #c0c0c0; + padding: 3px 5px 0px 5px ; + height: 25px; + width: 235px; +} + +GColorGrid:focus +{ + border: 1px solid #658cd9; + background-image: url(:/icons/shellcomboboxxl.png); + background-repeat: no-repeat; + background-position: right center; +} + +GColorGrid:on +{ + border: 1px solid #658cd9; + padding: 3px 0px 0px 0px; + height: 25px; + max-width: 235px; +} + +GColorGrid::drop-down { + width: 18px; + border: 0px solid #fff; +} + +GColorGrid::drop-down:on +{ + image: url(:/icons/shellcomboboxon.png); + background-repeat: no-repeat; + background-position: left center; + background-color: white; +} + +GColorGrid QListWidget[outterWidget="true"] +{ + border: 1px solid #658cd9; + max-width: 235px; +} + +GColorGrid QListWidget[topColorWidget="true"] +{ + border-top: 0px solid #06acfd; + padding: 5px 1px 6px 3px; + max-width: 235px; +} + +GColorGrid QListWidget[standartTitleWidget="true"] +{ + border-top: 0px solid #a6b8d3; + padding: 3px 1px 0px 3px; + max-width: 235px; +} + +GColorGrid QListWidget[themeTitleWidget="true"] +{ + border-top: 0px solid #a6b8d3; + padding: 3px 1px 0px 3px; + max-width: 235px; +} + +GColorGrid QListWidget[standardColorWidget="true"], [themeColorWidget="true"] +{ + border-top: 0px solid #a6b8d3; + padding: 4px 1px 4px 3px; + max-width: 235px; +} + +GColorGrid QListWidget[moreWidget="true"] +{ + border-top: 1px solid #a6b8d3; + padding: 0px; + max-width: 235px; + min-height: 23px; +} + +GColorGrid QAbstractItemView::item +{ + border: 0px solid #a6b8d3; + padding: 0px; + margin: 0px; +} + +GColorGrid QAbstractItemView::item:hover +{ + border: 1px solid #658cd9; + background-color: #fbf2c2; +} + +QTableView +{ + border: 0px solid #a6b8d3; +} + +.QWidget +{ + background-color:red; +} diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/GLDCustomComboBoxEx.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDCustomComboBoxEx.qss new file mode 100644 index 00000000..fcd4055a --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDCustomComboBoxEx.qss @@ -0,0 +1,78 @@ +/*******************GLDCustomComboBoxEx*************************/ +/*GLDCustomComboBoxEx处于关闭状态*/ +GLDCustomComboBoxEx { + padding: 0px 0px 0px 1px; + height: 25px; + color: #435057; + font-size: 12px; + border: 1px solid #39a9d1; + selection-background-color: #a1c3ee; + selection-color: #455059; +} + +GLDCustomComboBoxEx[borderStyle="noBorder"] +{ + border: 0px solid #39a9d1; +} + +/* GLDCustomComboBoxEx处于打开状态 */ +GLDCustomComboBoxEx:on +{ + color:#6f6f6f; + border: 1px solid #39a9d1; +} + +GLDCustomComboBoxEx[borderStyle="noBorder"]:on +{ + border: 0px solid #39a9d1; +} + +/*drop-down处于默认状态*/ +GLDCustomComboBoxEx::drop-down { + width: 24px; + border: 1px solid #fff; + image: url(:/icons/GLDCustomComboBoxEx-downarrow.png); +} + +/*下拉出来的QAbstractItemView参数控制*/ +GLDCustomComboBoxEx QAbstractItemView +{ + margin-top: 0px; + padding-left: 0px; + color: #6f6f6f; + background-color: #fff; + border: 1px solid #39a9d1; + border-bottom-left-radius: 0px; + border-bottom-right-radius: 0px; + outline: 0px; +} + +/*对QAbstractItemView中的每一个item进行控制*/ +GLDCustomComboBoxEx QAbstractItemView::item +{ + min-height: 25px; + margin-left: 4px; + margin-right: 5px; + padding-left: 0px; + color: #757575; + border-bottom: 0px; + background-color: #fff; +} + +/*当鼠标滑过每一个Item时的效果控制*/ +GLDCustomComboBoxEx QAbstractItemView::item:selected +{ + color: #146fae; + background-color: #dbf4fc; +} + +QScrollBar:vertical +{ + width: 14px; +} + +QScrollBar:horizontal +{ + width: 0px; + height: 0px; +} diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/GLDCustomLineEdit.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDCustomLineEdit.qss new file mode 100644 index 00000000..ad5321d9 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDCustomLineEdit.qss @@ -0,0 +1,13 @@ +GLDCustomLineEdit +{ + border: 1px solid #c0c0c0; + padding: 0px 0px 0px 2px; + background-color: white; + selection-background-color:#a1c3ee; + selection-color:#455059; +} + +GLDCustomLineEdit[border = "noBorder"] +{ + border: 0px; +} diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/GLDDateTimeEditEx.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDDateTimeEditEx.qss new file mode 100644 index 00000000..29646d00 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDDateTimeEditEx.qss @@ -0,0 +1,329 @@ +GLDDateTimeEditEx[GLDHasPopup = "true"] +{ + border: 1px solid #c0c0c0; + padding: 0px 0px 0px 2px; + selection-background-color: #a1c3ee; + selection-color: #455059; +} + +GLDDateTimeEditEx[GLDHasPopup = "true"]:on, +GLDDateTimeEditEx[GLDHasPopup = "true"]:focus +{ + border: 1px solid #39a9d1; +} + +/*GLDDateTimeEditEx下拉框小图标样式*/ +GLDDateTimeEditEx[GLDHasPopup = "true"]::drop-down +{ + subcontrol-origin: margin; + subcontrol-position: center right; + image: url(:/icons/calendar.png); + background-repeat: no-repeat; + background-color: transparent; + margin-right: 4px; + width: 20px; +} + +/*GLDDateTimeEditEx下拉框小图标点开的样式*/ +GLDDateTimeEditEx[GLDHasPopup = "true"]::drop-down:on +{ + image: url(:/icons/calendar.png); + background-repeat: no-repeat; + background-color: transparent; + padding: 8px; + width: 20px; +} + +QWidget[GLDCalendarWidget = "true"] +{ + background-color: #85ccf6; +} + +QWidget[GLDNavBackground = "true"] +{ + color: #ffffff; + background-color: #85ccf6; +} + +QWidget[GLDCalendarBody = "true"] +{ + background-color: white; + border-radius: 5px; + border-radius: 5px; +} + +QWidget[GLDCalendarHead = "true"] +{ + background-color: white; + padding: 0px; +} + +QPushButton[GLDHeadBtn = "true"] +{ + border: 0px solid white; + background-color: white; + color: black; + font: bold; + font-size: 12px; +} + +QPushButton[GLDPrevMonth = "true"] +{ + background-image: url(:/icons/arrowleft.png); + background-repeat: no repeat; + background-position: center; + background-color: #85ccf6; + border: 0px solid #85ccf6; +} + +QPushButton[GLDNextMonth = "true"] +{ + background-image: url(:/icons/arrowright.png); + background-repeat: no repeat; + background-position: center; + background-color: #85ccf6; + border: 0px solid #85ccf6; +} + +QLabel[GLDDisplayText = "true"] +{ + font-size: 12px; + color: black; + background-color: #85ccf6; + border: 0px solid #85ccf6; + width: 6px; +} + +QSpinBox[GLDYearSpinBox = "true"] +{ + font-size: 12px; + color: black; + background-color: #ffffff; + border: 1px solid #39a9d1; +} + +QToolButton[GLDYearToolBtn = "true"] + +{ + font-size: 12px; + color: black; + background-color: #85ccf6; + border: 0px solid #85ccf6; +} + +QComboBox[GLDMonthComboBox = "true"] +{ + font-size: 12px; + color: black; + background-color: #85ccf6; + border: 0px solid #85ccf6; +} + +QComboBox[GLDMonthComboBox = "true"]:on +{ + font-size: 12px; + color: black; + background-color: #ffffff; + border: 1px solid #39a9d1; +} + +QComboBox[GLDMonthComboBox = "true"] QAbstractItemView +{ + color: black; + background-color: #ffffff; + border: 1px solid #39a9d1; + padding-top: 4px; + padding-bottom: 4px; + outline: 0px; +} + +QComboBox[GLDMonthComboBox = "true"] QAbstractItemView::item +{ + height: 18px; + font-size: 12px; +} + +/*当鼠标滑过每一个Item时的效果控制*/ +QComboBox[GLDMonthComboBox = "true"] QAbstractItemView::item:selected +{ + color: #146fae; + background-color: #dbf4fc; + height: 18px; + font-size: 12px; +} + +QComboBox[GLDMonthComboBox = "true"]::drop-down +{ + subcontrol-origin: margin; + subcontrol-position: center right; + image: url(:/icons/arrowwithline.png); + background-repeat: no repeat; + background-color: #85ccf6; + margin-right: 5px; + width: 8px; + height: 5px; +} + +QComboBox[GLDMonthComboBox = "true"]::drop-down:on +{ + subcontrol-origin: margin; + subcontrol-position: center right; + image: url(:/icons/arrowdown.png); + background-repeat: no repeat; + background-color: #ffffff; + margin-top: 1px; + width: 8px; + height: 6px; +} + +QSpinBox[GLDYearSpinBox = "true"]::up-button +{ + border: 0px solid #788cba; + subcontrol-origin: padding; + subcontrol-position: top right; +} + +QSpinBox[GLDYearSpinBox = "true"]::up-arrow +{ + image: url(:/icons/arrowup.png); +} + +QSpinBox[GLDYearSpinBox = "true"]::down-button +{ + border: 0px solid #788cba; + subcontrol-origin: padding; + subcontrol-position: bottom right; +} + +QSpinBox[GLDYearSpinBox = "true"]::down-arrow +{ + image: url(:/icons/arrowdown.png); +} + +QCalendarWidget[GLDCalendar = "true"] +{ + border-radius: 3px; +} + +QCalendarWidget[GLDCalendar = "true"] QAbstractItemView +{ + selection-color: white; + selection-background-color: #85ccf6; + outline: 0px; +} + +/*无弹出框的日历控件样式*/ +GLDDateTimeEditEx[GLDHasPopup = "false"] +{ + color: #414645; + padding: 1px; + border: 1px solid #c0c0c0; + min-height: 13px; + selection-background-color: #a1c3ee; + selection-color: #455059; +} + +GLDDateTimeEditEx[GLDHasPopup = "false"]:on, +GLDDateTimeEditEx[GLDHasPopup = "false"]:focus +{ + border: 1px solid #d4d5d9; +} + +GLDDateTimeEditEx[GLDHasPopup = "false"]::up-button +{ + border: 0px solid #788cba; + background-color: rgba(46, 46, 46, 0); + subcontrol-origin: padding; + subcontrol-position: top right; + min-width: 18px; + min-height: 11px; +} + +GLDDateTimeEditEx[UpDownBtnBorder = "true"]::up-button +{ + border-left: 1px solid #788cba; +} + +GLDDateTimeEditEx[UpDownBtnBorder = "false"]::up-button +{ + border: 0px; +} + +GLDDateTimeEditEx[GLDHasPopup = "false"]::up-button:focus +{ + image: url(:/icons/arrowuphover.png); + border-left: 1px solid #788cba; + min-width: 18px; + min-height: 11px; +} + +GLDDateTimeEditEx[GLDHasPopup = "false"]::down-button +{ + border: 0px solid #788cba; + background-color: rgba(46, 46, 46 ,0); + subcontrol-origin: padding; + subcontrol-position: bottom right; + min-width: 18px; + min-height: 11px; +} + +GLDDateTimeEditEx[UpDownBtnBorder = "true"]::down-button +{ + border-left: 1px solid #788cba; + border-top: 1px solid #788cba; +} + +GLDDateTimeEditEx[UpDownBtnBorder = "false"]::down-button +{ + border: 0px; +} + +GLDDateTimeEditEx[GLDHasPopup = "false"]::down-button:focus +{ + image: url(:/icons/arrowdownhover.png); + border-left: 1px solid #788cba; + border-top: 1px solid #788cba; + min-width: 18px; + min-height: 11px; +} + +GLDDateTimeEditEx[GLDHasPopup = "false"]::up-arrow +{ + image: url(:/icons/arrowup.png); + min-width: 18px; + min-height: 11px; +} + +GLDDateTimeEditEx[GLDHasPopup = "false"]::up-arrow:hover, +GLDDateTimeEditEx[GLDHasPopup = "false"]::up-arrow:pressed +{ + image: url(:/icons/arrowuphover.png); + min-width: 18px; + min-height: 11px; +} + +GLDDateTimeEditEx[GLDHasPopup = "false"]::down-arrow +{ + image: url(:/icons/arrowdown.png); + min-width: 18px; + min-height: 11px; +} + +GLDDateTimeEditEx[GLDHasPopup = "false"]::down-arrow:hover, +GLDDateTimeEditEx[GLDHasPopup = "false"]::down-arrow:pressed +{ + image: url(:/icons/arrowdownhover.png); + min-width: 18px; + min-height: 11px; +} + +GLDDateTimeEditEx[GLDBorderStyle = "noBorder"] +{ + border: 0px; +} + +GLDDateTimeEditEx[GLDBorderStyle = "noBorder"]:on, +GLDDateTimeEditEx[GLDBorderStyle = "noBorder"]:focus +{ + border: 0px; +} diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/GLDFileDialog.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDFileDialog.qss new file mode 100644 index 00000000..4541d6da --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDFileDialog.qss @@ -0,0 +1,153 @@ +/*标题栏窗口按钮*/ +QWidget#m_pTitleBar { + background-color: qlineargradient(spread:reflect, x1:0.0, y1:0.0, x2:1.0, y2:1.0, stop:0.0284091 #2b9dcd, stop:0.420455 #0480b4); +} + +QLabel#m_pTitleLabel { + color: #ffffff; + font: 75 13pt "宋体" +} + +QToolButton#m_pQueryMaximize { + border-image:url(:/icons/GLDCustomTitleBar/Query_Max.png); +} + +QToolButton#m_pQueryMaximize:hover { + border-image:url(:/icons/GLDCustomTitleBar/Query_Max_Hover.png); +} + +QToolButton#m_pQueryMaximize:pressed { + border-image:url(:/icons/GLDCustomTitleBar/Query_Max_Pressed.png); +} + +QToolButton#m_pQueryMinimize { + border-image:url(:/icons/GLDCustomTitleBar/Query_Min.png); +} + +QToolButton#m_pQueryMinimize:hover { + border-image:url(:/icons/GLDCustomTitleBar/Query_Min_Hover.png); +} + +QToolButton#m_pQueryMinimize:pressed { + border-image:url(:/icons/GLDCustomTitleBar/Query_Min_Pressed.png); +} + +QToolButton#m_pQueryRestore { + border-image:url(:/icons/GLDCustomTitleBar/Query_Restore.png); +} + +QToolButton#m_pQueryRestore:hover { + border-image:url(:/icons/GLDCustomTitleBar/Query_Restore_Hover.png); +} + +QToolButton#m_pQueryRestore:pressed { + border-image:url(:/icons/GLDCustomTitleBar/Query_Restore_Pressed.png); +} + +QToolButton#m_pQueryClose { + border-image:url(:/icons/GLDCustomTitleBar/Query_Close.png); +} + +QToolButton#m_pQueryClose:hover { + border-image:url(:/icons/GLDCustomTitleBar/Query_Close_Hover.png); +} + +QToolButton#m_pQueryClose:pressed { + border-image:url(:/icons/GLDCustomTitleBar/Query_Close_Pressed.png); +} + +/*中央部分控件*/ +QAbstractItemView#pFileContent{ + border: 0px; + border-left: 1px solid #39a9d1; + border-top: 1px solid #39a9d1; + border-bottom: 1px solid #39a9d1; +} + +/*窗口底部按钮*/ +QToolButton#pOpenFileButton{ + border-image: url(:/icons/GLDFileDialog/Open.png); + min-width: 80px; + min-height: 28px; +} + +QToolButton#pCancelButton{ + border-image: url(:/icons/GLDFileDialog/Cancel.png); + min-width: 80px; + min-height: 28px; +} + +/*打开窗口边线样式*/ +QDialog#GLDOpenFileDialog{ + border-style: solid; + border-width: 1px; + border-color: qlineargradient(spread:reflect, x1:0.0, y1:0.0, x2:1.0, y2:1.0, stop:0.0284091 #2b9dcd, stop:0.420455 #0480b4); +} + +/*另存为窗口边线样式*/ +QDialog#GLDSaveAsDialog{ + border-style: solid; + border-width: 1px; + border-color: qlineargradient(spread:reflect, x1:0.0, y1:0.0, x2:1.0, y2:1.0, stop:0.0284091 #2b9dcd, stop:0.420455 #0480b4); +} + +/*GLDShellTreeViewEx样式*/ +GLDShellTreeViewEx{ + border: 0px; + border-right: 1px solid #39a9d1; + border-top: 1px solid #39a9d1; + border-bottom: 1px solid #39a9d1; + /* background-color:#fff;*/ + padding-left: 5px; + padding-right:0px; + outline: 0px; + padding-top: 0px; + padding-bottom 12px; +} + +GLDShellTreeViewEx::item{ + border: 1px solid transparent; + padding-left: -2px; + padding-right:20px; + font-size 12px; + height : 22px; +} + +GLDShellTreeViewEx::item:selected{ + margin 0 px; + border: 1px solid #b6d2ea; + padding-left: -2px; + color: #010101; + background-color:#dbf3fc; +} + +GLDShellTreeViewEx::item:hover{ + margin 20 px; + border: 1px solid #b6d2ea; + padding-left: -2px; +} + +GLDShellTreeViewEx::branch{ + image: none; +} + +QLineEdit#m_pFileNameFilter +{ + border: 1px solid #39a9d1; + padding: 0px 0px 0px 2px; + background-color: white; + selection-background-color:#a1c3ee; + selection-color:#455059; + height: 25px; +} + +QTreeView +{ + font: large "Microsoft YaHei UI"; +} + +QListView +{ + font: large "Microsoft YaHei UI"; +} + diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/GLDFontListEx.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDFontListEx.qss new file mode 100644 index 00000000..e7a546a4 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDFontListEx.qss @@ -0,0 +1,67 @@ +[GFontListEx = "hasborder"] +{ + border: 1px solid #d7d7da; + font-size: 12px; + padding: 3px 8px 3px 2px; + color: #435057; + height: 25px; + font-size: 12px; + selection-background-color: #a1c3ee; + selection-color: #455059; +} + +[GFontListEx = "hasborder"]:hover, +[GFontListEx = "hasborder"]:focus, +[GFontListEx = "hasborder"]:on +{ + border: 1px solid #39a9d1; +} + +[GFontListEx = "noborder"], +[GFontListEx = "noborder"]:hover, +[GFontListEx = "noborder"]:focus, +[GFontListEx = "noborder"]:on +{ + border: 0px; + font-size: 12px; + padding: 3px 8px 3px 2px; + color: #435057; + height: 25px; + font-size: 12px; + selection-background-color: #a1c3ee; + selection-color: #455059; +} + +GFontListEx::drop-down, pressed +{ + width: 24px; + border: 1px solid #fff; + image: url(:/icons/GLDCustomComboBoxEx-downarrow.png); +} + +GFontListEx QListView +{ + border: 1px solid #39a9d1; + padding-left: 0px; + padding-right: 0px; + background: #fff; +} + +GFontListEx QListView QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical +{ + background: none; +} + +/***********************滚动条******************************/ +/*当鼠标滑过滚动条时的效果控制*/ +GFontListEx QListView QScrollBar:vertical +{ + width: 14px; +} + +/*对滚动条整体效果进行控制*/ +GFontListEx QListView QScrollBar:horizontal +{ + width: 0px; + height: 0px; +} diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/GLDLineButtonEditEx.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDLineButtonEditEx.qss new file mode 100644 index 00000000..ce49d046 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDLineButtonEditEx.qss @@ -0,0 +1,76 @@ +[EllipsisButtonWrap = "GLDLineButtonEditEx"], +[EllipsisButtonWrap = "GLDLineButtonEditEx"]:hover { + border: 1px solid #39a9d1; +/* min-height: 16px; + min-width: 10px; + max-width: 500px;*/ + background-color: #fff; +} + +[EllipsisButtonWrap = "GLDLineButtonEditEx"] QLineEdit { + padding-left: 2px; + min-height: 16px; + color: #435057; + background-color: white; + border: 1px solid #39a9d1; + margin-right: 2px; + selection-background-color: #a1c3ee; + selection-color: #455059 +} + +[EllipsisButtonWrap = "GLDLineButtonEditEx"] QPushButton { + min-height: 10px; + border: 1px solid #5da7e5; + margin: 3px 3px 4px 0px; + border-radius: 2px; + color: #f2f6fa; + font-size: 12px; + background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(242, 246, 250, 255), stop:1 rgba(233,237,244, 255)); + background-image: url(:/icons/GLDLineButtonEditEx-ellipsis.png); + background-position: center center; + background-repeat: no-repeat; +} + +[EllipsisButtonWrap = "GLDLineButtonEditEx"] QPushButton:hover { + border: 1px solid #de9a53; +} + +/* 无边框时的样式 */ +[EllipsisButtonWrap = "noborder"], +[EllipsisButtonWrap = "noborder"]:hover { + border: 0px; +/* min-height: 16px; + min-width: 10px; + max-width: 500px;*/ + background-color: #fff; +} + +[EllipsisButtonWrap = "noborder"] QLineEdit { + padding-left: 2px; + min-height: 16px; + color: #435057; + background-color: white; + border: 0px; + margin-right: 2px; + selection-background-color: #a1c3ee; + selection-color: #455059 +} + +[EllipsisButtonWrap = "noborder"] QPushButton { + min-height: 10px; + background-color: #fff; + border: 1px solid #5da7e5; + margin: 3px; + margin-left: 0px; + border-radius: 2px; + color: #fff; + text-decoration: none; + background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(242, 246, 250, 255), stop:1 rgba(233,237,244, 255)); + background-image: url(:/icons/GLDLineButtonEditEx-ellipsis.png); + background-position: center center; + background-repeat: no-repeat; +} + +[EllipsisButtonWrap = "noborder"] QPushButton:hover { + border: 1px solid #de9a53; +} diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/GLDLineWidthComboBoxEx.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDLineWidthComboBoxEx.qss new file mode 100644 index 00000000..d8ffcf95 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDLineWidthComboBoxEx.qss @@ -0,0 +1,147 @@ +*[GLDLineWidthButton = "true"]:hover, +*[GLDNoLineButton = "true"]:hover +{ + background: #fbf2c0; + border: 1px solid #f19636; + border-radius:2px; +} + +*[GLDLineWidthButton = "true"], +*[GLDNoLineButton = "true"] +{ + border: 0px; + padding-top: 12px; + margin:3px 0 3px 0; /*设置外边距,防止粘贴在一起*/ +} + +*[GLDPixlLable = "true"], +*[GLDNoLineLabel = "true"] +{ + color: #757575; + padding:8px 7px 0px 8px; +} + +*[GLDNoLineLabel = "true"] +{ + padding-right:11px;/*右对齐多少磅的字*/ + padding-top:7px; +} + +*[GLDPopupListWidgets = "true"] +{ + border: 1px solid #39a9d1; + min-width: 220px; +} + +*[GLDMoreButton = "true"] +{ + border:0px; + text-align:left;/*text-align和padding配合使用,可以自由调整文字的位置*/ + padding-left:38px; + padding-bottom:3px; + font-size: 12px; + color: #44515a; +} + +/*定位到更多按钮上面 和线框不一样,它是item*/ +GLDLineWidthComboBoxEx [GLDMoreWidget = "true"] +{ + background-image: url(:/icons/GLDLineWidthEx-virtualLine.png); + background-repeat:no-repeat; + background-attachment: fixed; + background-position: left; + border-top: 1px solid #cfd9e5;/*设定更多按钮上面的线条*/ + border-bottom: 0; + border-left: 0; + border-right: 0; +} + +GLDLineWidthComboBoxEx [GLDLineWidgets = "true"]:item +{ + height:25px; +} + +/*整体默认样式*/ +GLDLineWidthComboBoxEx +{ + font-size: 12px; + color: #44515a; + height: 25px; + width: 210px; + padding-left:35px; + border: 1px solid #c0c0c0; + background-image: url(:/icons/GLDLineWidthEx-line.png); + background-repeat: no-repeat; + background-position: left; + subcontrol-position: padding; + left: 10px; + selection-background-color: #a1c3ee; + selection-color: #455059; +} + +GLDLineWidthComboBoxEx:on +{ + border: 1px solid #39a9d1; /*默认边框*/ +} + +GLDLineWidthComboBoxEx[GLDBorderStyle = "noBorder"] +{ + border: 0; +} + +/*默认的箭头样式*/ +GLDLineWidthComboBoxEx::drop-down +{ + subcontrol-origin: margin; + subcontrol-position: center right; + image: url(:/icons/GLDCustomComboBoxEx-downarrow.png); + padding-top:0px; + width: 24px; + height: 29px; +} + +GLDLineWidthComboBoxEx:on +{ + background-image: url(:/icons/GLDLineWidthEx-line.png); + background-repeat:no-repeat; + background-position:left; +} + +GLDLineWidthComboBoxEx:on +{ + border:1px solid #39a9d1; +} + +GLDLineWidthComboBoxEx[GLDBorderStyle = "noBorder"]:on +{ + border:0; +} + +GLDLineWidthComboBoxEx QAbstractItemView +{ + color:#757575;/*整个下拉框的字体颜色*/ + selection-background-color: #fbf2c0; + border: 0px solid #06abfd; + border-top: 0px; + outline: 0px; +} + +/*高度设置,more按钮的效果,下拉的每一项*/ +GLDLineWidthComboBoxEx QAbstractItemView::item +{ + height: 25px; + color: #757575; + border-top: 1px solid #fff; /*边框不显示*/ +} + +/***********************滚动条******************************/ +QScrollBar:vertical +{ + width: 14px; +} + +QScrollBar:horizontal +{ + width: 0px; + height:0px; +} diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/GLDPlainButtonEditEx.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDPlainButtonEditEx.qss new file mode 100644 index 00000000..5798ebbd --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDPlainButtonEditEx.qss @@ -0,0 +1,74 @@ +[EllipsisButtonWrap = "GLDPlainButtonEditEx"], +[EllipsisButtonWrap = "GLDPlainButtonEditEx"]:hover{ + border: 1px solid #39a9d1; + min-height: 16px; + min-width: 10px; +/* max-width: 500px;*/ + background-color: #fff; +} + +[EllipsisButtonWrap = "GLDPlainButtonEditEx"] QPlainTextEdit { + padding-left: 5px; + min-height: 16px; + color: #435057; + background-color: white; + border: 1px solid #39a9d1; + margin-right: 2px; + selection-background-color: #a1c3ee; + selection-color: #455059 +} + +[EllipsisButtonWrap = "GLDPlainButtonEditEx"] QPushButton { + min-height: 10px; + border: 1px solid #5da7e5; + margin: 3px 3px 4px 0px; + border-radius: 2px; + color: #f2f6fa; + font-size: 12px; + background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(242, 246, 250, 255), stop:1 rgba(233,237,244, 255)); + background-image: url(:/icons/GLDLineButtonEditEx-ellipsis.png); + background-position: center center; + background-repeat: no-repeat; +} + +[EllipsisButtonWrap = "GLDPlainButtonEditEx"] QPushButton:hover { + border: 1px solid #de9a53; +} + +/* 无边框的样式 */ +[EllipsisButtonWrap = "noborder"] { + border: 0px; + min-height: 16px; + min-width: 10px; +/* max-width: 500px;*/ + background-color: #fff; +} + +[EllipsisButtonWrap = "noborder"] QPlainTextEdit { + padding-left: 5px; + min-height: 16px; + color: #435057; + background-color: white; + border: 0px; + margin-right: 2px; + selection-background-color: #a1c3ee; + selection-color: #455059 +} + +[EllipsisButtonWrap = "noborder"] QPushButton { + min-height: 10px; + border: 1px solid #5da7e5; + margin: 3px 3px 4px 0px; + border-radius: 2px; + color: #f2f6fa; + font-size: 12px; + background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(242, 246, 250, 255), stop:1 rgba(233,237,244, 255)); + background-image: url(:/icons/GLDLineButtonEditEx-ellipsis.png); + background-position: center center; + background-repeat: no-repeat; +} + +[EllipsisButtonWrap = "noborder"] QPushButton:hover { + border: 1px solid #de9a53; +} + diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/GLDPlainTextEditEx.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDPlainTextEditEx.qss new file mode 100644 index 00000000..e22f70db --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDPlainTextEditEx.qss @@ -0,0 +1,7 @@ +GLDPlainTextEditEx +{ + padding-left: 5px; + background-color: white; + selection-background-color:#a1c3ee; + selection-color:#455059; +} diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/GLDQsses.qrc b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDQsses.qrc new file mode 100644 index 00000000..324e0d00 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDQsses.qrc @@ -0,0 +1,36 @@ + + + splitter.qss + outLookBar.qss + GLDCustomComboBoxEx.qss + GLDWindowComboBoxEx.qss + GLDLineButtonEditEx.qss + GLDPlainButtonEditEx.qss + GLDTableView.qss + GLDFontListEx.qss + GColorListEx.qss + GLDSpinBoxEx.qss + GLDShellComboBoxEx.qss + GLDLineWidthComboBoxEx.qss + GLDDateTimeEditEx.qss + GLDCustomLineEdit.qss + GLDPlainTextEditEx.qss + GLDShellTreeViewEx.qss + GlodonTreeViewEx.qss + GLDFileDialog.qss + GLDSearchEdit.qss + GLDToolBox.qss + BIMBlackStyle.qss + BIMBlueStyle.qss + BIMKeyboardBlackStyle.qss + BIMKeyboardBlueStyle.qss + GBJBlueStyle.qss + GBJKeyboardBlueStyle.qss + GBQKeyboardOrangeStyle.qss + GBQOrangeStyle.qss + GBTKeyboardPurpleStyle.qss + GBTPurpleStyle.qss + GCLGreenStyle.qss + GCLKeyboardGreenStyle.qss + + diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/GLDSearchEdit.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDSearchEdit.qss new file mode 100644 index 00000000..3f800542 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDSearchEdit.qss @@ -0,0 +1,50 @@ +QLineEdit#GLDSearchEdit[hasFocus="false"]{border: 1px solid #d7d6db; } +QLineEdit#GLDSearchEdit[hasFocus="true"]{border: 1px solid #569de5; } + +QPushButton[searching="false"][hasFocus="false"]{ + border-image:url(:/icons/GLDSearchEdit_Search.png); + min-width:34px; + min-height:25px; +} + +QPushButton[searching="false"][hasFocus="true"]{ + border-image:url(:/icons/GLDSearchEdit_Search_Focus.png); + min-width:34px; + min-height:25px; +} + +QPushButton[searching="true"][hasFocus="false"]:hover{ + border-image:url(:/icons/GLDSearchEdit_Clear_Hove.png); + min-width:34px; + min-height:25px; +} + +QPushButton[searching="true"][hasFocus="false"]:pressed{ + border-image:url(:/icons/GLDSearchEdit_Clear_Press.png); + min-width:34px; + min-height:25px; +} + +QPushButton[searching="true"][hasFocus="false"]{ + border-image:url(:/icons/GLDSearchEdit_Clear_Norm.png); + min-width:34px; + min-height:25px; +} + +QPushButton[searching="true"][hasFocus="true"]:hover{ + border-image:url(:/icons/GLDSearchEdit_Clear_Hove_Focus.png); + min-width:34px; + min-height:25px; +} + +QPushButton[searching="true"][hasFocus="true"]:pressed{ + border-image:url(:/icons/GLDSearchEdit_Clear_Press_Focus.png); + min-width:34px; + min-height:25px; +} + +QPushButton[searching="true"][hasFocus="true"]{ + border-image:url(:/icons/GLDSearchEdit_Clear_Norm_Focus.png); + min-width:34px; + min-height:25px; +} diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/GLDShellComboBoxEx.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDShellComboBoxEx.qss new file mode 100644 index 00000000..1d8913c3 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDShellComboBoxEx.qss @@ -0,0 +1,105 @@ +/*编辑框*/ +GLDPlainTextEdit{ + padding-top: 4px; + padding-left: 5px; + padding-right: 20px; + background-color: white; + left: 10px; + color: #6f6f6f; + selection-background-color: #a1c3ee; + selection-color: #455059 +} + +/*不弹出下拉时,下拉三角*/ +GLDPlainTextEdit[GLDPlainTextEditState = "hide"]{ + background-image: url(:/icons/GLDWindowComboBoxEx-downarrow.png); + background-repeat: no-repeat; + background-position: right; + subcontrol-position: padding; +} + +/*弹出下拉时,下拉三角*/ +GLDPlainTextEdit[GLDPlainTextEditState = "show"]{ + border: 1px solid #39a9d1; + background-image: url(:/icons/GLDWindowComboBoxEx-downarrow.png); + background-repeat: no-repeat; + background-position: right; + subcontrol-position: padding; +} + +/*边框*/ +GLDPlainTextEdit{ + border: 1px solid #d7d7da; +} + +GLDPlainTextEdit:focus{ + border: 1px solid #39a9d1; +} + +GLDPlainTextEdit:hover{ + border: 1px solid #39a9d1; +} + +GLDPlainTextEdit[borderStyle = "noBorder"] { + border: 0px; +} + +/*下拉中的TreeView属性设置*/ +GLDShellTreeView{ + border: 1px solid #39a9d1; + border-top: 1px solid #39a9d1; + background-color:#fff; + padding-left: 4px; + padding-right:0px; + outline: 0px; + margin-right:8px; + margin-bottom:8px; + margin-left:8px; +} + +GLDShellTreeView::item{ + border-bottom: 0px; + background-color:#fff; + margin-right:8px; + min-height: 25px; + font-family:"宋体"; + font-size:12px; +} + +GLDShellTreeView::item:selected{ + color: #146fae; + background-color:#daf4fc; +} + +GLDShellTreeView::item:hover{ + border: 0px; + border-left:0px; + color: #156fae; + background-color:#daf4fc; +} + +GLDShellTreeView::branch{ + image: none; +} + +/*弹出框美化*/ +GLDComboBoxPopup{ + max-height:320px; + min-height:120px; +} + +GLDComboBoxPopup QSizeGrip{ + image:none; +} + +/*滚动条设置*/ +QScrollBar:vertical +{ + width: 14px; +} + +QScrollBar:horizontal +{ + width: 0px; + height: 0px; +} diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/GLDShellTreeViewEx.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDShellTreeViewEx.qss new file mode 100644 index 00000000..35796c45 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDShellTreeViewEx.qss @@ -0,0 +1,52 @@ +/*下拉中的TreeView属性设置*/ +GLDShellTreeViewEx{ + border: 1px solid #39a9d1; + border-top: 1px solid #39a9d1; + /* background-color:#fff;*/ + padding-left: 5px; + padding-right:0px; + outline: 0px; + padding-top: 0px; + padding-bottom 12px; +} + +GLDShellTreeViewEx::item{ + border: 1px solid transparent; + padding-left: -2px; + padding-right:20px; + font-size 12px; + height : 22px; +} + +GLDShellTreeViewEx::item:selected{ + margin 0 px; + border: 1px solid #b6d2ea; + padding-left: -2px; + color: #010101; + background-color:#dbf3fc; +} + +GLDShellTreeViewEx::item:hover{ + margin 20 px; + border: 1px solid #b6d2ea; + padding-left: -2px; +} + +GLDShellTreeViewEx::branch{ + image: none; +} + + + +/*滚动条设置*/ +QScrollBar:vertical +{ + width: 14px; +} + +QScrollBar:horizontal +{ + width: 0px; + height: 0px; +} + diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/GLDSpinBoxEx.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDSpinBoxEx.qss new file mode 100644 index 00000000..39ac6be7 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDSpinBoxEx.qss @@ -0,0 +1,218 @@ +/* QSpinBox基本样式 */ +QSpinBox +{ + padding: 0px 5px 0px 2px; + font: 12px solid; + color: #6f6f6f; + selection-background-color:#a1c3ee; + selection-color:#455059; +} + +/* 有边框时样式 */ +QSpinBox[border="true"] +{ + border: 1px solid #d7d7da; +} + +QSpinBox[border="true"]:hover, +QSpinBox[border="true"]:focus +{ + border: 1px solid #39a9d1; +} + +/* 无边框时样式 */ +QSpinBox[border="false"] +{ + border: 0px; +} + +/* 向上按钮样式 */ +QSpinBox::up-button +{ + border: 0px solid #788cba; + background-color: rgba(46, 46, 46, 0); + subcontrol-origin: padding; + subcontrol-position: top right; + min-width: 16px; + min-height: 7px; +} + +QSpinBox[UpDownBtnBorder = "true"]::up-button +{ + border-left: 1px solid #788cba; +} + +QSpinBox[UpDownBtnBorder = "false"]::up-button +{ + border: 0px; +} + +/* 由于Qss中后面的样式会覆盖前面样式 */ +/* 因此Focus应该放在最后,否则会失去Focus的样式,后面同 */ +QSpinBox::up-button:focus +{ + border-left: 1px solid #788cba; +} + +/* 向下按钮样式 */ +QSpinBox::down-button +{ + border: 0px solid #788cba; + subcontrol-origin: padding; + subcontrol-position: bottom right; + min-width: 16px; + min-height: 8px; +} + +QSpinBox[UpDownBtnBorder = "true"]::down-button +{ + border-left: 1px solid #788cba; + border-top: 1px solid #788cba; +} + +QSpinBox[UpDownBtnBorder = "false"]::down-button +{ + border: 0px; +} + +QSpinBox::down-button:focus +{ + border-left: 1px solid #788cba; + border-top: 1px solid #788cba; +} + +/* 向上三角样式 */ +QSpinBox::up-arrow +{ + image: url(:/icons/arrowup.png); + min-width: 8px; + min-height: 5px; +} + +QSpinBox::up-arrow:hover, +QSpinBox::up-arrow:pressed +{ + image: url(:/icons/arrowuphover.png); +} + +/* 向下三角样式 */ +QSpinBox::down-arrow +{ + image: url(:/icons/arrowdown.png); + min-width: 8px; + min-height: 5px; +} + +QSpinBox::down-arrow:hover, +QSpinBox::down-arrow:pressed +{ + image: url(:/icons/arrowdownhover.png); +} + +/* QDoubleSpinBox基本样式 */ +QDoubleSpinBox +{ + padding: 0px 6px 0px 2px; + font: 12px solid; + color: #6f6f6f; + selection-background-color:#a1c3ee; + selection-color:#455059; +} + +/* 有边框时的样式 */ +QDoubleSpinBox[border = "true"] +{ + border: 1px solid #d7d7da; +} + +QDoubleSpinBox[border = "true"]:hover, +QDoubleSpinBox[border = "true"]:focus +{ + border: 1px solid #39a9d1; +} + +/* 无边框时的样式 */ +QDoubleSpinBox[border = "false"] +{ + border: 0px; +} + +/* 向上按钮样式 */ +QDoubleSpinBox::up-button +{ + border: 0px solid #788cba; + background-color: rgba(46, 46, 46, 0); + subcontrol-origin: padding; + subcontrol-position: top right; + min-width: 16px; + min-height: 7px; +} + +QDoubleSpinBox[UpDownBtnBorder = "true"]::up-button +{ + border-left: 1px solid #788cba; +} + +QDoubleSpinBox[UpDownBtnBorder = "false"]::up-button +{ + border: 0px; +} + +QDoubleSpinBox::up-button:focus +{ + border-left: 1px solid #788cba; +} + +/* 向下按钮样式 */ +QDoubleSpinBox::down-button +{ + border: 0px solid #788cba; + subcontrol-origin: padding; + subcontrol-position: bottom right; + min-width: 16px; + min-height: 8px; +} + +QDoubleSpinBox[UpDownBtnBorder = "true"]::down-button +{ + border-left: 1px solid #788cba; + border-top: 1px solid #788cba; +} + +QDoubleSpinBox[UpDownBtnBorder = "false"]::down-button +{ + border: 0px; +} + +QDoubleSpinBox::down-button:focus +{ + border-top: 1px solid #788cba; + border-left: 1px solid #788cba; +} + +/* 向上三角样式 */ +QDoubleSpinBox::up-arrow +{ + image: url(:/icons/arrowup.png); + min-width: 8px; + min-height: 5px; +} + +QDoubleSpinBox::up-arrow:hover, +QDoubleSpinBox::up-arrow:pressed +{ + image: url(:/icons/arrowuphover.png); +} + +QDoubleSpinBox::down-arrow +{ + image: url(:/icons/arrowdown.png); + min-width: 8px; + min-height: 5px; +} + +QDoubleSpinBox::down-arrow:hover, +QDoubleSpinBox::down-arrow:pressed +{ + image: url(:/icons/arrowdownhover.png); +} diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/GLDTableView.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDTableView.qss new file mode 100644 index 00000000..9ec8f0b1 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDTableView.qss @@ -0,0 +1,45 @@ +/***********************垂直滚动条******************************/ +QScrollBar:vertical +{ + width: 14px; +} + +/***********************水平滚动条******************************/ +QScrollBar:horizontal +{ + height: 14px; +} + +/*选中格子,垂直表头右边框绿色*/ +GlodonTableView GlodonHeaderView::section:vertical:checked +{ + background-color:#ffefb5; + border-top:0; + border-left:0; + border-bottom:0; + border-right: 2px solid #39a9d3; +} + +/*选中格子,水平表头右边框绿色*/ +GlodonTableView GlodonHeaderView::section:horizontal:checked +{ + background-color:#ffefb5; + border-top:0; + border-left:0; + border-right:0; + border-bottom: 2px solid #39a9d3; +} + +/* +画水平表头格线 +GlodonTableView GlodonHeaderView::section:horizontal +{ + border: 1px solid #d8d8d8; +} + +画垂直表头格线 +GlodonTableView GlodonHeaderView::section:vertical +{ + border: 1px solid #d8d8d8; +} +*/ \ No newline at end of file diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/GLDToolBox.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDToolBox.qss new file mode 100644 index 00000000..908b4040 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDToolBox.qss @@ -0,0 +1,141 @@ +GLDToolBox +{ + padding:0px, 0px, 0px, 0px; +} + +GLDToolBoxButton +{ + background-color: #f6fbfc; + color: #6d6d6d; +} + +GLDToolBoxButton[GLDCurrentBtn = "NoSelected"] +{ + background-color: #f6fbfc; + color: #6d6d6d; +} + +GLDToolBoxButton[GLDCurrentBtn = "Selected"] +{ + background-color: #439cf3; + color: #f6fbfc; +} + +QListView +{ + outline:0px; + border: 1px solid #c6d1de; + margin-bottom: 0px; + background-color: #f6fbfc; +} + +QListView::item +{ + background-color:#f6fbfc; + min-height:28px; + font-size:12px; + color:#595959; + padding-left:28px; +} + +QListView::item:hover +{ + background-color:#e7e7e7; + min-height:28px; + font-size:12px; + color:#595959; + padding-left:28px; +} + +QListView::item:selected +{ + background-color:#b6e6f0; + color:#595959; + min-height:28px; + font-size:12px; + outline:0px; + padding-left:28px; +} + +QListView::item:selected:active +{ + background-color:#b6e6f0; + color:#595959; + min-height:28px; + font-size:12px; + outline:0px; + padding-left:28px; +} + +QListView::item:selected:!active +{ + background-color:#b6e6f0; + min-height:28px; + font-size:12px; + outline:0px; + padding-left:28px; +} + +QTreeView +{ + outline:0px; + border: 1px solid #c6d1de; + margin-bottom: 0px; +} + +QTreeView::item +{ + background-color:#f6fbfc; + min-height:28px; + font-size:12px; + color:#595959; + padding-left:5px; +} + +QTreeView::item:has-children +{ + min-height:28px; + font-size: 18px; + color:#022846; + padding-left:5px; +} + +QTreeView::item:hover +{ + background-color:#e7e7e7; + min-height:28px; + font-size:12px; + color:#595959; + padding-left:5px; +} + +QTreeView::item:selected +{ + background-color:#b6e6f0; + min-height:28px; + font-size:12px; + outline:0px; + padding-left:5px; + outline:0px; +} + +QTreeView::item:selected:active +{ + background-color:#b6e6f0; + min-height:28px; + font-size:12px; + outline:0px; + padding-left:5px; + outline:0px; +} + +QTreeView::item:selected:!active +{ + background-color:#b6e6f0; + min-height:28px; + font-size:12px; + outline:0px; + padding-left:5px; + outline:0px; +} + diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/GLDWindowComboBoxEx.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDWindowComboBoxEx.qss new file mode 100644 index 00000000..5a71480f --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/GLDWindowComboBoxEx.qss @@ -0,0 +1,70 @@ +/*编辑框*/ +GLDPlainTextEdit{ + padding-top: 4px; + padding-left: 8px; + padding-right: 20px; + background-color: white; + left: 10px; + color: #6f6f6f; + selection-background-color: #a1c3ee; + selection-color: #455059 +} + +/*不弹出下拉时,下拉三角*/ +GLDPlainTextEdit[GLDPlainTextEditState = "ComboBoxArrow-hide"]{ + background-image: url(:/icons/GLDWindowComboBoxEx-downarrow.png); + background-repeat: no-repeat; + background-position: right; + subcontrol-position: padding; +} + +/*弹出下拉时,下拉三角*/ +GLDPlainTextEdit[GLDPlainTextEditState = "ComboBoxArrow-show"]{ + background-image: url(:/icons/GLDWindowComboBoxEx-downarrow.png); + background-repeat: no-repeat; + background-position: right; + subcontrol-position: padding; +} + +/*不弹出下拉时,三点按钮*/ +GLDPlainTextEdit[GLDPlainTextEditState = "Ellipsis-hide"]{ + background-image: url(:/icons/GLDWindowComboBoxEx-ellipsis.png); + background-repeat: no-repeat; + background-position: right; + subcontrol-position: padding; +} + +/*弹出下拉时,三点按钮*/ +GLDPlainTextEdit[GLDPlainTextEditState = "Ellipsis-show"]{ + background-image: url(:/icons/GLDWindowComboBoxEx-ellipsis-press.png); + background-repeat: no-repeat; + background-position: right; + subcontrol-position: padding; +} + +/*边框*/ +GLDPlainTextEdit{ + border: 1px solid #39a9d1; +} + +GLDPlainTextEdit[borderStyle = "noBorder"] { + border: 0px; +} + +/*下拉框*/ +GLDComboBoxPopupEx { + border: 1px solid #39a9d1; +} + +/*右下角的小图标*/ +GLDComboBoxPopupEx QSizeGrip { + image: url(:/icons/GLDComboBoxPopupEx-sizegrip.png); + padding-right: 8px; + padding-bottom: 8px; +} + +GLDComboBoxPopupEx QSizeGrip:hover { + image: url(:/icons/GLDComboBoxPopupEx-sizegriphover.png); + padding-right: 8px; + padding-bottom: 8px; +} diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/GlodonTreeViewEx.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/GlodonTreeViewEx.qss new file mode 100644 index 00000000..69e67279 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/GlodonTreeViewEx.qss @@ -0,0 +1,47 @@ +GlodonTreeViewEx::branch{ + image:none; +} + +GlodonTreeViewEx{ + border: 1px solid #39a9d1; + margin-bottom 0px; + padding: 0px; + outline: 50px; +} + +GlodonTreeViewEx::item{ + margin 20 px; + border: 1px solid transparent; + padding-left: -2px; + padding-right:20px; + color: #4c4c4c; + height : 21px; +} + +GlodonTreeViewEx::item:hover{ + margin 20 px; + border: 1px solid #b6d2ea; + padding-left: -2px; +} + +/*鼠标选中设置*/ +GlodonTreeViewEx::item:selected{ + margin 0 px; + border: 1px solid #b6d2ea; + padding-left: -2px; + color: #156ead; + background-color:#dbf3fc; +} + +/*滚动条设置*/ +QScrollBar:vertical +{ + width: 14px; +} + +QScrollBar:horizontal +{ + width: 0px; + height: 0px; +} + diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/outLookBar.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/outLookBar.qss new file mode 100644 index 00000000..f91703c6 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/outLookBar.qss @@ -0,0 +1,29 @@ +QPushButton { + text-align: left; + max-height: 84px; + border-image:url(:icons/GLDNavigationItem_default.png); +} + +QPushButton:hover, pressed { + border-image:url(:icons/GLDNavigationItem_hover); +} + +QPushButton:checked { + border-image:url(:icons/GLDNavigationItem_checdked.png); +} + +QToolBar { + border-image:url(:icons/GLDNavigationItem_default.png); +} + +QWidget[objectName="titleWidget"] { + background-color: rgb(85, 170, 255); +} + +QWidget[objectName="container"] { + background-color: rgb(255, 255, 255); +} + +QSplitterHandle{ + background-color:rgb(170, 170, 127); +} diff --git a/GCR/trunk/Glodon/src/GLD/Res/qss/splitter.qss b/GCR/trunk/Glodon/src/GLD/Res/qss/splitter.qss new file mode 100644 index 00000000..b1d4d8a0 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/qss/splitter.qss @@ -0,0 +1,55 @@ +QPushButton[objectName="left"] { + max-width:6px; + max-height:84px; + border-image:url(://icons/GBQ-splitter-left.png) +} + +QPushButton[objectName="left"]::hover { + border-image:url(://icons/GBQ-splitter-hover-left.png) +} + +QPushButton[objectName="left"]::pressed { + border-image:url(://icons/GBQ-splitter-pressedH.png) +} + +QPushButton[objectName="right"] { + max-width:6px; + max-height:84px; + border-image:url(://icons/GBQ-splitter-right.png) +} + +QPushButton[objectName="right"]::hover { + border-image:url(://icons/GBQ-splitter-hover-right.png) +} + +QPushButton[objectName="right"]::pressed { + border-image:url(://icons/GBQ-splitter-pressedH.png) +} + +QPushButton[objectName="top"] { + max-width:84px; + max-height:6px; + border-image:url(://icons/GBQ-splitter-top.png) +} + +QPushButton[objectName="top"]::hover { + border-image:url(://icons/GBQ-splitter-hover-top.png) +} + +QPushButton[objectName="top"]::pressed { + border-image:url(://icons/GBQ-splitter-pressedV.png) +} + +QPushButton[objectName="bottom"] { + max-width:84px; + max-height:6px; + border-image:url(://icons/GBQ-splitter-bottom.png) +} + +QPushButton[objectName="bottom"]::hover { + border-image:url(://icons/GBQ-splitter-hover-bottom.png) +} + +QPushButton[objectName="bottom"]::pressed { + border-image:url(://icons/GBQ-splitter-pressedV.png) +} diff --git a/GCR/trunk/Glodon/src/GLD/Res/rc/GLDCommon.rc b/GCR/trunk/Glodon/src/GLD/Res/rc/GLDCommon.rc new file mode 100644 index 00000000..41ff76b6 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/rc/GLDCommon.rc @@ -0,0 +1,48 @@ +# if defined(UNDER_CE) +# include +# else +# include +# endif + +#include "../../Base/version.h" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION GLDFILE_VERSION + PRODUCTVERSION 5.0.0.8000 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0x0L + BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "FileDescription", "GLD基础公共单元\0" + VALUE "CompanyName", GLDCOMPANY_NAME + VALUE "FileVersion", GLDFILE_VERSION + VALUE "InternalName", "GLDCommon\0" + #ifdef _DEBUG + VALUE "OriginalFilename", "GLDCommond.dll\0" + VALUE "ProductName", "GLDCommond\0" + #else + VALUE "OriginalFilename", "GLDCommon.dll\0" + VALUE "ProductName", "GLDCommon\0" + #endif + VALUE "ProductVersion", "5.0.0.8000\0" + VALUE "Comments","GLD base common\0" + VALUE "LegalCopyright", GLDVERSION_COPYRIGHT + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1200 + END + END +/* End of Version info */ + diff --git a/GCR/trunk/Glodon/src/GLD/Res/rc/GLDCrypt.rc b/GCR/trunk/Glodon/src/GLD/Res/rc/GLDCrypt.rc new file mode 100644 index 00000000..d1fea715 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/rc/GLDCrypt.rc @@ -0,0 +1,48 @@ +# if defined(UNDER_CE) +# include +# else +# include +# endif + +#include "../../Base/version.h" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION GLDFILE_VERSION + PRODUCTVERSION 5.0.0.8000 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0x0L + BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "FileDescription", "GLD加密单元\0" + VALUE "CompanyName", GLDCOMPANY_NAME + VALUE "FileVersion", GLDFILE_VERSION + VALUE "InternalName", "GLDCrypt\0" + #ifdef _DEBUG + VALUE "OriginalFilename", "GLDCryptd.dll\0" + VALUE "ProductName", "GLDCryptd\0" + #else + VALUE "OriginalFilename", "GLDCrypt.dll\0" + VALUE "ProductName", "GLDCrypt\0" + #endif + VALUE "ProductVersion", "5.0.0.8000\0" + VALUE "Comments","GLD base crypt\0" + VALUE "LegalCopyright", GLDVERSION_COPYRIGHT + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1200 + END + END +/* End of Version info */ + diff --git a/GCR/trunk/Glodon/src/GLD/Res/rc/GLDTableView.rc b/GCR/trunk/Glodon/src/GLD/Res/rc/GLDTableView.rc new file mode 100644 index 00000000..2ccea5cd --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/rc/GLDTableView.rc @@ -0,0 +1,48 @@ +# if defined(UNDER_CE) +# include +# else +# include +# endif + +#include "../../Base/version.h" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION GLDFILE_VERSION + PRODUCTVERSION 5.0.0.8000 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0x0L + BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "FileDescription", "GLD表格控件单元\0" + VALUE "CompanyName", GLDCOMPANY_NAME + VALUE "FileVersion", GLDFILE_VERSION + VALUE "InternalName", "GLDTableView\0" + #ifdef _DEBUG + VALUE "OriginalFilename", "GLDTableViewd.dll\0" + VALUE "ProductName", "GLDTableViewd\0" + #else + VALUE "OriginalFilename", "GLDTableView.dll\0" + VALUE "ProductName", "GLDTableView\0" + #endif + VALUE "ProductVersion", "5.0.0.8000\0" + VALUE "Comments","GLD tableview common\0" + VALUE "LegalCopyright", GLDVERSION_COPYRIGHT + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1200 + END + END +/* End of Version info */ + diff --git a/GCR/trunk/Glodon/src/GLD/Res/rc/GLDWidget.rc b/GCR/trunk/Glodon/src/GLD/Res/rc/GLDWidget.rc new file mode 100644 index 00000000..2e3221b0 --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/rc/GLDWidget.rc @@ -0,0 +1,48 @@ +# if defined(UNDER_CE) +# include +# else +# include +# endif + +#include "../../Base/version.h" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION GLDFILE_VERSION + PRODUCTVERSION 5.0.0.8000 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0x0L + BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "FileDescription", "GLD控件公共单元\0" + VALUE "CompanyName", GLDCOMPANY_NAME + VALUE "FileVersion", GLDFILE_VERSION + VALUE "InternalName", "GLDWidget\0" + #ifdef _DEBUG + VALUE "OriginalFilename", "GLDWidgetd.dll\0" + VALUE "ProductName", "GLDWidgetd\0" + #else + VALUE "OriginalFilename", "GLDWidgetd.dll\0" + VALUE "ProductName", "GLDWidget\0" + #endif + VALUE "ProductVersion", "5.0.0.8000\0" + VALUE "Comments","GLD common\0" + VALUE "LegalCopyright", GLDVERSION_COPYRIGHT + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1200 + END + END +/* End of Version info */ + diff --git a/GCR/trunk/Glodon/src/GLD/Res/rc/GLDXML.rc b/GCR/trunk/Glodon/src/GLD/Res/rc/GLDXML.rc new file mode 100644 index 00000000..44140eed --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/rc/GLDXML.rc @@ -0,0 +1,48 @@ +# if defined(UNDER_CE) +# include +# else +# include +# endif + +#include "../../Base/version.h" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION GLDFILE_VERSION + PRODUCTVERSION 5.0.0.8000 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0x0L + BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "FileDescription", "GLD XML公共单元\0" + VALUE "CompanyName", GLDCOMPANY_NAME + VALUE "FileVersion", GLDFILE_VERSION + VALUE "InternalName", "GLDXML\0" + #ifdef _DEBUG + VALUE "OriginalFilename", "GLDXMLd.dll\0" + VALUE "ProductName", "GLDXMLd\0" + #else + VALUE "OriginalFilename", "GLDXML.dll\0" + VALUE "ProductName", "GLDXML\0" + #endif + VALUE "ProductVersion", "5.0.0.8000\0" + VALUE "Comments","GLD XML common\0" + VALUE "LegalCopyright", GLDVERSION_COPYRIGHT + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1200 + END + END +/* End of Version info */ + diff --git a/GCR/trunk/Glodon/src/GLD/Res/rc/GLDZip.rc b/GCR/trunk/Glodon/src/GLD/Res/rc/GLDZip.rc new file mode 100644 index 00000000..df2ab52c --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/rc/GLDZip.rc @@ -0,0 +1,48 @@ +# if defined(UNDER_CE) +# include +# else +# include +# endif + +#include "../../Base/version.h" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION GLDFILE_VERSION + PRODUCTVERSION 5.0.0.8000 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0x0L + BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "FileDescription", "GLD压缩公共单元\0" + VALUE "CompanyName", GLDCOMPANY_NAME + VALUE "FileVersion", GLDFILE_VERSION + VALUE "InternalName", "GLDZip\0" + #ifdef _DEBUG + VALUE "OriginalFilename", "GLDZipd.dll\0" + VALUE "ProductName", "GLDZipd\0" + #else + VALUE "OriginalFilename", "GLDZip.dll\0" + VALUE "ProductName", "GLDZip\0" + #endif + VALUE "ProductVersion", "5.0.0.8000\0" + VALUE "Comments","GLD common\0" + VALUE "LegalCopyright", GLDVERSION_COPYRIGHT + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1200 + END + END +/* End of Version info */ + diff --git a/GCR/trunk/Glodon/src/GLD/Res/ui/gldhheadviewbackground.png b/GCR/trunk/Glodon/src/GLD/Res/ui/gldhheadviewbackground.png new file mode 100644 index 00000000..9532e065 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ui/gldhheadviewbackground.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ui/gldhheadviewsection.png b/GCR/trunk/Glodon/src/GLD/Res/ui/gldhheadviewsection.png new file mode 100644 index 00000000..b78773df Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ui/gldhheadviewsection.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ui/gldhheadviewsectionchecked.png b/GCR/trunk/Glodon/src/GLD/Res/ui/gldhheadviewsectionchecked.png new file mode 100644 index 00000000..4d796dd2 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ui/gldhheadviewsectionchecked.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ui/gldtableviewdefault.qss b/GCR/trunk/Glodon/src/GLD/Res/ui/gldtableviewdefault.qss new file mode 100644 index 00000000..c2efeb2d --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/ui/gldtableviewdefault.qss @@ -0,0 +1,85 @@ +/* Customize arrows. */ +/* +*::down-arrow, *::menu-indicator { + image: url(:/ui/down_arrow.png); + width: 7px; + height: 7px; +} + +*::down-arrow:disabled, *::down-arrow:off { + image: url(:/ui/down_arrow_disabled.png); +} + +*::up-arrow { + image: url(:/ui/up_arrow.png); + width: 7px; + height: 7px; +} + +*::up-arrow:disabled, *::up-arrow:off { + image: url(:/ui/up_arrow_disabled.png); +} +*/ + +GTableCornerbutton::section +{ + border-image: url(:/ui/gldhheadviewsection.png) 1; + border: 1px; + color: #666666; +} + +GlodonHHeaderView +{ + /*border-image: url(:/ui/gldhheadviewbackground.png) 3;*/ + /*margin-bottom:3;*/ + border: none; + +} +GlodonHHeaderView::section +{ + border-image: url(:/ui/gldhheadviewsection.png) 3; + border: 3px; + color: rgb(111, 111, 109); +} +GlodonHHeaderView::section:checked +{ + border-image: url(:/ui/gldhheadviewsectionchecked.png) 3; + border: 3px; + color: rgb(111, 111, 109); +} + +GlodonVHeaderView +{ + /*border-image: url(:/ui/gldvheadviewbackground.png) 1;*/ + border: none; +} +GlodonVHeaderView::section +{ + border-image: url(:/ui/gldvheadviewsection.png) 1; + border: 1px; + color: #666666; +} +GlodonVHeaderView::section:checked +{ + border-image: url(:/ui/gldvheadviewsectionchecked.png) 1; + border: 1px; + color: #666666; +} + +GlodonMultiHeaderView +{ + /*border-image: url(:/ui/jiJiahheadviewsection.png) 2;*/ + border: none; +} +GlodonMultiHeaderView::section +{ + border-image: url(:/ui/jiJiahheadviewsection.png) 2; + border: 1px; + color: black; +} +GlodonMultiHeaderView::section:checked +{ + border-image: url(:/ui/jiJiahheadviewsectionchecked.png) 2; + border: 1px; + color: black; +} \ No newline at end of file diff --git a/GCR/trunk/Glodon/src/GLD/Res/ui/gldui.qrc b/GCR/trunk/Glodon/src/GLD/Res/ui/gldui.qrc new file mode 100644 index 00000000..a11c450a --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/Res/ui/gldui.qrc @@ -0,0 +1,13 @@ + + + gldhheadviewbackground.png + gldhheadviewsection.png + gldhheadviewsectionchecked.png + gldvheadviewbackground.png + gldvheadviewsection.png + gldvheadviewsectionchecked.png + gldtableviewdefault.qss + jiJiahheadviewsection.png + jiJiahheadviewsectionchecked.png + + diff --git a/GCR/trunk/Glodon/src/GLD/Res/ui/gldvheadviewbackground.png b/GCR/trunk/Glodon/src/GLD/Res/ui/gldvheadviewbackground.png new file mode 100644 index 00000000..040179d3 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ui/gldvheadviewbackground.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ui/gldvheadviewsection.png b/GCR/trunk/Glodon/src/GLD/Res/ui/gldvheadviewsection.png new file mode 100644 index 00000000..889cd156 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ui/gldvheadviewsection.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ui/gldvheadviewsectionchecked.png b/GCR/trunk/Glodon/src/GLD/Res/ui/gldvheadviewsectionchecked.png new file mode 100644 index 00000000..4aab3cc2 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ui/gldvheadviewsectionchecked.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ui/jiJiahheadviewsection.png b/GCR/trunk/Glodon/src/GLD/Res/ui/jiJiahheadviewsection.png new file mode 100644 index 00000000..ec7e9f32 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ui/jiJiahheadviewsection.png differ diff --git a/GCR/trunk/Glodon/src/GLD/Res/ui/jiJiahheadviewsectionchecked.png b/GCR/trunk/Glodon/src/GLD/Res/ui/jiJiahheadviewsectionchecked.png new file mode 100644 index 00000000..b13ba9f3 Binary files /dev/null and b/GCR/trunk/Glodon/src/GLD/Res/ui/jiJiahheadviewsectionchecked.png differ diff --git "a/GCR/trunk/Glodon/src/GLD/Res/ui/qss\344\275\277\347\224\250\350\257\264\346\230\216.txt" "b/GCR/trunk/Glodon/src/GLD/Res/ui/qss\344\275\277\347\224\250\350\257\264\346\230\216.txt" new file mode 100644 index 00000000..f2972b76 --- /dev/null +++ "b/GCR/trunk/Glodon/src/GLD/Res/ui/qss\344\275\277\347\224\250\350\257\264\346\230\216.txt" @@ -0,0 +1,8 @@ +QFile fl(":/ui/gldtableviewdefault.qss"); +if (fl.open(QIODevice::ReadOnly)) +{ + QTextStream ts(&fl); + //QString qw = ts.readAll(); test + app.setStyleSheet(app.styleSheet() + ts.readAll()); + fl.close(); +} \ No newline at end of file diff --git a/GCR/trunk/Glodon/src/GLD/UpdateTs.bat b/GCR/trunk/Glodon/src/GLD/UpdateTs.bat new file mode 100644 index 00000000..1f92fe7e --- /dev/null +++ b/GCR/trunk/Glodon/src/GLD/UpdateTs.bat @@ -0,0 +1 @@ +lupdate -verbose -no-obsolete ./GLD.pro \ No newline at end of file diff --git a/GCR/trunk/Glodon/translations/GLD_MessageBox_CN.qm b/GCR/trunk/Glodon/translations/GLD_MessageBox_CN.qm new file mode 100644 index 00000000..0058d3e9 Binary files /dev/null and b/GCR/trunk/Glodon/translations/GLD_MessageBox_CN.qm differ diff --git a/GCR/trunk/Glodon/translations/GLD_zh_CN.qm b/GCR/trunk/Glodon/translations/GLD_zh_CN.qm new file mode 100644 index 00000000..a628000a Binary files /dev/null and b/GCR/trunk/Glodon/translations/GLD_zh_CN.qm differ diff --git a/GCR/trunk/Glodon/translations/GRP7_zh_CN.qm b/GCR/trunk/Glodon/translations/GRP7_zh_CN.qm new file mode 100644 index 00000000..10724abd Binary files /dev/null and b/GCR/trunk/Glodon/translations/GRP7_zh_CN.qm differ diff --git a/GCR/trunk/Glodon/translations/GSP_zh_CN.qm b/GCR/trunk/Glodon/translations/GSP_zh_CN.qm new file mode 100644 index 00000000..777c01a7 Binary files /dev/null and b/GCR/trunk/Glodon/translations/GSP_zh_CN.qm differ diff --git a/GCR/trunk/Glodon/translations/GUC_zh_CN.qm b/GCR/trunk/Glodon/translations/GUC_zh_CN.qm new file mode 100644 index 00000000..ba562010 Binary files /dev/null and b/GCR/trunk/Glodon/translations/GUC_zh_CN.qm differ diff --git a/GCR/trunk/Glodon/translations/Readme.txt b/GCR/trunk/Glodon/translations/Readme.txt new file mode 100644 index 00000000..3b3c0e85 --- /dev/null +++ b/GCR/trunk/Glodon/translations/Readme.txt @@ -0,0 +1,14 @@ +公共资源最近增加了英文功能。 +若想使用英文,默认地,我们不需要作任何修改。 +若想使用中文,我们需要做如下步骤: + +1.在main函数中声明定义了QApplication后,调用如下语句: + GLDTranslations cbbtr; + cbbtr.loadConfigFile(exePath() + "translations"); + cbbtr.installTranslators(); + 其中translations是公共资源新增加的文件夹。loadConfigFile的参数就是该文件夹的路径。 + +2.增加对应的头文件包含 + #include "GLDTranslations.h" + #include "GLDFileUtils.h" //不使用exePath()则不必包含 + diff --git a/GCR/trunk/Glodon/translations/TranslationsConfig.xml b/GCR/trunk/Glodon/translations/TranslationsConfig.xml new file mode 100644 index 00000000..f0fd8f0d --- /dev/null +++ b/GCR/trunk/Glodon/translations/TranslationsConfig.xml @@ -0,0 +1,9 @@ + + + + + + GLD_zh_CN.qm + GSP_zh_CN.qm + + \ No newline at end of file diff --git a/GCR/trunk/Glodon/translations/UnitConfig.xml b/GCR/trunk/Glodon/translations/UnitConfig.xml new file mode 100644 index 00000000..041e23ca --- /dev/null +++ b/GCR/trunk/Glodon/translations/UnitConfig.xml @@ -0,0 +1,5496 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git "a/GCR/trunk/Glodon/translations/\345\212\250\346\200\201\345\212\240\350\275\275\350\265\204\346\272\220\346\226\207\344\273\266.pdf" "b/GCR/trunk/Glodon/translations/\345\212\250\346\200\201\345\212\240\350\275\275\350\265\204\346\272\220\346\226\207\344\273\266.pdf" new file mode 100644 index 00000000..2cd8e061 Binary files /dev/null and "b/GCR/trunk/Glodon/translations/\345\212\250\346\200\201\345\212\240\350\275\275\350\265\204\346\272\220\346\226\207\344\273\266.pdf" differ