Changeset View
Changeset View
Standalone View
Standalone View
kcms/cursortheme/xcursor/thememodel.cpp
1 | /* | 1 | /* | ||
---|---|---|---|---|---|
2 | * Copyright © 2005-2007 Fredrik Höglund <fredrik@kde.org> | 2 | * Copyright © 2005-2007 Fredrik Höglund <fredrik@kde.org> | ||
3 | * Copyright © 2016 Jason A. Donenfeld <jason@zx2c4.com> | | |||
4 | * | 3 | * | ||
5 | * This program is free software; you can redistribute it and/or | 4 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public | 5 | * modify it under the terms of the GNU General Public | ||
7 | * License version 2 as published by the Free Software Foundation. | 6 | * License version 2 as published by the Free Software Foundation. | ||
8 | * | 7 | * | ||
9 | * This program is distributed in the hope that it will be useful, | 8 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | * General Public License for more details. | 11 | * General Public License for more details. | ||
13 | * | 12 | * | ||
14 | * You should have received a copy of the GNU General Public License | 13 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; see the file COPYING. If not, write to | 14 | * along with this program; see the file COPYING. If not, write to | ||
16 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 15 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
17 | * Boston, MA 02110-1301, USA. | 16 | * Boston, MA 02110-1301, USA. | ||
18 | */ | 17 | */ | ||
19 | 18 | | |||
20 | 19 | | |||
21 | #include <KLocalizedString> | 20 | #include <KLocalizedString> | ||
22 | #include <KConfig> | 21 | #include <KConfig> | ||
23 | #include <KConfigGroup> | 22 | #include <KConfigGroup> | ||
24 | #include <KShell> | | |||
25 | #include <QStringList> | 23 | #include <QStringList> | ||
26 | #include <QDir> | 24 | #include <QDir> | ||
27 | #include <QX11Info> | 25 | #include <QX11Info> | ||
28 | 26 | | |||
29 | #include "thememodel.h" | 27 | #include "thememodel.h" | ||
30 | #include "xcursortheme.h" | 28 | #include "xcursortheme.h" | ||
31 | 29 | | |||
30 | #include <X11/Xlib.h> | ||||
32 | #include <X11/Xcursor/Xcursor.h> | 31 | #include <X11/Xcursor/Xcursor.h> | ||
33 | 32 | | |||
33 | // Check for older version | ||||
34 | #if !defined(XCURSOR_LIB_MAJOR) && defined(XCURSOR_MAJOR) | ||||
35 | # define XCURSOR_LIB_MAJOR XCURSOR_MAJOR | ||||
36 | # define XCURSOR_LIB_MINOR XCURSOR_MINOR | ||||
37 | #endif | ||||
38 | | ||||
39 | | ||||
40 | | ||||
34 | CursorThemeModel::CursorThemeModel(QObject *parent) | 41 | CursorThemeModel::CursorThemeModel(QObject *parent) | ||
35 | : QAbstractTableModel(parent) | 42 | : QAbstractTableModel(parent) | ||
36 | { | 43 | { | ||
37 | insertThemes(); | 44 | insertThemes(); | ||
38 | } | 45 | } | ||
39 | 46 | | |||
40 | CursorThemeModel::~CursorThemeModel() | 47 | CursorThemeModel::~CursorThemeModel() | ||
41 | { | 48 | { | ||
42 | qDeleteAll(list); | 49 | qDeleteAll(list); | ||
43 | list.clear(); | 50 | list.clear(); | ||
44 | } | 51 | } | ||
45 | 52 | | |||
53 | QHash<int, QByteArray> CursorThemeModel::roleNames() const | ||||
54 | { | ||||
55 | QHash<int, QByteArray> roleNames = QAbstractTableModel::roleNames(); | ||||
56 | roleNames[CursorTheme::DisplayDetailRole] = "description"; | ||||
57 | roleNames[CursorTheme::IsWritableRole] = "isWritable"; | ||||
58 | | ||||
59 | return roleNames; | ||||
60 | } | ||||
61 | | ||||
46 | void CursorThemeModel::refreshList() | 62 | void CursorThemeModel::refreshList() | ||
47 | { | 63 | { | ||
48 | beginResetModel(); | 64 | beginResetModel(); | ||
49 | qDeleteAll(list); | 65 | qDeleteAll(list); | ||
50 | list.clear(); | 66 | list.clear(); | ||
51 | endResetModel(); | 67 | endResetModel(); | ||
52 | insertThemes(); | 68 | insertThemes(); | ||
53 | } | 69 | } | ||
▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Line(s) | 98 | { | |||
103 | // Description for the first name column | 119 | // Description for the first name column | ||
104 | if (role == CursorTheme::DisplayDetailRole && index.column() == NameColumn) | 120 | if (role == CursorTheme::DisplayDetailRole && index.column() == NameColumn) | ||
105 | return theme->description(); | 121 | return theme->description(); | ||
106 | 122 | | |||
107 | // Icon for the name column | 123 | // Icon for the name column | ||
108 | if (role == Qt::DecorationRole && index.column() == NameColumn) | 124 | if (role == Qt::DecorationRole && index.column() == NameColumn) | ||
109 | return theme->icon(); | 125 | return theme->icon(); | ||
110 | 126 | | |||
127 | if (role == CursorTheme::IsWritableRole) { | ||||
128 | return theme->isWritable(); | ||||
129 | } | ||||
130 | | ||||
111 | return QVariant(); | 131 | return QVariant(); | ||
112 | } | 132 | } | ||
113 | 133 | | |||
114 | 134 | | |||
115 | void CursorThemeModel::sort(int column, Qt::SortOrder order) | 135 | void CursorThemeModel::sort(int column, Qt::SortOrder order) | ||
116 | { | 136 | { | ||
117 | Q_UNUSED(column); | 137 | Q_UNUSED(column); | ||
118 | Q_UNUSED(order); | 138 | Q_UNUSED(order); | ||
Show All 36 Lines | |||||
155 | } | 175 | } | ||
156 | 176 | | |||
157 | 177 | | |||
158 | const QStringList CursorThemeModel::searchPaths() | 178 | const QStringList CursorThemeModel::searchPaths() | ||
159 | { | 179 | { | ||
160 | if (!baseDirs.isEmpty()) | 180 | if (!baseDirs.isEmpty()) | ||
161 | return baseDirs; | 181 | return baseDirs; | ||
162 | 182 | | |||
163 | baseDirs = QString(XcursorLibraryPath()).split(':', QString::SkipEmptyParts); | 183 | #if XCURSOR_LIB_MAJOR == 1 && XCURSOR_LIB_MINOR < 1 | ||
164 | std::transform(baseDirs.begin(), baseDirs.end(), baseDirs.begin(), KShell::tildeExpand); | 184 | // These are the default paths Xcursor will scan for cursor themes | ||
165 | baseDirs.removeDuplicates(); | 185 | QString path("~/.icons:/usr/share/icons:/usr/share/pixmaps:/usr/X11R6/lib/X11/icons"); | ||
186 | | ||||
187 | // If XCURSOR_PATH is set, use that instead of the default path | ||||
188 | char *xcursorPath = std::getenv("XCURSOR_PATH"); | ||||
189 | if (xcursorPath) | ||||
190 | path = xcursorPath; | ||||
191 | #else | ||||
192 | // Get the search path from Xcursor | ||||
193 | QString path = XcursorLibraryPath(); | ||||
194 | #endif | ||||
195 | | ||||
196 | // Separate the paths | ||||
197 | baseDirs = path.split(':', QString::SkipEmptyParts); | ||||
198 | | ||||
199 | // Remove duplicates | ||||
200 | QMutableStringListIterator i(baseDirs); | ||||
201 | while (i.hasNext()) | ||||
202 | { | ||||
203 | const QString path = i.next(); | ||||
204 | QMutableStringListIterator j(i); | ||||
205 | while (j.hasNext()) | ||||
206 | if (j.next() == path) | ||||
207 | j.remove(); | ||||
208 | } | ||||
166 | 209 | | |||
210 | // Expand all occurrences of ~/ to the home dir | ||||
211 | baseDirs.replaceInStrings(QRegExp("^~\\/"), QDir::home().path() + '/'); | ||||
167 | return baseDirs; | 212 | return baseDirs; | ||
168 | } | 213 | } | ||
169 | 214 | | |||
170 | 215 | | |||
171 | bool CursorThemeModel::hasTheme(const QString &name) const | 216 | bool CursorThemeModel::hasTheme(const QString &name) const | ||
172 | { | 217 | { | ||
173 | const uint hash = qHash(name); | 218 | const uint hash = qHash(name); | ||
174 | 219 | | |||
▲ Show 20 Lines • Show All 77 Lines • ▼ Show 20 Line(s) | 272 | { | |||
252 | 297 | | |||
253 | defaultName = QStringLiteral("default"); | 298 | defaultName = QStringLiteral("default"); | ||
254 | return false; | 299 | return false; | ||
255 | } | 300 | } | ||
256 | 301 | | |||
257 | 302 | | |||
258 | void CursorThemeModel::processThemeDir(const QDir &themeDir) | 303 | void CursorThemeModel::processThemeDir(const QDir &themeDir) | ||
259 | { | 304 | { | ||
260 | bool haveCursors = themeDir.exists(QStringLiteral("cursors")); | 305 | bool haveCursors = themeDir.exists(QStringLiteral("cursors")); | ||
davidedmundson: why change these QStringLiterals? Is a rebase needed? | |||||
yeah, it's so long this review is open that doesn't merge cleanly with master anymore :/ mart: yeah, it's so long this review is open that doesn't merge cleanly with master anymore :/ | |||||
261 | 306 | | |||
262 | // Special case handling of "default", since it's usually either a | 307 | // Special case handling of "default", since it's usually either a | ||
263 | // symlink to another theme, or an empty theme that inherits another | 308 | // symlink to another theme, or an empty theme that inherits another | ||
264 | // theme. | 309 | // theme. | ||
265 | if (defaultName.isNull() && themeDir.dirName() == QLatin1String("default")) | 310 | if (defaultName.isNull() && themeDir.dirName() == QLatin1String("default")) | ||
266 | { | 311 | { | ||
267 | if (handleDefault(themeDir)) | 312 | if (handleDefault(themeDir)) | ||
268 | return; | 313 | return; | ||
269 | } | 314 | } | ||
270 | 315 | | |||
271 | // If the directory doesn't have a cursors subdir and lacks an | 316 | // If the directory doesn't have a cursors subdir and lacks an | ||
272 | // index.theme file it can't be a cursor theme. | 317 | // index.theme file it can't be a cursor theme. | ||
273 | if (!themeDir.exists(QStringLiteral("index.theme")) && !haveCursors) | 318 | if (!themeDir.exists(QStringLiteral("index.theme")) && !haveCursors) | ||
274 | return; | 319 | return; | ||
275 | 320 | | |||
276 | // Create a cursor theme object for the theme dir | 321 | // Create a cursor theme object for the theme dir | ||
davidedmundson: This seems unrelated, adn I'm not sure is right. | |||||
277 | XCursorTheme *theme = new XCursorTheme(themeDir); | 322 | XCursorTheme *theme = new XCursorTheme(themeDir); | ||
278 | 323 | | |||
279 | // Skip this theme if it's hidden. | 324 | // Skip this theme if it's hidden. | ||
280 | if (theme->isHidden()) { | 325 | if (theme->isHidden()) { | ||
281 | delete theme; | 326 | delete theme; | ||
282 | return; | 327 | return; | ||
283 | } | 328 | } | ||
284 | 329 | | |||
▲ Show 20 Lines • Show All 97 Lines • Show Last 20 Lines |
why change these QStringLiterals? Is a rebase needed?