1// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
2//
3// SPDX-License-Identifier: GPL-3.0-or-later
4
5#include "naveditmainwindow.h"
6#include "autohidedockwidget.h"
7#include "base/abstractwidget.h"
8#include "base/abstractcentral.h"
9#include "base/abstractconsole.h"
10#include "services/window/windowservice.h"
11#include "services/project/projectservice.h"
12#include "services/symbol/symbolservice.h"
13#include "transceiver/codeeditorreceiver.h"
14#include "common/common.h"
15#include "toolbarmanager.h"
16
17#include <QDebug>
18#include <QDockWidget>
19#include <QEvent>
20#include <QWidget>
21#include <QTabBar>
22
23using namespace dpfservice;
24static NavEditMainWindow *ins{nullptr};
25int findIndex(QTabWidget* tabWidget, const QString &text)
26{
27 for (int index = 0; index < tabWidget->count(); index ++) {
28 if (tabWidget->tabText(index) == text) {
29 return index;
30 }
31 }
32 return -1;
33}
34
35NavEditMainWindow *NavEditMainWindow::instance()
36{
37 if (!ins)
38 ins = new NavEditMainWindow;
39 return ins;
40}
41
42NavEditMainWindow::NavEditMainWindow(QWidget *parent, Qt::WindowFlags flags)
43 : QMainWindow (parent, flags)
44{
45 qInfo() << __FUNCTION__;
46 auto &ctx = dpfInstance.serviceContext();
47 WindowService *windowService = ctx.service<WindowService>(WindowService::name());
48 using namespace std::placeholders;
49 if (!windowService->addToolBarActionItem) {
50 windowService->addToolBarActionItem = std::bind(&NavEditMainWindow::addToolBarActionItem, this, _1, _2, _3);
51 }
52
53 if (!windowService->addToolBarWidgetItem) {
54 windowService->addToolBarWidgetItem = std::bind(&NavEditMainWindow::addToolBarWidgetItem, this, _1, _2, _3);
55 }
56
57 if (!windowService->removeToolBarItem) {
58 windowService->removeToolBarItem = std::bind(&NavEditMainWindow::removeToolBarItem, this, _1);
59 }
60
61 if (!windowService->setToolBarItemDisable) {
62 windowService->setToolBarItemDisable = std::bind(&NavEditMainWindow::setToolBarItemDisable, this, _1, _2);
63 }
64
65 QObject::connect(EditorCallProxy::instance(), &EditorCallProxy::toSwitchContext,
66 this, &NavEditMainWindow::switchWidgetContext);
67
68 QObject::connect(EditorCallProxy::instance(), &EditorCallProxy::toSwitchWorkspace,
69 this, &NavEditMainWindow::switchWidgetWorkspace);
70
71 qDockWidgetContext = new AutoHideDockWidget(QDockWidget::tr("Context"), this);
72 qDockWidgetContext->setFeatures(QDockWidget::DockWidgetMovable);
73 qTabWidgetContext = new QTabWidget(qDockWidgetContext);
74 qTabWidgetContext->setMinimumHeight(100);
75 qDockWidgetContext->setWidget(qTabWidgetContext);
76 addDockWidget(Qt::DockWidgetArea::BottomDockWidgetArea, qDockWidgetContext);
77 mainToolBar = new ToolBarManager(tr("toolbar"));
78 addToolBar(Qt::ToolBarArea::TopToolBarArea, mainToolBar->getToolBar());
79}
80
81NavEditMainWindow::~NavEditMainWindow()
82{
83 qTabWidgetContext->removeTab(findIndex(qTabWidgetContext, dpfservice::CONSOLE_TAB_TEXT));
84 qInfo() << __FUNCTION__;
85}
86
87QStringList NavEditMainWindow::contextWidgetTitles() const
88{
89 QStringList result;
90 for (int index = 0; index < qTabWidgetContext->count(); index ++) {
91 result<< qTabWidgetContext->tabText(index);
92 }
93 return result;
94}
95
96void NavEditMainWindow::addWidgetWorkspace(const QString &title, AbstractWidget *treeWidget)
97{
98 if (!qDockWidgetWorkspace) {
99 qTabWidgetWorkspace = new QTabWidget();
100 QFont font = qTabWidgetWorkspace->font();
101 font.setItalic(true);
102 qTabWidgetWorkspace->setFont(font);
103 qTabWidgetWorkspace->setMinimumHeight(300);
104 qTabWidgetWorkspace->setTabPosition(QTabWidget::West);
105 qDockWidgetWorkspace = new AutoHideDockWidget(QDockWidget::tr("Workspace"), this);
106 qDockWidgetWorkspace->setFeatures(QDockWidget::DockWidgetMovable);
107 qDockWidgetWorkspace->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
108 addDockWidget(Qt::DockWidgetArea::LeftDockWidgetArea, qDockWidgetWorkspace);
109 qDockWidgetWorkspace->setWidget(qTabWidgetWorkspace);
110 }
111
112 if (qTabWidgetWorkspace) {
113 auto qTreeWidget = static_cast<QWidget*>(treeWidget->qWidget());
114 qTabWidgetWorkspace->addTab(qTreeWidget, title);
115 }
116 adjustWorkspaceItemOrder();
117}
118
119QWidget *NavEditMainWindow::setWidgetEdit(AbstractCentral *editWidget)
120{
121 QWidget *oldWidget = qWidgetEdit;
122 qWidgetEdit = static_cast<QWidget*>(editWidget->qWidget());
123 // avoid be deleted when setCentralWidget.
124 if (oldWidget) {
125 oldWidget->setParent(nullptr);
126 }
127 setCentralWidget(qWidgetEdit);
128 if (oldWidget) {
129 oldWidget->setParent(this);
130 }
131 return oldWidget;
132}
133
134QWidget *NavEditMainWindow::setWidgetWatch(AbstractWidget *watchWidget)
135{
136 if (!qDockWidgetWatch) {
137 qDockWidgetWatch = new AutoHideDockWidget(QDockWidget::tr("Watcher"), this);
138 qDockWidgetWatch->setFeatures(QDockWidget::AllDockWidgetFeatures);
139 qDockWidgetWatch->hide();
140 addDockWidget(Qt::DockWidgetArea::RightDockWidgetArea, qDockWidgetWatch);
141 }
142 QWidget *oldWidget = qWidgetWatch;
143 qWidgetWatch = static_cast<QWidget*>(watchWidget->qWidget());
144 qWidgetWatch->setParent(qDockWidgetWatch);
145 // avoid be deleted when setWidget.
146 if (oldWidget) {
147 oldWidget->setParent(nullptr);
148 }
149 qDockWidgetWatch->setWidget(qWidgetWatch);
150 if (oldWidget) {
151 oldWidget->setParent(qDockWidgetWatch);
152 }
153 qDockWidgetWatch->hide();
154 qWidgetWatch->hide();
155 return oldWidget;
156}
157
158void NavEditMainWindow::addContextWidget(const QString &title, AbstractWidget *contextWidget, const QString &group)
159{
160 QMutexLocker locker(&mutex);
161 QWidget *qWidget = static_cast<QWidget*>(contextWidget->qWidget());
162 if (!qWidget || !qTabWidgetContext || group.isEmpty()) {
163 return;
164 }
165
166 int index = 0;
167 if (!contextList.contains(group)) {
168 for (int i = 0; i < contextList.size(); i++) {
169 const QString &temp = contextList.at(i);
170 if (QString::compare(group, temp) < 0) {
171 break;
172 } else {
173 index++;
174 }
175 }
176 } else {
177 index = contextList.indexOf(group, 0);
178 for (; index < contextList.size(); index++) {
179 if (contextList.at(index) != group) {
180 break;
181 }
182 }
183 }
184 contextList.insert(index, group);
185 qTabWidgetContext->insertTab(index, qWidget, title);
186}
187
188void NavEditMainWindow::removeContextWidget(AbstractWidget *contextWidget)
189{
190 QWidget *qWidget = static_cast<QWidget*>(contextWidget->qWidget());
191 if (!qWidget || !qTabWidgetContext)
192 return;
193
194 int index = qTabWidgetContext->indexOf(qWidget);
195 qTabWidgetContext->removeTab(index);
196}
197
198bool NavEditMainWindow::switchWidgetWorkspace(const QString &title)
199{
200 for (int i = 0; i < qTabWidgetWorkspace->count(); i++) {
201 if (qTabWidgetWorkspace->tabText(i) == title) {
202 qTabWidgetWorkspace->setCurrentIndex(i);
203 return true;
204 }
205 }
206 return false;
207}
208
209bool NavEditMainWindow::switchWidgetContext(const QString &title)
210{
211 for (int i = 0; i < qTabWidgetContext->count(); i++){
212 if (qTabWidgetContext->tabText(i) == title) {
213 qTabWidgetContext->setCurrentIndex(i);
214 return true;
215 }
216 }
217 return false;
218}
219
220bool NavEditMainWindow::switchWidgetTools(const QString &title)
221{
222 for (int i = 0; i < qTabWidgetTools->count(); i++) {
223 if (qTabWidgetTools->tabText(i) == title) {
224 qTabWidgetTools->setCurrentIndex(i);
225 return true;
226 }
227 }
228 return false;
229}
230
231void NavEditMainWindow::addFindToolBar(AbstractWidget *findToolbar)
232{
233 if (!findToolbar)
234 return;
235
236 if (!qDockWidgetFindToolBar) {
237 qDockWidgetFindToolBar = new AutoHideDockWidget(QDockWidget::tr("Find ToolBar"), this);
238 addDockWidget(Qt::DockWidgetArea::TopDockWidgetArea, qDockWidgetFindToolBar);
239 QWidget *widget = static_cast<QWidget*>(findToolbar->qWidget());
240 qDockWidgetFindToolBar->setWidget(widget);
241 qDockWidgetFindToolBar->hide();
242 }
243}
244
245void NavEditMainWindow::showFindToolBar()
246{
247 if (qDockWidgetFindToolBar) {
248 if (qDockWidgetFindToolBar->isVisible()) {
249 qDockWidgetFindToolBar->hide();
250 } else {
251 qDockWidgetFindToolBar->show();
252 }
253 }
254}
255
256void NavEditMainWindow::addValgrindBar(AbstractWidget *valgrindbar)
257{
258 if (!valgrindbar)
259 return;
260
261 if (!qDockWidgetValgrindBar) {
262 qDockWidgetValgrindBar = new AutoHideDockWidget(QDockWidget::tr("Valgrind"), this);
263 addDockWidget(Qt::DockWidgetArea::TopDockWidgetArea, qDockWidgetValgrindBar);
264 QWidget *widget = static_cast<QWidget*>(valgrindbar->qWidget());
265 qDockWidgetValgrindBar->setWidget(widget);
266 qDockWidgetValgrindBar->hide();
267 }
268}
269
270void NavEditMainWindow::showValgrindBar()
271{
272 if (qDockWidgetValgrindBar) {
273 if (qDockWidgetValgrindBar->isVisible()) {
274 qDockWidgetValgrindBar->hide();
275 } else {
276 qDockWidgetValgrindBar->show();
277 }
278 }
279}
280
281bool NavEditMainWindow::addToolBarActionItem(const QString &id, QAction *action, const QString &group)
282{
283 QMutexLocker locker(&mutex);
284 if (!mainToolBar)
285 return false;
286
287 return mainToolBar->addActionItem(id, action, group);
288}
289
290bool NavEditMainWindow::addToolBarWidgetItem(const QString &id, AbstractWidget *widget, const QString &group)
291{
292 QMutexLocker locker(&mutex);
293 if (!mainToolBar)
294 return false;
295
296 return mainToolBar->addWidgetItem(id, static_cast<QWidget*>(widget->qWidget()), group);
297}
298
299void NavEditMainWindow::removeToolBarItem(const QString &id)
300{
301 if (mainToolBar)
302 mainToolBar->removeItem(id);
303}
304
305void NavEditMainWindow::setToolBarItemDisable(const QString &id, bool disable)
306{
307 if (mainToolBar)
308 mainToolBar->disableItem(id, disable);
309}
310
311void NavEditMainWindow::adjustWorkspaceItemOrder()
312{
313 auto tabBar = qTabWidgetWorkspace->tabBar();
314 for (int i = 0; i < tabBar->count(); i++) {
315 if(tabBar->tabText(i) == MWCWT_PROJECTS)
316 tabBar->moveTab(i, 0);
317 if (tabBar->tabText(i) == MWCWT_SYMBOL)
318 tabBar->moveTab(i, 1);
319 }
320}
321