|
|
|
/**********************************************************************
|
|
|
|
** Copyright (C) 2000 Trolltech AS. All rights reserved.
|
|
|
|
**
|
|
|
|
** This file is part of TQt Designer.
|
|
|
|
**
|
|
|
|
** This file may be distributed and/or modified under the terms of the
|
|
|
|
** GNU General Public License version 2 as published by the Free Software
|
|
|
|
** Foundation and appearing in the file LICENSE.GPL included in the
|
|
|
|
** packaging of this file.
|
|
|
|
**
|
|
|
|
** Licensees holding valid TQt Enterprise Edition or TQt Professional Edition
|
|
|
|
** licenses may use this file in accordance with the TQt Commercial License
|
|
|
|
** Agreement provided with the Software.
|
|
|
|
**
|
|
|
|
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
|
|
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
**
|
|
|
|
** See http://www.trolltech.com/gpl/ for GPL licensing information.
|
|
|
|
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
|
|
|
|
** information about TQt Commercial License Agreements.
|
|
|
|
**
|
|
|
|
** Contact info@trolltech.com if any conditions of this licensing are
|
|
|
|
** not clear to you.
|
|
|
|
**
|
|
|
|
**********************************************************************/
|
|
|
|
|
|
|
|
#include "sourcefile.h"
|
|
|
|
#include <tqfile.h>
|
|
|
|
#include <tqtextstream.h>
|
|
|
|
#include "designerappiface.h"
|
|
|
|
#include "sourceeditor.h"
|
|
|
|
#include "metadatabase.h"
|
|
|
|
#include "../interfaces/languageinterface.h"
|
|
|
|
#include <tqfiledialog.h>
|
|
|
|
#include <tqmessagebox.h>
|
|
|
|
#include "mainwindow.h"
|
|
|
|
#include "workspace.h"
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include <kfiledialog.h>
|
|
|
|
#include <klocale.h>
|
|
|
|
|
|
|
|
SourceFile::SourceFile( const TQString &fn, bool temp, Project *p )
|
|
|
|
: filename( fn ), ed( 0 ), fileNameTemp( temp ),
|
|
|
|
timeStamp( 0, p->makeAbsolute( fn ) ), pro( p ), pkg( FALSE )
|
|
|
|
, accepted( TRUE )
|
|
|
|
{
|
|
|
|
iface = 0;
|
|
|
|
|
|
|
|
if ( !temp )
|
|
|
|
accepted = checkFileName( TRUE );
|
|
|
|
|
|
|
|
if (accepted) {
|
|
|
|
load();
|
|
|
|
pro->addSourceFile( this );
|
|
|
|
MetaDataBase::addEntry( this );
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
SourceFile::~SourceFile()
|
|
|
|
{
|
|
|
|
if (iface)
|
|
|
|
delete iface;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString SourceFile::text() const
|
|
|
|
{
|
|
|
|
return txt;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SourceFile::setText( const TQString &s )
|
|
|
|
{
|
|
|
|
txt = s;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SourceFile::save( bool ignoreModified )
|
|
|
|
{
|
|
|
|
if ( fileNameTemp )
|
|
|
|
return saveAs();
|
|
|
|
if ( !ignoreModified && !isModified() )
|
|
|
|
return TRUE;
|
|
|
|
if ( ed )
|
|
|
|
ed->save();
|
|
|
|
|
|
|
|
if ( TQFile::exists( pro->makeAbsolute( filename ) ) ) {
|
|
|
|
TQString fn( pro->makeAbsolute( filename ) );
|
|
|
|
#if defined(Q_OS_WIN32)
|
|
|
|
fn += ".bak";
|
|
|
|
#else
|
|
|
|
fn += "~";
|
|
|
|
#endif
|
|
|
|
TQFile f( pro->makeAbsolute( filename ) );
|
|
|
|
if ( f.open( IO_ReadOnly ) ) {
|
|
|
|
TQFile f2( fn );
|
|
|
|
if ( f2.open( IO_WriteOnly | IO_Translate ) ) {
|
|
|
|
TQCString data( f.size() );
|
|
|
|
f.readBlock( data.data(), f.size() );
|
|
|
|
f2.writeBlock( data );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TQFile f( pro->makeAbsolute( filename ) );
|
|
|
|
if ( !f.open( IO_WriteOnly | IO_Translate ) )
|
|
|
|
return saveAs();
|
|
|
|
|
|
|
|
TQTextStream ts( &f );
|
|
|
|
ts << txt;
|
|
|
|
timeStamp.update();
|
|
|
|
setModified( FALSE );
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SourceFile::saveAs( bool ignoreModified )
|
|
|
|
{
|
|
|
|
LanguageInterface *iface = MetaDataBase::languageInterface( pro->language() );
|
|
|
|
TQString filter;
|
|
|
|
if ( iface )
|
|
|
|
filter = iface->fileFilterList().join("\n");
|
|
|
|
|
|
|
|
TQString old = filename;
|
|
|
|
TQString initFn = pro->makeAbsolute( filename );
|
|
|
|
if ( ignoreModified ) {
|
|
|
|
TQString dir = TQStringList::split( ':', project()->iFace()->customSetting( "QTSCRIPT_PACKAGES" ) ).first();
|
|
|
|
initFn = TQFileInfo( initFn ).fileName();
|
|
|
|
initFn.prepend( dir + "/" );
|
|
|
|
}
|
|
|
|
TQString fn = KFileDialog::getSaveFileName( initFn, filter );
|
|
|
|
if ( fn.isEmpty() )
|
|
|
|
return FALSE;
|
|
|
|
fileNameTemp = FALSE;
|
|
|
|
filename = pro->makeRelative( fn );
|
|
|
|
if ( !checkFileName( TRUE ) ) {
|
|
|
|
filename = old;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
pro->setModified( TRUE );
|
|
|
|
timeStamp.setFileName( pro->makeAbsolute( filename ) );
|
|
|
|
if ( ed )
|
|
|
|
ed->setCaption( i18n( "Edit %1" ).tqarg( filename ) );
|
|
|
|
setModified( TRUE );
|
|
|
|
if ( pro->isDummy() ) {
|
|
|
|
TQObject *o = ed->parent();
|
|
|
|
while ( o && !o->isA( "MainWindow" ) )
|
|
|
|
o = o->parent();
|
|
|
|
if ( o )
|
|
|
|
((MainWindow *)o)->addRecentlyOpenedFile( fn );
|
|
|
|
}
|
|
|
|
return save( ignoreModified );
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SourceFile::load()
|
|
|
|
{
|
|
|
|
TQFile f( pro->makeAbsolute( filename ) );
|
|
|
|
if ( !f.open( IO_ReadOnly ) )
|
|
|
|
return FALSE;
|
|
|
|
TQTextStream ts( &f );
|
|
|
|
txt = ts.read();
|
|
|
|
timeStamp.update();
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
DesignerSourceFile *SourceFile::iFace()
|
|
|
|
{
|
|
|
|
if ( !iface )
|
|
|
|
iface = new DesignerSourceFileImpl( this );
|
|
|
|
return iface;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SourceFile::setEditor( SourceEditor *e )
|
|
|
|
{
|
|
|
|
ed = e;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SourceFile::isModified() const
|
|
|
|
{
|
|
|
|
if ( !ed )
|
|
|
|
return FALSE;
|
|
|
|
return ed->isModified();
|
|
|
|
}
|
|
|
|
|
|
|
|
static TQMap<TQString, int> *extensionCounter;
|
|
|
|
TQString SourceFile::createUnnamedFileName( const TQString &extension )
|
|
|
|
{
|
|
|
|
if ( !extensionCounter )
|
|
|
|
extensionCounter = new TQMap<TQString, int>;
|
|
|
|
int count = -1;
|
|
|
|
TQMap<TQString, int>::Iterator it;
|
|
|
|
if ( ( it = extensionCounter->find( extension ) ) != extensionCounter->end() ) {
|
|
|
|
count = *it;
|
|
|
|
++count;
|
|
|
|
extensionCounter->replace( extension, count );
|
|
|
|
} else {
|
|
|
|
count = 1;
|
|
|
|
extensionCounter->insert( extension, count );
|
|
|
|
}
|
|
|
|
|
|
|
|
return "unnamed" + TQString::number( count ) + "." + extension;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SourceFile::setModified( bool m )
|
|
|
|
{
|
|
|
|
if ( !ed )
|
|
|
|
return;
|
|
|
|
ed->setModified( m );
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SourceFile::closeEvent()
|
|
|
|
{
|
|
|
|
if ( !isModified() && fileNameTemp ) {
|
|
|
|
pro->removeSourceFile( this );
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !isModified() )
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
if ( ed )
|
|
|
|
ed->save();
|
|
|
|
|
|
|
|
switch ( TQMessageBox::warning( MainWindow::self, i18n( "Save Code" ),
|
|
|
|
i18n( "Save changes to '%1'?" ).tqarg( filename ),
|
|
|
|
i18n( "&Yes" ), i18n( "&No" ), i18n( "&Cancel" ), 0, 2 ) ) {
|
|
|
|
case 0: // save
|
|
|
|
if ( !save() )
|
|
|
|
return FALSE;
|
|
|
|
break;
|
|
|
|
case 1: // don't save
|
|
|
|
load();
|
|
|
|
if ( ed )
|
|
|
|
ed->editorInterface()->setText( txt );
|
|
|
|
if ( fileNameTemp ) {
|
|
|
|
pro->removeSourceFile( this );
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
if ( MainWindow::self )
|
|
|
|
MainWindow::self->workspace()->update();
|
|
|
|
break;
|
|
|
|
case 2: // cancel
|
|
|
|
return FALSE;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
setModified( FALSE );
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SourceFile::close()
|
|
|
|
{
|
|
|
|
if ( !ed )
|
|
|
|
return TRUE;
|
|
|
|
return ed->close();
|
|
|
|
}
|
|
|
|
|
|
|
|
Project *SourceFile::project() const
|
|
|
|
{
|
|
|
|
return pro;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SourceFile::checkTimeStamp()
|
|
|
|
{
|
|
|
|
if ( timeStamp.isUpToDate() )
|
|
|
|
return;
|
|
|
|
timeStamp.update();
|
|
|
|
if ( TQMessageBox::information( MainWindow::self, i18n( "TQt Designer" ),
|
|
|
|
i18n( "File '%1' has been changed outside TQt Designer.\n"
|
|
|
|
"Do you want to reload it?" ).tqarg( filename ),
|
|
|
|
i18n( "&Yes" ), i18n( "&No" ) ) == 0 ) {
|
|
|
|
load();
|
|
|
|
if ( ed )
|
|
|
|
ed->editorInterface()->setText( txt );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SourceFile::checkFileName( bool allowBreak )
|
|
|
|
{
|
|
|
|
SourceFile *sf = pro->findSourceFile( filename, this );
|
|
|
|
if ( sf )
|
|
|
|
TQMessageBox::warning( MainWindow::self, i18n( "Invalid Filename" ),
|
|
|
|
i18n( "The project already contains a source file with \n"
|
|
|
|
"filename '%1'. Please choose a new filename." ).tqarg( filename ) );
|
|
|
|
while ( sf ) {
|
|
|
|
LanguageInterface *iface = MetaDataBase::languageInterface( pro->language() );
|
|
|
|
TQString filter;
|
|
|
|
if ( iface )
|
|
|
|
filter = iface->fileFilterList().join("\n");
|
|
|
|
TQString fn;
|
|
|
|
while ( fn.isEmpty() ) {
|
|
|
|
fn = KFileDialog::getSaveFileName( pro->makeAbsolute( filename ), filter );
|
|
|
|
if ( allowBreak && fn.isEmpty() )
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
filename = pro->makeRelative( fn );
|
|
|
|
sf = pro->findSourceFile( filename, this );
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|