00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
#include <qwhatsthis.h>
00012
#include <qdom.h>
00013
#include <qdir.h>
00014
#include <qfileinfo.h>
00015
#include <qvbox.h>
00016
#include <qtimer.h>
00017
00018
#include <kdeversion.h>
00019
#include <kiconloader.h>
00020
#include <klocale.h>
00021
#include <kdevgenericfactory.h>
00022
#include <kfiledialog.h>
00023
#include <kdebug.h>
00024
#include <kstandarddirs.h>
00025
#include <kstdaction.h>
00026
#include <kaction.h>
00027
#include <kapplication.h>
00028
00029
#include "kdevcore.h"
00030
#include "kdevmainwindow.h"
00031
#include "kdevproject.h"
00032
#include "kdevpartcontroller.h"
00033
#include "configwidgetproxy.h"
00034
00035
#include "filetemplate.h"
00036
#include "domutil.h"
00037
#include "urlutil.h"
00038
00039
#include "filecreate_widget2.h"
00040
#include "filecreate_widget3.h"
00041
#include "filecreate_part.h"
00042
#include "filecreate_filetype.h"
00043
#include "filecreate_filedialog.h"
00044
#include "filecreate_newfile.h"
00045
#include "fcconfigwidget.h"
00046
00047 #define PROJECTSETTINGSPAGE 1
00048 #define GLOBALSETTINGSPAGE 2
00049
00050
static const KAboutData data(
"kdevfilecreate",
I18N_NOOP(
"New File Wizard"),
"1.0");
00051
00052 typedef KDevGenericFactory<FileCreatePart> FileCreateFactory;
00053
K_EXPORT_COMPONENT_FACTORY( libkdevfilecreate,
FileCreateFactory( &data ) )
00054
00055 using namespace FileCreate;
00056
00057 FileCreatePart::
FileCreatePart(
QObject *parent, const
char *name, const
QStringList & )
00058 :
KDevCreateFile("FileCreate", "filecreate", parent, name ? name : "
FileCreatePart"), m_selectedWidget(-1), m_useSideTab(true)
00059 {
00060 setInstance(FileCreateFactory::instance());
00061 setXMLFile(
"kdevpart_filecreate.rc");
00062
00063 connect( core(), SIGNAL(projectOpened()),
this, SLOT(slotProjectOpened()) );
00064
00065 _configProxy =
new ConfigWidgetProxy( core() );
00066 _configProxy->createProjectConfigPage( i18n(
"New File Wizard"),
PROJECTSETTINGSPAGE );
00067 _configProxy->createGlobalConfigPage( i18n(
"New File Wizard"),
GLOBALSETTINGSPAGE );
00068 connect( _configProxy, SIGNAL(insertConfigWidget(
const KDialogBase*,
QWidget*,
unsigned int )),
00069
this, SLOT(insertConfigWidget(
const KDialogBase*,
QWidget*,
unsigned int )) );
00070
00071
00072
KAction * newAction =
KStdAction::openNew(
this, SLOT(slotNewFile()), actionCollection(),
"file_new");
00073 newAction->
setWhatsThis( i18n(
"<b>New file</b><p>Creates a new file. Also adds it the project if the <b>Add to project</b> checkbox is turned on.") );
00074 newAction->
setToolTip( i18n(
"Create a new file") );
00075
00076 m_filetypes.setAutoDelete(
true);
00077
00078 m_availableWidgets[0] =
new FriendlyWidget(
this);
00079 m_availableWidgets[1] =
new ListWidget(
this);
00080 m_numWidgets = 2;
00081
00085 selectWidget(1);
00086 }
00087
00088
00089 FileCreatePart::~FileCreatePart()
00090 {
00091
for(
int c=0;c<
m_numWidgets;c++){
00092
if (
TypeChooser* chooser =
m_availableWidgets[c]) {
00093
00094
if(
QWidget* as_widget = dynamic_cast<QWidget*>(chooser) )
00095
mainWindow()->
removeView( as_widget );
00096
00097
delete chooser;
00098 }
00099 }
00100
delete _configProxy;
00101 }
00102
00103 void FileCreatePart::insertConfigWidget(
const KDialogBase * dlg,
QWidget * page,
unsigned int pagenumber )
00104 {
00105
kdDebug() <<
k_funcinfo <<
endl;
00106
00107
switch( pagenumber )
00108 {
00109
case PROJECTSETTINGSPAGE:
00110 {
00111
FCConfigWidget* w =
new FCConfigWidget(
this,
false, page,
"filecreate config widget" );
00112 connect( dlg, SIGNAL( okClicked( ) ), w, SLOT( accept( ) ) );
00113 }
00114
break;
00115
00116
case GLOBALSETTINGSPAGE:
00117 {
00118
FCConfigWidget *w =
new FCConfigWidget(
this,
true, page,
"filecreate config widget" );
00119 connect(dlg, SIGNAL(okClicked()), w, SLOT(accept()));
00120 }
00121
break;
00122 }
00123 }
00124
00125 void FileCreatePart::selectWidget(
int widgetNumber) {
00126
if (
m_selectedWidget==widgetNumber)
return;
00127
if (widgetNumber<-1 || widgetNumber>=
m_numWidgets)
return;
00128
if (
setWidget(widgetNumber==-1 ? NULL :
m_availableWidgets[widgetNumber]))
00129
m_selectedWidget = widgetNumber;
00130 }
00131
00132
00133 bool FileCreatePart::setWidget(
TypeChooser * widg) {
00134
00135
QWidget *as_widget = widg ? dynamic_cast<QWidget*>(widg) : NULL;
00136
00137
00138
TypeChooser *tc =
typeChooserWidget();
00139
if (tc) {
00140 disconnect( tc->
signaller(), SIGNAL(filetypeSelected(
const FileType *)),
this, SLOT(
slotFiletypeSelected(
const FileType *)) );
00141
QWidget *as_widget2 = dynamic_cast<QWidget*>(tc);
00142
if (as_widget2) {
00143
kdDebug(9034) <<
"filecreate_part: Removing as_widget2" <<
endl;
00144
mainWindow()->
removeView(as_widget2);
00145 }
else
00146
kdWarning(9034) <<
"WARNING: could not cast to as_widget2" <<
endl;
00147
00148 }
00149
00150
if (widg && as_widget) {
00151 connect( widg->
signaller(), SIGNAL(filetypeSelected(
const FileType *)),
this, SLOT(
slotFiletypeSelected(
const FileType *)) );
00152
mainWindow()->
embedSelectView(as_widget, i18n(
"New File"), i18n(
"File creation"));
00153 }
00154
00155
return true;
00156 }
00157
00158 void FileCreatePart::refresh() {
00159
if (
typeChooserWidget())
typeChooserWidget()->
refresh();
00160 }
00161
00162 void FileCreatePart::slotNewFile() {
00163
KDevCreateFile::CreatedFile createdFile =
createNewFile();
00164
openCreatedFile(createdFile);
00165 }
00166
00167 void FileCreatePart::slotProjectOpened() {
00168 QTimer::singleShot( 0,
this, SLOT(
slotInitialize()) );
00169 }
00170
00171 void FileCreatePart::addFileType(
const QString & filename) {
00172
FileType * filetype =
getType(filename);
00173
if (!filetype) {
00174 filetype =
new FileType;
00175 filetype->
setName( filename +
" files" );
00176 filetype->
setExt( filename );
00177 filetype->
setCreateMethod(
"template");
00178
m_filetypes.append(filetype);
00179 }
00180 filetype->
setEnabled(
true);
00181 }
00182
00183 void FileCreatePart::slotProjectClosed() {
00184
m_filetypes.clear();
00185
refresh();
00186 }
00187
00188 void FileCreatePart::slotFiletypeSelected(
const FileType * filetype) {
00189
00190
KDevCreateFile::CreatedFile createdFile =
createNewFile(filetype->
ext(),
00191 QString::null,
00192 QString::null,
00193 filetype->
subtypeRef());
00194
00195
openCreatedFile(createdFile);
00196
00197
mainWindow()->
lowerView(
typeChooserWidgetAsQWidget() );
00198 }
00199
00200 void FileCreatePart::openCreatedFile(
const KDevCreateFile::CreatedFile & createdFile) {
00201
if (createdFile.
status == KDevCreateFile::CreatedFile::STATUS_OK) {
00202
KURL uu(
project()->projectDirectory() + createdFile.
dir +
"/" + createdFile.
filename );
00203
partController()->
editDocument ( uu );
00204 }
00205 }
00206
00207 int FileCreatePart::readTypes(
const QDomDocument & dom,
QPtrList<FileType> &m_filetypes,
bool enable) {
00208
int numRead = 0;
00209
QDomElement fileTypes = DomUtil::elementByPath(dom,
"/kdevfilecreate/filetypes");
00210
if (!fileTypes.isNull()) {
00211
for(
QDomNode node = fileTypes.firstChild();!node.isNull();node=node.nextSibling()) {
00212
00213
00214
if (node.isElement() && node.nodeName()==
"type") {
00215
QDomElement element = node.toElement();
00216
FileType * filetype =
new FileType;
00217 filetype->
setName( element.attribute(
"name") );
00218 filetype->
setExt( element.attribute(
"ext") );
00219 filetype->
setCreateMethod( element.attribute(
"create") );
00220
00221 filetype->
setIcon( element.attribute(
"icon") );
00222 filetype->
setDescr( (DomUtil::namedChildElement(element,
"descr")).
text() );
00223 filetype->
setEnabled(enable || (filetype->
ext()==
""));
00224 m_filetypes.append(filetype);
00225 numRead++;
00226
00227
kdDebug(9034) <<
"node: " << filetype->
name().latin1() <<
endl;
00228
00229
if (node.hasChildNodes()) {
00230
for(
QDomNode subnode = node.firstChild();!subnode.isNull();subnode=subnode.nextSibling()) {
00231
kdDebug(9034) <<
"subnode: " << subnode.nodeName().latin1() <<
endl;
00232
00233
if (subnode.isElement() && subnode.nodeName()==
"subtype") {
00234
QDomElement subelement = subnode.toElement();
00235 FileType * subtype =
new FileType;
00236 subtype->
setExt( filetype->
ext() );
00237 subtype->
setCreateMethod( filetype->
createMethod() );
00238 subtype->
setSubtypeRef( subelement.attribute(
"ref") );
00239 subtype->
setIcon( subelement.attribute(
"icon") );
00240 subtype->
setName( subelement.attribute(
"name") );
00241 subtype->
setDescr( (DomUtil::namedChildElement(subelement,
"descr")).
text() );
00242 subtype->
setEnabled(enable);
00243 filetype->
addSubtype(subtype);
00244 }
00245 }
00246 }
00247 }
00248 }
00249 }
00250
return numRead;
00251 }
00252
00253 FileType *
FileCreatePart::getType(
const QString & ex,
const QString subtRef) {
00254
00255
QString subtypeRef = subtRef;
00256
QString ext = ex;
00257
int dashPos = ext.find(
'-');
00258
if (dashPos>-1 && subtRef.isNull()) {
00259 ext = ex.left(dashPos);
00260 subtypeRef = ex.mid(dashPos+1);
00261 }
00262
00263
QPtrList<FileType> filetypes =
getFileTypes();
00264
for(
FileType * filetype = filetypes.first();
00265 filetype;
00266 filetype=filetypes.next()) {
00267
if (filetype->
ext()==ext) {
00268
if (subtypeRef.isNull())
return filetype;
00269
QPtrList<FileType> subtypes = filetype->
subtypes();
00270
for(
FileType * subtype = subtypes.first();
00271 subtype;
00272 subtype=subtypes.next()) {
00273
if (subtypeRef==subtype->
subtypeRef())
return subtype;
00274 }
00275 }
00276 }
00277
return NULL;
00278 }
00279
00280 FileType *
FileCreatePart::getEnabledType(
const QString & ex,
const QString subtRef) {
00281
00282
QString subtypeRef = subtRef;
00283
QString ext = ex;
00284
int dashPos = ext.find(
'-');
00285
if (dashPos>-1 && subtRef.isNull()) {
00286 ext = ex.left(dashPos);
00287 subtypeRef = ex.mid(dashPos+1);
00288 }
00289
00290
QPtrList<FileType> filetypes =
getFileTypes();
00291
for(
FileType * filetype = filetypes.first();
00292 filetype;
00293 filetype=filetypes.next()) {
00294
if (filetype->
ext()==ext) {
00295
if ( (subtypeRef.isNull()) && (filetype->
enabled()) )
return filetype;
00296
QPtrList<FileType> subtypes = filetype->
subtypes();
00297
for(
FileType * subtype = subtypes.first();
00298 subtype;
00299 subtype=subtypes.next()) {
00300
if ( (subtypeRef==subtype->
subtypeRef()) && (filetype->
enabled()) )
return subtype;
00301 }
00302 }
00303 }
00304
return NULL;
00305 }
00306
00307
00308
00309 KDevCreateFile::CreatedFile FileCreatePart::createNewFile(
QString ext,
QString dir,
QString name,
QString subtype)
00310 {
00311
KDevCreateFile::CreatedFile result;
00312
KURL projectURL(
project()->projectDirectory() );
00313
KURL selectedURL;
00314
00315
NewFileChooser dialog;
00316 dialog.
setFileTypes(
m_filetypes);
00317
const FileType *filetype =
getEnabledType(ext,subtype);
00318
kdDebug(9034) <<
"Looking for filetype pointer for " << ext <<
"/" << subtype <<
endl;
00319
if (filetype) {
00320
kdDebug(9034) <<
"found filetype" <<
endl;
00321 }
else {
00322
kdDebug(9034) <<
"could not find filetype" <<
endl;
00323 }
00324
00325
if (!dir.isNull())
00326 dialog.
setDirectory(dir);
00327
else
00328 {
00329
QString activeDir =
project()->
activeDirectory();
00330 dialog.
setDirectory(
project()->projectDirectory() +
00331 ( activeDir[0] ==
'/' ?
"" :
"/" )
00332 + activeDir );
00333 }
00334
if (!name.isNull()) dialog.
setName(name);
00335
if (filetype) dialog.
setCurrent(filetype);
00336
00337
int dialogResult = dialog.exec();
00338
00339
if (dialogResult == KDialogBase::Rejected) {
00340 result.
status = KDevCreateFile::CreatedFile::STATUS_NOTCREATED;
00341
return result;
00342 }
00343
00344
00345
00346 result.
addToProject = dialog.
addToProject();
00347 selectedURL = dialog.
url();
00348
const FileType *selectedFileType = dialog.
selectedType();
00349
00350
if (dialog.
addToProject() && !projectURL.
isParentOf(selectedURL)) {
00351 result.
status = KDevCreateFile::CreatedFile::STATUS_NOTWITHINPROJECT;
00352
return result;
00353 }
00354
00355
if (selectedFileType) {
00356 ext = selectedFileType->
ext();
00357 subtype = selectedFileType->
subtypeRef();
00358 }
00359
00360
if (dialog.
addToProject())
00361 {
00362
00363
QString relToProj =
URLUtil::relativePath(projectURL, selectedURL, URLUtil::SLASH_PREFIX );
00364
00365
00366
if (!ext.isNull() & ext!=
"" & !relToProj.endsWith(
"." + ext)) relToProj+=
"." + ext;
00367
00368
QString filename =
URLUtil::filename(relToProj);
00369
00370
kdDebug(9034) <<
"relative to proj dir = " << relToProj <<
endl;
00371
kdDebug(9034) <<
"filename = " << filename <<
endl;
00372
00373
00374
if (!subtype.isEmpty())
00375 ext +=
"-" + subtype;
00376
00377
00378
if (!FileTemplate::exists(
this, ext) ||
00379 !FileTemplate::copy(
this, ext,
project()->projectDirectory() + relToProj) ) {
00380
00381
QFile f(
project()->projectDirectory() + relToProj);
00382 f.open( IO_WriteOnly );
00383 f.close();
00384 }
00385
00386
project()->
addFile(relToProj.mid(1));
00387
00388
00389 result.
filename = filename;
00390 result.
dir =
URLUtil::directory(relToProj);
00391 result.
status = KDevCreateFile::CreatedFile::STATUS_OK;
00392 }
00393
else
00394 {
00395
QString fullPath = selectedURL.
path();
00396
00397
if (!ext.isNull() & ext!=
"" & !fullPath.endsWith(
"." + ext)) fullPath+=
"." + ext;
00398
00399
QString filename =
URLUtil::filename(fullPath);
00400
00401
kdDebug(9034) <<
"full path = " << fullPath <<
endl;
00402
kdDebug(9034) <<
"filename = " << filename <<
endl;
00403
00404
00405
if (!subtype.isEmpty())
00406 ext +=
"-" + subtype;
00407
00408
00409
if (!FileTemplate::exists(
this, ext) ||
00410 !FileTemplate::copy(
this, ext, fullPath) ) {
00411
00412
QFile f(fullPath);
00413 f.open( IO_WriteOnly );
00414 f.close();
00415 }
00416
KURL url;
00417 url.
setPath(fullPath);
00418
partController()->
editDocument(url);
00419 result.
filename = filename;
00420 result.
dir =
URLUtil::directory(fullPath);
00421 result.
status = KDevCreateFile::CreatedFile::STATUS_OK;
00422 }
00423
00424
return result;
00425 }
00426
00427 void FileCreatePart::setShowSideTab(
bool on) {
00428
selectWidget(on ? 1 : -1 );
00429 }
00430
00431 void FileCreatePart::slotNoteFiletype(
const FileType * filetype) {
00432
kdDebug(9034) <<
"Noting file type: " << (filetype ? filetype->
ext() : QString::fromLatin1(
"Null") ) <<
endl;
00433
m_filedialogFiletype = filetype;
00434 }
00435
00436 void FileCreatePart::slotInitialize( )
00437 {
00438
00439
QString globalXMLFile = ::locate(
"data",
"kdevfilecreate/template-info.xml");
00440
kdDebug(9034) <<
"Found global template info info " << globalXMLFile <<
endl;
00441
QDomDocument globalDom;
00442
if (!globalXMLFile.isNull() &&
00443 DomUtil::openDOMFile(globalDom,globalXMLFile)) {
00444
kdDebug(9034) <<
"Reading global template info..." <<
endl;
00445
00446
readTypes(globalDom,
m_filetypes,
false);
00447
00448
00450
QDomElement useSideTab = DomUtil::elementByPath(globalDom,
"/kdevfilecreate/sidetab");
00451
if (!useSideTab.isNull() && useSideTab.attribute(
"active")==
"no") {
00452
m_useSideTab =
false;
00453 }
00454 }
00455
00456
00457
00458
QDomElement useGlobalTypes =
00459 DomUtil::elementByPath(*
projectDom(),
"/kdevfilecreate/useglobaltypes");
00460
for(
QDomNode node = useGlobalTypes.firstChild();
00461 !node.isNull();node=node.nextSibling()) {
00462
00463
00464
00465
if (node.isElement() && node.nodeName()==
"type") {
00466
QDomElement element = node.toElement();
00467
QString ext = element.attribute(
"ext");
00468
QString subtyperef = element.attribute(
"subtyperef");
00469
00470
00471
if (subtyperef.isNull()) {
00472
FileType * filetype =
getType(ext);
00473
if (filetype) {
00474 filetype->
setEnabled(
true);
00475
if (filetype->
subtypes().count())
00476 filetype->
setSubtypesEnabled(
true);
00477 }
00478 }
else {
00479
00480
00481
FileType * filetype =
getType(ext);
00482
FileType * subtype = getType(ext,subtyperef);
00483
if (filetype && subtype) {
00484 filetype->
setEnabled(
true);
00485 subtype->
setEnabled(
true);
00486 }
00487 }
00488 }
00489 }
00490
00491
00492
if (
readTypes( *
projectDom(),
m_filetypes,
true )==0 ) {
00493
00494
00495
QDir templDir(
project()->projectDirectory() +
"/templates/" );
00496
if (templDir.exists()) {
00497 templDir.setFilter( QDir::Files );
00498
const QFileInfoList * list = templDir.entryInfoList();
00499
if( list ){
00500 QFileInfoListIterator it( *list );
00501
QFileInfo *fi;
00502
while ( (fi = it.current()) != 0 ) {
00503
addFileType(fi->fileName());
00504 ++it;
00505 }
00506 }
00507 }
00508
00509
00510
00511
00512
00513
00514 }
00515
00516
setShowSideTab(
m_useSideTab);
00517
00518
00519
refresh();
00520 }
00521
00522
#include "filecreate_part.moc"