vdirectorytree.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665
  1. #include <QtWidgets>
  2. #include "vdirectorytree.h"
  3. #include "dialog/vnewdirdialog.h"
  4. #include "vconfigmanager.h"
  5. #include "dialog/vdirinfodialog.h"
  6. #include "vnote.h"
  7. #include "vdirectory.h"
  8. #include "utils/vutils.h"
  9. #include "veditarea.h"
  10. VDirectoryTree::VDirectoryTree(VNote *vnote, QWidget *parent)
  11. : QTreeWidget(parent), vnote(vnote), m_editArea(NULL)
  12. {
  13. setColumnCount(1);
  14. setHeaderHidden(true);
  15. setContextMenuPolicy(Qt::CustomContextMenu);
  16. initActions();
  17. connect(this, SIGNAL(itemExpanded(QTreeWidgetItem*)),
  18. this, SLOT(handleItemExpanded(QTreeWidgetItem*)));
  19. connect(this, SIGNAL(itemCollapsed(QTreeWidgetItem*)),
  20. this, SLOT(handleItemCollapsed(QTreeWidgetItem*)));
  21. connect(this, SIGNAL(customContextMenuRequested(QPoint)),
  22. this, SLOT(contextMenuRequested(QPoint)));
  23. connect(this, &VDirectoryTree::currentItemChanged,
  24. this, &VDirectoryTree::currentDirectoryItemChanged);
  25. }
  26. void VDirectoryTree::initActions()
  27. {
  28. newRootDirAct = new QAction(QIcon(":/resources/icons/create_rootdir.svg"),
  29. tr("New &Root Directory"), this);
  30. newRootDirAct->setStatusTip(tr("Create a new root directory in current notebook"));
  31. connect(newRootDirAct, &QAction::triggered,
  32. this, &VDirectoryTree::newRootDirectory);
  33. newSubDirAct = new QAction(tr("&New Sub-Directory"), this);
  34. newSubDirAct->setStatusTip(tr("Create a new sub-directory"));
  35. connect(newSubDirAct, &QAction::triggered,
  36. this, &VDirectoryTree::newSubDirectory);
  37. deleteDirAct = new QAction(QIcon(":/resources/icons/delete_dir.svg"),
  38. tr("&Delete"), this);
  39. deleteDirAct->setStatusTip(tr("Delete selected directory"));
  40. connect(deleteDirAct, &QAction::triggered,
  41. this, &VDirectoryTree::deleteDirectory);
  42. dirInfoAct = new QAction(QIcon(":/resources/icons/dir_info.svg"),
  43. tr("&Info"), this);
  44. dirInfoAct->setStatusTip(tr("View and edit current directory's information"));
  45. connect(dirInfoAct, &QAction::triggered,
  46. this, &VDirectoryTree::editDirectoryInfo);
  47. copyAct = new QAction(QIcon(":/resources/icons/copy.svg"),
  48. tr("&Copy"), this);
  49. copyAct->setStatusTip(tr("Copy selected directories"));
  50. connect(copyAct, &QAction::triggered,
  51. this, &VDirectoryTree::copySelectedDirectories);
  52. cutAct = new QAction(QIcon(":/resources/icons/cut.svg"),
  53. tr("&Cut"), this);
  54. cutAct->setStatusTip(tr("Cut selected directories"));
  55. connect(cutAct, &QAction::triggered,
  56. this, &VDirectoryTree::cutSelectedDirectories);
  57. pasteAct = new QAction(QIcon(":/resources/icons/paste.svg"),
  58. tr("&Paste"), this);
  59. pasteAct->setStatusTip(tr("Paste directories"));
  60. connect(pasteAct, &QAction::triggered,
  61. this, &VDirectoryTree::pasteDirectoriesInCurDir);
  62. }
  63. void VDirectoryTree::setNotebook(VNotebook *p_notebook)
  64. {
  65. if (m_notebook == p_notebook) {
  66. return;
  67. }
  68. if (m_notebook) {
  69. // Disconnect
  70. disconnect((VNotebook *)m_notebook, &VNotebook::contentChanged,
  71. this, &VDirectoryTree::updateDirectoryTree);
  72. }
  73. m_notebook = p_notebook;
  74. if (m_notebook) {
  75. connect((VNotebook *)m_notebook, &VNotebook::contentChanged,
  76. this, &VDirectoryTree::updateDirectoryTree);
  77. } else {
  78. clear();
  79. return;
  80. }
  81. if (!m_notebook->open()) {
  82. VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
  83. QString("Failed to open notebook %1").arg(m_notebook->getName()), "",
  84. QMessageBox::Ok, QMessageBox::Ok, this);
  85. clear();
  86. return;
  87. }
  88. updateDirectoryTree();
  89. }
  90. void VDirectoryTree::fillTreeItem(QTreeWidgetItem &p_item, const QString &p_name,
  91. VDirectory *p_directory, const QIcon &p_icon)
  92. {
  93. p_item.setText(0, p_name);
  94. p_item.setData(0, Qt::UserRole, QVariant::fromValue(p_directory));
  95. p_item.setIcon(0, p_icon);
  96. }
  97. void VDirectoryTree::updateDirectoryTree()
  98. {
  99. clear();
  100. VDirectory *rootDir = m_notebook->getRootDir();
  101. const QVector<VDirectory *> &subDirs = rootDir->getSubDirs();
  102. for (int i = 0; i < subDirs.size(); ++i) {
  103. VDirectory *dir = subDirs[i];
  104. QTreeWidgetItem *item = new QTreeWidgetItem(this);
  105. fillTreeItem(*item, dir->getName(), dir,
  106. QIcon(":/resources/icons/dir_item.svg"));
  107. updateDirectoryTreeOne(item, 1);
  108. }
  109. setCurrentItem(topLevelItem(0));
  110. }
  111. void VDirectoryTree::updateDirectoryTreeOne(QTreeWidgetItem *p_parent, int depth)
  112. {
  113. Q_ASSERT(p_parent->childCount() == 0);
  114. if (depth <= 0) {
  115. return;
  116. }
  117. VDirectory *dir = getVDirectory(p_parent);
  118. if (!dir->open()) {
  119. VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
  120. QString("Failed to open directory %1").arg(dir->getName()), "",
  121. QMessageBox::Ok, QMessageBox::Ok, this);
  122. return;
  123. }
  124. const QVector<VDirectory *> &subDirs = dir->getSubDirs();
  125. for (int i = 0; i < subDirs.size(); ++i) {
  126. VDirectory *subDir = subDirs[i];
  127. QTreeWidgetItem *item = new QTreeWidgetItem(p_parent);
  128. fillTreeItem(*item, subDir->getName(), subDir,
  129. QIcon(":/resources/icons/dir_item.svg"));
  130. updateDirectoryTreeOne(item, depth - 1);
  131. }
  132. if (dir->isExpanded()) {
  133. expandItem(p_parent);
  134. }
  135. }
  136. void VDirectoryTree::handleItemCollapsed(QTreeWidgetItem *p_item)
  137. {
  138. VDirectory *dir = getVDirectory(p_item);
  139. dir->setExpanded(false);
  140. }
  141. void VDirectoryTree::handleItemExpanded(QTreeWidgetItem *p_item)
  142. {
  143. updateChildren(p_item);
  144. VDirectory *dir = getVDirectory(p_item);
  145. dir->setExpanded(true);
  146. }
  147. // Update @p_item's children items
  148. void VDirectoryTree::updateChildren(QTreeWidgetItem *p_item)
  149. {
  150. Q_ASSERT(p_item);
  151. int nrChild = p_item->childCount();
  152. if (nrChild == 0) {
  153. return;
  154. }
  155. for (int i = 0; i < nrChild; ++i) {
  156. QTreeWidgetItem *childItem = p_item->child(i);
  157. if (childItem->childCount() > 0) {
  158. continue;
  159. }
  160. updateDirectoryTreeOne(childItem, 1);
  161. }
  162. }
  163. void VDirectoryTree::updateItemChildren(QTreeWidgetItem *p_item)
  164. {
  165. QPointer<VDirectory> parentDir;
  166. if (p_item) {
  167. parentDir = getVDirectory(p_item);
  168. } else {
  169. parentDir = m_notebook->getRootDir();
  170. }
  171. const QVector<VDirectory *> &dirs = parentDir->getSubDirs();
  172. QHash<VDirectory *, QTreeWidgetItem *> itemDirMap;
  173. int nrChild = p_item ? p_item->childCount() : topLevelItemCount();
  174. for (int i = 0; i < nrChild; ++i) {
  175. QTreeWidgetItem *item = p_item ? p_item->child(i) : topLevelItem(i);
  176. itemDirMap.insert(getVDirectory(item), item);
  177. }
  178. for (int i = 0; i < dirs.size(); ++i) {
  179. VDirectory *dir = dirs[i];
  180. QTreeWidgetItem *item = itemDirMap.value(dir, NULL);
  181. if (item) {
  182. if (p_item) {
  183. p_item->removeChild(item);
  184. p_item->insertChild(i, item);
  185. } else {
  186. int topIdx = indexOfTopLevelItem(item);
  187. takeTopLevelItem(topIdx);
  188. insertTopLevelItem(i, item);
  189. }
  190. itemDirMap.remove(dir);
  191. } else {
  192. // Insert a new item
  193. if (p_item) {
  194. item = new QTreeWidgetItem(p_item);
  195. } else {
  196. item = new QTreeWidgetItem(this);
  197. }
  198. fillTreeItem(*item, dir->getName(), dir, QIcon(":/resources/icons/dir_item.svg"));
  199. updateDirectoryTreeOne(item, 1);
  200. }
  201. expandItemTree(item);
  202. }
  203. // Delete items without corresponding VDirectory
  204. for (auto iter = itemDirMap.begin(); iter != itemDirMap.end(); ++iter) {
  205. QTreeWidgetItem *item = iter.value();
  206. if (p_item) {
  207. p_item->removeChild(item);
  208. } else {
  209. int topIdx = indexOfTopLevelItem(item);
  210. takeTopLevelItem(topIdx);
  211. }
  212. delete item;
  213. }
  214. }
  215. void VDirectoryTree::contextMenuRequested(QPoint pos)
  216. {
  217. QTreeWidgetItem *item = itemAt(pos);
  218. if (!m_notebook) {
  219. return;
  220. }
  221. QMenu menu(this);
  222. if (!item) {
  223. // Context menu on the free space of the QTreeWidget
  224. menu.addAction(newRootDirAct);
  225. } else {
  226. // Context menu on a QTreeWidgetItem
  227. if (item->parent()) {
  228. // Low-level item
  229. menu.addAction(newSubDirAct);
  230. } else {
  231. // Top-level item
  232. menu.addAction(newRootDirAct);
  233. menu.addAction(newSubDirAct);
  234. }
  235. menu.addAction(deleteDirAct);
  236. menu.addSeparator();
  237. menu.addAction(copyAct);
  238. menu.addAction(cutAct);
  239. }
  240. if (VUtils::opTypeInClipboard() == ClipboardOpType::CopyDir
  241. && !m_copiedDirs.isEmpty()) {
  242. if (!item) {
  243. menu.addSeparator();
  244. }
  245. menu.addAction(pasteAct);
  246. }
  247. if (item) {
  248. menu.addSeparator();
  249. menu.addAction(dirInfoAct);
  250. }
  251. menu.exec(mapToGlobal(pos));
  252. }
  253. void VDirectoryTree::newSubDirectory()
  254. {
  255. if (!m_notebook) {
  256. return;
  257. }
  258. QTreeWidgetItem *curItem = currentItem();
  259. if (!curItem) {
  260. return;
  261. }
  262. VDirectory *curDir = getVDirectory(curItem);
  263. QString info = QString("Create sub-directory under %1.").arg(curDir->getName());
  264. QString text("&Directory name:");
  265. QString defaultText("new_directory");
  266. do {
  267. VNewDirDialog dialog(tr("Create Directory"), info, text, defaultText, this);
  268. if (dialog.exec() == QDialog::Accepted) {
  269. QString name = dialog.getNameInput();
  270. if (curDir->findSubDirectory(name)) {
  271. info = QString("Name already exists under %1. Please choose another name.").arg(curDir->getName());
  272. defaultText = name;
  273. continue;
  274. }
  275. VDirectory *subDir = curDir->createSubDirectory(name);
  276. if (!subDir) {
  277. VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
  278. QString("Failed to create directory %1.").arg(name), "",
  279. QMessageBox::Ok, QMessageBox::Ok, this);
  280. return;
  281. }
  282. updateItemChildren(curItem);
  283. locateDirectory(subDir);
  284. }
  285. break;
  286. } while (true);
  287. }
  288. void VDirectoryTree::newRootDirectory()
  289. {
  290. if (!m_notebook) {
  291. return;
  292. }
  293. QString info = QString("Create root directory in notebook %1.").arg(m_notebook->getName());
  294. QString text("&Directory name:");
  295. QString defaultText("new_directory");
  296. VDirectory *rootDir = m_notebook->getRootDir();
  297. do {
  298. VNewDirDialog dialog(tr("Create Root Directory"), info, text, defaultText, this);
  299. if (dialog.exec() == QDialog::Accepted) {
  300. QString name = dialog.getNameInput();
  301. if (rootDir->findSubDirectory(name)) {
  302. info = QString("Name already exists in notebook %1. Please choose another name.").arg(m_notebook->getName());
  303. defaultText = name;
  304. continue;
  305. }
  306. VDirectory *subDir = rootDir->createSubDirectory(name);
  307. if (!subDir) {
  308. VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
  309. QString("Failed to create directory %1.").arg(name), "",
  310. QMessageBox::Ok, QMessageBox::Ok, this);
  311. return;
  312. }
  313. updateItemChildren(NULL);
  314. locateDirectory(subDir);
  315. }
  316. break;
  317. } while (true);
  318. }
  319. void VDirectoryTree::deleteDirectory()
  320. {
  321. QTreeWidgetItem *curItem = currentItem();
  322. if (!curItem) {
  323. return;
  324. }
  325. VDirectory *curDir = getVDirectory(curItem);
  326. int ret = VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
  327. QString("Are you sure to delete directory %1?").arg(curDir->getName()),
  328. tr("This will delete any files under this directory."), QMessageBox::Ok | QMessageBox::Cancel,
  329. QMessageBox::Ok, this);
  330. if (ret == QMessageBox::Ok) {
  331. m_editArea->closeFile(curDir, true);
  332. VDirectory *parentDir = curDir->getParentDirectory();
  333. Q_ASSERT(parentDir);
  334. parentDir->deleteSubDirectory(curDir);
  335. delete curItem;
  336. }
  337. }
  338. void VDirectoryTree::currentDirectoryItemChanged(QTreeWidgetItem *currentItem)
  339. {
  340. if (!currentItem) {
  341. emit currentDirectoryChanged(NULL);
  342. return;
  343. }
  344. emit currentDirectoryChanged(getVDirectory(currentItem));
  345. }
  346. void VDirectoryTree::editDirectoryInfo()
  347. {
  348. QTreeWidgetItem *curItem = currentItem();
  349. if (!curItem) {
  350. return;
  351. }
  352. VDirectory *curDir = getVDirectory(curItem);
  353. VDirectory *parentDir = curDir->getParentDirectory();
  354. QString curName = curDir->getName();
  355. QString info;
  356. QString defaultName = curName;
  357. do {
  358. VDirInfoDialog dialog(tr("Directory Information"), info, defaultName, this);
  359. if (dialog.exec() == QDialog::Accepted) {
  360. QString name = dialog.getNameInput();
  361. if (name == curName) {
  362. return;
  363. }
  364. if (parentDir->findSubDirectory(name)) {
  365. info = "Name already exists. Please choose another name.";
  366. defaultName = name;
  367. continue;
  368. }
  369. if (!curDir->rename(name)) {
  370. VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
  371. QString("Failed to rename directory %1.").arg(curName), "",
  372. QMessageBox::Ok, QMessageBox::Ok, this);
  373. return;
  374. }
  375. curItem->setText(0, name);
  376. emit directoryUpdated(curDir);
  377. }
  378. break;
  379. } while (true);
  380. }
  381. void VDirectoryTree::copySelectedDirectories(bool p_cut)
  382. {
  383. QList<QTreeWidgetItem *> items = selectedItems();
  384. if (items.isEmpty()) {
  385. return;
  386. }
  387. QJsonArray dirs;
  388. m_copiedDirs.clear();
  389. for (int i = 0; i < items.size(); ++i) {
  390. VDirectory *dir = getVDirectory(items[i]);
  391. QJsonObject dirJson;
  392. dirJson["notebook"] = dir->getNotebookName();
  393. dirJson["path"] = dir->retrivePath();
  394. dirs.append(dirJson);
  395. m_copiedDirs.append(dir);
  396. }
  397. copyDirectoryInfoToClipboard(dirs, p_cut);
  398. }
  399. void VDirectoryTree::copyDirectoryInfoToClipboard(const QJsonArray &p_dirs, bool p_cut)
  400. {
  401. QJsonObject clip;
  402. clip["operation"] = (int)ClipboardOpType::CopyDir;
  403. clip["is_cut"] = p_cut;
  404. clip["sources"] = p_dirs;
  405. QClipboard *clipboard = QApplication::clipboard();
  406. clipboard->setText(QJsonDocument(clip).toJson(QJsonDocument::Compact));
  407. }
  408. void VDirectoryTree::cutSelectedDirectories()
  409. {
  410. copySelectedDirectories(true);
  411. }
  412. void VDirectoryTree::pasteDirectoriesInCurDir()
  413. {
  414. QTreeWidgetItem *item = currentItem();
  415. VDirectory *destDir = m_notebook->getRootDir();
  416. if (item) {
  417. destDir = getVDirectory(item);
  418. }
  419. pasteDirectories(destDir);
  420. }
  421. void VDirectoryTree::pasteDirectories(VDirectory *p_destDir)
  422. {
  423. QClipboard *clipboard = QApplication::clipboard();
  424. QString text = clipboard->text();
  425. QJsonObject clip = QJsonDocument::fromJson(text.toLocal8Bit()).object();
  426. Q_ASSERT(!clip.isEmpty() && clip["operation"] == (int)ClipboardOpType::CopyDir);
  427. bool isCut = clip["is_cut"].toBool();
  428. int nrPasted = 0;
  429. for (int i = 0; i < m_copiedDirs.size(); ++i) {
  430. QPointer<VDirectory> srcDir = m_copiedDirs[i];
  431. if (!srcDir) {
  432. continue;
  433. }
  434. QString dirName = srcDir->getName();
  435. VDirectory *srcParentDir = srcDir->getParentDirectory();
  436. if (srcParentDir == p_destDir && !isCut) {
  437. // Copy and paste in the same directory.
  438. // Rename it to xx_copy
  439. dirName = VUtils::generateCopiedDirName(srcParentDir->retrivePath(), dirName);
  440. }
  441. if (copyDirectory(p_destDir, dirName, srcDir, isCut)) {
  442. nrPasted++;
  443. }
  444. }
  445. qDebug() << "pasted" << nrPasted << "files successfully";
  446. clipboard->clear();
  447. m_copiedDirs.clear();
  448. }
  449. void VDirectoryTree::mousePressEvent(QMouseEvent *event)
  450. {
  451. QTreeWidgetItem *item = itemAt(event->pos());
  452. if (!item) {
  453. setCurrentItem(NULL);
  454. }
  455. QTreeWidget::mousePressEvent(event);
  456. }
  457. void VDirectoryTree::keyPressEvent(QKeyEvent *event)
  458. {
  459. if (event->key() == Qt::Key_Return) {
  460. QTreeWidgetItem *item = currentItem();
  461. if (item) {
  462. item->setExpanded(!item->isExpanded());
  463. }
  464. }
  465. QTreeWidget::keyPressEvent(event);
  466. }
  467. bool VDirectoryTree::copyDirectory(VDirectory *p_destDir, const QString &p_destName,
  468. VDirectory *p_srcDir, bool p_cut)
  469. {
  470. qDebug() << "copy" << p_srcDir->getName() << "to" << p_destDir->getName()
  471. << "as" << p_destName;
  472. QString srcName = p_srcDir->getName();
  473. QString srcPath = QDir::cleanPath(p_srcDir->retrivePath());
  474. QString destPath = QDir::cleanPath(QDir(p_destDir->retrivePath()).filePath(p_destName));
  475. if (srcPath == destPath) {
  476. return true;
  477. }
  478. VDirectory *srcParentDir = p_srcDir->getParentDirectory();
  479. VDirectory *destDir = VDirectory::copyDirectory(p_destDir, p_destName, p_srcDir, p_cut);
  480. if (destDir) {
  481. // Update QTreeWidget
  482. bool isWidget;
  483. QTreeWidgetItem *destItem = findVDirectory(p_destDir, isWidget);
  484. if (destItem || isWidget) {
  485. updateItemChildren(destItem);
  486. }
  487. if (p_cut) {
  488. QTreeWidgetItem *srcItem = findVDirectory(srcParentDir, isWidget);
  489. if (srcItem || isWidget) {
  490. updateItemChildren(srcItem);
  491. }
  492. }
  493. // Broadcast this update
  494. emit directoryUpdated(destDir);
  495. } else {
  496. VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
  497. QString("Failed to copy directory %1.").arg(srcName),
  498. QString("Please check if there alread exists a directory with the same name"),
  499. QMessageBox::Ok, QMessageBox::Ok, this);
  500. }
  501. return destDir;
  502. }
  503. QTreeWidgetItem *VDirectoryTree::findVDirectory(const VDirectory *p_dir, bool &p_widget)
  504. {
  505. p_widget = false;
  506. if (!p_dir) {
  507. return NULL;
  508. } else if (p_dir->getNotebookName() != m_notebook->getName()) {
  509. return NULL;
  510. } else if (p_dir == m_notebook->getRootDir()) {
  511. p_widget = true;
  512. return NULL;
  513. }
  514. bool isWidget;
  515. QTreeWidgetItem *pItem = findVDirectory(p_dir->getParentDirectory(), isWidget);
  516. if (pItem) {
  517. // Iterate all its children to find the match.
  518. int nrChild = pItem->childCount();
  519. for (int i = 0; i < nrChild; ++i) {
  520. QTreeWidgetItem *item = pItem->child(i);
  521. if (getVDirectory(item) == p_dir) {
  522. return item;
  523. }
  524. }
  525. } else if (isWidget) {
  526. // Iterate all the top-level items.
  527. int nrChild = topLevelItemCount();
  528. for (int i = 0; i < nrChild; ++i) {
  529. QTreeWidgetItem *item = topLevelItem(i);
  530. if (getVDirectory(item) == p_dir) {
  531. return item;
  532. }
  533. }
  534. }
  535. return NULL;
  536. }
  537. bool VDirectoryTree::locateDirectory(const VDirectory *p_directory)
  538. {
  539. if (p_directory) {
  540. qDebug() << "locate directory" << p_directory->retrivePath()
  541. << "in" << m_notebook->getName();
  542. if (p_directory->getNotebook() != m_notebook) {
  543. return false;
  544. }
  545. QTreeWidgetItem *item = expandToVDirectory(p_directory);
  546. if (item) {
  547. setCurrentItem(item);
  548. }
  549. return item;
  550. }
  551. return false;
  552. }
  553. QTreeWidgetItem *VDirectoryTree::expandToVDirectory(const VDirectory *p_directory)
  554. {
  555. if (!p_directory || p_directory->getNotebook() != m_notebook
  556. || p_directory == m_notebook->getRootDir()) {
  557. return NULL;
  558. }
  559. if (p_directory->getParentDirectory() == m_notebook->getRootDir()) {
  560. // Top-level items.
  561. int nrChild = topLevelItemCount();
  562. for (int i = 0; i < nrChild; ++i) {
  563. QTreeWidgetItem *item = topLevelItem(i);
  564. if (getVDirectory(item) == p_directory) {
  565. return item;
  566. }
  567. }
  568. } else {
  569. QTreeWidgetItem *pItem = expandToVDirectory(p_directory->getParentDirectory());
  570. if (!pItem) {
  571. return NULL;
  572. }
  573. int nrChild = pItem->childCount();
  574. if (nrChild == 0) {
  575. updateDirectoryTreeOne(pItem, 1);
  576. }
  577. nrChild = pItem->childCount();
  578. for (int i = 0; i < nrChild; ++i) {
  579. QTreeWidgetItem *item = pItem->child(i);
  580. if (getVDirectory(item) == p_directory) {
  581. return item;
  582. }
  583. }
  584. }
  585. return NULL;
  586. }
  587. void VDirectoryTree::expandItemTree(QTreeWidgetItem *p_item)
  588. {
  589. if (!p_item) {
  590. return;
  591. }
  592. VDirectory *dir = getVDirectory(p_item);
  593. int nrChild = p_item->childCount();
  594. for (int i = 0; i < nrChild; ++i) {
  595. expandItemTree(p_item->child(i));
  596. }
  597. if (dir->isExpanded()) {
  598. Q_ASSERT(nrChild > 0);
  599. expandItem(p_item);
  600. }
  601. }