summaryrefslogtreecommitdiffstats
path: root/kturtle/src/kturtle.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kturtle/src/kturtle.cpp')
-rw-r--r--kturtle/src/kturtle.cpp1181
1 files changed, 1181 insertions, 0 deletions
diff --git a/kturtle/src/kturtle.cpp b/kturtle/src/kturtle.cpp
new file mode 100644
index 00000000..2cc7c5ff
--- /dev/null
+++ b/kturtle/src/kturtle.cpp
@@ -0,0 +1,1181 @@
+/*
+ * KTurtle, Copyright (C) 2003-04 Cies Breijs <cies # kde ! nl>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+// BEGIN includes and defines
+
+#include <stdlib.h>
+
+#include <qbutton.h>
+#include <qregexp.h>
+#include <qpainter.h>
+#include <qtooltip.h>
+#include <qtimer.h>
+#include <qwhatsthis.h>
+
+#include <kapplication.h>
+#include <kconfigdialog.h>
+#include <kdebug.h>
+#include <kedittoolbar.h>
+#include <kfiledialog.h>
+#include <kimageio.h>
+#include <kinputdialog.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kmenubar.h>
+#include <kprinter.h>
+#include <ksavefile.h>
+#include <kstatusbar.h>
+
+#include <ktexteditor/clipboardinterface.h>
+#include <ktexteditor/cursorinterface.h>
+#include <ktexteditor/editorchooser.h>
+#include <ktexteditor/editinterface.h>
+#include <ktexteditor/highlightinginterface.h>
+#include <ktexteditor/printinterface.h>
+#include <ktexteditor/selectioninterface.h>
+#include <ktexteditor/undointerface.h>
+#include <ktexteditor/viewcursorinterface.h>
+#include <ktexteditor/encodinginterface.h>
+
+#include "lexer.h"
+#include "settings.h"
+#include "translate.h"
+
+#include "kturtle.h"
+
+// StatusBar field IDs
+#define IDS_STATUS 0
+#define IDS_LINECOLUMN 2
+#define IDS_INS 3
+#define IDS_LANG 4
+
+// END
+
+
+
+// BEGIN constructor and destructor
+
+MainWindow::MainWindow(KTextEditor::Document *document) : editor(0)
+{
+ // the initial values
+ CurrentFile = KURL(); // fill with empty URL
+ setCaption( i18n("Untitled") );
+ picker = 0; // for the colorpickerdialog
+ executing = false;
+ b_fullscreen = false;
+
+ // set the shell's ui resource file
+ if (!document)
+ {
+ if ( !(document = KTextEditor::EditorChooser::createDocument(0,"KTextEditor::Document") ) )
+ {
+ KMessageBox::error( this, i18n("A KDE text-editor component could not be found;\n"
+ "please check your KDE installation.") );
+ kapp->exit(1);
+ }
+ // docList.append(doc);
+ }
+ doc = document;
+
+ setupCanvas();
+ setupEditor();
+
+ setupStatusBar();
+ setupActions();
+ createShellGUI(true);
+ setMinimumSize(200,200);
+
+ // init with more usefull size, stolen from kwite (they stole it from konq)
+ if ( !initialGeometrySet() && !kapp->config()->hasGroup("MainWindow Settings") ) resize(640, 480);
+
+ KConfig *config = kapp->config();
+ readConfig(config);
+}
+
+MainWindow::~MainWindow()
+{
+ delete editor->document();
+}
+
+// END
+
+
+
+// BEGIN setup's (actions, editor, statusbar, canvas)
+
+void MainWindow::setupActions()
+{
+ KActionCollection *ac = actionCollection(); // abbreviation
+
+ // File actions
+ KStdAction::openNew(this, SLOT(slotNewFile()), ac);
+ openExAction = new KAction(i18n("Open Exa&mples..."), "bookmark_folder", CTRL+Key_E, this, SLOT(slotOpenExample()), ac, "open_examples");
+ KStdAction::open(this, SLOT(slotOpenFile()), ac);
+ m_recentFiles = KStdAction::openRecent(this, SLOT(slotOpenFile(const KURL&)), ac);
+ KStdAction::save(this, SLOT(slotSaveFile()), ac);
+ KStdAction::saveAs(this, SLOT(slotSaveAs()), ac);
+ new KAction(i18n("Save &Canvas..."), 0, 0, this, SLOT(slotSaveCanvas()), ac, "save_canvas");
+ speed = new KSelectAction(i18n("Execution Speed"), 0, ALT+Key_S, this, SLOT( slotChangeSpeed() ), ac, "speed");
+ QStringList speeds; speeds << i18n("Full Speed") << i18n("Slow") << i18n("Slower") << i18n("Slowest");
+ speed->setItems(speeds);
+ speed->setCurrentItem(0);
+ run = new KAction(i18n("&Execute Commands"), "gear", ALT+Key_Return, this, SLOT( slotExecute() ), ac, "run");
+ pause = new KToggleAction(i18n("Pause E&xecution"), "player_pause", Key_Pause, this, SLOT( slotPauseExecution() ), ac, "pause");
+ pause->setChecked(false);
+ pause->setEnabled(false);
+ stop = new KAction(i18n("Stop E&xecution"), "stop", Key_Escape, this, SLOT( slotAbortExecution() ), ac, "stop");
+ stop->setEnabled(false);
+ KStdAction::print(this, SLOT(slotPrint()), ac);
+ KStdAction::quit(this, SLOT(close()), ac);
+
+ // Edit actions
+ KStdAction::undo(this, SLOT(slotUndo()), ac);
+ KStdAction::redo(this, SLOT(slotRedo()), ac);
+ KStdAction::cut(this, SLOT(slotCut()), ac);
+ KStdAction::copy(this, SLOT(slotCopy()), ac);
+ KStdAction::paste(this, SLOT(slotPaste()), ac);
+ KStdAction::selectAll(this, SLOT(slotSelectAll()), ac);
+ KStdAction::deselect(this, SLOT(slotClearSelection()), ac);
+ new KToggleAction(i18n("Toggle Insert"), Key_Insert, this, SLOT(slotToggleInsert()), ac, "set_insert");
+ KStdAction::find(this, SLOT(slotFind()), ac);
+ KStdAction::findNext(this, SLOT(slotFindNext()), ac);
+ KStdAction::findPrev(this, SLOT(slotFindPrevious()), ac);
+ KStdAction::replace(this, SLOT(slotReplace()), ac);
+
+ // View actions
+ new KToggleAction(i18n("Show &Line Numbers"), 0, Key_F11, this, SLOT(slotToggleLineNumbers()), ac, "line_numbers");
+ m_fullscreen = KStdAction::fullScreen(this, SLOT(slotToggleFullscreen()), ac, this, "full_screen");
+ m_fullscreen->setChecked(b_fullscreen);
+
+ // Tools actions
+ colorpicker = new KToggleAction(i18n("&Color Picker"), "colorize", ALT+Key_C, this, SLOT(slotColorPicker()), ac, "color_picker");
+ new KAction(i18n("&Indent"), "indent", CTRL+Key_I, this, SLOT(slotIndent()), ac, "edit_indent");
+ new KAction(i18n("&Unindent"), "unindent", CTRL+SHIFT+Key_I, this, SLOT(slotUnIndent()), ac, "edit_unindent");
+ new KAction(i18n("Cl&ean Indentation"), 0, 0, this, SLOT(slotCleanIndent()), ac, "edit_cleanIndent");
+ new KAction(i18n("Co&mment"), 0, CTRL+Key_D, this, SLOT(slotComment()), ac, "edit_comment");
+ new KAction(i18n("Unc&omment"), 0, CTRL+SHIFT+Key_D, this, SLOT(slotUnComment()), ac, "edit_uncomment");
+
+ // Settings actions
+ KStdAction::preferences( this, SLOT(slotSettings()), ac );
+ new KAction(i18n("&Configure Editor..."), "configure", 0, this, SLOT(slotEditor()), ac, "set_confdlg");
+
+ // Help actions
+ ContextHelp = new KAction(0, 0, Key_F2, this, SLOT(slotContextHelp()), ac, "context_help");
+ slotContextHelpUpdate(); // this sets the label of this action
+
+ // other
+ setXMLFile("kturtleui.rc");
+ setupGUI();
+}
+
+void MainWindow::setupEditor()
+{
+ editorDock = new QDockWindow(this);
+ editorDock->setNewLine(true);
+ editorDock->setFixedExtentWidth(250);
+ editorDock->setFixedExtentHeight(150);
+ editorDock->setResizeEnabled(true);
+ editorDock->setFrameShape(QFrame::ToolBarPanel);
+ QWhatsThis::add( editorDock, i18n( "This is the code editor, here you type the Logo commands to instruct the turtle. You can also open an existing Logo program with File->Open Examples... or File->Open." ) );
+ moveDockWindow(editorDock, Qt::DockLeft);
+ editor = doc->createView (editorDock, 0L);
+ // editorInterface is the editor interface which allows us to access the text in the part
+ editorInterface = dynamic_cast<KTextEditor::EditInterface*>(doc);
+ dynamic_cast<KTextEditor::EncodingInterface*>(doc)->setEncoding("UTF-8");
+ editorDock->setWidget(editor);
+
+ // default the highlightstyle to "logo" using the needed i18n
+ kdDebug(0)<<"The HighlightStyle for the Code Editor: "<<Settings::logoLanguage()<<endl;
+ slotSetHighlightstyle( Settings::logoLanguage() );
+
+ // allow the cursor position to be indicated in the statusbar
+ connect( editor, SIGNAL(cursorPositionChanged()), this, SLOT(slotCursorStatusBar()) );
+ // and update the context help menu item
+ connect( editor, SIGNAL(cursorPositionChanged()), this, SLOT(slotContextHelpUpdate()) );
+
+ translate = new Translate();
+}
+
+void MainWindow::setupStatusBar()
+{
+ statusBar()->insertItem("", IDS_STATUS, 1, false);
+ statusBar()->setItemAlignment(IDS_STATUS, AlignLeft);
+ statusBar()->insertItem("", IDS_LANG, 0, true);
+ statusBar()->insertItem("", IDS_LINECOLUMN, 0, true);
+ statusBar()->insertItem("", IDS_INS, 0, true);
+
+ // fill the statusbar
+ slotStatusBar(i18n("Welcome to KTurtle..."), IDS_STATUS); // the message part
+ slotStatusBar(i18n("Line: %1 Column: %2").arg(1).arg(1), IDS_LINECOLUMN);
+ slotStatusBar(i18n("INS"), IDS_INS);
+}
+
+void MainWindow::setupCanvas()
+{
+ baseWidget = new QWidget(this);
+ setCentralWidget(baseWidget);
+ baseLayout = new QGridLayout(baseWidget, 0, 0);
+ canvasView = new Canvas(baseWidget);
+ baseLayout->addWidget(canvasView, 0, 0, AlignCenter);
+ baseLayout->setRowStretch(0, 1); // this apperntly fixes a pre-usefull scrollbars bug
+ baseLayout->setColStretch(0, 1);
+ QWhatsThis::add( canvasView, i18n("This is the canvas, here the turtle draws a picture.") );
+ canvasView->show();
+ connect( canvasView, SIGNAL( CanvasResized() ), this, SLOT( slotUpdateCanvas() ) );
+}
+
+// END
+
+
+
+// BEGIN staturbar related functions
+
+void MainWindow::slotStatusBar(QString text, int id)
+{
+ text = " " + text + " "; // help the layout
+ statusBar()->changeItem(text, id);
+}
+
+void MainWindow::slotCursorStatusBar()
+{
+ uint cursorLine;
+ uint cursorCol;
+ dynamic_cast<KTextEditor::ViewCursorInterface*>(editor)->cursorPositionReal(&cursorLine, &cursorCol);
+ QString linenumber = i18n(" Line: %1 Column: %2 ").arg(cursorLine + 1).arg(cursorCol + 1);
+ statusBar()->changeItem(linenumber, IDS_LINECOLUMN);
+}
+
+// END
+
+
+
+// BEGIN file menu related fuctions (new, open, save()as, image, print, quit)
+
+void MainWindow::slotNewFile()
+{
+ if ( !editor->document()->isModified() && CurrentFile.isEmpty() ) return; // do nothing when nothing can be done
+ if ( editor->document()->isModified() )
+ {
+ int result = KMessageBox::warningContinueCancel( this,
+ i18n("The program you are currently working on is not saved. "
+ "By continuing you may lose the changes you have made."),
+ i18n("Unsaved File"), i18n("&Discard Changes") );
+ if (result != KMessageBox::Continue) return;
+ }
+ editorInterface->clear(); // clear the editor
+ canvasView->slotClear(); // clear the view
+ editor->document()->setModified(false);
+ CurrentFile = KURL();
+ setCaption( i18n("Untitled") );
+ slotStatusBar(i18n("New file... Happy coding!"), IDS_STATUS);
+}
+
+
+
+void MainWindow::slotOpenFile(const KURL &urlRef)
+{
+ KURL url = urlRef;
+ if ( url.isEmpty() )
+ {
+ url = KFileDialog::getOpenURL( QString(":logo_dir"), QString("*.logo|") + i18n("Logo Files"), this, i18n("Open Logo File") );
+ }
+ loadFile(url);
+}
+
+void MainWindow::slotOpenExample()
+{
+ KURL url;
+ url.setPath( locate("data", "kturtle/examples/" + Settings::logoLanguage() + "/") );
+ url = KFileDialog::getOpenURL( url.path(), QString("*.logo|") + i18n("Logo Examples Files"), this, i18n("Open Logo Example File") );
+ loadFile(url);
+}
+
+void MainWindow::loadFile(const KURL &url)
+{
+ if ( !url.isEmpty() )
+ {
+ QFile file( url.path() );
+ if ( file.open(IO_ReadOnly) )
+ {
+ if ( editor->document()->isModified() )
+ {
+ int result = KMessageBox::warningContinueCancel( this,
+ i18n("The program you are currently working on is not saved. "
+ "By continuing you may lose the changes you have made."),
+ i18n("Unsaved File"), i18n("&Discard Changes") );
+ if (result != KMessageBox::Continue)
+ {
+ slotStatusBar(i18n("Opening aborted, nothing opened."), IDS_STATUS);
+ return;
+ }
+ }
+ QTextStream stream(&file);
+ stream.setEncoding(QTextStream::UnicodeUTF8);
+ editorInterface->setText( stream.read() );
+ file.close();
+ m_recentFiles->addURL(url);
+ setCaption( url.fileName() );
+ slotStatusBar(i18n("Opened file: %1").arg( url.fileName() ), IDS_STATUS);
+ editor->document()->setModified(false);
+ CurrentFile = url;
+ return;
+ }
+ else
+ {
+ KMessageBox::error( this,
+ i18n("KTurtle was unable to open: \n%1.").arg( url.prettyURL() ),
+ i18n("Open Error") );
+ slotStatusBar(i18n("Opening aborted because of error."), IDS_STATUS);
+ return;
+ }
+ }
+ slotStatusBar(i18n("Opening aborted."), IDS_STATUS); // fallback
+}
+
+void MainWindow::slotSaveFile()
+{
+ writeFile(CurrentFile);
+}
+
+void MainWindow::slotSaveAs()
+{
+ KURL url;
+ while (true)
+ {
+ url = KFileDialog::getSaveURL( QString(":logo_dir"), QString("*.logo|") + i18n("Logo Files"), this, i18n("Save As") );
+ if ( url.isEmpty() ) // cancelled the save dialog
+ {
+ slotStatusBar(i18n("Saving aborted."), IDS_STATUS);
+ return;
+ }
+ if ( QFile( url.path() ).exists() )
+ {
+ int result = KMessageBox::warningContinueCancel ( this,
+ i18n("A program named \"%1\" already exists in this folder. "
+ "Do you want to overwrite it?").arg( url.fileName() ),
+ i18n("Overwrite?"), i18n("&Overwrite") );
+ if (result != KMessageBox::Continue) return;
+ }
+ break;
+ }
+ writeFile(url);
+}
+
+void MainWindow::writeFile(const KURL &url)
+{
+ if ( url.isEmpty() ) slotSaveAs();
+ else
+ {
+ editor->document()->saveAs(url); // use the KateParts method for saving
+ loadFile(url); // reload the file as utf8 otherwise display weird chars
+ setCaption( url.fileName() );
+ slotStatusBar(i18n("Saved to: %1").arg( url.fileName() ), IDS_STATUS);
+ m_recentFiles->addURL(url);
+ editor->document()->setModified(false);
+ CurrentFile = url;
+ }
+}
+
+
+
+void MainWindow::slotSaveCanvas()
+{
+ KURL url;
+ while (true)
+ {
+ url = KFileDialog::getSaveURL( QString(":logo_dir"), QString("*.png|") +
+ i18n("Pictures"), this, i18n("Save Canvas as Picture") );
+ if ( url.isEmpty() ) return; // when cancelled the KFiledialog?
+ if ( QFile( url.path() ).exists() )
+ {
+ int result = KMessageBox::warningContinueCancel( this,
+ i18n("A picture named \"%1\" already in this folder. "
+ "Do you want to overwrite it?").arg( url.fileName() ),
+ i18n("Overwrite?"), i18n("&Overwrite") );
+ if (result != KMessageBox::Continue) return;
+ }
+ break;
+ }
+
+ QString type( KImageIO::type( url.path() ) );
+ if ( type.isNull() ) type = "PNG";
+ bool ok = false;
+ QPixmap* pixmap = canvasView->canvas2Pixmap();
+ if ( url.isLocalFile() )
+ {
+ KSaveFile saveFile( url.path() );
+ if ( saveFile.status() == 0 )
+ {
+ if ( pixmap->save( saveFile.file(), type.latin1() ) ) ok = saveFile.close();
+ }
+ }
+ if (!ok)
+ {
+ kdWarning() << "KTurtle was unable to save the canvas drawing" << endl;
+ KMessageBox::error(this,
+ i18n("KTurtle was unable to save the image to: \n%1.").arg( url.prettyURL() ),
+ i18n("Unable to Save Image") );
+ slotStatusBar(i18n("Could not save image."), IDS_STATUS);
+ return;
+ }
+ slotStatusBar(i18n("Saved canvas to: %1").arg( url.fileName() ), IDS_STATUS);
+}
+
+
+
+void MainWindow::slotPrint()
+{
+ int result = KMessageBox::questionYesNoCancel( this,
+ i18n("Do you want to print the Logo code or the canvas?"),
+ i18n("What to Print?"), i18n("Print &Logo Code"), i18n("Print &Canvas") );
+ if (result == KMessageBox::Yes)
+ {
+ dynamic_cast<KTextEditor::PrintInterface*>(doc)->printDialog();
+ return;
+ }
+ if (result == KMessageBox::No)
+ {
+ KPrinter printer;
+ if ( printer.setup(this) )
+ {
+ QPainter painter(&printer);
+ QPixmap *CanvasPic = canvasView->canvas2Pixmap();
+ painter.drawPixmap(0, 0, *CanvasPic);
+ }
+ return;
+ }
+ slotStatusBar(i18n("Printing aborted."), IDS_STATUS);
+}
+
+
+
+bool MainWindow::queryClose()
+{
+ if ( editor->document()->isModified() )
+ {
+ slotStatusBar(i18n("Quitting KTurtle..."), IDS_STATUS);
+ // make sure the dialog looks good with new -- unnamed -- files.
+ int result = KMessageBox::warningYesNoCancel( this,
+ i18n("The program you are currently working on is not saved. "
+ "By quitting KTurtle you may lose the changes you have made."),
+ i18n("Unsaved File"), i18n("&Save"), i18n("Discard Changes && &Quit") );
+ if (result == KMessageBox::Cancel)
+ {
+ slotStatusBar(i18n("Quitting aborted."), IDS_STATUS);
+ return false;
+ }
+ else if (result == KMessageBox::Yes)
+ {
+ slotSaveFile();
+ if ( CurrentFile.isEmpty() )
+ {
+ // when saveAs get cancelled or X-ed it should not quit
+ slotStatusBar(i18n("Quitting aborted."), IDS_STATUS);
+ return false;
+ }
+ }
+ }
+ KConfig *config = kapp->config();
+ config->setGroup("General Options");
+ m_recentFiles->saveEntries(config, "Recent Files");
+ config->sync();
+ return true;
+}
+
+// END
+
+
+
+// BEGIN run related functions
+
+void MainWindow::slotExecute()
+{
+ if (b_fullscreen) // check if execution should be execution in 'fullscreen' mode
+ {
+ editorDock->hide();
+ statusBar()->hide();
+ menuBar()->hide();
+ toolBar()->hide();
+ }
+
+ run->setEnabled(false); // set action indications
+ pause->setEnabled(true);
+ stop->setEnabled(true);
+
+ // start paring
+ slotStatusBar(i18n("Parsing commands..."), IDS_STATUS);
+ kdDebug(0)<<"############## PARSING STARTED ##############"<<endl;
+ kapp->processEvents();
+ errMsg = new ErrorMessage(this); // create an empty errorDialog
+ QString txt = editorInterface->text() + "\x0a\x0a"; // parser expects input to have 2 delimiting newlines
+ QTextIStream in(&txt); // create the stream
+ Parser parser(in); // pass the reference to the stream to the parse object
+ connect(&parser, SIGNAL( ErrorMsg(Token&, const QString&, uint) ),
+ errMsg, SLOT( slotAddError(Token&, const QString&, uint) ) );
+ connect( errMsg, SIGNAL(setSelection(uint, uint, uint, uint) ),
+ this, SLOT(slotSetSelection(uint, uint, uint, uint) ) );
+ parser.parse(); // and GO!
+ TreeNode* root = parser.getTree(); // when finished parsing get the nodeTree
+ kdDebug(0)<<"############## PARSING FINISHED ##############"<<endl;
+
+ kdDebug(0)<<"TreeNode::showTree():"<<endl;
+ root->showTree(root); // show nodeTree, this is a DEBUG OPTION (but nice)
+
+ // start execution
+ slotStatusBar(i18n("Executing commands..."), IDS_STATUS);
+ kdDebug(0)<<"############## EXECUTION STARTED ##############"<<endl;
+ exe = new Executer(root); // make Executer object, 'exe', and pass it the nodeTree
+
+ connect(this, SIGNAL( changeSpeed(int) ), exe, SLOT(slotChangeSpeed(int) ) );
+ connect(this, SIGNAL( unpauseExecution() ), exe, SLOT( slotStopPausing() ) );
+ connect( exe, SIGNAL( setSelection(uint, uint, uint, uint) ),
+ this, SLOT ( slotSetSelection(uint, uint, uint, uint) ) );
+ connect( exe, SIGNAL( ErrorMsg(Token&, const QString&, uint) ),
+ errMsg, SLOT ( slotAddError(Token&, const QString&, uint) ) );
+ connect( exe, SIGNAL( InputDialog(QString&) ), this, SLOT( slotInputDialog(QString&) ) );
+ connect( exe, SIGNAL( MessageDialog(QString) ), this, SLOT( slotMessageDialog(QString) ) );
+
+ // Connect the signals form Executer to the slots from Canvas:
+ connect( exe, SIGNAL( Clear() ), canvasView, SLOT( slotClear() ) );
+ connect( exe, SIGNAL( Go(double, double) ), canvasView, SLOT( slotGo(double, double) ) );
+ connect( exe, SIGNAL( GoX(double) ), canvasView, SLOT( slotGoX(double) ) );
+ connect( exe, SIGNAL( GoY(double) ), canvasView, SLOT( slotGoY(double) ) );
+ connect( exe, SIGNAL( Forward(double) ), canvasView, SLOT( slotForward(double) ) );
+ connect( exe, SIGNAL( Backward(double) ), canvasView, SLOT( slotBackward(double) ) );
+ connect( exe, SIGNAL( Direction(double) ), canvasView, SLOT( slotDirection(double) ) );
+ connect( exe, SIGNAL( TurnLeft(double) ), canvasView, SLOT( slotTurnLeft(double) ) );
+ connect( exe, SIGNAL( TurnRight(double) ), canvasView, SLOT( slotTurnRight(double) ) );
+ connect( exe, SIGNAL( Center() ), canvasView, SLOT( slotCenter() ) );
+ connect( exe, SIGNAL( SetPenWidth(int) ), canvasView, SLOT( slotSetPenWidth(int) ) );
+ connect( exe, SIGNAL( PenUp() ), canvasView, SLOT( slotPenUp() ) );
+ connect( exe, SIGNAL( PenDown() ), canvasView, SLOT( slotPenDown() ) );
+ connect( exe, SIGNAL( SetFgColor(int, int, int) ), canvasView, SLOT( slotSetFgColor(int, int, int) ) );
+ connect( exe, SIGNAL( SetBgColor(int, int, int) ), canvasView, SLOT( slotSetBgColor(int, int, int) ) );
+ connect( exe, SIGNAL( ResizeCanvas(int, int) ), canvasView, SLOT( slotResizeCanvas(int, int) ) );
+ connect( exe, SIGNAL( SpriteShow() ), canvasView, SLOT( slotSpriteShow() ) );
+ connect( exe, SIGNAL( SpriteHide() ), canvasView, SLOT( slotSpriteHide() ) );
+ connect( exe, SIGNAL( SpritePress() ), canvasView, SLOT( slotSpritePress() ) );
+ connect( exe, SIGNAL( SpriteChange(int) ), canvasView, SLOT( slotSpriteChange(int) ) );
+ connect( exe, SIGNAL( Print(QString) ), canvasView, SLOT( slotPrint(QString) ) );
+ connect( exe, SIGNAL( FontType(QString, QString) ), canvasView, SLOT( slotFontType(QString, QString) ) );
+ connect( exe, SIGNAL( FontSize(int) ), canvasView, SLOT( slotFontSize(int) ) );
+ connect( exe, SIGNAL( WrapOn() ), canvasView, SLOT( slotWrapOn() ) );
+ connect( exe, SIGNAL( WrapOff() ), canvasView, SLOT( slotWrapOff() ) );
+ connect( exe, SIGNAL( Reset() ), canvasView, SLOT( slotReset() ) );
+
+ // START EXECUTION on the selected speed, and use the feedbacked boolean value
+ slotChangeSpeed();
+ if ( exe->run() ) slotStatusBar(i18n("Done."), IDS_STATUS);
+ else slotStatusBar(i18n("Execution aborted."), IDS_STATUS);
+ finishExecution();
+
+ delete exe; // clean-up
+
+ if ( errMsg->containsErrors() ) errMsg->display(); // if errors show them
+}
+
+void MainWindow::slotPauseExecution()
+{
+ if ( pause->isChecked() )
+ {
+ exe->pause();
+ slotStatusBar(i18n("Execution paused."), IDS_STATUS);
+ }
+ else
+ {
+ emit unpauseExecution();
+ slotStatusBar(i18n("Executing commands..."), IDS_STATUS);
+ }
+}
+
+void MainWindow::slotAbortExecution()
+{
+ // To abort the executor, this can for instance be handy when the
+ // executer got stuck in a user made endless loops...
+ // to keep the program responding to interrupts like this, all the
+ // loops have possible breaks. This activates them breaks:
+ exe->abort();
+}
+
+void MainWindow::finishExecution()
+{
+ kdDebug(0)<<"############## EXECUTION FINISHED ##############"<<endl;
+ executing = false;
+ pause->setEnabled(false);
+ pause->setChecked(false);
+ run->setEnabled(true);
+ stop->setEnabled(false);
+
+ // if execution finished on FullSpeed the selection does not match the last executed command -> clear-it
+ if (speed->currentItem() == 0) slotClearSelection();
+
+ // if coming from fullscreen-mode show the editor, menu- and statusbar
+ if (b_fullscreen) QTimer::singleShot( 1000, this, SLOT( slotFinishedFullScreenExecution() ) );
+}
+
+void MainWindow::slotChangeSpeed()
+{
+ emit changeSpeed( speed->currentItem() );
+}
+
+
+// slots for logo functions that need to use the MainWindow class:
+
+void MainWindow::slotInputDialog(QString& value)
+{
+ value = KInputDialog::getText(i18n("Input"), value);
+}
+
+void MainWindow::slotMessageDialog(QString text)
+{
+ KMessageBox::information( this, text, i18n("Message") );
+}
+
+// END
+
+
+
+// BEGIN editor connections (undo, redo, cut, copy, paste, cursor, selections, find, replace, linenumbers etc.)
+
+void MainWindow::slotEditor()
+{
+ KAction *a = editor->actionCollection()->action("set_confdlg");
+ a->activate();
+}
+
+void MainWindow::slotSetHighlightstyle(QString langCode)
+{
+ KTextEditor::HighlightingInterface *hli = dynamic_cast<KTextEditor::HighlightingInterface*>(doc);
+ for (uint i = 0; i < hli->hlModeCount(); i++)
+ {
+ if (hli->hlModeName(i) == langCode)
+ {
+ hli->setHlMode(i);
+ return;
+ }
+ }
+ // and the fallback:
+ for (uint i = 0; i < hli->hlModeCount(); i++)
+ {
+ if(hli->hlModeName(i) == "en_US") hli->setHlMode(i);
+ }
+}
+
+
+void MainWindow::slotUndo()
+{
+ dynamic_cast<KTextEditor::UndoInterface*>(doc)->undo();
+}
+
+void MainWindow::slotRedo()
+{
+ dynamic_cast<KTextEditor::UndoInterface*>(doc)->redo();
+}
+
+
+void MainWindow::slotCut()
+{
+ dynamic_cast<KTextEditor::ClipboardInterface*>(editor)->cut();
+}
+
+void MainWindow::slotCopy()
+{
+ dynamic_cast<KTextEditor::ClipboardInterface*>(editor)->copy();
+}
+
+void MainWindow::slotPaste()
+{
+ dynamic_cast<KTextEditor::ClipboardInterface*>(editor)->paste();
+}
+
+
+void MainWindow::slotSelectAll()
+{
+ dynamic_cast<KTextEditor::SelectionInterface*>(doc)->selectAll();
+}
+
+void MainWindow::slotClearSelection()
+{
+ dynamic_cast<KTextEditor::SelectionInterface*>(doc)->clearSelection();
+}
+
+void MainWindow::slotFind()
+{
+ KAction *a = editor->actionCollection()->action("edit_find");
+ a->activate();
+}
+
+void MainWindow::slotFindNext()
+{
+ KAction *a = editor->actionCollection()->action("edit_find_next");
+ a->activate();
+}
+
+void MainWindow::slotFindPrevious()
+{
+ KAction *a = editor->actionCollection()->action("edit_find_prev");
+ a->activate();
+}
+
+void MainWindow::slotReplace()
+{
+ KAction* a = editor->actionCollection()->action("edit_replace");
+ a->activate();
+}
+
+void MainWindow::slotToggleInsert()
+{
+ KToggleAction *a = dynamic_cast<KToggleAction*>(editor->actionCollection()->action("set_insert"));
+ a->activate();
+ if (a) statusBar()->changeItem(a->isChecked() ? i18n(" OVR ") : i18n(" INS "), IDS_INS);
+}
+
+void MainWindow::slotIndent()
+{
+ KAction *a = editor->actionCollection()->action("tools_indent");
+ a->activate();
+}
+
+void MainWindow::slotUnIndent()
+{
+ KAction *a = editor->actionCollection()->action("tools_unindent");
+ a->activate();
+}
+
+void MainWindow::slotCleanIndent()
+{
+ KAction *a = editor->actionCollection()->action("tools_cleanIndent");
+ a->activate();
+}
+
+void MainWindow::slotComment()
+{
+ KAction *a = editor->actionCollection()->action("tools_comment");
+ a->activate();
+}
+
+void MainWindow::slotUnComment()
+{
+ KAction *a = editor->actionCollection()->action("tools_uncomment");
+ a->activate();
+}
+
+void MainWindow::slotToggleLineNumbers()
+{
+ KToggleAction *a = dynamic_cast<KToggleAction*>( editor->actionCollection()->action("view_line_numbers") );
+ a->activate();
+}
+
+void MainWindow::slotInsertText(QString str)
+{
+ uint StartLine, StartCol, EndLine, EndCol;
+ dynamic_cast<KTextEditor::ViewCursorInterface*>(editor)->cursorPositionReal(&StartLine, &StartCol);
+ dynamic_cast<KTextEditor::EditInterface*>(doc)->insertText(StartLine, StartCol, str);
+ dynamic_cast<KTextEditor::ViewCursorInterface*>(editor)->cursorPositionReal(&EndLine, &EndCol);
+ dynamic_cast<KTextEditor::SelectionInterface*>(doc)->setSelection(StartLine, StartCol, EndLine, EndCol);
+}
+
+void MainWindow::slotSetCursorPos(uint row, uint col)
+{
+ dynamic_cast<KTextEditor::ViewCursorInterface*>(editor)->setCursorPositionReal(row - 1, col);
+ // kdDebug(0)<<"Cursor set to: ("<<row-1<<", "<<col<<")"<<endl;
+}
+
+void MainWindow::slotSetSelection(uint StartLine, uint StartCol, uint EndLine, uint EndCol)
+{
+ dynamic_cast<KTextEditor::SelectionInterface*>(doc)->setSelection(StartLine - 1, StartCol - 1, EndLine - 1, EndCol - 1);
+ // kdDebug(0)<<"Selection set to: ("<<StartLine<<", "<<StartCol<<", "<<EndLine<<", "<<EndCol<<")"<<endl;
+}
+// END
+
+
+
+// BEGIN fullscreen functions
+
+void MainWindow::slotToggleFullscreen()
+{
+ if (!b_fullscreen) showFullScreen(); // both calls will generate event triggering updateFullScreen()
+ else if ( isFullScreen() ) showNormal();
+}
+
+bool MainWindow::event(QEvent* e)
+{
+ // executes updateFullScreen() after a ShowFullScreen or ShowNormal event got triggered
+ if (e->type() == QEvent::ShowFullScreen || e->type() == QEvent::ShowNormal) updateFullScreen();
+ return KMainWindow::event(e);
+}
+
+void MainWindow::updateFullScreen()
+{
+ if (isFullScreen() == b_fullscreen) return;
+ b_fullscreen = isFullScreen();
+ if (m_fullscreen) m_fullscreen->setChecked(b_fullscreen);
+}
+
+void MainWindow::slotFinishedFullScreenExecution()
+{
+ restartOrBackDialog = new RestartOrBack(this); // we have to make some to delete some
+ if ( errMsg->containsErrors() ) slotBackToFullScreen(); // straight back to edit if there where errors
+ else
+ {
+ connect( restartOrBackDialog, SIGNAL( user1Clicked() ), this, SLOT( slotRestartFullScreen() ) );
+ connect( restartOrBackDialog, SIGNAL( user2Clicked() ), this, SLOT( slotBackToFullScreen() ) );
+ connect( restartOrBackDialog, SIGNAL( finished() ), this, SLOT( slotBackToFullScreen() ) );
+ restartOrBackDialog->show();
+ restartOrBackDialog->move(50, 50);
+ }
+}
+
+void MainWindow::slotBackToFullScreen()
+{
+ delete restartOrBackDialog;
+ editorDock->show();
+ statusBar()->show();
+ menuBar()->show();
+ toolBar()->show();
+}
+
+void MainWindow::slotRestartFullScreen()
+{
+ delete restartOrBackDialog;
+ slotExecute();
+}
+
+// END
+
+
+
+// BEGIN configuration related functions
+
+void MainWindow::slotSettings()
+{
+ // Check if there is already a dialog, if so bring it to the foreground.
+ if ( KConfigDialog::showDialog("settings") ) return;
+
+ // Create a new dialog with the same name as the above checking code.
+ KConfigDialog *dialog = new KConfigDialog(this, "settings", Settings::self() );
+ // connect the help
+ connect( dialog, SIGNAL( helpClicked() ), this, SLOT( slotSettingsHelp() ) );
+
+ // making the filling for the 'General' settings dept.
+ general = new QWidget();
+ QGridLayout *generalLayout = new QGridLayout( general, 1, 1, 11, 6, "generalLayout");
+ WidthHeightBox = new QGroupBox( i18n("Initial Canvas Size"), general );
+ WidthHeightBox->setColumnLayout(0, Qt::Vertical );
+ WidthHeightBox->layout()->setSpacing( 6 );
+ WidthHeightBox->layout()->setMargin( 11 );
+ QVBoxLayout *WidthHeightBoxLayout = new QVBoxLayout( WidthHeightBox->layout() );
+ WidthHeightBoxLayout->setAlignment( Qt::AlignTop );
+ QHBoxLayout *layout3 = new QHBoxLayout( 0, 0, 6, "layout3");
+ QVBoxLayout *layout2 = new QVBoxLayout( 0, 0, 6, "layout2");
+
+ QVBoxLayout *layout1 = new QVBoxLayout( 0, 0, 6, "layout1");
+
+ kcfg_CanvasWidth = new KIntNumInput( WidthHeightBox, "kcfg_CanvasWidth" );
+ kcfg_CanvasWidth->setValue( 400 );
+ kcfg_CanvasWidth->setMinValue( 1 );
+ kcfg_CanvasWidth->setReferencePoint( 1 );
+ layout1->addWidget( kcfg_CanvasWidth );
+
+ kcfg_CanvasHeight = new KIntNumInput( WidthHeightBox, "kcfg_CanvasHeight" );
+ kcfg_CanvasHeight->setValue( 300 );
+ kcfg_CanvasHeight->setMinValue( 1 );
+ kcfg_CanvasHeight->setReferencePoint( 1 );
+ layout1->addWidget( kcfg_CanvasHeight );
+
+ WidthLabel = new QLabel( kcfg_CanvasWidth, i18n("Canvas &width:"), WidthHeightBox );
+ layout2->addWidget( WidthLabel );
+ HeightLabel = new QLabel( kcfg_CanvasHeight, i18n("Ca&nvas height:"), WidthHeightBox );
+ layout2->addWidget( HeightLabel );
+ layout3->addLayout( layout2 );
+
+ layout3->addLayout( layout1 );
+ WidthHeightBoxLayout->addLayout( layout3 );
+ QLabel* WidthHeightLabel = new QLabel(i18n("You need to restart before these settings have effect"), WidthHeightBox);
+ WidthHeightBoxLayout->addWidget( WidthHeightLabel );
+ generalLayout->addWidget( WidthHeightBox, 0, 0 );
+ general->resize( QSize(234, 109).expandedTo(minimumSizeHint()) );
+
+ dialog->addPage( general, i18n("General"), "package_settings", i18n("General Settings") );
+
+ // making the filling for the 'Language' settings dept.
+ QWidget *language = new QWidget();
+ QGridLayout *languageLayout = new QGridLayout( language, 1, 1, 11, 6, "Form1Layout");
+ QGroupBox *groupBox1 = new QGroupBox( language, "groupBox1" );
+ groupBox1->setColumnLayout(0, Qt::Vertical );
+ groupBox1->layout()->setSpacing( 6 );
+ groupBox1->layout()->setMargin( 11 );
+ QGridLayout *groupBox1Layout = new QGridLayout( groupBox1->layout() );
+ groupBox1Layout->setAlignment( Qt::AlignTop );
+
+ QVBoxLayout *layout4 = new QVBoxLayout( 0, 0, 6, "layout4");
+
+ kcfg_LanguageComboBox = new KComboBox(groupBox1, "kcfg_LanguageComboBox");
+ kcfg_LanguageComboBox->setEditable(false);
+ QStringList LogoLanguageList = Settings::logoLanguageList();
+ // Add the full language names to the items
+ for ( QStringList::Iterator it = LogoLanguageList.begin(); it != LogoLanguageList.end(); ++it ) {
+ *it = KGlobal::locale()->twoAlphaToLanguageName( (*it).left(2) ) + " (" + *it + ")";
+ }
+ kcfg_LanguageComboBox->insertStringList(LogoLanguageList);
+
+ LanguageLabel = new QLabel(kcfg_LanguageComboBox, i18n("&Select the language for the Logo commands:"), groupBox1);
+ layout4->addWidget( LanguageLabel );
+ layout4->addWidget( kcfg_LanguageComboBox );
+ LanguageLabel->setBuddy( kcfg_LanguageComboBox );
+
+ groupBox1Layout->addLayout( layout4, 0, 0 );
+ languageLayout->addWidget( groupBox1, 0, 0 );
+ language->resize( QSize(373, 80).expandedTo(minimumSizeHint()) );
+
+ dialog->addPage( language, i18n("Language"), "locale", i18n("Language Settings") );
+
+ // When the user clicks OK or Apply we want to update our settings.
+ connect( dialog, SIGNAL( settingsChanged() ), this, SLOT( slotUpdateSettings() ) );
+
+ // Display the dialog is there where errors.
+ dialog->setInitialSize( QSize(550, 300) );
+ dialog->show();
+}
+
+void MainWindow::slotUpdateSettings()
+{
+ // get the selected language as a language code
+ QString selectedLogoLanguage = kcfg_LanguageComboBox->currentText().section( "(", -1, -1 ).remove(")");
+ // update the settings
+ Settings::setLogoLanguage( selectedLogoLanguage );
+ Settings::setLanguageComboBox( kcfg_LanguageComboBox->currentItem() );
+ Settings::writeConfig();
+ // set the HLstyle
+ slotSetHighlightstyle( selectedLogoLanguage );
+ // set the statusbar to display the language as just updated
+ // TODO maybe this language name can be more pretty by not using ".left(2)", ie "American English" would than be possible... [if this is possible this should be fixed at more places.]
+ KConfig entry(locate("locale", "all_languages"));
+ entry.setGroup(Settings::logoLanguage().left(2));
+ slotStatusBar(i18n("Command language: %1").arg( entry.readEntry("Name") ), IDS_LANG);
+
+ delete translate; // to update the currently used language
+ translate = new Translate();
+}
+
+void MainWindow::readConfig(KConfig *config)
+{
+ config->setGroup("General Options");
+ m_recentFiles->loadEntries(config, "Recent Files");
+ KConfig entry(locate("locale", "all_languages"));
+ entry.setGroup(Settings::logoLanguage().left(2));
+ slotStatusBar(i18n("Command language: %1").arg( entry.readEntry("Name") ), IDS_LANG);
+}
+
+void MainWindow::slotSettingsHelp()
+{
+ kapp->invokeHelp("settings-configure", "", "");
+}
+
+// END
+
+
+
+// BEGIN help related functions
+
+void MainWindow::slotContextHelp()
+{
+// somehow the 'anchor' parameter of invokeHelp is not working correcctly (yet)
+
+// this is/was appearently a bug in KHTML that Waldo Bastian kindly and quikly fixed.
+
+// Ooh... and we also want a DCOPmethod to close the sidebar since it over-informs...
+// Ooh3... we want fancy help (using KHTML) @ errormessage dialog
+// Ooh4... And we might also have to keep track of the KHelpCenter instance we open so
+// we will not end up with loads of them
+//
+
+// IDEA!!: put all the keyword in a i18n("...") this will make translating them a lot easier!!!
+// MAYBE THIS IS ALSO POSSIBLE FOR THE INTERPRETER!!!!
+// this should be discussed with translators (and please think of the highlight-themes too (since
+// right now thay can probably be translated with a simple perl script
+
+ kdDebug(0)<<"help requested on this text: "<<helpKeyword<<endl;
+
+ QString helpWord;
+ if ( helpKeyword == i18n("<no keyword>") )
+ {
+ KMessageBox::information( this, i18n("There is currently no text under the cursor to get help on."), i18n("Nothing Under Cursor") );
+ return;
+ }
+ else if ( helpKeyword == i18n("<number>") ) helpWord = "number";
+ else if ( helpKeyword == i18n("<string>") ) helpWord = "string";
+ else if ( helpKeyword == i18n("<assignment>") ) helpWord = "assignment";
+ else if ( helpKeyword == i18n("<question>") ) helpWord = "questions";
+ else if ( helpKeyword == i18n("<name>") ) helpWord = "name";
+ else if ( helpKeyword == i18n("<comment>") ) helpWord = "comment";
+ else
+ {
+ // make lowercase
+ helpWord = helpKeyword.lower();
+ // if the key is an alias translate that alias to a key
+ if ( !translate->alias2key(helpKeyword).isEmpty() ) helpWord = translate->alias2key(helpKeyword);
+ else if ( !translate->name2key (helpKeyword).isEmpty() ) helpWord = translate->name2key (helpKeyword);
+
+ // at this point helpKeyword should contain a valid
+ // section/anchor-id that can be used found in the doc
+ // if not... who cares :)... well let's put an debugMsg for that occasion:
+ else kdDebug(0)<<"Error in MainWindow::slotContextHelp: could not translate \""<<helpKeyword<<"\""<<endl;
+ }
+
+ kdDebug(0)<<"trying to open a help page using this keyword: "<<helpWord<<endl;
+
+ kapp->invokeHelp(helpWord, "", "");
+
+ QString help2statusBar;
+ if ( helpKeyword.startsWith("<") ) help2statusBar = helpKeyword;
+ else help2statusBar = i18n("\"%1\"").arg(helpKeyword);
+ slotStatusBar(i18n("Displaying help on %1").arg(help2statusBar), IDS_STATUS);
+}
+
+void MainWindow::slotContextHelpUpdate()
+{
+ uint row, col;
+ dynamic_cast<KTextEditor::ViewCursorInterface*>(editor)->cursorPositionReal(&row, &col);
+ QString line = dynamic_cast<KTextEditor::EditInterface*>(doc)->textLine(row);
+
+ // two shortcuts so we dont do all the CPU intensive regexp stuff when it not needed
+ if ( line.stripWhiteSpace().startsWith("#") )
+ {
+ helpKeyword = i18n("<comment>");
+ ContextHelp->setText( i18n("Help on: %1").arg(helpKeyword) );
+ return;
+ }
+ if ( line.stripWhiteSpace().isEmpty() || line.mid(col-1,2).stripWhiteSpace().isEmpty() )
+ {
+ helpKeyword = i18n("<no keyword>");
+ ContextHelp->setText( i18n("Help on: %1").arg(helpKeyword) );
+ return;
+ }
+
+ int start, length, pos;
+
+ pos = 0;
+ if ( line.contains('"') )
+ {
+ QRegExp delimitedStrings("(\"[^\"\\\\\\r\\n]*(\\\\.[^\"\\\\\\r\\n]*)*\")");
+ while ( delimitedStrings.search(line, pos) != -1 )
+ {
+ // kdDebug(0)<<"stringsearch: >>"<<pos<<"<<"<<endl;
+ start = delimitedStrings.search(line, pos);
+ length = delimitedStrings.matchedLength(); // the length of the last matched string, or -1 if there was no match
+ if ( col >= (uint)start && col < (uint)(start+length) )
+ {
+ helpKeyword = i18n("<string>");
+ ContextHelp->setText( i18n("Help on: %1").arg(helpKeyword) );
+ return;
+ }
+ pos += (length <= 0 ? 1 : length);
+ }
+ }
+
+
+ // except for "strings" this regexp effectively separates logo code in 'words' (in a very broad meaning)
+ QRegExp splitter("(([^ ,+\\-*/()=<>[!]|(?!==|<=|>=|!=))*)|(([ ,+\\-*/()=<>[!]|==|<=|>=|!=))");
+
+ pos = 0;
+ while (splitter.search(line, pos) != -1)
+ {
+ start = splitter.search(line, pos);
+ length = splitter.matchedLength();
+ if ( col < (uint)start ) break;
+ if ( col >= (uint)start && col < (uint)(start+length) )
+ {
+ QString cursorWord = line.mid( (uint)start, (uint)length );
+ kdDebug(0)<<"cursorWord: '"<<cursorWord<<"'"<<endl;
+
+ kdDebug(0)<<"(translate->name2key( cursorWord.lower() )): '"<<translate->name2key( cursorWord.lower() )<<"'"<<endl;
+ kdDebug(0)<<"(translate->alias2key( cursorWord.lower() )): '"<<translate->alias2key( cursorWord.lower() )<<"'"<<endl;
+
+ if ( cursorWord.stripWhiteSpace().isEmpty() ) helpKeyword = i18n("<no keyword>");
+
+ else if ( !translate->name2key( cursorWord.lower() ).isEmpty() ) helpKeyword = cursorWord;
+ else if ( !translate->alias2key( cursorWord.lower() ).isEmpty() ) helpKeyword = cursorWord;
+
+ else if ( cursorWord.find( QRegExp("[\\d.]+") ) == 0 ) helpKeyword = i18n("<number>");
+
+ else if ( cursorWord.find( QRegExp("[+\\-*/\\(\\)]") ) == 0 ) helpKeyword = i18n("<math>");
+
+ else if ( cursorWord == QString("=") ) helpKeyword = i18n("<assignment>");
+
+ else if ( cursorWord.find( QRegExp("==|<|>|<=|>=|!=") ) == 0 ) helpKeyword = i18n("<question>");
+
+ // if we come here we either have an ID of some sort or an error
+ // all we can do is try to catch some errors (TODO) and then...
+
+ else helpKeyword = i18n("<name>");
+
+ ContextHelp->setText( i18n("Help on: %1").arg(helpKeyword) );
+ return;
+ }
+ pos += (length <= 0 ? 1 : length); // the pos had to be increased with at least one
+ }
+
+ // we allready cached some in the beginning of this method; yet its still needed as fall-through
+ helpKeyword = i18n("<no keyword>");
+ ContextHelp->setText( i18n("Help on: %1").arg(helpKeyword) );
+}
+
+// END
+
+
+
+// BEGIN misc. functions
+
+void MainWindow::slotColorPicker()
+{
+ // in the constructor picker is initialised as 0
+ // if picker is 0 when this funktion is called a colorpickerdialog is created and connected
+ if (picker == 0)
+ {
+ picker = new ColorPicker(this);
+ if(picker == 0) return; // safety
+ connect( picker, SIGNAL( visible(bool) ), colorpicker, SLOT( setChecked(bool) ) );
+ connect( picker, SIGNAL( ColorCode(QString) ), this, SLOT( slotInsertText(QString) ) );
+ }
+ // if picker is not 0, there is a colorpickerdialog which only needs to be shown OR hidden
+ if ( picker->isHidden() )
+ {
+ picker->show();
+ colorpicker->setChecked(true);
+ }
+ else
+ {
+ picker->hide();
+ colorpicker->setChecked(false);
+ }
+}
+
+void MainWindow::slotUpdateCanvas()
+{
+ // fixes a non updateing bug
+ // I tried doing this by connecting Canvas's resized to baseWidget's update...
+ // but i had no luck :( ... this worked though :)
+ canvasView->hide();
+ canvasView->show();
+}
+
+// END
+
+
+#include "kturtle.moc"