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