#include <qdropsite.h>
#include <qdragobject.h>
#include <qvbox.h>
#include <dcopclient.h>
#include <qtimer.h>
#include <ktoolbarbutton.h>
#include <kfiledialog.h>
#include <kiconloader.h>
#include <kaboutdata.h>
#include <kstatusbar.h>
#include <kstdaction.h>
#include <kaction.h>
#include <kdebug.h>
#include <kglobal.h>
#include <kapplication.h>
#include <klocale.h>
#include <kurl.h>
#include <kconfig.h>
#include <kcmdlineargs.h>
#include <kkeydialog.h>
#include <kedittoolbar.h>
#include <kparts/event.h>
#include <kmenubar.h>
#include <kfiledialog.h> //ADDED
#include <klibloader.h>
#include <kmessagebox.h>
#include <stdlib.h>
#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<Kate::Document> 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<char> it(urls);
for( ; it.current(); ++it ) {
slotOpen( (*it) );
}
}
}
void Editor::slotEnableActions( bool enable )
{
QValueList<KAction *> actions = actionCollection()->actions();
QValueList<KAction *>::ConstIterator it = actions.begin();
QValueList<KAction *>::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
}
syntax highlighted by Code2HTML, v. 0.9.1