workspacemodel.cpp 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. /****************************************************************************
  2. **
  3. ** Copyright (C) 2020 The Qt Company Ltd.
  4. ** Contact: https://www.qt.io/licensing/
  5. **
  6. ** This file is part of Qt Creator.
  7. **
  8. ** Commercial License Usage
  9. ** Licensees holding valid commercial Qt licenses may use this file in
  10. ** accordance with the commercial license agreement provided with the
  11. ** Software or, alternatively, in accordance with the terms contained in
  12. ** a written agreement between you and The Qt Company. For licensing terms
  13. ** and conditions see https://www.qt.io/terms-conditions. For further
  14. ** information use the contact form at https://www.qt.io/contact-us.
  15. **
  16. ** GNU Lesser General Public License Usage
  17. ** Alternatively, this file may be used under the terms of the GNU Lesser
  18. ** General Public License version 2.1 or (at your option) any later version.
  19. ** The licenses are as published by the Free Software Foundation
  20. ** and appearing in the file LICENSE.LGPLv21 included in the packaging
  21. ** of this file. Please review the following information to ensure
  22. ** the GNU Lesser General Public License version 2.1 requirements
  23. ** will be met: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  24. **
  25. ** GNU General Public License Usage
  26. ** Alternatively, this file may be used under the terms of the GNU
  27. ** General Public License version 3 or (at your option) any later version
  28. ** approved by the KDE Free Qt Foundation. The licenses are as published by
  29. ** the Free Software Foundation and appearing in the file LICENSE.GPL3
  30. ** included in the packaging of this file. Please review the following
  31. ** information to ensure the GNU General Public License requirements will
  32. ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
  33. **
  34. ****************************************************************************/
  35. #include "workspacemodel.h"
  36. #include "dockmanager.h"
  37. #include "workspacedialog.h"
  38. #include <utils/algorithm.h>
  39. // #include <utils/fileutils.h>
  40. // #include <utils/stringutils.h>
  41. #include <QDir>
  42. #include <QFileInfo>
  43. namespace ADS {
  44. WorkspaceModel::WorkspaceModel(DockManager *manager, QObject *parent)
  45. : QAbstractTableModel(parent)
  46. , m_manager(manager)
  47. {
  48. m_sortedWorkspaces = m_manager->workspaces();
  49. connect(m_manager, &DockManager::workspaceLoaded, this, &WorkspaceModel::resetWorkspaces);
  50. }
  51. int WorkspaceModel::indexOfWorkspace(const QString &workspace)
  52. {
  53. return m_sortedWorkspaces.indexOf(workspace);
  54. }
  55. QString WorkspaceModel::workspaceAt(int row) const
  56. {
  57. return m_sortedWorkspaces.value(row, QString());
  58. }
  59. QVariant WorkspaceModel::headerData(int section, Qt::Orientation orientation, int role) const
  60. {
  61. QVariant result;
  62. if (orientation == Qt::Horizontal) {
  63. switch (role) {
  64. case Qt::DisplayRole:
  65. switch (section) {
  66. case 0:
  67. result = tr("Workspace");
  68. break;
  69. case 1:
  70. result = tr("Last Modified");
  71. break;
  72. } // switch (section)
  73. break;
  74. } // switch (role)
  75. }
  76. return result;
  77. }
  78. int WorkspaceModel::columnCount(const QModelIndex &) const
  79. {
  80. static int sectionCount = 0;
  81. if (sectionCount == 0) {
  82. // headers sections defining possible columns
  83. while (!headerData(sectionCount, Qt::Horizontal, Qt::DisplayRole).isNull())
  84. sectionCount++;
  85. }
  86. return sectionCount;
  87. }
  88. int WorkspaceModel::rowCount(const QModelIndex &) const
  89. {
  90. return m_sortedWorkspaces.count();
  91. }
  92. QStringList pathsToBaseNames(const QStringList &paths)
  93. {
  94. return Utils::transform(paths,
  95. [](const QString &path) { return QFileInfo(path).completeBaseName(); });
  96. }
  97. QStringList pathsWithTildeHomePath(const QStringList &paths)
  98. {
  99. QStringList result;
  100. std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](const QString &path) {
  101. // 转换为本地分隔符格式
  102. QString nativePath = QDir::toNativeSeparators(path);
  103. // 获取用户主目录路径(使用本地分隔符)
  104. QString homePath = QDir::homePath();
  105. QString nativeHomePath = QDir::toNativeSeparators(homePath);
  106. // 检查路径是否以主目录开头
  107. if (nativePath.startsWith(nativeHomePath, Qt::CaseSensitive)) {
  108. // 替换主目录部分为波浪线(~)
  109. nativePath.replace(0, nativeHomePath.length(), "~");
  110. }
  111. return nativePath;
  112. });
  113. return result;
  114. }
  115. QVariant WorkspaceModel::data(const QModelIndex &index, int role) const
  116. {
  117. QVariant result;
  118. if (index.isValid()) {
  119. QString workspaceName = m_sortedWorkspaces.at(index.row());
  120. switch (role) {
  121. case Qt::DisplayRole:
  122. switch (index.column()) {
  123. case 0:
  124. result = workspaceName;
  125. break;
  126. case 1:
  127. result = m_manager->workspaceDateTime(workspaceName);
  128. break;
  129. } // switch (section)
  130. break;
  131. case Qt::FontRole: {
  132. QFont font;
  133. if (m_manager->isDefaultWorkspace(workspaceName))
  134. font.setItalic(true);
  135. else
  136. font.setItalic(false);
  137. if (m_manager->activeWorkspace() == workspaceName
  138. && !m_manager->isFactoryDefaultWorkspace(workspaceName))
  139. font.setBold(true);
  140. else
  141. font.setBold(false);
  142. result = font;
  143. } break;
  144. case DefaultWorkspaceRole:
  145. result = m_manager->isDefaultWorkspace(workspaceName);
  146. break;
  147. case LastWorkspaceRole:
  148. result = m_manager->lastWorkspace() == workspaceName;
  149. break;
  150. case ActiveWorkspaceRole:
  151. result = m_manager->activeWorkspace() == workspaceName;
  152. break;
  153. } // switch (role)
  154. }
  155. return result;
  156. }
  157. QHash<int, QByteArray> WorkspaceModel::roleNames() const
  158. {
  159. static QHash<int, QByteArray> extraRoles{{Qt::DisplayRole, "workspaceName"},
  160. {DefaultWorkspaceRole, "defaultWorkspace"},
  161. {LastWorkspaceRole, "activeWorkspace"},
  162. {ActiveWorkspaceRole, "lastWorkspace"}};
  163. return QAbstractTableModel::roleNames().unite(extraRoles);
  164. }
  165. void WorkspaceModel::sort(int column, Qt::SortOrder order)
  166. {
  167. beginResetModel();
  168. const auto cmp = [this, column, order](const QString &s1, const QString &s2) {
  169. bool isLess;
  170. if (column == 0)
  171. isLess = s1 < s2;
  172. else
  173. isLess = m_manager->workspaceDateTime(s1) < m_manager->workspaceDateTime(s2);
  174. if (order == Qt::DescendingOrder)
  175. isLess = !isLess;
  176. return isLess;
  177. };
  178. Utils::sort(m_sortedWorkspaces, cmp);
  179. endResetModel();
  180. }
  181. bool WorkspaceModel::isDefaultVirgin() const
  182. {
  183. return false; //m_manager->isFactoryDefaultWorkspace(); // TODO
  184. }
  185. void WorkspaceModel::resetWorkspaces()
  186. {
  187. beginResetModel();
  188. m_sortedWorkspaces = m_manager->workspaces();
  189. endResetModel();
  190. }
  191. void WorkspaceModel::newWorkspace(QWidget *parent)
  192. {
  193. WorkspaceNameInputDialog workspaceInputDialog(m_manager, parent);
  194. workspaceInputDialog.setWindowTitle(tr("New Workspace Name"));
  195. workspaceInputDialog.setActionText(tr("&Create"), tr("Create and &Open"));
  196. runWorkspaceNameInputDialog(&workspaceInputDialog, [this](const QString &newName) {
  197. m_manager->createWorkspace(newName);
  198. });
  199. }
  200. void WorkspaceModel::cloneWorkspace(QWidget *parent, const QString &workspace)
  201. {
  202. WorkspaceNameInputDialog workspaceInputDialog(m_manager, parent);
  203. workspaceInputDialog.setWindowTitle(tr("New Workspace Name"));
  204. workspaceInputDialog.setActionText(tr("&Clone"), tr("Clone and &Open"));
  205. workspaceInputDialog.setValue(workspace + " (2)");
  206. runWorkspaceNameInputDialog(&workspaceInputDialog, [this, workspace](const QString &newName) {
  207. m_manager->cloneWorkspace(workspace, newName);
  208. });
  209. }
  210. void WorkspaceModel::deleteWorkspaces(const QStringList &workspaces)
  211. {
  212. if (!m_manager->confirmWorkspaceDelete(workspaces))
  213. return;
  214. beginResetModel();
  215. m_manager->deleteWorkspaces(workspaces);
  216. endResetModel();
  217. }
  218. void WorkspaceModel::renameWorkspace(QWidget *parent, const QString &workspace)
  219. {
  220. WorkspaceNameInputDialog workspaceInputDialog(m_manager, parent);
  221. workspaceInputDialog.setWindowTitle(tr("Rename Workspace"));
  222. workspaceInputDialog.setActionText(tr("&Rename"), tr("Rename and &Open"));
  223. workspaceInputDialog.setValue(workspace);
  224. runWorkspaceNameInputDialog(&workspaceInputDialog, [this, workspace](const QString &newName) {
  225. m_manager->renameWorkspace(workspace, newName);
  226. });
  227. }
  228. void WorkspaceModel::switchToWorkspace(const QString &workspace)
  229. {
  230. m_manager->openWorkspace(workspace);
  231. emit workspaceSwitched();
  232. }
  233. void WorkspaceModel::runWorkspaceNameInputDialog(WorkspaceNameInputDialog *workspaceInputDialog,
  234. std::function<void(const QString &)> createWorkspace)
  235. {
  236. if (workspaceInputDialog->exec() == QDialog::Accepted) {
  237. QString newWorkspace = workspaceInputDialog->value();
  238. if (newWorkspace.isEmpty() || m_manager->workspaces().contains(newWorkspace))
  239. return;
  240. beginResetModel();
  241. createWorkspace(newWorkspace);
  242. m_sortedWorkspaces = m_manager->workspaces();
  243. endResetModel();
  244. if (workspaceInputDialog->isSwitchToRequested())
  245. switchToWorkspace(newWorkspace);
  246. emit workspaceCreated(newWorkspace);
  247. }
  248. }
  249. } // namespace ADS