Skip to content
This repository

razor-config based on XDG Desktop Menu Specification #266

Merged
merged 4 commits into from over 2 years ago

2 participants

Alexander Sokolov Petr Vanek
Alexander Sokolov
Owner

razor-config based on XDG Desktop Menu Specification

razor-config GUI improvement

Petr Vanek pvanek merged commit 10ab181 into from
Petr Vanek pvanek closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 4 unique commits by 1 author.

Apr 05, 2012
Alexander Sokolov SokoloffA razor-config based on XDG Desktop Menu Specification fc0454b
Apr 06, 2012
Alexander Sokolov SokoloffA Merge branch 'master' of github.com:Razor-qt/razor-qt
Conflicts:
	razorqt-config/src/mainwindow.cpp
	razorqt-config/src/mainwindow.h
	razorqt-config/src/mainwindow.ui
a23bf72
Alexander Sokolov SokoloffA razor-config based on XDG Desktop Menu Specification 2 aa1689a
Alexander Sokolov SokoloffA razor-config GUI improvement 5cc3829
This page is out of date. Refresh to see the latest.
1  razorqt-config/src/CMakeLists.txt
@@ -39,3 +39,4 @@ target_link_libraries( razor-config qcategorizedview)
39 39
40 40 INSTALL(TARGETS razor-config RUNTIME DESTINATION bin)
41 41 install(FILES ${DESKTOP_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications)
  42 +install(FILES razor-config.menu DESTINATION /etc/xdg/menus/)
128 razorqt-config/src/mainwindow.cpp
@@ -30,9 +30,12 @@
30 30
31 31 #include "mainwindow.h"
32 32 #include <QtDebug>
  33 +#include <QtGui/QMessageBox>
33 34
34 35 #include <qtxdg/xdgdesktopfile.h>
35 36 #include <qtxdg/xdgicon.h>
  37 +#include <qtxdg/xdgmenu.h>
  38 +#include <qtxdg/xmlhelper.h>
36 39 #include <razorqt/razoraboutdlg.h>
37 40
38 41 #include "qcategorizedview.h"
@@ -45,7 +48,7 @@ struct ConfigPaneData: public QSharedData
45 48 {
46 49 QString id;
47 50 QString category;
48   - XdgDesktopFile *xdg;
  51 + XdgDesktopFile xdg;
49 52 };
50 53
51 54 class ConfigPane
@@ -55,8 +58,8 @@ class ConfigPane
55 58 ConfigPane(const ConfigPane &other): d(other.d) { }
56 59
57 60 inline QString &id() const { return d->id; }
58   - inline XdgDesktopFile* xdg() const { return d->xdg; }
59   - inline void setXdg(XdgDesktopFile* xdg) { d->xdg = xdg; }
  61 + inline XdgDesktopFile xdg() const { return d->xdg; }
  62 + inline void setXdg(XdgDesktopFile xdg) { d->xdg = xdg; }
60 63 inline QString &category() const { return d->category; }
61 64
62 65 bool operator==(const ConfigPane &other)
@@ -68,96 +71,59 @@ class ConfigPane
68 71 QExplicitlySharedDataPointer<ConfigPaneData> d;
69 72 };
70 73
71   -static QStringList preferredCategoryOrder;
72   -
73   -static bool categorySorter(const ConfigPane &a, const ConfigPane &b)
74   -{
75   - int aIdx = preferredCategoryOrder.indexOf(a.category());
76   - int bIdx = preferredCategoryOrder.indexOf(b.category());
77   - if (aIdx < 0)
78   - return false;
79   - return aIdx < bIdx;
80   -}
81 74
82 75 class ConfigPaneModel: public QAbstractListModel
83 76 {
84 77 public:
85 78 ConfigPaneModel(): QAbstractListModel()
86 79 {
87   - if (preferredCategoryOrder.isEmpty()) {
88   - preferredCategoryOrder << "Razor" << "System" << "Other";
  80 + QString menuFile = XdgMenu::getMenuFileName("config.menu");
  81 + XdgMenu xdgMenu;
  82 + xdgMenu.setEnvironments(QStringList() << "X-RAZOR" << "RAZOR");
  83 + bool res = xdgMenu.read(menuFile);
  84 + if (!res)
  85 + {
  86 + QMessageBox::warning(0, "Parse error", xdgMenu.errorString());
  87 + return;
89 88 }
90   -
91   - QDirIterator it("/usr/share/applications", QStringList() << "*.desktop", QDir::NoFilter, QDirIterator::Subdirectories);
92   - QString name;
93   - QString categories;
  89 +
  90 + DomElementIterator it(xdgMenu.xml().documentElement() , "Menu");
  91 + while(it.hasNext())
  92 + {
  93 + this->builGroup(it.next());
  94 + }
  95 +
  96 + }
  97 +
  98 + void builGroup(const QDomElement& xml)
  99 + {
94 100 QString category;
95   - QString onlyShowIn;
96   -
97   - while (it.hasNext()) {
98   - name = it.next();
99   - XdgDesktopFile *xdg = new XdgDesktopFile();
100   - xdg->load(name);
101   - if (!xdg->isValid())
102   - {
103   - qDebug() << "INVALID DESKTOP FILE:" << name;
104   - delete xdg;
105   - continue;
106   - }
107   -
108   - onlyShowIn = xdg->value("OnlyShowIn").toString();
109   - if (!onlyShowIn.isEmpty()
110   - && !onlyShowIn.contains("X-RAZOR") && !onlyShowIn.contains("RAZOR")
111   - //&& !onlyShowIn.contains("YaST")
112   - )
113   - {
114   - qDebug() << "NOT SHOWN" << name << onlyShowIn;
115   - delete xdg;
116   - continue;
117   - }
118   -
119   - // do not show self
120   - if (xdg->value("Exec").toString() == "razor-config")
121   - {
122   - delete xdg;
123   - continue;
124   - }
125   -
126   - categories = xdg->value("Categories").toString();
127   - if (!categories.contains("Settings"))
128   - {
129   - delete xdg;
130   - continue;
131   - }
132   -
133   - if (categories.contains("X-RAZOR") || categories.contains("RAZOR"))
134   - {
135   - category = "Razor";
136   - }
137   - else if (categories.contains("System"))
138   - {
139   - category = "System";
140   - }
141   - else
142   - {
143   - category = "Other";
144   - }
145   -
  101 + if (! xml.attribute("title").isEmpty())
  102 + category = xml.attribute("title");
  103 + else
  104 + category = xml.attribute("name");
  105 +
  106 + DomElementIterator it(xml , "AppLink");
  107 + while(it.hasNext())
  108 + {
  109 + QDomElement x = it.next();
  110 +
  111 + XdgDesktopFile xdg;
  112 + xdg.load(x.attribute("desktopFile"));
  113 +
146 114 ConfigPane pane;
147   - pane.id() = xdg->value("Icon").toString();
  115 + pane.id() = xdg.value("Icon").toString();
148 116 pane.category() = category;
149 117 pane.setXdg(xdg);
150 118 m_list.append(pane);
151 119 }
152   -
153   - qSort(m_list.begin(), m_list.end(), categorySorter);
154 120 }
155   -
  121 +
156 122 void activateItem(const QModelIndex &index)
157 123 {
158 124 if (!index.isValid())
159 125 return;
160   - m_list[index.row()].xdg()->startDetached();
  126 + m_list[index.row()].xdg().startDetached();
161 127 }
162 128
163 129 ~ConfigPaneModel() { }
@@ -175,7 +141,7 @@ class ConfigPaneModel: public QAbstractListModel
175 141 QVariant data(const QModelIndex &index, int role) const
176 142 {
177 143 if (role == Qt::DisplayRole)
178   - return m_list[index.row()].xdg()->name();
  144 + return m_list[index.row()].xdg().name();
179 145 if (role == QCategorizedSortFilterProxyModel::CategoryDisplayRole)
180 146 return m_list[index.row()].category();
181 147 if (role == QCategorizedSortFilterProxyModel::CategorySortRole)
@@ -184,7 +150,7 @@ class ConfigPaneModel: public QAbstractListModel
184 150 return m_list[index.row()].id();
185 151 if (role == Qt::DecorationRole)
186 152 {
187   - return m_list[index.row()].xdg()->icon(XdgIcon::defaultApplicationIcon());
  153 + return m_list[index.row()].xdg().icon(XdgIcon::defaultApplicationIcon());
188 154 }
189 155 return QVariant();
190 156 }
@@ -192,18 +158,18 @@ class ConfigPaneModel: public QAbstractListModel
192 158 private:
193 159 QList<ConfigPane> m_list;
194 160 };
195   -
  161 +
196 162 }
197 163
198 164
199 165 RazorConfig::MainWindow::MainWindow() : QMainWindow()
200 166 {
201 167 setupUi(this);
202   -
  168 +
203 169 model = new ConfigPaneModel();
204 170
205 171 view->setViewMode(QListView::IconMode);
206   - view->setIconSize(QSize(48, 48));
  172 + view->setIconSize(QSize(32, 32));
207 173 view->setGridSize(QSize(140, 74));
208 174 view->setCategoryDrawer(new QCategoryDrawerV3(view));
209 175
@@ -212,7 +178,7 @@ RazorConfig::MainWindow::MainWindow() : QMainWindow()
212 178 proxyModel->setSourceModel(model);
213 179
214 180 view->setModel(proxyModel);
215   -
  181 +
216 182 connect(view, SIGNAL(activated(const QModelIndex&)),
217 183 this, SLOT(activateItem(const QModelIndex&)));
218 184 }
4 razorqt-config/src/mainwindow.h
@@ -31,6 +31,7 @@
31 31
32 32
33 33 #include "ui_mainwindow.h"
  34 +#include <QtXml/QDomElement>
34 35
35 36 class QCategorizedSortFilterProxyModel;
36 37
@@ -53,6 +54,9 @@ class MainWindow : public QMainWindow, public Ui::MainWindow
53 54 QCategorizedSortFilterProxyModel *proxyModel;
54 55 ConfigPaneModel *model;
55 56
  57 +private:
  58 + void builGroup(const QDomElement& xml);
  59 +
56 60 private slots:
57 61 void activateItem(const QModelIndex &index);
58 62 };
40 razorqt-config/src/mainwindow.ui
@@ -6,25 +6,45 @@
6 6 <rect>
7 7 <x>0</x>
8 8 <y>0</y>
9   - <width>548</width>
10   - <height>368</height>
  9 + <width>696</width>
  10 + <height>404</height>
11 11 </rect>
12 12 </property>
13 13 <property name="windowTitle">
14 14 <string>Razor Configuration Center</string>
15 15 </property>
16 16 <widget class="QWidget" name="centralwidget">
17   - <layout class="QGridLayout" name="gridLayout">
18   - <item row="0" column="0" colspan="2">
19   - <widget class="QCategorizedView" name="view"/>
20   - </item>
21   - <item row="1" column="0" colspan="2">
22   - <widget class="QDialogButtonBox" name="buttonBox">
23   - <property name="standardButtons">
24   - <set>QDialogButtonBox::Close</set>
  17 + <layout class="QVBoxLayout" name="verticalLayout">
  18 + <property name="leftMargin">
  19 + <number>0</number>
  20 + </property>
  21 + <property name="topMargin">
  22 + <number>1</number>
  23 + </property>
  24 + <property name="rightMargin">
  25 + <number>1</number>
  26 + </property>
  27 + <item>
  28 + <widget class="QCategorizedView" name="view">
  29 + <property name="frameShape">
  30 + <enum>QFrame::NoFrame</enum>
25 31 </property>
26 32 </widget>
27 33 </item>
  34 + <item>
  35 + <layout class="QHBoxLayout" name="horizontalLayout">
  36 + <property name="margin">
  37 + <number>4</number>
  38 + </property>
  39 + <item>
  40 + <widget class="QDialogButtonBox" name="buttonBox">
  41 + <property name="standardButtons">
  42 + <set>QDialogButtonBox::Close</set>
  43 + </property>
  44 + </widget>
  45 + </item>
  46 + </layout>
  47 + </item>
28 48 </layout>
29 49 </widget>
30 50 </widget>
66 razorqt-config/src/razor-config.menu
... ... @@ -0,0 +1,66 @@
  1 +<!DOCTYPE Menu PUBLIC '-//freedesktop//DTD Menu 1.0//EN' 'http://www.freedesktop.org/standards/menu-spec/1.0/menu.dtd'>
  2 +<Menu>
  3 + <Name>Settings</Name>
  4 + <Directory>razor-menu-applications.directory</Directory>
  5 + <!-- Read standard .directory and .desktop file locations -->
  6 + <DefaultAppDirs/>
  7 + <DefaultDirectoryDirs/>
  8 + <!-- Read in overrides and child menus from applications-merged/ -->
  9 + <DefaultMergeDirs/>
  10 + <Include>
  11 + <Category>Settings</Category>
  12 + </Include>
  13 +
  14 +
  15 + <Menu>
  16 + <Name>Razor settings</Name>
  17 + <Directory>razor-settings-razor.directory</Directory>
  18 + <Include>
  19 + <And>
  20 + <Category>Settings</Category>
  21 + <Or>
  22 + <Category>X-RAZOR</Category>
  23 + <Category>RAZOR</Category>
  24 + </Or>
  25 + <Not>
  26 + <Filename>razor-config.desktop</Filename>
  27 + </Not>
  28 + </And>
  29 + </Include>
  30 + </Menu>
  31 +
  32 + <Menu>
  33 + <Name>System settings</Name>
  34 + <Directory>razor-settings-system.directory</Directory>
  35 + <Include>
  36 + <And>
  37 + <Category>Settings</Category>
  38 + <Category>System</Category>
  39 + </And>
  40 + </Include>
  41 + </Menu>
  42 +
  43 + <Menu>
  44 + <Name>Other settings</Name>
  45 + <Directory>razor-settings-other.directory</Directory>
  46 + <Include>
  47 + <And>
  48 + <Category>Settings</Category>
  49 + <Not>
  50 + <Or>
  51 + <Category>X-RAZOR</Category>
  52 + <Category>RAZOR</Category>
  53 + <Category>System</Category>
  54 + </Or>
  55 + </Not>
  56 + </And>
  57 + </Include>
  58 + </Menu>
  59 +
  60 + <Layout>
  61 + <Menuname>Razor settings</Menuname>
  62 + <Menuname>System settings</Menuname>
  63 + <Merge type="menus"/>
  64 + </Layout>
  65 +</Menu>
  66 +
7 razorqt-resources/application-menu/desktop-directories/razor-settings-other.directory
... ... @@ -0,0 +1,7 @@
  1 +[Desktop Entry]
  2 +Encoding=UTF-8
  3 +Type=Directory
  4 +Name=Other settings
  5 +Name[ru]=Прочие настройки
  6 +Icon=razor-qt-system
  7 +X-Ubuntu-Gettext-Domain=desktop_kdebase-runtime

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.