00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <qdir.h>
00021
00022 #include <kdebug.h>
00023 #include <kdesktopfile.h>
00024 #include <kdirwatch.h>
00025 #include <kinstance.h>
00026 #include <kinputdialog.h>
00027 #include <klocale.h>
00028 #include <kmessagebox.h>
00029 #include <kstandarddirs.h>
00030 #include <kprotocolinfo.h>
00031 #include <kpopupmenu.h>
00032 #include <krun.h>
00033
00034 #include <kio/job.h>
00035
00036 #include <kpropertiesdialog.h>
00037 #include "konq_operations.h"
00038 #include "konq_undo.h"
00039 #include "knewmenu.h"
00040 #include <utime.h>
00041
00042
00043 #include <qlayout.h>
00044 #include <qhbox.h>
00045 #include <klineedit.h>
00046 #include <kurlrequester.h>
00047 #include <qlabel.h>
00048 #include <qpopupmenu.h>
00049
00050 QValueList<KNewMenu::Entry> * KNewMenu::s_templatesList = 0L;
00051 int KNewMenu::s_templatesVersion = 0;
00052 bool KNewMenu::s_filesParsed = false;
00053 KDirWatch * KNewMenu::s_pDirWatch = 0L;
00054
00055 class KNewMenu::KNewMenuPrivate
00056 {
00057 public:
00058 KNewMenuPrivate() : m_parentWidget(0) {}
00059 KActionCollection * m_actionCollection;
00060 QString m_destPath;
00061 QWidget *m_parentWidget;
00062 KActionMenu *m_menuDev;
00063 KActionMenu *m_menuNew;
00064 };
00065
00066 KNewMenu::KNewMenu( KActionCollection * _collec, const char *name ) :
00067 KActionMenu( i18n( "Create New" ), "filenew", _collec, name ),
00068 menuItemsVersion( 0 )
00069 {
00070
00071
00072
00073 d = new KNewMenuPrivate;
00074 d->m_actionCollection = _collec;
00075 makeMenus();
00076 }
00077
00078 KNewMenu::KNewMenu( KActionCollection * _collec, QWidget *parentWidget, const char *name ) :
00079 KActionMenu( i18n( "Create New" ), "filenew", _collec, name ),
00080 menuItemsVersion( 0 )
00081 {
00082 d = new KNewMenuPrivate;
00083 d->m_actionCollection = _collec;
00084 d->m_parentWidget = parentWidget;
00085 makeMenus();
00086 }
00087
00088 KNewMenu::~KNewMenu()
00089 {
00090
00091 delete d;
00092 }
00093
00094 void KNewMenu::makeMenus()
00095 {
00096 d->m_menuDev = new KActionMenu( i18n( "Device" ), "filenew", d->m_actionCollection, "devnew" );
00097 d->m_menuNew = new KActionMenu( i18n( "File" ), "filenew", d->m_actionCollection, "devnew" );
00098 }
00099
00100 void KNewMenu::slotCheckUpToDate( )
00101 {
00102
00103
00104
00105 if (menuItemsVersion < s_templatesVersion || s_templatesVersion == 0)
00106 {
00107
00108
00109
00110 QValueList<KAction*> actions = d->m_actionCollection->actions( "KNewMenu" );
00111 for( QValueListIterator<KAction*> it = actions.begin(); it != actions.end(); ++it )
00112 {
00113 remove( *it );
00114 d->m_actionCollection->remove( *it );
00115 }
00116
00117 if (!s_templatesList) {
00118 s_templatesList = new QValueList<Entry>();
00119 slotFillTemplates();
00120 parseFiles();
00121 }
00122
00123
00124
00125 if ( !s_filesParsed )
00126 parseFiles();
00127
00128 fillMenu();
00129
00130 menuItemsVersion = s_templatesVersion;
00131 }
00132 }
00133
00134 void KNewMenu::parseFiles()
00135 {
00136
00137 s_filesParsed = true;
00138 QValueList<Entry>::Iterator templ = s_templatesList->begin();
00139 for ( ; templ != s_templatesList->end(); ++templ)
00140 {
00141 QString iconname;
00142 QString filePath = (*templ).filePath;
00143 if ( !filePath.isEmpty() )
00144 {
00145 QString text;
00146 QString templatePath;
00147
00148
00149 if ( KDesktopFile::isDesktopFile( filePath ) ) {
00150 KSimpleConfig config( filePath, true );
00151 config.setDesktopGroup();
00152 text = config.readEntry("Name");
00153 (*templ).icon = config.readEntry("Icon");
00154 (*templ).comment = config.readEntry("Comment");
00155 QString type = config.readEntry( "Type" );
00156 if ( type == "Link" )
00157 {
00158 templatePath = config.readPathEntry("URL");
00159 if ( templatePath[0] != '/' )
00160 {
00161 if ( templatePath.left(6) == "file:/" )
00162 templatePath = templatePath.right( templatePath.length() - 6 );
00163 else
00164 {
00165
00166 QString linkDir = filePath.left( filePath.findRev( '/' ) + 1 );
00167
00168 templatePath = linkDir + templatePath;
00169 }
00170 }
00171 }
00172 if ( templatePath.isEmpty() )
00173 {
00174
00175 (*templ).entryType = TEMPLATE;
00176 (*templ).templatePath = (*templ).filePath;
00177 } else {
00178 (*templ).entryType = LINKTOTEMPLATE;
00179 (*templ).templatePath = templatePath;
00180 }
00181
00182 }
00183 if (text.isEmpty())
00184 {
00185 text = KURL(filePath).fileName();
00186 if ( text.right(8) == ".desktop" )
00187 text.truncate( text.length() - 8 );
00188 else if ( text.right(7) == ".kdelnk" )
00189 text.truncate( text.length() - 7 );
00190 }
00191 (*templ).text = text;
00192
00193
00194
00195 }
00196 else {
00197 (*templ).entryType = SEPARATOR;
00198 }
00199 }
00200 }
00201
00202 void KNewMenu::fillMenu()
00203 {
00204
00205 popupMenu()->clear();
00206 d->m_menuDev->popupMenu()->clear();
00207 d->m_menuNew->popupMenu()->clear();
00208
00209 int i = 1;
00210 QValueList<Entry>::Iterator templ = s_templatesList->begin();
00211 for ( ; templ != s_templatesList->end(); ++templ, ++i)
00212 {
00213 if ( (*templ).entryType != SEPARATOR )
00214 {
00215
00216
00217
00218
00219
00220
00221 bool bSkip = false;
00222
00223 QValueList<KAction*> actions = d->m_actionCollection->actions();
00224 QValueListIterator<KAction*> it = actions.begin();
00225 for( ; it != actions.end() && !bSkip; ++it )
00226 {
00227 if ( (*it)->text() == (*templ).text )
00228 {
00229 kdDebug(1203) << "KNewMenu: skipping " << (*templ).filePath << endl;
00230 bSkip = true;
00231 }
00232 }
00233
00234 if ( !bSkip )
00235 {
00236 Entry entry = *(s_templatesList->at( i-1 ));
00237
00238
00239 if((*templ).templatePath.right( 8 ) == "emptydir")
00240 {
00241 KAction * act = new KAction( (*templ).text, (*templ).icon, 0, this, SLOT( slotNewDir() ),
00242 d->m_actionCollection, QCString().sprintf("newmenu%d", i ) );
00243 act->setGroup( "KNewMenu" );
00244 act->plug( popupMenu() );
00245 }
00246 else if ( KDesktopFile::isDesktopFile( entry.templatePath ) )
00247 {
00248 KDesktopFile df( entry.templatePath );
00249 if(df.readType() == "FSDevice")
00250 {
00251 KAction * act = new KAction( (*templ).text, (*templ).icon, 0, this, SLOT( slotNewFile() ),
00252 d->m_actionCollection, QCString().sprintf("newmenu%d", i ) );
00253 act->setGroup( "KNewMenu" );
00254 act->plug( d->m_menuDev->popupMenu() );
00255 }
00256 else
00257 {
00258 KAction * act = new KAction( (*templ).text, (*templ).icon, 0, this, SLOT( slotNewFile() ),
00259 d->m_actionCollection, QCString().sprintf("newmenu%d", i ) );
00260 act->setGroup( "KNewMenu" );
00261 act->plug( d->m_menuNew->popupMenu() );
00262 }
00263 }
00264 else
00265 {
00266 KAction * act = new KAction( (*templ).text, (*templ).icon, 0, this, SLOT( slotNewFile() ),
00267 d->m_actionCollection, QCString().sprintf("newmenu%d", i ) );
00268 act->setGroup( "KNewMenu" );
00269 act->plug( d->m_menuNew->popupMenu() );
00270 }
00271 }
00272 } else {
00273 Q_ASSERT( (*templ).entryType != 0 );
00274
00275 KActionSeparator * act = new KActionSeparator();
00276 act->plug( popupMenu() );
00277 }
00278 }
00279
00280 d->m_menuNew->plug( popupMenu() );
00281 d->m_menuDev->plug( popupMenu() );
00282 }
00283
00284 void KNewMenu::slotFillTemplates()
00285 {
00286
00287
00288 if ( ! s_pDirWatch )
00289 {
00290 s_pDirWatch = new KDirWatch;
00291 QStringList dirs = d->m_actionCollection->instance()->dirs()->resourceDirs("templates");
00292 for ( QStringList::Iterator it = dirs.begin() ; it != dirs.end() ; ++it )
00293 {
00294
00295 s_pDirWatch->addDir( *it );
00296 }
00297 connect ( s_pDirWatch, SIGNAL( dirty( const QString & ) ),
00298 this, SLOT ( slotFillTemplates() ) );
00299 connect ( s_pDirWatch, SIGNAL( created( const QString & ) ),
00300 this, SLOT ( slotFillTemplates() ) );
00301 connect ( s_pDirWatch, SIGNAL( deleted( const QString & ) ),
00302 this, SLOT ( slotFillTemplates() ) );
00303
00304 }
00305 s_templatesVersion++;
00306 s_filesParsed = false;
00307
00308 s_templatesList->clear();
00309
00310
00311 QStringList files = d->m_actionCollection->instance()->dirs()->findAllResources("templates");
00312 KSortableValueList<Entry,QString> slist;
00313 for ( QStringList::Iterator it = files.begin() ; it != files.end() ; ++it )
00314 {
00315
00316 if ( (*it)[0] != '.' )
00317 {
00318 Entry e;
00319 e.filePath = *it;
00320 e.entryType = 0;
00321
00322 if ( (*it).endsWith( "Directory.desktop" ) )
00323 s_templatesList->prepend( e );
00324 else
00325 {
00326 KSimpleConfig config( *it, true );
00327 config.setDesktopGroup();
00328 slist.insert( config.readEntry("Name"), e );
00329 }
00330 }
00331 }
00332 slist.sort();
00333 for(KSortableValueList<Entry, QString>::ConstIterator it = slist.begin(); it != slist.end(); ++it)
00334 {
00335 s_templatesList->append( (*it).value() );
00336 }
00337
00338 }
00339
00340 void KNewMenu::slotNewDir()
00341 {
00342 emit activated();
00343
00344 if (popupFiles.isEmpty())
00345 return;
00346
00347 KonqOperations::newDir(d->m_parentWidget, popupFiles.first());
00348 }
00349
00350 void KNewMenu::slotNewFile()
00351 {
00352 int id = QString( sender()->name() + 7 ).toInt();
00353 if (id == 0)
00354 {
00355
00356 KRun::runCommand(QString(sender()->name()));
00357 return;
00358 }
00359
00360 emit activated();
00361
00362 Entry entry = *(s_templatesList->at( id - 1 ));
00363
00364
00365 if ( !QFile::exists( entry.templatePath ) ) {
00366 kdWarning(1203) << entry.templatePath << " doesn't exist" << endl;
00367 KMessageBox::sorry( 0L, i18n("<qt>The template file <b>%1</b> doesn't exist.</qt>").arg(entry.templatePath));
00368 return;
00369 }
00370 m_isURLDesktopFile = false;
00371 QString name;
00372 if ( KDesktopFile::isDesktopFile( entry.templatePath ) )
00373 {
00374 KDesktopFile df( entry.templatePath );
00375
00376 if ( df.readType() == "Link" )
00377 {
00378 m_isURLDesktopFile = true;
00379
00380 KURLDesktopFileDlg dlg( i18n("File name:"), entry.comment, d->m_parentWidget );
00381
00382 if ( dlg.exec() )
00383 {
00384 name = dlg.fileName();
00385 m_linkURL = dlg.url();
00386 if ( name.isEmpty() || m_linkURL.isEmpty() )
00387 return;
00388 if ( !name.endsWith( ".desktop" ) )
00389 name += ".desktop";
00390 }
00391 else
00392 return;
00393 }
00394 else
00395 {
00396 KURL::List::Iterator it = popupFiles.begin();
00397 for ( ; it != popupFiles.end(); ++it )
00398 {
00399
00400
00401
00402 QString text = entry.text;
00403 text.replace( "...", QString::null );
00404 (void) new KPropertiesDialog( entry.templatePath, *it, text, d->m_parentWidget );
00405 }
00406 return;
00407 }
00408 }
00409 else
00410 {
00411
00412
00413 bool ok;
00414 QString text = entry.text;
00415 text.replace( "...", QString::null );
00416 name = KInputDialog::getText( QString::null, entry.comment,
00417 text, &ok, d->m_parentWidget );
00418 if ( !ok )
00419 return;
00420 }
00421
00422
00423
00424 KURL::List::Iterator it = popupFiles.begin();
00425
00426 QString src = entry.templatePath;
00427 for ( ; it != popupFiles.end(); ++it )
00428 {
00429 KURL dest( *it );
00430 dest.addPath( KIO::encodeFileName(name) );
00431 d->m_destPath = dest.path();
00432
00433 KURL uSrc;
00434 uSrc.setPath( src );
00435
00436 KIO::Job * job = KIO::copyAs( uSrc, dest );
00437 connect( job, SIGNAL( result( KIO::Job * ) ),
00438 SLOT( slotResult( KIO::Job * ) ) );
00439 if ( m_isURLDesktopFile )
00440 connect( job, SIGNAL( renamed( KIO::Job *, const KURL&, const KURL& ) ),
00441 SLOT( slotRenamed( KIO::Job *, const KURL&, const KURL& ) ) );
00442 KURL::List lst;
00443 lst.append( uSrc );
00444 (void)new KonqCommandRecorder( KonqCommand::COPY, lst, dest, job );
00445 }
00446 }
00447
00448
00449
00450 void KNewMenu::slotRenamed( KIO::Job *, const KURL& from , const KURL& to )
00451 {
00452 if ( from.isLocalFile() )
00453 {
00454 kdDebug() << k_funcinfo << from.prettyURL() << " -> " << to.prettyURL() << " ( m_destPath=" << d->m_destPath << ")" << endl;
00455 Q_ASSERT( from.path() == d->m_destPath );
00456 d->m_destPath = to.path();
00457 }
00458 }
00459
00460 void KNewMenu::slotResult( KIO::Job * job )
00461 {
00462 if (job->error())
00463 job->showErrorDialog();
00464 else
00465 {
00466 KURL destURL = static_cast<KIO::CopyJob*>(job)->destURL();
00467 if ( destURL.isLocalFile() )
00468 {
00469 if ( m_isURLDesktopFile )
00470 {
00471
00472
00473 kdDebug(1203) << " destURL=" << destURL.path() << " " << " d->m_destPath=" << d->m_destPath << endl;
00474 KDesktopFile df( d->m_destPath );
00475 df.writeEntry( "Name", m_linkURL );
00476 df.writeEntry( "Icon", KProtocolInfo::icon( KURL(m_linkURL).protocol() ) );
00477 df.writePathEntry( "URL", m_linkURL );
00478 df.sync();
00479 }
00480 else
00481 {
00482
00483 (void) ::utime( QFile::encodeName( destURL.path() ), 0 );
00484 }
00485 }
00486 }
00487 }
00488
00490
00491 KURLDesktopFileDlg::KURLDesktopFileDlg( const QString& textFileName, const QString& textUrl )
00492 : KDialogBase( Plain, QString::null, Ok|Cancel|User1, Ok, 0L , 0L, true,
00493 true, KStdGuiItem::clear() )
00494 {
00495 initDialog( textFileName, QString::null, textUrl, QString::null );
00496 }
00497
00498 KURLDesktopFileDlg::KURLDesktopFileDlg( const QString& textFileName, const QString& textUrl, QWidget *parent )
00499 : KDialogBase( Plain, QString::null, Ok|Cancel|User1, Ok, parent, 0L, true,
00500 true, KStdGuiItem::clear() )
00501 {
00502 initDialog( textFileName, QString::null, textUrl, QString::null );
00503 }
00504
00505 void KURLDesktopFileDlg::initDialog( const QString& textFileName, const QString& defaultName, const QString& textUrl, const QString& defaultUrl )
00506 {
00507 QVBoxLayout * topLayout = new QVBoxLayout( plainPage(), 0, spacingHint() );
00508
00509
00510 QHBox * fileNameBox = new QHBox( plainPage() );
00511 topLayout->addWidget( fileNameBox );
00512
00513 QLabel * label = new QLabel( textFileName, fileNameBox );
00514 m_leFileName = new KLineEdit( fileNameBox, 0L );
00515 m_leFileName->setMinimumWidth(m_leFileName->sizeHint().width() * 3);
00516 label->setBuddy(m_leFileName);
00517 m_leFileName->setText( defaultName );
00518 m_leFileName->setSelection(0, m_leFileName->text().length());
00519 connect( m_leFileName, SIGNAL(textChanged(const QString&)),
00520 SLOT(slotNameTextChanged(const QString&)) );
00521
00522
00523 QHBox * urlBox = new QHBox( plainPage() );
00524 topLayout->addWidget( urlBox );
00525 label = new QLabel( textUrl, urlBox );
00526 m_urlRequester = new KURLRequester( defaultUrl, urlBox, "urlRequester" );
00527 m_urlRequester->setMode( KFile::File | KFile::Directory );
00528
00529 m_urlRequester->setMinimumWidth( m_urlRequester->sizeHint().width() * 3 );
00530 connect( m_urlRequester->lineEdit(), SIGNAL(textChanged(const QString&)),
00531 SLOT(slotURLTextChanged(const QString&)) );
00532 label->setBuddy(m_urlRequester);
00533
00534 m_urlRequester->setFocus();
00535 enableButtonOK( !defaultName.isEmpty() && !defaultUrl.isEmpty() );
00536 connect( this, SIGNAL(user1Clicked()), this, SLOT(slotClear()) );
00537 m_fileNameEdited = false;
00538 }
00539
00540 QString KURLDesktopFileDlg::url() const
00541 {
00542 if ( result() == QDialog::Accepted )
00543 return m_urlRequester->url();
00544 else
00545 return QString::null;
00546 }
00547
00548 QString KURLDesktopFileDlg::fileName() const
00549 {
00550 if ( result() == QDialog::Accepted )
00551 return m_leFileName->text();
00552 else
00553 return QString::null;
00554 }
00555
00556 void KURLDesktopFileDlg::slotClear()
00557 {
00558 m_leFileName->setText( QString::null );
00559 m_urlRequester->clear();
00560 m_fileNameEdited = false;
00561 }
00562
00563 void KURLDesktopFileDlg::slotNameTextChanged( const QString& )
00564 {
00565 kdDebug() << k_funcinfo << endl;
00566 m_fileNameEdited = true;
00567 enableButtonOK( !m_leFileName->text().isEmpty() && !m_urlRequester->url().isEmpty() );
00568 }
00569
00570 void KURLDesktopFileDlg::slotURLTextChanged( const QString& )
00571 {
00572 if ( !m_fileNameEdited )
00573 {
00574
00575
00576
00577 KURL url( m_urlRequester->url() );
00578 if ( KProtocolInfo::supportsListing( url ) )
00579 m_leFileName->setText( url.fileName() );
00580 else
00581 m_leFileName->setText( url.url() );
00582 m_fileNameEdited = false;
00583 }
00584 enableButtonOK( !m_leFileName->text().isEmpty() && !m_urlRequester->url().isEmpty() );
00585 }
00586
00587
00588 #include "knewmenu.moc"