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