2
* Copyright (C) 2003 Waldo Bastian <bastian@kde.org>
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; either version 2 of the License, or
7
* (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24
#include <KDesktopFile>
25
#include <KStandardDirs>
26
#include <KConfigGroup>
37
static QStringList *s_newShortcuts = 0;
38
static QStringList *s_freeShortcuts = 0;
39
static QStringList *s_deletedApps = 0;
42
void MenuFolderInfo::add(MenuSeparatorInfo *info, bool initial)
45
initialLayout.append(info);
49
void MenuFolderInfo::add(MenuFolderInfo *info, bool initial)
51
subFolders.append(info);
53
initialLayout.append(info);
56
// Remove sub menu (without deleting it)
57
void MenuFolderInfo::take(MenuFolderInfo *info)
59
subFolders.removeAll(info);
62
// Remove sub menu (without deleting it)
63
bool MenuFolderInfo::takeRecursive(MenuFolderInfo *info)
65
if (subFolders.removeAll(info) > 0)
70
foreach (MenuFolderInfo *subFolderInfo, subFolders)
72
if (subFolderInfo->takeRecursive(info))
78
// Recursively update all fullIds
79
void MenuFolderInfo::updateFullId(const QString &parentId)
81
fullId = parentId + id;
83
foreach (MenuFolderInfo *subFolderInfo, subFolders)
85
subFolderInfo->updateFullId(fullId);
90
void MenuFolderInfo::add(MenuEntryInfo *entry, bool initial)
92
entries.append(entry);
94
initialLayout.append(entry);
98
void MenuFolderInfo::take(MenuEntryInfo *entry)
100
entries.removeAll(entry);
104
// Return a unique sub-menu caption inspired by @p caption
105
QString MenuFolderInfo::uniqueMenuCaption(const QString &caption)
107
QRegExp r("(.*)(?=-\\d+)");
108
QString cap = (r.indexIn(caption) > -1) ? r.cap(1) : caption;
110
QString result = caption;
112
for(int n = 1; ++n; )
115
foreach (MenuFolderInfo *subFolderInfo, subFolders)
117
if (subFolderInfo->caption == result)
126
result = cap + QString("-%1").arg(n);
128
return QString(); // Never reached
131
// Return a unique item caption inspired by @p caption
132
QString MenuFolderInfo::uniqueItemCaption(const QString &caption, const QString &exclude)
134
QRegExp r("(.*)(?=-\\d+)");
135
QString cap = (r.indexIn(caption) > -1) ? r.cap(1) : caption;
137
QString result = caption;
139
for(int n = 1; ++n; )
142
if (result == exclude)
144
foreach (MenuEntryInfo *entryInfo, entries)
146
if (entryInfo->caption == result)
155
result = cap + QString("-%1").arg(n);
157
return QString(); // Never reached
160
// Return a list of existing submenu ids
161
QStringList MenuFolderInfo::existingMenuIds()
164
foreach (MenuFolderInfo *subFolderInfo, subFolders)
166
result.append(subFolderInfo->id);
171
void MenuFolderInfo::setDirty()
176
void MenuFolderInfo::save(MenuFile *menuFile)
181
// Remove hotkeys for applications that have been deleted
182
for(QStringList::ConstIterator it = s_deletedApps->constBegin();
183
it != s_deletedApps->constEnd(); ++it)
185
// The shorcut is deleted if we set a empty sequence
186
KHotKeys::changeMenuEntryShortcut(*it, "");
189
delete s_deletedApps;
195
QString local = KDesktopFile::locateLocal(directoryFile);
197
KDesktopFile *df = 0;
198
if (directoryFile != local)
200
KDesktopFile orig(QStandardPaths::ApplicationsLocation, directoryFile);
201
df = orig.copyTo(local);
205
df = new KDesktopFile(QStandardPaths::ApplicationsLocation, directoryFile);
208
KConfigGroup dg( df->desktopGroup() );
209
dg.writeEntry("Name", caption);
210
dg.writeEntry("GenericName", genericname);
211
dg.writeEntry("Comment", comment);
212
dg.writeEntry("Icon", icon);
219
foreach (MenuFolderInfo *subFolderInfo, subFolders)
221
subFolderInfo->save(menuFile);
225
foreach (MenuEntryInfo *entryInfo, entries)
227
if (entryInfo->needInsertion())
228
menuFile->addEntry(fullId, entryInfo->menuId());
233
bool MenuFolderInfo::hasDirt()
235
if (dirty) return true;
238
foreach (MenuFolderInfo *subFolderInfo, subFolders)
240
if (subFolderInfo->hasDirt()) return true;
244
foreach (MenuEntryInfo *entryInfo, entries)
246
if (entryInfo->dirty || entryInfo->shortcutDirty) return true;
251
KService::Ptr MenuFolderInfo::findServiceShortcut(const KShortcut&cut)
253
KService::Ptr result;
255
foreach (MenuFolderInfo *subFolderInfo, subFolders)
257
result = subFolderInfo->findServiceShortcut(cut);
263
foreach (MenuEntryInfo *entryInfo, entries)
265
if (entryInfo->shortCut == cut)
266
return entryInfo->service;
268
return KService::Ptr();
271
void MenuFolderInfo::setInUse(bool inUse)
273
// Propagate to sub-menus
274
foreach (MenuFolderInfo *subFolderInfo, subFolders)
276
subFolderInfo->setInUse(inUse);
279
// Propagate to entries
280
foreach (MenuEntryInfo *entryInfo, entries)
282
entryInfo->setInUse(inUse);
290
MenuEntryInfo::~MenuEntryInfo()
292
m_desktopFile->markAsClean();
293
delete m_desktopFile;
296
KDesktopFile *MenuEntryInfo::desktopFile()
300
m_desktopFile = new KDesktopFile(service->entryPath());
302
return m_desktopFile;
305
void MenuEntryInfo::setDirty()
311
QString local = KStandardDirs::locateLocal("xdgdata-apps", service->menuId());
312
if (local != service->entryPath())
314
KDesktopFile *oldDf = desktopFile();
315
m_desktopFile = oldDf->copyTo(local);
320
bool MenuEntryInfo::needInsertion()
322
// If entry is dirty and previously stored under applnk, then we need to be added explicitly
323
return dirty && !service->entryPath().startsWith('/');
326
void MenuEntryInfo::save()
330
m_desktopFile->sync();
336
if( KHotKeys::present())
338
KHotKeys::changeMenuEntryShortcut( service->storageId(), shortCut.toString() );
340
shortcutDirty = false;
345
void MenuEntryInfo::setCaption(const QString &_caption)
347
if (caption == _caption)
351
desktopFile()->desktopGroup().writeEntry("Name", caption);
354
void MenuEntryInfo::setDescription(const QString &_description)
356
if (description == _description)
358
description = _description;
360
desktopFile()->desktopGroup().writeEntry("GenericName", description);
363
void MenuEntryInfo::setIcon(const QString &_icon)
370
desktopFile()->desktopGroup().writeEntry("Icon", icon);
373
KShortcut MenuEntryInfo::shortcut()
378
shortcutLoaded = true;
379
if( KHotKeys::present())
381
shortCut = KShortcut(KHotKeys::getMenuEntryShortcut( service->storageId() ));
388
static void freeShortcut(const KShortcut &shortCut)
390
if (!shortCut.isEmpty())
392
QString shortcutKey = shortCut.toString();
394
s_newShortcuts->removeAll(shortcutKey);
396
if (!s_freeShortcuts)
397
s_freeShortcuts = new QStringList;
399
s_freeShortcuts->append(shortcutKey);
403
static void allocateShortcut(const KShortcut &shortCut)
405
if (!shortCut.isEmpty())
407
QString shortcutKey = shortCut.toString();
409
s_freeShortcuts->removeAll(shortcutKey);
412
s_newShortcuts = new QStringList;
414
s_newShortcuts->append(shortcutKey);
418
void MenuEntryInfo::setShortcut(const KShortcut &_shortcut)
420
if (shortCut == _shortcut)
423
freeShortcut(shortCut);
424
allocateShortcut(_shortcut);
426
shortCut = _shortcut;
427
if (shortCut.isEmpty())
428
shortCut = KShortcut(); // Normalize
430
shortcutLoaded = true;
431
shortcutDirty = true;
434
void MenuEntryInfo::setInUse(bool inUse)
438
KShortcut temp = shortcut();
439
shortCut = KShortcut();
440
if (isShortcutAvailable(temp))
443
shortcutDirty = true;
444
allocateShortcut(shortCut);
447
s_deletedApps->removeAll(service->storageId());
451
freeShortcut(shortcut());
453
// Add to list of deleted apps
455
s_deletedApps = new QStringList;
457
s_deletedApps->append(service->storageId());
461
bool MenuEntryInfo::isShortcutAvailable(const KShortcut &_shortcut)
463
// We only have to check agains not saved local shortcuts.
464
// KKeySequenceWidget checks against all other registered shortcuts.
465
if (shortCut == _shortcut)
468
QString shortcutKey = _shortcut.toString();
469
bool available = true;
470
if (available && s_newShortcuts)
472
available = !s_newShortcuts->contains(shortcutKey);
474
if (!available && s_freeShortcuts)
476
available = s_freeShortcuts->contains(shortcutKey);