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