52 #include <QtDesigner/QDesignerDnDItemInterface> 
   53 #include <QtDesigner/QDesignerFormEditorInterface> 
   55 #if QT_VERSION < QT_VERSION_CHECK(5, 5, 0) 
   56 #include <QtDesigner/QDesignerCustomWidgetInterface> 
   58 #include <QtUiPlugin/QDesignerCustomWidgetInterface> 
   62 #include <QActionGroup> 
   63 #include <QApplication> 
   64 #include <QContextMenuEvent> 
   65 #include <QHeaderView> 
   67 #include <QTreeWidgetItem> 
   69 #include <QtCore/QDebug> 
   70 #include <QtCore/QFile> 
   71 #include <QtCore/QTimer> 
   87 static const char* 
qtLogoC = 
"qtlogo.png";
 
   92     return QIcon(QString::fromUtf8(
":/widgetbox/") + 
name);
 
  101     item->setData(0, Qt::UserRole, QVariant(tlr));
 
  106     return static_cast<ETopLevelRole>(item->data(0, Qt::UserRole).toInt());
 
  112     : QTreeWidget(parent), m_core(core), m_iconMode(false), m_scratchPadDeleteTimer(nullptr)
 
  114     setFocusPolicy(Qt::NoFocus);
 
  116     setRootIsDecorated(
false);
 
  119 #if QT_VERSION >= 0x050000 
  120     header()->setSectionResizeMode(QHeaderView::Stretch);
 
  122     setTextElideMode(Qt::ElideMiddle);
 
  123     setVerticalScrollMode(ScrollPerPixel);
 
  127     connect(
this, SIGNAL(itemPressed(QTreeWidgetItem*, 
int)), 
this,
 
  133     if (iconName.isEmpty())
 
  134         iconName = QLatin1String(
qtLogoC);
 
  136     if (iconName.startsWith(QLatin1String(
iconPrefixC))) {
 
  137         const IconCache::const_iterator it = 
m_pluginIcons.constFind(iconName);
 
  147     if (QTreeWidgetItem* cat_item = topLevelItem(idx))
 
  148         if (QTreeWidgetItem* embedItem = cat_item->child(0))
 
  149             rc = qobject_cast<WidgetBoxCategoryListView*>(itemWidget(embedItem, 0));
 
  161     std::cout << 
"WidgetBoxTreeWidget::restoreExpandedState() -> XXX Not implemented." << std::endl;
 
  186     if (!file.open(QIODevice::WriteOnly))
 
  191     for (
int i = 0; i < count; ++i)
 
  194     QXmlStreamWriter writer(&file);
 
  195     writer.setAutoFormatting(
true);
 
  196     writer.setAutoFormattingIndent(1);
 
  197     writer.writeStartDocument();
 
  199     writer.writeEndDocument();
 
  214     if (QApplication::mouseButtons() != Qt::LeftButton)
 
  217     if (item->parent() == 
nullptr) {
 
  218 #if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0) 
  219         item->setExpanded(!item->isExpanded());
 
  221         setItemExpanded(item, !isItemExpanded(item));
 
  230     if (existingIndex != -1)
 
  231         return existingIndex;
 
  233     QTreeWidgetItem* scratch_item = 
new QTreeWidgetItem(
this);
 
  234     scratch_item->setText(0, 
"Scratchpad");
 
  243     QTreeWidgetItem* embed_item = 
new QTreeWidgetItem(parent);
 
  244     embed_item->setFlags(Qt::ItemIsEnabled);
 
  246     categoryView->
setViewMode(iconMode ? QListView::IconMode : QListView::ListMode);
 
  247     connect(categoryView, SIGNAL(scratchPadChanged()), 
this, SLOT(
slotSave()));
 
  248     connect(categoryView, SIGNAL(
pressed(QString, QString, QPoint)), 
this,
 
  249             SIGNAL(
pressed(QString, QString, QPoint)));
 
  252     setItemWidget(embed_item, 0, categoryView);
 
  258     if (
const int numTopLevels = topLevelItemCount()) {
 
  259         for (
int i = numTopLevels - 1; i >= 0; --i) {
 
  269     const int topLevelCount = topLevelItemCount();
 
  270     for (
int i = 0; i < topLevelCount; ++i) {
 
  271         if (topLevelItem(i)->text(0) == 
name)
 
  293     if (!f.open(QIODevice::ReadOnly)) 
 
  296     const QString contents = QString::fromUtf8(f.readAll());
 
  302     QString errorMessage;
 
  308     for (
const Category& cat : cat_list)
 
  318         if (
const int numTopLevels = topLevelItemCount()) {
 
  319             for (
int t = 0; t < numTopLevels; ++t)
 
  325     const CategoryList::const_iterator cend = customList.constEnd();
 
  326     for (CategoryList::const_iterator it = customList.constBegin(); it != cend; ++it)
 
  330 static inline QString 
msgXmlError(
const QString& fileName, 
const QXmlStreamReader& r)
 
  332     return QString(
"An error has been encountered at line %1 of %2: %3")
 
  334         .arg(fileName, r.errorString());
 
  348     QXmlStreamReader reader(contents);
 
  351     bool ignoreEntries = 
false;
 
  353     while (!reader.atEnd()) {
 
  354         switch (reader.readNext()) {
 
  355         case QXmlStreamReader::StartElement: {
 
  356             const QStringRef tag = reader.name();
 
  363                 const QXmlStreamAttributes attributes = reader.attributes();
 
  364                 const QString categoryName =
 
  367                     ignoreEntries = 
true;
 
  372                         category.setType(Category::Scratchpad);
 
  379                 if (!ignoreEntries) {
 
  380                     QXmlStreamAttributes attr = reader.attributes();
 
  381                     const QString widgetName = attr.value(QLatin1String(
nameAttributeC)).toString();
 
  382                     const QString widgetIcon = attr.value(QLatin1String(
iconAttributeC)).toString();
 
  383                     const WidgetBoxTreeWidget::Widget::Type widgetType =
 
  386                             ? WidgetBoxTreeWidget::Widget::Custom
 
  387                             : WidgetBoxTreeWidget::Widget::Default;
 
  390                     w.setName(widgetName);
 
  391                     w.setIconName(widgetIcon);
 
  392                     w.setType(widgetType);
 
  396                     cats->back().addWidget(w);
 
  402         case QXmlStreamReader::EndElement: {
 
  403             const QStringRef tag = reader.name();
 
  408                 ignoreEntries = 
false;
 
  421     if (reader.hasError()) {
 
  454     qint64 startTagPosition = 0, endTagPosition = 0;
 
  457     bool endEncountered = 
false;
 
  458     bool parsedWidgetTag = 
false;
 
  459     QString outmostElement;
 
  460     while (!endEncountered) {
 
  461         const qint64 currentPosition = r.characterOffset();
 
  462         switch (r.readNext()) {
 
  463         case QXmlStreamReader::StartElement:
 
  464             if (nesting++ == 0) {
 
  466                 const QStringRef 
name = r.name();
 
  468                     startTagPosition = currentPosition;
 
  471                         startTagPosition = currentPosition;
 
  472                         parsedWidgetTag = 
true;
 
  474                         r.raiseError(QString(
"Unexpected element <%1> encountered when " 
  475                                              "parsing for <widget> or <ui>")
 
  476                                          .arg(
name.toString()));
 
  482                 if (!parsedWidgetTag && r.name() == QLatin1String(
widgetElementC)) {
 
  483                     parsedWidgetTag = 
true;
 
  487         case QXmlStreamReader::EndElement:
 
  489             if (--nesting == 0) {
 
  490                 endTagPosition = r.characterOffset();
 
  491                 endEncountered = 
true;
 
  494         case QXmlStreamReader::EndDocument:
 
  495             r.raiseError(
"Unexpected end of file encountered when parsing widgets.");
 
  497         case QXmlStreamReader::Invalid:
 
  503     if (!parsedWidgetTag) {
 
  504         r.raiseError(
"A widget element could not be found.");
 
  508     QString widgetXml = xml.mid(startTagPosition, endTagPosition - startTagPosition);
 
  509     const QChar lessThan = QLatin1Char(
'<');
 
  510     if (!widgetXml.startsWith(lessThan))
 
  511         widgetXml.prepend(lessThan);
 
  512     w->setDomXml(widgetXml);
 
  526     const QString iconPrefix = QLatin1String(
iconPrefixC);
 
  543     writer.writeStartElement(widgetbox);
 
  545     for (
const Category& cat : cat_list) {
 
  547         writer.writeAttribute(
name, cat.name());
 
  548         if (cat.type() == Category::Scratchpad)
 
  553             const Widget wgt = cat.widget(i);
 
  554             if (wgt.type() == Widget::Custom)
 
  557             writer.writeStartElement(categoryEntry);
 
  558             writer.writeAttribute(
name, wgt.name());
 
  559             if (!wgt.iconName().startsWith(iconPrefix))
 
  560                 writer.writeAttribute(icon, wgt.iconName());
 
  561             writer.writeAttribute(type, defaultType);
 
  566                 domUI->
write(writer);
 
  569             writer.writeEndElement(); 
 
  571         writer.writeEndElement(); 
 
  573     writer.writeEndElement(); 
 
  580     std::cout << 
"WidgetBoxTreeWidget::loadCustomCategoryList() -> XXX Not implemented." 
  587     QTreeWidgetItem* embedItem = cat_item->child(0);
 
  588     if (embedItem == 
nullptr)
 
  593     list_widget->setFixedWidth(header()->width());
 
  594     list_widget->doItemsLayout();
 
  595     const int height = qMax(list_widget->contentsSize().height(), 1);
 
  596     list_widget->setFixedHeight(height);
 
  597     embedItem->setSizeHint(0, QSize(-1, height - 1));
 
  602     return topLevelItemCount();
 
  607     if (cat_idx >= topLevelItemCount())
 
  610     QTreeWidgetItem* cat_item = topLevelItem(cat_idx);
 
  612     QTreeWidgetItem* embedItem = cat_item->child(0);
 
  617     result.setName(cat_item->text(0));
 
  621         result.setType(Category::Scratchpad);
 
  624         result.setType(Category::Default);
 
  632     if (cat.widgetCount() == 0)
 
  635     const bool isScratchPad = cat.type() == Category::Scratchpad;
 
  637     QTreeWidgetItem* cat_item;
 
  642         cat_item = topLevelItem(idx);
 
  645         if (existingIndex == -1) {
 
  646             cat_item = 
new QTreeWidgetItem();
 
  647             cat_item->setText(0, cat.name());
 
  651             if (scratchPadIndex == -1) {
 
  652                 addTopLevelItem(cat_item);
 
  654                 insertTopLevelItem(scratchPadIndex, cat_item);
 
  656 #if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0) 
  657             cat_item->setExpanded(
true);
 
  659             setItemExpanded(cat_item, 
true);
 
  665             cat_item = topLevelItem(existingIndex);
 
  671         const Widget w = cat.widget(i);
 
  680     if (cat_idx >= topLevelItemCount())
 
  682     delete takeTopLevelItem(cat_idx);
 
  687     if (cat_idx >= topLevelItemCount())
 
  695     if (cat_idx >= topLevelItemCount())
 
  704     if (cat_idx >= topLevelItemCount())
 
  707     QTreeWidgetItem* cat_item = topLevelItem(cat_idx);
 
  717     if (cat_idx >= topLevelItemCount())
 
  724     if (wgt_idx >= categoryView->
count(am))
 
  733     QTreeWidgetItem* scratch_item = topLevelItem(scratch_idx);
 
  756     delete takeTopLevelItem(idx);
 
  774     if (
const int numTopLevels = topLevelItemCount()) {
 
  775         for (
int i = numTopLevels - 1; i >= 0; --i) {
 
  776             QTreeWidgetItem* topLevel = topLevelItem(i);
 
  778             const QListView::ViewMode viewMode =
 
  780                                                                           : QListView::ListMode;
 
  782             if (viewMode != categoryView->viewMode()) {
 
  783                 categoryView->setViewMode(viewMode);
 
  793     QTreeWidget::resizeEvent(e);
 
  794     if (
const int numTopLevels = topLevelItemCount()) {
 
  795         for (
int i = numTopLevels - 1; i >= 0; --i)
 
  802     QTreeWidgetItem* item = itemAt(e->pos());
 
  804     const bool scratchpad_menu = item != 
nullptr && item->parent() != 
nullptr 
  808     menu.addAction(
"Expand all", 
this, SLOT(expandAll()));
 
  809     menu.addAction(
"Collapse all", 
this, SLOT(collapseAll()));
 
  812     QAction* listModeAction = menu.addAction(
"List View");
 
  813     QAction* iconModeAction = menu.addAction(
"Icon View");
 
  814     listModeAction->setCheckable(
true);
 
  815     iconModeAction->setCheckable(
true);
 
  816     QActionGroup* viewModeGroup = 
new QActionGroup(&menu);
 
  817     viewModeGroup->addAction(listModeAction);
 
  818     viewModeGroup->addAction(iconModeAction);
 
  820         iconModeAction->setChecked(
true);
 
  822         listModeAction->setChecked(
true);
 
  823     connect(listModeAction, SIGNAL(triggered()), SLOT(
slotListMode()));
 
  824     connect(iconModeAction, SIGNAL(triggered()), SLOT(
slotIconMode()));
 
  826     if (scratchpad_menu) {
 
  828         menu.addAction(
"Remove", itemWidget(item, 0), SLOT(removeCurrentItem()));
 
  830             menu.addAction(
"Edit name", itemWidget(item, 0), SLOT(editCurrentItem()));
 
  833     menu.exec(mapToGlobal(e->pos()));
 
  838     QTreeWidgetItem* scratch_item = 
nullptr;
 
  842     for (QDesignerDnDItemInterface* item : item_list) {
 
  843         QWidget* w = item->widget();
 
  847         DomUI* dom_ui = item->domUi();
 
  848         if (dom_ui == 
nullptr)
 
  852         scratch_item = topLevelItem(scratch_idx);
 
  858         if (fakeTopLevel && !fakeTopLevel->
elementWidget().isEmpty()) {
 
  868             QXmlStreamWriter writer(&xml);
 
  869             writer.setAutoFormatting(
true);
 
  870             writer.setAutoFormattingIndent(1);
 
  871             writer.writeStartDocument();
 
  872             dom_ui->
write(writer);
 
  873             writer.writeEndDocument();
 
  881 #if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0) 
  882         scratch_item->setExpanded(
true);
 
  884         setItemExpanded(scratch_item, 
true);
 
  891         QApplication::setActiveWindow(
this);
 
  894         if (
const int count = categoryView->
count(am))
 
  896         categoryView->adjustSize(); 
 
  903     const bool empty = f.isEmpty();
 
  904     QRegExp re = empty ? QRegExp() : QRegExp(f, Qt::CaseInsensitive, QRegExp::FixedString);
 
  905     const int numTopLevels = topLevelItemCount();
 
  906     bool changed = 
false;
 
  907     for (
int i = 0; i < numTopLevels; i++) {
 
  908         QTreeWidgetItem* tl = topLevelItem(i);
 
  914         if (oldCount != newCount) {
 
  916             const bool categoryEnabled = newCount > 0 || empty;
 
  917             if (categoryEnabled) {
 
  918                 categoryView->adjustSize();
 
  921             setRowHidden(i, QModelIndex(), !categoryEnabled);
 
Defines the macro ASSERT.
 
#define ASSERT(condition)
 
void setElementWidget(DomWidget *a)
 
DomWidget * takeElementWidget()
 
void write(QXmlStreamWriter &writer, const QString &tagName="") const
 
sample designer interface
 
QString const  & name(EShape k)
 
static QString msgXmlError(const QString &fileName, const QXmlStreamReader &r)
 
QDESIGNER_SHARED_EXPORT void designerWarning(const QString &message)