LeechCraft  0.6.70-10870-g558588d6ec
Modular cross-platform feature rich live environment.
item.cpp
Go to the documentation of this file.
1 /**********************************************************************
2  * LeechCraft - modular cross-platform feature rich internet client.
3  * Copyright (C) 2006-2014 Georg Rudoy
4  *
5  * Boost Software License - Version 1.0 - August 17th, 2003
6  *
7  * Permission is hereby granted, free of charge, to any person or organization
8  * obtaining a copy of the software and accompanying documentation covered by
9  * this license (the "Software") to use, reproduce, display, distribute,
10  * execute, and transmit the Software, and to prepare derivative works of the
11  * Software, and to permit third-parties to whom the Software is furnished to
12  * do so, all subject to the following:
13  *
14  * The copyright notices in the Software and this entire statement, including
15  * the above license grant, this restriction and the following disclaimer,
16  * must be included in all copies of the Software, in whole or in part, and
17  * all derivative works of the Software, unless such copies or derivative
18  * works are solely in the form of machine-executable object code generated by
19  * a source language processor.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
24  * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
25  * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
26  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27  * DEALINGS IN THE SOFTWARE.
28  **********************************************************************/
29 
30 #include "item.h"
31 #include <stdexcept>
32 #include <QFile>
33 #include <QUrl>
34 #include <QProcess>
35 #include <util/xpc/util.h>
38 #include "desktopparser.h"
39 #include "xdg.h"
40 
41 namespace LeechCraft
42 {
43 namespace Util
44 {
45 namespace XDG
46 {
47  bool operator== (const Item& left, const Item& right)
48  {
49  return left.IsHidden_ == right.IsHidden_ &&
50  left.Type_ == right.Type_ &&
51  left.Name_ == right.Name_ &&
52  left.GenericName_ == right.GenericName_ &&
53  left.Comments_ == right.Comments_ &&
54  left.Categories_ == right.Categories_ &&
55  left.Command_ == right.Command_ &&
56  left.WD_ == right.WD_ &&
57  left.IconName_ == right.IconName_;
58  }
59 
60  bool operator!= (const Item& left, const Item& right)
61  {
62  return !(left == right);
63  }
64 
65  bool Item::IsValid () const
66  {
67  return !Name_.isEmpty ();
68  }
69 
70  bool Item::IsHidden () const
71  {
72  return IsHidden_;
73  }
74 
75  void Item::Execute (ICoreProxy_ptr proxy) const
76  {
77  auto command = GetCommand ();
78 
79  if (GetType () == Type::Application)
80  {
81  command.remove ("%c");
82  command.remove ("%f");
83  command.remove ("%F");
84  command.remove ("%u");
85  command.remove ("%U");
86  command.remove ("%i");
87  auto items = command.split (' ', QString::SkipEmptyParts);
88  auto removePred = [] (const QString& str)
89  { return str.size () == 2 && str.at (0) == '%'; };
90  items.erase (std::remove_if (items.begin (), items.end (), removePred),
91  items.end ());
92  if (items.isEmpty ())
93  return;
94 
95  QProcess::startDetached (items.at (0), items.mid (1), GetWorkingDirectory ());
96  }
97  else if (GetType () == Type::URL)
98  {
99  const auto& e = Util::MakeEntity (QUrl (command),
100  QString (),
102  proxy->GetEntityManager ()->HandleEntity (e);
103  }
104  else
105  {
106  qWarning () << Q_FUNC_INFO
107  << "don't know how to execute this type of app";
108  }
109  }
110 
111  namespace
112  {
113  QString ByLang (const QHash<QString, QString>& cont, const QString& lang)
114  {
115  return cont.value (cont.contains (lang) ? lang : QString ());
116  }
117  }
118 
119  QString Item::GetName (const QString& lang) const
120  {
121  return ByLang (Name_, lang);
122  }
123 
124  QString Item::GetGenericName (const QString& lang) const
125  {
126  return ByLang (GenericName_, lang);
127  }
128 
129  QString Item::GetComment (const QString& lang) const
130  {
131  return ByLang (Comments_, lang);
132  }
133 
134  QString Item::GetIconName () const
135  {
136  return IconName_;
137  }
138 
139  QStringList Item::GetCategories () const
140  {
141  return Categories_;
142  }
143 
145  {
146  return Type_;
147  }
148 
149  QString Item::GetCommand () const
150  {
151  return Command_;
152  }
153 
154  QString Item::GetWorkingDirectory () const
155  {
156  return WD_;
157  }
158 
159  QString Item::GetPermanentID () const
160  {
161  return GetCommand ();
162  }
163 
164  namespace
165  {
166  QIcon GetIconDevice (const ICoreProxy_ptr& proxy, QString name)
167  {
168  if (name.isEmpty ())
169  return QIcon ();
170 
171  if (name.endsWith (".png") || name.endsWith (".svg"))
172  name.chop (4);
173 
174  auto result = proxy->GetIconThemeManager ()->GetIcon (name);
175  if (!result.isNull ())
176  return result;
177 
178  result = GetAppIcon (name);
179  if (!result.isNull ())
180  return result;
181 
182  qDebug () << Q_FUNC_INFO << name << "not found";
183 
184  return result;
185  }
186  }
187 
188  QIcon Item::GetIcon (const ICoreProxy_ptr& proxy) const
189  {
190  if (!Icon_)
191  Icon_ = GetIconDevice (proxy, GetIconName ());
192 
193  return *Icon_;
194  }
195 
196  QDebug Item::DebugPrint (QDebug dbg) const
197  {
198  dbg.nospace () << "DesktopItem\n{\n\tNames: " << Name_
199  << "\n\tGenericNames: " << GenericName_
200  << "\n\tComments: " << Comments_
201  << "\n\tCategories: " << Categories_
202  << "\n\tCommand: " << Command_
203  << "\n\tWorkingDir: " << WD_
204  << "\n\tIconName: " << IconName_
205  << "\n\tHidden: " << IsHidden_
206  << "\n}\n";
207  return dbg.space ();
208  }
209 
210  namespace
211  {
212  QHash<QString, QString> FirstValues (const QHash<QString, QStringList>& hash)
213  {
214  QHash<QString, QString> result;
215  for (auto i = hash.begin (), end = hash.end (); i != end; ++i)
216  result [i.key ()] = i->value (0);
217  return result;
218  }
219  }
220 
221  Item_ptr Item::FromDesktopFile (const QString& filename)
222  {
223  QFile file (filename);
224  if (!file.open (QIODevice::ReadOnly))
225  throw std::runtime_error ("Unable to open file");
226 
227  const auto& result = Util::XDG::DesktopParser {} (file.readAll ());
228  const auto& group = result ["Desktop Entry"];
229 
230  const auto& item = std::make_shared<Item> ();
231  item->Name_ = FirstValues (group ["Name"]);
232  item->GenericName_ = FirstValues (group ["GenericName"]);
233  item->Comments_ = FirstValues (group ["Comment"]);
234 
235  item->Categories_ = group ["Categories"] [{}];
236 
237  auto getSingle = [&group] (const QString& name) { return group [name] [{}].value (0); };
238 
239  item->IconName_ = getSingle ("Icon");
240 
241  const auto& typeStr = getSingle ("Type");
242  if (typeStr == "Application")
243  {
244  item->Type_ = Type::Application;
245  item->Command_ = getSingle ("Exec");
246  item->WD_ = getSingle ("Path");
247  }
248  else if (typeStr == "URL")
249  {
250  item->Type_ = Type::URL;
251  item->Command_ = getSingle ("URL");
252  }
253  else if (typeStr == "Directory")
254  item->Type_ = Type::Dir;
255  else
256  item->Type_ = Type::Other;
257 
258  item->IsHidden_ = getSingle ("NoDisplay").toLower () == "true";
259 
260  return item;
261  }
262 
263  QDebug operator<< (QDebug dbg, const Item& item)
264  {
265  return item.DebugPrint (dbg);
266  }
267 }
268 }
269 }
Entity MakeEntity(const QVariant &entity, const QString &location, TaskParameters tp, const QString &mime)
Definition: util.cpp:105
void Execute(ICoreProxy_ptr proxy) const
Executes this item, if possible.
Definition: item.cpp:75
A shortcut to an URL.
std::shared_ptr< Item > Item_ptr
Definition: item.h:49
bool operator!=(const Item &left, const Item &right)
Definition: item.cpp:60
QString GetIconName() const
Returns the name of the icon for this item.
Definition: item.cpp:134
Describes a single XDG .desktop entry.
Definition: item.h:60
static Item_ptr FromDesktopFile(const QString &file)
Loads the XDG .desktop item from file.
Definition: item.cpp:221
A shortcut to an application.
QStringList GetCategories() const
Returns the categories where this item belongs.
Definition: item.cpp:139
bool IsValid() const
Checks whether this XDG item is valid.
Definition: item.cpp:65
bool operator==(const Item &left, const Item &right)
Definition: item.cpp:47
QString GetName(const QString &language) const
Returns the name of this item.
Definition: item.cpp:119
QDebug DebugPrint(QDebug stream) const
Serializes item contents to the debugging stream.
Definition: item.cpp:196
Type
Describes the various types of XDG .desktop files.
Definition: itemtypes.h:48
QString GetComment(const QString &language) const
Returns the comment of this item.
Definition: item.cpp:129
QString GetPermanentID() const
Returns the permanent ID of this item.
Definition: item.cpp:159
std::shared_ptr< ICoreProxy > ICoreProxy_ptr
Definition: icoreproxy.h:225
QString GetCommand() const
Returns type type-specific command for this item.
Definition: item.cpp:149
QString GetGenericName(const QString &language) const
Returns the generic name of this item.
Definition: item.cpp:124
QIcon GetAppIcon(const QString &name)
Definition: xdg.cpp:40
bool IsHidden() const
Checks whether this XDG item should be hidden.
Definition: item.cpp:70
QString GetWorkingDirectory() const
Returns the working directory for command execution.
Definition: item.cpp:154
QIcon GetIcon(const ICoreProxy_ptr &) const
Returns the icon previously set by SetIcon().
Definition: item.cpp:188
QDebug operator<<(QDebug dbg, const Item &item)
Serializes item contents to the debugging stream.
Definition: item.cpp:263
Type GetType() const
Returns the type of this item.
Definition: item.cpp:144
A shortcut to a directory.
A parser for XDG .desktop files.
Definition: desktopparser.h:51