#include "DockChildList.h" #include #include #include #include #include #include DockChildList::DockChildList(QWidget *parent) : QTreeWidget(parent) { setDragEnabled(true); setAcceptDrops(true); setSelectionMode(QAbstractItemView::SingleSelection); setDragDropMode(QAbstractItemView::InternalMove); setStyleSheet("QTreeWidget::item{height:20px}"); this->header()->hide(); } DockChildList::~DockChildList() { } void DockChildList::InitConfig(const QString& strFile) { std::string path = strFile.toStdString(); tinyxml2::XMLDocument xmlDocument; tinyxml2::XMLError error = xmlDocument.LoadFile(path.c_str()); if (tinyxml2::XMLError::XML_SUCCESS != error) { return; } m_strCurConfig = strFile; const tinyxml2::XMLElement* root = xmlDocument.RootElement(); if (root) { const char* eleRootName = root->Name(); if (0 == strcmp(eleRootName, "Layout")) { const tinyxml2::XMLElement* xmlMainWindow = root->FirstChildElement(); while (nullptr != xmlMainWindow) { // MainWindow const char* eleMainWindowName = xmlMainWindow->Name(); QTreeWidgetItem* pMainWindowItem = new QTreeWidgetItem; pMainWindowItem->setTextColor(0, Qt::green); pMainWindowItem->setText(0, eleMainWindowName); pMainWindowItem->setData(0, Qt::UserRole, true); // 是否允许拖拽 pMainWindowItem->setData(0, Qt::UserRole + 1, "MainWindow"); pMainWindowItem->setData(0, Qt::UserRole + 2, eleMainWindowName); pMainWindowItem->setFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable); { const tinyxml2::XMLAttribute* attribute = xmlMainWindow->FirstAttribute(); while (nullptr != attribute) { if (0 == strcmp(attribute->Name(), "Name")) { pMainWindowItem->setText(0, attribute->Value()); } attribute = attribute->Next(); } } // docArea const tinyxml2::XMLElement* xmlDocArea = xmlMainWindow->FirstChildElement(); while (nullptr != xmlDocArea) { const char* eleDocAreaName = xmlDocArea->Name(); QTreeWidgetItem* pDocAreaItem = new QTreeWidgetItem; pDocAreaItem->setTextColor(0, Qt::green); pDocAreaItem->setText(0, eleDocAreaName); pDocAreaItem->setData(0, Qt::UserRole, true); // 是否允许拖拽 pDocAreaItem->setData(0, Qt::UserRole + 2, eleDocAreaName); if (0 == strcmp(eleDocAreaName, "CentralWidget")) { pDocAreaItem->setData(0, Qt::UserRole + 1, "CentralWidget"); } else { pDocAreaItem->setData(0, Qt::UserRole + 1, "DocArea"); } { const tinyxml2::XMLAttribute* attribute = xmlDocArea->FirstAttribute(); while (nullptr != attribute) { if (0 == strcmp(attribute->Name(), "Name")) { pDocAreaItem->setText(0, attribute->Value()); } attribute = attribute->Next(); } } const tinyxml2::XMLElement* xmlDocAreaChild = xmlDocArea->FirstChildElement(); while (nullptr != xmlDocAreaChild) { const char* eleDocAreaChildName = xmlDocAreaChild->Name(); if (0 == strcmp(eleDocAreaChildName, "Widget")) // widget { const tinyxml2::XMLAttribute* attribute = xmlDocAreaChild->FirstAttribute(); QTreeWidgetItem* pWidgetItem = new QTreeWidgetItem; pWidgetItem->setData(0, Qt::UserRole, false); // 是否允许拖拽 pWidgetItem->setData(0, Qt::UserRole + 1, "Widget"); while (nullptr != attribute) { if (0 == strcmp(attribute->Name(), "Plugin")) { pWidgetItem->setData(0, Qt::UserRole + 2, attribute->Value()); } else if (0 == strcmp(attribute->Name(), "Name")) { pWidgetItem->setText(0, attribute->Value()); } attribute = attribute->Next(); } pDocAreaItem->addChild(pWidgetItem); } else if (0 == strcmp(eleDocAreaChildName, "DocTab")) // tab { QTreeWidgetItem* pTabItem = new QTreeWidgetItem; pTabItem->setTextColor(0, Qt::green); pTabItem->setText(0, eleDocAreaChildName); pTabItem->setData(0, Qt::UserRole, false); // 是否允许拖拽 pTabItem->setData(0, Qt::UserRole + 1, "DocTab"); pTabItem->setData(0, Qt::UserRole + 2, eleDocAreaChildName); { const tinyxml2::XMLAttribute* attribute = xmlDocAreaChild->FirstAttribute(); while (nullptr != attribute) { if (0 == strcmp(attribute->Name(), "Name")) { pTabItem->setText(0, attribute->Value()); } attribute = attribute->Next(); } } pDocAreaItem->addChild(pTabItem); // widget const tinyxml2::XMLElement* xmlElementUI = xmlDocAreaChild->FirstChildElement(); while (nullptr != xmlElementUI) { QTreeWidgetItem* pWidgetItem = new QTreeWidgetItem; pWidgetItem->setData(0, Qt::UserRole, false); // 是否允许拖拽 pWidgetItem->setData(0, Qt::UserRole + 1, "Widget"); const tinyxml2::XMLAttribute* attribute = xmlElementUI->FirstAttribute(); while (nullptr != attribute) { if (0 == strcmp(attribute->Name(), "Plugin")) { pWidgetItem->setData(0, Qt::UserRole + 2, attribute->Value()); } else if (0 == strcmp(attribute->Name(), "Name")) { pWidgetItem->setText(0, attribute->Value()); } attribute = attribute->Next(); } pTabItem->addChild(pWidgetItem); xmlElementUI = xmlElementUI->NextSiblingElement(); } pTabItem->setExpanded(true); } xmlDocAreaChild = xmlDocAreaChild->NextSiblingElement(); } xmlDocArea = xmlDocArea->NextSiblingElement(); pMainWindowItem->addChild(pDocAreaItem); } xmlMainWindow = xmlMainWindow->NextSiblingElement(); addTopLevelItem(pMainWindowItem); pMainWindowItem->setExpanded(true); } } } } void DockChildList::SaveConfig() { tinyxml2::XMLDocument doc; doc.LinkEndChild(doc.NewDeclaration("xml version=\"1.0\" encoding=\"UTF-8\"")); tinyxml2::XMLElement* lyt = doc.NewElement("Layout"); doc.LinkEndChild(lyt); for (int i = 0; i < this->topLevelItemCount(); i++) { QTreeWidgetItem* pMainWindowItem = this->topLevelItem(i); QString strMainWindowName = pMainWindowItem->text(0); tinyxml2::XMLElement* mainWindowEle = doc.NewElement("MainWindow"); mainWindowEle->SetAttribute("Name", strMainWindowName.toStdString().c_str()); lyt->LinkEndChild(mainWindowEle); for (int j = 0; j < pMainWindowItem->childCount(); j++) { QTreeWidgetItem* pAreaItem = pMainWindowItem->child(j); QString strAreaNodeName = pAreaItem->data(0, Qt::UserRole + 2).toString(); tinyxml2::XMLElement* docAreaEle = doc.NewElement(strAreaNodeName.toStdString().c_str()); docAreaEle->SetAttribute("Name", pAreaItem->text(0).toStdString().c_str()); mainWindowEle->LinkEndChild(docAreaEle); for (int m = 0; m < pAreaItem->childCount(); m++) { QTreeWidgetItem* pAreaChildItem = pAreaItem->child(m); QString strType = pAreaChildItem->data(0, Qt::UserRole + 1).toString(); if (strType == "DocTab") { tinyxml2::XMLElement* tabEle = doc.NewElement("DocTab"); tabEle->SetAttribute("Name", pAreaChildItem->text(0).toStdString().c_str()); docAreaEle->LinkEndChild(tabEle); for (int k = 0; k < pAreaChildItem->childCount(); k++) { tinyxml2::XMLElement* widgetEle = doc.NewElement("Widget"); widgetEle->SetAttribute("Plugin", pAreaChildItem->child(k)->data(0,Qt::UserRole+2).toString().toStdString().c_str()); widgetEle->SetAttribute("Name", pAreaChildItem->child(k)->text(0).toStdString().c_str()); tabEle->LinkEndChild(widgetEle); } } else { tinyxml2::XMLElement* widgetEle = doc.NewElement("Widget"); widgetEle->SetAttribute("Plugin", pAreaChildItem->data(0, Qt::UserRole + 2).toString().toStdString().c_str()); widgetEle->SetAttribute("Name", pAreaChildItem->text(0).toStdString().c_str()); docAreaEle->LinkEndChild(widgetEle); } } } } tinyxml2::XMLError xmlError = doc.SaveFile(m_strCurConfig.toStdString().c_str(), false); if (tinyxml2::XML_SUCCESS != xmlError) { return; } } QVariant DockChildList::GetAreaLayout() { QVariantList listMainWindow; for (int i = 0; i < this->topLevelItemCount(); i++) { QTreeWidgetItem* pMainWindowItem = this->topLevelItem(i); QString strMainWindowName = pMainWindowItem->text(0); QVariantMap mapWindow; mapWindow.insert("Name", strMainWindowName); QVariantList listDocArea; for (int j = 0; j < pMainWindowItem->childCount(); j++) { QTreeWidgetItem* pDocAreaItem = pMainWindowItem->child(j); QVariantList listDocAreaChild; for (size_t m = 0; m < pDocAreaItem->childCount(); m++) { QTreeWidgetItem* pDocAreaChildItem = pDocAreaItem->child(m); QString strType = pDocAreaChildItem->data(0, Qt::UserRole + 1).toString(); if (strType == "DocTab") { QVariantList listWidget; for (int k = 0; k < pDocAreaChildItem->childCount(); k++) { QTreeWidgetItem* pWidgetItem = pDocAreaChildItem->child(k); listWidget.push_back(pWidgetItem->data(0, Qt::UserRole + 2)); } if (listWidget.size() > 0) { listDocAreaChild.push_back(listWidget); } } else { listDocAreaChild.push_back(pDocAreaChildItem->data(0, Qt::UserRole + 2)); } } listDocArea.push_back(listDocAreaChild); } mapWindow.insert("Widget", listDocArea); listMainWindow.push_back(mapWindow); } return QVariant(listMainWindow); } void DockChildList::slotAddTab() { QTreeWidgetItem* pItem = new QTreeWidgetItem; pItem->setTextColor(0, Qt::green); pItem->setText(0, QString::fromLocal8Bit("水平分页")); pItem->setData(0, Qt::UserRole, false); // 是否允许拖拽 pItem->setData(0, Qt::UserRole + 1, "DocTab"); pItem->setData(0, Qt::UserRole + 2, "DocTab"); m_pMenuItem->addChild(pItem); } void DockChildList::slotRemoveTab() { int iCount = m_pMenuItem->childCount(); QTreeWidgetItem* pParentItem = m_pMenuItem->parent(); int iIndex = pParentItem->indexOfChild(m_pMenuItem); while(m_pMenuItem->childCount() > 0) { QTreeWidgetItem* pItem = m_pMenuItem->child(0); m_pMenuItem->removeChild(pItem); pParentItem->insertChild(iIndex, pItem); iIndex++; } pParentItem->removeChild(m_pMenuItem); } void DockChildList::slotFront() { int iIndex = m_pMenuItem->parent()->indexOfChild(m_pMenuItem); QTreeWidgetItem* pParentItem = m_pMenuItem->parent(); m_pMenuItem = pParentItem->takeChild(iIndex); pParentItem->insertChild(iIndex - 1, m_pMenuItem); } void DockChildList::slotBack() { int iIndex = m_pMenuItem->parent()->indexOfChild(m_pMenuItem); QTreeWidgetItem* pParentItem = m_pMenuItem->parent(); m_pMenuItem = pParentItem->takeChild(iIndex); pParentItem->insertChild(iIndex+1, m_pMenuItem); } void DockChildList::slotAddWindow() { QTreeWidgetItem* pMainWindowItem = new QTreeWidgetItem; pMainWindowItem->setTextColor(0, Qt::green); pMainWindowItem->setText(0,tr("Added a window")); pMainWindowItem->setData(0, Qt::UserRole, true); // 是否允许拖拽 pMainWindowItem->setData(0, Qt::UserRole + 1, "MainWindow"); pMainWindowItem->setData(0, Qt::UserRole + 2, "MainWindow"); pMainWindowItem->setFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable); { QTreeWidgetItem* pDocAreaItem = new QTreeWidgetItem; pDocAreaItem->setTextColor(0, Qt::green); pDocAreaItem->setText(0, tr("Central area")); pDocAreaItem->setData(0, Qt::UserRole, true); // 是否允许拖拽 pDocAreaItem->setData(0, Qt::UserRole + 1, "CentralWidget"); pDocAreaItem->setData(0, Qt::UserRole + 2, "CentralWidget"); pMainWindowItem->addChild(pDocAreaItem); } { QTreeWidgetItem* pDocAreaItem = new QTreeWidgetItem; pDocAreaItem->setTextColor(0, Qt::green); pDocAreaItem->setText(0, tr("Left area")); pDocAreaItem->setData(0, Qt::UserRole, true); // 是否允许拖拽 pDocAreaItem->setData(0, Qt::UserRole + 1, "DocArea"); pDocAreaItem->setData(0, Qt::UserRole + 2, "DockLeftArea"); pMainWindowItem->addChild(pDocAreaItem); } { QTreeWidgetItem* pDocAreaItem = new QTreeWidgetItem; pDocAreaItem->setTextColor(0, Qt::green); pDocAreaItem->setText(0, tr("Upper area")); pDocAreaItem->setData(0, Qt::UserRole, true); // 是否允许拖拽 pDocAreaItem->setData(0, Qt::UserRole + 1, "DocArea"); pDocAreaItem->setData(0, Qt::UserRole + 2, "DockTopArea"); pMainWindowItem->addChild(pDocAreaItem); } { QTreeWidgetItem* pDocAreaItem = new QTreeWidgetItem; pDocAreaItem->setTextColor(0, Qt::green); pDocAreaItem->setText(0, tr("Right area")); pDocAreaItem->setData(0, Qt::UserRole, true); // 是否允许拖拽 pDocAreaItem->setData(0, Qt::UserRole + 1, "DocArea"); pDocAreaItem->setData(0, Qt::UserRole + 2, "DockRightArea"); pMainWindowItem->addChild(pDocAreaItem); } { QTreeWidgetItem* pDocAreaItem = new QTreeWidgetItem; pDocAreaItem->setTextColor(0, Qt::green); pDocAreaItem->setText(0, tr("Underneath the area")); pDocAreaItem->setData(0, Qt::UserRole, true); // 是否允许拖拽 pDocAreaItem->setData(0, Qt::UserRole + 1, "DocArea"); pDocAreaItem->setData(0, Qt::UserRole + 2, "DockBottomArea"); pMainWindowItem->addChild(pDocAreaItem); } addTopLevelItem(pMainWindowItem); pMainWindowItem->setExpanded(true); } void DockChildList::slotRemoveWindow() { int iIndex = indexOfTopLevelItem(m_pMenuItem); takeTopLevelItem(iIndex); } void DockChildList::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { QTreeWidgetItem* pItem = dynamic_cast(itemAt(event->pos())); if (NULL == pItem) { QTreeWidget::mousePressEvent(event); return; } m_pCurDragItem = pItem; if (!pItem->data(1, Qt::UserRole).toBool()) { QTreeWidget::mousePressEvent(event); return; } } QTreeWidget::mousePressEvent(event); } void DockChildList::dropEvent(QDropEvent* event) { QTreeWidgetItem* currentItem = this->itemAt(event->pos()); if (currentItem == nullptr) return; else { QString strItemName = currentItem->text(0); QString strType = currentItem->data(0, Qt::UserRole + 1).toString(); if (strType == "MainWindow") { return; } if (strType != "DocTab" && strType != "DocArea" && strType != "CentralWidget") { return; } if (strType == "CentralWidget") { if (currentItem->childCount() > 0) { return; } } QString strDragType = m_pCurDragItem->data(0, Qt::UserRole + 1).toString(); if (strType == strDragType) return; currentItem->addChild(m_pCurDragItem); } QTreeWidget::dropEvent(event); } void DockChildList::contextMenuEvent(QContextMenuEvent* event) { QPoint pos = event->globalPos(); QTreeWidgetItem *pItem = this->itemAt(event->pos()); if (pItem) { m_pMenuItem = pItem; QMenu menu(this); QString strType = pItem->data(0, Qt::UserRole + 1).toString(); if (strType == "DocArea") { QAction* addItemAction = menu.addAction(QString::fromLocal8Bit("添加DocTab")); connect(addItemAction, &QAction::triggered, this, &DockChildList::slotAddTab); } else if (strType == "CentralWidget") { return; } else if (strType == "DocTab") { if (!m_pMenuItem->parent()) return; if (m_pMenuItem->parent()->childCount() < 2) { return; } if (m_pMenuItem->childCount() < 1) { QAction* removeItemAction = menu.addAction(QString::fromLocal8Bit("移除DocTab")); connect(removeItemAction, &QAction::triggered, this, &DockChildList::slotRemoveTab); } int iCurIndex = pItem->parent()->indexOfChild(pItem); if (iCurIndex < 1) { QAction* backItemAction = menu.addAction(QString::fromLocal8Bit("下移")); connect(backItemAction, &QAction::triggered, this, &DockChildList::slotBack); } else if (iCurIndex == pItem->parent()->childCount() - 1) { QAction* frontItemAction = menu.addAction(QString::fromLocal8Bit("上移")); connect(frontItemAction, &QAction::triggered, this, &DockChildList::slotFront); } else { QAction* frontItemAction = menu.addAction(QString::fromLocal8Bit("上移")); connect(frontItemAction, &QAction::triggered, this, &DockChildList::slotFront); QAction* backItemAction = menu.addAction(QString::fromLocal8Bit("下移")); connect(backItemAction, &QAction::triggered, this, &DockChildList::slotBack); } } else if (strType == "MainWindow") { for (int i = 0; i < m_pMenuItem->childCount(); i++) // docArea { if ("Widget" == m_pMenuItem->child(i)->data(0, Qt::UserRole + 1).toString()) // widget { return; } else // doctab { if (m_pMenuItem->child(i)->childCount() > 0) { return; } } } QAction* addMainWindowAction = menu.addAction(tr("delete Window")); connect(addMainWindowAction, &QAction::triggered, this, &DockChildList::slotRemoveWindow); } else { if (!m_pMenuItem->parent()) return; if (m_pMenuItem->parent()->childCount() < 2) { return; } int iCurIndex = pItem->parent()->indexOfChild(pItem); if (iCurIndex < 1) { QAction* backItemAction = menu.addAction(tr("Move down")); // 下移 connect(backItemAction, &QAction::triggered, this, &DockChildList::slotBack); } else if (iCurIndex == pItem->parent()->childCount() - 1) { QAction* frontItemAction = menu.addAction(tr("Move up")); // 上移 connect(frontItemAction, &QAction::triggered, this, &DockChildList::slotFront); } else { QAction* frontItemAction = menu.addAction(tr("Move up")); // 上移 connect(frontItemAction, &QAction::triggered, this, &DockChildList::slotFront); QAction* backItemAction = menu.addAction(tr("Move down")); // 下移 connect(backItemAction, &QAction::triggered, this, &DockChildList::slotBack); } } menu.exec(pos); } else { QMenu menu(this); QAction* addMainWindowAction = menu.addAction(tr("add window")); connect(addMainWindowAction, &QAction::triggered, this, &DockChildList::slotAddWindow); menu.exec(pos); } QTreeWidget::contextMenuEvent(event); }