• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdelibs API Reference
  • KDE Home
  • Contact Us
 

KIO

  • sources
  • kde-4.14
  • kdelibs
  • kio
  • kfile
kpropertiesdialog.cpp
Go to the documentation of this file.
1 /* This file is part of the KDE project
2 
3  Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
4  Copyright (c) 1999, 2000 Preston Brown <pbrown@kde.org>
5  Copyright (c) 2000 Simon Hausmann <hausmann@kde.org>
6  Copyright (c) 2000 David Faure <faure@kde.org>
7  Copyright (c) 2003 Waldo Bastian <bastian@kde.org>
8 
9  This library is free software; you can redistribute it and/or
10  modify it under the terms of the GNU Library General Public
11  License as published by the Free Software Foundation; either
12  version 2 of the License, or (at your option) any later version.
13 
14  This library is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  Library General Public License for more details.
18 
19  You should have received a copy of the GNU Library General Public License
20  along with this library; see the file COPYING.LIB. If not, write to
21  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  Boston, MA 02110-1301, USA.
23 */
24 
25 /*
26  * kpropertiesdialog.cpp
27  * View/Edit Properties of files, locally or remotely
28  *
29  * some FilePermissionsPropsPlugin-changes by
30  * Henner Zeller <zeller@think.de>
31  * some layout management by
32  * Bertrand Leconte <B.Leconte@mail.dotcom.fr>
33  * the rest of the layout management, bug fixes, adaptation to libkio,
34  * template feature by
35  * David Faure <faure@kde.org>
36  * More layout, cleanups, and fixes by
37  * Preston Brown <pbrown@kde.org>
38  * Plugin capability, cleanups and port to KDialog by
39  * Simon Hausmann <hausmann@kde.org>
40  * KDesktopPropsPlugin by
41  * Waldo Bastian <bastian@kde.org>
42  */
43 
44 #include "kpropertiesdialog.h"
45 #include "kpropertiesdialog_p.h"
46 
47 
48 #include <config.h>
49 #include <config-acl.h>
50 extern "C" {
51 #include <pwd.h>
52 #include <grp.h>
53 #include <time.h>
54 #include <sys/stat.h>
55 #include <sys/types.h>
56 }
57 #include <unistd.h>
58 #include <errno.h>
59 #include <algorithm>
60 #include <functional>
61 
62 #include <QtCore/QFile>
63 #include <QtCore/QDir>
64 #include <QtGui/QLabel>
65 #include <QtGui/QPushButton>
66 #include <QtGui/QCheckBox>
67 #include <QtCore/QMutableStringListIterator>
68 #include <QtCore/QTextIStream>
69 #include <QtGui/QPainter>
70 #include <QtGui/QLayout>
71 #include <QtGui/QStyle>
72 #include <QtGui/QProgressBar>
73 #include <QVector>
74 #include <QFileInfo>
75 
76 #ifdef HAVE_POSIX_ACL
77 extern "C" {
78 # include <sys/xattr.h>
79 }
80 #endif
81 
82 #include <kauthorized.h>
83 #include <kdialog.h>
84 #include <kdirnotify.h>
85 #include <kdiskfreespaceinfo.h>
86 #include <kdebug.h>
87 #include <kdesktopfile.h>
88 #include <kicondialog.h>
89 #include <kurl.h>
90 #include <kurlrequester.h>
91 #include <klocale.h>
92 #include <kglobal.h>
93 #include <kglobalsettings.h>
94 #include <kstandarddirs.h>
95 #include <kjobuidelegate.h>
96 #include <kio/job.h>
97 #include <kio/copyjob.h>
98 #include <kio/chmodjob.h>
99 #include <kio/directorysizejob.h>
100 #include <kio/renamedialog.h>
101 #include <kio/netaccess.h>
102 #include <kio/jobuidelegate.h>
103 #include <kfiledialog.h>
104 #include <kmimetype.h>
105 #include <kmountpoint.h>
106 #include <kiconloader.h>
107 #include <kmessagebox.h>
108 #include <kservice.h>
109 #include <kcombobox.h>
110 #include <kcompletion.h>
111 #include <klineedit.h>
112 #include <kseparator.h>
113 #include <ksqueezedtextlabel.h>
114 #include <kmimetypetrader.h>
115 #include <kpreviewprops.h>
116 #include <krun.h>
117 #include <kvbox.h>
118 #include <kacl.h>
119 #include <kconfiggroup.h>
120 #include <kshell.h>
121 #include <kcapacitybar.h>
122 #include <kfileitemlistproperties.h>
123 
124 #ifndef Q_OS_WIN
125 #include "kfilesharedialog.h"
126 #endif
127 
128 #include "ui_kpropertiesdesktopbase.h"
129 #include "ui_kpropertiesdesktopadvbase.h"
130 #ifdef HAVE_POSIX_ACL
131 #include "kacleditwidget.h"
132 #endif
133 
134 #include <kbuildsycocaprogressdialog.h>
135 #include <kmimetypechooser.h>
136 
137 #ifdef Q_WS_WIN
138 # include <kkernel_win.h>
139 #ifdef __GNUC__
140 # warning TODO: port completely to win32
141 #endif
142 #endif
143 
144 using namespace KDEPrivate;
145 
146 static QString nameFromFileName(QString nameStr)
147 {
148  if ( nameStr.endsWith(QLatin1String(".desktop")) )
149  nameStr.truncate( nameStr.length() - 8 );
150  if ( nameStr.endsWith(QLatin1String(".kdelnk")) )
151  nameStr.truncate( nameStr.length() - 7 );
152  // Make it human-readable (%2F => '/', ...)
153  nameStr = KIO::decodeFileName( nameStr );
154  return nameStr;
155 }
156 
157 mode_t KFilePermissionsPropsPlugin::fperm[3][4] = {
158  {S_IRUSR, S_IWUSR, S_IXUSR, S_ISUID},
159  {S_IRGRP, S_IWGRP, S_IXGRP, S_ISGID},
160  {S_IROTH, S_IWOTH, S_IXOTH, S_ISVTX}
161 };
162 
163 class KPropertiesDialog::KPropertiesDialogPrivate
164 {
165 public:
166  KPropertiesDialogPrivate(KPropertiesDialog *qq)
167  {
168  q = qq;
169  m_aborted = false;
170  fileSharePage = 0;
171  }
172  ~KPropertiesDialogPrivate()
173  {
174  }
175 
179  void init();
183  void insertPages();
184 
185  KPropertiesDialog *q;
186  bool m_aborted:1;
187  QWidget* fileSharePage;
191  KUrl m_singleUrl;
195  KFileItemList m_items;
199  QString m_defaultName;
200  KUrl m_currentDir;
204  QList<KPropertiesDialogPlugin*> m_pageList;
205 };
206 
207 KPropertiesDialog::KPropertiesDialog (const KFileItem& item,
208  QWidget* parent)
209  : KPageDialog(parent), d(new KPropertiesDialogPrivate(this))
210 {
211  setCaption( i18n( "Properties for %1" , KIO::decodeFileName(item.url().fileName())) );
212 
213  Q_ASSERT( !item.isNull() );
214  d->m_items.append(item);
215 
216  d->m_singleUrl = item.url();
217  Q_ASSERT(!d->m_singleUrl.isEmpty());
218 
219  d->init();
220 }
221 
222 KPropertiesDialog::KPropertiesDialog (const QString& title,
223  QWidget* parent)
224  : KPageDialog(parent), d(new KPropertiesDialogPrivate(this))
225 {
226  setCaption( i18n( "Properties for %1", title ) );
227 
228  d->init();
229 }
230 
231 KPropertiesDialog::KPropertiesDialog(const KFileItemList& _items,
232  QWidget* parent)
233  : KPageDialog(parent), d(new KPropertiesDialogPrivate(this))
234 {
235  if ( _items.count() > 1 )
236  setCaption( i18np( "Properties for 1 item", "Properties for %1 Selected Items", _items.count() ) );
237  else
238  setCaption( i18n( "Properties for %1" , KIO::decodeFileName(_items.first().url().fileName())) );
239 
240  Q_ASSERT( !_items.isEmpty() );
241  d->m_singleUrl = _items.first().url();
242  Q_ASSERT(!d->m_singleUrl.isEmpty());
243 
244  d->m_items = _items;
245 
246  d->init();
247 }
248 
249 KPropertiesDialog::KPropertiesDialog (const KUrl& _url,
250  QWidget* parent)
251  : KPageDialog(parent), d(new KPropertiesDialogPrivate(this))
252 {
253  setCaption( i18n( "Properties for %1" , KIO::decodeFileName(_url.fileName())) );
254 
255  d->m_singleUrl = _url;
256 
257  KIO::UDSEntry entry;
258  KIO::NetAccess::stat(_url, entry, parent);
259 
260  d->m_items.append(KFileItem(entry, _url));
261  d->init();
262 }
263 
264 KPropertiesDialog::KPropertiesDialog (const KUrl& _tempUrl, const KUrl& _currentDir,
265  const QString& _defaultName,
266  QWidget* parent)
267  : KPageDialog(parent), d(new KPropertiesDialogPrivate(this))
268 {
269  setCaption( i18n( "Properties for %1" , KIO::decodeFileName(_tempUrl.fileName())) );
270 
271  d->m_singleUrl = _tempUrl;
272  d->m_defaultName = _defaultName;
273  d->m_currentDir = _currentDir;
274  Q_ASSERT(!d->m_singleUrl.isEmpty());
275 
276  // Create the KFileItem for the _template_ file, in order to read from it.
277  d->m_items.append(KFileItem(KFileItem::Unknown, KFileItem::Unknown, d->m_singleUrl));
278  d->init();
279 }
280 
281 bool KPropertiesDialog::showDialog(const KFileItem& item, QWidget* parent,
282  bool modal)
283 {
284  // TODO: do we really want to show the win32 property dialog?
285  // This means we lose metainfo, support for .desktop files, etc. (DF)
286 #ifdef Q_WS_WIN
287  QString localPath = item.localPath();
288  if (!localPath.isEmpty())
289  return showWin32FilePropertyDialog(localPath);
290 #endif
291  KPropertiesDialog* dlg = new KPropertiesDialog(item, parent);
292  if (modal) {
293  dlg->exec();
294  } else {
295  dlg->show();
296  }
297 
298  return true;
299 }
300 
301 bool KPropertiesDialog::showDialog(const KUrl& _url, QWidget* parent,
302  bool modal)
303 {
304 #ifdef Q_WS_WIN
305  if (_url.isLocalFile())
306  return showWin32FilePropertyDialog( _url.toLocalFile() );
307 #endif
308  KPropertiesDialog* dlg = new KPropertiesDialog(_url, parent);
309  if (modal) {
310  dlg->exec();
311  } else {
312  dlg->show();
313  }
314 
315  return true;
316 }
317 
318 bool KPropertiesDialog::showDialog(const KFileItemList& _items, QWidget* parent,
319  bool modal)
320 {
321  if (_items.count()==1) {
322  const KFileItem item = _items.first();
323  if (item.entry().count() == 0 && item.localPath().isEmpty()) // this remote item wasn't listed by a slave
324  // Let's stat to get more info on the file
325  return KPropertiesDialog::showDialog(item.url(), parent, modal);
326  else
327  return KPropertiesDialog::showDialog(_items.first(), parent, modal);
328  }
329  KPropertiesDialog* dlg = new KPropertiesDialog(_items, parent);
330  if (modal) {
331  dlg->exec();
332  } else {
333  dlg->show();
334  }
335  return true;
336 }
337 
338 void KPropertiesDialog::KPropertiesDialogPrivate::init()
339 {
340  q->setFaceType(KPageDialog::Tabbed);
341  q->setButtons(KDialog::Ok | KDialog::Cancel);
342  q->setDefaultButton(KDialog::Ok);
343 
344  connect(q, SIGNAL(okClicked()), q, SLOT(slotOk()));
345  connect(q, SIGNAL(cancelClicked()), q, SLOT(slotCancel()));
346 
347  insertPages();
348 
349  KConfigGroup group(KGlobal::config(), "KPropertiesDialog");
350  q->restoreDialogSize(group);
351 }
352 
353 void KPropertiesDialog::showFileSharingPage()
354 {
355  if (d->fileSharePage) {
356  // FIXME: this showFileSharingPage thingy looks broken! (tokoe)
357  // showPage( pageIndex( d->fileSharePage));
358  }
359 }
360 
361 void KPropertiesDialog::setFileSharingPage(QWidget* page) {
362  d->fileSharePage = page;
363 }
364 
365 
366 void KPropertiesDialog::setFileNameReadOnly( bool ro )
367 {
368  foreach(KPropertiesDialogPlugin *it, d->m_pageList) {
369  KFilePropsPlugin* plugin = dynamic_cast<KFilePropsPlugin*>(it);
370  if ( plugin ) {
371  plugin->setFileNameReadOnly( ro );
372  break;
373  }
374  }
375 }
376 
377 KPropertiesDialog::~KPropertiesDialog()
378 {
379  qDeleteAll(d->m_pageList);
380  delete d;
381 
382  KConfigGroup group(KGlobal::config(), "KPropertiesDialog");
383  saveDialogSize(group, KConfigBase::Persistent);
384 }
385 
386 void KPropertiesDialog::insertPlugin (KPropertiesDialogPlugin* plugin)
387 {
388  connect (plugin, SIGNAL (changed()),
389  plugin, SLOT (setDirty()));
390 
391  d->m_pageList.append(plugin);
392 }
393 
394 KUrl KPropertiesDialog::kurl() const
395 {
396  return d->m_singleUrl;
397 }
398 
399 KFileItem& KPropertiesDialog::item()
400 {
401  return d->m_items.first();
402 }
403 
404 KFileItemList KPropertiesDialog::items() const
405 {
406  return d->m_items;
407 }
408 
409 KUrl KPropertiesDialog::currentDir() const
410 {
411  return d->m_currentDir;
412 }
413 
414 QString KPropertiesDialog::defaultName() const
415 {
416  return d->m_defaultName;
417 }
418 
419 bool KPropertiesDialog::canDisplay( const KFileItemList& _items )
420 {
421  // TODO: cache the result of those calls. Currently we parse .desktop files far too many times
422  return KFilePropsPlugin::supports( _items ) ||
423  KFilePermissionsPropsPlugin::supports( _items ) ||
424  KDesktopPropsPlugin::supports( _items ) ||
425  KUrlPropsPlugin::supports( _items ) ||
426  KDevicePropsPlugin::supports( _items ) ||
427  KPreviewPropsPlugin::supports( _items );
428 }
429 
430 void KPropertiesDialog::slotOk()
431 {
432  QList<KPropertiesDialogPlugin*>::const_iterator pageListIt;
433  d->m_aborted = false;
434 
435  KFilePropsPlugin * filePropsPlugin = qobject_cast<KFilePropsPlugin*>(d->m_pageList.first());
436 
437  // If any page is dirty, then set the main one (KFilePropsPlugin) as
438  // dirty too. This is what makes it possible to save changes to a global
439  // desktop file into a local one. In other cases, it doesn't hurt.
440  for (pageListIt = d->m_pageList.constBegin(); pageListIt != d->m_pageList.constEnd(); ++pageListIt) {
441  if ( (*pageListIt)->isDirty() && filePropsPlugin )
442  {
443  filePropsPlugin->setDirty();
444  break;
445  }
446  }
447 
448  // Apply the changes in the _normal_ order of the tabs now
449  // This is because in case of renaming a file, KFilePropsPlugin will call
450  // KPropertiesDialog::rename, so other tab will be ok with whatever order
451  // BUT for file copied from templates, we need to do the renaming first !
452  for (pageListIt = d->m_pageList.constBegin(); pageListIt != d->m_pageList.constEnd() && !d->m_aborted; ++pageListIt) {
453  if ( (*pageListIt)->isDirty() )
454  {
455  kDebug( 250 ) << "applying changes for " << (*pageListIt)->metaObject()->className();
456  (*pageListIt)->applyChanges();
457  // applyChanges may change d->m_aborted.
458  }
459  else {
460  kDebug( 250 ) << "skipping page " << (*pageListIt)->metaObject()->className();
461  }
462  }
463 
464  if ( !d->m_aborted && filePropsPlugin )
465  filePropsPlugin->postApplyChanges();
466 
467  if ( !d->m_aborted )
468  {
469  emit applied();
470  emit propertiesClosed();
471  deleteLater(); // somewhat like Qt::WA_DeleteOnClose would do.
472  accept();
473  } // else, keep dialog open for user to fix the problem.
474 }
475 
476 void KPropertiesDialog::slotCancel()
477 {
478  emit canceled();
479  emit propertiesClosed();
480 
481  deleteLater();
482  done( Rejected );
483 }
484 
485 void KPropertiesDialog::KPropertiesDialogPrivate::insertPages()
486 {
487  if (m_items.isEmpty())
488  return;
489 
490  if ( KFilePropsPlugin::supports( m_items ) ) {
491  KPropertiesDialogPlugin *p = new KFilePropsPlugin(q);
492  q->insertPlugin(p);
493  }
494 
495  if ( KFilePermissionsPropsPlugin::supports( m_items ) ) {
496  KPropertiesDialogPlugin *p = new KFilePermissionsPropsPlugin(q);
497  q->insertPlugin(p);
498  }
499 
500  if ( KDesktopPropsPlugin::supports( m_items ) ) {
501  KPropertiesDialogPlugin *p = new KDesktopPropsPlugin(q);
502  q->insertPlugin(p);
503  }
504 
505  if ( KUrlPropsPlugin::supports( m_items ) ) {
506  KPropertiesDialogPlugin *p = new KUrlPropsPlugin(q);
507  q->insertPlugin(p);
508  }
509 
510  if ( KDevicePropsPlugin::supports( m_items ) ) {
511  KPropertiesDialogPlugin *p = new KDevicePropsPlugin(q);
512  q->insertPlugin(p);
513  }
514 
515  if ( KPreviewPropsPlugin::supports( m_items ) ) {
516  KPropertiesDialogPlugin *p = new KPreviewPropsPlugin(q);
517  q->insertPlugin(p);
518  }
519 
520  //plugins
521 
522  if ( m_items.count() != 1 )
523  return;
524 
525  const KFileItem item = m_items.first();
526  const QString mimetype = item.mimetype();
527 
528  if ( mimetype.isEmpty() )
529  return;
530 
531  QString query = QString::fromLatin1(
532  "((not exist [X-KDE-Protocol]) or "
533  " ([X-KDE-Protocol] == '%1' ) )"
534  ).arg(item.url().protocol());
535 
536  kDebug( 250 ) << "trader query: " << query;
537  const KService::List offers = KMimeTypeTrader::self()->query( mimetype, "KPropertiesDialog/Plugin", query );
538  foreach (const KService::Ptr &ptr, offers) {
539  KPropertiesDialogPlugin *plugin = ptr->createInstance<KPropertiesDialogPlugin>(q);
540  if (!plugin)
541  continue;
542  plugin->setObjectName(ptr->name());
543 
544  q->insertPlugin(plugin);
545  }
546 }
547 
548 void KPropertiesDialog::updateUrl( const KUrl& _newUrl )
549 {
550  Q_ASSERT(d->m_items.count() == 1);
551  kDebug(250) << "KPropertiesDialog::updateUrl (pre)" << _newUrl.url();
552  KUrl newUrl = _newUrl;
553  emit saveAs(d->m_singleUrl, newUrl);
554  kDebug(250) << "KPropertiesDialog::updateUrl (post)" << newUrl.url();
555 
556  d->m_singleUrl = newUrl;
557  d->m_items.first().setUrl(newUrl);
558  Q_ASSERT(!d->m_singleUrl.isEmpty());
559  // If we have an Desktop page, set it dirty, so that a full file is saved locally
560  // Same for a URL page (because of the Name= hack)
561  foreach (KPropertiesDialogPlugin *it, d->m_pageList) {
562  if ( qobject_cast<KUrlPropsPlugin*>(it) ||
563  qobject_cast<KDesktopPropsPlugin*>(it) )
564  {
565  //kDebug(250) << "Setting page dirty";
566  it->setDirty();
567  break;
568  }
569  }
570 }
571 
572 void KPropertiesDialog::rename( const QString& _name )
573 {
574  Q_ASSERT(d->m_items.count() == 1);
575  kDebug(250) << "KPropertiesDialog::rename " << _name;
576  KUrl newUrl;
577  // if we're creating from a template : use currentdir
578  if (!d->m_currentDir.isEmpty()) {
579  newUrl = d->m_currentDir;
580  newUrl.addPath(_name);
581  } else {
582  QString tmpurl = d->m_singleUrl.url();
583  if (!tmpurl.isEmpty() && tmpurl.at(tmpurl.length() - 1) == '/') {
584  // It's a directory, so strip the trailing slash first
585  tmpurl.truncate(tmpurl.length() - 1);
586  }
587 
588  newUrl = tmpurl;
589  newUrl.setFileName(_name);
590  }
591  updateUrl(newUrl);
592 }
593 
594 void KPropertiesDialog::abortApplying()
595 {
596  d->m_aborted = true;
597 }
598 
599 class KPropertiesDialogPlugin::KPropertiesDialogPluginPrivate
600 {
601 public:
602  KPropertiesDialogPluginPrivate()
603  {
604  }
605  ~KPropertiesDialogPluginPrivate()
606  {
607  }
608 
609  bool m_bDirty;
610  int fontHeight;
611 };
612 
613 KPropertiesDialogPlugin::KPropertiesDialogPlugin( KPropertiesDialog *_props )
614  : QObject( _props ),d(new KPropertiesDialogPluginPrivate)
615 {
616  properties = _props;
617  d->fontHeight = 2*properties->fontMetrics().height();
618  d->m_bDirty = false;
619 }
620 
621 KPropertiesDialogPlugin::~KPropertiesDialogPlugin()
622 {
623  delete d;
624 }
625 
626 #ifndef KDE_NO_DEPRECATED
627 bool KPropertiesDialogPlugin::isDesktopFile( const KFileItem& _item )
628 {
629  return _item.isDesktopFile();
630 }
631 #endif
632 
633 void KPropertiesDialogPlugin::setDirty( bool b )
634 {
635  d->m_bDirty = b;
636 }
637 
638 void KPropertiesDialogPlugin::setDirty()
639 {
640  d->m_bDirty = true;
641 }
642 
643 bool KPropertiesDialogPlugin::isDirty() const
644 {
645  return d->m_bDirty;
646 }
647 
648 void KPropertiesDialogPlugin::applyChanges()
649 {
650  kWarning(250) << "applyChanges() not implemented in page !";
651 }
652 
653 int KPropertiesDialogPlugin::fontHeight() const
654 {
655  return d->fontHeight;
656 }
657 
659 
660 class KFilePropsPlugin::KFilePropsPluginPrivate
661 {
662 public:
663  KFilePropsPluginPrivate()
664  {
665  dirSizeJob = 0L;
666  dirSizeUpdateTimer = 0L;
667  m_lined = 0;
668  m_capacityBar = 0;
669  m_linkTargetLineEdit = 0;
670  }
671  ~KFilePropsPluginPrivate()
672  {
673  if ( dirSizeJob )
674  dirSizeJob->kill();
675  }
676 
677  KIO::DirectorySizeJob * dirSizeJob;
678  QTimer *dirSizeUpdateTimer;
679  QFrame *m_frame;
680  bool bMultiple;
681  bool bIconChanged;
682  bool bKDesktopMode;
683  bool bDesktopFile;
684  KCapacityBar *m_capacityBar;
685  QString mimeType;
686  QString oldFileName;
687  KLineEdit* m_lined;
688 
689  QWidget *iconArea;
690  QWidget *nameArea;
691 
692  QLabel *m_sizeLabel;
693  QPushButton *m_sizeDetermineButton;
694  QPushButton *m_sizeStopButton;
695  KLineEdit* m_linkTargetLineEdit;
696 
697  QString m_sRelativePath;
698  bool m_bFromTemplate;
699 
703  QString oldName;
704 };
705 
706 KFilePropsPlugin::KFilePropsPlugin( KPropertiesDialog *_props )
707  : KPropertiesDialogPlugin( _props ),d(new KFilePropsPluginPrivate)
708 {
709  d->bMultiple = (properties->items().count() > 1);
710  d->bIconChanged = false;
711  d->bDesktopFile = KDesktopPropsPlugin::supports(properties->items());
712  kDebug(250) << "KFilePropsPlugin::KFilePropsPlugin bMultiple=" << d->bMultiple;
713 
714  // We set this data from the first item, and we'll
715  // check that the other items match against it, resetting when not.
716  bool isLocal;
717  const KFileItem item = properties->item();
718  KUrl url = item.mostLocalUrl( isLocal );
719  bool isReallyLocal = item.url().isLocalFile();
720  bool bDesktopFile = item.isDesktopFile();
721  mode_t mode = item.mode();
722  bool hasDirs = item.isDir() && !item.isLink();
723  bool hasRoot = url.path() == QLatin1String("/");
724  QString iconStr = KMimeType::iconNameForUrl(url, mode);
725  QString directory = properties->kurl().directory();
726  QString protocol = properties->kurl().protocol();
727  d->bKDesktopMode = protocol == QLatin1String("desktop") ||
728  properties->currentDir().protocol() == QLatin1String("desktop");
729  QString mimeComment = item.mimeComment();
730  d->mimeType = item.mimetype();
731  KIO::filesize_t totalSize = item.size();
732  QString magicMimeComment;
733  if ( isLocal ) {
734  KMimeType::Ptr magicMimeType = KMimeType::findByFileContent(url.toLocalFile());
735  if ( magicMimeType->name() != KMimeType::defaultMimeType() )
736  magicMimeComment = magicMimeType->comment();
737  }
738 #ifdef Q_WS_WIN
739  if ( isReallyLocal ) {
740  directory = QDir::toNativeSeparators( directory.mid( 1 ) );
741  }
742 #endif
743 
744  // Those things only apply to 'single file' mode
745  QString filename;
746  bool isTrash = false;
747  d->m_bFromTemplate = false;
748 
749  // And those only to 'multiple' mode
750  uint iDirCount = hasDirs ? 1 : 0;
751  uint iFileCount = 1-iDirCount;
752 
753  d->m_frame = new QFrame();
754  properties->addPage(d->m_frame, i18nc("@title:tab File properties", "&General"));
755 
756  QVBoxLayout *vbl = new QVBoxLayout( d->m_frame );
757  vbl->setMargin( 0 );
758  vbl->setObjectName( QLatin1String( "vbl" ) );
759  QGridLayout *grid = new QGridLayout(); // unknown rows
760  grid->setColumnStretch(0, 0);
761  grid->setColumnStretch(1, 0);
762  grid->setColumnStretch(2, 1);
763  grid->addItem(new QSpacerItem(KDialog::spacingHint(),0), 0, 1);
764  vbl->addLayout(grid);
765  int curRow = 0;
766 
767  if ( !d->bMultiple )
768  {
769  QString path;
770  if ( !d->m_bFromTemplate ) {
771  isTrash = ( properties->kurl().protocol().toLower() == "trash" );
772  // Extract the full name, but without file: for local files
773  if ( isReallyLocal )
774  path = properties->kurl().toLocalFile();
775  else
776  path = properties->kurl().prettyUrl();
777  } else {
778  path = properties->currentDir().path(KUrl::AddTrailingSlash) + properties->defaultName();
779  directory = properties->currentDir().prettyUrl();
780  }
781 
782  if (d->bDesktopFile) {
783  determineRelativePath( path );
784  }
785 
786  // Extract the file name only
787  filename = properties->defaultName();
788  if ( filename.isEmpty() ) { // no template
789  const QFileInfo finfo (item.name()); // this gives support for UDS_NAME, e.g. for kio_trash or kio_system
790  filename = finfo.fileName(); // Make sure only the file's name is displayed (#160964).
791  } else {
792  d->m_bFromTemplate = true;
793  setDirty(); // to enforce that the copy happens
794  }
795  d->oldFileName = filename;
796 
797  // Make it human-readable
798  filename = nameFromFileName( filename );
799 
800  if ( d->bKDesktopMode && d->bDesktopFile ) {
801  KDesktopFile config(url.toLocalFile());
802  if ( config.desktopGroup().hasKey( "Name" ) ) {
803  filename = config.readName();
804  }
805  }
806 
807  d->oldName = filename;
808  }
809  else
810  {
811  // Multiple items: see what they have in common
812  const KFileItemList items = properties->items();
813  KFileItemList::const_iterator kit = items.begin();
814  const KFileItemList::const_iterator kend = items.end();
815  for ( ++kit /*no need to check the first one again*/ ; kit != kend; ++kit )
816  {
817  const KUrl url = (*kit).url();
818  kDebug(250) << "KFilePropsPlugin::KFilePropsPlugin " << url.prettyUrl();
819  // The list of things we check here should match the variables defined
820  // at the beginning of this method.
821  if ( url.isLocalFile() != isLocal )
822  isLocal = false; // not all local
823  if ( bDesktopFile && (*kit).isDesktopFile() != bDesktopFile )
824  bDesktopFile = false; // not all desktop files
825  if ( (*kit).mode() != mode )
826  mode = (mode_t)0;
827  if ( KMimeType::iconNameForUrl(url, mode) != iconStr )
828  iconStr = "document-multiple";
829  if ( url.directory() != directory )
830  directory.clear();
831  if ( url.protocol() != protocol )
832  protocol.clear();
833  if ( !mimeComment.isNull() && (*kit).mimeComment() != mimeComment )
834  mimeComment.clear();
835  if ( isLocal && !magicMimeComment.isNull() ) {
836  KMimeType::Ptr magicMimeType = KMimeType::findByFileContent(url.toLocalFile());
837  if ( magicMimeType->comment() != magicMimeComment )
838  magicMimeComment.clear();
839  }
840 
841  if ( isLocal && url.path() == QLatin1String("/") )
842  hasRoot = true;
843  if ( (*kit).isDir() && !(*kit).isLink() )
844  {
845  iDirCount++;
846  hasDirs = true;
847  }
848  else
849  {
850  iFileCount++;
851  totalSize += (*kit).size();
852  }
853  }
854  }
855 
856  if (!isReallyLocal && !protocol.isEmpty())
857  {
858  directory += ' ';
859  directory += '(';
860  directory += protocol;
861  directory += ')';
862  }
863 
864  if (!isTrash && (bDesktopFile || S_ISDIR(mode))
865  && !d->bMultiple // not implemented for multiple
866  && enableIconButton()) // #56857
867  {
868  KIconButton *iconButton = new KIconButton( d->m_frame );
869  int bsize = 66 + 2 * iconButton->style()->pixelMetric(QStyle::PM_ButtonMargin);
870  iconButton->setFixedSize(bsize, bsize);
871  iconButton->setIconSize(48);
872  iconButton->setStrictIconSize(false);
873  QString iconStr = KMimeType::findByUrl(url, mode)->iconName(url);
874  if (bDesktopFile && isLocal) {
875  KDesktopFile config(url.toLocalFile());
876  KConfigGroup group = config.desktopGroup();
877  iconStr = group.readEntry( "Icon" );
878  if ( config.hasDeviceType() )
879  iconButton->setIconType( KIconLoader::Desktop, KIconLoader::Device );
880  else
881  iconButton->setIconType( KIconLoader::Desktop, KIconLoader::Application );
882  } else {
883  iconButton->setIconType( KIconLoader::Desktop, KIconLoader::Place );
884  }
885  iconButton->setIcon(iconStr);
886  d->iconArea = iconButton;
887  connect(iconButton, SIGNAL(iconChanged(QString)),
888  this, SLOT(slotIconChanged()));
889  } else {
890  QLabel *iconLabel = new QLabel( d->m_frame );
891  int bsize = 66 + 2 * iconLabel->style()->pixelMetric(QStyle::PM_ButtonMargin);
892  iconLabel->setFixedSize(bsize, bsize);
893  iconLabel->setPixmap( KIconLoader::global()->loadIcon( iconStr, KIconLoader::Desktop, 48) );
894  d->iconArea = iconLabel;
895  }
896  grid->addWidget(d->iconArea, curRow, 0, Qt::AlignLeft);
897 
898  if (d->bMultiple || isTrash || hasRoot)
899  {
900  QLabel *lab = new QLabel(d->m_frame );
901  if ( d->bMultiple )
902  lab->setText( KIO::itemsSummaryString( iFileCount + iDirCount, iFileCount, iDirCount, 0, false ) );
903  else
904  lab->setText( filename );
905  d->nameArea = lab;
906  } else
907  {
908  d->m_lined = new KLineEdit( d->m_frame );
909  d->m_lined->setText(filename);
910  d->nameArea = d->m_lined;
911  d->m_lined->setFocus();
912 
913  //if we don't have permissions to rename, we need to make "m_lined" read only.
914  KFileItemListProperties itemList(KFileItemList()<< item);
915  setFileNameReadOnly(!itemList.supportsMoving());
916 
917  // Enhanced rename: Don't highlight the file extension.
918  QString extension = KMimeType::extractKnownExtension( filename );
919  if ( !extension.isEmpty() )
920  d->m_lined->setSelection( 0, filename.length() - extension.length() - 1 );
921  else
922  {
923  int lastDot = filename.lastIndexOf('.');
924  if (lastDot > 0)
925  d->m_lined->setSelection(0, lastDot);
926  }
927 
928  connect( d->m_lined, SIGNAL(textChanged(QString)),
929  this, SLOT(nameFileChanged(QString)) );
930  }
931 
932  grid->addWidget(d->nameArea, curRow++, 2);
933 
934  KSeparator* sep = new KSeparator( Qt::Horizontal, d->m_frame);
935  grid->addWidget(sep, curRow, 0, 1, 3);
936  ++curRow;
937 
938  QLabel *l;
939  if (!mimeComment.isEmpty() && !isTrash) {
940  l = new QLabel(i18n("Type:"), d->m_frame );
941  grid->addWidget(l, curRow, 0, Qt::AlignRight | Qt::AlignTop);
942 
943  KVBox *box = new KVBox(d->m_frame);
944  box->setSpacing(2); // without that spacing the button literally “sticks” to the label ;)
945  l = new QLabel(mimeComment, box );
946  grid->addWidget(box, curRow++, 2);
947 
948  QPushButton *button = new QPushButton(box);
949  button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); // Minimum still makes the button grow to the entire layout width
950  button->setIcon( KIcon(QString::fromLatin1("configure")) );
951 
952  if ( d->mimeType == KMimeType::defaultMimeType() )
953  button->setText(i18n("Create New File Type"));
954  else
955  button->setText(i18n("File Type Options"));
956 
957  connect( button, SIGNAL(clicked()), SLOT(slotEditFileType()));
958 
959  if (!KAuthorized::authorizeKAction("editfiletype"))
960  button->hide();
961  }
962 
963  if ( !magicMimeComment.isEmpty() && magicMimeComment != mimeComment )
964  {
965  l = new QLabel(i18n("Contents:"), d->m_frame );
966  grid->addWidget(l, curRow, 0, Qt::AlignRight);
967 
968  l = new QLabel(magicMimeComment, d->m_frame );
969  grid->addWidget(l, curRow++, 2);
970  }
971 
972  if ( !directory.isEmpty() )
973  {
974  l = new QLabel( i18n("Location:"), d->m_frame );
975  grid->addWidget(l, curRow, 0, Qt::AlignRight);
976 
977  l = new KSqueezedTextLabel( directory, d->m_frame );
978  // force the layout direction to be always LTR
979  l->setLayoutDirection(Qt::LeftToRight);
980  // but if we are in RTL mode, align the text to the right
981  // otherwise the text is on the wrong side of the dialog
982  if (properties->layoutDirection() == Qt::RightToLeft)
983  l->setAlignment( Qt::AlignRight );
984  l->setTextInteractionFlags(Qt::TextSelectableByMouse|Qt::TextSelectableByKeyboard);
985  grid->addWidget(l, curRow++, 2);
986  }
987 
988  l = new QLabel(i18n("Size:"), d->m_frame );
989  grid->addWidget(l, curRow, 0, Qt::AlignRight);
990 
991  d->m_sizeLabel = new QLabel( d->m_frame );
992  grid->addWidget( d->m_sizeLabel, curRow++, 2 );
993 
994  if ( !hasDirs ) // Only files [and symlinks]
995  {
996  d->m_sizeLabel->setText(QString::fromLatin1("%1 (%2)").arg(KIO::convertSize(totalSize))
997  .arg(KGlobal::locale()->formatNumber(totalSize, 0)));
998  d->m_sizeDetermineButton = 0L;
999  d->m_sizeStopButton = 0L;
1000  }
1001  else // Directory
1002  {
1003  QHBoxLayout * sizelay = new QHBoxLayout();
1004  grid->addLayout( sizelay, curRow++, 2 );
1005 
1006  // buttons
1007  d->m_sizeDetermineButton = new QPushButton( i18n("Calculate"), d->m_frame );
1008  d->m_sizeStopButton = new QPushButton( i18n("Stop"), d->m_frame );
1009  connect( d->m_sizeDetermineButton, SIGNAL(clicked()), this, SLOT(slotSizeDetermine()) );
1010  connect( d->m_sizeStopButton, SIGNAL(clicked()), this, SLOT(slotSizeStop()) );
1011  sizelay->addWidget(d->m_sizeDetermineButton, 0);
1012  sizelay->addWidget(d->m_sizeStopButton, 0);
1013  sizelay->addStretch(10); // so that the buttons don't grow horizontally
1014 
1015  // auto-launch for local dirs only, and not for '/'
1016  if ( isLocal && !hasRoot )
1017  {
1018  d->m_sizeDetermineButton->setText( i18n("Refresh") );
1019  slotSizeDetermine();
1020  }
1021  else
1022  d->m_sizeStopButton->setEnabled( false );
1023  }
1024 
1025  if (!d->bMultiple && item.isLink()) {
1026  l = new QLabel(i18n("Points to:"), d->m_frame );
1027  grid->addWidget(l, curRow, 0, Qt::AlignRight);
1028 
1029  d->m_linkTargetLineEdit = new KLineEdit(item.linkDest(), d->m_frame );
1030  grid->addWidget(d->m_linkTargetLineEdit, curRow++, 2);
1031  connect(d->m_linkTargetLineEdit, SIGNAL(textChanged(QString)), this, SLOT(setDirty()));
1032  }
1033 
1034  if (!d->bMultiple) // Dates for multiple don't make much sense...
1035  {
1036  KDateTime dt = item.time(KFileItem::CreationTime);
1037  if ( !dt.isNull() )
1038  {
1039  l = new QLabel(i18n("Created:"), d->m_frame );
1040  grid->addWidget(l, curRow, 0, Qt::AlignRight);
1041 
1042  l = new QLabel(KGlobal::locale()->formatDateTime(dt), d->m_frame );
1043  grid->addWidget(l, curRow++, 2);
1044  }
1045 
1046  dt = item.time(KFileItem::ModificationTime);
1047  if ( !dt.isNull() )
1048  {
1049  l = new QLabel(i18n("Modified:"), d->m_frame );
1050  grid->addWidget(l, curRow, 0, Qt::AlignRight);
1051 
1052  l = new QLabel(KGlobal::locale()->formatDateTime(dt), d->m_frame );
1053  grid->addWidget(l, curRow++, 2);
1054  }
1055 
1056  dt = item.time(KFileItem::AccessTime);
1057  if ( !dt.isNull() )
1058  {
1059  l = new QLabel(i18n("Accessed:"), d->m_frame );
1060  grid->addWidget(l, curRow, 0, Qt::AlignRight);
1061 
1062  l = new QLabel(KGlobal::locale()->formatDateTime(dt), d->m_frame );
1063  grid->addWidget(l, curRow++, 2);
1064  }
1065  }
1066 
1067  if ( isLocal && hasDirs ) // only for directories
1068  {
1069 
1070  KMountPoint::Ptr mp = KMountPoint::currentMountPoints().findByPath(url.toLocalFile());
1071  if (mp) {
1072  KDiskFreeSpaceInfo info = KDiskFreeSpaceInfo::freeSpaceInfo( mp->mountPoint() );
1073  if(info.size() != 0 )
1074  {
1075  sep = new KSeparator( Qt::Horizontal, d->m_frame);
1076  grid->addWidget(sep, curRow, 0, 1, 3);
1077  ++curRow;
1078  if (mp->mountPoint() != "/")
1079  {
1080  l = new QLabel(i18n("Mounted on:"), d->m_frame );
1081  grid->addWidget(l, curRow, 0, Qt::AlignRight);
1082 
1083  l = new KSqueezedTextLabel( mp->mountPoint(), d->m_frame );
1084  l->setTextInteractionFlags(Qt::TextSelectableByMouse|Qt::TextSelectableByKeyboard);
1085  grid->addWidget( l, curRow++, 2 );
1086  }
1087 
1088  l = new QLabel(i18n("Device usage:"), d->m_frame );
1089  grid->addWidget(l, curRow, 0, Qt::AlignRight);
1090 
1091  d->m_capacityBar = new KCapacityBar( KCapacityBar::DrawTextOutline, d->m_frame );
1092  grid->addWidget( d->m_capacityBar, curRow++, 2);
1093 
1094  slotFoundMountPoint( info.mountPoint(), info.size()/1024, info.used()/1024, info.available()/1024);
1095  }
1096  }
1097  }
1098 
1099  vbl->addStretch(1);
1100 }
1101 
1102 bool KFilePropsPlugin::enableIconButton() const
1103 {
1104  bool iconEnabled = false;
1105  const KFileItem item = properties->item();
1106  // If the current item is a directory, check if it's writable,
1107  // so we can create/update a .directory
1108  // Current item is a file, same thing: check if it is writable
1109  if (item.isWritable()) {
1110  iconEnabled = true;
1111  }
1112  return iconEnabled;
1113 }
1114 
1115 // QString KFilePropsPlugin::tabName () const
1116 // {
1117 // return i18n ("&General");
1118 // }
1119 
1120 void KFilePropsPlugin::setFileNameReadOnly( bool ro )
1121 {
1122  if ( d->m_lined && !d->m_bFromTemplate )
1123  {
1124  d->m_lined->setReadOnly( ro );
1125  if (ro)
1126  {
1127  // Don't put the initial focus on the line edit when it is ro
1128  properties->setButtonFocus(KDialog::Ok);
1129  }
1130  }
1131 }
1132 
1133 void KFilePropsPlugin::slotEditFileType()
1134 {
1135  QString mime;
1136  if (d->mimeType == KMimeType::defaultMimeType()) {
1137  const int pos = d->oldFileName.lastIndexOf('.');
1138  if (pos != -1)
1139  mime = '*' + d->oldFileName.mid(pos);
1140  else
1141  mime = '*';
1142  } else {
1143  mime = d->mimeType;
1144  }
1145  QString keditfiletype = QString::fromLatin1("keditfiletype");
1146  KRun::runCommand( keditfiletype
1147 #ifdef Q_WS_X11
1148  + " --parent " + QString::number( (ulong)properties->window()->winId())
1149 #endif
1150  + " --caption " + KShell::quoteArg(KGlobal::caption())
1151  + ' ' + KShell::quoteArg(mime),
1152  keditfiletype, keditfiletype /*unused*/, properties->window());
1153 }
1154 
1155 void KFilePropsPlugin::slotIconChanged()
1156 {
1157  d->bIconChanged = true;
1158  emit changed();
1159 }
1160 
1161 void KFilePropsPlugin::nameFileChanged(const QString &text )
1162 {
1163  properties->enableButtonOk(!text.isEmpty());
1164  emit changed();
1165 }
1166 
1167 void KFilePropsPlugin::determineRelativePath( const QString & path )
1168 {
1169  // now let's make it relative
1170  d->m_sRelativePath = KGlobal::dirs()->relativeLocation("apps", path);
1171  if (d->m_sRelativePath.startsWith('/'))
1172  {
1173  d->m_sRelativePath =KGlobal::dirs()->relativeLocation("xdgdata-apps", path);
1174  if (d->m_sRelativePath.startsWith('/'))
1175  d->m_sRelativePath.clear();
1176  else
1177  d->m_sRelativePath = path;
1178  }
1179 }
1180 
1181 void KFilePropsPlugin::slotFoundMountPoint( const QString&,
1182  quint64 kibSize,
1183  quint64 /*kibUsed*/,
1184  quint64 kibAvail )
1185 {
1186  d->m_capacityBar->setText(
1187  i18nc("Available space out of total partition size (percent used)", "%1 free of %2 (%3% used)",
1188  KIO::convertSizeFromKiB(kibAvail),
1189  KIO::convertSizeFromKiB(kibSize),
1190  100 - (int)(100.0 * kibAvail / kibSize) ));
1191 
1192  d->m_capacityBar->setValue(100 - (int)(100.0 * kibAvail / kibSize));
1193 }
1194 
1195 void KFilePropsPlugin::slotDirSizeUpdate()
1196 {
1197  KIO::filesize_t totalSize = d->dirSizeJob->totalSize();
1198  KIO::filesize_t totalFiles = d->dirSizeJob->totalFiles();
1199  KIO::filesize_t totalSubdirs = d->dirSizeJob->totalSubdirs();
1200  d->m_sizeLabel->setText(
1201  i18n("Calculating... %1 (%2)\n%3, %4",
1202  KIO::convertSize(totalSize),
1203  totalSize,
1204  i18np("1 file", "%1 files", totalFiles),
1205  i18np("1 sub-folder", "%1 sub-folders", totalSubdirs)));
1206 }
1207 
1208 void KFilePropsPlugin::slotDirSizeFinished( KJob * job )
1209 {
1210  if (job->error())
1211  d->m_sizeLabel->setText( job->errorString() );
1212  else
1213  {
1214  KIO::filesize_t totalSize = d->dirSizeJob->totalSize();
1215  KIO::filesize_t totalFiles = d->dirSizeJob->totalFiles();
1216  KIO::filesize_t totalSubdirs = d->dirSizeJob->totalSubdirs();
1217  d->m_sizeLabel->setText( QString::fromLatin1("%1 (%2)\n%3, %4")
1218  .arg(KIO::convertSize(totalSize))
1219  .arg(KGlobal::locale()->formatNumber(totalSize, 0))
1220  .arg(i18np("1 file","%1 files",totalFiles))
1221  .arg(i18np("1 sub-folder","%1 sub-folders",totalSubdirs)));
1222  }
1223  d->m_sizeStopButton->setEnabled(false);
1224  // just in case you change something and try again :)
1225  d->m_sizeDetermineButton->setText( i18n("Refresh") );
1226  d->m_sizeDetermineButton->setEnabled(true);
1227  d->dirSizeJob = 0;
1228  delete d->dirSizeUpdateTimer;
1229  d->dirSizeUpdateTimer = 0;
1230 }
1231 
1232 void KFilePropsPlugin::slotSizeDetermine()
1233 {
1234  d->m_sizeLabel->setText( i18n("Calculating...") );
1235  kDebug(250) << " KFilePropsPlugin::slotSizeDetermine() properties->item()=" << properties->item();
1236  kDebug(250) << " URL=" << properties->item().url().url();
1237 
1238  d->dirSizeJob = KIO::directorySize( properties->items() );
1239  d->dirSizeUpdateTimer = new QTimer(this);
1240  connect( d->dirSizeUpdateTimer, SIGNAL(timeout()),
1241  SLOT(slotDirSizeUpdate()) );
1242  d->dirSizeUpdateTimer->start(500);
1243  connect( d->dirSizeJob, SIGNAL(result(KJob*)),
1244  SLOT(slotDirSizeFinished(KJob*)) );
1245  d->m_sizeStopButton->setEnabled(true);
1246  d->m_sizeDetermineButton->setEnabled(false);
1247 
1248  // also update the "Free disk space" display
1249  if ( d->m_capacityBar )
1250  {
1251  bool isLocal;
1252  const KFileItem item = properties->item();
1253  KUrl url = item.mostLocalUrl( isLocal );
1254  if (isLocal) {
1255  KMountPoint::Ptr mp = KMountPoint::currentMountPoints().findByPath(url.toLocalFile());
1256  if (mp) {
1257  KDiskFreeSpaceInfo info = KDiskFreeSpaceInfo::freeSpaceInfo( mp->mountPoint() );
1258  slotFoundMountPoint( info.mountPoint(), info.size()/1024, info.used()/1024, info.available()/1024);
1259  }
1260  }
1261  }
1262 }
1263 
1264 void KFilePropsPlugin::slotSizeStop()
1265 {
1266  if ( d->dirSizeJob )
1267  {
1268  KIO::filesize_t totalSize = d->dirSizeJob->totalSize();
1269  d->m_sizeLabel->setText(i18n("At least %1",
1270  KIO::convertSize(totalSize)));
1271  d->dirSizeJob->kill();
1272  d->dirSizeJob = 0;
1273  }
1274  if ( d->dirSizeUpdateTimer )
1275  d->dirSizeUpdateTimer->stop();
1276 
1277  d->m_sizeStopButton->setEnabled(false);
1278  d->m_sizeDetermineButton->setEnabled(true);
1279 }
1280 
1281 KFilePropsPlugin::~KFilePropsPlugin()
1282 {
1283  delete d;
1284 }
1285 
1286 bool KFilePropsPlugin::supports( const KFileItemList& /*_items*/ )
1287 {
1288  return true;
1289 }
1290 
1291 void KFilePropsPlugin::applyChanges()
1292 {
1293  if ( d->dirSizeJob )
1294  slotSizeStop();
1295 
1296  kDebug(250) << "KFilePropsPlugin::applyChanges";
1297 
1298  if (qobject_cast<QLineEdit*>(d->nameArea))
1299  {
1300  QString n = ((QLineEdit *) d->nameArea)->text();
1301  // Remove trailing spaces (#4345)
1302  while ( ! n.isEmpty() && n[n.length()-1].isSpace() )
1303  n.truncate( n.length() - 1 );
1304  if ( n.isEmpty() )
1305  {
1306  KMessageBox::sorry( properties, i18n("The new file name is empty."));
1307  properties->abortApplying();
1308  return;
1309  }
1310 
1311  // Do we need to rename the file ?
1312  kDebug(250) << "oldname = " << d->oldName;
1313  kDebug(250) << "newname = " << n;
1314  if ( d->oldName != n || d->m_bFromTemplate ) { // true for any from-template file
1315  KIO::Job * job = 0L;
1316  KUrl oldurl = properties->kurl();
1317 
1318  QString newFileName = KIO::encodeFileName(n);
1319  if (d->bDesktopFile && !newFileName.endsWith(QLatin1String(".desktop")) &&
1320  !newFileName.endsWith(QLatin1String(".kdelnk")))
1321  newFileName += ".desktop";
1322 
1323  // Tell properties. Warning, this changes the result of properties->kurl() !
1324  properties->rename( newFileName );
1325 
1326  // Update also relative path (for apps and mimetypes)
1327  if ( !d->m_sRelativePath.isEmpty() )
1328  determineRelativePath( properties->kurl().toLocalFile() );
1329 
1330  kDebug(250) << "New URL = " << properties->kurl().url();
1331  kDebug(250) << "old = " << oldurl.url();
1332 
1333  // Don't remove the template !!
1334  if ( !d->m_bFromTemplate ) // (normal renaming)
1335  job = KIO::moveAs( oldurl, properties->kurl() );
1336  else // Copying a template
1337  job = KIO::copyAs( oldurl, properties->kurl() );
1338 
1339  connect( job, SIGNAL(result(KJob*)),
1340  SLOT(slotCopyFinished(KJob*)) );
1341  connect( job, SIGNAL(renamed(KIO::Job*,KUrl,KUrl)),
1342  SLOT(slotFileRenamed(KIO::Job*,KUrl,KUrl)) );
1343  // wait for job
1344  QEventLoop eventLoop;
1345  connect(this, SIGNAL(leaveModality()),
1346  &eventLoop, SLOT(quit()));
1347  eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
1348  return;
1349  }
1350  properties->updateUrl(properties->kurl());
1351  // Update also relative path (for apps and mimetypes)
1352  if ( !d->m_sRelativePath.isEmpty() )
1353  determineRelativePath( properties->kurl().toLocalFile() );
1354  }
1355 
1356  // No job, keep going
1357  slotCopyFinished( 0L );
1358 }
1359 
1360 void KFilePropsPlugin::slotCopyFinished( KJob * job )
1361 {
1362  kDebug(250) << "KFilePropsPlugin::slotCopyFinished";
1363  if (job)
1364  {
1365  // allow apply() to return
1366  emit leaveModality();
1367  if ( job->error() )
1368  {
1369  job->uiDelegate()->showErrorMessage();
1370  // Didn't work. Revert the URL to the old one
1371  properties->updateUrl( static_cast<KIO::CopyJob*>(job)->srcUrls().first() );
1372  properties->abortApplying(); // Don't apply the changes to the wrong file !
1373  return;
1374  }
1375  }
1376 
1377  Q_ASSERT( !properties->item().isNull() );
1378  Q_ASSERT( !properties->item().url().isEmpty() );
1379 
1380  // Save the file where we can -> usually in ~/.kde/...
1381  if (d->bDesktopFile && !d->m_sRelativePath.isEmpty())
1382  {
1383  kDebug(250) << "KFilePropsPlugin::slotCopyFinished " << d->m_sRelativePath;
1384  KUrl newURL;
1385  newURL.setPath( KDesktopFile::locateLocal(d->m_sRelativePath) );
1386  kDebug(250) << "KFilePropsPlugin::slotCopyFinished path=" << newURL.path();
1387  properties->updateUrl( newURL );
1388  }
1389 
1390  if ( d->bKDesktopMode && d->bDesktopFile ) {
1391  // Renamed? Update Name field
1392  // Note: The desktop ioslave does this as well, but not when
1393  // the file is copied from a template.
1394  if ( d->m_bFromTemplate ) {
1395  KIO::UDSEntry entry;
1396  KIO::NetAccess::stat( properties->kurl(), entry, 0 );
1397  KFileItem item( entry, properties->kurl() );
1398  KDesktopFile config( item.localPath() );
1399  KConfigGroup cg = config.desktopGroup();
1400  QString nameStr = nameFromFileName(properties->kurl().fileName());
1401  cg.writeEntry( "Name", nameStr );
1402  cg.writeEntry( "Name", nameStr, KConfigGroup::Persistent|KConfigGroup::Localized);
1403  }
1404  }
1405 
1406  if (d->m_linkTargetLineEdit && !d->bMultiple) {
1407  const KFileItem item = properties->item();
1408  const QString newTarget = d->m_linkTargetLineEdit->text();
1409  if (newTarget != item.linkDest()) {
1410  kDebug(250) << "Updating target of symlink to" << newTarget;
1411  KIO::Job* job = KIO::symlink(newTarget, item.url(), KIO::Overwrite);
1412  job->ui()->setAutoErrorHandlingEnabled(true);
1413  job->exec();
1414  }
1415  }
1416 
1417  // "Link to Application" templates need to be made executable
1418  // Instead of matching against a filename we check if the destination
1419  // is an Application now.
1420  if ( d->m_bFromTemplate ) {
1421  // destination is not necessarily local, use the src template
1422  KDesktopFile templateResult ( static_cast<KIO::CopyJob*>(job)->srcUrls().first().toLocalFile() );
1423  if ( templateResult.hasApplicationType() ) {
1424  // We can either stat the file and add the +x bit or use the larger chmod() job
1425  // with a umask designed to only touch u+x. This is only one KIO job, so let's
1426  // do that.
1427 
1428  KFileItem appLink ( properties->item() );
1429  KFileItemList fileItemList;
1430  fileItemList << appLink;
1431 
1432  // first 0100 adds u+x, second 0100 only allows chmod to change u+x
1433  KIO::Job* chmodJob = KIO::chmod( fileItemList, 0100, 0100, QString(), QString(), KIO::HideProgressInfo );
1434  chmodJob->exec();
1435  }
1436  }
1437 }
1438 
1439 void KFilePropsPlugin::applyIconChanges()
1440 {
1441  KIconButton *iconButton = qobject_cast<KIconButton*>(d->iconArea);
1442  if ( !iconButton || !d->bIconChanged )
1443  return;
1444  // handle icon changes - only local files (or pseudo-local) for now
1445  // TODO: Use KTempFile and KIO::file_copy with overwrite = true
1446  KUrl url = properties->kurl();
1447  url = KIO::NetAccess::mostLocalUrl( url, properties );
1448  if ( url.isLocalFile()) {
1449  QString path;
1450 
1451  if (S_ISDIR(properties->item().mode()))
1452  {
1453  path = url.toLocalFile(KUrl::AddTrailingSlash) + QString::fromLatin1(".directory");
1454  // don't call updateUrl because the other tabs (i.e. permissions)
1455  // apply to the directory, not the .directory file.
1456  }
1457  else
1458  path = url.toLocalFile();
1459 
1460  // Get the default image
1461  QString str = KMimeType::findByUrl( url,
1462  properties->item().mode(),
1463  true )->iconName();
1464  // Is it another one than the default ?
1465  QString sIcon;
1466  if ( str != iconButton->icon() )
1467  sIcon = iconButton->icon();
1468  // (otherwise write empty value)
1469 
1470  kDebug(250) << "**" << path << "**";
1471 
1472  // If default icon and no .directory file -> don't create one
1473  if ( !sIcon.isEmpty() || QFile::exists(path) )
1474  {
1475  KDesktopFile cfg(path);
1476  kDebug(250) << "sIcon = " << (sIcon);
1477  kDebug(250) << "str = " << (str);
1478  cfg.desktopGroup().writeEntry( "Icon", sIcon );
1479  cfg.sync();
1480 
1481  cfg.reparseConfiguration();
1482  if ( cfg.desktopGroup().readEntry("Icon") != sIcon ) {
1483  KMessageBox::sorry( 0, i18n("<qt>Could not save properties. You do not "
1484  "have sufficient access to write to <b>%1</b>.</qt>", path));
1485  }
1486  }
1487  }
1488 }
1489 
1490 void KFilePropsPlugin::slotFileRenamed( KIO::Job *, const KUrl &, const KUrl & newUrl )
1491 {
1492  // This is called in case of an existing local file during the copy/move operation,
1493  // if the user chooses Rename.
1494  properties->updateUrl( newUrl );
1495 }
1496 
1497 void KFilePropsPlugin::postApplyChanges()
1498 {
1499  // Save the icon only after applying the permissions changes (#46192)
1500  applyIconChanges();
1501 
1502  const KFileItemList items = properties->items();
1503  const KUrl::List lst = items.urlList();
1504  org::kde::KDirNotify::emitFilesChanged( lst.toStringList() );
1505 }
1506 
1507 class KFilePermissionsPropsPlugin::KFilePermissionsPropsPluginPrivate
1508 {
1509 public:
1510  KFilePermissionsPropsPluginPrivate()
1511  {
1512  }
1513  ~KFilePermissionsPropsPluginPrivate()
1514  {
1515  }
1516 
1517  QFrame *m_frame;
1518  QCheckBox *cbRecursive;
1519  QLabel *explanationLabel;
1520  KComboBox *ownerPermCombo, *groupPermCombo, *othersPermCombo;
1521  QCheckBox *extraCheckbox;
1522  mode_t partialPermissions;
1523  KFilePermissionsPropsPlugin::PermissionsMode pmode;
1524  bool canChangePermissions;
1525  bool isIrregular;
1526  bool hasExtendedACL;
1527  KACL extendedACL;
1528  KACL defaultACL;
1529  bool fileSystemSupportsACLs;
1530 
1531  KComboBox *grpCombo;
1532 
1533  KLineEdit *usrEdit;
1534  KLineEdit *grpEdit;
1535 
1536  // Old permissions
1537  mode_t permissions;
1538  // Old group
1539  QString strGroup;
1540  // Old owner
1541  QString strOwner;
1542 };
1543 
1544 #define UniOwner (S_IRUSR|S_IWUSR|S_IXUSR)
1545 #define UniGroup (S_IRGRP|S_IWGRP|S_IXGRP)
1546 #define UniOthers (S_IROTH|S_IWOTH|S_IXOTH)
1547 #define UniRead (S_IRUSR|S_IRGRP|S_IROTH)
1548 #define UniWrite (S_IWUSR|S_IWGRP|S_IWOTH)
1549 #define UniExec (S_IXUSR|S_IXGRP|S_IXOTH)
1550 #define UniSpecial (S_ISUID|S_ISGID|S_ISVTX)
1551 
1552 // synced with PermissionsTarget
1553 const mode_t KFilePermissionsPropsPlugin::permissionsMasks[3] = {UniOwner, UniGroup, UniOthers};
1554 const mode_t KFilePermissionsPropsPlugin::standardPermissions[4] = { 0, UniRead, UniRead|UniWrite, (mode_t)-1 };
1555 
1556 // synced with PermissionsMode and standardPermissions
1557 const char *KFilePermissionsPropsPlugin::permissionsTexts[4][4] = {
1558  { I18N_NOOP("Forbidden"),
1559  I18N_NOOP("Can Read"),
1560  I18N_NOOP("Can Read & Write"),
1561  0 },
1562 { I18N_NOOP("Forbidden"),
1563  I18N_NOOP("Can View Content"),
1564  I18N_NOOP("Can View & Modify Content"),
1565  0 },
1566 { 0, 0, 0, 0}, // no texts for links
1567 { I18N_NOOP("Forbidden"),
1568  I18N_NOOP("Can View Content & Read"),
1569  I18N_NOOP("Can View/Read & Modify/Write"),
1570  0 }
1571 };
1572 
1573 
1574 KFilePermissionsPropsPlugin::KFilePermissionsPropsPlugin( KPropertiesDialog *_props )
1575  : KPropertiesDialogPlugin( _props ),d(new KFilePermissionsPropsPluginPrivate)
1576 {
1577  d->cbRecursive = 0L;
1578  d->grpCombo = 0L; d->grpEdit = 0;
1579  d->usrEdit = 0L;
1580  QString path = properties->kurl().path(KUrl::RemoveTrailingSlash);
1581  QString fname = properties->kurl().fileName();
1582  bool isLocal = properties->kurl().isLocalFile();
1583  bool isTrash = ( properties->kurl().protocol().toLower() == "trash" );
1584  bool IamRoot = (geteuid() == 0);
1585 
1586  const KFileItem item = properties->item();
1587  bool isLink = item.isLink();
1588  bool isDir = item.isDir(); // all dirs
1589  bool hasDir = item.isDir(); // at least one dir
1590  d->permissions = item.permissions(); // common permissions to all files
1591  d->partialPermissions = d->permissions; // permissions that only some files have (at first we take everything)
1592  d->isIrregular = isIrregular(d->permissions, isDir, isLink);
1593  d->strOwner = item.user();
1594  d->strGroup = item.group();
1595  d->hasExtendedACL = item.ACL().isExtended() || item.defaultACL().isValid();
1596  d->extendedACL = item.ACL();
1597  d->defaultACL = item.defaultACL();
1598  d->fileSystemSupportsACLs = false;
1599 
1600  if ( properties->items().count() > 1 )
1601  {
1602  // Multiple items: see what they have in common
1603  const KFileItemList items = properties->items();
1604  KFileItemList::const_iterator it = items.begin();
1605  const KFileItemList::const_iterator kend = items.end();
1606  for ( ++it /*no need to check the first one again*/ ; it != kend; ++it )
1607  {
1608  const KUrl url = (*it).url();
1609  if (!d->isIrregular)
1610  d->isIrregular |= isIrregular((*it).permissions(),
1611  (*it).isDir() == isDir,
1612  (*it).isLink() == isLink);
1613  d->hasExtendedACL = d->hasExtendedACL || (*it).hasExtendedACL();
1614  if ( (*it).isLink() != isLink )
1615  isLink = false;
1616  if ( (*it).isDir() != isDir )
1617  isDir = false;
1618  hasDir |= (*it).isDir();
1619  if ( (*it).permissions() != d->permissions )
1620  {
1621  d->permissions &= (*it).permissions();
1622  d->partialPermissions |= (*it).permissions();
1623  }
1624  if ( (*it).user() != d->strOwner )
1625  d->strOwner.clear();
1626  if ( (*it).group() != d->strGroup )
1627  d->strGroup.clear();
1628  }
1629  }
1630 
1631  if (isLink)
1632  d->pmode = PermissionsOnlyLinks;
1633  else if (isDir)
1634  d->pmode = PermissionsOnlyDirs;
1635  else if (hasDir)
1636  d->pmode = PermissionsMixed;
1637  else
1638  d->pmode = PermissionsOnlyFiles;
1639 
1640  // keep only what's not in the common permissions
1641  d->partialPermissions = d->partialPermissions & ~d->permissions;
1642 
1643  bool isMyFile = false;
1644 
1645  if (isLocal && !d->strOwner.isEmpty()) { // local files, and all owned by the same person
1646  struct passwd *myself = getpwuid( geteuid() );
1647  if ( myself != 0L )
1648  {
1649  isMyFile = (d->strOwner == QString::fromLocal8Bit(myself->pw_name));
1650  } else
1651  kWarning() << "I don't exist ?! geteuid=" << geteuid();
1652  } else {
1653  //We don't know, for remote files, if they are ours or not.
1654  //So we let the user change permissions, and
1655  //KIO::chmod will tell, if he had no right to do it.
1656  isMyFile = true;
1657  }
1658 
1659  d->canChangePermissions = (isMyFile || IamRoot) && (!isLink);
1660 
1661 
1662  // create GUI
1663 
1664  d->m_frame = new QFrame();
1665  properties->addPage( d->m_frame, i18n("&Permissions") );
1666 
1667  QBoxLayout *box = new QVBoxLayout( d->m_frame );
1668  box->setMargin( 0 );
1669 
1670  QWidget *l;
1671  QLabel *lbl;
1672  QGroupBox *gb;
1673  QGridLayout *gl;
1674  QPushButton* pbAdvancedPerm = 0;
1675 
1676  /* Group: Access Permissions */
1677  gb = new QGroupBox ( i18n("Access Permissions"), d->m_frame );
1678  box->addWidget (gb);
1679 
1680  gl = new QGridLayout (gb);
1681  gl->setColumnStretch(1, 1);
1682 
1683  l = d->explanationLabel = new QLabel( "", gb );
1684  if (isLink)
1685  d->explanationLabel->setText(i18np("This file is a link and does not have permissions.",
1686  "All files are links and do not have permissions.",
1687  properties->items().count()));
1688  else if (!d->canChangePermissions)
1689  d->explanationLabel->setText(i18n("Only the owner can change permissions."));
1690  gl->addWidget(l, 0, 0, 1, 2);
1691 
1692  lbl = new QLabel( i18n("O&wner:"), gb);
1693  gl->addWidget(lbl, 1, 0, Qt::AlignRight);
1694  l = d->ownerPermCombo = new KComboBox(gb);
1695  lbl->setBuddy(l);
1696  gl->addWidget(l, 1, 1);
1697  connect(l, SIGNAL(activated(int)), this, SIGNAL(changed()));
1698  l->setWhatsThis(i18n("Specifies the actions that the owner is allowed to do."));
1699 
1700  lbl = new QLabel( i18n("Gro&up:"), gb);
1701  gl->addWidget(lbl, 2, 0, Qt::AlignRight);
1702  l = d->groupPermCombo = new KComboBox(gb);
1703  lbl->setBuddy(l);
1704  gl->addWidget(l, 2, 1);
1705  connect(l, SIGNAL(activated(int)), this, SIGNAL(changed()));
1706  l->setWhatsThis(i18n("Specifies the actions that the members of the group are allowed to do."));
1707 
1708  lbl = new QLabel( i18n("O&thers:"), gb);
1709  gl->addWidget(lbl, 3, 0, Qt::AlignRight);
1710  l = d->othersPermCombo = new KComboBox(gb);
1711  lbl->setBuddy(l);
1712  gl->addWidget(l, 3, 1);
1713  connect(l, SIGNAL(activated(int)), this, SIGNAL(changed()));
1714  l->setWhatsThis(i18n("Specifies the actions that all users, who are neither "
1715  "owner nor in the group, are allowed to do."));
1716 
1717  if (!isLink) {
1718  l = d->extraCheckbox = new QCheckBox(hasDir ?
1719  i18n("Only own&er can rename and delete folder content") :
1720  i18n("Is &executable"),
1721  gb );
1722  connect( d->extraCheckbox, SIGNAL(clicked()), this, SIGNAL(changed()) );
1723  gl->addWidget(l, 4, 1);
1724  l->setWhatsThis(hasDir ? i18n("Enable this option to allow only the folder's owner to "
1725  "delete or rename the contained files and folders. Other "
1726  "users can only add new files, which requires the 'Modify "
1727  "Content' permission.")
1728  : i18n("Enable this option to mark the file as executable. This only makes "
1729  "sense for programs and scripts. It is required when you want to "
1730  "execute them."));
1731 
1732  QLayoutItem *spacer = new QSpacerItem(0, 20, QSizePolicy::Minimum, QSizePolicy::Expanding);
1733  gl->addItem(spacer, 5, 0, 1, 3);
1734 
1735  pbAdvancedPerm = new QPushButton(i18n("A&dvanced Permissions"), gb);
1736  gl->addWidget(pbAdvancedPerm, 6, 0, 1, 2, Qt::AlignRight);
1737  connect(pbAdvancedPerm, SIGNAL(clicked()), this, SLOT(slotShowAdvancedPermissions()));
1738  }
1739  else
1740  d->extraCheckbox = 0;
1741 
1742 
1743  /**** Group: Ownership ****/
1744  gb = new QGroupBox ( i18n("Ownership"), d->m_frame );
1745  box->addWidget (gb);
1746 
1747  gl = new QGridLayout (gb);
1748  gl->addItem(new QSpacerItem(0, 10), 0, 0);
1749 
1750  /*** Set Owner ***/
1751  l = new QLabel( i18n("User:"), gb );
1752  gl->addWidget (l, 1, 0, Qt::AlignRight);
1753 
1754  /* GJ: Don't autocomplete more than 1000 users. This is a kind of random
1755  * value. Huge sites having 10.000+ user have a fair chance of using NIS,
1756  * (possibly) making this unacceptably slow.
1757  * OTOH, it is nice to offer this functionality for the standard user.
1758  */
1759  int i, maxEntries = 1000;
1760  struct passwd *user;
1761 
1762  /* File owner: For root, offer a KLineEdit with autocompletion.
1763  * For a user, who can never chown() a file, offer a QLabel.
1764  */
1765  if (IamRoot && isLocal)
1766  {
1767  d->usrEdit = new KLineEdit( gb );
1768  KCompletion *kcom = d->usrEdit->completionObject();
1769  kcom->setOrder(KCompletion::Sorted);
1770  setpwent();
1771  for (i=0; ((user = getpwent()) != 0L) && (i < maxEntries); ++i)
1772  kcom->addItem(QString::fromLatin1(user->pw_name));
1773  endpwent();
1774  d->usrEdit->setCompletionMode((i < maxEntries) ? KGlobalSettings::CompletionAuto :
1775  KGlobalSettings::CompletionNone);
1776  d->usrEdit->setText(d->strOwner);
1777  gl->addWidget(d->usrEdit, 1, 1);
1778  connect( d->usrEdit, SIGNAL(textChanged(QString)),
1779  this, SIGNAL(changed()) );
1780  }
1781  else
1782  {
1783  l = new QLabel(d->strOwner, gb);
1784  gl->addWidget(l, 1, 1);
1785  }
1786 
1787  /*** Set Group ***/
1788 
1789  QStringList groupList;
1790  QByteArray strUser;
1791  user = getpwuid(geteuid());
1792  if (user != 0L)
1793  strUser = user->pw_name;
1794 
1795 #ifdef HAVE_GETGROUPLIST
1796  // pick the groups to which the user belongs
1797  int groupCount = 0;
1798 #ifdef Q_OS_MAC
1799  QVarLengthArray<int> groups;
1800 #else
1801  QVarLengthArray<gid_t> groups;
1802 #endif
1803  if (getgrouplist(strUser, user->pw_gid, NULL, &groupCount) < 0) {
1804  groups.resize(groupCount);
1805  if (groups.data())
1806  getgrouplist(strUser, user->pw_gid, groups.data(), &groupCount);
1807  else
1808  groupCount = 0;
1809  }
1810 
1811  for (i = 0; i < groupCount; i++) {
1812  struct group *mygroup = getgrgid(groups[i]);
1813  if (mygroup)
1814  groupList += QString::fromLocal8Bit(mygroup->gr_name);
1815  }
1816 #endif // HAVE_GETGROUPLIST
1817 
1818  bool isMyGroup = groupList.contains(d->strGroup);
1819 
1820  /* add the group the file currently belongs to ..
1821  * .. if it is not there already
1822  */
1823  if (!isMyGroup)
1824  groupList += d->strGroup;
1825 
1826  l = new QLabel( i18n("Group:"), gb );
1827  gl->addWidget (l, 2, 0, Qt::AlignRight);
1828 
1829  /* Set group: if possible to change:
1830  * - Offer a KLineEdit for root, since he can change to any group.
1831  * - Offer a KComboBox for a normal user, since he can change to a fixed
1832  * (small) set of groups only.
1833  * If not changeable: offer a QLabel.
1834  */
1835  if (IamRoot && isLocal)
1836  {
1837  d->grpEdit = new KLineEdit(gb);
1838  KCompletion *kcom = new KCompletion;
1839  kcom->setItems(groupList);
1840  d->grpEdit->setCompletionObject(kcom, true);
1841  d->grpEdit->setAutoDeleteCompletionObject( true );
1842  d->grpEdit->setCompletionMode(KGlobalSettings::CompletionAuto);
1843  d->grpEdit->setText(d->strGroup);
1844  gl->addWidget(d->grpEdit, 2, 1);
1845  connect( d->grpEdit, SIGNAL(textChanged(QString)),
1846  this, SIGNAL(changed()) );
1847  }
1848  else if ((groupList.count() > 1) && isMyFile && isLocal)
1849  {
1850  d->grpCombo = new KComboBox(gb);
1851  d->grpCombo->setObjectName(QLatin1String("combogrouplist"));
1852  d->grpCombo->addItems(groupList);
1853  d->grpCombo->setCurrentIndex(groupList.indexOf(d->strGroup));
1854  gl->addWidget(d->grpCombo, 2, 1);
1855  connect( d->grpCombo, SIGNAL(activated(int)),
1856  this, SIGNAL(changed()) );
1857  }
1858  else
1859  {
1860  l = new QLabel(d->strGroup, gb);
1861  gl->addWidget(l, 2, 1);
1862  }
1863 
1864  gl->setColumnStretch(2, 10);
1865 
1866  // "Apply recursive" checkbox
1867  if ( hasDir && !isLink && !isTrash )
1868  {
1869  d->cbRecursive = new QCheckBox( i18n("Apply changes to all subfolders and their contents"), d->m_frame );
1870  connect( d->cbRecursive, SIGNAL(clicked()), this, SIGNAL(changed()) );
1871  box->addWidget( d->cbRecursive );
1872  }
1873 
1874  updateAccessControls();
1875 
1876 
1877  if ( isTrash )
1878  {
1879  //don't allow to change properties for file into trash
1880  enableAccessControls(false);
1881  if ( pbAdvancedPerm)
1882  pbAdvancedPerm->setEnabled(false);
1883  }
1884 
1885  box->addStretch (10);
1886 }
1887 
1888 #ifdef HAVE_POSIX_ACL
1889 static bool fileSystemSupportsACL( const QByteArray& path )
1890 {
1891  bool fileSystemSupportsACLs = false;
1892 #ifdef Q_OS_FREEBSD
1893  struct statfs buf;
1894  fileSystemSupportsACLs = ( statfs( path.data(), &buf ) == 0 ) && ( buf.f_flags & MNT_ACLS );
1895 #else
1896  fileSystemSupportsACLs =
1897  getxattr( path.data(), "system.posix_acl_access", NULL, 0 ) >= 0 || errno == ENODATA;
1898 #endif
1899  return fileSystemSupportsACLs;
1900 }
1901 #endif
1902 
1903 
1904 void KFilePermissionsPropsPlugin::slotShowAdvancedPermissions() {
1905 
1906  bool isDir = (d->pmode == PermissionsOnlyDirs) || (d->pmode == PermissionsMixed);
1907  KDialog dlg( properties );
1908  dlg.setModal( true );
1909  dlg.setCaption( i18n("Advanced Permissions") );
1910  dlg.setButtons( KDialog::Ok | KDialog::Cancel );
1911 
1912  QLabel *l, *cl[3];
1913  QGroupBox *gb;
1914  QGridLayout *gl;
1915 
1916  QWidget *mainw = new QWidget( &dlg );
1917  QVBoxLayout *vbox = new QVBoxLayout(mainw);
1918  // Group: Access Permissions
1919  gb = new QGroupBox ( i18n("Access Permissions"), mainw );
1920  vbox->addWidget(gb);
1921 
1922  gl = new QGridLayout (gb);
1923  gl->addItem(new QSpacerItem(0, 10), 0, 0);
1924 
1925  QVector<QWidget*> theNotSpecials;
1926 
1927  l = new QLabel(i18n("Class"), gb );
1928  gl->addWidget(l, 1, 0);
1929  theNotSpecials.append( l );
1930 
1931  if (isDir)
1932  l = new QLabel( i18n("Show\nEntries"), gb );
1933  else
1934  l = new QLabel( i18n("Read"), gb );
1935  gl->addWidget (l, 1, 1);
1936  theNotSpecials.append( l );
1937  QString readWhatsThis;
1938  if (isDir)
1939  readWhatsThis = i18n("This flag allows viewing the content of the folder.");
1940  else
1941  readWhatsThis = i18n("The Read flag allows viewing the content of the file.");
1942  l->setWhatsThis(readWhatsThis);
1943 
1944  if (isDir)
1945  l = new QLabel( i18n("Write\nEntries"), gb );
1946  else
1947  l = new QLabel( i18n("Write"), gb );
1948  gl->addWidget (l, 1, 2);
1949  theNotSpecials.append( l );
1950  QString writeWhatsThis;
1951  if (isDir)
1952  writeWhatsThis = i18n("This flag allows adding, renaming and deleting of files. "
1953  "Note that deleting and renaming can be limited using the Sticky flag.");
1954  else
1955  writeWhatsThis = i18n("The Write flag allows modifying the content of the file.");
1956  l->setWhatsThis(writeWhatsThis);
1957 
1958  QString execWhatsThis;
1959  if (isDir) {
1960  l = new QLabel( i18nc("Enter folder", "Enter"), gb );
1961  execWhatsThis = i18n("Enable this flag to allow entering the folder.");
1962  }
1963  else {
1964  l = new QLabel( i18n("Exec"), gb );
1965  execWhatsThis = i18n("Enable this flag to allow executing the file as a program.");
1966  }
1967  l->setWhatsThis(execWhatsThis);
1968  theNotSpecials.append( l );
1969  // GJ: Add space between normal and special modes
1970  QSize size = l->sizeHint();
1971  size.setWidth(size.width() + 15);
1972  l->setFixedSize(size);
1973  gl->addWidget (l, 1, 3);
1974 
1975  l = new QLabel( i18n("Special"), gb );
1976  gl->addWidget(l, 1, 4, 1, 2);
1977  QString specialWhatsThis;
1978  if (isDir)
1979  specialWhatsThis = i18n("Special flag. Valid for the whole folder, the exact "
1980  "meaning of the flag can be seen in the right hand column.");
1981  else
1982  specialWhatsThis = i18n("Special flag. The exact meaning of the flag can be seen "
1983  "in the right hand column.");
1984  l->setWhatsThis(specialWhatsThis);
1985 
1986  cl[0] = new QLabel( i18n("User"), gb );
1987  gl->addWidget (cl[0], 2, 0);
1988  theNotSpecials.append( cl[0] );
1989 
1990  cl[1] = new QLabel( i18n("Group"), gb );
1991  gl->addWidget (cl[1], 3, 0);
1992  theNotSpecials.append( cl[1] );
1993 
1994  cl[2] = new QLabel( i18n("Others"), gb );
1995  gl->addWidget (cl[2], 4, 0);
1996  theNotSpecials.append( cl[2] );
1997 
1998  l = new QLabel(i18n("Set UID"), gb);
1999  gl->addWidget(l, 2, 5);
2000  QString setUidWhatsThis;
2001  if (isDir)
2002  setUidWhatsThis = i18n("If this flag is set, the owner of this folder will be "
2003  "the owner of all new files.");
2004  else
2005  setUidWhatsThis = i18n("If this file is an executable and the flag is set, it will "
2006  "be executed with the permissions of the owner.");
2007  l->setWhatsThis(setUidWhatsThis);
2008 
2009  l = new QLabel(i18n("Set GID"), gb);
2010  gl->addWidget(l, 3, 5);
2011  QString setGidWhatsThis;
2012  if (isDir)
2013  setGidWhatsThis = i18n("If this flag is set, the group of this folder will be "
2014  "set for all new files.");
2015  else
2016  setGidWhatsThis = i18n("If this file is an executable and the flag is set, it will "
2017  "be executed with the permissions of the group.");
2018  l->setWhatsThis(setGidWhatsThis);
2019 
2020  l = new QLabel(i18nc("File permission", "Sticky"), gb);
2021  gl->addWidget(l, 4, 5);
2022  QString stickyWhatsThis;
2023  if (isDir)
2024  stickyWhatsThis = i18n("If the Sticky flag is set on a folder, only the owner "
2025  "and root can delete or rename files. Otherwise everybody "
2026  "with write permissions can do this.");
2027  else
2028  stickyWhatsThis = i18n("The Sticky flag on a file is ignored on Linux, but may "
2029  "be used on some systems");
2030  l->setWhatsThis(stickyWhatsThis);
2031 
2032  mode_t aPermissions, aPartialPermissions;
2033  mode_t dummy1, dummy2;
2034 
2035  if (!d->isIrregular) {
2036  switch (d->pmode) {
2037  case PermissionsOnlyFiles:
2038  getPermissionMasks(aPartialPermissions,
2039  dummy1,
2040  aPermissions,
2041  dummy2);
2042  break;
2043  case PermissionsOnlyDirs:
2044  case PermissionsMixed:
2045  getPermissionMasks(dummy1,
2046  aPartialPermissions,
2047  dummy2,
2048  aPermissions);
2049  break;
2050  case PermissionsOnlyLinks:
2051  aPermissions = UniRead | UniWrite | UniExec | UniSpecial;
2052  aPartialPermissions = 0;
2053  break;
2054  }
2055  }
2056  else {
2057  aPermissions = d->permissions;
2058  aPartialPermissions = d->partialPermissions;
2059  }
2060 
2061  // Draw Checkboxes
2062  QCheckBox *cba[3][4];
2063  for (int row = 0; row < 3 ; ++row) {
2064  for (int col = 0; col < 4; ++col) {
2065  QCheckBox *cb = new QCheckBox(gb);
2066  if ( col != 3 ) theNotSpecials.append( cb );
2067  cba[row][col] = cb;
2068  cb->setChecked(aPermissions & fperm[row][col]);
2069  if ( aPartialPermissions & fperm[row][col] )
2070  {
2071  cb->setTristate();
2072  cb->setCheckState(Qt::PartiallyChecked);
2073  }
2074  else if (d->cbRecursive && d->cbRecursive->isChecked())
2075  cb->setTristate();
2076 
2077  cb->setEnabled( d->canChangePermissions );
2078  gl->addWidget (cb, row+2, col+1);
2079  switch(col) {
2080  case 0:
2081  cb->setWhatsThis(readWhatsThis);
2082  break;
2083  case 1:
2084  cb->setWhatsThis(writeWhatsThis);
2085  break;
2086  case 2:
2087  cb->setWhatsThis(execWhatsThis);
2088  break;
2089  case 3:
2090  switch(row) {
2091  case 0:
2092  cb->setWhatsThis(setUidWhatsThis);
2093  break;
2094  case 1:
2095  cb->setWhatsThis(setGidWhatsThis);
2096  break;
2097  case 2:
2098  cb->setWhatsThis(stickyWhatsThis);
2099  break;
2100  }
2101  break;
2102  }
2103  }
2104  }
2105  gl->setColumnStretch(6, 10);
2106 
2107 #ifdef HAVE_POSIX_ACL
2108  KACLEditWidget *extendedACLs = 0;
2109 
2110  // FIXME make it work with partial entries
2111  if ( properties->items().count() == 1 ) {
2112  QByteArray path = QFile::encodeName( properties->item().url().toLocalFile() );
2113  d->fileSystemSupportsACLs = fileSystemSupportsACL( path );
2114  }
2115  if ( d->fileSystemSupportsACLs ) {
2116  std::for_each( theNotSpecials.begin(), theNotSpecials.end(), std::mem_fun( &QWidget::hide ) );
2117  extendedACLs = new KACLEditWidget( mainw );
2118  vbox->addWidget(extendedACLs);
2119  if ( d->extendedACL.isValid() && d->extendedACL.isExtended() )
2120  extendedACLs->setACL( d->extendedACL );
2121  else
2122  extendedACLs->setACL( KACL( aPermissions ) );
2123 
2124  if ( d->defaultACL.isValid() )
2125  extendedACLs->setDefaultACL( d->defaultACL );
2126 
2127  if ( properties->items().first().isDir() )
2128  extendedACLs->setAllowDefaults( true );
2129  }
2130 #endif
2131  dlg.setMainWidget( mainw );
2132  if (dlg.exec() != KDialog::Accepted)
2133  return;
2134 
2135  mode_t andPermissions = mode_t(~0);
2136  mode_t orPermissions = 0;
2137  for (int row = 0; row < 3; ++row)
2138  for (int col = 0; col < 4; ++col) {
2139  switch (cba[row][col]->checkState())
2140  {
2141  case Qt::Checked:
2142  orPermissions |= fperm[row][col];
2143  //fall through
2144  case Qt::Unchecked:
2145  andPermissions &= ~fperm[row][col];
2146  break;
2147  default: // NoChange
2148  break;
2149  }
2150  }
2151 
2152  d->isIrregular = false;
2153  const KFileItemList items = properties->items();
2154  KFileItemList::const_iterator it = items.begin();
2155  const KFileItemList::const_iterator kend = items.end();
2156  for ( ; it != kend; ++it ) {
2157  if (isIrregular(((*it).permissions() & andPermissions) | orPermissions,
2158  (*it).isDir(), (*it).isLink())) {
2159  d->isIrregular = true;
2160  break;
2161  }
2162  }
2163 
2164  d->permissions = orPermissions;
2165  d->partialPermissions = andPermissions;
2166 
2167 #ifdef HAVE_POSIX_ACL
2168  // override with the acls, if present
2169  if ( extendedACLs ) {
2170  d->extendedACL = extendedACLs->getACL();
2171  d->defaultACL = extendedACLs->getDefaultACL();
2172  d->hasExtendedACL = d->extendedACL.isExtended() || d->defaultACL.isValid();
2173  d->permissions = d->extendedACL.basePermissions();
2174  d->permissions |= ( andPermissions | orPermissions ) & ( S_ISUID|S_ISGID|S_ISVTX );
2175  }
2176 #endif
2177 
2178  updateAccessControls();
2179  emit changed();
2180 }
2181 
2182 // QString KFilePermissionsPropsPlugin::tabName () const
2183 // {
2184 // return i18n ("&Permissions");
2185 // }
2186 
2187 KFilePermissionsPropsPlugin::~KFilePermissionsPropsPlugin()
2188 {
2189  delete d;
2190 }
2191 
2192 bool KFilePermissionsPropsPlugin::supports( const KFileItemList& /*_items*/ )
2193 {
2194  return true;
2195 }
2196 
2197 // sets a combo box in the Access Control frame
2198 void KFilePermissionsPropsPlugin::setComboContent(QComboBox *combo, PermissionsTarget target,
2199  mode_t permissions, mode_t partial) {
2200  combo->clear();
2201  if (d->isIrregular) //#176876
2202  return;
2203 
2204  if (d->pmode == PermissionsOnlyLinks) {
2205  combo->addItem(i18n("Link"));
2206  combo->setCurrentIndex(0);
2207  return;
2208  }
2209 
2210  mode_t tMask = permissionsMasks[target];
2211  int textIndex;
2212  for (textIndex = 0; standardPermissions[textIndex] != (mode_t)-1; textIndex++) {
2213  if ((standardPermissions[textIndex]&tMask) == (permissions&tMask&(UniRead|UniWrite)))
2214  break;
2215  }
2216  Q_ASSERT(standardPermissions[textIndex] != (mode_t)-1); // must not happen, would be irreglar
2217 
2218  for (int i = 0; permissionsTexts[(int)d->pmode][i]; i++)
2219  combo->addItem(i18n(permissionsTexts[(int)d->pmode][i]));
2220 
2221  if (partial & tMask & ~UniExec) {
2222  combo->addItem(i18n("Varying (No Change)"));
2223  combo->setCurrentIndex(3);
2224  }
2225  else {
2226  combo->setCurrentIndex(textIndex);
2227  }
2228 }
2229 
2230 // permissions are irregular if they cant be displayed in a combo box.
2231 bool KFilePermissionsPropsPlugin::isIrregular(mode_t permissions, bool isDir, bool isLink) {
2232  if (isLink) // links are always ok
2233  return false;
2234 
2235  mode_t p = permissions;
2236  if (p & (S_ISUID | S_ISGID)) // setuid/setgid -> irregular
2237  return true;
2238  if (isDir) {
2239  p &= ~S_ISVTX; // ignore sticky on dirs
2240 
2241  // check supported flag combinations
2242  mode_t p0 = p & UniOwner;
2243  if ((p0 != 0) && (p0 != (S_IRUSR | S_IXUSR)) && (p0 != UniOwner))
2244  return true;
2245  p0 = p & UniGroup;
2246  if ((p0 != 0) && (p0 != (S_IRGRP | S_IXGRP)) && (p0 != UniGroup))
2247  return true;
2248  p0 = p & UniOthers;
2249  if ((p0 != 0) && (p0 != (S_IROTH | S_IXOTH)) && (p0 != UniOthers))
2250  return true;
2251  return false;
2252  }
2253  if (p & S_ISVTX) // sticky on file -> irregular
2254  return true;
2255 
2256  // check supported flag combinations
2257  mode_t p0 = p & UniOwner;
2258  bool usrXPossible = !p0; // true if this file could be an executable
2259  if (p0 & S_IXUSR) {
2260  if ((p0 == S_IXUSR) || (p0 == (S_IWUSR | S_IXUSR)))
2261  return true;
2262  usrXPossible = true;
2263  }
2264  else if (p0 == S_IWUSR)
2265  return true;
2266 
2267  p0 = p & UniGroup;
2268  bool grpXPossible = !p0; // true if this file could be an executable
2269  if (p0 & S_IXGRP) {
2270  if ((p0 == S_IXGRP) || (p0 == (S_IWGRP | S_IXGRP)))
2271  return true;
2272  grpXPossible = true;
2273  }
2274  else if (p0 == S_IWGRP)
2275  return true;
2276  if (p0 == 0)
2277  grpXPossible = true;
2278 
2279  p0 = p & UniOthers;
2280  bool othXPossible = !p0; // true if this file could be an executable
2281  if (p0 & S_IXOTH) {
2282  if ((p0 == S_IXOTH) || (p0 == (S_IWOTH | S_IXOTH)))
2283  return true;
2284  othXPossible = true;
2285  }
2286  else if (p0 == S_IWOTH)
2287  return true;
2288 
2289  // check that there either all targets are executable-compatible, or none
2290  return (p & UniExec) && !(usrXPossible && grpXPossible && othXPossible);
2291 }
2292 
2293 // enables/disabled the widgets in the Access Control frame
2294 void KFilePermissionsPropsPlugin::enableAccessControls(bool enable) {
2295  d->ownerPermCombo->setEnabled(enable);
2296  d->groupPermCombo->setEnabled(enable);
2297  d->othersPermCombo->setEnabled(enable);
2298  if (d->extraCheckbox)
2299  d->extraCheckbox->setEnabled(enable);
2300  if ( d->cbRecursive )
2301  d->cbRecursive->setEnabled(enable);
2302 }
2303 
2304 // updates all widgets in the Access Control frame
2305 void KFilePermissionsPropsPlugin::updateAccessControls() {
2306  setComboContent(d->ownerPermCombo, PermissionsOwner,
2307  d->permissions, d->partialPermissions);
2308  setComboContent(d->groupPermCombo, PermissionsGroup,
2309  d->permissions, d->partialPermissions);
2310  setComboContent(d->othersPermCombo, PermissionsOthers,
2311  d->permissions, d->partialPermissions);
2312 
2313  switch(d->pmode) {
2314  case PermissionsOnlyLinks:
2315  enableAccessControls(false);
2316  break;
2317  case PermissionsOnlyFiles:
2318  enableAccessControls(d->canChangePermissions && !d->isIrregular && !d->hasExtendedACL);
2319  if (d->canChangePermissions)
2320  d->explanationLabel->setText(d->isIrregular || d->hasExtendedACL ?
2321  i18np("This file uses advanced permissions",
2322  "These files use advanced permissions.",
2323  properties->items().count()) : "");
2324  if (d->partialPermissions & UniExec) {
2325  d->extraCheckbox->setTristate();
2326  d->extraCheckbox->setCheckState(Qt::PartiallyChecked);
2327  }
2328  else {
2329  d->extraCheckbox->setTristate(false);
2330  d->extraCheckbox->setChecked(d->permissions & UniExec);
2331  }
2332  break;
2333  case PermissionsOnlyDirs:
2334  enableAccessControls(d->canChangePermissions && !d->isIrregular && !d->hasExtendedACL);
2335  // if this is a dir, and we can change permissions, don't dis-allow
2336  // recursive, we can do that for ACL setting.
2337  if ( d->cbRecursive )
2338  d->cbRecursive->setEnabled( d->canChangePermissions && !d->isIrregular );
2339 
2340  if (d->canChangePermissions)
2341  d->explanationLabel->setText(d->isIrregular || d->hasExtendedACL ?
2342  i18np("This folder uses advanced permissions.",
2343  "These folders use advanced permissions.",
2344  properties->items().count()) : "");
2345  if (d->partialPermissions & S_ISVTX) {
2346  d->extraCheckbox->setTristate();
2347  d->extraCheckbox->setCheckState(Qt::PartiallyChecked);
2348  }
2349  else {
2350  d->extraCheckbox->setTristate(false);
2351  d->extraCheckbox->setChecked(d->permissions & S_ISVTX);
2352  }
2353  break;
2354  case PermissionsMixed:
2355  enableAccessControls(d->canChangePermissions && !d->isIrregular && !d->hasExtendedACL);
2356  if (d->canChangePermissions)
2357  d->explanationLabel->setText(d->isIrregular || d->hasExtendedACL ?
2358  i18n("These files use advanced permissions.") : "");
2359  break;
2360  if (d->partialPermissions & S_ISVTX) {
2361  d->extraCheckbox->setTristate();
2362  d->extraCheckbox->setCheckState(Qt::PartiallyChecked);
2363  }
2364  else {
2365  d->extraCheckbox->setTristate(false);
2366  d->extraCheckbox->setChecked(d->permissions & S_ISVTX);
2367  }
2368  break;
2369  }
2370 }
2371 
2372 // gets masks for files and dirs from the Access Control frame widgets
2373 void KFilePermissionsPropsPlugin::getPermissionMasks(mode_t &andFilePermissions,
2374  mode_t &andDirPermissions,
2375  mode_t &orFilePermissions,
2376  mode_t &orDirPermissions) {
2377  andFilePermissions = mode_t(~UniSpecial);
2378  andDirPermissions = mode_t(~(S_ISUID|S_ISGID));
2379  orFilePermissions = 0;
2380  orDirPermissions = 0;
2381  if (d->isIrregular)
2382  return;
2383 
2384  mode_t m = standardPermissions[d->ownerPermCombo->currentIndex()];
2385  if (m != (mode_t) -1) {
2386  orFilePermissions |= m & UniOwner;
2387  if ((m & UniOwner) &&
2388  ((d->pmode == PermissionsMixed) ||
2389  ((d->pmode == PermissionsOnlyFiles) && (d->extraCheckbox->checkState() == Qt::PartiallyChecked))))
2390  andFilePermissions &= ~(S_IRUSR | S_IWUSR);
2391  else {
2392  andFilePermissions &= ~(S_IRUSR | S_IWUSR | S_IXUSR);
2393  if ((m & S_IRUSR) && (d->extraCheckbox->checkState() == Qt::Checked))
2394  orFilePermissions |= S_IXUSR;
2395  }
2396 
2397  orDirPermissions |= m & UniOwner;
2398  if (m & S_IRUSR)
2399  orDirPermissions |= S_IXUSR;
2400  andDirPermissions &= ~(S_IRUSR | S_IWUSR | S_IXUSR);
2401  }
2402 
2403  m = standardPermissions[d->groupPermCombo->currentIndex()];
2404  if (m != (mode_t) -1) {
2405  orFilePermissions |= m & UniGroup;
2406  if ((m & UniGroup) &&
2407  ((d->pmode == PermissionsMixed) ||
2408  ((d->pmode == PermissionsOnlyFiles) && (d->extraCheckbox->checkState() == Qt::PartiallyChecked))))
2409  andFilePermissions &= ~(S_IRGRP | S_IWGRP);
2410  else {
2411  andFilePermissions &= ~(S_IRGRP | S_IWGRP | S_IXGRP);
2412  if ((m & S_IRGRP) && (d->extraCheckbox->checkState() == Qt::Checked))
2413  orFilePermissions |= S_IXGRP;
2414  }
2415 
2416  orDirPermissions |= m & UniGroup;
2417  if (m & S_IRGRP)
2418  orDirPermissions |= S_IXGRP;
2419  andDirPermissions &= ~(S_IRGRP | S_IWGRP | S_IXGRP);
2420  }
2421 
2422  m = d->othersPermCombo->currentIndex() >= 0 ? standardPermissions[d->othersPermCombo->currentIndex()] : (mode_t)-1;
2423  if (m != (mode_t) -1) {
2424  orFilePermissions |= m & UniOthers;
2425  if ((m & UniOthers) &&
2426  ((d->pmode == PermissionsMixed) ||
2427  ((d->pmode == PermissionsOnlyFiles) && (d->extraCheckbox->checkState() == Qt::PartiallyChecked))))
2428  andFilePermissions &= ~(S_IROTH | S_IWOTH);
2429  else {
2430  andFilePermissions &= ~(S_IROTH | S_IWOTH | S_IXOTH);
2431  if ((m & S_IROTH) && (d->extraCheckbox->checkState() == Qt::Checked))
2432  orFilePermissions |= S_IXOTH;
2433  }
2434 
2435  orDirPermissions |= m & UniOthers;
2436  if (m & S_IROTH)
2437  orDirPermissions |= S_IXOTH;
2438  andDirPermissions &= ~(S_IROTH | S_IWOTH | S_IXOTH);
2439  }
2440 
2441  if (((d->pmode == PermissionsMixed) || (d->pmode == PermissionsOnlyDirs)) &&
2442  (d->extraCheckbox->checkState() != Qt::PartiallyChecked)) {
2443  andDirPermissions &= ~S_ISVTX;
2444  if (d->extraCheckbox->checkState() == Qt::Checked)
2445  orDirPermissions |= S_ISVTX;
2446  }
2447 }
2448 
2449 void KFilePermissionsPropsPlugin::applyChanges()
2450 {
2451  mode_t orFilePermissions;
2452  mode_t orDirPermissions;
2453  mode_t andFilePermissions;
2454  mode_t andDirPermissions;
2455 
2456  if (!d->canChangePermissions)
2457  return;
2458 
2459  if (!d->isIrregular)
2460  getPermissionMasks(andFilePermissions,
2461  andDirPermissions,
2462  orFilePermissions,
2463  orDirPermissions);
2464  else {
2465  orFilePermissions = d->permissions;
2466  andFilePermissions = d->partialPermissions;
2467  orDirPermissions = d->permissions;
2468  andDirPermissions = d->partialPermissions;
2469  }
2470 
2471  QString owner, group;
2472  if (d->usrEdit)
2473  owner = d->usrEdit->text();
2474  if (d->grpEdit)
2475  group = d->grpEdit->text();
2476  else if (d->grpCombo)
2477  group = d->grpCombo->currentText();
2478 
2479  if (owner == d->strOwner)
2480  owner.clear(); // no change
2481 
2482  if (group == d->strGroup)
2483  group.clear();
2484 
2485  bool recursive = d->cbRecursive && d->cbRecursive->isChecked();
2486  bool permissionChange = false;
2487 
2488  KFileItemList files, dirs;
2489  const KFileItemList items = properties->items();
2490  KFileItemList::const_iterator it = items.begin();
2491  const KFileItemList::const_iterator kend = items.end();
2492  for ( ; it != kend; ++it ) {
2493  if ((*it).isDir()) {
2494  dirs.append(*it);
2495  if ((*it).permissions() != (((*it).permissions() & andDirPermissions) | orDirPermissions))
2496  permissionChange = true;
2497  }
2498  else if ((*it).isFile()) {
2499  files.append(*it);
2500  if ((*it).permissions() != (((*it).permissions() & andFilePermissions) | orFilePermissions))
2501  permissionChange = true;
2502  }
2503  }
2504 
2505  const bool ACLChange = ( d->extendedACL != properties->item().ACL() );
2506  const bool defaultACLChange = ( d->defaultACL != properties->item().defaultACL() );
2507 
2508  if (owner.isEmpty() && group.isEmpty() && !recursive
2509  && !permissionChange && !ACLChange && !defaultACLChange)
2510  return;
2511 
2512  KIO::Job * job;
2513  if (files.count() > 0) {
2514  job = KIO::chmod( files, orFilePermissions, ~andFilePermissions,
2515  owner, group, false );
2516  if ( ACLChange && d->fileSystemSupportsACLs )
2517  job->addMetaData( "ACL_STRING", d->extendedACL.isValid()?d->extendedACL.asString():"ACL_DELETE" );
2518  if ( defaultACLChange && d->fileSystemSupportsACLs )
2519  job->addMetaData( "DEFAULT_ACL_STRING", d->defaultACL.isValid()?d->defaultACL.asString():"ACL_DELETE" );
2520 
2521  connect( job, SIGNAL(result(KJob*)),
2522  SLOT(slotChmodResult(KJob*)) );
2523  QEventLoop eventLoop;
2524  connect(this, SIGNAL(leaveModality()),
2525  &eventLoop, SLOT(quit()));
2526  eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
2527  }
2528  if (dirs.count() > 0) {
2529  job = KIO::chmod( dirs, orDirPermissions, ~andDirPermissions,
2530  owner, group, recursive );
2531  if ( ACLChange && d->fileSystemSupportsACLs )
2532  job->addMetaData( "ACL_STRING", d->extendedACL.isValid()?d->extendedACL.asString():"ACL_DELETE" );
2533  if ( defaultACLChange && d->fileSystemSupportsACLs )
2534  job->addMetaData( "DEFAULT_ACL_STRING", d->defaultACL.isValid()?d->defaultACL.asString():"ACL_DELETE" );
2535 
2536  connect( job, SIGNAL(result(KJob*)),
2537  SLOT(slotChmodResult(KJob*)) );
2538  QEventLoop eventLoop;
2539  connect(this, SIGNAL(leaveModality()),
2540  &eventLoop, SLOT(quit()));
2541  eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
2542  }
2543 }
2544 
2545 void KFilePermissionsPropsPlugin::slotChmodResult( KJob * job )
2546 {
2547  kDebug(250) << "KFilePermissionsPropsPlugin::slotChmodResult";
2548  if (job->error())
2549  job->uiDelegate()->showErrorMessage();
2550  // allow apply() to return
2551  emit leaveModality();
2552 }
2553 
2554 
2555 
2556 
2557 class KUrlPropsPlugin::KUrlPropsPluginPrivate
2558 {
2559 public:
2560  KUrlPropsPluginPrivate()
2561  {
2562  }
2563  ~KUrlPropsPluginPrivate()
2564  {
2565  }
2566 
2567  QFrame *m_frame;
2568  KUrlRequester *URLEdit;
2569  QString URLStr;
2570 };
2571 
2572 KUrlPropsPlugin::KUrlPropsPlugin( KPropertiesDialog *_props )
2573  : KPropertiesDialogPlugin( _props ),d(new KUrlPropsPluginPrivate)
2574 {
2575  d->m_frame = new QFrame();
2576  properties->addPage(d->m_frame, i18n("U&RL"));
2577  QVBoxLayout *layout = new QVBoxLayout(d->m_frame);
2578  layout->setMargin(0);
2579 
2580  QLabel *l;
2581  l = new QLabel( d->m_frame );
2582  l->setObjectName( QLatin1String( "Label_1" ) );
2583  l->setText( i18n("URL:") );
2584  layout->addWidget(l, Qt::AlignRight);
2585 
2586  d->URLEdit = new KUrlRequester( d->m_frame );
2587  layout->addWidget(d->URLEdit);
2588 
2589  KUrl url = KIO::NetAccess::mostLocalUrl( properties->kurl(), properties );
2590  if (url.isLocalFile()) {
2591  QString path = url.toLocalFile();
2592 
2593  QFile f( path );
2594  if ( !f.open( QIODevice::ReadOnly ) ) {
2595  return;
2596  }
2597  f.close();
2598 
2599  KDesktopFile config( path );
2600  const KConfigGroup dg = config.desktopGroup();
2601  d->URLStr = dg.readPathEntry( "URL", QString() );
2602 
2603  if (!d->URLStr.isEmpty()) {
2604  d->URLEdit->setUrl( KUrl(d->URLStr) );
2605  }
2606  }
2607 
2608  connect( d->URLEdit, SIGNAL(textChanged(QString)),
2609  this, SIGNAL(changed()) );
2610 
2611  layout->addStretch (1);
2612 }
2613 
2614 KUrlPropsPlugin::~KUrlPropsPlugin()
2615 {
2616  delete d;
2617 }
2618 
2619 // QString KUrlPropsPlugin::tabName () const
2620 // {
2621 // return i18n ("U&RL");
2622 // }
2623 
2624 bool KUrlPropsPlugin::supports( const KFileItemList& _items )
2625 {
2626  if ( _items.count() != 1 )
2627  return false;
2628  const KFileItem item = _items.first();
2629  // check if desktop file
2630  if (!item.isDesktopFile())
2631  return false;
2632 
2633  // open file and check type
2634  bool isLocal;
2635  KUrl url = item.mostLocalUrl(isLocal);
2636  if (!isLocal) {
2637  return false;
2638  }
2639 
2640  KDesktopFile config(url.toLocalFile());
2641  return config.hasLinkType();
2642 }
2643 
2644 void KUrlPropsPlugin::applyChanges()
2645 {
2646  KUrl url = KIO::NetAccess::mostLocalUrl( properties->kurl(), properties );
2647  if (!url.isLocalFile()) {
2648  //FIXME: 4.2 add this: KMessageBox::sorry(0, i18n("Could not save properties. Only entries on local file systems are supported."));
2649  return;
2650  }
2651 
2652  QString path = url.toLocalFile();
2653  QFile f( path );
2654  if ( !f.open( QIODevice::ReadWrite ) ) {
2655  KMessageBox::sorry( 0, i18n("<qt>Could not save properties. You do not have "
2656  "sufficient access to write to <b>%1</b>.</qt>", path));
2657  return;
2658  }
2659  f.close();
2660 
2661  KDesktopFile config( path );
2662  KConfigGroup dg = config.desktopGroup();
2663  dg.writeEntry( "Type", QString::fromLatin1("Link"));
2664  dg.writePathEntry( "URL", d->URLEdit->url().url() );
2665  // Users can't create a Link .desktop file with a Name field,
2666  // but distributions can. Update the Name field in that case.
2667  if ( dg.hasKey("Name") )
2668  {
2669  QString nameStr = nameFromFileName(properties->kurl().fileName());
2670  dg.writeEntry( "Name", nameStr );
2671  dg.writeEntry( "Name", nameStr, KConfigBase::Persistent|KConfigBase::Localized );
2672 
2673  }
2674 }
2675 
2676 
2677 /* ----------------------------------------------------
2678  *
2679  * KDevicePropsPlugin
2680  *
2681  * -------------------------------------------------- */
2682 
2683 class KDevicePropsPlugin::KDevicePropsPluginPrivate
2684 {
2685 public:
2686  KDevicePropsPluginPrivate()
2687  {
2688  }
2689  ~KDevicePropsPluginPrivate()
2690  {
2691  }
2692 
2693  bool isMounted() const {
2694  const QString dev = device->currentText();
2695  return !dev.isEmpty() && KMountPoint::currentMountPoints().findByDevice(dev);
2696  }
2697 
2698  QFrame *m_frame;
2699  QStringList mountpointlist;
2700  QLabel *m_freeSpaceText;
2701  QLabel *m_freeSpaceLabel;
2702  QProgressBar *m_freeSpaceBar;
2703 
2704  KComboBox* device;
2705  QLabel* mountpoint;
2706  QCheckBox* readonly;
2707 
2708  QStringList m_devicelist;
2709 };
2710 
2711 KDevicePropsPlugin::KDevicePropsPlugin( KPropertiesDialog *_props ) : KPropertiesDialogPlugin( _props ),d(new KDevicePropsPluginPrivate)
2712 {
2713  d->m_frame = new QFrame();
2714  properties->addPage(d->m_frame, i18n("De&vice"));
2715 
2716  QStringList devices;
2717  const KMountPoint::List mountPoints = KMountPoint::possibleMountPoints();
2718 
2719  for(KMountPoint::List::ConstIterator it = mountPoints.begin();
2720  it != mountPoints.end(); ++it)
2721  {
2722  const KMountPoint::Ptr mp = (*it);
2723  QString mountPoint = mp->mountPoint();
2724  QString device = mp->mountedFrom();
2725  kDebug()<<"mountPoint :"<<mountPoint<<" device :"<<device<<" mp->mountType() :"<<mp->mountType();
2726 
2727  if ((mountPoint != "-") && (mountPoint != "none") && !mountPoint.isEmpty()
2728  && device != "none")
2729  {
2730  devices.append( device + QString::fromLatin1(" (")
2731  + mountPoint + QString::fromLatin1(")") );
2732  d->m_devicelist.append(device);
2733  d->mountpointlist.append(mountPoint);
2734  }
2735  }
2736 
2737  QGridLayout *layout = new QGridLayout( d->m_frame );
2738 
2739  layout->setMargin(0);
2740  layout->setColumnStretch(1, 1);
2741 
2742  QLabel* label;
2743  label = new QLabel( d->m_frame );
2744  label->setText( devices.count() == 0 ?
2745  i18n("Device (/dev/fd0):") : // old style
2746  i18n("Device:") ); // new style (combobox)
2747  layout->addWidget(label, 0, 0, Qt::AlignRight);
2748 
2749  d->device = new KComboBox( d->m_frame );
2750  d->device->setObjectName( QLatin1String( "ComboBox_device" ) );
2751  d->device->setEditable( true );
2752  d->device->addItems( devices );
2753  layout->addWidget(d->device, 0, 1);
2754  connect( d->device, SIGNAL(activated(int)),
2755  this, SLOT(slotActivated(int)) );
2756 
2757  d->readonly = new QCheckBox( d->m_frame );
2758  d->readonly->setObjectName( QLatin1String( "CheckBox_readonly" ) );
2759  d->readonly->setText( i18n("Read only") );
2760  layout->addWidget(d->readonly, 1, 1);
2761 
2762  label = new QLabel( d->m_frame );
2763  label->setText( i18n("File system:") );
2764  layout->addWidget(label, 2, 0, Qt::AlignRight);
2765 
2766  QLabel *fileSystem = new QLabel( d->m_frame );
2767  layout->addWidget(fileSystem, 2, 1);
2768 
2769  label = new QLabel( d->m_frame );
2770  label->setText( devices.count()==0 ?
2771  i18n("Mount point (/mnt/floppy):") : // old style
2772  i18n("Mount point:")); // new style (combobox)
2773  layout->addWidget(label, 3, 0, Qt::AlignRight);
2774 
2775  d->mountpoint = new QLabel( d->m_frame );
2776  d->mountpoint->setObjectName( QLatin1String( "LineEdit_mountpoint" ) );
2777 
2778  layout->addWidget(d->mountpoint, 3, 1);
2779 
2780  // show disk free
2781  d->m_freeSpaceText = new QLabel(i18n("Device usage:"), d->m_frame );
2782  layout->addWidget(d->m_freeSpaceText, 4, 0, Qt::AlignRight);
2783 
2784  d->m_freeSpaceLabel = new QLabel( d->m_frame );
2785  layout->addWidget( d->m_freeSpaceLabel, 4, 1 );
2786 
2787  d->m_freeSpaceBar = new QProgressBar( d->m_frame );
2788  d->m_freeSpaceBar->setObjectName( "freeSpaceBar" );
2789  layout->addWidget(d->m_freeSpaceBar, 5, 0, 1, 2);
2790 
2791  // we show it in the slot when we know the values
2792  d->m_freeSpaceText->hide();
2793  d->m_freeSpaceLabel->hide();
2794  d->m_freeSpaceBar->hide();
2795 
2796  KSeparator* sep = new KSeparator( Qt::Horizontal, d->m_frame);
2797  layout->addWidget(sep, 6, 0, 1, 2);
2798 
2799  layout->setRowStretch(7, 1);
2800 
2801  KUrl url = KIO::NetAccess::mostLocalUrl( _props->kurl(), _props );
2802  if (!url.isLocalFile()) {
2803  return;
2804  }
2805  QString path = url.toLocalFile();
2806 
2807  QFile f( path );
2808  if ( !f.open( QIODevice::ReadOnly ) )
2809  return;
2810  f.close();
2811 
2812  const KDesktopFile _config( path );
2813  const KConfigGroup config = _config.desktopGroup();
2814  QString deviceStr = config.readEntry( "Dev" );
2815  QString mountPointStr = config.readEntry( "MountPoint" );
2816  bool ro = config.readEntry( "ReadOnly", false );
2817 
2818  fileSystem->setText(config.readEntry("FSType"));
2819 
2820  d->device->setEditText( deviceStr );
2821  if ( !deviceStr.isEmpty() ) {
2822  // Set default options for this device (first matching entry)
2823  int index = d->m_devicelist.indexOf(deviceStr);
2824  if (index != -1)
2825  {
2826  //kDebug(250) << "found it" << index;
2827  slotActivated( index );
2828  }
2829  }
2830 
2831  if ( !mountPointStr.isEmpty() )
2832  {
2833  d->mountpoint->setText( mountPointStr );
2834  updateInfo();
2835  }
2836 
2837  d->readonly->setChecked( ro );
2838 
2839  connect( d->device, SIGNAL(activated(int)),
2840  this, SIGNAL(changed()) );
2841  connect( d->device, SIGNAL(textChanged(QString)),
2842  this, SIGNAL(changed()) );
2843  connect( d->readonly, SIGNAL(toggled(bool)),
2844  this, SIGNAL(changed()) );
2845 
2846  connect( d->device, SIGNAL(textChanged(QString)),
2847  this, SLOT(slotDeviceChanged()) );
2848 }
2849 
2850 KDevicePropsPlugin::~KDevicePropsPlugin()
2851 {
2852  delete d;
2853 }
2854 
2855 // QString KDevicePropsPlugin::tabName () const
2856 // {
2857 // return i18n ("De&vice");
2858 // }
2859 
2860 void KDevicePropsPlugin::updateInfo()
2861 {
2862  // we show it in the slot when we know the values
2863  d->m_freeSpaceText->hide();
2864  d->m_freeSpaceLabel->hide();
2865  d->m_freeSpaceBar->hide();
2866 
2867  if (!d->mountpoint->text().isEmpty() && d->isMounted()) {
2868  KDiskFreeSpaceInfo info = KDiskFreeSpaceInfo::freeSpaceInfo( d->mountpoint->text() );
2869  slotFoundMountPoint( info.mountPoint(), info.size()/1024, info.used()/1024, info.available()/1024);
2870  }
2871 }
2872 
2873 void KDevicePropsPlugin::slotActivated( int index )
2874 {
2875  // index can be more than the number of known devices, when the user types
2876  // a "custom" device.
2877  if (index < d->m_devicelist.count()) {
2878  // Update mountpoint so that it matches the device that was selected in the combo
2879  d->device->setEditText(d->m_devicelist[index]);
2880  d->mountpoint->setText(d->mountpointlist[index]);
2881  }
2882 
2883  updateInfo();
2884 }
2885 
2886 void KDevicePropsPlugin::slotDeviceChanged()
2887 {
2888  // Update mountpoint so that it matches the typed device
2889  int index = d->m_devicelist.indexOf( d->device->currentText() );
2890  if ( index != -1 )
2891  d->mountpoint->setText( d->mountpointlist[index] );
2892  else
2893  d->mountpoint->setText( QString() );
2894 
2895  updateInfo();
2896 }
2897 
2898 void KDevicePropsPlugin::slotFoundMountPoint( const QString&,
2899  quint64 kibSize,
2900  quint64 /*kibUsed*/,
2901  quint64 kibAvail )
2902 {
2903  d->m_freeSpaceText->show();
2904  d->m_freeSpaceLabel->show();
2905 
2906  const int percUsed = kibSize != 0 ? (100 - (int)(100.0 * kibAvail / kibSize)) : 100;
2907 
2908  d->m_freeSpaceLabel->setText(
2909  i18nc("Available space out of total partition size (percent used)", "%1 free of %2 (%3% used)",
2910  KIO::convertSizeFromKiB(kibAvail),
2911  KIO::convertSizeFromKiB(kibSize),
2912  percUsed ));
2913 
2914  d->m_freeSpaceBar->setRange(0, 100);
2915  d->m_freeSpaceBar->setValue(percUsed);
2916  d->m_freeSpaceBar->show();
2917 }
2918 
2919 bool KDevicePropsPlugin::supports( const KFileItemList& _items )
2920 {
2921  if ( _items.count() != 1 )
2922  return false;
2923  const KFileItem item = _items.first();
2924  // check if desktop file
2925  if (!item.isDesktopFile())
2926  return false;
2927 
2928  // open file and check type
2929  bool isLocal;
2930  KUrl url = item.mostLocalUrl(isLocal);
2931  if (!isLocal) {
2932  return false;
2933  }
2934 
2935  KDesktopFile config(url.toLocalFile());
2936  return config.hasDeviceType();
2937 }
2938 
2939 void KDevicePropsPlugin::applyChanges()
2940 {
2941  KUrl url = KIO::NetAccess::mostLocalUrl( properties->kurl(), properties );
2942  if ( !url.isLocalFile() )
2943  return;
2944  QString path = url.toLocalFile();
2945 
2946  QFile f( path );
2947  if ( !f.open( QIODevice::ReadWrite ) )
2948  {
2949  KMessageBox::sorry( 0, i18n("<qt>Could not save properties. You do not have sufficient "
2950  "access to write to <b>%1</b>.</qt>", path));
2951  return;
2952  }
2953  f.close();
2954 
2955  KDesktopFile _config( path );
2956  KConfigGroup config = _config.desktopGroup();
2957  config.writeEntry( "Type", QString::fromLatin1("FSDevice") );
2958 
2959  config.writeEntry( "Dev", d->device->currentText() );
2960  config.writeEntry( "MountPoint", d->mountpoint->text() );
2961 
2962  config.writeEntry( "ReadOnly", d->readonly->isChecked() );
2963 
2964  config.sync();
2965 }
2966 
2967 
2968 /* ----------------------------------------------------
2969  *
2970  * KDesktopPropsPlugin
2971  *
2972  * -------------------------------------------------- */
2973 
2974 class KDesktopPropsPlugin::KDesktopPropsPluginPrivate
2975 {
2976 public:
2977  KDesktopPropsPluginPrivate()
2978  : w( new Ui_KPropertiesDesktopBase )
2979  , m_frame( new QFrame() )
2980  {
2981  }
2982  ~KDesktopPropsPluginPrivate()
2983  {
2984  delete w;
2985  }
2986  Ui_KPropertiesDesktopBase* w;
2987  QWidget *m_frame;
2988 
2989  QString m_origCommandStr;
2990  QString m_terminalOptionStr;
2991  QString m_suidUserStr;
2992  QString m_dbusStartupType;
2993  QString m_dbusServiceName;
2994  QString m_origDesktopFile;
2995  bool m_terminalBool;
2996  bool m_suidBool;
2997  bool m_startupBool;
2998  bool m_systrayBool;
2999 };
3000 
3001 KDesktopPropsPlugin::KDesktopPropsPlugin( KPropertiesDialog *_props )
3002  : KPropertiesDialogPlugin( _props ), d( new KDesktopPropsPluginPrivate )
3003 {
3004  d->w->setupUi(d->m_frame);
3005 
3006  properties->addPage(d->m_frame, i18n("&Application"));
3007 
3008  bool bKDesktopMode = properties->kurl().protocol() == QLatin1String("desktop") ||
3009  properties->currentDir().protocol() == QLatin1String("desktop");
3010 
3011  if (bKDesktopMode)
3012  {
3013  // Hide Name entry
3014  d->w->nameEdit->hide();
3015  d->w->nameLabel->hide();
3016  }
3017 
3018  d->w->pathEdit->setMode(KFile::Directory | KFile::LocalOnly);
3019  d->w->pathEdit->lineEdit()->setAcceptDrops(false);
3020 
3021  connect( d->w->nameEdit, SIGNAL(textChanged(QString)), this, SIGNAL(changed()) );
3022  connect( d->w->genNameEdit, SIGNAL(textChanged(QString)), this, SIGNAL(changed()) );
3023  connect( d->w->commentEdit, SIGNAL(textChanged(QString)), this, SIGNAL(changed()) );
3024  connect( d->w->commandEdit, SIGNAL(textChanged(QString)), this, SIGNAL(changed()) );
3025  connect( d->w->pathEdit, SIGNAL(textChanged(QString)), this, SIGNAL(changed()) );
3026 
3027  connect( d->w->browseButton, SIGNAL(clicked()), this, SLOT(slotBrowseExec()) );
3028  connect( d->w->addFiletypeButton, SIGNAL(clicked()), this, SLOT(slotAddFiletype()) );
3029  connect( d->w->delFiletypeButton, SIGNAL(clicked()), this, SLOT(slotDelFiletype()) );
3030  connect( d->w->advancedButton, SIGNAL(clicked()), this, SLOT(slotAdvanced()) );
3031 
3032  // now populate the page
3033 
3034  KUrl url = KIO::NetAccess::mostLocalUrl( _props->kurl(), _props );
3035  if (!url.isLocalFile()) {
3036  return;
3037  }
3038 
3039  d->m_origDesktopFile = url.toLocalFile();
3040 
3041  QFile f( d->m_origDesktopFile );
3042  if ( !f.open( QIODevice::ReadOnly ) )
3043  return;
3044  f.close();
3045 
3046  KDesktopFile _config( d->m_origDesktopFile );
3047  KConfigGroup config = _config.desktopGroup();
3048  QString nameStr = _config.readName();
3049  QString genNameStr = _config.readGenericName();
3050  QString commentStr = _config.readComment();
3051  QString commandStr = config.readEntry( "Exec", QString() );
3052  if (commandStr.startsWith(QLatin1String("ksystraycmd ")))
3053  {
3054  commandStr.remove(0, 12);
3055  d->m_systrayBool = true;
3056  }
3057  else
3058  d->m_systrayBool = false;
3059 
3060  d->m_origCommandStr = commandStr;
3061  QString pathStr = config.readEntry( "Path", QString() ); // not readPathEntry, see kservice.cpp
3062  d->m_terminalBool = config.readEntry( "Terminal", false );
3063  d->m_terminalOptionStr = config.readEntry( "TerminalOptions" );
3064  d->m_suidBool = config.readEntry( "X-KDE-SubstituteUID", false );
3065  d->m_suidUserStr = config.readEntry( "X-KDE-Username" );
3066  if( config.hasKey( "StartupNotify" ))
3067  d->m_startupBool = config.readEntry( "StartupNotify", true );
3068  else
3069  d->m_startupBool = config.readEntry( "X-KDE-StartupNotify", true );
3070  d->m_dbusStartupType = config.readEntry("X-DBUS-StartupType").toLower();
3071  // ### should there be a GUI for this setting?
3072  // At least we're copying it over to the local file, to avoid side effects (#157853)
3073  d->m_dbusServiceName = config.readEntry("X-DBUS-ServiceName");
3074 
3075  const QStringList mimeTypes = config.readXdgListEntry( "MimeType" );
3076 
3077  if ( nameStr.isEmpty() || bKDesktopMode ) {
3078  // We'll use the file name if no name is specified
3079  // because we _need_ a Name for a valid file.
3080  // But let's do it in apply, not here, so that we pick up the right name.
3081  setDirty();
3082  }
3083  if ( !bKDesktopMode )
3084  d->w->nameEdit->setText(nameStr);
3085 
3086  d->w->genNameEdit->setText( genNameStr );
3087  d->w->commentEdit->setText( commentStr );
3088  d->w->commandEdit->setText( commandStr );
3089  d->w->pathEdit->lineEdit()->setText( pathStr );
3090 
3091  // was: d->w->filetypeList->setFullWidth(true);
3092  // d->w->filetypeList->header()->setStretchEnabled(true, d->w->filetypeList->columns()-1);
3093 
3094  KMimeType::Ptr defaultMimetype = KMimeType::defaultMimeTypePtr();
3095  for(QStringList::ConstIterator it = mimeTypes.begin();
3096  it != mimeTypes.end(); )
3097  {
3098  KMimeType::Ptr p = KMimeType::mimeType(*it, KMimeType::ResolveAliases);
3099  ++it;
3100  QString preference;
3101  if (it != mimeTypes.end())
3102  {
3103  bool numeric;
3104  (*it).toInt(&numeric);
3105  if (numeric)
3106  {
3107  preference = *it;
3108  ++it;
3109  }
3110  }
3111  if (p)
3112  {
3113  QTreeWidgetItem *item = new QTreeWidgetItem();
3114  item->setText(0, p->name());
3115  item->setText(1, p->comment());
3116  item->setText(2, preference);
3117  d->w->filetypeList->addTopLevelItem(item);
3118  }
3119  }
3120  d->w->filetypeList->resizeColumnToContents(0);
3121 
3122 }
3123 
3124 KDesktopPropsPlugin::~KDesktopPropsPlugin()
3125 {
3126  delete d;
3127 }
3128 
3129 void KDesktopPropsPlugin::slotAddFiletype()
3130 {
3131  KMimeTypeChooserDialog dlg( i18n("Add File Type for %1", properties->kurl().fileName()),
3132  i18n("Select one or more file types to add:"),
3133  QStringList(), // no preselected mimetypes
3134  QString(),
3135  QStringList(),
3136  KMimeTypeChooser::Comments|KMimeTypeChooser::Patterns,
3137  d->m_frame );
3138 
3139  if (dlg.exec() == KDialog::Accepted)
3140  {
3141  foreach(const QString &mimetype, dlg.chooser()->mimeTypes())
3142  {
3143  KMimeType::Ptr p = KMimeType::mimeType(mimetype);
3144  if (!p)
3145  continue;
3146 
3147  bool found = false;
3148  int count = d->w->filetypeList->topLevelItemCount();
3149  for (int i = 0; !found && i < count; ++i) {
3150  if (d->w->filetypeList->topLevelItem(i)->text(0) == mimetype) {
3151  found = true;
3152  }
3153  }
3154  if (!found) {
3155  QTreeWidgetItem *item = new QTreeWidgetItem();
3156  item->setText(0, p->name());
3157  item->setText(1, p->comment());
3158  d->w->filetypeList->addTopLevelItem(item);
3159  }
3160  d->w->filetypeList->resizeColumnToContents(0);
3161  }
3162  }
3163  emit changed();
3164 }
3165 
3166 void KDesktopPropsPlugin::slotDelFiletype()
3167 {
3168  QTreeWidgetItem *cur = d->w->filetypeList->currentItem();
3169  if (cur) {
3170  delete cur;
3171  emit changed();
3172  }
3173 }
3174 
3175 void KDesktopPropsPlugin::checkCommandChanged()
3176 {
3177  if (KRun::binaryName(d->w->commandEdit->text(), true) !=
3178  KRun::binaryName(d->m_origCommandStr, true))
3179  {
3180  d->m_origCommandStr = d->w->commandEdit->text();
3181  d->m_dbusStartupType.clear(); // Reset
3182  d->m_dbusServiceName.clear();
3183  }
3184 }
3185 
3186 void KDesktopPropsPlugin::applyChanges()
3187 {
3188  kDebug(250) << "KDesktopPropsPlugin::applyChanges";
3189 
3190  KUrl url = KIO::NetAccess::mostLocalUrl( properties->kurl(), properties );
3191  if (!url.isLocalFile()) {
3192  //FIXME: 4.2 add this: KMessageBox::sorry(0, i18n("Could not save properties. Only entries on local file systems are supported."));
3193  return;
3194  }
3195 
3196  const QString path (url.toLocalFile());
3197 
3198  QFile f( path );
3199  if ( !f.open( QIODevice::ReadWrite ) ) {
3200  KMessageBox::sorry( 0, i18n("<qt>Could not save properties. You do not have "
3201  "sufficient access to write to <b>%1</b>.</qt>", path));
3202  return;
3203  }
3204  f.close();
3205 
3206  // If the command is changed we reset certain settings that are strongly
3207  // coupled to the command.
3208  checkCommandChanged();
3209 
3210  KDesktopFile origConfig (d->m_origDesktopFile);
3211  QScopedPointer<KDesktopFile> _config (origConfig.copyTo(path));
3212  KConfigGroup config = _config->desktopGroup();
3213  config.writeEntry( "Type", QString::fromLatin1("Application"));
3214  config.writeEntry( "Comment", d->w->commentEdit->text() );
3215  config.writeEntry( "Comment", d->w->commentEdit->text(), KConfigGroup::Persistent|KConfigGroup::Localized ); // for compat
3216  config.writeEntry( "GenericName", d->w->genNameEdit->text() );
3217  config.writeEntry( "GenericName", d->w->genNameEdit->text(), KConfigGroup::Persistent|KConfigGroup::Localized ); // for compat
3218 
3219  if (d->m_systrayBool)
3220  config.writeEntry( "Exec", d->w->commandEdit->text().prepend("ksystraycmd ") );
3221  else
3222  config.writeEntry( "Exec", d->w->commandEdit->text() );
3223  config.writeEntry( "Path", d->w->pathEdit->lineEdit()->text() ); // not writePathEntry, see kservice.cpp
3224 
3225  // Write mimeTypes
3226  QStringList mimeTypes;
3227  int count = d->w->filetypeList->topLevelItemCount();
3228  for (int i = 0; i < count; ++i) {
3229  QTreeWidgetItem *item = d->w->filetypeList->topLevelItem(i);
3230  QString preference = item->text(2);
3231  mimeTypes.append(item->text(0));
3232  if (!preference.isEmpty())
3233  mimeTypes.append(preference);
3234  }
3235 
3236  kDebug() << mimeTypes;
3237  config.writeXdgListEntry( "MimeType", mimeTypes );
3238 
3239  if ( !d->w->nameEdit->isHidden() ) {
3240  QString nameStr = d->w->nameEdit->text();
3241  config.writeEntry( "Name", nameStr );
3242  config.writeEntry( "Name", nameStr, KConfigGroup::Persistent|KConfigGroup::Localized );
3243  }
3244 
3245  config.writeEntry("Terminal", d->m_terminalBool);
3246  config.writeEntry("TerminalOptions", d->m_terminalOptionStr);
3247  config.writeEntry("X-KDE-SubstituteUID", d->m_suidBool);
3248  config.writeEntry("X-KDE-Username", d->m_suidUserStr);
3249  config.writeEntry("StartupNotify", d->m_startupBool);
3250  config.writeEntry("X-DBUS-StartupType", d->m_dbusStartupType);
3251  config.writeEntry("X-DBUS-ServiceName", d->m_dbusServiceName);
3252  config.sync();
3253 
3254  // KSycoca update needed?
3255  QString sycocaPath = KGlobal::dirs()->relativeLocation("apps", path);
3256  bool updateNeeded = !sycocaPath.startsWith('/');
3257  if (!updateNeeded)
3258  {
3259  sycocaPath = KGlobal::dirs()->relativeLocation("xdgdata-apps", path);
3260  updateNeeded = !sycocaPath.startsWith('/');
3261  }
3262  if (updateNeeded)
3263  KBuildSycocaProgressDialog::rebuildKSycoca(d->m_frame);
3264 }
3265 
3266 
3267 void KDesktopPropsPlugin::slotBrowseExec()
3268 {
3269  KUrl f = KFileDialog::getOpenUrl( KUrl(),
3270  QString(), d->m_frame );
3271  if ( f.isEmpty() )
3272  return;
3273 
3274  if ( !f.isLocalFile()) {
3275  KMessageBox::sorry(d->m_frame, i18n("Only executables on local file systems are supported."));
3276  return;
3277  }
3278 
3279  QString path = f.toLocalFile();
3280  path = KShell::quoteArg( path );
3281  d->w->commandEdit->setText( path );
3282 }
3283 
3284 void KDesktopPropsPlugin::slotAdvanced()
3285 {
3286  KDialog dlg( d->m_frame );
3287  dlg.setObjectName( "KPropertiesDesktopAdv" );
3288  dlg.setModal( true );
3289  dlg.setCaption( i18n("Advanced Options for %1", properties->kurl().fileName()) );
3290  dlg.setButtons( KDialog::Ok | KDialog::Cancel );
3291  dlg.setDefaultButton( KDialog::Ok );
3292  Ui_KPropertiesDesktopAdvBase w;
3293  w.setupUi(dlg.mainWidget());
3294 
3295  // If the command is changed we reset certain settings that are strongly
3296  // coupled to the command.
3297  checkCommandChanged();
3298 
3299  // check to see if we use konsole if not do not add the nocloseonexit
3300  // because we don't know how to do this on other terminal applications
3301  KConfigGroup confGroup( KGlobal::config(), QString::fromLatin1("General") );
3302  QString preferredTerminal = confGroup.readPathEntry("TerminalApplication",
3303  QString::fromLatin1("konsole"));
3304 
3305  bool terminalCloseBool = false;
3306 
3307  if (preferredTerminal == "konsole")
3308  {
3309  terminalCloseBool = (d->m_terminalOptionStr.contains( "--noclose" ) > 0);
3310  w.terminalCloseCheck->setChecked(terminalCloseBool);
3311  d->m_terminalOptionStr.remove( "--noclose");
3312  }
3313  else
3314  {
3315  w.terminalCloseCheck->hide();
3316  }
3317 
3318  w.terminalCheck->setChecked(d->m_terminalBool);
3319  w.terminalEdit->setText(d->m_terminalOptionStr);
3320  w.terminalCloseCheck->setEnabled(d->m_terminalBool);
3321  w.terminalEdit->setEnabled(d->m_terminalBool);
3322  w.terminalEditLabel->setEnabled(d->m_terminalBool);
3323 
3324  w.suidCheck->setChecked(d->m_suidBool);
3325  w.suidEdit->setText(d->m_suidUserStr);
3326  w.suidEdit->setEnabled(d->m_suidBool);
3327  w.suidEditLabel->setEnabled(d->m_suidBool);
3328 
3329  w.startupInfoCheck->setChecked(d->m_startupBool);
3330  w.systrayCheck->setChecked(d->m_systrayBool);
3331 
3332  if (d->m_dbusStartupType == "unique")
3333  w.dbusCombo->setCurrentIndex(2);
3334  else if (d->m_dbusStartupType == "multi")
3335  w.dbusCombo->setCurrentIndex(1);
3336  else if (d->m_dbusStartupType == "wait")
3337  w.dbusCombo->setCurrentIndex(3);
3338  else
3339  w.dbusCombo->setCurrentIndex(0);
3340 
3341  // Provide username completion up to 1000 users.
3342  KCompletion *kcom = new KCompletion;
3343  kcom->setOrder(KCompletion::Sorted);
3344  struct passwd *pw;
3345  int i, maxEntries = 1000;
3346  setpwent();
3347  for (i=0; ((pw = getpwent()) != 0L) && (i < maxEntries); i++)
3348  kcom->addItem(QString::fromLatin1(pw->pw_name));
3349  endpwent();
3350  if (i < maxEntries)
3351  {
3352  w.suidEdit->setCompletionObject(kcom, true);
3353  w.suidEdit->setAutoDeleteCompletionObject( true );
3354  w.suidEdit->setCompletionMode(KGlobalSettings::CompletionAuto);
3355  }
3356  else
3357  {
3358  delete kcom;
3359  }
3360 
3361  connect( w.terminalEdit, SIGNAL(textChanged(QString)),
3362  this, SIGNAL(changed()) );
3363  connect( w.terminalCloseCheck, SIGNAL(toggled(bool)),
3364  this, SIGNAL(changed()) );
3365  connect( w.terminalCheck, SIGNAL(toggled(bool)),
3366  this, SIGNAL(changed()) );
3367  connect( w.suidCheck, SIGNAL(toggled(bool)),
3368  this, SIGNAL(changed()) );
3369  connect( w.suidEdit, SIGNAL(textChanged(QString)),
3370  this, SIGNAL(changed()) );
3371  connect( w.startupInfoCheck, SIGNAL(toggled(bool)),
3372  this, SIGNAL(changed()) );
3373  connect( w.systrayCheck, SIGNAL(toggled(bool)),
3374  this, SIGNAL(changed()) );
3375  connect( w.dbusCombo, SIGNAL(activated(int)),
3376  this, SIGNAL(changed()) );
3377 
3378  if ( dlg.exec() == QDialog::Accepted )
3379  {
3380  d->m_terminalOptionStr = w.terminalEdit->text().trimmed();
3381  d->m_terminalBool = w.terminalCheck->isChecked();
3382  d->m_suidBool = w.suidCheck->isChecked();
3383  d->m_suidUserStr = w.suidEdit->text().trimmed();
3384  d->m_startupBool = w.startupInfoCheck->isChecked();
3385  d->m_systrayBool = w.systrayCheck->isChecked();
3386 
3387  if (w.terminalCloseCheck->isChecked())
3388  {
3389  d->m_terminalOptionStr.append(" --noclose");
3390  }
3391 
3392  switch(w.dbusCombo->currentIndex())
3393  {
3394  case 1: d->m_dbusStartupType = "multi"; break;
3395  case 2: d->m_dbusStartupType = "unique"; break;
3396  case 3: d->m_dbusStartupType = "wait"; break;
3397  default: d->m_dbusStartupType = "none"; break;
3398  }
3399  }
3400 }
3401 
3402 bool KDesktopPropsPlugin::supports( const KFileItemList& _items )
3403 {
3404  if ( _items.count() != 1 ) {
3405  return false;
3406  }
3407 
3408  const KFileItem item = _items.first();
3409 
3410  // check if desktop file
3411  if (!item.isDesktopFile()) {
3412  return false;
3413  }
3414 
3415  // open file and check type
3416  bool isLocal;
3417  KUrl url = item.mostLocalUrl( isLocal );
3418  if (!isLocal) {
3419  return false;
3420  }
3421 
3422  KDesktopFile config(url.toLocalFile());
3423  return config.hasApplicationType() &&
3424  KAuthorized::authorize("run_desktop_files") &&
3425  KAuthorized::authorize("shell_access");
3426 }
3427 
3428 #include "kpropertiesdialog.moc"
3429 #include "kpropertiesdialog_p.moc"
3430 
KDEPrivate::KDesktopPropsPlugin::~KDesktopPropsPlugin
virtual ~KDesktopPropsPlugin()
Definition: kpropertiesdialog.cpp:3124
QSpacerItem
KIO::NetAccess::stat
static bool stat(const KUrl &url, KIO::UDSEntry &entry, QWidget *window)
Tests whether a URL exists and return information on it.
Definition: netaccess.cpp:225
kdialog.h
KGlobal::caption
QString caption()
i18n
QString i18n(const char *text)
KDEPrivate::KFilePermissionsPropsPlugin::~KFilePermissionsPropsPlugin
virtual ~KFilePermissionsPropsPlugin()
Definition: kpropertiesdialog.cpp:2187
QProgressBar
KPropertiesDialog::slotCancel
virtual void slotCancel()
Called when the user presses 'Cancel'.
Definition: kpropertiesdialog.cpp:476
KConfigGroup::readPathEntry
QString readPathEntry(const QString &pKey, const QString &aDefault) const
KIO::Overwrite
When set, automatically overwrite the destination if it exists already.
Definition: jobclasses.h:67
KDEPrivate::KFilePermissionsPropsPlugin::PermissionsOthers
Definition: kpropertiesdialog_p.h:123
kcombobox.h
KSharedPtr< KService >
KBuildSycocaProgressDialog::rebuildKSycoca
static void rebuildKSycoca(QWidget *parent)
Rebuild KSycoca and show a progress dialog while doing so.
Definition: kbuildsycocaprogressdialog.cpp:41
KDEPrivate::KUrlPropsPlugin::applyChanges
virtual void applyChanges()
Applies all changes to the file.
Definition: kpropertiesdialog.cpp:2644
QWidget
QDir::toNativeSeparators
QString toNativeSeparators(const QString &pathName)
KPageDialog
KIO::filesize_t
qulonglong filesize_t
64-bit file size
Definition: global.h:57
KFileItem::isWritable
bool isWritable() const
Checks whether the file or directory is writable.
Definition: kfileitem.cpp:1099
KUrl::directory
QString directory(const DirectoryOptions &options=IgnoreTrailingSlash) const
QWidget::setupUi
void setupUi(QWidget *widget)
netaccess.h
KUrl::RemoveTrailingSlash
KVBox
KDEPrivate::KDevicePropsPlugin::applyChanges
virtual void applyChanges()
Applies all changes to the file.
Definition: kpropertiesdialog.cpp:2939
KPropertiesDialog::rename
void rename(const QString &_name)
Renames the item to the specified name.
Definition: kpropertiesdialog.cpp:572
QString::truncate
void truncate(int position)
QSize::width
int width() const
KIO::Job::addMetaData
void addMetaData(const QString &key, const QString &value)
Add key/value pair to the meta data that is sent to the slave.
Definition: job.cpp:264
QDialog::modal
modal
QEventLoop
KConfigGroup::writePathEntry
void writePathEntry(const QString &pKey, const QString &path, WriteConfigFlags pFlags=Normal)
KFileItem::isDir
bool isDir() const
Returns true if this item represents a directory.
Definition: kfileitem.cpp:1141
KDEPrivate::KFilePropsPlugin::slotEditFileType
void slotEditFileType()
Definition: kpropertiesdialog.cpp:1133
KPropertiesDialog::applied
void applied()
This signal is emitted when the properties changes are applied (for example, with the OK button) ...
KDEPrivate::KFilePropsPlugin::slotDirSizeFinished
void slotDirSizeFinished(KJob *)
Definition: kpropertiesdialog.cpp:1208
kdebug.h
KDEPrivate::KFilePropsPlugin::slotSizeStop
void slotSizeStop()
Definition: kpropertiesdialog.cpp:1264
kmimetype.h
KUrl::AddTrailingSlash
kurl.h
QVector::append
void append(const T &value)
KCompletion::Sorted
QGridLayout::addWidget
void addWidget(QWidget *widget, int row, int column, QFlags< Qt::AlignmentFlag > alignment)
KIO::DirectorySizeJob
Computes a directory size (similar to "du", but doesn't give the same results since we simply sum up ...
Definition: directorysizejob.h:35
QWidget::window
QWidget * window() const
QVector::begin
iterator begin()
QByteArray
KIconLoader::global
static KIconLoader * global()
KIO::UDSEntry
Universal Directory Service.
Definition: udsentry.h:58
group
KPropertiesDialog::items
KFileItemList items() const
Definition: kpropertiesdialog.cpp:404
kglobalsettings.h
KFileItem::mimetype
QString mimetype() const
Returns the mimetype of the file item.
Definition: kfileitem.cpp:770
KFileItem::user
QString user() const
Returns the owner of the file.
Definition: kfileitem.cpp:681
kmountpoint.h
KMountPoint::currentMountPoints
static List currentMountPoints(DetailsNeededFlags infoNeeded=BasicInfoNeeded)
kauthorized.h
KDesktopFile::readComment
QString readComment() const
KFile::Directory
Definition: kfile.h:46
kfiledialog.h
i18np
QString i18np(const char *sing, const char *plur, const A1 &a1)
timeout
int timeout
kdirnotify.h
KFileItem::isNull
bool isNull() const
Return true if default-constructed.
Definition: kfileitem.cpp:1714
KIO::mimetype
MimetypeJob * mimetype(const KUrl &url, JobFlags flags=DefaultFlags)
Find mimetype for one file or directory.
Definition: job.cpp:1856
KUrlRequester
This class is a widget showing a lineedit and a button, which invokes a filedialog.
Definition: kurlrequester.h:60
QWidget::style
QStyle * style() const
label
QString label(StandardShortcut id)
QStyle::pixelMetric
virtual int pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const =0
KIO::HideProgressInfo
Hide progress information dialog, i.e.
Definition: jobclasses.h:51
QLabel::setPixmap
void setPixmap(const QPixmap &)
kshell.h
KDEPrivate::KFilePermissionsPropsPlugin::applyChanges
virtual void applyChanges()
Applies all changes to the file.
Definition: kpropertiesdialog.cpp:2449
KIO::decodeFileName
QString decodeFileName(const QString &str)
Decodes (from the filename to the text displayed) This doesn't do anything anymore, it used to do the opposite of encodeFileName when encodeFileName was using %2F for '/'.
Definition: global.cpp:153
KCompositeJob::exec
bool exec()
QComboBox::clear
void clear()
KMountPoint::List::findByDevice
Ptr findByDevice(const QString &device) const
KGlobal::dirs
KStandardDirs * dirs()
KPropertiesDialog::abortApplying
void abortApplying()
To abort applying changes.
Definition: kpropertiesdialog.cpp:594
QStringList::contains
bool contains(const QString &str, Qt::CaseSensitivity cs) const
kbuildsycocaprogressdialog.h
directorysizejob.h
kurlrequester.h
kpreviewprops.h
QVarLengthArray
KDEPrivate::KFilePropsPlugin::setFileNameReadOnly
void setFileNameReadOnly(bool ro)
Definition: kpropertiesdialog.cpp:1120
QHBoxLayout
f
static quint32 f(DES_KEY *key, quint32 r, char *subkey)
Definition: des.cpp:378
QDialog::exec
int exec()
QLabel::setAlignment
void setAlignment(QFlags< Qt::AlignmentFlag >)
KDesktopFile::hasApplicationType
bool hasApplicationType() const
KDEPrivate::KFilePropsPlugin::postApplyChanges
void postApplyChanges()
Called after all plugins applied their changes.
Definition: kpropertiesdialog.cpp:1497
KConfigGroup::writeEntry
void writeEntry(const QString &key, const QVariant &value, WriteConfigFlags pFlags=Normal)
KMimeTypeChooser::Comments
Show the Mimetypes Comment field in a column ("HTML Document").
Definition: kmimetypechooser.h:45
kiconloader.h
KUrl::toLocalFile
QString toLocalFile(AdjustPathOption trailing=LeaveTrailingSlash) const
QDialog::done
virtual void done(int r)
QGridLayout
KPropertiesDialogPlugin::fontHeight
int fontHeight() const
Returns the font height.
Definition: kpropertiesdialog.cpp:653
KFileItem::permissions
mode_t permissions() const
Returns the permissions of the file (stat.st_mode containing only permissions).
Definition: kfileitem.cpp:1551
KIconButton::setIcon
void setIcon(const QString &icon)
Sets the button's initial icon.
Definition: kicondialog.cpp:849
KDEPrivate::KDesktopPropsPlugin::slotAdvanced
void slotAdvanced()
Definition: kpropertiesdialog.cpp:3284
KDialog
KIconButton
A pushbutton for choosing an icon.
Definition: kicondialog.h:243
KIconButton::setIconType
void setIconType(KIconLoader::Group group, KIconLoader::Context context, bool user=false)
Sets the icon group and context.
Definition: kicondialog.cpp:842
KIconButton::setIconSize
void setIconSize(int size)
Sets the size of the icon to be shown / selected.
Definition: kicondialog.cpp:817
QFile::exists
bool exists() const
KIconLoader::Place
QString::remove
QString & remove(int position, int n)
I18N_NOOP
#define I18N_NOOP(x)
KACL::isValid
bool isValid() const
Returns whether the KACL object represents a valid acl.
Definition: kacl.cpp:120
KMimeTypeChooser::Patterns
Show the Mimetypes Patterns field in a column ("*.html;*.htm").
Definition: kmimetypechooser.h:46
KIconButton::icon
QString icon
Definition: kicondialog.h:246
KPropertiesDialogPlugin::properties
KPropertiesDialog * properties
Pointer to the dialog.
Definition: kpropertiesdialog.h:393
kdesktopfile.h
kDebug
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
klocale.h
QUrl::isEmpty
bool isEmpty() const
QAbstractButton::setIcon
void setIcon(const QIcon &icon)
kjobuidelegate.h
kacleditwidget.h
KIconLoader::Desktop
KDEPrivate::KDevicePropsPlugin::supports
static bool supports(const KFileItemList &_items)
Definition: kpropertiesdialog.cpp:2919
KDEPrivate::KFilePropsPlugin::leaveModality
void leaveModality()
QFile
KDEPrivate::KFilePropsPlugin::slotCopyFinished
void slotCopyFinished(KJob *)
Definition: kpropertiesdialog.cpp:1360
KUrl
KDEPrivate::KFilePermissionsPropsPlugin::PermissionsMode
PermissionsMode
Definition: kpropertiesdialog_p.h:113
KIO::copyAs
CopyJob * copyAs(const KUrl &src, const KUrl &dest, JobFlags flags=DefaultFlags)
Copy a file or directory src into the destination dest, which is the destination name in any case...
Definition: copyjob.cpp:2172
KFileItemListProperties::supportsMoving
bool supportsMoving() const
Check if moving capability is supported.
Definition: kfileitemlistproperties.cpp:145
KIconButton::setStrictIconSize
void setStrictIconSize(bool b)
Sets a strict icon size policy for allowed icons.
Definition: kicondialog.cpp:807
i18nc
QString i18nc(const char *ctxt, const char *text)
QLayoutItem
KGlobal::config
KSharedConfigPtr config()
QString::lastIndexOf
int lastIndexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
QString::isNull
bool isNull() const
KUrl::setPath
void setPath(const QString &path)
KIO::Job::ui
JobUiDelegate * ui() const
Retrieves the UI delegate of this job.
Definition: job.cpp:90
KDEPrivate::KUrlPropsPlugin
Used to edit the files containing [Desktop Entry] URL=....
Definition: kpropertiesdialog_p.h:177
KDEPrivate::KFilePermissionsPropsPlugin::PermissionsMixed
Definition: kpropertiesdialog_p.h:117
kcapacitybar.h
QString::clear
void clear()
QComboBox::addItem
void addItem(const QString &text, const QVariant &userData)
QLabel::setBuddy
void setBuddy(QWidget *buddy)
KSeparator
KFileItem::Unknown
Definition: kfileitem.h:48
kpropertiesdialog.h
KCapacityBar::DrawTextOutline
KDEPrivate::KFilePropsPlugin::slotFileRenamed
void slotFileRenamed(KIO::Job *, const KUrl &, const KUrl &)
Definition: kpropertiesdialog.cpp:1490
KPropertiesDialog::currentDir
KUrl currentDir() const
If the dialog is being built from a template, this method returns the current directory.
Definition: kpropertiesdialog.cpp:409
kglobal.h
KPropertiesDialogPlugin::changed
void changed()
Emit this signal when the user changed anything in the plugin's tabs.
QWidget::setEnabled
void setEnabled(bool)
kdiskfreespaceinfo.h
KUrl::addPath
void addPath(const QString &txt)
KFileItem::ACL
KACL ACL() const
Returns the access control list for the file.
Definition: kfileitem.cpp:627
QBoxLayout::addWidget
void addWidget(QWidget *widget, int stretch, QFlags< Qt::AlignmentFlag > alignment)
QString::number
QString number(int n, int base)
QList::count
int count(const T &value) const
QString::fromLocal8Bit
QString fromLocal8Bit(const char *str, int size)
KPropertiesDialogPlugin::KPropertiesDialogPlugin
KPropertiesDialogPlugin(KPropertiesDialog *_props)
Constructor To insert tabs into the properties dialog, use the add methods provided by KPageDialog (t...
Definition: kpropertiesdialog.cpp:613
KIO::UDSEntry::count
int count() const
count fields
Definition: udsentry.cpp:113
KPropertiesDialogPlugin
A Plugin in the Properties dialog This is an abstract class.
Definition: kpropertiesdialog.h:347
KPropertiesDialog::propertiesClosed
void propertiesClosed()
This signal is emitted when the Properties Dialog is closed (for example, with OK or Cancel buttons) ...
QList::append
void append(const T &value)
KDEPrivate::KDesktopPropsPlugin::supports
static bool supports(const KFileItemList &_items)
Definition: kpropertiesdialog.cpp:3402
KPropertiesDialog::insertPlugin
void insertPlugin(KPropertiesDialogPlugin *plugin)
Adds a "3rd party" properties plugin to the dialog.
Definition: kpropertiesdialog.cpp:386
KJobUiDelegate::setAutoErrorHandlingEnabled
void setAutoErrorHandlingEnabled(bool enable)
QGridLayout::setRowStretch
void setRowStretch(int row, int stretch)
KDEPrivate::KFilePermissionsPropsPlugin::supports
static bool supports(const KFileItemList &_items)
Tests whether the file specified by _items needs a 'Permissions' plugin.
Definition: kpropertiesdialog.cpp:2192
KDEPrivate::KFilePermissionsPropsPlugin::leaveModality
void leaveModality()
QGroupBox
QTimer
KPropertiesDialogPlugin::applyChanges
virtual void applyChanges()
Applies all changes to the file.
Definition: kpropertiesdialog.cpp:648
QWidget::setLayoutDirection
void setLayoutDirection(Qt::LayoutDirection direction)
KDEPrivate::KDevicePropsPlugin::~KDevicePropsPlugin
virtual ~KDevicePropsPlugin()
Definition: kpropertiesdialog.cpp:2850
KPropertiesDialog::KPropertiesDialog
KPropertiesDialog(const KFileItem &item, QWidget *parent=0)
Brings up a Properties dialog, as shown above.
Definition: kpropertiesdialog.cpp:207
QEventLoop::exec
int exec(QFlags< QEventLoop::ProcessEventsFlag > flags)
KFileItem::ModificationTime
Definition: kfileitem.h:58
KIO::encodeFileName
QString encodeFileName(const QString &str)
Encodes (from the text displayed to the real filename) This translates '/' into a "unicode fraction s...
Definition: global.cpp:146
kfilesharedialog.h
KPropertiesDialog::showDialog
static bool showDialog(const KFileItem &item, QWidget *parent=0, bool modal=true)
Immediately displays a Properties dialog using constructor with the same parameters.
Definition: kpropertiesdialog.cpp:281
KDesktopFile::copyTo
KDesktopFile * copyTo(const QString &file) const
QObject
KDEPrivate::KFilePermissionsPropsPlugin::KFilePermissionsPropsPlugin
KFilePermissionsPropsPlugin(KPropertiesDialog *_props)
Constructor.
Definition: kpropertiesdialog.cpp:1574
KDEPrivate::KDevicePropsPlugin
Properties plugin for device .desktop files.
Definition: kpropertiesdialog_p.h:201
QCheckBox
KUrl::protocol
QString protocol() const
QScopedPointer
QString::toInt
int toInt(bool *ok, int base) const
QSize::setWidth
void setWidth(int width)
KMimeTypeTrader::query
KService::List query(const QString &mimeType, const QString &genericServiceType=QString::fromLatin1("Application"), const QString &constraint=QString()) const
QList::isEmpty
bool isEmpty() const
KPreviewPropsPlugin
Definition: kpreviewprops.h:31
KMessageBox::sorry
static void sorry(QWidget *parent, const QString &text, const QString &caption=QString(), Options options=Notify)
QObject::setObjectName
void setObjectName(const QString &name)
KPropertiesDialog::showFileSharingPage
void showFileSharingPage()
Shows the page that was previously set by setFileSharingPage(), or does nothing if no page was set ye...
Definition: kpropertiesdialog.cpp:353
KFileItem::localPath
QString localPath() const
Returns the local path if isLocalFile() == true or the KIO item has a UDS_LOCAL_PATH atom...
Definition: kfileitem.cpp:602
KFileItem::linkDest
QString linkDest() const
Returns the link destination if isLink() == true.
Definition: kfileitem.cpp:568
QString::isEmpty
bool isEmpty() const
KStandardDirs::relativeLocation
QString relativeLocation(const char *type, const QString &absPath)
KCompletion
KPropertiesDialogPlugin::isDesktopFile
static bool isDesktopFile(const KFileItem &_item)
Convenience method for most ::supports methods.
Definition: kpropertiesdialog.cpp:627
KGlobalSettings::CompletionAuto
KRun::runCommand
static bool runCommand(const QString &cmd, QWidget *window)
Run the given shell command and notifies KDE of the starting of the application.
Definition: krun.cpp:1057
QString::startsWith
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
UniOthers
#define UniOthers
Definition: kpropertiesdialog.cpp:1546
kmimetypetrader.h
KFileItemList
List of KFileItems, which adds a few helper methods to QList.
Definition: kfileitem.h:674
KIO::itemsSummaryString
QString itemsSummaryString(uint items, uint files, uint dirs, KIO::filesize_t size, bool showSize)
Helper for showing information about a set of files and directories.
Definition: global.cpp:119
KIcon
UniSpecial
#define UniSpecial
Definition: kpropertiesdialog.cpp:1550
kacl.h
KFileItem::mimeComment
QString mimeComment() const
Returns the user-readable string representing the type of this file, like "OpenDocument Text File"...
Definition: kfileitem.cpp:823
KPreviewPropsPlugin::supports
static bool supports(const KFileItemList &_items)
Tests whether a preview for the first item should be shown.
Definition: kpreviewprops.cpp:67
KMimeTypeTrader::self
static KMimeTypeTrader * self()
KDEPrivate::KFilePermissionsPropsPlugin::PermissionsOwner
Definition: kpropertiesdialog_p.h:121
QVBoxLayout
copyjob.h
QString::endsWith
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
kpropertiesdialog_p.h
KPropertiesDialog::item
KFileItem & item()
Definition: kpropertiesdialog.cpp:399
KConfigGroup::readXdgListEntry
QStringList readXdgListEntry(const QString &pKey, const QStringList &aDefault=QStringList()) const
KPropertiesDialog::defaultName
QString defaultName() const
If the dialog is being built from a template, this method returns the default name.
Definition: kpropertiesdialog.cpp:414
QWidget::winId
WId winId() const
UniGroup
#define UniGroup
Definition: kpropertiesdialog.cpp:1545
QObject::deleteLater
void deleteLater()
QList::first
T & first()
QLabel::setText
void setText(const QString &)
KPropertiesDialog::slotOk
virtual void slotOk()
Called when the user presses 'Ok'.
Definition: kpropertiesdialog.cpp:430
kicondialog.h
QString
KFileItem::group
QString group() const
Returns the group of the file.
Definition: kfileitem.cpp:712
KDEPrivate::KDesktopPropsPlugin::applyChanges
virtual void applyChanges()
Applies all changes to the file.
Definition: kpropertiesdialog.cpp:3186
QList< KPropertiesDialogPlugin * >
QWidget::hide
void hide()
KPropertiesDialog::canDisplay
static bool canDisplay(const KFileItemList &_items)
Determine whether there are any property pages available for the given file items.
Definition: kpropertiesdialog.cpp:419
KCompletion::setItems
virtual void setItems(const QStringList &list)
KUrl::path
QString path(AdjustPathOption trailing=LeaveTrailingSlash) const
kvbox.h
KFileItem::size
KIO::filesize_t size() const
Returns the size of the file, if known.
Definition: kfileitem.cpp:610
KPropertiesDialogPlugin::setDirty
void setDirty(bool b)
Definition: kpropertiesdialog.cpp:633
QLayout::setMargin
void setMargin(int margin)
QFile::open
virtual bool open(QFlags< QIODevice::OpenModeFlag > mode)
QWidget::setSizePolicy
void setSizePolicy(QSizePolicy)
QDialog::accept
virtual void accept()
QStringList
KSqueezedTextLabel
KDEPrivate::KFilePropsPlugin
'General' plugin This plugin displays the name of the file, its size and access times.
Definition: kpropertiesdialog_p.h:48
KPropertiesDialog::saveAs
void saveAs(const KUrl &oldUrl, KUrl &newUrl)
Emitted before changes to oldUrl are saved as newUrl.
KImageIO::mimeTypes
QStringList mimeTypes(Mode mode=Writing)
Returns a list of MIME types for all KImageIO supported formats.
Definition: kimageio.cpp:64
kservice.h
KDEPrivate::KFilePropsPlugin::slotFoundMountPoint
void slotFoundMountPoint(const QString &mp, quint64 kibSize, quint64 kibUsed, quint64 kibAvail)
Definition: kpropertiesdialog.cpp:1181
kcompletion.h
kkernel_win.h
jobuidelegate.h
KACL::isExtended
bool isExtended() const
The interface to the extended ACL.
Definition: kacl.cpp:131
QFileInfo
KPropertiesDialog
The main properties dialog class.
Definition: kpropertiesdialog.h:57
KMimeTypeChooserDialog
A Dialog to choose some mimetypes.
Definition: kmimetypechooser.h:111
QList::end
iterator end()
QString::toLower
QString toLower() const
KIO::symlink
SimpleJob * symlink(const QString &target, const KUrl &dest, JobFlags flags=DefaultFlags)
Create or move a symlink.
Definition: job.cpp:738
KShell::quoteArg
QString quoteArg(const QString &arg)
KFileItem::isDesktopFile
bool isDesktopFile() const
Checks whether the file is a readable local .desktop file, i.e.
Definition: kfileitem.cpp:1772
QCheckBox::setTristate
void setTristate(bool y)
KFileItem::isLink
bool isLink() const
Returns true if this item represents a link in the UNIX sense of a link.
Definition: kfileitem.cpp:1567
KFileItemListProperties
Provides information about the common properties of a group of KFileItem objects. ...
Definition: kfileitemlistproperties.h:49
KCapacityBar
KIO::chmod
ChmodJob * chmod(const KFileItemList &lstItems, int permissions, int mask, const QString &newOwner, const QString &newGroup, bool recursive, JobFlags flags=DefaultFlags)
Creates a job that changes permissions/ownership on several files or directories, optionally recursiv...
Definition: chmodjob.cpp:268
QSize
QWidget::setFixedSize
void setFixedSize(const QSize &s)
KDateTime
KIO::convertSizeFromKiB
QString convertSizeFromKiB(KIO::filesize_t kibSize)
Converts size from kibi-bytes (2^10) to the string representation.
Definition: global.cpp:58
KDEPrivate::KFilePermissionsPropsPlugin::PermissionsOnlyFiles
Definition: kpropertiesdialog_p.h:114
KPropertiesDialogPlugin::~KPropertiesDialogPlugin
virtual ~KPropertiesDialogPlugin()
Definition: kpropertiesdialog.cpp:621
QFrame
QFile::close
virtual void close()
ksqueezedtextlabel.h
KDesktopFile
renamedialog.h
KConfigGroup::hasKey
bool hasKey(const QString &key) const
KIO::NetAccess::mostLocalUrl
static KUrl mostLocalUrl(const KUrl &url, QWidget *window)
Tries to map a local URL for the given URL.
Definition: netaccess.cpp:234
KGlobal::locale
KLocale * locale()
kseparator.h
KPropertiesDialogPlugin::setDirty
void setDirty()
Definition: kpropertiesdialog.cpp:638
KDEPrivate::KFilePropsPlugin::applyChanges
virtual void applyChanges()
Applies all changes made.
Definition: kpropertiesdialog.cpp:1291
QAbstractButton::setChecked
void setChecked(bool)
job.h
KIO::moveAs
CopyJob * moveAs(const KUrl &src, const KUrl &dest, JobFlags flags=DefaultFlags)
Moves a file or directory src to the given destination dest.
Definition: copyjob.cpp:2196
KConfigGroup
KIconLoader::Application
KDesktopFile::readGenericName
QString readGenericName() const
QGridLayout::addLayout
void addLayout(QLayout *layout, int row, int column, QFlags< Qt::AlignmentFlag > alignment)
QLabel::setTextInteractionFlags
void setTextInteractionFlags(QFlags< Qt::TextInteractionFlag > flags)
KUrl::List
KFile::LocalOnly
Definition: kfile.h:49
krun.h
KLineEdit
KUrl::setFileName
void setFileName(const QString &_txt)
QWidget::setWhatsThis
void setWhatsThis(const QString &)
KPropertiesDialog::setFileNameReadOnly
void setFileNameReadOnly(bool ro)
Call this to make the filename lineedit readonly, to prevent the user from renaming the file...
Definition: kpropertiesdialog.cpp:366
KDEPrivate::KDevicePropsPlugin::KDevicePropsPlugin
KDevicePropsPlugin(KPropertiesDialog *_props)
Definition: kpropertiesdialog.cpp:2711
KDEPrivate::KFilePropsPlugin::supports
static bool supports(const KFileItemList &_items)
Tests whether the files specified by _items need a 'General' plugin.
Definition: kpropertiesdialog.cpp:1286
QString::mid
QString mid(int position, int n) const
QWidget::fontMetrics
QFontMetrics fontMetrics() const
QVector
KDEPrivate::KFilePropsPlugin::slotDirSizeUpdate
void slotDirSizeUpdate()
Definition: kpropertiesdialog.cpp:1195
KIconLoader::Device
KFileDialog::getOpenUrl
static KUrl getOpenUrl(const KUrl &startDir=KUrl(), const QString &filter=QString(), QWidget *parent=0, const QString &caption=QString())
Creates a modal file dialog and returns the selected URL or an empty string if none was chosen...
Definition: kfiledialog.cpp:552
KPropertiesDialog::canceled
void canceled()
This signal is emitted when the properties changes are aborted (for example, with the Cancel button) ...
KFileItem::time
KDateTime time(FileTimes which) const
Requests the modification, access or creation time, depending on which.
Definition: kfileitem.cpp:655
KGlobalSettings::CompletionNone
QTreeWidgetItem
QLatin1String
UniRead
#define UniRead
Definition: kpropertiesdialog.cpp:1547
KDEPrivate::KDesktopPropsPlugin::slotDelFiletype
void slotDelFiletype()
Definition: kpropertiesdialog.cpp:3166
KUrl::fileName
QString fileName(const DirectoryOptions &options=IgnoreTrailingSlash) const
QBoxLayout::addStretch
void addStretch(int stretch)
KDEPrivate::KDesktopPropsPlugin::slotAddFiletype
void slotAddFiletype()
Definition: kpropertiesdialog.cpp:3129
KDEPrivate::KFilePropsPlugin::slotSizeDetermine
void slotSizeDetermine()
Definition: kpropertiesdialog.cpp:1232
KFileItem::defaultACL
KACL defaultACL() const
Returns the default access control list for the directory.
Definition: kfileitem.cpp:642
KMountPoint::possibleMountPoints
static List possibleMountPoints(DetailsNeededFlags infoNeeded=BasicInfoNeeded)
QGridLayout::setColumnStretch
void setColumnStretch(int column, int stretch)
KDesktopFile::locateLocal
static QString locateLocal(const QString &path)
kstandarddirs.h
KMountPoint::List::findByPath
Ptr findByPath(const QString &path) const
quint64
KFileItem::name
QString name(bool lowerCase=false) const
Return the name of the file item (without a path).
Definition: kfileitem.cpp:1591
KDEPrivate::KFilePermissionsPropsPlugin::PermissionsOnlyDirs
Definition: kpropertiesdialog_p.h:115
QGridLayout::addItem
void addItem(QLayoutItem *item, int row, int column, int rowSpan, int columnSpan, QFlags< Qt::AlignmentFlag > alignment)
KACL
The KACL class encapsulates a POSIX Access Control List.
Definition: kacl.h:47
QString::at
const QChar at(int position) const
kmimetypechooser.h
KFileItem::CreationTime
Definition: kfileitem.h:60
QList< Ptr >::ConstIterator
typedef ConstIterator
QFontMetrics::height
int height() const
KDEPrivate::KFilePropsPlugin::~KFilePropsPlugin
virtual ~KFilePropsPlugin()
Definition: kpropertiesdialog.cpp:1281
QWidget::setCaption
void setCaption(const QString &c)
KDEPrivate::KFilePermissionsPropsPlugin
'Permissions' plugin In this plugin you can modify permissions and change the owner of a file...
Definition: kpropertiesdialog_p.h:109
QLabel::sizeHint
virtual QSize sizeHint() const
KIO::Job
The base class for all jobs.
Definition: jobclasses.h:94
KHBox::setSpacing
void setSpacing(int space)
QTreeWidgetItem::setText
void setText(int column, const QString &text)
KDEPrivate::KDesktopPropsPlugin::slotBrowseExec
void slotBrowseExec()
Definition: kpropertiesdialog.cpp:3267
KComboBox
KUrl::List::toStringList
QStringList toStringList() const
QComboBox::setCurrentIndex
void setCurrentIndex(int index)
KPropertiesDialog::setFileSharingPage
void setFileSharingPage(QWidget *page)
Sets the file sharing page.
Definition: kpropertiesdialog.cpp:361
QString::length
int length() const
UniOwner
#define UniOwner
Definition: kpropertiesdialog.cpp:1544
QVarLengthArray::data
T * data()
OrgKdeKDirNotifyInterface::emitFilesChanged
static void emitFilesChanged(const QStringList &fileList)
Definition: kdirnotify.cpp:52
QByteArray::data
char * data()
kWarning
static QDebug kWarning(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
QAbstractButton::setText
void setText(const QString &text)
KCompletion::addItem
void addItem(const QString &item)
KDEPrivate::KUrlPropsPlugin::KUrlPropsPlugin
KUrlPropsPlugin(KPropertiesDialog *_props)
Constructor.
Definition: kpropertiesdialog.cpp:2572
KAuthorized::authorize
bool authorize(const QString &genericAction)
KDEPrivate::KUrlPropsPlugin::~KUrlPropsPlugin
virtual ~KUrlPropsPlugin()
Definition: kpropertiesdialog.cpp:2614
QString::fromLatin1
QString fromLatin1(const char *str, int size)
KMountPoint::List
QPushButton
QStringList::indexOf
int indexOf(const QRegExp &rx, int from) const
KFileItem::mode
mode_t mode() const
Returns the file type (stat.st_mode containing only S_IFDIR, S_IFLNK, ...).
Definition: kfileitem.cpp:1559
showWin32FilePropertyDialog
bool showWin32FilePropertyDialog(const QString &fileName)
klineedit.h
UniExec
#define UniExec
Definition: kpropertiesdialog.cpp:1549
KPropertiesDialog::updateUrl
void updateUrl(const KUrl &_newUrl)
Updates the item URL (either called by rename or because a global apps/mimelnk desktop file is being ...
Definition: kpropertiesdialog.cpp:548
KDEPrivate::KDesktopPropsPlugin
Used to edit the files containing [Desktop Entry] Type=Application.
Definition: kpropertiesdialog_p.h:234
kfileitemlistproperties.h
KUrl::url
QString url(AdjustPathOption trailing=LeaveTrailingSlash) const
QWidget::show
void show()
QLineEdit
UniWrite
#define UniWrite
Definition: kpropertiesdialog.cpp:1548
quit
KAction * quit(const QObject *recvr, const char *slot, QObject *parent)
KIO::directorySize
DirectorySizeJob * directorySize(const KUrl &directory)
Computes a directory size (by doing a recursive listing).
Definition: directorysizejob.cpp:202
KConfigGroup::sync
void sync()
KDEPrivate::KUrlPropsPlugin::supports
static bool supports(const KFileItemList &_items)
Definition: kpropertiesdialog.cpp:2624
KFileItem::entry
KIO::UDSEntry entry() const
Returns the UDS entry.
Definition: kfileitem.cpp:1672
KUrl::isLocalFile
bool isLocalFile() const
KDEPrivate::KFilePermissionsPropsPlugin::PermissionsOnlyLinks
Definition: kpropertiesdialog_p.h:116
kmessagebox.h
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
KPropertiesDialog::kurl
KUrl kurl() const
The URL of the file that has its properties being displayed.
Definition: kpropertiesdialog.cpp:394
KIO::convertSize
QString convertSize(KIO::filesize_t size)
Converts size from bytes to the string representation.
Definition: global.cpp:53
QLabel
QObject::parent
QObject * parent() const
KPropertiesDialog::~KPropertiesDialog
virtual ~KPropertiesDialog()
Cleans up the properties dialog and frees any associated resources, including the dialog itself...
Definition: kpropertiesdialog.cpp:377
QString::arg
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
KService::createInstance
T * createInstance(QObject *parent=0, const QVariantList &args=QVariantList(), QString *error=0) const
QVector::end
iterator end()
QVarLengthArray::resize
void resize(int size)
KConfigGroup::readEntry
T readEntry(const QString &key, const T &aDefault) const
QTreeWidgetItem::text
QString text(int column) const
KJob
KRun::binaryName
static QString binaryName(const QString &execLine, bool removePath)
Given a full command line (e.g.
Definition: krun.cpp:568
QBoxLayout
KDesktopFile::desktopGroup
KConfigGroup desktopGroup() const
QList::begin
iterator begin()
KDesktopFile::readName
QString readName() const
KUrl::prettyUrl
QString prettyUrl(AdjustPathOption trailing=LeaveTrailingSlash) const
KCompletion::setOrder
virtual void setOrder(CompOrder order)
KAuthorized::authorizeKAction
bool authorizeKAction(const QString &action)
KFileItemList::urlList
KUrl::List urlList() const
Definition: kfileitem.cpp:1751
chmodjob.h
KDEPrivate::KDesktopPropsPlugin::KDesktopPropsPlugin
KDesktopPropsPlugin(KPropertiesDialog *_props)
Constructor.
Definition: kpropertiesdialog.cpp:3001
KFileItem::url
KUrl url() const
Returns the url of the file.
Definition: kfileitem.cpp:1543
QFile::encodeName
QByteArray encodeName(const QString &fileName)
KDEPrivate::KFilePermissionsPropsPlugin::PermissionsGroup
Definition: kpropertiesdialog_p.h:122
nameFromFileName
static QString nameFromFileName(QString nameStr)
Definition: kpropertiesdialog.cpp:146
KFileItem::mostLocalUrl
KUrl mostLocalUrl(bool &local) const
Tries to give a local URL for this file item if possible.
Definition: kfileitem.cpp:1470
KFileItem
A KFileItem is a generic class to handle a file, local or remote.
Definition: kfileitem.h:45
kconfiggroup.h
QCheckBox::setCheckState
void setCheckState(Qt::CheckState state)
QBoxLayout::addLayout
void addLayout(QLayout *layout, int stretch)
KFileItem::AccessTime
Definition: kfileitem.h:59
KDateTime::isNull
bool isNull() const
KPropertiesDialogPlugin::isDirty
bool isDirty() const
Definition: kpropertiesdialog.cpp:643
QComboBox
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:24:53 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KIO

Skip menu "KIO"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal