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" ),
"kcmdevices", 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::CopyJob * job = KIO::copyAs( uSrc, dest );
00437 job->setDefaultPermissions(
true );
00438 connect( job, SIGNAL( result( KIO::Job * ) ),
00439 SLOT( slotResult( KIO::Job * ) ) );
00440
if ( m_isURLDesktopFile )
00441 connect( job, SIGNAL( renamed( KIO::Job *,
const KURL&,
const KURL& ) ),
00442 SLOT( slotRenamed( KIO::Job *,
const KURL&,
const KURL& ) ) );
00443 KURL::List lst;
00444 lst.append( uSrc );
00445 (
void)
new KonqCommandRecorder( KonqCommand::COPY, lst, dest, job );
00446 }
00447 }
00448
00449
00450
00451
void KNewMenu::slotRenamed( KIO::Job *,
const KURL& from ,
const KURL& to )
00452 {
00453
if ( from.isLocalFile() )
00454 {
00455 kdDebug() << k_funcinfo << from.prettyURL() <<
" -> " << to.prettyURL() <<
" ( m_destPath=" << d->m_destPath <<
")" << endl;
00456 Q_ASSERT( from.path() == d->m_destPath );
00457 d->m_destPath = to.path();
00458 }
00459 }
00460
00461
void KNewMenu::slotResult( KIO::Job * job )
00462 {
00463
if (job->error())
00464 job->showErrorDialog();
00465
else
00466 {
00467 KURL destURL = static_cast<KIO::CopyJob*>(job)->destURL();
00468
if ( destURL.isLocalFile() )
00469 {
00470
if ( m_isURLDesktopFile )
00471 {
00472
00473
00474 kdDebug(1203) <<
" destURL=" << destURL.path() <<
" " <<
" d->m_destPath=" << d->m_destPath << endl;
00475 KDesktopFile df( d->m_destPath );
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"