玉兔远程控制 0.1.0-bate6
载入中...
搜索中...
未找到
FavoriteView.cpp
1// Author: Kang Lin <kl222@126.com>
2
3#include <QFileDialog>
4#include <QToolBar>
5#include <QMouseEvent>
6#include <QDrag>
7#include <QMimeData>
8#include <QApplication>
9#include <QHeaderView>
10#include <QSettings>
11#include <QSettings>
12#include <QMenu>
13#include <QAction>
14#include <QInputDialog>
15#include <QMessageBox>
16#include <QDir>
17#include <QLoggingCategory>
18#include <QVBoxLayout>
19
20#include "RabbitCommonDir.h"
21#include "FavoriteMimeData.h"
22#include "TitleBar.h"
23#include "FavoriteView.h"
24
25static Q_LOGGING_CATEGORY(log, "Favorite")
26
27CFavoriteView::CFavoriteView(CParameterApp *pPara, QWidget *parent)
28 : QWidget(parent)
29 , m_pParaApp(pPara)
30 , m_pDockTitleBar(nullptr)
31 , m_pTreeView(nullptr)
32 , m_pModel(nullptr)
33 , m_pDatabase(nullptr)
34 , m_pStartAction(nullptr)
35 , m_pEidtStartAction(nullptr)
36 , m_pAddFolderAction(nullptr)
37 , m_pEditAction(nullptr)
38 , m_pDeleteAction(nullptr)
39 , m_pImportAction(nullptr)
40 , m_pExportAction(nullptr)
41 , m_pRefresh(nullptr)
42 , m_pShowToolbar(nullptr)
43 , m_pMenu(nullptr)
44{
45 bool check = false;
46
47 setWindowTitle(tr("Favorite"));
48
49 m_pDockTitleBar = new RabbitCommon::CTitleBar(parent);
50 // Create tools pushbutton in title bar
51 m_pMenu = new QMenu(tr("Tools"), m_pDockTitleBar);
52 check = connect(m_pMenu, SIGNAL(aboutToShow()), this, SLOT(slotMenu()));
53 Q_ASSERT(check);
54 QPushButton* pTools = m_pDockTitleBar->CreateSmallPushButton(
55 QIcon::fromTheme("tools"), m_pDockTitleBar);
56 pTools->setToolTip(tr("Tools"));
57 pTools->setMenu(m_pMenu);
58 QList<QWidget*> lstWidget;
59 lstWidget << pTools;
60 m_pDockTitleBar->AddWidgets(lstWidget);
61
62 setupUI();
63}
64
65CFavoriteView::~CFavoriteView()
66{
67 if(m_pDatabase) {
68 delete m_pDatabase;
69 m_pDatabase = nullptr;
70 }
71}
72
73void CFavoriteView::setupUI()
74{
75 QVBoxLayout *pMainLayout = new QVBoxLayout(this);
76 if(!pMainLayout) return;
77
78 setupToolBar(pMainLayout);
79
80 setupTreeView(pMainLayout);
81}
82
83void CFavoriteView::setupToolBar(QLayout *layout)
84{
85 if(!layout) return;
86 bool check = false;
87 QToolBar* pToolBar = new QToolBar(this);
88 if(!pToolBar) return;
89 layout->addWidget(pToolBar);
90
91 m_pShowToolbar = new QAction(tr("Show tool bar"), this);
92 m_pShowToolbar->setCheckable(true);
93 m_pShowToolbar->setChecked(m_pParaApp->GetDockListFavoriteShowToolBar());
94 pToolBar->setVisible(m_pShowToolbar->isChecked());
95 check = connect(m_pShowToolbar, &QAction::triggered, this, [&, pToolBar]() {
96 if(m_pShowToolbar && m_pParaApp) {
97 pToolBar->setVisible(m_pShowToolbar->isChecked());
98 m_pParaApp->SetDockListFovoriteShowToolBar(m_pShowToolbar->isChecked());
99 m_pParaApp->Save();
100 }
101 });
102 Q_ASSERT(check);
103
104 m_pStartAction = pToolBar->addAction(
105 QIcon::fromTheme("media-playback-start"), tr("Start"));
106 if(m_pStartAction) {
107 m_pStartAction->setToolTip(m_pStartAction->text());
108 m_pStartAction->setStatusTip(m_pStartAction->text());
109 check = connect(m_pStartAction, &QAction::triggered,
110 this, &CFavoriteView::slotStart);
111 Q_ASSERT(check);
112 }
113
114 m_pEidtStartAction = pToolBar->addAction(
115 QIcon::fromTheme("system-settings"), tr("Open settings and Start"));
116 if(m_pEidtStartAction) {
117 m_pEidtStartAction->setToolTip(m_pEidtStartAction->text());
118 m_pEidtStartAction->setStatusTip(m_pEidtStartAction->text());
119 check = connect(m_pEidtStartAction, &QAction::triggered,
120 this, &CFavoriteView::slotOpenStart);
121 Q_ASSERT(check);
122 }
123
124 pToolBar->addSeparator();
125
126 m_pAddFolderAction = pToolBar->addAction(
127 QIcon::fromTheme("folder-new"), tr("New group"));
128 if(m_pAddFolderAction) {
129 m_pAddFolderAction->setToolTip(m_pAddFolderAction->text());
130 m_pAddFolderAction->setStatusTip(m_pAddFolderAction->text());
131 check = connect(m_pAddFolderAction, &QAction::triggered,
132 this, &CFavoriteView::slotNewGroup);
133 Q_ASSERT(check);
134 }
135
136 m_pEditAction = pToolBar->addAction(QIcon::fromTheme("edit"), tr("Edit"));
137 if(m_pEditAction) {
138 m_pEditAction->setToolTip(m_pEditAction->text());
139 m_pEditAction->setStatusTip(m_pEditAction->text());
140 check = connect(m_pEditAction, &QAction::triggered,
141 this, &CFavoriteView::slotEdit);
142 Q_ASSERT(check);
143 }
144
145 m_pDeleteAction = pToolBar->addAction(QIcon::fromTheme("edit-delete"), tr("Delete"));
146 if(m_pDeleteAction) {
147 m_pDeleteAction->setToolTip(m_pDeleteAction->text());
148 m_pDeleteAction->setStatusTip(m_pDeleteAction->text());
149 check = connect(m_pDeleteAction, &QAction::triggered, this, &CFavoriteView::slotDelete);
150 Q_ASSERT(check);
151 }
152
153 pToolBar->addSeparator();
154
155 m_pImportAction = pToolBar->addAction(QIcon::fromTheme("import"), tr("Import"));
156 if(m_pImportAction) {
157 m_pImportAction->setToolTip(m_pImportAction->text());
158 m_pImportAction->setStatusTip(m_pImportAction->text());
159 check = connect(m_pImportAction, &QAction::triggered, this, &CFavoriteView::slotImport);
160 Q_ASSERT(check);
161 }
162
163 m_pExportAction = pToolBar->addAction(QIcon::fromTheme("export"), tr("Export"));
164 if(m_pExportAction) {
165 m_pExportAction->setToolTip(m_pExportAction->text());
166 m_pExportAction->setStatusTip(m_pExportAction->text());
167 check = connect(m_pExportAction, &QAction::triggered, this, &CFavoriteView::slotExport);
168 Q_ASSERT(check);
169 }
170
171 pToolBar->addSeparator();
172 m_pRefresh = pToolBar->addAction(QIcon::fromTheme("view-refresh"), tr("Refresh"), this, [&](){
173 if(m_pModel)
174 m_pModel->Refresh();
175 });
176}
177
178void CFavoriteView::setupTreeView(QLayout *layout)
179{
180 if(!layout) return;
181 m_pTreeView = new QTreeView(this);
182 if(!m_pTreeView)
183 return;
184 layout->addWidget(m_pTreeView);
185
186 m_pTreeView->setAcceptDrops(true);
187 m_pTreeView->setUniformRowHeights(true);
188 m_pTreeView->setHeaderHidden(true);
189
190 //m_pTreeView->setExpandsOnDoubleClick(true);
191 // 如果需要自动展开第一层
192 //m_pTreeView->expandAll(); // 或者根据需要展开特定节点
193 //m_pTreeView->expandToDepth(1);
194
195 m_pTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
196 bool check = connect(m_pTreeView,
197 SIGNAL(customContextMenuRequested(const QPoint &)),
198 this, SLOT(slotCustomContextMenu(const QPoint &)));
199 Q_ASSERT(check);
200 check = connect(m_pTreeView, SIGNAL(clicked(const QModelIndex&)),
201 this, SLOT(slotFavrtieClicked(const QModelIndex&)));
202 Q_ASSERT(check);
203 check = connect(m_pTreeView, SIGNAL(doubleClicked(const QModelIndex&)),
204 this, SLOT(slotFavortiedoubleClicked(const QModelIndex&)));
205 Q_ASSERT(check);
206
207 //m_pTreeView->installEventFilter(this);
208}
209
210void CFavoriteView::Initial()
211{
212 m_pDatabase = new CFavoriteDatabase(this);
213 if(m_pDatabase)
214 m_pDatabase->OpenDatabase(m_pParaApp->m_pDatabase);
215 if(m_pDatabase) {
216 m_pModel = new CFavoriteModel(m_pDatabase, this);
217 m_pTreeView->setModel(m_pModel);
218 }
219
220 EnableAction();
221}
222
223void CFavoriteView::EnableAction(const QModelIndex &index)
224{
225 if(!m_pModel) return;
226 if(index.isValid()) {
228 m_pModel->data(index, CFavoriteModel::RoleItem)
229 .value<CFavoriteDatabase::Item>();
230 if(item.isFavorite()) {
231 m_pStartAction->setEnabled(true);
232 m_pEidtStartAction->setEnabled(true);
233 } else {
234 m_pStartAction->setEnabled(false);
235 m_pEidtStartAction->setEnabled(false);
236 }
237 m_pEditAction->setEnabled(true);
238 m_pDeleteAction->setEnabled(true);
239 return;
240 }
241
242 if(m_pStartAction)
243 m_pStartAction->setEnabled(false);
244 if(m_pEidtStartAction)
245 m_pEidtStartAction->setEnabled(false);
246 if(m_pEditAction)
247 m_pEditAction->setEnabled(false);
248 if(m_pDeleteAction)
249 m_pDeleteAction->setEnabled(false);
250}
251
252void CFavoriteView::slotAddToFavorite(const QString &szFile,
253 const QString &szName,
254 const QString &szDescription,
255 const QIcon &icon
256 )
257{
258 if(!m_pModel || !m_pTreeView) return;
259
260 int parentId = 0;
261 QString szGroup = tr("Root");
262 auto indexes = m_pTreeView->selectionModel()->selectedIndexes();
263 if(!indexes.isEmpty())
264 {
265 QModelIndex idx = indexes.at(0);
266 while (idx.isValid()) {
268 m_pModel->data(idx, CFavoriteModel::RoleItem).value<CFavoriteDatabase::Item>();
269 if(item.isFolder() && item.id > 0) {
270 parentId = item.id;
271 szGroup = item.szName;
272 break;
273 }
274 idx = idx.parent();
275 }
276 }
277 // Check if it already exists
278 auto item = m_pModel->GetFavorite(szFile);
279 if(item.id > 0) {
280 if(item.parentId == parentId) {
281 QMessageBox::information(
282 nullptr, tr("Add favorite"),
283 tr("\"%1\" already exists in \"%2\"").arg(szName, szGroup));
284 return;
285 }
286 int ret = QMessageBox::warning(
287 nullptr, tr("Add favorite"),
288 tr("\"%1\" already exists, do you want to move it to \"%2\"?").arg(szName, szGroup),
289 QMessageBox::Ok | QMessageBox::No);
290 if(QMessageBox::Ok != ret)
291 return;
292 }
293
294 m_pModel->AddFavorite(szFile, szName, icon, szDescription, parentId);
295
296 return;
297}
298
299void CFavoriteView::slotUpdateFavorite(
300 const QString &szFile, const QString &szName,
301 const QString &szDescription, const QIcon &icon)
302{
303 if(!m_pModel || !m_pTreeView || szFile.isEmpty()) return;
304 m_pModel->UpdateFavorite(szFile, szName, szDescription, icon);
305}
306
307void CFavoriteView::slotFavrtieClicked(const QModelIndex &index)
308{
309 EnableAction(index);
310}
311
312void CFavoriteView::slotFavortiedoubleClicked(const QModelIndex &index)
313{
314 if(!index.isValid()) return;
315 if(m_pTreeView->editTriggers() != QTreeView::NoEditTriggers)
316 return;
317 QString szFile = m_pModel->data(index, CFavoriteModel::RoleFile).toString();
318 if(!szFile.isEmpty())
319 emit sigStart(szFile, false);
320}
321
322void CFavoriteView::slotDoubleEditNode(bool bEdit)
323{
324 if(bEdit)
325 m_pTreeView->setEditTriggers(QTreeView::DoubleClicked);
326 else
327 m_pTreeView->setEditTriggers(QTreeView::NoEditTriggers);
328}
329
330void CFavoriteView::slotMenu()
331{
332 if(!m_pTreeView)
333 return;
334
335 m_pMenu->clear();
336 m_pMenu->addAction(m_pStartAction);
337 m_pMenu->addAction(m_pEidtStartAction);
338
339 m_pMenu->addSeparator();
340 m_pMenu->addAction(m_pAddFolderAction);
341 m_pMenu->addAction(m_pEditAction);
342 m_pMenu->addAction(m_pDeleteAction);
343
344 m_pMenu->addSeparator();
345 m_pMenu->addAction(m_pImportAction);
346 m_pMenu->addAction(m_pExportAction);
347
348 m_pMenu->addSeparator();
349 m_pMenu->addAction(m_pRefresh);
350
351 m_pMenu->addSeparator();
352 m_pMenu->addAction(m_pShowToolbar);
353}
354
355void CFavoriteView::slotCustomContextMenu(const QPoint &pos)
356{
357 slotMenu();
358 m_pMenu->exec(m_pTreeView->mapToGlobal(pos));
359}
360
361void CFavoriteView::slotStart()
362{
363 auto lstIndex = m_pTreeView->selectionModel()->selectedIndexes();
364 foreach(auto index, lstIndex)
365 {
366 QString szFile = m_pModel->data(index, CFavoriteModel::RoleFile).toString();
367 if(!szFile.isEmpty())
368 emit sigStart(szFile, false);
369 }
370}
371
372void CFavoriteView::slotOpenStart()
373{
374 auto lstIndex = m_pTreeView->selectionModel()->selectedIndexes();
375 foreach(auto index, lstIndex)
376 {
377 QString szFile = m_pModel->data(index, CFavoriteModel::RoleFile).toString();
378 if(!szFile.isEmpty())
379 emit sigStart(szFile, true);
380 }
381}
382
383void CFavoriteView::slotEdit()
384{
385 auto lstIndex = m_pTreeView->selectionModel()->selectedIndexes();
386 foreach(auto index, lstIndex)
387 {
388 QString szName = m_pModel->data(index).toString();
389 szName = QInputDialog::getText(
390 this, tr("Edit"), tr("Enter the modified name"), QLineEdit::Normal, szName);
391 if(szName.isEmpty())
392 return;
393 m_pModel->setData(index, szName);
394 }
395}
396
397void CFavoriteView::slotDelete()
398{
399 auto lstIndex = m_pTreeView->selectionModel()->selectedIndexes();
400 if(1 == lstIndex.size()) {
402 m_pModel->data(lstIndex.at(0), CFavoriteModel::RoleItem)
403 .value<CFavoriteDatabase::Item>();
404 if(0 < item.id) {
405 int ret = QMessageBox::warning(
406 nullptr, tr("Delete"), tr("Will be delete \"%1\"").arg(item.szName),
407 QMessageBox::Ok|QMessageBox::No);
408 if(QMessageBox::Ok != ret)
409 return;
410 }
411 }
412 foreach(auto index, lstIndex)
413 m_pModel->removeRow(index.row(), index.parent());
414}
415
416void CFavoriteView::slotNewGroup()
417{
418 if(!m_pModel) return;
419 QString szGroup = QInputDialog::getText(
420 this, tr("New group"), tr("Input group name"));
421 if(szGroup.isEmpty()) return;
422
423 int parentId = 0;
424 auto lstIndex = m_pTreeView->selectionModel()->selectedIndexes();
425 if(!lstIndex.isEmpty())
426 {
428 m_pModel->data(lstIndex.at(0), CFavoriteModel::RoleItem)
429 .value<CFavoriteDatabase::Item>();
430 if(0 < item.id && item.isFolder())
431 parentId = item.id;
432 }
433
434 m_pModel->AddNode(szGroup, parentId);
435}
436
437void CFavoriteView::slotRefresh()
438{
439 if(m_pModel)
440 m_pModel->Refresh();
441}
442
443void CFavoriteView::slotImport()
444{
445 QString filename = QFileDialog::getOpenFileName(
446 this, tr("Import favorite"),
447 RabbitCommon::CDir::Instance()->GetDirUserDocument(),
448 tr("JSON (*.json)"));
449
450 if (!filename.isEmpty()) {
451 QFileInfo fi(filename);
452 if(0 == fi.suffix().compare("json", Qt::CaseInsensitive)) {
453 if (m_pDatabase->ImportFromJsonFile(filename)) {
454 slotRefresh();
455 QMessageBox::information(
456 this, tr("Success"),
457 tr("Successfully imported favorite from json file"));
458 } else {
459 QMessageBox::warning(
460 this, tr("Failure"),
461 tr("Failed to import favorite from json file"));
462 }
463 return;
464 }
465 }
466}
467
468void CFavoriteView::slotExport()
469{
470 QString filename = QFileDialog::getSaveFileName(
471 this, tr("Export favorite"),
472 RabbitCommon::CDir::Instance()->GetDirUserDocument(),
473 tr("JSON (*.json)"));
474
475 if (!filename.isEmpty()) {
476 QFileInfo fi(filename);
477 if(0 == fi.suffix().compare("json", Qt::CaseInsensitive)) {
478 if (m_pDatabase->ExportToJsonFile(filename)) {
479 QMessageBox::information(
480 this, tr("Success"),
481 tr("Successfully export favorite to json file"));
482 } else {
483 QMessageBox::warning(
484 this, tr("Failure"),
485 tr("Failed to export favorite to json file"));
486 }
487 return;
488 }
489 }
490}
491
492void CFavoriteView::dragEnterEvent(QDragEnterEvent *event)
493{
494 qDebug(log) << "dragEnterEvent";
495 const CFavoriteMimeData* pData =
496 qobject_cast<const CFavoriteMimeData*>(event->mimeData());
497 if (pData)
498 {
499 qDebug(log) << "dragEnterEvent acceptProposedAction";
500 event->acceptProposedAction();
501 }
502}
503
504void CFavoriteView::dragMoveEvent(QDragMoveEvent *event)
505{
506}
507
508void CFavoriteView::dropEvent(QDropEvent *event)
509{
510 qDebug(log) << "dropEvent";
511 const CFavoriteMimeData *pData = qobject_cast<const CFavoriteMimeData*>(event->mimeData());
512 if(!pData) return;
513 /*
514 QStandardItemModel* pModel = dynamic_cast<QStandardItemModel*>(model());
515 if(!pModel) return;
516#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
517 auto index = indexAt(event->position().toPoint());
518#else
519 auto index = indexAt(event->pos());
520#endif
521 if(index.isValid())
522 {
523 auto item = pModel->itemFromIndex(index);
524 if(item->data().isNull())
525 {
526 foreach(auto i, pData->m_Items)
527 {
528 qDebug(log) << "dropEvent:" << item->text();
529
530 auto newItem = NewItem(i);
531 item->appendRow(newItem);
532 if(event->dropAction() == Qt::MoveAction)
533 pModel->removeRow(i.row(), i.parent());
534 }
535 } else
536 qWarning(log) << "Don't group node. the data:" << item->data();
537 }else{
538 foreach(auto i, pData->m_Items)
539 {
540 pModel->appendRow(NewItem(i));
541 if(event->dropAction() == Qt::MoveAction)
542 pModel->removeRow(i.row(), i.parent());
543 }
544 }
545//*/
546 event->accept();
547}
548/*
549QStandardItem* CFavoriteView::NewItem(const QModelIndex &index)
550{
551 QStandardItemModel* pModel = dynamic_cast<QStandardItemModel*>(model());
552 if(!pModel) return nullptr;
553 auto item = pModel->itemFromIndex(index);
554 if(!item) return nullptr;
555 auto ri = new QStandardItem(item->text());
556 ri->setData(item->data());
557 return ri;
558}
559
560void CFavoriteView::mousePressEvent(QMouseEvent *event)
561{
562 if (event->button() == Qt::LeftButton)
563 m_DragStartPosition = event->pos();
564 QTreeView::mousePressEvent(event);
565}
566
567void CFavoriteView::mouseMoveEvent(QMouseEvent *event)
568{
569 qDebug(log) << "mouseMoveEvent";
570 do{
571 if (!(event->buttons() & Qt::LeftButton))
572 break;
573 if ((event->pos() - m_DragStartPosition).manhattanLength()
574 < QApplication::startDragDistance())
575 break;
576 qDebug(log) << "mouseMoveEvent drag";
577 QDrag *drag = new QDrag(this);
578 CFavoriteMimeData *pData = new CFavoriteMimeData();
579 pData->m_Items = this->selectionModel()->selectedIndexes();
580 drag->setMimeData(pData);
581
582 Qt::DropAction dropAction = Qt::MoveAction;
583 if(event->modifiers() & Qt::ControlModifier)
584 dropAction = Qt::CopyAction;
585 drag->exec(dropAction);
586 } while (false);
587
588 QTreeView::mouseMoveEvent(event);
589}
590//*/
591bool CFavoriteView::eventFilter(QObject *watched, QEvent *event)
592{
593 return QWidget::eventFilter(watched, event);
594}
virtual bool OpenDatabase(CParameterDatabase *pPara=nullptr)
OpenDatabase
Definition Database.cpp:45
virtual int Save(QString szFile=QString(), bool bForce=true)
Save to file
Definition Parameter.cpp:47