/***************************************************************************
quantaview . cpp - description
- - - - - - - - - - - - - - - - - - -
begin : <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 9 13 : 29 : 57 EEST 2000
copyright : ( C ) 2000 by Dmitry Poplavsky & Alexander Yakovlev & Eric Laffoon < pdima @ users . sourceforge . net , yshurik @ linuxfan . com , sequitur @ easystreet . com >
( C ) 2001 - 2005 Andras Mantia < amantia @ kde . org >
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/***************************************************************************
* *
* This program is free software ; you can redistribute it and / or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation ; either version 2 of the License , or *
* ( at your option ) any later version . *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
// include files for TQt
# include <tqprinter.h>
# include <tqpainter.h>
# include <tqtabbar.h>
# include <tqtabwidget.h>
# include <tqtimer.h>
# include <tqlayout.h>
# include <tqwidgetstack.h>
# include <tqdom.h>
# include <tqfile.h>
# include <tqevent.h>
# include <tqwidget.h>
# include <tqsplitter.h>
# include <tqpoint.h>
# include <tqscrollview.h>
// include files for KDE
# include <kaction.h>
# include <kdebug.h>
# include <kdirwatch.h>
# include <khtmlview.h>
# include <klocale.h>
# include <kstandarddirs.h>
# include <kmenubar.h>
# include <kiconloader.h>
# include <kmessagebox.h>
# include <kurldrag.h>
# include <kdeversion.h>
# include <kparts/partmanager.h>
# include <kstatusbar.h>
# include "undoredo.h"
# include "kafkacommon.h"
# include "wkafkapart.h"
# include <ktexteditor/document.h>
# include <ktexteditor/selectioninterface.h>
# include <ktexteditor/selectioninterfaceext.h>
# include <ktexteditor/view.h>
# include <ktexteditor/viewcursorinterface.h>
// application specific includes
# include "document.h"
# include "resource.h"
# include "quantaview.h"
# include "quanta.h"
# include "quantacommon.h"
# include "qextfileinfo.h"
# include "viewmanager.h"
# include "tagaction.h"
# include "toolbartabwidget.h"
# include "quantaplugin.h"
# include "project.h"
# include "structtreeview.h"
# include "tagdialog.h"
extern int NN ;
extern TQValueList < Node * > nodes ;
QuantaView : : QuantaView ( TQWidget * tqparent , const char * name , const TQString & caption )
: KMdiChildView ( tqparent , name )
, m_document ( 0L )
, m_plugin ( 0L )
, m_customWidget ( 0L )
, m_kafkaDocument ( 0L )
, m_currentFocus ( SourceFocus )
{
setMDICaption ( caption ) ;
//Connect the VPL update timers
connect ( & m_sourceUpdateTimer , TQT_SIGNAL ( timeout ( ) ) , this , TQT_SLOT ( sourceUpdateTimerTimeout ( ) ) ) ;
connect ( & m_VPLUpdateTimer , TQT_SIGNAL ( timeout ( ) ) , this , TQT_SLOT ( VPLUpdateTimerTimeout ( ) ) ) ;
//create the source and VPL holding widgets
m_documentArea = new TQWidget ( this ) ;
//get the reference to the user toolbar holding widget
ToolbarTabWidget * m_toolbarTab = ToolbarTabWidget : : ref ( ) ;
m_toolbarTab - > reparent ( this , 0 , TQPoint ( ) , true ) ;
m_toolbarTab - > setFocusPolicy ( TQ_NoFocus ) ;
//create a splitter to separate the VPL and document area
m_splitter = new TQSplitter ( Qt : : Vertical , this ) ;
//place the widgets in a grid
m_viewLayout = new TQGridLayout ( this , 2 , 0 ) ;
m_viewLayout - > setRowStretch ( 0 , 0 ) ;
m_viewLayout - > setRowStretch ( 1 , 1 ) ;
m_viewLayout - > addWidget ( m_toolbarTab , 0 , 0 ) ;
m_viewLayout - > addWidget ( m_documentArea , 1 , 0 ) ;
m_documentArea - > show ( ) ;
setAcceptDrops ( true ) ; // [MB02] Accept drops on the view
}
QuantaView : : ~ QuantaView ( )
{
// quantaApp is undefined if the destructor of QuantaApp is active
if ( quantaApp )
quantaApp - > slotFileClosed ( m_document ) ;
if ( m_document )
{
m_document - > view ( ) - > reparent ( 0L , 0 , TQPoint ( ) , false ) ;
if ( quantaApp )
emit documentClosed ( m_document - > url ( ) ) ;
}
delete m_document ;
m_document = 0L ;
}
bool QuantaView : : mayRemove ( )
{
emit hidePreview ( ) ;
if ( m_plugin )
{
m_plugin - > unload ( false ) ;
} else
{
bool unmodifiedUntitled = false ;
if ( m_document & & m_document - > isUntitled ( ) & & ! m_document - > isModified ( ) )
unmodifiedUntitled = true ;
if ( m_customWidget )
m_customWidget - > reparent ( 0L , 0 , TQPoint ( ) , false ) ;
if ( ! saveModified ( ) )
return false ;
slotSetSourceLayout ( ) ;
if ( static_cast < QuantaView * > ( quantaApp - > activeWindow ( ) ) = = this )
{
parser - > setSAParserEnabled ( false ) ;
kdDebug ( 24000 ) < < " Node objects before delete = " < < NN < < " ; list count = " < < nodes . count ( ) < < endl ;
Node : : deleteNode ( baseNode ) ;
baseNode = 0L ;
kdDebug ( 24000 ) < < " Node objects after delete = " < < NN < < " ; list count = " < < nodes . count ( ) < < endl ;
TQValueList < Node * > nList = nodes ;
/* for (TQValueList<Node*>::ConstIterator it = nList.constBegin(); it != nList.constEnd(); ++it)
Node : : deleteNode ( * it ) ;
kdDebug ( 24000 ) < < " Node objects after cleanup = " < < NN < < " ; list count = " < < nodes . count ( ) < < endl ; */
}
if ( m_document )
{
KURL url = m_document - > url ( ) ;
Project : : ref ( ) - > saveBookmarks ( url , dynamic_cast < KTextEditor : : MarkInterface * > ( m_document - > doc ( ) ) ) ;
if ( ! unmodifiedUntitled )
emit eventHappened ( " before_close " , url . url ( ) , TQString ( ) ) ;
m_currentViewsLayout = - 1 ;
// m_document->closeTempFile();
if ( ! m_document - > isUntitled ( ) & & url . isLocalFile ( ) )
{
fileWatcher - > removeFile ( url . path ( ) ) ;
// kdDebug(24000) << "removeFile[mayRemove]: " << url.path() << endl;
}
Project : : ref ( ) - > saveCursorPosition ( url , dynamic_cast < KTextEditor : : ViewCursorInterface * > ( m_document - > view ( ) ) ) ;
quantaApp - > menuBar ( ) - > activateItemAt ( - 1 ) ;
quantaApp - > guiFactory ( ) - > removeClient ( m_document - > view ( ) ) ;
if ( ! unmodifiedUntitled )
emit eventHappened ( " after_close " , url . url ( ) , TQString ( ) ) ;
}
/* kdDebug(24000) << "Calling reparse from close " << endl;
parser - > setSAParserEnabled ( true ) ;
quantaApp - > reparse ( true ) ; */
}
return true ;
}
void QuantaView : : addDocument ( Document * document )
{
if ( ! document )
return ;
m_document = document ;
connect ( m_document , TQT_SIGNAL ( editorGotFocus ( ) ) , this , TQT_SLOT ( slotSourceGetFocus ( ) ) ) ;
connect ( m_document - > view ( ) , TQT_SIGNAL ( cursorPositionChanged ( ) ) , this , TQT_SIGNAL ( cursorPositionChanged ( ) ) ) ;
m_kafkaDocument = KafkaDocument : : ref ( ) ;
connect ( m_kafkaDocument - > getKafkaWidget ( ) , TQT_SIGNAL ( hasFocus ( bool ) ) ,
this , TQT_SLOT ( slotVPLGetFocus ( bool ) ) ) ;
connect ( m_kafkaDocument , TQT_SIGNAL ( newCursorPosition ( int , int ) ) ,
this , TQT_SLOT ( slotSetCursorPositionInSource ( int , int ) ) ) ;
connect ( m_kafkaDocument , TQT_SIGNAL ( loadingError ( Node * ) ) ,
this , TQT_SLOT ( slotVPLLoadingError ( Node * ) ) ) ;
m_kafkaReloadingEnabled = true ;
m_quantaReloadingEnabled = true ;
m_curCol = m_curLine = m_curOffset = 0 ;
//init the VPL part
m_currentViewsLayout = SourceOnly ; //to correctly reload the timers.
reloadUpdateTimers ( ) ;
m_currentViewsLayout = - 1 ; //force loading of this tqlayout
slotSetSourceLayout ( ) ;
}
void QuantaView : : addPlugin ( QuantaPlugin * plugin )
{
ToolbarTabWidget * m_toolbarTab = ToolbarTabWidget : : ref ( ) ;
m_toolbarTab - > reparent ( 0 , 0 , TQPoint ( ) , false ) ;
m_plugin = plugin ;
m_splitter - > hide ( ) ;
TQWidget * w = m_plugin - > widget ( ) ;
if ( w )
{
w - > reparent ( m_documentArea , 0 , TQPoint ( ) , true ) ;
w - > resize ( m_documentArea - > size ( ) ) ;
}
m_documentArea - > reparent ( this , 0 , TQPoint ( ) , true ) ;
m_viewLayout - > addWidget ( m_documentArea , 1 , 0 ) ;
activated ( ) ;
updateTab ( ) ;
}
void QuantaView : : addCustomWidget ( TQWidget * widget , const TQString & label )
{
if ( widget )
{
ToolbarTabWidget : : ref ( ) - > reparent ( 0 , 0 , TQPoint ( ) , false ) ;
m_customWidget = widget ;
m_splitter - > hide ( ) ;
widget - > reparent ( m_documentArea , 0 , TQPoint ( ) , true ) ;
widget - > resize ( m_documentArea - > size ( ) ) ;
if ( ! label . isEmpty ( ) )
{
widget - > setCaption ( label ) ;
updateTab ( ) ;
}
m_viewLayout - > addWidget ( m_documentArea , 1 , 0 ) ;
m_documentArea - > show ( ) ;
} else
if ( m_customWidget )
{
ToolbarTabWidget : : ref ( ) - > reparent ( this , 0 , TQPoint ( ) , qConfig . enableDTDToolbar ) ;
m_viewLayout - > addWidget ( ToolbarTabWidget : : ref ( ) , 0 , 0 ) ;
m_customWidget = 0L ; //avoid infinite recursion
reloadLayout ( ) ;
}
if ( m_documentArea - > height ( ) + ToolbarTabWidget : : ref ( ) - > height ( ) > height ( ) & & ToolbarTabWidget : : ref ( ) - > isVisible ( ) )
resize ( m_documentArea - > width ( ) , m_documentArea - > height ( ) - ToolbarTabWidget : : ref ( ) - > height ( ) ) ;
else if ( ToolbarTabWidget : : ref ( ) - > isHidden ( ) )
resize ( width ( ) , height ( ) ) ;
}
void QuantaView : : reloadLayout ( )
{
int currentViewsLayout = m_currentViewsLayout ;
m_currentViewsLayout = - 1 ; //force loading of this tqlayout
switch ( currentViewsLayout )
{
case SourceOnly :
slotSetSourceLayout ( ) ;
break ;
case SourceAndVPL :
slotSetSourceAndVPLLayout ( ) ;
break ;
case VPLOnly :
slotSetVPLOnlyLayout ( ) ;
break ;
}
}
void QuantaView : : updateTab ( )
{
if ( qConfig . showCloseButtons = = " ShowAlways " )
{
setIcon ( SmallIcon ( " fileclose " ) ) ;
}
if ( m_document )
{
// try to set the icon from mimetype
TQIconSet mimeIcon ( KMimeType : : pixmapForURL ( m_document - > url ( ) , 0 , KIcon : : Small ) ) ;
if ( mimeIcon . isNull ( ) )
mimeIcon = TQIconSet ( SmallIcon ( " document " ) ) ;
TQString urlStr = QExtFileInfo : : shortName ( m_document - > url ( ) . path ( ) ) ;
if ( m_document - > isModified ( ) )
{
if ( qConfig . showCloseButtons = = " ShowAlways " )
{
setMDICaption ( urlStr + " " + i18n ( " [modified] " ) ) ;
} else
{
setIcon ( SmallIcon ( " filesave " ) ) ;
setMDICaption ( urlStr ) ;
}
m_szCaption = urlStr + " " + i18n ( " [modified] " ) ;
} else
{
if ( qConfig . showCloseButtons ! = " ShowAlways " )
{
setIcon ( mimeIcon . pixmap ( ) ) ;
}
setMDICaption ( urlStr ) ;
quantaApp - > setTabToolTip ( this , m_document - > url ( ) . prettyURL ( 0 , KURL : : StripFileProtocol ) ) ;
}
} else
if ( m_plugin )
{
if ( qConfig . showCloseButtons ! = " ShowAlways " )
{
setIcon ( SmallIcon ( m_plugin - > icon ( ) ) ) ;
}
setMDICaption ( m_plugin - > name ( ) ) ;
} else
if ( m_customWidget )
{
if ( qConfig . showCloseButtons ! = " ShowAlways " )
{
setIcon ( * ( m_customWidget - > icon ( ) ) ) ;
}
setMDICaption ( m_customWidget - > caption ( ) ) ;
}
}
TQString QuantaView : : tabName ( )
{
if ( m_document )
{
return m_document - > url ( ) . fileName ( ) ;
} else
if ( m_plugin )
{
return m_plugin - > name ( ) ;
} else
if ( m_customWidget )
{
return m_customWidget - > caption ( ) ;
} else
return " " ;
}
void QuantaView : : slotSetSourceLayout ( )
{
emit hidePreview ( ) ;
if ( m_currentViewsLayout = = SourceOnly | | ! m_document )
return ;
if ( m_currentViewsLayout = = SourceAndVPL )
m_splitterSizes = m_splitter - > sizes ( ) ;
KToggleAction * ta = ( KToggleAction * ) quantaApp - > actionCollection ( ) - > action ( " show_quanta_editor " ) ;
if ( ta )
ta - > setChecked ( true ) ;
//hide the VPL widget, reload the source if necessary
if ( ( m_currentViewsLayout = = SourceAndVPL & & m_kafkaDocument - > getKafkaWidget ( ) - > view ( ) - > hasFocus ( ) ) | |
m_currentViewsLayout = = VPLOnly )
{
reloadSourceView ( ) ;
}
if ( m_kafkaDocument - > isLoaded ( ) )
m_kafkaDocument - > unloadDocument ( ) ;
//show the document if full size
m_splitter - > hide ( ) ;
m_kafkaDocument - > getKafkaWidget ( ) - > view ( ) - > reparent ( 0 , 0 , TQPoint ( ) , false ) ;
m_document - > view ( ) - > reparent ( m_documentArea , 0 , TQPoint ( ) , true ) ;
m_document - > view ( ) - > resize ( m_documentArea - > size ( ) ) ;
m_viewLayout - > addWidget ( m_documentArea , 1 , 0 ) ;
m_document - > view ( ) - > setFocus ( ) ;
m_currentViewsLayout = SourceOnly ;
//update timers are not needed in source only mode
m_sourceUpdateTimer . stop ( ) ;
m_VPLUpdateTimer . stop ( ) ;
}
void QuantaView : : slotSetSourceAndVPLLayout ( )
{
emit hidePreview ( ) ;
if ( m_currentViewsLayout = = SourceAndVPL | | ! m_document )
return ;
KToggleAction * ta = ( KToggleAction * ) quantaApp - > actionCollection ( ) - > action ( " show_kafka_and_quanta " ) ;
if ( m_document - > defaultDTD ( ) - > name . tqcontains ( " HTML " , false ) = = 0 )
{
KMessageBox : : information ( this , i18n ( " The VPL Mode does not support the current DTD, at the moment: %1 " ) . tqarg ( m_document - > defaultDTD ( ) - > nickName ) ) ;
KToggleAction * ta2 = ( KToggleAction * ) quantaApp - > actionCollection ( ) - > action ( " show_quanta_editor " ) ;
if ( ta2 )
ta2 - > setChecked ( true ) ;
return ;
}
if ( ta )
ta - > setChecked ( true ) ;
if ( ! m_kafkaDocument - > isLoaded ( ) )
m_kafkaDocument - > loadDocument ( m_document ) ;
if ( m_currentViewsLayout = = VPLOnly )
{
reloadSourceView ( ) ;
}
m_kafkaDocument - > getKafkaWidget ( ) - > view ( ) - > reparent ( m_splitter , 0 , TQPoint ( ) , true ) ;
m_splitter - > moveToFirst ( m_kafkaDocument - > getKafkaWidget ( ) - > view ( ) ) ;
m_document - > view ( ) - > reparent ( m_splitter , 0 , TQPoint ( ) , true ) ;
m_viewLayout - > addWidget ( m_splitter , 1 , 0 ) ;
m_splitter - > setSizes ( m_splitterSizes ) ;
m_splitter - > show ( ) ;
if ( m_currentViewsLayout = = SourceOnly & &
( ! baseNode | | ( baseNode - > tag - > type = = Tag : : Empty & &
! baseNode - > next & & ! baseNode - > child ) ) )
{
quantaApp - > documentProperties ( true ) ;
}
m_currentViewsLayout = SourceAndVPL ;
reloadUpdateTimers ( ) ;
}
void QuantaView : : slotSetVPLOnlyLayout ( )
{
emit hidePreview ( ) ;
if ( m_currentViewsLayout = = VPLOnly | | ! m_document )
return ;
if ( m_currentViewsLayout = = SourceAndVPL )
m_splitterSizes = m_splitter - > sizes ( ) ;
KToggleAction * ta = ( KToggleAction * ) quantaApp - > actionCollection ( ) - > action ( " show_kafka_view " ) ;
if ( m_document - > defaultDTD ( ) - > name . tqcontains ( " HTML " , false ) = = 0 )
{
KMessageBox : : information ( this , i18n ( " The VPL Mode does not support the current DTD, at the moment: %1 " ) . tqarg ( m_document - > defaultDTD ( ) - > nickName ) ) ;
KToggleAction * ta2 = ( KToggleAction * ) quantaApp - > actionCollection ( ) - > action ( " show_quanta_editor " ) ;
if ( ta2 )
ta2 - > setChecked ( true ) ;
return ;
}
if ( ta )
ta - > setChecked ( true ) ;
m_splitter - > hide ( ) ;
if ( ! m_kafkaDocument - > isLoaded ( ) )
m_kafkaDocument - > loadDocument ( m_document ) ;
m_kafkaDocument - > getKafkaWidget ( ) - > view ( ) - > reparent ( m_documentArea , 0 , TQPoint ( ) , true ) ;
m_kafkaDocument - > getKafkaWidget ( ) - > view ( ) - > resize ( m_documentArea - > size ( ) ) ;
m_viewLayout - > addWidget ( m_documentArea , 1 , 0 ) ;
m_kafkaDocument - > getKafkaWidget ( ) - > view ( ) - > setFocus ( ) ;
if ( m_currentViewsLayout = = SourceOnly & &
( ! baseNode | | ( baseNode - > tag - > type = = Tag : : Empty & &
! baseNode - > next & & ! baseNode - > child ) ) )
{
quantaApp - > documentProperties ( true ) ;
}
m_currentViewsLayout = VPLOnly ;
//update timers are not needed in VPL only mode
m_sourceUpdateTimer . stop ( ) ;
m_VPLUpdateTimer . stop ( ) ;
}
void QuantaView : : reloadUpdateTimers ( )
{
QuantaView * view = ViewManager : : ref ( ) - > activeView ( ) ;
m_sourceUpdateTimer . stop ( ) ;
m_VPLUpdateTimer . stop ( ) ;
if ( m_kafkaDocument - > isLoaded ( ) & & m_currentViewsLayout = = SourceAndVPL & & view & & view = = this )
{
if ( m_currentFocus = = VPLFocus & & ! qConfig . quantaRefreshOnFocus )
m_sourceUpdateTimer . start ( qConfig . quantaRefreshDelay ) ;
if ( m_currentFocus = = SourceFocus & & ! qConfig . kafkaRefreshOnFocus )
m_VPLUpdateTimer . start ( qConfig . kafkaRefreshDelay ) ;
}
}
void QuantaView : : slotVPLGetFocus ( bool focus )
{
// is Quanta exiting?
if ( ! quantaApp ) return ;
# ifdef LIGHT_DEBUG
kdDebug ( 25001 ) < < " slotVPLGetFocus( " < < focus < < " ) " < < endl ;
# endif
int contentsX , contentsY ;
KAction * action ;
if ( focus )
{
//We reload the kafka part from the Node Tree
if ( m_currentViewsLayout = = SourceAndVPL & & m_currentFocus = = SourceFocus )
{
contentsX = m_kafkaDocument - > getKafkaWidget ( ) - > view ( ) - > contentsX ( ) ;
contentsY = m_kafkaDocument - > getKafkaWidget ( ) - > view ( ) - > contentsY ( ) ;
//Reload the kafka Editor only if Quanta was modified or if something has happened (e.g. a reparse)
//and NEED a kafka reload.
if ( parser - > parsingNeeded ( ) )
baseNode = parser - > rebuild ( m_document ) ;
reloadVPLView ( ) ;
//doesn't work!
m_kafkaDocument - > getKafkaWidget ( ) - > view ( ) - > setContentsPos ( contentsX , contentsY ) ;
}
//We disable some actions which doesn't work on kafka for the moment
action = quantaApp - > actionCollection ( ) - > action ( " tag_edit_table " ) ;
if ( action )
action - > setEnabled ( false ) ;
action = 0L ;
action = quantaApp - > actionCollection ( ) - > action ( " tag_quick_list " ) ;
if ( action )
action - > setEnabled ( false ) ;
action = 0L ;
action = quantaApp - > actionCollection ( ) - > action ( " tag_color " ) ;
if ( action )
action - > setEnabled ( false ) ;
action = 0L ;
action = quantaApp - > actionCollection ( ) - > action ( " tag_mail " ) ;
if ( action )
action - > setEnabled ( false ) ;
action = 0L ;
action = quantaApp - > actionCollection ( ) - > action ( " tag_misc " ) ;
if ( action )
action - > setEnabled ( false ) ;
action = 0L ;
action = quantaApp - > actionCollection ( ) - > action ( " tag_frame_wizard " ) ;
if ( action )
action - > setEnabled ( false ) ;
action = 0L ;
action = quantaApp - > actionCollection ( ) - > action ( " insert_css " ) ;
if ( action )
action - > setEnabled ( false ) ;
action = 0L ;
action = quantaApp - > actionCollection ( ) - > action ( " insert_char " ) ;
if ( action )
action - > setEnabled ( false ) ;
//TEMPORARY: Enable VPL undo/redo logging
m_document - > docUndoRedo - > turnOn ( true ) ;
m_currentFocus = VPLFocus ;
reloadUpdateTimers ( ) ;
}
}
void QuantaView : : slotSourceGetFocus ( )
{
// is Quanta exiting?
if ( ! quantaApp ) return ;
# ifdef LIGHT_DEBUG
kdDebug ( 25001 ) < < " slotSourceGetFocus(true) " < < endl ;
# endif
KAction * action ;
quantaApp - > partManager ( ) - > setActivePart ( m_document - > doc ( ) , m_document - > view ( ) ) ;
//We reload the quanta view from the Node Tree.
if ( m_currentViewsLayout = = SourceAndVPL & & m_currentFocus = = VPLFocus )
{
reloadSourceView ( ) ;
//FIXME: the tree (and the output)is right, the pos aren't.
//This will reparse the whole Node tree and reload kafka.
baseNode = parser - > parse ( m_document ) ;
}
m_currentFocus = SourceFocus ;
reloadUpdateTimers ( ) ;
//We enable some actions which doesn't work on kafka for the moment
action = quantaApp - > actionCollection ( ) - > action ( " tag_edit_table " ) ;
if ( action )
action - > setEnabled ( true ) ;
action = 0L ;
action = quantaApp - > actionCollection ( ) - > action ( " tag_quick_list " ) ;
if ( action )
action - > setEnabled ( true ) ;
action = 0L ;
action = quantaApp - > actionCollection ( ) - > action ( " tag_color " ) ;
if ( action )
action - > setEnabled ( true ) ;
action = 0L ;
action = quantaApp - > actionCollection ( ) - > action ( " tag_mail " ) ;
if ( action )
action - > setEnabled ( true ) ;
action = 0L ;
action = quantaApp - > actionCollection ( ) - > action ( " tag_misc " ) ;
if ( action )
action - > setEnabled ( true ) ;
action = 0L ;
action = quantaApp - > actionCollection ( ) - > action ( " tag_frame_wizard " ) ;
if ( action )
action - > setEnabled ( true ) ;
action = 0L ;
action = quantaApp - > actionCollection ( ) - > action ( " insert_css " ) ;
if ( action )
action - > setEnabled ( true ) ;
action = 0L ;
action = quantaApp - > actionCollection ( ) - > action ( " insert_char " ) ;
if ( action )
action - > setEnabled ( true ) ;
//TEMPORARY: Disable VPL undo/redo logging
m_document - > docUndoRedo - > turnOn ( false ) ;
}
/** Reloads both views ONLY when changes have been made to the Node tree ONLY. */
void QuantaView : : reloadBothViews ( bool force )
{
reloadSourceView ( force ) ;
reloadVPLView ( force ) ;
}
/** reload the Kafka view from the Node Tree. Set force to true if you want to reload even if not necessary. */
void QuantaView : : reloadVPLView ( bool force )
{
if ( m_document & & ( m_kafkaReloadingEnabled | | force ) )
m_document - > docUndoRedo - > reloadKafkaEditor ( force ) ;
}
/** reload the Quanta view from the Node Tree. Set force to true if you want to reload even if not necessary. */
void QuantaView : : reloadSourceView ( bool force )
{
if ( m_quantaReloadingEnabled | | force )
m_document - > docUndoRedo - > reloadQuantaEditor ( force ) ;
}
void QuantaView : : VPLUpdateTimerTimeout ( )
{
if ( quantaApp & & m_currentFocus = = SourceFocus )
reloadVPLView ( ) ;
}
void QuantaView : : sourceUpdateTimerTimeout ( )
{
if ( quantaApp & & m_currentFocus = = VPLFocus )
reloadSourceView ( ) ;
}
void QuantaView : : slotVPLLoadingError ( Node * )
{
emit showProblemsView ( ) ;
}
void QuantaView : : slotSetCursorPositionInSource ( int col , int line )
{
m_curCol = col ;
m_curLine = line ;
if ( m_currentViewsLayout = = SourceAndVPL | | m_currentViewsLayout = = SourceOnly )
m_document - > viewCursorIf - > setCursorPositionReal ( line , col ) ;
}
void QuantaView : : dragEnterEvent ( TQDragEnterEvent * e )
{
e - > accept ( KURLDrag : : canDecode ( e ) ) ;
}
void QuantaView : : dropEvent ( TQDropEvent * e )
{
emit dragInsert ( e ) ;
}
void QuantaView : : resizeEvent ( TQResizeEvent * e )
{
TQWidget : : resizeEvent ( e ) ;
resize ( m_documentArea - > width ( ) , m_documentArea - > height ( ) ) ;
}
void QuantaView : : resize ( int width , int height )
{
if ( m_plugin & & m_plugin - > widget ( ) )
{
m_plugin - > widget ( ) - > resize ( width , height ) ;
return ;
} else
if ( m_customWidget )
{
m_customWidget - > resize ( width , height ) ;
return ;
} else
if ( ! m_document )
return ;
if ( m_currentViewsLayout = = SourceOnly )
m_document - > view ( ) - > resize ( width , height ) ;
else
if ( m_currentViewsLayout = = VPLOnly )
m_kafkaDocument - > getKafkaWidget ( ) - > view ( ) - > resize ( width , height ) ;
else
if ( m_currentViewsLayout = = SourceAndVPL )
{
m_splitter - > resize ( width , height ) ;
m_splitterSizes = m_splitter - > sizes ( ) ;
}
}
void QuantaView : : insertTag ( const char * tag )
{
if ( ! m_document )
return ;
TQString tagStr = QuantaCommon : : tagCase ( tag ) ;
const DTDStruct * dtd = m_document - > currentDTD ( true ) ;
bool single = QuantaCommon : : isSingleTag ( dtd - > name , tagStr ) ;
bool optional = QuantaCommon : : isOptionalTag ( dtd - > name , tagStr ) ;
TQString startTag = tagStr ;
startTag . prepend ( " < " ) ;
if ( dtd - > singleTagStyle = = " xml " & &
( single | | ( optional & & ! qConfig . closeOptionalTags ) )
)
{
startTag . append ( " / " ) ;
}
startTag . append ( " > " ) ;
if ( ( qConfig . closeTags & & ! single & & ! optional ) | |
( qConfig . closeOptionalTags & & optional ) )
{
m_document - > insertTag ( startTag , TQString ( " </ " ) + tagStr + " > " ) ;
}
else
{
m_document - > insertTag ( startTag ) ;
}
}
//FIXME: Move out from here??
/** Insert a new tag by bringing up the TagDialog. */
void QuantaView : : insertNewTag ( const TQString & tag , const TQString & attr , bool insertInLine )
{
if ( m_document )
{
if ( m_currentFocus = = QuantaView : : VPLFocus | |
( m_currentFocus = = QuantaView : : SourceFocus & & qConfig . smartTagInsertion ) )
insertOutputInTheNodeTree ( " " , " " , quantaApp - > showTagDialogAndReturnNode ( tag , attr ) ) ;
else
{
TQString selection ;
if ( m_document - > selectionIf )
selection = m_document - > selectionIf - > selection ( ) ;
TagDialog * dlg = new TagDialog ( QuantaCommon : : tagFromDTD ( m_document - > getDTDIdentifier ( ) , tag ) , selection , attr , baseURL ( ) ) ;
if ( dlg - > exec ( ) )
{
dlg - > insertTag ( m_document , insertInLine ) ;
}
delete dlg ;
}
}
}
void QuantaView : : insertOutputInTheNodeTree ( const TQString & str1 , const TQString & str2 , Node * node )
{
if ( ! m_document )
return ;
# ifdef LIGHT_DEBUG
if ( node )
kdDebug ( 25001 ) < < " QuantaView::insertOutputInTheNodeTree() - node : " < < node - > tag - > name < <
" - type : " < < node - > tag - > type < < endl ;
else
kdDebug ( 25001 ) < < " QuantaView::insertOutputInTheNodeTree() - str1 : " < < str1 < <
" - str2 : " < < str2 < < endl ;
# endif
KafkaWidget * kafkaPart = m_kafkaDocument - > getKafkaWidget ( ) ;
NodeModifsSet * modifs ;
DOM : : Node domNode , domStartContainer , domEndContainer ;
TQString tagName ;
TQTag * nodeTQTag , * qTag , * nodeParentTQTag ;
Node * nodeCursor , * startContainer , * endContainer , * nodeParent , * dummy ;
TQPtrList < TQTag > qTagList ;
int startCol , startLine , endCol , endLine ;
bool specialTagInsertion = false ;
long nodeOffset , startOffset , endOffset , domNodeOffset ;
TQValueList < int > loc ;
uint line , col ;
bool smartTagInsertion , hasSelection , nodeTreeModified ;
if ( ! node & & str1 . isEmpty ( ) | | node & & ! str1 . isEmpty ( ) )
return ;
//Three cases :
//- Tag insertion in VPL
//- Normal tag insertion in kate
//- Smart tag insertion in kate
smartTagInsertion = ( m_currentFocus = = QuantaView : : SourceFocus & & qConfig . smartTagInsertion ) ;
if ( m_currentFocus = = QuantaView : : VPLFocus | | smartTagInsertion )
{
modifs = new NodeModifsSet ( ) ;
if ( ! node & & ! str1 . isEmpty ( ) )
{
//We build the node from the str1
node = kafkaCommon : : createNode ( " " , " " , Tag : : XmlTag , m_document ) ;
node - > tag - > parse ( str1 , m_document ) ;
node - > tag - > name = QuantaCommon : : tagCase ( node - > tag - > name ) ;
node - > tag - > single = QuantaCommon : : isSingleTag ( m_document - > defaultDTD ( ) - > name ,
node - > tag - > name ) ;
}
if ( m_currentFocus = = QuantaView : : VPLFocus )
{
kafkaPart - > getCurrentNode ( domNode , domNodeOffset ) ;
nodeCursor = m_kafkaDocument - > getNode ( domNode ) ;
}
else
{
m_document - > viewCursorIf - > cursorPositionReal ( & line , & col ) ;
nodeCursor = parser - > nodeAt ( line , col , false ) ;
}
if ( ! nodeCursor )
return ;
nodeParent = nodeCursor ;
if ( nodeParent - > tag - > type = = Tag : : Text )
nodeParent = nodeParent - > tqparent ;
//Checking if at least one tqparent of node can have a Text Node as child, otherwise
//it is impossible for the
//user to add this node. In that case, try to insert the Node in the closest tqparent accepting it.
//e.g. TR : a normal insertion would require to have the caret in the TABLE Node, but it is
//impossible
nodeTQTag = QuantaCommon : : tagFromDTD ( m_document - > defaultDTD ( ) ,
node - > tag - > name ) ;
if ( ! nodeTQTag )
return ;
qTagList = nodeTQTag - > parents ( ) ;
# ifdef HEAVY_DEBUG
kdDebug ( 25001 ) < < " nodeTQTag name : " < < nodeTQTag - > name ( ) < < endl ;
/**kdDebug(25001)<< nodeTQTag->isChild("#text", false) << endl;
kdDebug ( 25001 ) < < nodeTQTag - > isChild ( " #text " , true ) < < endl ; */
# endif
for ( qTag = qTagList . first ( ) ; qTag ; qTag = qTagList . next ( ) )
{
if ( qTag - > isChild ( " #text " , false ) )
break ;
if ( qTag = = qTagList . getLast ( ) )
specialTagInsertion = true ;
}
if ( m_currentFocus = = QuantaView : : VPLFocus )
{
m_kafkaDocument - > translateKafkaIntoNodeCursorPosition ( domNode , domNodeOffset , & dummy , nodeOffset ) ;
kafkaPart - > selection ( domStartContainer , startOffset , domEndContainer , endOffset ) ;
m_kafkaDocument - > translateKafkaIntoNodeCursorPosition ( domStartContainer , startOffset ,
& startContainer , startOffset ) ;
m_kafkaDocument - > translateKafkaIntoNodeCursorPosition ( domEndContainer , endOffset ,
& endContainer , endOffset ) ;
hasSelection = kafkaPart - > hasSelection ( ) ;
}
else
if ( m_document - > selectionIfExt )
{
m_kafkaDocument - > translateQuantaIntoNodeCursorPosition ( line , col , & dummy , nodeOffset ) ;
startCol = m_document - > selectionIfExt - > selStartCol ( ) ;
startLine = m_document - > selectionIfExt - > selStartLine ( ) ;
endCol = m_document - > selectionIfExt - > selEndCol ( ) ;
endLine = m_document - > selectionIfExt - > selEndLine ( ) ;
m_kafkaDocument - > translateQuantaIntoNodeCursorPosition ( ( unsigned ) startLine , ( unsigned ) startCol ,
& startContainer , startOffset ) ;
m_kafkaDocument - > translateQuantaIntoNodeCursorPosition ( ( unsigned ) endLine , ( unsigned ) endCol ,
& endContainer , endOffset ) ;
hasSelection = m_document - > selectionIf - > hasSelection ( ) ;
if ( startContainer = = endContainer & & startContainer - > tag - > type = = Tag : : Empty )
{
hasSelection = false ;
}
if ( endContainer & & endContainer - > tag - > type = = Tag : : XmlTag & & endOffset < ( signed ) endContainer - > tag - > tagStr ( ) . length ( ) )
{
endContainer = endContainer - > previousSibling ( ) ;
endOffset = ( endContainer ) ? endContainer - > tag - > tagStr ( ) . length ( ) : 0 ;
}
/**else
{
if ( startContainer & & startContainer - > tag - > type = = Tag : : Empty )
startContainer = startContainer - > nextNE ( ) ;
if ( endContainer & & endContainer - > tag - > type = = Tag : : Empty )
endContainer = endContainer - > prevNE ( ) ;
} */
}
nodeTreeModified = false ;
if ( specialTagInsertion )
{
//let's try to insert this node in the closest tqparent accepting it.
while ( nodeParent )
{
nodeParentTQTag =
QuantaCommon : : tagFromDTD ( m_document - > defaultDTD ( ) ,
nodeParent - > tag - > name ) ;
if ( nodeParentTQTag & & nodeParentTQTag - > isChild ( node ) )
{
nodeCursor = kafkaCommon : : createMandatoryNodeSubtree ( node ,
m_document ) ;
nodeOffset = 0 ;
kafkaCommon : : insertNodeSubtree ( node , nodeParent , 0L , 0L , modifs ) ;
nodeTreeModified = true ;
break ;
}
nodeParent = nodeParent - > tqparent ;
}
}
else if ( hasSelection & & ! nodeTQTag - > isSingle ( ) )
{
//If some text is selected in kafka, surround the selection with the new Node.
if ( ! startContainer | | ! endContainer )
return ;
nodeTreeModified = kafkaCommon : : DTDinsertRemoveNode ( node , startContainer , ( int ) startOffset ,
endContainer , ( int ) endOffset , m_document , & nodeCursor ,
nodeOffset , modifs ) ;
}
else
{
//Nothing is selected, simply inserting the Node if it is not an inline.
/* if(!kafkaCommon::isInline(node->tag->name) || nodeTQTag->isSingle())
{ */
nodeTreeModified = kafkaCommon : : DTDinsertRemoveNode ( node , nodeCursor , ( int ) nodeOffset , nodeCursor ,
( int ) nodeOffset , m_document , & nodeCursor , nodeOffset , modifs ) ;
// }
}
m_document - > docUndoRedo - > addNewModifsSet ( modifs , undoRedo : : NodeTreeModif ) ;
if ( m_currentFocus = = QuantaView : : VPLFocus )
{
//view->reloadVPLView();
//Now update the VPL cursor position
m_kafkaDocument - > translateNodeIntoKafkaCursorPosition ( nodeCursor , nodeOffset , domNode ,
domNodeOffset ) ;
if ( ! domNode . isNull ( ) & & domNode . nodeType ( ) ! = DOM : : Node : : TEXT_NODE & &
! domNode . firstChild ( ) . isNull ( ) & & domNode . firstChild ( ) . nodeType ( ) = =
DOM : : Node : : TEXT_NODE )
domNode = domNode . firstChild ( ) ;
if ( ! domNode . isNull ( ) )
kafkaPart - > setCurrentNode ( domNode , domNodeOffset ) ;
}
else
{
//view->reloadSourceView();
//Now update the source cursor position
m_kafkaDocument - > translateNodeIntoQuantaCursorPosition ( nodeCursor , nodeOffset , line , col ) ;
m_document - > viewCursorIf - > setCursorPositionReal ( line , col ) ;
}
if ( ! nodeTreeModified )
quantaApp - > slotStatusMsg ( i18n ( " Cannot insert the tag: invalid location. " ) ) ;
}
else
{
m_document - > insertTag ( str1 , str2 ) ;
}
}
/** Returns the baseURL of the document. */
KURL QuantaView : : baseURL ( )
{
KURL base ;
if ( m_document & & ! m_document - > isUntitled ( ) )
{
base = QuantaCommon : : convertToPath ( m_document - > url ( ) ) ;
} else
{
base = Project : : ref ( ) - > projectBaseURL ( ) ;
}
return base ;
}
void QuantaView : : refreshWindow ( )
{
if ( ! m_document )
{
if ( m_plugin )
quantaApp - > partManager ( ) - > setActivePart ( m_plugin - > part ( ) , m_plugin - > widget ( ) ) ;
resize ( width ( ) , height ( ) ) ;
} else
{
/*
kdDebug ( 24000 ) < < " m_documentArea->height(): " < < m_documentArea - > height ( ) < < endl ;
kdDebug ( 24000 ) < < " ToolbarTabWidget::ref()->height(): " < < ToolbarTabWidget : : ref ( ) - > height ( ) < < " hidden: " < < ToolbarTabWidget : : ref ( ) - > isHidden ( ) < < " visible: " < < ToolbarTabWidget : : ref ( ) - > isVisible ( ) < < endl ;
kdDebug ( 24000 ) < < " sum: " < < m_documentArea - > height ( ) + ToolbarTabWidget : : ref ( ) - > height ( ) < < endl ;
kdDebug ( 24000 ) < < " height(): " < < height ( ) < < endl ;
*/
if ( m_documentArea - > height ( ) + ToolbarTabWidget : : ref ( ) - > height ( ) - 1 > height ( ) & & ! ToolbarTabWidget : : ref ( ) - > isHidden ( ) ) //don't use isVisible alone instead of isHidden!
resize ( m_documentArea - > width ( ) , m_documentArea - > height ( ) - ToolbarTabWidget : : ref ( ) - > height ( ) ) ;
else if ( ToolbarTabWidget : : ref ( ) - > isHidden ( ) )
resize ( width ( ) , height ( ) ) ;
}
}
void QuantaView : : activated ( )
{
if ( ! m_document )
{
parser - > setSAParserEnabled ( false ) ;
quantaApp - > slotReloadStructTreeView ( ) ;
refreshWindow ( ) ;
return ;
}
ToolbarTabWidget : : ref ( ) - > reparent ( this , 0 , TQPoint ( ) , qConfig . enableDTDToolbar ) ;
m_viewLayout - > addWidget ( ToolbarTabWidget : : ref ( ) , 0 , 0 ) ;
quantaApp - > partManager ( ) - > setActivePart ( m_document - > doc ( ) , m_document - > view ( ) ) ;
m_document - > checkDirtytqStatus ( ) ;
StructTreeView : : ref ( ) - > useOpenLevelSetting = true ;
quantaApp - > slotLoadToolbarForDTD ( m_document - > getDTDIdentifier ( ) ) ;
//TEMP : If the activated document is not a (X)HTML document, disable smartTagInsertion
//Will be removed when VPL will support every DTD
KAction * action = quantaApp - > actionCollection ( ) - > action ( " smart_tag_insertion " ) ;
if ( action & & m_document - > defaultDTD ( ) - > name . tqcontains ( " HTML " , false ) = = 0 )
{
qConfig . smartTagInsertion = false ;
( static_cast < KToggleAction * > ( action ) ) - > setChecked ( false ) ;
}
reloadLayout ( ) ;
refreshWindow ( ) ;
}
void QuantaView : : deactivated ( )
{
if ( m_plugin )
{
quantaApp - > statusBar ( ) - > changeItem ( " " , IDS_STATUS ) ;
}
m_sourceUpdateTimer . stop ( ) ;
m_VPLUpdateTimer . stop ( ) ;
}
bool QuantaView : : saveModified ( bool ask )
{
if ( ! m_document )
return true ;
bool completed = true ;
TQString fileName = m_document - > url ( ) . fileName ( ) ;
if ( m_document - > isModified ( ) )
{
if ( m_currentFocus = = VPLFocus )
reloadSourceView ( ) ;
int want_save ;
if ( ask )
want_save = KMessageBox : : warningYesNoCancel ( this ,
i18n ( " The file \" %1 \" has been modified. \n Do you want to save it? " ) . tqarg ( fileName ) ,
i18n ( " Warning " ) , KStdGuiItem : : save ( ) , KStdGuiItem : : discard ( ) ) ;
else
want_save = KMessageBox : : Yes ;
switch ( want_save )
{
case KMessageBox : : Yes :
if ( m_document - > isUntitled ( ) )
{
completed = quantaApp - > slotFileSaveAs ( this ) ;
}
else
{
completed = saveDocument ( m_document - > url ( ) ) ;
} ;
break ;
case KMessageBox : : No :
{
m_document - > removeBackup ( quantaApp - > config ( ) ) ;
completed = true ;
}
break ;
case KMessageBox : : Cancel :
completed = false ;
break ;
default :
completed = false ;
break ;
}
} else
m_document - > removeBackup ( quantaApp - > config ( ) ) ;
return completed ;
}
bool QuantaView : : saveDocument ( const KURL & url )
{
if ( url . isEmpty ( ) )
return false ;
emit eventHappened ( " before_save " , url . url ( ) , TQString ( ) ) ;
m_saveResult = true ;
KURL oldURL = m_document - > url ( ) ;
if ( ! m_document - > isUntitled ( ) & & oldURL . isLocalFile ( ) )
{
fileWatcher - > removeFile ( oldURL . path ( ) ) ;
// kdDebug(24000) << "removeFile[saveDocument]: " << oldURL.path() << endl;
}
if ( url . isLocalFile ( ) )
{
if ( ! m_document - > saveAs ( url ) )
{
fileWatcher - > addFile ( oldURL . path ( ) ) ;
// kdDebug(24000) << "addFile[saveDocument]: " << oldURL.path() << endl;
return false ; //saving to a local file failed
} else //successful saving to a local file
{
m_document - > setDirtytqStatus ( false ) ;
m_document - > removeBackup ( quantaApp - > config ( ) ) ;
fileWatcher - > addFile ( m_document - > url ( ) . path ( ) ) ;
// kdDebug(24000) << "addFile[saveDocument, 2]: " << m_document->url().path() << endl;
}
} else //saving to a remote file
{
KTextEditor : : Document * doc = m_document - > doc ( ) ;
m_eventLoopStarted = false ;
connect ( doc , TQT_SIGNAL ( canceled ( const TQString & ) ) , this , TQT_SLOT ( slotSavingFailed ( const TQString & ) ) ) ;
connect ( doc , TQT_SIGNAL ( completed ( ) ) , this , TQT_SLOT ( slotSavingCompleted ( ) ) ) ;
m_saveResult = m_document - > saveAs ( url ) ;
if ( m_saveResult )
{
//start an event loop and wait until the saving finished
QExtFileInfo internalFileInfo ;
m_eventLoopStarted = true ;
internalFileInfo . enter_loop ( ) ;
}
disconnect ( doc , TQT_SIGNAL ( canceled ( const TQString & ) ) , this , TQT_SLOT ( slotSavingFailed ( const TQString & ) ) ) ;
disconnect ( doc , TQT_SIGNAL ( completed ( ) ) , this , TQT_SLOT ( slotSavingCompleted ( ) ) ) ;
if ( ! m_saveResult ) //there was an error while saving
{
if ( oldURL . isLocalFile ( ) )
{
fileWatcher - > addFile ( oldURL . path ( ) ) ;
// kdDebug(24000) << "addFile[saveDocument, 3]: " << oldURL.path() << endl;
}
return false ;
}
}
// everything went fine
if ( oldURL ! = m_document - > url ( ) )
{
setCaption ( m_document - > url ( ) . fileName ( ) ) ;
}
emit eventHappened ( " after_save " , m_document - > url ( ) . url ( ) , TQString ( ) ) ;
return true ;
}
void QuantaView : : slotSavingFailed ( const TQString & error )
{
Q_UNUSED ( error ) ;
m_saveResult = false ;
if ( m_eventLoopStarted )
tqApp - > exit_loop ( ) ;
}
void QuantaView : : slotSavingCompleted ( )
{
m_saveResult = true ;
m_document - > setDirtytqStatus ( false ) ;
m_document - > removeBackup ( quantaApp - > config ( ) ) ;
if ( m_eventLoopStarted )
tqApp - > exit_loop ( ) ;
}
# include "quantaview.moc"