summaryrefslogtreecommitdiffstats
path: root/src/textdocument.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/textdocument.cpp')
-rw-r--r--src/textdocument.cpp1146
1 files changed, 1146 insertions, 0 deletions
diff --git a/src/textdocument.cpp b/src/textdocument.cpp
new file mode 100644
index 0000000..ba03c04
--- /dev/null
+++ b/src/textdocument.cpp
@@ -0,0 +1,1146 @@
+/***************************************************************************
+ * Copyright (C) 2005 by David Saxton *
+ * *
+ * 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 "asmformatter.h"
+#include "asminfo.h"
+#include "asmparser.h"
+#include "debugmanager.h"
+#include "docmanager.h"
+#include "documentiface.h"
+#include "filemetainfo.h"
+#include "gpsimprocessor.h"
+#include "ktechlab.h"
+#include "language.h"
+#include "languagemanager.h"
+#include "microselectwidget.h"
+#include "programmerdlg.h"
+#include "symbolviewer.h"
+#include "textdocument.h"
+#include "textview.h"
+
+// #include <kate/katedocument.h>
+
+#include <kdebug.h>
+#include <klibloader.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <ktempfile.h>
+
+
+TextDocument *TextDocument::constructTextDocument( const QString& caption, KTechlab *parent, const char *name )
+{
+ TextDocument *textDocument = new TextDocument( caption, parent, name);
+ if( textDocument->m_constructorSuccessful )
+ return textDocument;
+ delete textDocument;
+ return 0L;
+}
+
+
+TextDocument::TextDocument( const QString &caption, KTechlab *ktechlab, const char *name )
+ : Document( caption, ktechlab, name ),
+ m_doc(0)
+{
+ m_constructorSuccessful = false;
+
+#ifndef NO_GPSIM
+ m_bOwnDebugger = false;
+ b_lockSyncBreakpoints = false;
+ m_lastDebugLineAt = -1;
+ m_pDebugger = 0l;
+#endif
+
+ m_pLastTextOutputTarget = 0l;
+ m_guessedCodeType = TextDocument::ct_unknown;
+ m_type = Document::dt_text;
+ m_bookmarkActions.setAutoDelete(true);
+ m_pDocumentIface = new TextDocumentIface(this);
+
+ KLibFactory *factory = KLibLoader::self()->factory("libkatepart");
+ if(!factory)
+ {
+ KMessageBox::sorry( ktechlab, i18n("Libkatepart not available for constructing editor") );
+ return;
+ }
+ m_doc = (Kate::Document*)(KTextEditor::Document *)factory->create( 0L, "kate", "KTextEditor::Document");
+
+ guessScheme();
+
+ connect( m_doc, SIGNAL(undoChanged()), this, SIGNAL(undoRedoStateChanged()) );
+ connect( m_doc, SIGNAL(undoChanged()), this, SLOT(slotSyncModifiedStates()) );
+ connect( m_doc, SIGNAL(textChanged()), this, SLOT(slotSyncModifiedStates()) );
+ connect( m_doc, SIGNAL(marksChanged()), this, SLOT(slotUpdateMarksInfo()) );
+ connect( m_doc, SIGNAL(selectionChanged()), this, SLOT(slotSelectionmChanged()) );
+
+ m_doc->setDescription((KTextEditor::MarkInterface::MarkTypes)Breakpoint, i18n("Breakpoint"));
+ m_doc->setPixmap((KTextEditor::MarkInterface::MarkTypes)Breakpoint, *inactiveBreakpointPixmap());
+ m_doc->setPixmap((KTextEditor::MarkInterface::MarkTypes)ActiveBreakpoint, *activeBreakpointPixmap());
+ m_doc->setPixmap((KTextEditor::MarkInterface::MarkTypes)ReachedBreakpoint, *reachedBreakpointPixmap());
+ m_doc->setPixmap((KTextEditor::MarkInterface::MarkTypes)DisabledBreakpoint, *disabledBreakpointPixmap());
+ m_doc->setPixmap((KTextEditor::MarkInterface::MarkTypes)ExecutionPoint, *executionPointPixmap());
+ m_doc->setMarksUserChangable( Bookmark | Breakpoint );
+
+ m_constructorSuccessful = true;
+}
+
+
+TextDocument::~TextDocument()
+{
+ if( !m_constructorSuccessful )
+ return;
+
+ debugStop();
+
+ ViewList::iterator end = m_viewList.end();
+ for ( ViewList::iterator it = m_viewList.begin(); it != end; ++it )
+ {
+ if ( TextView * tv = dynamic_cast<TextView*>( (View*)*it) )
+ {
+ Kate::View * kv = tv->kateView();
+ p_ktechlab->factory()->removeClient( kv );
+ }
+ }
+
+ delete m_doc;
+ m_doc = 0l;
+
+ delete m_pDocumentIface;
+ m_pDocumentIface = 0l;
+}
+
+
+bool TextDocument::fileClose()
+{
+ const QString path = url().prettyURL();
+ if ( !path.isEmpty() )
+ fileMetaInfo()->grabMetaInfo( path, this );
+
+ return Document::fileClose();
+}
+
+
+TextView* TextDocument::textView() const
+{
+ return static_cast<TextView*>(activeView());
+}
+
+
+View * TextDocument::createView( ViewContainer *viewContainer, uint viewAreaId, const char *name )
+{
+ TextView * textView = new TextView( this, viewContainer, viewAreaId, name );
+
+ fileMetaInfo()->initializeFromMetaInfo( url().prettyURL(), textView );
+
+ handleNewView(textView);
+ return textView;
+}
+
+
+Kate::View* TextDocument::createKateView( QWidget *parent, const char *name )
+{
+ return static_cast<Kate::View*>((m_doc->createView( parent, name ))->qt_cast("Kate::View"));
+}
+
+
+void TextDocument::cut()
+{
+ if (textView())
+ textView()->cut();
+}
+void TextDocument::copy()
+{
+ if (textView())
+ textView()->copy();
+}
+void TextDocument::paste()
+{
+ if (textView())
+ textView()->paste();
+}
+
+
+void TextDocument::setText( const QString & text, bool asInitial )
+{
+ if ( asInitial )
+ {
+ disconnect( m_doc, SIGNAL(undoChanged()), this, SIGNAL(undoRedoStateChanged()) );
+ disconnect( m_doc, SIGNAL(undoChanged()), this, SLOT(slotSyncModifiedStates()) );
+ disconnect( m_doc, SIGNAL(textChanged()), this, SLOT(slotSyncModifiedStates()) );
+ }
+
+ const ViewList::iterator end = m_viewList.end();
+ for ( ViewList::iterator it = m_viewList.begin(); it != end; ++it )
+ (static_cast<TextView*>((View*)*it))->saveCursorPosition();
+
+ m_doc->setText(text);
+
+ for ( ViewList::iterator it = m_viewList.begin(); it != end; ++it )
+ (static_cast<TextView*>((View*)*it))->restoreCursorPosition();
+
+ if ( asInitial )
+ {
+ m_doc->clearUndo();
+ m_doc->clearRedo();
+ setModified(false);
+
+ connect( m_doc, SIGNAL(undoChanged()), this, SIGNAL(undoRedoStateChanged()) );
+ connect( m_doc, SIGNAL(undoChanged()), this, SLOT(slotSyncModifiedStates()) );
+ connect( m_doc, SIGNAL(textChanged()), this, SLOT(slotSyncModifiedStates()) );
+ }
+}
+
+
+void TextDocument::undo()
+{
+ m_doc->undo();
+ slotSyncModifiedStates();
+}
+
+
+void TextDocument::redo()
+{
+ m_doc->redo();
+ slotSyncModifiedStates();
+}
+
+
+void TextDocument::slotSyncModifiedStates()
+{
+ setModified( m_doc->isModified() );
+}
+void TextDocument::setModified( bool modified )
+{
+ if ( (modified == b_modified) && (modified == isModified()) ) {
+ return;
+ }
+ m_doc->setModified(modified);
+ b_modified = modified;
+
+ emit modifiedStateChanged();
+}
+
+
+void TextDocument::guessScheme( bool allowDisable )
+{
+ // And specific file actions depending on the current type of file
+ QString fileName = url().fileName();
+ QString extension = fileName.right( fileName.length() - fileName.findRev('.') - 1 );
+
+ if ( extension == "asm" || extension == "src" || extension == "inc" )
+ slotInitLanguage(ct_asm);
+
+ else if ( extension == "hex" )
+ slotInitLanguage(ct_hex);
+
+ else if ( extension == "basic" || extension == "microbe" )
+ slotInitLanguage(ct_microbe);
+
+ else if ( extension == "c" )
+ slotInitLanguage(ct_c);
+
+ else if ( m_guessedCodeType != TextDocument::ct_unknown )
+ slotInitLanguage(m_guessedCodeType);
+
+ else if ( allowDisable && activeView() )
+ textView()->disableActions();
+}
+
+
+void TextDocument::slotInitLanguage( CodeType type )
+{
+ QString hlName;
+
+ switch (type)
+ {
+ case ct_asm:
+ hlName = "PicAsm";
+ break;
+
+ case ct_c:
+ hlName = "C";
+ break;
+
+ case ct_hex:
+ break;
+
+ case ct_microbe:
+ hlName = "Microbe";
+ break;
+
+ case ct_unknown:
+ break;
+ }
+
+ if ( !hlName.isEmpty() )
+ {
+ int i = 0;
+ int hlModeCount = m_doc->hlModeCount();
+ while ( i<hlModeCount && m_doc->hlModeName(i) != hlName )
+ i++;
+
+ m_doc->setHlMode(i);
+ }
+
+ m_guessedCodeType = type;
+
+ ViewList::iterator end = m_viewList.end();
+ for ( ViewList::iterator it = m_viewList.begin(); it != end; ++it )
+ {
+ if ( TextView * tv = dynamic_cast<TextView*>( (View*)*it ) )
+ tv->initCodeActions();
+ }
+}
+
+
+void TextDocument::formatAssembly()
+{
+ AsmFormatter formatter;
+ QStringList lines = QStringList::split( "\n", m_doc->text(), true );
+ setText( formatter.tidyAsm(lines), false );
+ setModified(true);
+}
+
+
+void TextDocument::fileSave( const KURL& url )
+{
+ if ( m_doc->url().path() != url.path() )
+ {
+ kdError() << k_funcinfo << "Error: Kate::View url and passed url do not match; cannot save." << endl;
+ return;
+ }
+
+ if ( activeView() && (textView()->save() == Kate::View::SAVE_OK ) )
+ saveDone();
+}
+
+
+void TextDocument::fileSaveAs()
+{
+ if ( activeView() && (textView()->saveAs() == Kate::View::SAVE_OK) )
+ saveDone();
+
+ // Our modified state may not have changed, but we emit this to force the
+ // main window to update our caption.
+ emit modifiedStateChanged();
+}
+
+
+void TextDocument::saveDone()
+{
+ setURL( m_doc->url() );
+ guessScheme(false);
+ setModified(false);
+ emit modifiedStateChanged();
+}
+
+
+bool TextDocument::openURL( const KURL& url )
+{
+ m_doc->openURL(url);
+ setURL(url);
+
+ fileMetaInfo()->initializeFromMetaInfo( url.prettyURL(), this );
+ guessScheme();
+
+#ifndef NO_GPSIM
+ DebugManager::self()->urlOpened( this );
+#endif
+
+ return true;
+}
+
+
+void TextDocument::setLastTextOutputTarget( TextDocument * target )
+{
+ m_pLastTextOutputTarget = target;
+}
+
+
+QString TextDocument::outputFilePath( const QString &ext )
+{
+ QString filePath = url().path();
+ if ( filePath.isEmpty() )
+ {
+ KTempFile f( QString::null, ext );
+ (*f.textStream()) << m_doc->text();
+ f.close();
+ DocManager::self()->associateDocument( f.name(), this );
+ return f.name();
+ }
+ if ( isModified() )
+ {
+ fileSave();
+ }
+ return filePath;
+}
+
+
+void TextDocument::slotConvertTo( int target )
+{
+ switch ( (ConvertToTarget)target )
+ {
+ case TextDocument::MicrobeOutput:
+ break;
+
+ case TextDocument::AssemblyOutput:
+ convertToAssembly();
+ break;
+
+ case TextDocument::HexOutput:
+ convertToHex();
+ break;
+
+ case TextDocument::PICOutput:
+ convertToPIC();
+ break;
+ }
+}
+
+
+void TextDocument::convertToAssembly()
+{
+ QString filePath;
+ bool showPICSelect = false;
+ ProcessOptions::ProcessPath::MediaType toType;
+
+ if ( m_guessedCodeType == TextDocument::ct_microbe )
+ {
+ toType = ProcessOptions::ProcessPath::AssemblyAbsolute;
+ filePath = outputFilePath(".microbe");
+ }
+
+ else if ( m_guessedCodeType == TextDocument::ct_hex )
+ {
+ toType = ProcessOptions::ProcessPath::Disassembly;
+ filePath = outputFilePath(".hex");
+ }
+
+ else if ( m_guessedCodeType == TextDocument::ct_c )
+ {
+ toType = ProcessOptions::ProcessPath::AssemblyRelocatable;
+ filePath = outputFilePath(".c");
+ showPICSelect = true;
+ }
+
+ else
+ {
+ kdError() << "Could not get file type for converting to assembly!"<<endl;
+ return;
+ }
+
+ OutputMethodDlg dlg( i18n("Assembly Code Output"), url(), showPICSelect, p_ktechlab );
+
+ if ( m_guessedCodeType == TextDocument::ct_c )
+ dlg.microSelect()->setAllowedAsmSet( AsmInfo::PIC14 | AsmInfo::PIC16 );
+
+ dlg.setOutputExtension(".asm");
+ dlg.setFilter("*.asm *.src *.inc|Assembly Code (*.asm, *.src, *.inc)\n*|All Files");
+ dlg.exec();
+ if (!dlg.isAccepted())
+ return;
+
+ ProcessOptions o( dlg.info() );
+ o.setTextOutputTarget( m_pLastTextOutputTarget, this, SLOT(setLastTextOutputTarget( TextDocument* )) );
+ o.setInputFiles(filePath);
+ o.setProcessPath( ProcessOptions::ProcessPath::path( ProcessOptions::guessMediaType(filePath), toType ) );
+ LanguageManager::self()->compile(o);
+}
+
+
+void TextDocument::convertToHex()
+{
+ QString filePath;
+ bool showPICSelect = false;
+
+ if ( m_guessedCodeType == TextDocument::ct_microbe )
+ filePath = outputFilePath(".microbe");
+
+ else if ( m_guessedCodeType == TextDocument::ct_asm )
+ filePath = outputFilePath(".asm");
+
+ else if ( m_guessedCodeType == TextDocument::ct_c )
+ {
+ filePath = outputFilePath(".c");
+ showPICSelect = true;
+ }
+
+ else
+ {
+ kdError() << "Could not get file type for converting to hex!"<<endl;
+ return;
+ }
+
+ OutputMethodDlg dlg( i18n("Hex Code Output"), url(), showPICSelect, p_ktechlab );
+ dlg.setOutputExtension(".hex");
+ dlg.setFilter("*.hex|Hex (*.hex)\n*|All Files");
+
+ if ( m_guessedCodeType == TextDocument::ct_c )
+ dlg.microSelect()->setAllowedAsmSet( AsmInfo::PIC14 | AsmInfo::PIC16 );
+
+ dlg.exec();
+ if (!dlg.isAccepted())
+ return;
+
+ ProcessOptions o( dlg.info() );
+ o.setTextOutputTarget( m_pLastTextOutputTarget, this, SLOT(setLastTextOutputTarget( TextDocument* )) );
+ o.setInputFiles(filePath);
+ o.setProcessPath( ProcessOptions::ProcessPath::path( ProcessOptions::guessMediaType(filePath), ProcessOptions::ProcessPath::Program ) );
+ LanguageManager::self()->compile(o);
+}
+
+
+void TextDocument::convertToPIC()
+{
+ QString filePath;
+
+ QString picID;
+
+ switch ( m_guessedCodeType )
+ {
+ case ct_microbe:
+ filePath = outputFilePath(".microbe");
+ break;
+
+ case ct_asm:
+ {
+ filePath = outputFilePath(".asm");
+ AsmParser p( filePath );
+ p.parse();
+ picID = p.picID();
+ break;
+ }
+
+ case ct_c:
+ filePath = outputFilePath(".c");
+ break;
+
+ case ct_hex:
+ filePath = outputFilePath(".hex");
+ break;
+
+ case ct_unknown:
+ kdError() << "Could not get file type for converting to hex!"<<endl;
+ return;
+ }
+
+ ProgrammerDlg * dlg = new ProgrammerDlg( picID, (QWidget*)p_ktechlab, "Programmer Dlg" );
+
+ if ( m_guessedCodeType == TextDocument::ct_c )
+ dlg->microSelect()->setAllowedAsmSet( AsmInfo::PIC14 | AsmInfo::PIC16 );
+
+ dlg->exec();
+ if ( !dlg->isAccepted() )
+ {
+ dlg->deleteLater();
+ return;
+ }
+
+ ProcessOptions o;
+ dlg->initOptions( & o );
+ o.setInputFiles( filePath );
+ o.setProcessPath( ProcessOptions::ProcessPath::path( ProcessOptions::guessMediaType(filePath), ProcessOptions::ProcessPath::Pic ) );
+ LanguageManager::self()->compile( o );
+
+ dlg->deleteLater();
+}
+
+
+void TextDocument::print()
+{
+ KTextEditor::printInterface(m_doc)->print ();
+}
+
+
+void TextDocument::slotSelectionmChanged()
+{
+ p_ktechlab->action( "edit_cut" )->setEnabled( m_doc->hasSelection () );
+ p_ktechlab->action( "edit_copy" )->setEnabled( m_doc->hasSelection () );
+}
+
+
+IntList TextDocument::bookmarkList() const
+{
+ IntList bookmarkList;
+
+ typedef QPtrList<KTextEditor::Mark> MarkList;
+ MarkList markList = m_doc->marks();
+
+ // Find out what marks need adding to our internal lists
+ for ( KTextEditor::Mark * mark = markList.first(); mark; mark = markList.next() )
+ {
+ if ( mark->type & Bookmark )
+ bookmarkList += mark->line;
+ }
+
+ return bookmarkList;
+}
+
+
+void TextDocument::slotUpdateMarksInfo()
+{
+ if ( activeView() )
+ textView()->slotUpdateMarksInfo();
+
+#ifndef NO_GPSIM
+ syncBreakpoints();
+#endif
+
+ // Update our list of bookmarks in the menu
+ p_ktechlab->unplugActionList("bookmark_actionlist");
+ m_bookmarkActions.clear();
+
+ QPtrList<KTextEditor::Mark> markList = m_doc->marks();
+
+ // Find out what marks need adding to our internal lists
+ for ( KTextEditor::Mark * mark = markList.first(); mark; mark = markList.next() )
+ {
+ if ( mark->type & Bookmark )
+ {
+ KAction * a = new KAction( i18n("%1 - %2").arg( QString::number( mark->line+1 ) ).arg( m_doc->textLine(mark->line) ),
+ 0, this, SLOT(slotBookmarkRequested()), this,
+ QString("bookmark_%1").arg(QString::number(mark->line).ascii()) );
+ m_bookmarkActions.append(a);
+ }
+ }
+
+ p_ktechlab->plugActionList( "bookmark_actionlist", m_bookmarkActions );
+}
+
+
+void TextDocument::slotBookmarkRequested()
+{
+ const QObject * s = sender();
+ if (!s) return;
+
+ QString name = s->name();
+ if ( !name.startsWith("bookmark_") )
+ return;
+
+ name.remove("bookmark_");
+ int line = -1;
+ bool ok;
+ line = name.toInt(&ok);
+ if ( ok && line >= 0 && activeView() )
+ (static_cast<TextView*>(activeView()))->gotoLine(line);
+}
+
+
+void TextDocument::setBookmarks( const IntList &lines )
+{
+ clearBookmarks();
+ const IntList::const_iterator end = lines.end();
+ for ( IntList::const_iterator it = lines.begin(); it != end; ++it )
+ setBookmark( *it, true );
+}
+
+
+void TextDocument::clearBookmarks()
+{
+ QPtrList<KTextEditor::Mark> markList = m_doc->marks();
+
+ // Find out what marks need adding to our internal lists
+ for ( KTextEditor::Mark * mark = markList.first(); mark; mark = markList.next() )
+ {
+ if ( mark->type & Bookmark )
+ m_doc->removeMark( mark->line, Bookmark );
+ }
+
+ slotUpdateMarksInfo();
+}
+
+
+void TextDocument::setBookmark( uint line, bool isBookmark )
+{
+ if (isBookmark)
+ m_doc->addMark( line, Bookmark );
+
+ else
+ m_doc->removeMark( line, Bookmark );
+}
+
+
+void TextDocument::setBreakpoints( const IntList &lines )
+{
+#ifndef NO_GPSIM
+ clearBreakpoints();
+ const IntList::const_iterator end = lines.end();
+ for ( IntList::const_iterator it = lines.begin(); it != end; ++it )
+ setBreakpoint( *it, true );
+#endif // !NO_GPSIM
+}
+
+
+IntList TextDocument::breakpointList() const
+{
+ IntList breakpointList;
+
+#ifndef NO_GPSIM
+ typedef QPtrList<KTextEditor::Mark> MarkList;
+ MarkList markList = m_doc->marks();
+
+ // Find out what marks need adding to our internal lists
+ for ( KTextEditor::Mark * mark = markList.first(); mark; mark = markList.next() )
+ {
+ if ( mark->type & Breakpoint )
+ breakpointList += mark->line;
+ }
+#endif // !NO_GPSIM
+
+ return breakpointList;
+}
+
+
+void TextDocument::setBreakpoint( uint line, bool isBreakpoint )
+{
+#ifndef NO_GPSIM
+ if (isBreakpoint)
+ {
+ m_doc->addMark( line, Breakpoint );
+ if (m_pDebugger)
+ m_pDebugger->setBreakpoint( m_debugFile, line, true );
+ }
+ else
+ {
+ m_doc->removeMark( line, Breakpoint );
+ if (m_pDebugger)
+ m_pDebugger->setBreakpoint( m_debugFile, line, false );
+ }
+#endif // !NO_GPSIM
+}
+
+
+void TextDocument::debugRun()
+{
+#ifndef NO_GPSIM
+ if (m_pDebugger)
+ {
+ m_pDebugger->gpsim()->setRunning(true);
+ slotInitDebugActions();
+ return;
+ }
+
+ switch ( guessedCodeType() )
+ {
+ case ct_unknown:
+ KMessageBox::sorry( 0l, i18n("Unknown code type."), i18n("Cannot debug") );
+ return;
+
+ case ct_hex:
+ KMessageBox::sorry( 0l, i18n("Cannot debug hex."), i18n("Cannot debug") );
+ return;
+
+ case ct_microbe:
+ m_bLoadDebuggerAsHLL = true;
+ m_debugFile = outputFilePath(".microbe");
+ break;
+
+ case ct_asm:
+ m_bLoadDebuggerAsHLL = false;
+ m_debugFile = outputFilePath(".asm");
+ break;
+
+ case ct_c:
+ m_bLoadDebuggerAsHLL = true;
+ m_debugFile = outputFilePath(".c");
+ break;
+ }
+
+ m_symbolFile = GpsimProcessor::generateSymbolFile( m_debugFile, this, SLOT(slotCODCreationSucceeded()), SLOT(slotCODCreationFailed()) );
+#endif // !NO_GPSIM
+}
+
+
+void TextDocument::debugInterrupt()
+{
+#ifndef NO_GPSIM
+ if (!m_pDebugger)
+ return;
+
+ m_pDebugger->gpsim()->setRunning(false);
+ slotInitDebugActions();
+#endif // !NO_GPSIM
+}
+
+
+void TextDocument::debugStop()
+{
+#ifndef NO_GPSIM
+ if ( !m_pDebugger || !m_bOwnDebugger )
+ return;
+
+ m_pDebugger->gpsim()->deleteLater();
+ m_pDebugger = 0l;
+ slotDebugSetCurrentLine( SourceLine() );
+ slotInitDebugActions();
+#endif // !NO_GPSIM
+}
+
+
+void TextDocument::debugStep()
+{
+#ifndef NO_GPSIM
+ if (!m_pDebugger)
+ return;
+
+ m_pDebugger->stepInto();
+#endif // !NO_GPSIM
+}
+
+
+void TextDocument::debugStepOver()
+{
+#ifndef NO_GPSIM
+ if (!m_pDebugger)
+ return;
+
+ m_pDebugger->stepOver();
+#endif // !NO_GPSIM
+}
+
+
+void TextDocument::debugStepOut()
+{
+#ifndef NO_GPSIM
+ if (!m_pDebugger)
+ return;
+
+ m_pDebugger->stepOut();
+#endif // !NO_GPSIM
+}
+
+
+void TextDocument::slotDebugSetCurrentLine( const SourceLine & line )
+{
+#ifndef NO_GPSIM
+ int textLine = line.line();
+
+ if ( DocManager::self()->findDocument( line.fileName() ) != this )
+ textLine = -1;
+
+ m_doc->removeMark( m_lastDebugLineAt, ExecutionPoint );
+ m_doc->addMark( textLine, ExecutionPoint );
+
+ if ( activeView() )
+ textView()->setCursorPosition( textLine, 0 );
+
+ m_lastDebugLineAt = textLine;
+#endif // !NO_GPSIM
+}
+
+
+void TextDocument::slotInitDebugActions()
+{
+#ifndef NO_GPSIM
+ if ( m_pDebugger )
+ {
+ if ( m_pDebugger->gpsim()->isRunning() )
+ slotDebugSetCurrentLine( SourceLine() );
+ else
+ slotDebugSetCurrentLine( m_pDebugger->currentLine() );
+ }
+
+ if ( activeView() )
+ textView()->slotInitDebugActions();
+#endif // !NO_GPSIM
+}
+
+
+void TextDocument::slotCODCreationSucceeded()
+{
+#ifndef NO_GPSIM
+ GpsimProcessor * gpsim = new GpsimProcessor( m_symbolFile, this );
+
+ if (m_bLoadDebuggerAsHLL)
+ gpsim->setDebugMode( GpsimDebugger::HLLDebugger );
+ else
+ gpsim->setDebugMode( GpsimDebugger::AsmDebugger );
+
+ setDebugger( gpsim->currentDebugger(), true );
+#endif // !NO_GPSIM
+}
+void TextDocument::slotCODCreationFailed()
+{
+#ifndef NO_GPSIM
+ m_debugFile = QString::null;
+ m_symbolFile = QString::null;
+#endif // !NO_GPSIM
+}
+
+
+void TextDocument::slotDebuggerDestroyed()
+{
+#ifndef NO_GPSIM
+ slotDebugSetCurrentLine( SourceLine() );
+ m_pDebugger = 0l;
+ m_debugFile = QString::null;
+ slotInitDebugActions();
+#endif // !NO_GPSIM
+}
+
+
+#ifndef NO_GPSIM
+void TextDocument::clearBreakpoints()
+{
+ QPtrList<KTextEditor::Mark> markList = m_doc->marks();
+
+ // Find out what marks need adding to our internal lists
+ for ( KTextEditor::Mark * mark = markList.first(); mark; mark = markList.next() )
+ {
+ if ( mark->type & Bookmark )
+ m_doc->removeMark( mark->line, Breakpoint );
+ }
+
+ slotUpdateMarksInfo();
+}
+
+
+void TextDocument::syncBreakpoints()
+{
+ if (b_lockSyncBreakpoints)
+ return;
+
+ // We don't really care about synching marks if we aren't debugging / aren't able to take use of the marks
+ if (!m_pDebugger)
+ return;
+
+ b_lockSyncBreakpoints = true;
+
+ typedef QPtrList<KTextEditor::Mark> MarkList;
+ MarkList markList = m_doc->marks();
+
+ IntList bpList;
+
+ // Find out what marks need adding to our internal lists
+ for ( KTextEditor::Mark * mark = markList.first(); mark; mark = markList.next() )
+ {
+ const int line = mark->line;
+
+ if ( mark->type & Breakpoint )
+ bpList.append(line);
+
+ if ( mark->type == ExecutionPoint )
+ m_lastDebugLineAt = line;
+ }
+
+ m_pDebugger->setBreakpoints( m_debugFile, bpList );
+
+ b_lockSyncBreakpoints = false;
+}
+
+
+bool TextDocument::debuggerIsRunning() const
+{
+ return m_pDebugger;
+}
+
+
+bool TextDocument::debuggerIsStepping() const
+{
+ return m_pDebugger && !m_pDebugger->gpsim()->isRunning();
+}
+
+
+void TextDocument::setDebugger( GpsimDebugger * debugger, bool ownDebugger )
+{
+ if ( debugger == m_pDebugger )
+ return;
+
+ // If we create a gpsim, then we may get called by DebugManager, which will
+ // try to claim we don't own it. So if we have a symbol file waiting, thne
+ // wait until we are called from its successful creation
+ if ( !m_symbolFile.isEmpty() && !ownDebugger )
+ return;
+
+ // Reset it for use next time
+ m_symbolFile = QString::null;
+
+ if (m_bOwnDebugger)
+ delete m_pDebugger;
+
+ m_pDebugger = debugger;
+ m_bOwnDebugger = ownDebugger;
+
+ if (!m_pDebugger)
+ return;
+
+ if ( m_debugFile.isEmpty() )
+ m_debugFile = url().path();
+
+ connect( m_pDebugger, SIGNAL(destroyed()), this, SLOT(slotDebuggerDestroyed()) );
+ connect( m_pDebugger->gpsim(), SIGNAL(runningStatusChanged(bool )), this, SLOT(slotInitDebugActions()) );
+ connect( m_pDebugger, SIGNAL(lineReached(const SourceLine &)), this, SLOT(slotDebugSetCurrentLine(const SourceLine &)) );
+ m_pDebugger->setBreakpoints( m_debugFile, breakpointList() );
+
+ slotInitDebugActions();
+ if ( !m_pDebugger->gpsim()->isRunning() )
+ slotDebugSetCurrentLine( m_pDebugger->currentLine() );
+
+ if ( this == dynamic_cast<TextDocument*>(DocManager::self()->getFocusedDocument()) )
+ SymbolViewer::self()->setContext( m_pDebugger->gpsim() );
+}
+#endif // !NO_GPSIM
+
+
+const QPixmap* TextDocument::inactiveBreakpointPixmap()
+{
+ const char*breakpoint_gr_xpm[]={
+ "11 16 6 1",
+ "c c #c6c6c6",
+ "d c #2c2c2c",
+ "# c #000000",
+ ". c None",
+ "a c #ffffff",
+ "b c #555555",
+ "...........",
+ "...........",
+ "...#####...",
+ "..#aaaaa#..",
+ ".#abbbbbb#.",
+ "#abbbbbbbb#",
+ "#abcacacbd#",
+ "#abbbbbbbb#",
+ "#abcacacbd#",
+ "#abbbbbbbb#",
+ ".#bbbbbbb#.",
+ "..#bdbdb#..",
+ "...#####...",
+ "...........",
+ "...........",
+ "..........."};
+ static QPixmap pixmap( breakpoint_gr_xpm );
+ return &pixmap;
+}
+
+
+const QPixmap* TextDocument::activeBreakpointPixmap()
+{
+ const char* breakpoint_xpm[]={
+ "11 16 6 1",
+ "c c #c6c6c6",
+ ". c None",
+ "# c #000000",
+ "d c #840000",
+ "a c #ffffff",
+ "b c #ff0000",
+ "...........",
+ "...........",
+ "...#####...",
+ "..#aaaaa#..",
+ ".#abbbbbb#.",
+ "#abbbbbbbb#",
+ "#abcacacbd#",
+ "#abbbbbbbb#",
+ "#abcacacbd#",
+ "#abbbbbbbb#",
+ ".#bbbbbbb#.",
+ "..#bdbdb#..",
+ "...#####...",
+ "...........",
+ "...........",
+ "..........."};
+ static QPixmap pixmap( breakpoint_xpm );
+ return &pixmap;
+}
+
+
+
+const QPixmap* TextDocument::reachedBreakpointPixmap()
+{
+ const char*breakpoint_bl_xpm[]={
+ "11 16 7 1",
+ "a c #c0c0ff",
+ "# c #000000",
+ "c c #0000c0",
+ "e c #0000ff",
+ "b c #dcdcdc",
+ "d c #ffffff",
+ ". c None",
+ "...........",
+ "...........",
+ "...#####...",
+ "..#ababa#..",
+ ".#bcccccc#.",
+ "#acccccccc#",
+ "#bcadadace#",
+ "#acccccccc#",
+ "#bcadadace#",
+ "#acccccccc#",
+ ".#ccccccc#.",
+ "..#cecec#..",
+ "...#####...",
+ "...........",
+ "...........",
+ "..........."};
+ static QPixmap pixmap( breakpoint_bl_xpm );
+ return &pixmap;
+}
+
+
+const QPixmap* TextDocument::disabledBreakpointPixmap()
+{
+ const char*breakpoint_wh_xpm[]={
+ "11 16 7 1",
+ "a c #c0c0ff",
+ "# c #000000",
+ "c c #0000c0",
+ "e c #0000ff",
+ "b c #dcdcdc",
+ "d c #ffffff",
+ ". c None",
+ "...........",
+ "...........",
+ "...#####...",
+ "..#ddddd#..",
+ ".#ddddddd#.",
+ "#ddddddddd#",
+ "#ddddddddd#",
+ "#ddddddddd#",
+ "#ddddddddd#",
+ "#ddddddddd#",
+ ".#ddddddd#.",
+ "..#ddddd#..",
+ "...#####...",
+ "...........",
+ "...........",
+ "..........."};
+ static QPixmap pixmap( breakpoint_wh_xpm );
+ return &pixmap;
+}
+
+
+const QPixmap* TextDocument::executionPointPixmap()
+{
+ const char*exec_xpm[]={
+ "11 16 4 1",
+ "a c #00ff00",
+ "b c #000000",
+ ". c None",
+ "# c #00c000",
+ "...........",
+ "...........",
+ "...........",
+ "#a.........",
+ "#aaa.......",
+ "#aaaaa.....",
+ "#aaaaaaa...",
+ "#aaaaaaaaa.",
+ "#aaaaaaa#b.",
+ "#aaaaa#b...",
+ "#aaa#b.....",
+ "#a#b.......",
+ "#b.........",
+ "...........",
+ "...........",
+ "..........."};
+ static QPixmap pixmap( exec_xpm );
+ return &pixmap;
+}
+
+#include "textdocument.moc"