// // // "Desktop Options" Tab for KDesktop configuration // // (c) Martin R. Jones 1996 // (c) Bernd Wuebben 1998 // // Layouts // (c) Christian Tibirna 1998 // Port to KControl, split from Misc Tab, Port to KControl2 // (c) David Faure 1998 // Desktop menus, paths // (c) David Faure 2000 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // include default values directly from libkonq #include #include "rootopts.h" //----------------------------------------------------------------------------- DesktopPathConfig::DesktopPathConfig(TQWidget *parent, const char * ) : TDECModule( parent, "kcmkonq" ) { TQLabel * tmpLabel; #undef RO_LASTROW #undef RO_LASTCOL #define RO_LASTROW 10 // 9 paths + last row #define RO_LASTCOL 2 int row = 0; TQGridLayout *lay = new TQGridLayout(this, RO_LASTROW+1, RO_LASTCOL+1, 0, KDialog::spacingHint()); lay->setRowStretch(RO_LASTROW,10); // last line grows lay->setColStretch(0,0); lay->setColStretch(1,0); lay->setColStretch(2,10); setQuickHelp( i18n("

Paths

\n" "This module allows you to choose where in the filesystem the " "files on your desktop should be stored.\n" "Use the \"What's This?\" (Shift+F1) to get help on specific options.")); // Desktop Paths row++; tmpLabel = new TQLabel(i18n("Des&ktop path:"), this); lay->addWidget(tmpLabel, row, 0); urDesktop = new KURLRequester(this); urDesktop->setMode( KFile::Directory ); tmpLabel->setBuddy( urDesktop ); lay->addMultiCellWidget(urDesktop, row, row, 1, RO_LASTCOL); connect(urDesktop, TQ_SIGNAL(textChanged(const TQString &)), this, TQ_SLOT(changed())); TQString wtstr = i18n("This folder contains all the files" " which you see on your desktop. You can change the location of this" " folder if you want to, and the contents will move automatically" " to the new location as well."); TQWhatsThis::add( tmpLabel, wtstr ); TQWhatsThis::add( urDesktop, wtstr ); row++; tmpLabel = new TQLabel(i18n("A&utostart path:"), this); lay->addWidget(tmpLabel, row, 0); urAutostart = new KURLRequester(this); urAutostart->setMode( KFile::Directory ); tmpLabel->setBuddy( urAutostart ); lay->addMultiCellWidget(urAutostart, row, row, 1, RO_LASTCOL); connect(urAutostart, TQ_SIGNAL(textChanged(const TQString &)), this, TQ_SLOT(changed())); wtstr = i18n("This folder contains applications or" " links to applications (shortcuts) that you want to have started" " automatically whenever TDE starts. You can change the location of this" " folder if you want to, and the contents will move automatically" " to the new location as well."); TQWhatsThis::add( tmpLabel, wtstr ); TQWhatsThis::add( urAutostart, wtstr ); row++; tmpLabel = new TQLabel(i18n("D&ocuments path:"), this); lay->addWidget(tmpLabel, row, 0); urDocument = new KURLRequester(this); urDocument->setMode( KFile::Directory ); tmpLabel->setBuddy( urDocument ); lay->addMultiCellWidget(urDocument, row, row, 1, RO_LASTCOL); connect(urDocument, TQ_SIGNAL(textChanged(const TQString &)), this, TQ_SLOT(changed())); wtstr = i18n("This folder will be used by default to load or save documents from or to."); TQWhatsThis::add( tmpLabel, wtstr ); TQWhatsThis::add( urDocument, wtstr ); row++; tmpLabel = new TQLabel(i18n("Download path:"), this); lay->addWidget(tmpLabel, row, 0); urDownload = new KURLRequester(this); urDownload->setMode( KFile::Directory ); tmpLabel->setBuddy( urDownload ); lay->addMultiCellWidget(urDownload, row, row, 1, RO_LASTCOL); connect(urDownload, TQ_SIGNAL(textChanged(const TQString &)), this, TQ_SLOT(changed())); wtstr = i18n("This folder will be used by default to load or save downloads from or to."); TQWhatsThis::add( tmpLabel, wtstr ); TQWhatsThis::add( urDownload, wtstr ); row++; tmpLabel = new TQLabel(i18n("Music path:"), this); lay->addWidget(tmpLabel, row, 0); urMusic = new KURLRequester(this); urMusic->setMode( KFile::Directory ); tmpLabel->setBuddy( urMusic ); lay->addMultiCellWidget(urMusic, row, row, 1, RO_LASTCOL); connect(urMusic, TQ_SIGNAL(textChanged(const TQString &)), this, TQ_SLOT(changed())); wtstr = i18n("This folder will be used by default to load or save music from or to."); TQWhatsThis::add( tmpLabel, wtstr ); TQWhatsThis::add( urMusic, wtstr ); row++; tmpLabel = new TQLabel(i18n("Pictures path:"), this); lay->addWidget(tmpLabel, row, 0); urPictures = new KURLRequester(this); urPictures->setMode( KFile::Directory ); tmpLabel->setBuddy( urPictures ); lay->addMultiCellWidget(urPictures, row, row, 1, RO_LASTCOL); connect(urPictures, TQ_SIGNAL(textChanged(const TQString &)), this, TQ_SLOT(changed())); wtstr = i18n("This folder will be used by default to load or save pictures from or to."); TQWhatsThis::add( tmpLabel, wtstr ); TQWhatsThis::add( urPictures, wtstr ); row++; tmpLabel = new TQLabel(i18n("Public Share path:"), this); lay->addWidget(tmpLabel, row, 0); urPublicShare = new KURLRequester(this); urPublicShare->setMode( KFile::Directory ); tmpLabel->setBuddy( urPublicShare ); lay->addMultiCellWidget(urPublicShare, row, row, 1, RO_LASTCOL); connect(urPublicShare, TQ_SIGNAL(textChanged(const TQString &)), this, TQ_SLOT(changed())); wtstr = i18n("This folder will be used by default to load or save public shared files from or to."); TQWhatsThis::add( tmpLabel, wtstr ); TQWhatsThis::add( urPublicShare, wtstr ); row++; tmpLabel = new TQLabel(i18n("Templates path:"), this); lay->addWidget(tmpLabel, row, 0); urTemplates = new KURLRequester(this); urTemplates->setMode( KFile::Directory ); tmpLabel->setBuddy( urTemplates ); lay->addMultiCellWidget(urTemplates, row, row, 1, RO_LASTCOL); connect(urTemplates, TQ_SIGNAL(textChanged(const TQString &)), this, TQ_SLOT(changed())); wtstr = i18n("This folder will be used by default to load or save templates from or to."); TQWhatsThis::add( tmpLabel, wtstr ); TQWhatsThis::add( urTemplates, wtstr ); row++; tmpLabel = new TQLabel(i18n("Videos path:"), this); lay->addWidget(tmpLabel, row, 0); urVideos = new KURLRequester(this); urVideos->setMode( KFile::Directory ); tmpLabel->setBuddy( urVideos ); lay->addMultiCellWidget(urVideos, row, row, 1, RO_LASTCOL); connect(urVideos, TQ_SIGNAL(textChanged(const TQString &)), this, TQ_SLOT(changed())); wtstr = i18n("This folder will be used by default to load or save videos from or to."); TQWhatsThis::add( tmpLabel, wtstr ); TQWhatsThis::add( urVideos, wtstr ); // -- Bottom -- Q_ASSERT( row == RO_LASTROW-1 ); // if it fails here, check the row++ and RO_LASTROW above loadTmr = new TQTimer(this); connect(loadTmr, TQ_SIGNAL(timeout()), this, TQ_SLOT(loadTimerDone())); load(); } void DesktopPathConfig::load() { load( false ); } void DesktopPathConfig::load( bool useDefaults ) { TDEConfig config("kdeglobals", true, false); // Desktop Paths config.setReadDefaults( useDefaults ); config.setGroup("Paths"); urAutostart->setURL( config.readPathEntry( "Autostart" , TDEGlobalSettings::autostartPath() )); TDEConfig xdguserconfig(TQDir::homeDirPath() + "/.config/user-dirs.dirs"); urDesktop->setURL(xdguserconfig.readPathEntry("XDG_DESKTOP_DIR", TDEGlobalSettings::desktopPath()).remove("\"")); urDocument->setURL(xdguserconfig.readPathEntry("XDG_DOCUMENTS_DIR", TDEGlobalSettings::documentPath()).remove("\"")); urDownload->setURL(xdguserconfig.readPathEntry("XDG_DOWNLOAD_DIR", TDEGlobalSettings::downloadPath()).remove("\"")); urMusic->setURL(xdguserconfig.readPathEntry("XDG_MUSIC_DIR", TDEGlobalSettings::musicPath()).remove("\"")); urPictures->setURL(xdguserconfig.readPathEntry("XDG_PICTURES_DIR", TDEGlobalSettings::picturesPath()).remove("\"")); urPublicShare->setURL(xdguserconfig.readPathEntry("XDG_PUBLICSHARE_DIR", TDEGlobalSettings::publicSharePath()).remove("\"")); urTemplates->setURL(xdguserconfig.readPathEntry("XDG_TEMPLATES_DIR", TDEGlobalSettings::templatesPath()).remove("\"")); urVideos->setURL(xdguserconfig.readPathEntry("XDG_VIDEOS_DIR", TDEGlobalSettings::videosPath()).remove("\"")); emit changed(useDefaults); // If any of the folder does not exists, enable the Apply button so that the folders can be created if (!TQDir(urDesktop->url()).exists() || !TQDir(urDocument->url()).exists() || !TQDir(urDownload->url()).exists() || !TQDir(urMusic->url()).exists() || !TQDir(urPictures->url()).exists() || !TQDir(urPublicShare->url()).exists() || !TQDir(urTemplates->url()).exists() || !TQDir(urVideos->url()).exists() || !TQDir(urAutostart->url()).exists()) { // Need to delay emitting the signal to give some time to the module to be added to the kcontrol GUI loadTmr->start(1000, true); } } void DesktopPathConfig::loadTimerDone() { emit changed(true); } void DesktopPathConfig::defaults() { load( true ); } void DesktopPathConfig::save() { TDEConfig *config = TDEGlobal::config(); TDEConfig *xdgconfig = new TDEConfig( TQDir::homeDirPath()+"/.config/user-dirs.dirs" ); TDEConfigGroupSaver cgs( config, "Paths" ); bool pathChanged = false; bool autostartMoved = false; KURL autostartURL; autostartURL.setPath(TDEGlobalSettings::autostartPath()); KURL newAutostartURL; newAutostartURL.setPath(urAutostart->url()); KURL desktopURL; desktopURL.setPath(TDEGlobalSettings::desktopPath()); KURL newDesktopURL; newDesktopURL.setPath(urDesktop->url()); KURL documentURL; documentURL.setPath(TDEGlobalSettings::documentPath()); KURL newDocumentURL; newDocumentURL.setPath(urDocument->url()); KURL downloadURL; downloadURL.setPath(TDEGlobalSettings::downloadPath()); KURL newDownloadURL; newDownloadURL.setPath(urDownload->url()); KURL musicURL; musicURL.setPath(TDEGlobalSettings::musicPath()); KURL newMusicURL; newMusicURL.setPath(urMusic->url()); KURL picturesURL; picturesURL.setPath(TDEGlobalSettings::picturesPath()); KURL newPicturesURL; newPicturesURL.setPath(urPictures->url()); KURL publicShareURL; publicShareURL.setPath(TDEGlobalSettings::publicSharePath()); KURL newPublicShareURL; newPublicShareURL.setPath(urPublicShare->url()); KURL templatesURL; templatesURL.setPath(TDEGlobalSettings::templatesPath()); KURL newTemplatesURL; newTemplatesURL.setPath(urTemplates->url()); KURL videosURL; videosURL.setPath(TDEGlobalSettings::videosPath()); KURL newVideosURL; newVideosURL.setPath(urVideos->url()); if (!newDesktopURL.equals(desktopURL, true)) { // Test which other paths were inside this one (as it is by default) // and for each, test where it should go. // * Inside destination -> let them be moved with the desktop (but adjust name if necessary) // * Not inside destination -> move first // !!! kdDebug() << "desktopURL=" << desktopURL.url() << endl; TQString urlDesktop = urDesktop->url(); if ( !urlDesktop.endsWith( "/" )) urlDesktop+="/"; if ( desktopURL.isParentOf( autostartURL ) ) { kdDebug() << "Autostart is on the desktop" << endl; // Either the Autostart field wasn't changed (-> need to update it) if ( newAutostartURL.equals( autostartURL, true ) ) { // Hack. It could be in a subdir inside desktop. Hmmm... Argl. urAutostart->setURL( urlDesktop + "Autostart/" ); kdDebug() << "Autostart is moved with the desktop" << endl; autostartMoved = true; } // or it has been changed (->need to move it from here) else { KURL futureAutostartURL; futureAutostartURL.setPath( urlDesktop + "Autostart/" ); if ( newAutostartURL.equals( futureAutostartURL, true ) ) autostartMoved = true; else autostartMoved = moveDir( KURL( TDEGlobalSettings::autostartPath() ), KURL( urAutostart->url() ), i18n("Autostart") ); } } if ( moveDir( KURL( TDEGlobalSettings::desktopPath() ), KURL( urlDesktop ), i18n("Desktop") ) ) { xdgconfig->writePathEntry( "XDG_DESKTOP_DIR", '"'+ urlDesktop + '"', true, false, false, false ); pathChanged = true; } } if (!xdgconfig->hasKey("XDG_DESKTOP_DIR")) { xdgconfig->writePathEntry("XDG_DESKTOP_DIR", '"'+ urDesktop->url() + '"', true, false, false, false ); } if (!newAutostartURL.equals(autostartURL, true)) { if (!autostartMoved) autostartMoved = moveDir( KURL( TDEGlobalSettings::autostartPath() ), KURL( urAutostart->url() ), i18n("Autostart") ); if (autostartMoved) { config->writePathEntry( "Autostart", urAutostart->url(), true, true, false, false ); pathChanged = true; } } if (!newDocumentURL.equals(documentURL, true) || !TQDir(urDocument->url()).exists()) { bool pathOk = true; TQString path = urDocument->url(); if (!TQDir(path).exists()) { if (!TDEStandardDirs::makeDir(path)) { KMessageBox::sorry(this, TDEIO::buildErrorString(TDEIO::ERR_COULD_NOT_MKDIR, path)); urDocument->setURL(documentURL.path()); pathOk = false; } } if (pathOk) { xdgconfig->writePathEntry( "XDG_DOCUMENTS_DIR", '"' + path + '"', true, false, false, false ); pathChanged = true; } } if (!newDownloadURL.equals(downloadURL, true) || !TQDir(urDownload->url()).exists()) { bool pathOk = true; TQString path = urDownload->url(); if (!TQDir(path).exists()) { if (!TDEStandardDirs::makeDir(path)) { KMessageBox::sorry(this, TDEIO::buildErrorString(TDEIO::ERR_COULD_NOT_MKDIR, path)); urDownload->setURL(downloadURL.path()); pathOk = false; } } if (pathOk) { xdgconfig->writePathEntry( "XDG_DOWNLOAD_DIR", '"' + path + '"', true, false, false, false ); pathChanged = true; } } if (!newMusicURL.equals(musicURL, true) || !TQDir(urMusic->url()).exists()) { bool pathOk = true; TQString path = urMusic->url(); if (!TQDir(path).exists()) { if (!TDEStandardDirs::makeDir(path)) { KMessageBox::sorry(this, TDEIO::buildErrorString(TDEIO::ERR_COULD_NOT_MKDIR, path)); urMusic->setURL(musicURL.path()); pathOk = false; } } if (pathOk) { xdgconfig->writePathEntry( "XDG_MUSIC_DIR", '"' + path + '"', true, false, false, false ); pathChanged = true; } } if (!newPicturesURL.equals(picturesURL, true) || !TQDir(urPictures->url()).exists()) { bool pathOk = true; TQString path = urPictures->url(); if (!TQDir(path).exists()) { if (!TDEStandardDirs::makeDir(path)) { KMessageBox::sorry(this, TDEIO::buildErrorString(TDEIO::ERR_COULD_NOT_MKDIR, path)); urPictures->setURL(picturesURL.path()); pathOk = false; } } if (pathOk) { xdgconfig->writePathEntry( "XDG_PICTURES_DIR", '"' + path + '"', true, false, false, false ); pathChanged = true; } } if (!newPublicShareURL.equals(publicShareURL, true) || !TQDir(urPublicShare->url()).exists()) { bool pathOk = true; TQString path = urPublicShare->url(); if (!TQDir(path).exists()) { if (!TDEStandardDirs::makeDir(path)) { KMessageBox::sorry(this, TDEIO::buildErrorString(TDEIO::ERR_COULD_NOT_MKDIR, path)); urPublicShare->setURL(publicShareURL.path()); pathOk = false; } } if (pathOk) { xdgconfig->writePathEntry( "XDG_PUBLICSHARE_DIR", '"' + path + '"', true, false, false, false ); pathChanged = true; } } if (!newTemplatesURL.equals(templatesURL, true) || !TQDir(urTemplates->url()).exists()) { bool pathOk = true; TQString path = urTemplates->url(); if (!TQDir(path).exists()) { if (!TDEStandardDirs::makeDir(path)) { KMessageBox::sorry(this, TDEIO::buildErrorString(TDEIO::ERR_COULD_NOT_MKDIR, path)); urTemplates->setURL(templatesURL.path()); pathOk = false; } } if (pathOk) { xdgconfig->writePathEntry( "XDG_TEMPLATES_DIR", '"' + path + '"', true, false, false, false ); pathChanged = true; } } if (!newVideosURL.equals(videosURL, true) || !TQDir(urVideos->url()).exists()) { bool pathOk = true; TQString path = urVideos->url(); if (!TQDir(path).exists()) { if (!TDEStandardDirs::makeDir(path)) { KMessageBox::sorry(this, TDEIO::buildErrorString(TDEIO::ERR_COULD_NOT_MKDIR, path)); urVideos->setURL(videosURL.path()); pathOk = false; } } if (pathOk) { xdgconfig->writePathEntry( "XDG_VIDEOS_DIR", '"' + path + '"', true, false, false, false ); pathChanged = true; } } config->sync(); xdgconfig->sync(); if (pathChanged) { kdDebug() << "DesktopPathConfig::save sending message SettingsChanged" << endl; KIPC::sendMessageAll(KIPC::SettingsChanged, TDEApplication::SETTINGS_PATHS); } // Tell kdesktop about the new config file if ( !kapp->dcopClient()->isAttached() ) kapp->dcopClient()->attach(); TQByteArray data; int konq_screen_number = TDEApplication::desktop()->primaryScreen(); TQCString appname; if (konq_screen_number == 0) { appname = "kdesktop"; } else { appname.sprintf("kdesktop-screen-%d", konq_screen_number); } kapp->dcopClient()->send( appname, "KDesktopIface", "configure()", data ); } bool DesktopPathConfig::moveDir( const KURL & src, const KURL & dest, const TQString & type ) { if (!src.isLocalFile() || !dest.isLocalFile()) return true; m_ok = true; // Ask for confirmation before moving the files if ( KMessageBox::questionYesNo( this, i18n("The path for '%1' has been changed;\ndo you want the files to be moved from '%2' to '%3'?"). arg(type).arg(src.path()).arg(dest.path()), i18n("Confirmation Required"),i18n("Move"),KStdGuiItem::cancel() ) == KMessageBox::Yes ) { bool destExists = TQFile::exists(dest.path()); if (destExists) { m_copyToDest = dest; m_copyFromSrc = src; TDEIO::ListJob* job = TDEIO::listDir( src ); connect( job, TQ_SIGNAL( entries( TDEIO::Job *, const TDEIO::UDSEntryList& ) ), this, TQ_SLOT( slotEntries( TDEIO::Job *, const TDEIO::UDSEntryList& ) ) ); tqApp->enter_loop(); if (m_ok) { TDEIO::del( src ); } } else { TDEIO::Job * job = TDEIO::move( src, dest ); connect( job, TQ_SIGNAL( result( TDEIO::Job * ) ), this, TQ_SLOT( slotResult( TDEIO::Job * ) ) ); // wait for job tqApp->enter_loop(); } } kdDebug() << "DesktopPathConfig::slotResult returning " << m_ok << endl; return m_ok; } void DesktopPathConfig::slotEntries( TDEIO::Job * job, const TDEIO::UDSEntryList& list) { if (job->error()) { job->showErrorDialog(this); return; } TDEIO::UDSEntryListConstIterator it = list.begin(); TDEIO::UDSEntryListConstIterator end = list.end(); for (; it != end; ++it) { KFileItem file(*it, m_copyFromSrc, true, true); if (file.url() == m_copyFromSrc || file.url().fileName() == "..") { continue; } TDEIO::Job * moveJob = TDEIO::move( file.url(), m_copyToDest ); connect( moveJob, TQ_SIGNAL( result( TDEIO::Job * ) ), this, TQ_SLOT( slotResult( TDEIO::Job * ) ) ); tqApp->enter_loop(); } tqApp->exit_loop(); } void DesktopPathConfig::slotResult( TDEIO::Job * job ) { if (job->error()) { if ( job->error() != TDEIO::ERR_DOES_NOT_EXIST ) m_ok = false; // If the source doesn't exist, no wonder we couldn't move the dir. // In that case, trust the user and set the new setting in any case. job->showErrorDialog(this); } tqApp->exit_loop(); } #include "rootopts.moc"