1 #include "applicationdialog.h"
2 #include "fileutils.h"
3
4 #include <QVBoxLayout>
5 #include <QDialogButtonBox>
6 #include <QFormLayout>
7 #include <QCompleter>
8 #include <QApplication>
9
10 /**
11 * @brief Constructor
12 * @param parent
13 */
14
ApplicationDialog(bool enable_launcher,QWidget * parent)15 ApplicationDialog::ApplicationDialog(bool enable_launcher,
16 QWidget *parent) :
17 QDialog(parent)
18 , appList(Q_NULLPTR)
19 , edtCommand(Q_NULLPTR)
20 {
21 // Title and size
22 setWindowTitle(tr("Select application"));
23 setMinimumSize(320, 320);
24
25 // Creates app list view
26 appList = new QTreeWidget(this);
27 appList->setIconSize(QSize(24, 24));
28 appList->setAlternatingRowColors(true);
29 appList->headerItem()->setText(0, tr("Application"));
30
31 // Creates buttons
32 QDialogButtonBox *buttons = new QDialogButtonBox(this);
33 buttons->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
34 connect(buttons, SIGNAL(accepted()), this, SLOT(accept()));
35 connect(buttons, SIGNAL(rejected()), this, SLOT(reject()));
36
37 // Command bar
38 edtCommand = new QLineEdit(this);
39 edtCommand->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
40 QFormLayout* layoutCommand = new QFormLayout();
41 if (enable_launcher) {
42 layoutCommand->addRow(tr("Launcher: "), edtCommand);
43 }
44
45 // Layout
46 QVBoxLayout* layout = new QVBoxLayout(this);
47 layout->addWidget(appList);
48 layout->addLayout(layoutCommand);
49 layout->addWidget(buttons);
50
51 // Synonyms for category names
52 catNames.clear();
53 catNames.insert("Development", QStringList() << "Programming");
54 catNames.insert("Games", QStringList() << "Game");
55 catNames.insert("Graphics", QStringList());
56 catNames.insert("Internet", QStringList() << "Network" << "WebBrowser");
57 catNames.insert("Multimedia", QStringList() << "AudioVideo" << "Video");
58 catNames.insert("Office", QStringList());
59 catNames.insert("Other", QStringList());
60 catNames.insert("Settings", QStringList() << "System");
61 catNames.insert("Utilities", QStringList() << "Utility");
62
63 // Load default icon
64 defaultIcon = QIcon::fromTheme("application-x-executable");
65
66 // Create completer and its model for editation of command
67 QStringListModel* model = new QStringListModel(this);
68 model->setStringList(applications.keys());
69 QCompleter* completer = new QCompleter(this);
70 completer->setModel(model);
71 edtCommand->setCompleter(completer);
72 if (!enable_launcher) { edtCommand->hide(); }
73
74 // Signals
75 connect(appList,
76 SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
77 SLOT(updateCommand(QTreeWidgetItem*,QTreeWidgetItem*)));
78
79 // populate
80 QTimer::singleShot(100, this, SLOT(populate()));
81 }
82
83 /**
84 * @brief Returns currently selected launcher
85 * @return currently selected launcher
86 */
87
getCurrentLauncher() const88 QString ApplicationDialog::getCurrentLauncher() const
89 {
90 return edtCommand->text();
91 }
92
populate()93 void ApplicationDialog::populate()
94 {
95 // Create default application categories
96 categories.clear();
97 createCategories();
98
99 // Load applications and create category tree list
100 QList<DesktopFile> apps = FileUtils::getApplications();
101 foreach (DesktopFile app, apps) {
102 // Check for name
103 if (app.getName().compare("") == 0 || app.noDisplay()) { continue; }
104
105 // Find category
106 QTreeWidgetItem* category = findCategory(app);
107
108 // Create item from current mime
109 QTreeWidgetItem *item = new QTreeWidgetItem(category);
110 item->setIcon(0, FileUtils::searchAppIcon(app, defaultIcon));
111 item->setText(0, app.getName());
112 item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
113
114 // Register application
115 QApplication::processEvents();
116 applications.insert(app.getPureFileName(), item);
117 }
118 }
119
120 /**
121 * @brief Creates default application categories
122 * @param names names of cathegories with synonyms
123 */
124
createCategories()125 void ApplicationDialog::createCategories()
126 {
127 // Create categories
128 foreach (QString name, catNames.keys()) {
129 // Find icon
130 QIcon icon = QIcon::fromTheme("applications-" + name.toLower());
131
132 // If icon not found, check synonyms
133 if (icon.isNull()) {
134 foreach (QString synonym, catNames.value(name)) {
135 icon = QIcon::fromTheme("applications-" + synonym.toLower());
136 break;
137 }
138 }
139
140 // If icon still not found, retrieve default icon
141 if (icon.isNull()) { icon = defaultIcon; }
142
143 // Create category
144 QTreeWidgetItem* category = new QTreeWidgetItem(appList);
145 category->setText(0, name);
146 category->setIcon(0, icon);
147 category->setFlags(Qt::ItemIsEnabled);
148 categories.insert(name, category);
149 }
150 }
151
152 /**
153 * @brief Searches the most suitable category for application
154 * @param app
155 * @return cathegory
156 */
157
findCategory(const DesktopFile & app)158 QTreeWidgetItem* ApplicationDialog::findCategory(const DesktopFile &app)
159 {
160 // Default category is 'Other'
161 QTreeWidgetItem* category = categories.value("Other");
162
163 // Try to find more suitable category
164 foreach (QString name, catNames.keys()) {
165 // Try cathegory name
166 if (app.getCategories().contains(name)) {
167 category = categories.value(name);
168 break;
169 }
170 // Try synonyms
171 bool found = false;
172 foreach (QString synonym, catNames.value(name)) {
173 if (app.getCategories().contains(synonym)) {
174 found = true;
175 break;
176 }
177 }
178 if (found) {
179 category = categories.value(name);
180 break;
181 }
182 }
183 return category;
184 }
185
186 /**
187 * @brief Updates launcher command
188 * @param current
189 * @param previous
190 */
191
updateCommand(QTreeWidgetItem * current,QTreeWidgetItem * previous)192 void ApplicationDialog::updateCommand(QTreeWidgetItem *current,
193 QTreeWidgetItem *previous)
194 {
195 Q_UNUSED(previous)
196 edtCommand->setText(applications.key(current));
197 }
198