#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //ADDED #include #include #include #include "editor.h" //#include "setupFxmenu.cpp" // StatusBar field IDs #define ID_LINE_COLUMN 1 #define ID_INS_OVR 2 #define ID_SEL_NORM_BLOCK 3 #define ID_MODIFIED 4 #define ID_GENERAL 5 #define RUNID 12 #define RUNICON "run" #define FXICON "paren" //icons for run and function menu QPtrList docList; //documents Editor::Editor (Kate::Document *doc) { setMinimumSize(200,200); if (!initialGeometrySet())resize(640,400); factory = KLibLoader::self()->factory( "libkatepart" ); if (!doc) { KTextEditor::Document *tmpDoc = (KTextEditor::Document *) factory->create (0L, "kate", "KTextEditor::Document"); doc = (Kate::Document *)tmpDoc; //new doc with default path docList.append(doc); } setupEditWidget(doc); setupActions(); setupStatusBar(); setAcceptDrops(true); setXMLFile("editorui.rc"); createShellGUI( true ); guiFactory()->addClient( kateView ); KParts::GUIActivateEvent ev( true ); QApplication::sendEvent( kateView, &ev ); // Read basic main-view settings, and set to autosave setAutoSaveSettings( "Editor Options" ); readConfig(); } Editor::~Editor() { // if (kateView->isLastView()) docList.remove((Kate::Document*)kateView->getDoc()); } // Now send the data to Octave! void Editor::runCMDS(int id) { kateView->save(); //save case we crash QString *cmds = new QString(""); cmds->append( kateView->getDoc()->text() ); if(!kateView->getDoc()->isModified() ) emit runBuffer( cmds ); //emit the buffer } void Editor::init() { KToolBar *tb = toolBar("mainToolBar"); if (tb) { m_paShowToolBar->setChecked( !tb->isHidden() ); const QString text = QString("Save and run (F5)"); const QString icon=QString(RUNICON); const QString fxicon=QString(FXICON); KIconLoader::KIconLoader ic = KIconLoader::KIconLoader( icon ); KIconLoader::KIconLoader fx = KIconLoader::KIconLoader( fxicon ); const char *tbname="Run"; KToolBar *tb2 = toolBar(tbname); //put run button onto a own toolbar :) else tb->insert.. tb2->insertButton( ic.iconPath(icon, -1, false), RUNID, SIGNAL( clicked(int)), this, SLOT( runCMDS(int) ), true, text, -1, KGlobal::instance() ); //RUNID IS DEFINED ON TOP OF THIS FILE! //function menu const QString fxtext="Function list"; fxmenu= new QPopupMenu(); setupFxmenu(fxmenu); tb2->insertButton(fx.iconPath(fxicon,-1,false) , RUNID+1,fxmenu, true, fxtext,-1); // connect(fxmenu,SIGNAL(activated(int) ),this,SLOT(insertFunction(int) ) ); } else m_paShowToolBar->setEnabled(false); KStatusBar *sb = statusBar(); if (sb) m_paShowStatusBar->setChecked( !sb->isHidden() ); else m_paShowStatusBar->setEnabled(false); newCurPos(); newStatus(); kateView->setLineNumbersOn(true); //we allways want linenumbers show(); } void Editor::loadURL(const KURL &url) { m_recentFiles->addURL( url ); kateView->getDoc()->openURL(url); } bool Editor::queryClose() { if (!kateView->isLastView()) return true; return kateView->canDiscard(); } bool Editor::queryExit() { writeConfig(); kapp->config()->sync(); // return true; delete this; // here ?? } void Editor::setupEditWidget(Kate::Document *doc) { kateView = (Kate::View *)doc->createView (this, 0L); connect(kateView, SIGNAL(cursorPositionChanged()),this,SLOT(newCurPos())); connect(kateView, SIGNAL(newStatus()),this,SLOT(newStatus())); connect(kateView->getDoc(), SIGNAL(fileNameChanged()), this, SLOT(newCaption())); connect(kateView, SIGNAL(dropEventPass(QDropEvent *)), this, SLOT(slotDropEvent(QDropEvent *))); setCentralWidget(kateView); } void Editor::functions(){} // setup File menu void Editor::setupActions() { KStdAction::print(this, SLOT(printDlg()), actionCollection()); KStdAction::openNew( this, SLOT(slotNew()), actionCollection(), "file_new" ); KStdAction::open( this, SLOT( slotOpen() ), actionCollection(), "file_open" ); m_recentFiles = KStdAction::openRecent(this, SLOT(slotOpen_delayed1(const KURL&)), actionCollection()); new KAction(i18n("New &View"), 0, this, SLOT(newView()), actionCollection(), "file_newView"); // setup Settings menu m_paShowToolBar = KStdAction::showToolbar( this, SLOT( toggleToolBar() ), actionCollection() ); m_paShowStatusBar = KStdAction::showStatusbar(this, SLOT(toggleStatusBar()), actionCollection()); m_paShowPath = new KToggleAction(i18n("Sho&w Path"), 0, this, SLOT(newCaption()), actionCollection(), "set_showPath"); KStdAction::quit(this, SLOT(slotClose()), actionCollection()); KStdAction::keyBindings(this, SLOT(editKeys()), actionCollection()); KStdAction::configureToolbars(this, SLOT(editToolbars()), actionCollection()); } void Editor::setupStatusBar() { KStatusBar *statusbar; statusbar = statusBar(); statusbar->insertItem(" Line:000000 Col: 000 ", ID_LINE_COLUMN); statusbar->insertItem(" XXX ", ID_INS_OVR); statusbar->insertItem(" XXX ", ID_SEL_NORM_BLOCK); statusbar->insertFixedItem(" * ", ID_MODIFIED); statusbar->insertItem("", ID_GENERAL, 1); statusbar->setItemAlignment( ID_GENERAL, AlignLeft ); } void Editor::slotSave() { KURL url=KFileDialog::getSaveURL(QString::null, i18n("*.m *.oct *.txt|Matlab, Octave files"), this, i18n("Open File...")); if(!url.isEmpty()) { setCaption("Newfile"); kateView->saveAs(); } } void Editor::slotNew() { kateView->flush(); //this will ask if we want to save changes first.. } void Editor::slotOpen_delayed1(const KURL& url) { delayedURL=url; QTimer::singleShot(0,this,SLOT(slotOpen_delayed2())); } void Editor::slotOpen_delayed2() { slotOpen(delayedURL); } void Editor::slotOpen() { KURL url=KFileDialog::getOpenURL(QString::null, i18n("*.m *.oct|Ocatave, Matlab files"), this, i18n("Open File...")); if(!url.isEmpty()) { slotOpen( url); } } // Called after user has selected a file (file is in url) void Editor::slotOpen( const KURL& url ) { if ( url.isEmpty() )return; if ( kateView->getDoc()->isModified() ) //Ask if we want to save the current? { int want_save = KMessageBox::warningYesNoCancel(this, i18n("The current file has been modified.\n" "Do you want to save it?"),i18n("Warning")); switch(want_save) { case KMessageBox::Yes: kateView->save(); loadURL(url); break; case KMessageBox::No: loadURL(url); //no save then.. break; case KMessageBox::Cancel: break; default: break; } }else{ //if we chose cancel this is skipped, thus no change to current! kateView->getDoc()->setEncoding(encoding); loadURL(url); } } void Editor::newView() { Editor *t = new Editor((Kate::Document *)kateView->getDoc()); t->readConfig(); t->init(); } void Editor::toggleToolBar() { if( m_paShowToolBar->isChecked() ) toolBar("mainToolBar")->show(); else toolBar("mainToolBar")->hide(); } void Editor::toggleStatusBar() { if( m_paShowStatusBar->isChecked() ) statusBar()->show(); else statusBar()->hide(); } void Editor::editKeys() { KKeyDialog dlg; dlg.insert(actionCollection()); if( kateView ) dlg.insert(kateView->actionCollection()); dlg.configure(); } void Editor::editToolbars() { KEditToolbar *dlg = new KEditToolbar(guiFactory()); if (dlg->exec()) { KParts::GUIActivateEvent ev1( false ); QApplication::sendEvent( kateView, &ev1 ); guiFactory()->removeClient( kateView ); createShellGUI( false ); createShellGUI( true ); guiFactory()->addClient( kateView ); KParts::GUIActivateEvent ev2( true ); QApplication::sendEvent( kateView, &ev2 ); } delete dlg; } void Editor::printNow() { kateView->getDoc()->print (); } void Editor::printDlg() { kateView->getDoc()->printDialog (); } void Editor::newCurPos() { statusBar()->changeItem(i18n(" Line: %1 Col: %2 ") .arg(KGlobal::locale()->formatNumber(kateView->cursorLine()+1, 0)) .arg(KGlobal::locale()->formatNumber(kateView->cursorColumn(), 0)), ID_LINE_COLUMN); } void Editor::newStatus() { newCaption(); bool readOnly = !kateView->getDoc()->isReadWrite(); uint config = kateView->getDoc()->configFlags(); bool block=kateView->getDoc()->blockSelectionMode(); if (readOnly) statusBar()->changeItem(i18n(" R/O "),ID_INS_OVR); else statusBar()->changeItem(config & Kate::Document::cfOvr ? i18n(" OVR ") : i18n(" INS "),ID_INS_OVR); statusBar()->changeItem(kateView->getDoc()->isModified() ? " * " : "",ID_MODIFIED); statusBar()->changeItem(block ? i18n("BLK") : i18n(" NORM "),ID_SEL_NORM_BLOCK); } void Editor::newCaption() { if (kateView->getDoc()->url().isEmpty()) { setCaption(i18n("Untitled"),kateView->getDoc()->isModified()); } else { //set caption if ( m_paShowPath->isChecked() ) { //File name shouldn't be too long - Maciek if (kateView->getDoc()->url().filename().length() > 200) setCaption(kateView->getDoc()->url().prettyURL().left(197) + "...",kateView->getDoc()->isModified()); else setCaption(kateView->getDoc()->url().prettyURL(),kateView->getDoc()->isModified()); } else { //File name shouldn't be too long - Maciek if (kateView->getDoc()->url().filename().length() > 200) setCaption("..." + kateView->getDoc()->url().fileName().right(197),kateView->getDoc()->isModified()); else setCaption(kateView->getDoc()->url().fileName(),kateView->getDoc()->isModified()); } } } void Editor::dragEnterEvent( QDragEnterEvent *event ) { event->accept(QUriDrag::canDecode(event)); } void Editor::dropEvent( QDropEvent *event ) { slotDropEvent(event); } void Editor::slotDropEvent( QDropEvent *event ) { QStrList urls; if (QUriDrag::decode(event, urls)) { kdDebug(13000) << "Editor:Handling QUriDrag..." << endl; QPtrListIterator it(urls); for( ; it.current(); ++it ) { slotOpen( (*it) ); } } } void Editor::slotEnableActions( bool enable ) { QValueList actions = actionCollection()->actions(); QValueList::ConstIterator it = actions.begin(); QValueList::ConstIterator end = actions.end(); for (; it != end; ++it )(*it)->setEnabled( enable ); actions = kateView->actionCollection()->actions(); it = actions.begin(); end = actions.end(); for (; it != end; ++it ) (*it)->setEnabled( enable ); } //write config for editor on close void Editor::slotClose() { writeConfig(); close(); } //common config void Editor::readConfig(KConfig *config) { m_paShowPath->setChecked( config->readBoolEntry("ShowPath") ); m_recentFiles->loadEntries(config, "Recent Files"); } void Editor::writeConfig(KConfig *config) { config->writeEntry("ShowPath",m_paShowPath->isChecked()); m_recentFiles->saveEntries(config, "Recent Files"); } //config file void Editor::readConfig() { KConfig *config; config = kapp->config(); config->setGroup("Editor Options"); readConfig(config); kateView->getDoc()->readConfig(); readProperties(config); } void Editor::writeConfig() { KConfig *config; config = kapp->config(); config->setGroup("Editor Options"); writeConfig(config); kateView->getDoc()->writeConfig(); saveGlobalProperties(config); } void Editor::readProperties(KConfig *config) { readConfig(config); kateView->readSessionConfig(config); } void Editor::saveProperties(KConfig *config) { writeConfig(config); config->writeEntry("DocumentNumber",docList.find((Kate::Document *)kateView->getDoc()) + 1); kateView->writeSessionConfig(config); } void Editor::saveGlobalProperties(KConfig *config) //save documents { uint z; QString buf; Kate::Document *doc; config->setGroup("Number"); config->writeEntry("NumberOfDocuments",docList.count()); for (z = 1; z <= docList.count(); z++) { buf = QString("Document%1").arg(z); config->setGroup(buf); doc = (Kate::Document *) docList.at(z - 1); doc->writeSessionConfig(config); } } //F5 == save & run bool Editor::eventFilter( QObject *o,QEvent *e) { if(e->type() == QEvent::KeyPress) { QKeyEvent * ke = (QKeyEvent*) e; if ( ke->key() == Qt::Key_F5 ) { #ifdef DEBUG_S qDebug("RUN now!"); //kate might be using F5 by default for reload! #endif runCMDS(1); return true; } else return false; } else return false; } // session management void Editor::restore(KConfig *config, int n) { if (kateView->isLastView() && !kateView->getDoc()->url().isEmpty()) { //in this case first view loadURL(kateView->getDoc()->url()); } readPropertiesInternal(config, n); init(); } void Editor::setupFxmenu(QPopupMenu *menu) { menu->insertTearOffHandle(-1,-1); //only first ? QString cmdfile= QDir::home().path()+"/.commands.lst"; #ifdef DEBUG_S qDebug(cmdfile.latin1() ); #endif QFile file( cmdfile); //point to kdehome ...apps...koctav/commands. if(file.exists() ) { if ( file.open( IO_ReadOnly ) ) { QTextStream stream( &file ); QString line; while ( !stream.eof() ) { line = stream.readLine(); // line of text excluding '\n' fxEntry += line; } } //process all lines in lines //and insert them int id=0; bool first=true; for(QStringList::Iterator it = fxEntry.begin(); it !=fxEntry.end(); ++it ) { const QString name=(*it); //label if( (*it).length() == 1) //then this is a menu label { subPopup =new QPopupMenu(); //contents of menu menu->insertItem ( name,subPopup,-1,-1 ); } else //this is a entry { id=subPopup->insertItem ((*it), -1, -1 ); //entry 1 fxId contains the id of item if(first) { first=false; fxFirst =id; } subPopup->connectItem (id, this, SLOT( insertFunction(int) ) ); #ifdef DEBUG_S qDebug("Menu id:" +QString::number(id)+" text: "+ subPopup->text(id) ); //divide id with id of first to get 1-N ? #endif } } } file.close(); } //insert the function selected void Editor::insertFunction(int at) { QString item=*fxEntry.at(abs(at-fxFirst)+1) ; //|at-first|+1 , at-first is negative so abs, //insert item at cursor //entries are allways +1, since first is label of menu A-Z kateView->insertText(item); #ifdef DEBUG_S //number is negative???? abs? qDebug("selected item with id "+QString::number(abs(at-fxFirst)+1)+"name :"+ *fxEntry.at(abs(at-fxFirst)+1)); #endif }