~ubuntu-branches/ubuntu/lucid/kdebase/lucid

« back to all changes in this revision

Viewing changes to ksplashml/kcmksplash/installer.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Ana Beatriz Guerrero Lopez
  • Date: 2009-04-05 05:22:13 UTC
  • mfrom: (0.4.2 experimental) (0.2.2 upstream)
  • mto: This revision was merged to the branch mainline in revision 235.
  • Revision ID: james.westby@ubuntu.com-20090405052213-39thr4l6p2ss07uj
Tags: 4:4.2.2-1
* New upstream release:
  - khtml fixes. (Closes: #290285, #359680)
  - Default konsole sessions can be deleted. (Closes: #286342)
  - Tag widget uses standard application palette. (Closes: #444800)
  - ... and surely many more but we have lost track...

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/***************************************************************************
2
 
 *   Copyright Ravikiran Rajagopal 2003                                    *
3
 
 *   ravi@ee.eng.ohio-state.edu                                            *
4
 
 *   Copyright (c) 1998 Stefan Taferner <taferner@kde.org>                 *
5
 
 *                                                                         *
6
 
 *   This program is free software; you can redistribute it and/or modify  *
7
 
 *   it under the terms of the GNU General Public License (version 2) as   *
8
 
 *   published by the Free Software Foundation.                            *
9
 
 *                                                                         *
10
 
 ***************************************************************************/
11
 
 
12
 
#include <unistd.h>
13
 
#include <stdlib.h>
14
 
 
15
 
#include <qdir.h>
16
 
#include <qlabel.h>
17
 
#include <qlayout.h>
18
 
#include <qtextedit.h>
19
 
 
20
 
#include "installer.h"
21
 
 
22
 
#include <kdebug.h>
23
 
#include <kfiledialog.h>
24
 
#include <kglobalsettings.h>
25
 
#include <klocale.h>
26
 
#include <kmessagebox.h>
27
 
#include <kprocess.h>
28
 
#include <kpushbutton.h>
29
 
#include <kstandarddirs.h>
30
 
#include <ktar.h>
31
 
#include <ktrader.h>
32
 
#include <kurldrag.h>
33
 
#include <kio/netaccess.h>
34
 
 
35
 
ThemeListBox::ThemeListBox(QWidget *parent)
36
 
  : KListBox(parent)
37
 
{
38
 
   setAcceptDrops(true);
39
 
   connect(this, SIGNAL(mouseButtonPressed(int, QListBoxItem *, const QPoint &)),
40
 
           this, SLOT(slotMouseButtonPressed(int, QListBoxItem *, const QPoint &)));
41
 
}
42
 
 
43
 
void ThemeListBox::dragEnterEvent(QDragEnterEvent* event)
44
 
{
45
 
   event->accept((event->source() != this) && KURLDrag::canDecode(event));
46
 
}
47
 
 
48
 
void ThemeListBox::dropEvent(QDropEvent* event)
49
 
{
50
 
   KURL::List urls;
51
 
   if (KURLDrag::decode(event, urls))
52
 
   {
53
 
      emit filesDropped(urls);
54
 
   }
55
 
}
56
 
 
57
 
void ThemeListBox::slotMouseButtonPressed(int button, QListBoxItem *item, const QPoint &p)
58
 
{
59
 
   if ((button & LeftButton) == 0) return;
60
 
   mOldPos = p;
61
 
   mDragFile = QString::null;
62
 
   int cur = index(item);
63
 
   if (cur >= 0)
64
 
      mDragFile = text2path[text(cur)];
65
 
}
66
 
 
67
 
void ThemeListBox::mouseMoveEvent(QMouseEvent *e)
68
 
{
69
 
   if (((e->state() & LeftButton) != 0) && !mDragFile.isEmpty())
70
 
   {
71
 
      int delay = KGlobalSettings::dndEventDelay();
72
 
      QPoint newPos = e->globalPos();
73
 
      if(newPos.x() > mOldPos.x()+delay || newPos.x() < mOldPos.x()-delay ||
74
 
         newPos.y() > mOldPos.y()+delay || newPos.y() < mOldPos.y()-delay)
75
 
      {
76
 
         KURL url;
77
 
         url.setPath(mDragFile);
78
 
         KURL::List urls;
79
 
         urls.append(url);
80
 
         KURLDrag *d = new KURLDrag(urls, this);
81
 
         d->dragCopy();
82
 
      }
83
 
   }
84
 
   KListBox::mouseMoveEvent(e);
85
 
}
86
 
 
87
 
//-----------------------------------------------------------------------------
88
 
SplashInstaller::SplashInstaller (QWidget *aParent, const char *aName, bool aInit)
89
 
  : QWidget(aParent, aName), mGui(!aInit)
90
 
{
91
 
  KGlobal::dirs()->addResourceType("ksplashthemes", KStandardDirs::kde_default("data") + "ksplash/Themes");
92
 
 
93
 
  if (!mGui)
94
 
    return;
95
 
 
96
 
  QHBoxLayout* hbox = new QHBoxLayout( this, 0, KDialog::spacingHint() );
97
 
 
98
 
  QVBoxLayout* leftbox = new QVBoxLayout( hbox, KDialog::spacingHint() );
99
 
  hbox->setStretchFactor( leftbox, 1 );
100
 
 
101
 
  mThemesList = new ThemeListBox(this);
102
 
  mThemesList->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Expanding );
103
 
  connect(mThemesList, SIGNAL(highlighted(int)), SLOT(slotSetTheme(int)));
104
 
  connect(mThemesList, SIGNAL(filesDropped(const KURL::List&)), SLOT(slotFilesDropped(const KURL::List&)));
105
 
  leftbox->addWidget(mThemesList);
106
 
 
107
 
  mBtnAdd = new KPushButton( i18n("Add..."), this );
108
 
  leftbox->addWidget( mBtnAdd );
109
 
  connect(mBtnAdd, SIGNAL(clicked()), SLOT(slotAdd()));
110
 
 
111
 
  mBtnRemove = new KPushButton( i18n("Remove"), this );
112
 
  leftbox->addWidget( mBtnRemove );
113
 
  connect(mBtnRemove, SIGNAL(clicked()), SLOT(slotRemove()));
114
 
 
115
 
  mBtnTest = new KPushButton( i18n("Test"), this );
116
 
  leftbox->addWidget( mBtnTest );
117
 
  connect(mBtnTest, SIGNAL(clicked()), SLOT(slotTest()));
118
 
 
119
 
  QVBoxLayout* rightbox = new QVBoxLayout( hbox, KDialog::spacingHint() );
120
 
  hbox->setStretchFactor( rightbox, 3 );
121
 
 
122
 
  mPreview = new QLabel(this);
123
 
  mPreview->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
124
 
  mPreview->setFrameStyle(QFrame::Panel|QFrame::Sunken);
125
 
  mPreview->setMinimumSize(QSize(320,240));
126
 
  mPreview->setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
127
 
  rightbox->addWidget(mPreview);
128
 
  rightbox->setStretchFactor( mPreview, 3 );
129
 
 
130
 
  mText = new QTextEdit(this);
131
 
  mText->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );
132
 
  mText->setMinimumSize(mText->sizeHint());
133
 
  mText->setReadOnly(true);
134
 
  rightbox->addWidget(mText);
135
 
  rightbox->setStretchFactor( mText, 1 );
136
 
 
137
 
  readThemesList();
138
 
  load();
139
 
}
140
 
 
141
 
 
142
 
//-----------------------------------------------------------------------------
143
 
SplashInstaller::~SplashInstaller()
144
 
{
145
 
}
146
 
 
147
 
int SplashInstaller::addTheme(const QString &path, const QString &name)
148
 
{
149
 
  //kdDebug() << "SplashInstaller::addTheme: " << path << " " << name << endl;
150
 
  QString tmp(i18n( name.utf8() ));
151
 
  int i = mThemesList->count();
152
 
  while((i > 0) && (mThemesList->text(i-1) > tmp))
153
 
    i--;
154
 
  if ((i > 0) && (mThemesList->text(i-1) == tmp))
155
 
    return i-1;
156
 
  mThemesList->insertItem(tmp, i);
157
 
  mThemesList->text2path.insert( tmp, path+"/"+name );
158
 
  return i;
159
 
}
160
 
 
161
 
// Copy theme package into themes directory
162
 
void SplashInstaller::addNewTheme(const KURL &srcURL)
163
 
{
164
 
  QString dir = KGlobal::dirs()->saveLocation("ksplashthemes");
165
 
  KURL url;
166
 
  QString filename = srcURL.fileName();
167
 
  int i = filename.findRev('.');
168
 
  // Convert extension to lower case.
169
 
  if (i >= 0)
170
 
     filename = filename.left(i)+filename.mid(i).lower();
171
 
  url.setPath(locateLocal("tmp",filename));
172
 
 
173
 
  // Remove file from temporary directory if it aleady exists - usually the result of a failed install.
174
 
  if ( KIO::NetAccess::exists( url, true, 0 ) )
175
 
    KIO::NetAccess::del( url, 0 );
176
 
 
177
 
  bool rc = KIO::NetAccess::copy(srcURL, url, 0);
178
 
  if (!rc)
179
 
  {
180
 
    kdWarning() << "Failed to copy theme " << srcURL.fileName()
181
 
        << " into temporary directory " << url.path() << endl;
182
 
    return;
183
 
  }
184
 
 
185
 
  // Extract into theme directory: we may have multiple themes in one tarball!
186
 
  KTar tarFile(url.path());
187
 
  if (!tarFile.open(IO_ReadOnly))
188
 
  {
189
 
    kdDebug() << "Unable to open archive: " << url.path() << endl;
190
 
    return;
191
 
  }
192
 
  KArchiveDirectory const *ad = tarFile.directory();
193
 
  // Find first directory entry.
194
 
  QStringList entries = ad->entries();
195
 
  QString themeName( entries.first() );
196
 
#if 0
197
 
  // The isDirectory() call always returns false; why?
198
 
  for ( QStringList::Iterator it = entries.begin(); it != entries.end(); ++it )
199
 
  {
200
 
    if ( ad->entry( *it )->isDirectory() )
201
 
    {
202
 
      themeName = *it;
203
 
      break;
204
 
    }
205
 
  }
206
 
#endif
207
 
  // TODO: Make sure we put the entries into a subdirectory if the tarball does not.
208
 
  // TODO: Warn the user if we overwrite something.
209
 
  ad->copyTo(locateLocal("ksplashthemes","/"));
210
 
  tarFile.close();
211
 
  KIO::NetAccess::del( url, 0 );
212
 
 
213
 
  // TODO: Update only the entries from this installation.
214
 
  readThemesList();
215
 
  mThemesList->setCurrentItem(findTheme(themeName));
216
 
  mThemesList->setSelected(mThemesList->currentItem(), true);
217
 
}
218
 
 
219
 
//-----------------------------------------------------------------------------
220
 
void SplashInstaller::readThemesList()
221
 
{
222
 
  mThemesList->clear();
223
 
 
224
 
  // Read local themes
225
 
  QStringList entryList = KGlobal::dirs()->resourceDirs("ksplashthemes");
226
 
  //kdDebug() << "readThemesList: " << entryList << endl;
227
 
  QDir dir;
228
 
  QStringList subdirs;
229
 
  QStringList::ConstIterator name;
230
 
  for(name = entryList.begin(); name != entryList.end(); name++)
231
 
  {
232
 
    dir = *name;
233
 
    if (!dir.exists())
234
 
      continue;
235
 
    subdirs = dir.entryList( QDir::Dirs );
236
 
    // kdDebug() << "readThemesList: " << subdirs << endl;
237
 
    // TODO: Make sure it contains a *.rc file.
238
 
    for (QStringList::Iterator l = subdirs.begin(); l != subdirs.end(); l++ )
239
 
      if ( !(*l).startsWith(QString(".")) )
240
 
      {
241
 
        mThemesList->blockSignals( true ); // Don't activate any theme until all themes are loaded.
242
 
        addTheme(dir.path(),*l);
243
 
        mThemesList->blockSignals( false );
244
 
      }
245
 
  }
246
 
}
247
 
 
248
 
//-----------------------------------------------------------------------------
249
 
void SplashInstaller::defaults()
250
 
{
251
 
   load( true );
252
 
}
253
 
 
254
 
void SplashInstaller::load()
255
 
{
256
 
   load( false );
257
 
}
258
 
 
259
 
void SplashInstaller::load( bool useDefaults )
260
 
{
261
 
  KConfig cnf("ksplashrc");
262
 
  cnf.setReadDefaults( useDefaults );
263
 
  cnf.setGroup("KSplash");
264
 
  QString curTheme = cnf.readEntry("Theme","Default");
265
 
  mThemesList->setCurrentItem(findTheme(curTheme));
266
 
  emit changed( useDefaults );
267
 
}
268
 
 
269
 
//-----------------------------------------------------------------------------
270
 
void SplashInstaller::save()
271
 
{
272
 
  KConfig cnf("ksplashrc");
273
 
  cnf.setGroup("KSplash");
274
 
  int cur = mThemesList->currentItem();
275
 
  if (cur < 0)
276
 
    return;
277
 
  QString path = mThemesList->text(cur);
278
 
  if ( mThemesList->text2path.contains( path ) )
279
 
    path = mThemesList->text2path[path];
280
 
  cur = path.findRev('/');
281
 
  cnf.writeEntry("Theme", path.mid(cur+1) );
282
 
  cnf.sync();
283
 
  emit changed( false );
284
 
}
285
 
 
286
 
//-----------------------------------------------------------------------------
287
 
void SplashInstaller::slotRemove()
288
 
{
289
 
  int cur = mThemesList->currentItem();
290
 
  if (cur < 0)
291
 
    return;
292
 
 
293
 
  bool rc = false;
294
 
  QString themeName = mThemesList->text(cur);
295
 
  QString themeDir = mThemesList->text2path[themeName];
296
 
  if (!themeDir.isEmpty())
297
 
  {
298
 
     KURL url;
299
 
     url.setPath(themeDir);
300
 
     if (KMessageBox::warningContinueCancel(this,i18n("Delete folder %1 and its contents?").arg(themeDir),"",KGuiItem(i18n("&Delete"),"editdelete"))==KMessageBox::Continue)
301
 
       rc = KIO::NetAccess::del(url,this);
302
 
     else
303
 
       return;
304
 
  }
305
 
  if (!rc)
306
 
  {
307
 
    KMessageBox::sorry(this, i18n("Failed to remove theme '%1'").arg(themeName));
308
 
    return;
309
 
  }
310
 
  //mThemesList->removeItem(cur);
311
 
  readThemesList();
312
 
  cur = ((unsigned int)cur >= mThemesList->count())?mThemesList->count()-1:cur;
313
 
  mThemesList->setCurrentItem(cur);
314
 
}
315
 
 
316
 
 
317
 
//-----------------------------------------------------------------------------
318
 
void SplashInstaller::slotSetTheme(int id)
319
 
{
320
 
  bool enabled;
321
 
  QString path(QString::null);
322
 
  QString infoTxt;
323
 
 
324
 
  if (id < 0)
325
 
  {
326
 
    mPreview->setText(QString::null);
327
 
    mText->setText(QString::null);
328
 
    enabled = false;
329
 
  }
330
 
  else
331
 
  {
332
 
    QString error = i18n("(Could not load theme)");
333
 
    path = mThemesList->text(id);
334
 
    if ( mThemesList->text2path.contains( path ) )
335
 
        path = mThemesList->text2path[path];
336
 
    enabled = false;
337
 
    KURL url;
338
 
    QString themeName;
339
 
    if (!path.isEmpty())
340
 
    {
341
 
      // Make sure the correct plugin is installed.
342
 
      int i = path.findRev('/');
343
 
      if (i >= 0)
344
 
        themeName = path.mid(i+1);
345
 
      url.setPath( path + "/Theme.rc" );
346
 
      if (!KIO::NetAccess::exists(url, true, 0))
347
 
      {
348
 
        url.setPath( path + "/Theme.RC" );
349
 
        if (!KIO::NetAccess::exists(url, true, 0))
350
 
        {
351
 
          url.setPath( path + "/theme.rc" );
352
 
          if (!KIO::NetAccess::exists(url, true, 0))
353
 
            url.setPath( path + "/" + themeName + ".rc" );
354
 
        }
355
 
      }
356
 
      if (KIO::NetAccess::exists(url, true, 0))
357
 
      {
358
 
        KConfig cnf(url.path());
359
 
        cnf.setGroup( QString("KSplash Theme: %1").arg(themeName) );
360
 
 
361
 
        // Get theme information.
362
 
        infoTxt = "<qt>";
363
 
        if ( cnf.hasKey( "Name" ) )
364
 
          infoTxt += i18n( "<b>Name:</b> %1<br>" ).arg( cnf.readEntry( "Name", i18n( "Unknown" ) ) );
365
 
        if ( cnf.hasKey( "Description" ) )
366
 
          infoTxt += i18n( "<b>Description:</b> %1<br>" ).arg( cnf.readEntry( "Description", i18n( "Unknown" ) ) );
367
 
        if ( cnf.hasKey( "Version" ) )
368
 
          infoTxt += i18n( "<b>Version:</b> %1<br>" ).arg( cnf.readEntry( "Version", i18n( "Unknown" ) ) );
369
 
        if ( cnf.hasKey( "Author" ) )
370
 
          infoTxt += i18n( "<b>Author:</b> %1<br>" ).arg( cnf.readEntry( "Author", i18n( "Unknown" ) ) );
371
 
        if ( cnf.hasKey( "Homepage" ) )
372
 
          infoTxt += i18n( "<b>Homepage:</b> %1<br>" ).arg( cnf.readEntry( "Homepage", i18n( "Unknown" ) ) );
373
 
        infoTxt += "</qt>";
374
 
 
375
 
        QString pluginName( cnf.readEntry( "Engine", "Default" ) ); // Perhaps no default is better?
376
 
        if ((KTrader::self()->query("KSplash/Plugin", QString("[X-KSplash-PluginName] == '%1'").arg(pluginName))).isEmpty())
377
 
        {
378
 
          enabled = false;
379
 
          error = i18n("This theme requires the plugin %1 which is not installed.").arg(pluginName);
380
 
        }
381
 
        else
382
 
          enabled = true; // Hooray, there is at least one plugin which can handle this theme.
383
 
      }
384
 
      else
385
 
      {
386
 
        error = i18n("Could not load theme configuration file.");
387
 
      }
388
 
    }
389
 
    mBtnTest->setEnabled(enabled && themeName != "None" );
390
 
    mText->setText(infoTxt);
391
 
    if (!enabled)
392
 
    {
393
 
      url.setPath( path + "/" + "Preview.png" );
394
 
      if (KIO::NetAccess::exists(url, true, 0))
395
 
        mPreview->setPixmap(QPixmap(url.path()));
396
 
      else
397
 
        mPreview->setText(i18n("(Could not load theme)"));
398
 
      KMessageBox::sorry(this, error);
399
 
    }
400
 
    else
401
 
    {
402
 
      url.setPath( path + "/" + "Preview.png" );
403
 
      if (KIO::NetAccess::exists(url, true, 0))
404
 
        mPreview->setPixmap(QPixmap(url.path()));
405
 
      else
406
 
        mPreview->setText(i18n("No preview available."));
407
 
      emit changed(true);
408
 
    }
409
 
  }
410
 
  mBtnRemove->setEnabled( !path.isEmpty() && QFileInfo(path).isWritable());
411
 
}
412
 
 
413
 
 
414
 
//-----------------------------------------------------------------------------
415
 
void SplashInstaller::slotAdd()
416
 
{
417
 
  static QString path;
418
 
  if (path.isEmpty()) path = QDir::homeDirPath();
419
 
 
420
 
  KFileDialog dlg(path, "*.tgz *.tar.gz *.tar.bz2|" + i18n( "KSplash Theme Files" ), 0, 0, true);
421
 
  dlg.setCaption(i18n("Add Theme"));
422
 
  if (!dlg.exec())
423
 
    return;
424
 
 
425
 
  path = dlg.baseURL().url();
426
 
  addNewTheme(dlg.selectedURL());
427
 
}
428
 
 
429
 
//-----------------------------------------------------------------------------
430
 
void SplashInstaller::slotFilesDropped(const KURL::List &urls)
431
 
{
432
 
  for(KURL::List::ConstIterator it = urls.begin();
433
 
      it != urls.end();
434
 
      ++it)
435
 
      addNewTheme(*it);
436
 
}
437
 
 
438
 
//-----------------------------------------------------------------------------
439
 
int SplashInstaller::findTheme( const QString &theme )
440
 
{
441
 
  // theme is untranslated, but the listbox contains translated items
442
 
  QString tmp(i18n( theme.utf8() ));
443
 
  int id = mThemesList->count()-1;
444
 
 
445
 
  while (id >= 0)
446
 
  {
447
 
    if (mThemesList->text(id) == tmp)
448
 
      return id;
449
 
    id--;
450
 
  }
451
 
 
452
 
  return 0;
453
 
}
454
 
 
455
 
//-----------------------------------------------------------------------------
456
 
void SplashInstaller::slotTest()
457
 
{
458
 
  int i = mThemesList->currentItem();
459
 
  if (i < 0)
460
 
    return;
461
 
  QString themeName = mThemesList->text2path[mThemesList->text(i)];
462
 
  int r = themeName.findRev('/');
463
 
  if (r >= 0)
464
 
    themeName = themeName.mid(r+1);
465
 
 
466
 
  // special handling for none and simple splashscreens
467
 
  if( themeName == "None" )
468
 
    return;
469
 
  if( themeName == "Simple" )
470
 
  {
471
 
    KProcess proc;
472
 
    proc << "ksplashsimple" << "--test";
473
 
    if (!proc.start(KProcess::Block))
474
 
      KMessageBox::error(this,i18n("Unable to start ksplashsimple."));
475
 
    return;
476
 
  }
477
 
  KProcess proc;
478
 
  proc << "ksplash" << "--test" << "--theme" << themeName;
479
 
  if (!proc.start(KProcess::Block))
480
 
    KMessageBox::error(this,i18n("Unable to start ksplash."));
481
 
}
482
 
 
483
 
//-----------------------------------------------------------------------------
484
 
#include "installer.moc"