LeechCraft  %{LEECHCRAFT_VERSION}
Modular cross-platform feature rich live environment.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
util.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 "util.h"
31 #include <functional>
32 #include <stdexcept>
33 #include <type_traits>
34 #include <QString>
35 #include <QApplication>
36 #include <QTranslator>
37 #include <QLocale>
38 #include <QFile>
39 #include <QDir>
40 #include <QTime>
41 #include <QSettings>
42 #include <QTextCodec>
43 #include <QUrl>
44 #include <QAction>
45 #include <QBuffer>
46 #include <QPainter>
47 #include <QtDebug>
48 
50 
51 QString LeechCraft::Util::GetAsBase64Src (const QImage& pix)
52 {
53  QBuffer buf;
54  buf.open (QIODevice::ReadWrite);
55  pix.save (&buf, "PNG", 100);
56  return QString ("data:image/png;base64,%1")
57  .arg (QString (buf.buffer ().toBase64 ()));
58 }
59 
61 {
62  QString string = QObject::tr ("Too long to show");
63  if (p.Additional_.contains ("UserVisibleName") &&
64  p.Additional_ ["UserVisibleName"].canConvert<QString> ())
65  string = p.Additional_ ["UserVisibleName"].toString ();
66  else if (p.Entity_.canConvert<QByteArray> ())
67  {
68  QByteArray entity = p.Entity_.toByteArray ();
69  if (entity.size () < 100)
70  string = QTextCodec::codecForName ("UTF-8")->toUnicode (entity);
71  }
72  else if (p.Entity_.canConvert<QUrl> ())
73  {
74  string = p.Entity_.toUrl ().toString ();
75  if (string.size () > 100)
76  string = string.left (97) + "...";
77  }
78  else
79  string = QObject::tr ("Binary entity");
80 
81  if (!p.Mime_.isEmpty ())
82  string += QObject::tr ("<br /><br />of type <code>%1</code>").arg (p.Mime_);
83 
84  if (!p.Additional_ ["SourceURL"].toUrl ().isEmpty ())
85  {
86  QString urlStr = p.Additional_ ["SourceURL"].toUrl ().toString ();
87  if (urlStr.size () > 63)
88  urlStr = urlStr.left (60) + "...";
89  string += QObject::tr ("<br />from %1")
90  .arg (urlStr);
91  }
92 
93  return string;
94 }
95 
96 QString LeechCraft::Util::MakePrettySize (qint64 sourcesize)
97 {
98  int strNum = 0;
99  long double size = sourcesize;
100  if (size >= 1024)
101  {
102  strNum = 1;
103  size /= 1024;
104  }
105  if (size >= 1024)
106  {
107  strNum = 2;
108  size /= 1024;
109  }
110  if (size >= 1024)
111  {
112  strNum = 3;
113  size /= 1024;
114  }
115 
116  switch (strNum)
117  {
118  case 0:
119  {
120  static const QString unit = QObject::tr (" b");
121  return QString::number (size, 'f', 1) + unit;
122  }
123  case 1:
124  {
125  static const QString unit = QObject::tr (" KiB");
126  return QString::number (size, 'f', 1) + unit;
127  }
128  case 2:
129  {
130  static const QString unit = QObject::tr (" MiB");
131  return QString::number (size, 'f', 1) + unit;
132  }
133  case 3:
134  {
135  static const QString unit = QObject::tr (" GiB");
136  return QString::number (size, 'f', 1) + unit;
137  }
138  default:
139  return "unknown";
140  }
141 }
142 
144 {
145  int d = time / 86400;
146  time -= d * 86400;
147  QString result;
148  if (d)
149  result += QObject::tr ("%n day(s), ", "", d);
150  result += QTime (0, 0, 0).addSecs (time).toString ();
151  return result;
152 }
153 
154 QTranslator* LeechCraft::Util::LoadTranslator (const QString& baseName,
155  const QString& localeName,
156  const QString& prefix,
157  const QString& appName)
158 {
159  auto filename = prefix;
160  filename.append ("_");
161  if (!baseName.isEmpty ())
162  filename.append (baseName).append ("_");
163  filename.append (localeName);
164 
165  auto transl = new QTranslator;
166 #ifdef Q_OS_WIN32
167  if (transl->load (filename, ":/") ||
168  transl->load (filename,
169  QCoreApplication::applicationDirPath () + "/translations"))
170 #elif defined (Q_OS_MAC)
171  const auto tryLocal = QApplication::arguments ().contains ("-nobundle");
172  if (transl->load (filename, ":/") ||
173  (tryLocal &&
174  transl->load (filename,
175  QString ("/usr/local/share/%1/translations").arg (appName))) ||
176  transl->load (filename,
177  QCoreApplication::applicationDirPath () + "/../Resources/translations"))
178 #elif defined (INSTALL_PREFIX)
179  if (transl->load (filename, ":/") ||
180  transl->load (filename,
181  QString (INSTALL_PREFIX "/share/%1/translations").arg (appName)))
182 #else
183  if (transl->load (filename, ":/") ||
184  transl->load (filename,
185  QString ("/usr/local/share/%1/translations").arg (appName)) ||
186  transl->load (filename,
187  QString ("/usr/share/%1/translations").arg (appName)))
188 #endif
189  return transl;
190 
191  delete transl;
192 
193  return nullptr;
194 }
195 
196 QTranslator* LeechCraft::Util::InstallTranslator (const QString& baseName,
197  const QString& prefix,
198  const QString& appName)
199 {
200  const auto& localeName = GetLocaleName ();
201  if (auto transl = LoadTranslator (baseName, localeName, prefix, appName))
202  {
203  qApp->installTranslator (transl);
204  return transl;
205  }
206 
207  qWarning () << Q_FUNC_INFO
208  << "could not load translation file for locale"
209  << localeName
210  << baseName
211  << prefix
212  << appName;
213  return nullptr;
214 }
215 
217 {
218  QSettings settings (QCoreApplication::organizationName (),
219  QCoreApplication::applicationName ());
220  QString localeName = settings.value ("Language", "system").toString ();
221 
222  if (localeName == "system")
223  {
224  localeName = QString (::getenv ("LANG")).left (5);
225  if (localeName.isEmpty () || localeName.size () != 5)
226  localeName = QLocale::system ().name ();
227  localeName = localeName.left (5);
228  }
229 
230  if (localeName.size () == 2)
231  {
232  QLocale::Language lang = QLocale (localeName).language ();
233  QList<QLocale::Country> cs = QLocale::countriesForLanguage (lang);
234  if (cs.isEmpty ())
235  localeName += "_00";
236  else
237  localeName = QLocale (lang, cs.at (0)).name ();
238  }
239 
240  return localeName;
241 }
242 
243 QString LeechCraft::Util::GetInternetLocaleName (const QLocale& locale)
244 {
245 #if QT_VERSION >= 0x040800
246  if (locale.language () == QLocale::AnyLanguage)
247  return "*";
248 #endif
249 
250  QString locStr = locale.name ();
251  locStr.replace ('_', '-');
252  return locStr;
253 }
254 
256 {
257  return GetLocaleName ().left (2);
258 }
259 
260 QModelIndexList LeechCraft::Util::GetSummarySelectedRows (QObject *sender)
261 {
262  QAction *senderAct = qobject_cast<QAction*> (sender);
263  if (!senderAct)
264  {
265  QString debugString;
266  {
267  QDebug d (&debugString);
268  d << "sender is not a QAction*"
269  << sender;
270  }
271  throw std::runtime_error (qPrintable (debugString));
272  }
273 
274  return senderAct->
275  property ("SelectedRows").value<QList<QModelIndex>> ();
276 }
277 
278 QAction* LeechCraft::Util::CreateSeparator (QObject *parent)
279 {
280  QAction *result = new QAction (parent);
281  result->setSeparator (true);
282  return result;
283 }
284 
286  const QString& text, QFont font, const QPen& pen, const QBrush& brush)
287 {
288  const auto& iconSize = px.size ();
289 
290  const auto fontHeight = px.height () * 0.45;
291  font.setPixelSize (std::max (6., fontHeight));
292 
293  const QFontMetrics fm (font);
294  const auto width = fm.width (text) + 2. * px.width () / 10.;
295  const auto height = fm.height () + 2. * px.height () / 10.;
296  const bool tooSmall = width > iconSize.width ();
297 
298  const QRect textRect (iconSize.width () - width, iconSize.height () - height, width, height);
299 
300  QPainter p (&px);
301  p.setBrush (brush);
302  p.setFont (font);
303  p.setPen (pen);
304  p.setRenderHint (QPainter::Antialiasing);
305  p.setRenderHint (QPainter::TextAntialiasing);
306  p.setRenderHint (QPainter::HighQualityAntialiasing);
307  p.drawRoundedRect (textRect, 4, 4);
308  p.drawText (textRect,
309  Qt::AlignCenter,
310  tooSmall ? "#" : text);
311  p.end ();
312 
313  return px;
314 }
315 
316 namespace
317 {
318  template<typename To, typename From>
319  typename std::enable_if<std::is_same<From, To>::value, To>::type DumbCast (From from)
320  {
321  return from;
322  }
323 
324  template<typename To, typename From>
325  typename std::enable_if<!std::is_same<From, To>::value &&
326  std::is_integral<From>::value &&
327  std::is_integral<To>::value, To>::type DumbCast (From from)
328  {
329  return static_cast<To> (from);
330  }
331 
332  template<typename To, typename From>
333  typename std::enable_if<!std::is_same<From, To>::value &&
334  !(std::is_integral<From>::value &&
335  std::is_integral<To>::value), To>::type DumbCast (From from)
336  {
337  return reinterpret_cast<To> (from);
338  }
339 }
340 
341 uintptr_t LeechCraft::Util::Handle2Num (Qt::HANDLE handle)
342 {
343  return DumbCast<uintptr_t> (handle);
344 }
Q_DECLARE_METATYPE(QList< QModelIndex >)
UTIL_API QString MakePrettySize(qint64 sourceSize)
Makes a formatted size from number.
Definition: util.cpp:96
UTIL_API QTranslator * LoadTranslator(const QString &base, const QString &locale, const QString &prefix="leechcraft", const QString &appname="leechcraft")
Definition: util.cpp:154
UTIL_API uintptr_t Handle2Num(Qt::HANDLE handle)
Converts the handle to an integer.
Definition: util.cpp:341
UTIL_API QString GetLocaleName()
Returns the current locale name, like en_US.
Definition: util.cpp:216
UTIL_API QString MakeTimeFromLong(ulong time)
Makes a formatted time from number.
Definition: util.cpp:143
UTIL_API QString GetLanguage()
Returns the current language name.
Definition: util.cpp:255
UTIL_API QString GetInternetLocaleName(const QLocale &)
Definition: util.cpp:243
UTIL_API QTranslator * InstallTranslator(const QString &base, const QString &prefix="leechcraft", const QString &appname="leechcraft")
Loads and installs a translator.
Definition: util.cpp:196
UTIL_API QAction * CreateSeparator(QObject *parent)
Returns the action that is set to act as a separator.
Definition: util.cpp:278
UTIL_API QString GetUserText(const Entity &entity)
Return the user-readable representation of the entity.
Definition: util.cpp:60
UTIL_API QPixmap DrawOverlayText(QPixmap px, const QString &text, QFont font, const QPen &pen, const QBrush &brush)
Definition: util.cpp:285
UTIL_API QString GetAsBase64Src(const QImage &image)
Returns the given image in a Base64-encoded form.
Definition: util.cpp:51
UTIL_API QModelIndexList GetSummarySelectedRows(QObject *sender)
Definition: util.cpp:260
QMap< QString, QVariant > Additional_
Additional parameters.
Definition: structures.h:225
QString Mime_
MIME type of the entity.
Definition: structures.h:209
QVariant Entity_
The entity that this object represents.
Definition: structures.h:173
Describes parameters of an entity.
Definition: structures.h:156