widgetbox.cpp

来自「奇趣公司比较新的qt/emd版本」· C++ 代码 · 共 1,171 行 · 第 1/3 页

CPP
1,171
字号
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the Qt Designer of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.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 GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************//*TRANSLATOR qdesigner_internal::WidgetBoxTreeView*/#include "widgetbox.h"// shared#include <pluginmanager_p.h>#include <sheet_delegate_p.h>#include <iconloader_p.h>#include <ui4_p.h>#include <qdesigner_utils_p.h>#include <QtDesigner/QDesignerFormEditorInterface>#include <QtDesigner/QDesignerFormWindowManagerInterface>#include <QtDesigner/QDesignerCustomWidgetInterface>#include <QtDesigner/QDesignerWidgetDataBaseInterface>#include <QtGui/QApplication>#include <QtGui/QTreeWidget>#include <QtGui/QHeaderView>#include <QtGui/QVBoxLayout>#include <QtGui/QContextMenuEvent>#include <QtGui/QMenu>#include <QtGui/QLineEdit>#include <QtGui/qevent.h>#include <QtXml/QDomDocument>#include <QtCore/QFile>#include <QtCore/qdebug.h>#include "widgetbox_dnditem.h"namespace {    enum TopLevelRole  { NORMAL_ITEM, SCRATCHPAD_ITEM=1,CUSTOM_ITEM=2 };    typedef QList<QDomElement> ElementList;}/********************************************************************************* Tools*/static QDomElement childElement(const QDomNode &node, const QString &tag,                                const QString &attr_name,                                const QString &attr_value){    if (node.isElement()) {       const  QDomElement elt = node.toElement();        if (elt.tagName() == tag) {            if (attr_name.isEmpty())                return elt;            if (elt.hasAttribute(attr_name)) {                if (attr_value.isEmpty())                    return elt;                if (elt.attribute(attr_name) == attr_value)                    return elt;            }        }    }    QDomNode child = node.firstChild();    for (; !child.isNull(); child = child.nextSibling()) {        const  QDomElement elt = childElement(child, tag, attr_name, attr_value);        if (!elt.isNull())            return elt;    }    return QDomElement();}static void _childElementList(const QDomNode &node, const QString &tag,                                    const QString &attr_name,                                    const QString &attr_value,                                    ElementList *result){    if (node.isElement()) {        const  QDomElement elt = node.toElement();        if (elt.tagName() == tag) {            if (attr_name.isEmpty()) {                result->append(elt);            } else if (elt.hasAttribute(attr_name)) {                if (attr_value.isEmpty())                    result->append(elt);                else if (elt.attribute(attr_name) == attr_value)                    result->append(elt);            }        }    }    QDomNode child = node.firstChild();    for (; !child.isNull(); child = child.nextSibling())        _childElementList(child, tag, attr_name, attr_value, result);}static QString domToString(const QDomElement &elt){    QString result;    QTextStream stream(&result, QIODevice::WriteOnly);    elt.save(stream, 2);    stream.flush();    return result;}static QDomDocument stringToDom(const QString &xml){    QDomDocument result;    result.setContent(xml);    return result;}static DomWidget *xmlToUi(const QString &name, const QString &xml, QString &errorMessage){    QDomDocument doc;    QString err_msg;    int err_line, err_col;    if (!doc.setContent(xml, &err_msg, &err_line, &err_col)) {        errorMessage = QObject::tr("A parse error occurred at line %1, column %2 of the XML code specified for the widget %3: %4\n%5").                                arg(err_line).arg(err_col).arg(name).arg(err_msg).arg( xml);        return 0;    }    const QDomElement dom_elt = doc.firstChildElement();    if (dom_elt.nodeName() != QLatin1String("widget")) {        errorMessage = QObject::tr("The XML code specified for the widget %1 contains an invalid root element %2.\n%3").                                      arg(name).arg(dom_elt.nodeName()).arg(xml);        return 0;    }    DomWidget *widget = new DomWidget;    widget->read(dom_elt);    return widget;}static DomWidget *xmlToUi(const QString &name, const QString &xml){    QString errorMessage;    DomWidget *rc = xmlToUi(name, xml, errorMessage);    if (!rc)        qdesigner_internal::designerWarning(errorMessage);    return rc;}static void setTopLevelRole(TopLevelRole tlr, QTreeWidgetItem *item){    item->setData(0, Qt::UserRole, QVariant(tlr));}static TopLevelRole topLevelRole(const  QTreeWidgetItem *item){    return static_cast<TopLevelRole>(item->data(0, Qt::UserRole).toInt());}/********************************************************************************* WidgetBoxItemDelegate*/namespace qdesigner_internal {class WidgetBoxItemDelegate : public SheetDelegate{public:    WidgetBoxItemDelegate(QTreeWidget *tree, QWidget *parent = 0)        : SheetDelegate(tree, parent) {}    QWidget *createEditor(QWidget *parent,                          const QStyleOptionViewItem &option,                          const QModelIndex &index) const;};/********************************************************************************* WidgetBoxTreeView*/class WidgetBoxTreeView : public QTreeWidget{    Q_OBJECTpublic:    typedef QDesignerWidgetBoxInterface::Widget Widget;    typedef QDesignerWidgetBoxInterface::Category Category;    typedef QDesignerWidgetBoxInterface::CategoryList CategoryList;    WidgetBoxTreeView(QDesignerFormEditorInterface *core, QWidget *parent = 0);    ~WidgetBoxTreeView();    int categoryCount() const;    Category category(int cat_idx) const;    void addCategory(const Category &cat);    void removeCategory(int cat_idx);    int widgetCount(int cat_idx) const;    Widget widget(int cat_idx, int wgt_idx) const;    void addWidget(int cat_idx, const Widget &wgt);    void removeWidget(int cat_idx, int wgt_idx);    void dropWidgets(const QList<QDesignerDnDItemInterface*> &item_list);    void setFileName(const QString &file_name);    QString fileName() const;    bool load(WidgetBox::LoadMode loadMode);    bool loadContents(const QString &contents, const QString &fileName);    bool save();signals:    void pressed(const QString name, const QString dom_xml, bool custom, const QPoint &global_mouse_pos);protected:    void contextMenuEvent(QContextMenuEvent *e);private slots:    void handleMousePress(QTreeWidgetItem *item);    void removeCurrentItem();    void editCurrentItem();    void updateItemData(QTreeWidgetItem *item);    void deleteScratchpad();private:    QDesignerFormEditorInterface *m_core;    QString m_file_name;    mutable QHash<QString, QIcon> m_pluginIcons;    QStringList m_widgetNames;    CategoryList domToCategoryList(const QDomDocument &doc) const;    Category domToCategory(const QDomElement &cat_elt) const;    CategoryList loadCustomCategoryList() const;    QDomDocument categoryListToDom(const CategoryList &cat_list) const;    QTreeWidgetItem *widgetToItem(const Widget &wgt, QTreeWidgetItem *parent,                                    bool editable = false);    static Widget itemToWidget(const QTreeWidgetItem *item);    int indexOfCategory(const QString &name) const;    int indexOfScratchpad() const;    int ensureScratchpad();    void addCustomCategories(bool replace);    void saveExpandedState() const;    void restoreExpandedState();    static QString widgetDomXml(const Widget &widget);    static QString qtify(const QString &name);};QWidget *WidgetBoxItemDelegate::createEditor(QWidget *parent,                                                const QStyleOptionViewItem &option,                                                const QModelIndex &index) const{    QWidget *result = SheetDelegate::createEditor(parent, option, index);    QLineEdit *line_edit = qobject_cast<QLineEdit*>(result);    if (line_edit == 0)        return result;    line_edit->setValidator(new QRegExpValidator(QRegExp(QLatin1String("[_a-zA-Z][_a-zA-Z0-9]*")), line_edit));    return result;}WidgetBoxTreeView::WidgetBoxTreeView(QDesignerFormEditorInterface *core, QWidget *parent)    : QTreeWidget(parent),m_core(core){    setFocusPolicy(Qt::NoFocus);    setIconSize(QSize(22, 22));    setItemDelegate(new WidgetBoxItemDelegate(this, this));    setRootIsDecorated(false);    setColumnCount(1);    header()->hide();    header()->setResizeMode(QHeaderView::Stretch);    setTextElideMode (Qt::ElideMiddle);    connect(this, SIGNAL(itemPressed(QTreeWidgetItem*,int)),            this, SLOT(handleMousePress(QTreeWidgetItem*)));    connect(this, SIGNAL(itemChanged(QTreeWidgetItem*,int)),            this, SLOT(updateItemData(QTreeWidgetItem*)));    setEditTriggers(QAbstractItemView::AnyKeyPressed);}void WidgetBoxTreeView::saveExpandedState() const{    QStringList closedCategories;    if (const int numCategories = categoryCount()) {        for (int i = 0; i < numCategories; ++i) {            const QTreeWidgetItem *cat_item = topLevelItem(i);            if (!isItemExpanded(cat_item))                closedCategories.append(cat_item->text(0));        }    }    QSettings settings;    settings.beginGroup(QLatin1String("WidgetBox"));    settings.setValue(QLatin1String("Closed categories"), closedCategories);    settings.endGroup();}void  WidgetBoxTreeView::restoreExpandedState(){    typedef QSet<QString> StringSet;    QSettings settings;    const StringSet closedCategories = settings.value(QLatin1String("WidgetBox/Closed categories"), QStringList()).toStringList().toSet();    expandAll();    if (closedCategories.empty())        return;    if (const int numCategories = categoryCount()) {        for (int i = 0; i < numCategories; ++i) {            QTreeWidgetItem *item = topLevelItem(i);            if (closedCategories.contains(item->text(0)))                item->setExpanded(false);            }    }}WidgetBoxTreeView::~WidgetBoxTreeView(){    saveExpandedState();}QString WidgetBoxTreeView::qtify(const QString &name){    QString qname = name;    Q_ASSERT(name.isEmpty() == false);    if (qname.count() > 1 && qname.at(1).toUpper() == qname.at(1) && (qname.at(0) == QLatin1Char('Q') || qname.at(0) == QLatin1Char('K')))        qname = qname.mid(1);    int i=0;    while (i < qname.length()) {        if (qname.at(i).toLower() != qname.at(i))            qname[i] = qname.at(i).toLower();        else            break;        ++i;    }    return qname;}QString WidgetBoxTreeView::widgetDomXml(const Widget &widget){    QString domXml = widget.domXml();    if (domXml.isEmpty()) {        const QString defaultVarName = qtify(widget.name());        const QString typeStr = widget.type() == Widget::Default                            ? QLatin1String("default")                            : QLatin1String("custom");        domXml = QString::fromUtf8("<widget class=\"%1\" name=\"%2\" type=\"%3\"/>")            .arg(widget.name())            .arg(defaultVarName)            .arg(typeStr);    }    return domXml;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?