• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

libkonq

knewmenu.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE project
00002    Copyright (C) 1998, 1999 David Faure <faure@kde.org>
00003                  2003       Sven Leiber <s.leiber@web.de>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License version 2 as published by the Free Software Foundation.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017    Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include "knewmenu.h"
00021 #include "knewmenu_p.h"
00022 #include "konq_operations.h"
00023 
00024 #include <QDir>
00025 #include <QVBoxLayout>
00026 #include <QList>
00027 #include <kactioncollection.h>
00028 #include <kdebug.h>
00029 #include <kdesktopfile.h>
00030 #include <kdirwatch.h>
00031 #include <kicon.h>
00032 #include <kcomponentdata.h>
00033 #include <kinputdialog.h>
00034 #include <klocale.h>
00035 #include <kmessagebox.h>
00036 #include <kstandarddirs.h>
00037 #include <kprotocolinfo.h>
00038 #include <kprotocolmanager.h>
00039 #include <kmenu.h>
00040 #include <krun.h>
00041 #include <kio/copyjob.h>
00042 #include <kio/jobuidelegate.h>
00043 #include <kio/renamedialog.h>
00044 #include <kio/netaccess.h>
00045 #include <kio/fileundomanager.h>
00046 
00047 #include <kpropertiesdialog.h>
00048 #include <ktemporaryfile.h>
00049 #include <utime.h>
00050 
00051 // For KUrlDesktopFileDlg
00052 #include <QLayout>
00053 #include <klineedit.h>
00054 #include <kurlrequester.h>
00055 #include <QLabel>
00056 
00057 // Singleton, with data shared by all KNewMenu instances
00058 class KNewMenuSingleton
00059 {
00060 public:
00061     KNewMenuSingleton()
00062         : templatesList(0),
00063           templatesVersion(0),
00064           filesParsed(false),
00065           dirWatch(0)
00066     {
00067     }
00068     ~KNewMenuSingleton()
00069     {
00070         delete templatesList;
00071         delete dirWatch;
00072     }
00073 
00074     struct Entry {
00075         QString text;
00076         QString filePath; // empty for SEPARATOR
00077         QString templatePath; // same as filePath for TEMPLATE
00078         QString icon;
00079         int entryType;
00080         QString comment;
00081     };
00082     // NOTE: only filePath is known before we call parseFiles
00083 
00088     typedef QList<Entry> EntryList;
00089     EntryList * templatesList;
00090 
00096     int templatesVersion;
00097 
00102     bool filesParsed;
00103     KDirWatch * dirWatch;
00104 };
00105 
00106 K_GLOBAL_STATIC(KNewMenuSingleton, kNewMenuGlobals)
00107 
00108 class KNewMenu::KNewMenuPrivate
00109 {
00110 public:
00111     KNewMenuPrivate()
00112         : menuItemsVersion(0)
00113     {}
00114     KActionCollection * m_actionCollection;
00115     QWidget *m_parentWidget;
00116     KActionMenu *m_menuDev;
00117     QAction* m_newDirAction;
00118 
00119     int menuItemsVersion;
00120 
00125     KUrl::List popupFiles;
00126 
00130     bool m_isUrlDesktopFile;
00131     QString m_tempFileToDelete; // set when a tempfile was created for a Type=URL desktop file
00132 
00136     QActionGroup* m_newMenuGroup;
00137 };
00138 
00139 KNewMenu::KNewMenu( KActionCollection *parent, QWidget* parentWidget, const QString& name )
00140     : KActionMenu( KIcon("document-new"), i18n( "Create New" ), parentWidget )
00141 {
00142     // Don't fill the menu yet
00143     // We'll do that in slotCheckUpToDate (should be connected to aboutToShow)
00144     d = new KNewMenuPrivate;
00145     d->m_newMenuGroup = new QActionGroup(this);
00146     connect(d->m_newMenuGroup, SIGNAL(triggered(QAction*)), this, SLOT(slotActionTriggered(QAction*)));
00147     d->m_actionCollection = parent;
00148     d->m_parentWidget = parentWidget;
00149 
00150     d->m_actionCollection->addAction( name, this );
00151 
00152     makeMenus();
00153 }
00154 
00155 KNewMenu::~KNewMenu()
00156 {
00157     //kDebug(1203) << "KNewMenu::~KNewMenu " << this;
00158     delete d;
00159 }
00160 
00161 void KNewMenu::makeMenus()
00162 {
00163     d->m_menuDev = new KActionMenu( KIcon("drive-removable-media"), i18n( "Link to Device" ), this );
00164 }
00165 
00166 void KNewMenu::slotCheckUpToDate( )
00167 {
00168     KNewMenuSingleton* s = kNewMenuGlobals;
00169     //kDebug(1203) << "KNewMenu::slotCheckUpToDate() " << this
00170     //              << " : menuItemsVersion=" << d->menuItemsVersion
00171     //              << " s->templatesVersion=" << s->templatesVersion;
00172     if (d->menuItemsVersion < s->templatesVersion || s->templatesVersion == 0) {
00173         //kDebug(1203) << "KNewMenu::slotCheckUpToDate() : recreating actions";
00174         // We need to clean up the action collection
00175         // We look for our actions using the group
00176         foreach (QAction* action, d->m_newMenuGroup->actions())
00177             delete action;
00178 
00179         if (!s->templatesList) { // No templates list up to now
00180             s->templatesList = new KNewMenuSingleton::EntryList;
00181             slotFillTemplates();
00182             parseFiles();
00183         }
00184 
00185         // This might have been already done for other popupmenus,
00186         // that's the point in s->filesParsed.
00187         if ( !s->filesParsed )
00188             parseFiles();
00189 
00190         fillMenu();
00191 
00192         d->menuItemsVersion = s->templatesVersion;
00193     }
00194 }
00195 
00196 void KNewMenu::parseFiles()
00197 {
00198     KNewMenuSingleton* s = kNewMenuGlobals;
00199     //kDebug(1203) << "KNewMenu::parseFiles()";
00200     s->filesParsed = true;
00201     KNewMenuSingleton::EntryList::iterator templ = s->templatesList->begin();
00202     const KNewMenuSingleton::EntryList::iterator templ_end = s->templatesList->end();
00203     for ( ; templ != templ_end; ++templ )
00204     {
00205         QString iconname;
00206         QString filePath = (*templ).filePath;
00207         if ( !filePath.isEmpty() )
00208         {
00209             QString text;
00210             QString templatePath;
00211             // If a desktop file, then read the name from it.
00212             // Otherwise (or if no name in it?) use file name
00213             if ( KDesktopFile::isDesktopFile( filePath ) ) {
00214                 KDesktopFile desktopFile(  filePath );
00215                 const KConfigGroup config = desktopFile.desktopGroup();
00216                 text = config.readEntry("Name");
00217                 (*templ).icon = config.readEntry("Icon");
00218                 (*templ).comment = config.readEntry("Comment");
00219                 QString type = config.readEntry( "Type" );
00220                 if ( type == "Link" )
00221                 {
00222                     templatePath = config.readPathEntry("URL", QString());
00223                     if ( templatePath[0] != '/' )
00224                     {
00225                         if ( templatePath.startsWith("file:/") )
00226                             templatePath = KUrl(templatePath).path();
00227                         else
00228                         {
00229                             // A relative path, then (that's the default in the files we ship)
00230                             QString linkDir = filePath.left( filePath.lastIndexOf( '/' ) + 1 /*keep / */ );
00231                             //kDebug(1203) << "linkDir=" << linkDir;
00232                             templatePath = linkDir + templatePath;
00233                         }
00234                     }
00235                 }
00236                 if ( templatePath.isEmpty() )
00237                 {
00238                     // No dest, this is an old-style template
00239                     (*templ).entryType = TEMPLATE;
00240                     (*templ).templatePath = (*templ).filePath; // we'll copy the file
00241                 } else {
00242                     (*templ).entryType = LINKTOTEMPLATE;
00243                     (*templ).templatePath = templatePath;
00244                 }
00245 
00246             }
00247             if (text.isEmpty())
00248             {
00249                 text = KUrl(filePath).fileName();
00250                 if ( text.endsWith(".desktop") )
00251                     text.truncate( text.length() - 8 );
00252             }
00253             (*templ).text = text;
00254             /*kDebug(1203) << "Updating entry with text=" << text
00255                           << "entryType=" << (*templ).entryType
00256                           << "templatePath=" << (*templ).templatePath;*/
00257         }
00258         else {
00259             (*templ).entryType = SEPARATOR;
00260         }
00261     }
00262 }
00263 
00264 void KNewMenu::fillMenu()
00265 {
00266     //kDebug(1203) << "KNewMenu::fillMenu()";
00267     menu()->clear();
00268     d->m_menuDev->menu()->clear();
00269     d->m_newDirAction = 0;
00270 
00271     QSet<QString> seenTexts;
00272     QAction *linkURL = 0, *linkApp = 0;  // these shall be put at special positions
00273 
00274     KNewMenuSingleton* s = kNewMenuGlobals;
00275     int i = 1;
00276     KNewMenuSingleton::EntryList::const_iterator templ = s->templatesList->constBegin();
00277     const KNewMenuSingleton::EntryList::const_iterator templ_end = s->templatesList->constEnd();
00278     for ( ; templ != templ_end; ++templ, ++i)
00279     {
00280         if ( (*templ).entryType != SEPARATOR )
00281         {
00282             // There might be a .desktop for that one already, if it's a kdelnk
00283             // This assumes we read .desktop files before .kdelnk files ...
00284 
00285             // In fact, we skip any second item that has the same text as another one.
00286             // Duplicates in a menu look bad in any case.
00287 
00288             bool bSkip = seenTexts.contains((*templ).text);
00289             if ( bSkip ) {
00290                 kDebug(1203) << "KNewMenu: skipping" << (*templ).filePath;
00291             } else {
00292                 seenTexts.insert((*templ).text);
00293                 const KNewMenuSingleton::Entry entry = s->templatesList->at( i-1 );
00294 
00295                 // The best way to identify the "Create Directory", "Link to Location", "Link to Application" was the template
00296                 if ( (*templ).templatePath.endsWith( "emptydir" ) )
00297                 {
00298                     QAction * act = new QAction( this );
00299                     d->m_newDirAction = act;
00300                     act->setIcon( KIcon((*templ).icon) );
00301                     act->setText( (*templ).text );
00302                     act->setActionGroup( d->m_newMenuGroup );
00303                     menu()->addAction( act );
00304 
00305                     QAction *sep = new QAction(this);
00306                     sep->setSeparator( true );
00307                     menu()->addAction( sep );
00308                 }
00309                 else
00310                 {
00311                     QAction * act = new QAction(this);
00312                     act->setData( i );
00313                     act->setIcon( KIcon((*templ).icon) );
00314                     act->setText( (*templ).text );
00315                     act->setActionGroup( d->m_newMenuGroup );
00316 
00317                     if ( (*templ).templatePath.endsWith( "URL.desktop" ) )
00318                     {
00319                         linkURL = act;
00320                     }
00321                     else if ( (*templ).templatePath.endsWith( "Program.desktop" ) )
00322                     {
00323                         linkApp = act;
00324                     }
00325                     else if ( KDesktopFile::isDesktopFile( entry.templatePath ) )
00326                     {
00327                         KDesktopFile df( entry.templatePath );
00328                         if(df.readType() == "FSDevice")
00329                             d->m_menuDev->menu()->addAction( act );
00330                         else
00331                             menu()->addAction( act );
00332                     }
00333                     else
00334                     {
00335                         menu()->addAction( act );
00336                     }
00337                 }
00338             }
00339         } else { // Separate system from personal templates
00340             Q_ASSERT( (*templ).entryType != 0 );
00341 
00342             QAction *sep = new QAction( this );
00343             sep->setSeparator( true );
00344             menu()->addAction( sep );
00345         }
00346     }
00347 
00348     QAction *sep = new QAction( this );
00349     sep->setSeparator( true );
00350     menu()->addAction( sep );
00351     if ( linkURL ) menu()->addAction( linkURL );
00352     if ( linkApp ) menu()->addAction( linkApp );
00353     Q_ASSERT(d->m_menuDev);
00354     menu()->addAction( d->m_menuDev );
00355 
00356 }
00357 
00358 void KNewMenu::slotFillTemplates()
00359 {
00360     KNewMenuSingleton* s = kNewMenuGlobals;
00361     //kDebug(1203) << "KNewMenu::slotFillTemplates()";
00362     // Ensure any changes in the templates dir will call this
00363     if ( ! s->dirWatch ) {
00364         s->dirWatch = new KDirWatch;
00365         const QStringList dirs = d->m_actionCollection->componentData().dirs()->resourceDirs("templates");
00366         for ( QStringList::const_iterator it = dirs.constBegin() ; it != dirs.constEnd() ; ++it ) {
00367             //kDebug(1203) << "Templates resource dir:" << *it;
00368             s->dirWatch->addDir( *it );
00369         }
00370         connect ( s->dirWatch, SIGNAL( dirty( const QString & ) ),
00371                   this, SLOT ( slotFillTemplates() ) );
00372         connect ( s->dirWatch, SIGNAL( created( const QString & ) ),
00373                   this, SLOT ( slotFillTemplates() ) );
00374         connect ( s->dirWatch, SIGNAL( deleted( const QString & ) ),
00375                   this, SLOT ( slotFillTemplates() ) );
00376         // Ok, this doesn't cope with new dirs in KDEDIRS, but that's another story
00377     }
00378     ++s->templatesVersion;
00379     s->filesParsed = false;
00380 
00381     s->templatesList->clear();
00382 
00383     // Look into "templates" dirs.
00384     const QStringList files = d->m_actionCollection->componentData().dirs()->findAllResources("templates");
00385     QMap<QString, KNewMenuSingleton::Entry> slist; // used for sorting
00386     for ( QStringList::const_iterator it = files.constBegin() ; it != files.constEnd() ; ++it )
00387     {
00388         //kDebug(1203) << *it;
00389         if ( (*it)[0] != '.' )
00390         {
00391             KNewMenuSingleton::Entry e;
00392             e.filePath = *it;
00393             e.entryType = 0; // not parsed yet
00394             // put Directory etc. with special order (see fillMenu()) first in the list (a bit hacky)
00395             if ( (*it).endsWith( "Directory.desktop" ) ||
00396                  (*it).endsWith( "linkProgram.desktop" ) ||
00397                  (*it).endsWith( "linkURL.desktop" ) )
00398                 s->templatesList->prepend( e );
00399             else
00400             {
00401                 KDesktopFile config(  *it );
00402 
00403                 // tricky solution to ensure that TextFile is at the beginning
00404                 // because this filetype is the most used (according kde-core discussion)
00405                 QString key = config.desktopGroup().readEntry("Name");
00406                 if ( (*it).endsWith( "TextFile.desktop" ) )
00407                     key.prepend( '1' );
00408                 else
00409                     key.prepend( '2' );
00410 
00411                 slist.insert( key, e );
00412             }
00413         }
00414     }
00415     (*s->templatesList) += slist.values();
00416 }
00417 
00418 void KNewMenu::newDir()
00419 {
00420     if (d->popupFiles.isEmpty())
00421        return;
00422 
00423     KIO::SimpleJob* job = KonqOperations::newDir(d->m_parentWidget, d->popupFiles.first());
00424     if (job) {
00425         // We want the error handling to be done by slotResult so that subclasses can reimplement it
00426         job->ui()->setAutoErrorHandlingEnabled(false);
00427         connect( job, SIGNAL( result( KJob * ) ),
00428                  SLOT( slotResult( KJob * ) ) );
00429     }
00430 
00431 }
00432 
00433 void KNewMenu::slotActionTriggered(QAction* action)
00434 {
00435     trigger(); // for KDIconView::slotNewMenuActivated()
00436 
00437     if (action == d->m_newDirAction) {
00438         newDir();
00439         return;
00440     }
00441     const int id = action->data().toInt();
00442     Q_ASSERT(id > 0);
00443 
00444     KNewMenuSingleton* s = kNewMenuGlobals;
00445     const KNewMenuSingleton::Entry entry = s->templatesList->at( id - 1 );
00446     //kDebug(1203) << "sFile=" << sFile;
00447 
00448     if ( !QFile::exists( entry.templatePath ) ) {
00449         kWarning(1203) << entry.templatePath << "doesn't exist" ;
00450         KMessageBox::sorry( 0L, i18n("<qt>The template file <b>%1</b> does not exist.</qt>", entry.templatePath));
00451         return;
00452     }
00453 
00454     // true when a desktop file with Type=URL is being copied
00455     d->m_isUrlDesktopFile = false;
00456     KUrl linkUrl; // the url to put in the file
00457 
00458     QString name;
00459     if ( KDesktopFile::isDesktopFile( entry.templatePath ) )
00460     {
00461         KDesktopFile df( entry.templatePath );
00462         //kDebug(1203) <<  df.readType();
00463         if ( df.readType() == "Link" )
00464         {
00465             d->m_isUrlDesktopFile = true;
00466             // entry.comment contains i18n("Enter link to location (URL):"). JFYI :)
00467             KUrlDesktopFileDlg dlg( i18n("File name:"), entry.comment, d->m_parentWidget );
00468             // TODO dlg.setCaption( i18n( ... ) );
00469             if ( dlg.exec() )
00470             {
00471                 name = dlg.fileName();
00472                 linkUrl = dlg.url();
00473                 if ( name.isEmpty() || linkUrl.isEmpty() )
00474                     return;
00475                 if ( !name.endsWith( ".desktop" ) )
00476                     name += ".desktop";
00477             }
00478             else
00479                 return;
00480         }
00481         else // any other desktop file (Device, App, etc.)
00482         {
00483             KUrl::List::Iterator it = d->popupFiles.begin();
00484             for ( ; it != d->popupFiles.end(); ++it )
00485             {
00486                 //kDebug(1203) << "first arg=" << entry.templatePath;
00487                 //kDebug(1203) << "second arg=" << (*it).url();
00488                 //kDebug(1203) << "third arg=" << entry.text;
00489                 QString text = entry.text;
00490                 text.replace( "...", QString() ); // the ... is fine for the menu item but not for the default filename
00491 
00492                 KUrl defaultFile( *it );
00493                 defaultFile.addPath( KIO::encodeFileName( text ) );
00494                 if ( defaultFile.isLocalFile() && QFile::exists( defaultFile.path() ) )
00495                     text = KIO::RenameDialog::suggestName( *it, text);
00496 
00497                 KUrl templateUrl( entry.templatePath );
00498                 KPropertiesDialog dlg( templateUrl, *it, text, d->m_parentWidget );
00499                 dlg.exec();
00500             }
00501             return; // done, exit.
00502         }
00503     }
00504     else
00505     {
00506         // The template is not a desktop file
00507         // Show the small dialog for getting the destination filename
00508         bool ok;
00509         QString text = entry.text;
00510         text.replace( "...", QString() ); // the ... is fine for the menu item but not for the default filename
00511 
00512         KUrl defaultFile( *(d->popupFiles.begin()) );
00513         defaultFile.addPath( KIO::encodeFileName( text ) );
00514         if ( defaultFile.isLocalFile() && QFile::exists( defaultFile.path() ) )
00515             text = KIO::RenameDialog::suggestName( *(d->popupFiles.begin()), text);
00516 
00517         name = KInputDialog::getText( QString(), entry.comment,
00518                                       text, &ok, d->m_parentWidget );
00519         if ( !ok )
00520             return;
00521     }
00522 
00523     QString src = entry.templatePath;
00524 
00525     if (d->m_isUrlDesktopFile) {
00526         // It's a "URL" desktop file; we need to make a temp copy of it, to modify it
00527         // before copying it to the final destination [which could be a remote protocol]
00528         KTemporaryFile tmpFile;
00529         tmpFile.setAutoRemove(false); // done below
00530         if (!tmpFile.open()) {
00531             kError() << "Couldn't create temp file!";
00532             return;
00533         }
00534         // First copy the template into the temp file
00535         QFile file(src);
00536         if (!file.open(QIODevice::ReadOnly)) {
00537             kError() << "Couldn't open template" << src;
00538             return;
00539         }
00540         const QByteArray data = file.readAll();
00541         tmpFile.write(data);
00542         const QString tempFileName = tmpFile.fileName();
00543         Q_ASSERT(!tempFileName.isEmpty());
00544         tmpFile.close();
00545 
00546         KDesktopFile df(tempFileName);
00547         KConfigGroup group = df.desktopGroup();
00548         group.writeEntry("Icon", KProtocolInfo::icon(linkUrl.protocol()));
00549         group.writePathEntry("URL", linkUrl.prettyUrl());
00550         df.sync();
00551         src = tempFileName;
00552         d->m_tempFileToDelete = tempFileName;
00553     }
00554 
00555     // The template is not a desktop file [or it's a URL one]
00556     // Copy it.
00557     KUrl::List::const_iterator it = d->popupFiles.constBegin();
00558     for ( ; it != d->popupFiles.constEnd(); ++it )
00559     {
00560         KUrl dest( *it );
00561         dest.addPath( KIO::encodeFileName(name) ); // Chosen destination file name
00562 
00563         KUrl uSrc(src);
00564         //kDebug(1203) << "KNewMenu : KIO::copyAs(" << uSrc.url() << "," << dest.url() << ")";
00565         KIO::CopyJob * job = KIO::copyAs( uSrc, dest );
00566         job->setDefaultPermissions( true );
00567         job->ui()->setWindow( d->m_parentWidget );
00568         connect( job, SIGNAL( result( KJob * ) ),
00569                 SLOT( slotResult( KJob * ) ) );
00570         KUrl::List lst;
00571         lst.append(uSrc);
00572         KIO::FileUndoManager::self()->recordJob(KIO::FileUndoManager::Copy, lst, dest, job);
00573     }
00574 }
00575 
00576 void KNewMenu::slotResult( KJob * job )
00577 {
00578     if (job->error()) {
00579         static_cast<KIO::Job*>( job )->ui()->showErrorMessage();
00580     } else {
00581         // Was this a copy or a mkdir?
00582         KIO::CopyJob* copyJob = ::qobject_cast<KIO::CopyJob*>(job);
00583         if (copyJob) {
00584             const KUrl destUrl = copyJob->destUrl();
00585             const KUrl localUrl = KIO::NetAccess::mostLocalUrl(destUrl, d->m_parentWidget);
00586             if (localUrl.isLocalFile()) {
00587                 // Normal (local) file. Need to "touch" it, kio_file copied the mtime.
00588                 (void) ::utime(QFile::encodeName(localUrl.path()), 0);
00589             }
00590         }
00591     }
00592     if (!d->m_tempFileToDelete.isEmpty())
00593         QFile::remove(d->m_tempFileToDelete);
00594 }
00595 
00596 void KNewMenu::setPopupFiles(const KUrl::List& files)
00597 {
00598     d->popupFiles = files;
00599     if (files.isEmpty()) {
00600         d->m_newMenuGroup->setEnabled(false);
00601     } else {
00602         KUrl firstUrl = files.first();
00603         if (KProtocolManager::supportsWriting(firstUrl)) {
00604             d->m_newMenuGroup->setEnabled(true);
00605             if (d->m_newDirAction) {
00606                 d->m_newDirAction->setEnabled(KProtocolManager::supportsMakeDir(firstUrl)); // e.g. trash:/
00607             }
00608         } else {
00609             d->m_newMenuGroup->setEnabled(true);
00610         }
00611     }
00612 }
00613 
00615 
00616 KUrlDesktopFileDlg::KUrlDesktopFileDlg( const QString& textFileName, const QString& textUrl, QWidget *parent )
00617     : KDialog( parent )
00618 {
00619     setButtons( Ok | Cancel | User1 );
00620     setButtonGuiItem( User1, KStandardGuiItem::clear() );
00621     showButtonSeparator( true );
00622 
00623     initDialog( textFileName, QString(), textUrl, QString() );
00624 }
00625 
00626 void KUrlDesktopFileDlg::initDialog( const QString& textFileName, const QString& defaultName, const QString& textUrl, const QString& defaultUrl )
00627 {
00628     QFrame *plainPage = new QFrame( this );
00629     setMainWidget( plainPage );
00630 
00631     QVBoxLayout * topLayout = new QVBoxLayout( plainPage );
00632     topLayout->setMargin( 0 );
00633     topLayout->setSpacing( spacingHint() );
00634 
00635     // First line: filename
00636     KHBox * fileNameBox = new KHBox( plainPage );
00637     topLayout->addWidget( fileNameBox );
00638 
00639     QLabel * label = new QLabel( textFileName, fileNameBox );
00640     m_leFileName = new KLineEdit( fileNameBox );
00641     m_leFileName->setMinimumWidth(m_leFileName->sizeHint().width() * 3);
00642     label->setBuddy(m_leFileName);  // please "scheck" style
00643     m_leFileName->setText( defaultName );
00644     m_leFileName->setSelection(0, m_leFileName->text().length()); // autoselect
00645     connect( m_leFileName, SIGNAL(textChanged(const QString&)),
00646              SLOT(slotNameTextChanged(const QString&)) );
00647 
00648     // Second line: url
00649     KHBox * urlBox = new KHBox( plainPage );
00650     topLayout->addWidget( urlBox );
00651     label = new QLabel( textUrl, urlBox );
00652     m_urlRequester = new KUrlRequester( defaultUrl, urlBox);
00653     m_urlRequester->setMode( KFile::File | KFile::Directory );
00654 
00655     m_urlRequester->setMinimumWidth( m_urlRequester->sizeHint().width() * 3 );
00656     connect( m_urlRequester->lineEdit(), SIGNAL(textChanged(const QString&)),
00657              SLOT(slotURLTextChanged(const QString&)) );
00658     label->setBuddy(m_urlRequester);  // please "scheck" style
00659 
00660     m_urlRequester->setFocus();
00661     enableButtonOk( !defaultName.isEmpty() && !defaultUrl.isEmpty() );
00662     connect( this, SIGNAL(user1Clicked()), this, SLOT(slotClear()) );
00663     m_fileNameEdited = false;
00664 }
00665 
00666 KUrl KUrlDesktopFileDlg::url() const
00667 {
00668     if ( result() == QDialog::Accepted )
00669         return m_urlRequester->url();
00670     else
00671         return KUrl();
00672 }
00673 
00674 QString KUrlDesktopFileDlg::fileName() const
00675 {
00676     if ( result() == QDialog::Accepted )
00677         return m_leFileName->text();
00678     else
00679         return QString();
00680 }
00681 
00682 void KUrlDesktopFileDlg::slotClear()
00683 {
00684     m_leFileName->clear();
00685     m_urlRequester->clear();
00686     m_fileNameEdited = false;
00687 }
00688 
00689 void KUrlDesktopFileDlg::slotNameTextChanged( const QString& )
00690 {
00691     kDebug() ;
00692     m_fileNameEdited = true;
00693     enableButtonOk( !m_leFileName->text().isEmpty() && !m_urlRequester->url().isEmpty() );
00694 }
00695 
00696 void KUrlDesktopFileDlg::slotURLTextChanged( const QString& )
00697 {
00698     if ( !m_fileNameEdited )
00699     {
00700         // use URL as default value for the filename
00701         // (we copy only its filename if protocol supports listing,
00702         // but for HTTP we don't want tons of index.html links)
00703         KUrl url( m_urlRequester->url() );
00704         if (KProtocolManager::supportsListing(url) && !url.fileName().isEmpty())
00705             m_leFileName->setText( url.fileName() );
00706         else
00707             m_leFileName->setText( url.url() );
00708         m_fileNameEdited = false; // slotNameTextChanged set it to true erroneously
00709     }
00710     enableButtonOk( !m_leFileName->text().isEmpty() && !m_urlRequester->url().isEmpty() );
00711 }
00712 
00713 
00714 #include "knewmenu.moc"
00715 #include "knewmenu_p.moc"

libkonq

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

API Reference

Skip menu "API Reference"
  • Konsole
  • Libraries
  •   libkonq
Generated for API Reference by doxygen 1.5.7
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal