libyui-qt-pkg  2.42.5
 All Classes Functions Variables Enumerations
YQPkgDescriptionView.cc
1 /**************************************************************************
2 Copyright (C) 2000 - 2010 Novell, Inc.
3 All Rights Reserved.
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 
19 **************************************************************************/
20 
21 
22 /*---------------------------------------------------------------------\
23 | |
24 | __ __ ____ _____ ____ |
25 | \ \ / /_ _/ ___|_ _|___ \ |
26 | \ V / _` \___ \ | | __) | |
27 | | | (_| |___) || | / __/ |
28 | |_|\__,_|____/ |_| |_____| |
29 | |
30 | core system |
31 | (C) SuSE GmbH |
32 \----------------------------------------------------------------------/
33 
34  File: YQPkgDescriptionView.cc
35 
36  Author: Stefan Hundhammer <sh@suse.de>
37 
38  Textdomain "qt-pkg"
39 
40 /-*/
41 
42 #define YUILogComponent "qt-pkg"
43 #include "YUILog.h"
44 #include <QRegExp>
45 #include <QFile>
46 #include <QFileInfo>
47 #include <QList>
48 #include <QSettings>
49 #include "zypp/VendorSupportOptions.h"
50 #include "YQPkgDescriptionView.h"
51 #include "YQPkgDescriptionDialog.h"
52 #include "YQi18n.h"
53 #include "utf8.h"
54 
55 #define DESKTOP_TRANSLATIONS "desktop_translations"
56 #define DESKTOPFILEDIR "\\/share\\/applications\\/.*\\.desktop$" // RegExp
57 #define ICONSIZE "32x32"
58 #define ICONPATH "/usr/share/icons/locolor/" ICONSIZE "/apps/" \
59  << "/usr/share/icons/hicolor/" ICONSIZE "/apps/" \
60  << "/usr/share/icons/oxygen/" ICONSIZE "/apps/" \
61  << "/usr/share/icons/Tango/" ICONSIZE "/apps/" \
62  << "/usr/share/icons/gnome/" ICONSIZE "/apps/" \
63  << "/opt/kde3/share/icons/hicolor/" ICONSIZE "/apps/";
64 
65 
66 
67 using std::list;
68 using std::endl;
69 using std::string;
70 using namespace zypp;
71 
72 YQPkgDescriptionView::YQPkgDescriptionView( QWidget * parent, bool showSupportability )
73  : YQPkgGenericDetailsView( parent )
74  , _showSupportability ( showSupportability )
75 {
76  //FIXME setMimeSourceFactory( 0 );
77  initLang();
78 }
79 
80 
82 {
83  // NOP
84 }
85 
86 
87 void
88 YQPkgDescriptionView::showDetails( ZyppSel selectable )
89 {
90  _selectable = selectable;
91 
92  if ( ! selectable )
93  {
94  clear();
95  return;
96  }
97 
98  QString html_text = htmlStart();
99 
100  html_text += htmlHeading( selectable );
101 
102  QString description = fromUTF8( selectable->theObj()->description() );
103 
104  if ( ! description.contains( "<!-- DT:Rich -->" ) )
105  description = simpleHtmlParagraphs( description );
106 
107  html_text += ( "<p>" + description + "</p>");
108 
109  // if the object is a patch, show the problem references too
110  Patch::constPtr patch = asKind<Patch>(selectable->theObj());
111  if ( patch )
112  {
113  html_text += "<p>";
114  html_text += _("References:");
115  html_text += "</p>";
116  html_text += "<ul>";
117 
118  for ( Patch::ReferenceIterator rit = patch->referencesBegin();
119  rit != patch->referencesEnd();
120  ++rit )
121  {
122  html_text += QString().sprintf("<li>%s (%s) : %s</li>", rit.id().c_str(), rit.type().c_str(), rit.title().c_str() );
123  }
124  html_text += "</ul>";
125  }
126 
127  // if it is a package, show the support information
128  Package::constPtr package = asKind<Package>(selectable->theObj());
129  if ( _showSupportability && package )
130  {
131  html_text += "<p>";
132  // Translators: %1 contains the support level like "Level 3", "unsupported" or "unknown"
133  html_text += _("Supportability: %1").arg( fromUTF8(asUserString(package->vendorSupport()).c_str() ));
134  html_text += "</p>";
135  }
136 
137  // show application names and icons from desktop files if available
138  ZyppPkg installed = tryCastToZyppPkg( selectable->installedObj() );
139  if ( installed )
140  {
141  // ma@: It might be worth passing Package::FileList directly
142  // instead of copying _all_ filenames into a list first.
143  // Package::FileList is a query, so it does not eat much memory.
144  zypp::Package::FileList f( installed->filelist() );
145  std::list<std::string> tmp( f.begin(), f.end() );
146  html_text += applicationIconList( tmp );
147  }
148 
149  html_text += htmlEnd();
150  setHtml( html_text );
151  //FIXME ensureVisible( 0, 0 ); // Otherwise hyperlinks will be centered
152 }
153 
154 
155 
157 {
158  bool foundAuthorsList = false;
159  QString html_text = "<p>";
160 
161  QStringList lines = text.trimmed().split( '\n', QString::KeepEmptyParts );
162  QStringList::const_iterator it = lines.begin();
163 
164  while ( it != lines.end() )
165  {
166  QString line = htmlEscape( *it ).trimmed();
167 
168  if ( line.startsWith("* ") || line.startsWith("- ") || line.startsWith("# ") )
169  {
170  line = "<li>" + line + "</li>";
171  }
172 
173  if ( line.startsWith( "Authors:" ) )
174  {
175  line = "<p><b>" + line + "</b><ul>";
176  foundAuthorsList = true;
177  }
178 
179  if ( foundAuthorsList )
180  {
181  if ( ! line.startsWith( "-----" ) && ! line.isEmpty() )
182  html_text += "<li>" + line + "</li>";
183  }
184  else
185  {
186  if ( line.isEmpty() )
187  html_text += "</p><p>";
188  else
189  html_text += " " + line;
190  }
191 
192 
193 
194 
195  ++it;
196  }
197 
198  if ( foundAuthorsList )
199  html_text += "</ul>";
200 
201  html_text += "</p>";
202 
203  return html_text;
204 }
205 
206 
207 void
209 {
210  if ( url.scheme() == "pkg" )
211  {
212  QString pkgName = url.authority();
213  yuiMilestone() << "Hyperlinking to package \"" << pkgName << "\"" << endl;
215  }
216  else
217  {
218  yuiError() << "Protocol not supported - can't follow hyperlink \""
219  << url.toString() << "\"" << endl;
220  }
221 }
222 
223 
224 void
226 {
227  showLink( url );
228 }
229 
230 
231 QString
232 YQPkgDescriptionView::applicationIconList( const list<string> & fileList ) const
233 {
234  QString html = "";
235  QMap<QString, QString> desktopEntries;
236 
237  QStringList desktopFiles = findDesktopFiles( fileList );
238 
239  if ( desktopFiles.size() == 0 )
240  return QString();
241 
242  // headline for a list of application icons that belong to a selected package
243 
244  for ( int i = 0; i < desktopFiles.size(); ++i )
245  {
246  desktopEntries = readDesktopFile( desktopFiles[i] );
247 
248  QString desktopIcon = findDesktopIcon ( desktopEntries["Icon"] );
249 
250  if ( ! desktopIcon.isEmpty() )
251  {
252  html += "<tr><td valign='middle' align='center'>";
253  html += QString( "<img src=\"" ) + desktopIcon + QString( "\">" );
254  html += "</td><td valign='middle' align='left'>";
255  html += "<b>" + desktopEntries["Name"] + "</b>";
256  html += "</td></tr>";
257  }
258  }
259 
260  if ( ! html.isEmpty() )
261  {
262  html = _("This package contains: ")
263  + "<table border='0'>"
264  + html
265  + "</table>";
266  }
267 
268  return "<p>" + html + "</p>";
269 }
270 
271 
272 QString
273 YQPkgDescriptionView::findDesktopIcon ( const QString& iconName ) const
274 {
275  QStringList path;
276  path << ICONPATH;
277 
278  for ( int i=0; i < path.size(); ++i )
279  {
280  QString fullName = path[i] + iconName + ".png";
281  QFile file(fullName);
282  if ( file.exists() )
283  return fullName;
284  }
285 
286  return QString();
287 }
288 
289 
290 QMap<QString, QString>
291 YQPkgDescriptionView::readDesktopFile( const QString & fileName ) const
292 {
293  QMap<QString, QString> desktopEntries;
294  QString name, genericName;
295 
296  QSettings file( fileName, QSettings::IniFormat );
297  file.setIniCodec( "UTF-8");
298  file.beginGroup( "Desktop Entry" );
299  desktopEntries["Icon"] = file.value( "Icon" ).toString();
300  desktopEntries["Exec"] = file.value( "Exec" ).toString();
301 
302  // translate Name
303  name = file.value( QString( "Name[%1]" ).arg( langWithCountry ) ).toString();
304 
305  if ( name.isEmpty() )
306  name= file.value( QString( "Name[%1]" ).arg( lang ) ).toString() ;
307 
308  if ( name.isEmpty() )
309  {
310  QFileInfo fileInfo (fileName);
311  QString msgid = QString( "Name(%1)" ).arg( fileInfo.fileName() );
312  msgid += ": ";
313  msgid += file.value( QString( "Name" )).toString();
314  name = QString::fromUtf8( dgettext( DESKTOP_TRANSLATIONS, msgid.toAscii() ) );
315 
316  if ( name == msgid )
317  name = "";
318  }
319  if ( name.isEmpty() )
320  name= file.value( QString( "Name" ) ).toString() ;
321  desktopEntries["Name"] = name;
322 
323  file.endGroup();
324 
325  return desktopEntries;
326 }
327 
328 
329 QStringList
330 YQPkgDescriptionView::findDesktopFiles( const list<string> & fileList ) const
331 {
332  QStringList desktopFiles;
333 
334  for ( list<string>::const_iterator it = fileList.begin();
335  it != fileList.end(); ++it )
336  {
337  QString line = fromUTF8( *it );
338 
339  if ( line.contains( QRegExp( DESKTOPFILEDIR ) ) )
340  desktopFiles << line;
341  }
342 
343  return desktopFiles;
344 }
345 
346 
348 {
349  const char *lang_cstr = getenv( "LANG" );
350 
351  if ( lang_cstr )
352  {
353  langWithCountry = lang_cstr;
354  langWithCountry.replace( QRegExp( "[@\\.].*$" ), "" ); // remove .utf8 / @euro etc.
355 
356  lang = langWithCountry;
357  lang.replace( QRegExp( "_.*$" ), "" ); // remove _DE etc.
358  }
359 }
360 
361 
362 #include "YQPkgDescriptionView.moc"