/***************************************************************************
                          koctave3.cpp  -  description
                             -------------------
    begin                : Thu Oct 24 19:35:22 IST 2002
    copyright            : (C) 2002 by Matti
    email                : hei00rhe@syd.kth.se
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

// include files for QT
#include <qdir.h>
#include <qprinter.h>
#include <qpainter.h>
#include <qlayout.h>

// include files for KDE
#include <kiconloader.h>
#include <kmessagebox.h>
#include <kfiledialog.h>
#include <kmenubar.h>
#include <kstatusbar.h>
#include <klocale.h>
#include <kconfig.h>
#include <kstdaction.h>
#include <kparts/part.h>
#include <klibloader.h>


// application specific includes
#include "koctave3.h"
#include "koctave3view.h"
#include "mainwidget.h"
#include "helpwindow.h"
#include "prefs.h"

#define ID_STATUS_MSG 1
//#define DEBUG_S		//for debuging

#define RUNICON "run"


Koctave3App::Koctave3App(QWidget* , const char* name):KMainWindow(0, name)
{
  config=kapp->config();
  
  initStatusBar();
  initActions();
  initView();

  //check this before we create the mainwidget.
  config->setGroup("Paths");
  if( config->readEntry("octave").isNull() ) //user must config this before we can run.
  {
    QString defpath="/usr/bin/octave";		//this is default on package dists, most anyway...
    QFile octave(defpath);
    if( !octave.exists() )
    {	//do this if it's not located in std directory, we dont want to slowdown this by a search..
	KMessageBox::information(0,QString("Octave path is not configured properly\nset this and restart the program"),QString("Please configure kOctave now."));
	prefs *p = new prefs(this);
	p->show();
#ifdef DEBUG_S
	qDebug("Octavepath not set");
#endif
    }else
    {
	KMessageBox::information(0,QString("Octave path is not set, but found what seems to be Octave\nWill try to use "+defpath),
				QString("Probably found Octave, change this in settings if its wrong"));
	config->setGroup("Paths");
	config->writeEntry("octave",defpath);
    }
  }

  editor = new Editor();          //create the editor, not shown until init() is called..
  octave = new MainWidget(this);  //mainwidget containing octave konsole
  setCentralWidget(octave);           //put the widget to window!
  connect( editor, SIGNAL(runBuffer(QString*)), this, SLOT( slotEditorCmd(QString*)) );	
  connect( octave, SIGNAL(fileSelected(QString)), this, SLOT( slotOpen(QString)) );
 
  readOptions();
  //filePrint->setEnabled(false);
  editCopy->setEnabled(true);
  editPaste->setEnabled(true);

  
  emit hidelogo();	        //now lets hide the logo

}

Koctave3App::~Koctave3App()
{
    QString *exit=new QString("exit");	//exit octave nice!
    octave->sendCmdSlot(exit);		
}

void Koctave3App::initActions()
{
  //Octave Help files
  helpTopics = KStdAction::help(this, SLOT( slotHelpTopics()), actionCollection());
  
  fileNew = KStdAction::openNew(this, SLOT(slotFileNew()), actionCollection());
  fileOpen = KStdAction::open(this, SLOT(slotFileOpen()), actionCollection());
  fileOpenRecent = KStdAction::openRecent(this, SLOT(slotFileOpenRecent(const KURL&)), actionCollection());
//  filePrint = KStdAction::print(this, SLOT(slotFilePrint()), actionCollection());
  fileQuit = KStdAction::quit(this, SLOT(slotFileQuit()), actionCollection());
  editCopy = KStdAction::copy(this, SLOT(slotEditCopy()), actionCollection());
  editPaste = KStdAction::paste(this, SLOT(slotEditPaste()), actionCollection());
  viewToolBar = KStdAction::showToolbar(this, SLOT(slotViewToolBar()), actionCollection());
  viewStatusBar = KStdAction::showStatusbar(this, SLOT(slotViewStatusBar()), actionCollection());
  settings = KStdAction::preferences(this, SLOT(slotSettings()), actionCollection());

  fileNew->setStatusText(i18n("Creates a new document"));
  fileOpen->setStatusText(i18n("Opens an existing document"));
  fileOpenRecent->setStatusText(i18n("Opens a recently used file"));

//  filePrint ->setStatusText(i18n("Prints out the actual document"));
  fileQuit->setStatusText(i18n("Quits the application"));
  editCopy->setStatusText(i18n("Copies the selected section to the clipboard"));
  editPaste->setStatusText(i18n("Pastes the clipboard contents to actual position"));
  viewToolBar->setStatusText(i18n("Enables/disables the toolbar"));
  viewStatusBar->setStatusText(i18n("Enables/disables the statusbar"));
  // use the absolute path to your koctave3ui.rc file for testing purpose in createGUI();
  createGUI();
  
  //insert a change directory toolbar
  KToolBar *tb = toolBar("mainToolBar");
		      
  const QString bicon="editclear";		  
  KIconLoader::KIconLoader ic = KIconLoader::KIconLoader( bicon );		  
  tb->insertButton( ic.iconPath(bicon,-1,false), -1, SIGNAL(clicked()),this ,SLOT(changeDirBrowserSlot() ),
		    true,QString::QString("Set Directory"),-1,KGlobal::instance() ); 

  QStringList lst;				//read this from file perhaps ?, and add each new in changeDirSlot() .
  lst.append(QDir::home().path());
  lst.append("/usr/");
  tb->insertCombo(lst, -1,true, SIGNAL(returnPressed(const QString &)),this,SLOT(changeDirSlot(const QString&)) 
		  ,true,QString("Type directory and press enter here to change."),70,-1,QComboBox::AtBottom);	

}

//browse the dir (so user dont have to cd dir)
void Koctave3App::changeDirBrowserSlot()
{
    KURL url=KFileDialog::getExistingDirectory(QString::null,
            			      this, i18n("Set working path..."));
    if(! url.path().isNull() )changeDirSlot( url.path() );
		 
}

void Koctave3App::changeDirSlot(const QString &dir)
{
#ifdef DEBUG_S
    qDebug("Change dir:Enter pressed.");
#endif
    QString *cd= new QString("cd "+dir);
    slotEditorCmd(cd);
}

void Koctave3App::initView(){ }

void Koctave3App::initStatusBar()
{
  // TODO: add your own items you need for displaying current application status.
  statusBar()->insertItem(i18n("Ready."), ID_STATUS_MSG);
}



void Koctave3App::openDocumentFile(const KURL& url)
{
  slotStatusMsg(i18n("Opening file..."));
  editor->loadURL(url);
  fileOpenRecent->addURL( url );
  slotStatusMsg(i18n("Ready."));
}

void Koctave3App::saveOptions()
{	
  config->setGroup("General Options");
  config->writeEntry("Geometry", size());
  config->writeEntry("Show Toolbar", viewToolBar->isChecked());
  config->writeEntry("Show Statusbar",viewStatusBar->isChecked());
  config->writeEntry("ToolBarPos", (int) toolBar("mainToolBar")->barPos());
  fileOpenRecent->saveEntries(config,"Recent Files");
}


void Koctave3App::readOptions()
{
	
  config->setGroup("General Options");

  // bar status settings
  bool bViewToolbar = config->readBoolEntry("Show Toolbar", true);
  viewToolBar->setChecked(bViewToolbar);
  slotViewToolBar();

  bool bViewStatusbar = config->readBoolEntry("Show Statusbar", true);
  viewStatusBar->setChecked(bViewStatusbar);
  slotViewStatusBar();


  // bar position settings
  KToolBar::BarPosition toolBarPos;
  toolBarPos=(KToolBar::BarPosition) config->readNumEntry("ToolBarPos", KToolBar::Top);
  toolBar("mainToolBar")->setBarPos(toolBarPos);
	
  // initialize the recent file list
  fileOpenRecent->loadEntries(config,"Recent Files");

  QSize size=config->readSizeEntry("Geometry");
  if(!size.isEmpty())
  {
    resize(size);
  }
}

// save ? 
void Koctave3App::saveProperties(KConfig *_cfg){}

void Koctave3App::readProperties(KConfig* _cfg){}		


// Would be a pity if we just exit wo this question, variables could get lost!
// but perhaps make it possible to dissable ?
// this is here so that CTRL+D will do a "fast exit" from octave
bool Koctave3App::queryClose()
{
//3=yes
  if(3 == KMessageBox::questionYesNo(this,QString("Are you sure you want to exit ?\nAll unsaved variables will be lost!"),
				     QString("Please confirm.")))
    {
     // editor->close();		//could be null!!
      saveOptions();
      return true;
    }
  else return false;

}
//allways exit...dont do anything special here
bool Koctave3App::queryExit()
{
 saveOptions();
 return true;
}

/////////////////////////////////////////////////////////////////////
// SLOT IMPLEMENTATION
/////////////////////////////////////////////////////////////////////

// Clone window ...not wanted ?
void Koctave3App::slotFileNewWindow(){}
// not used
void Koctave3App::slotFileClose(){}
//not used
void Koctave3App::slotFileSave(){}


void Koctave3App::slotFileNew()
{
  slotStatusMsg(i18n("Creating new document..."));
    editor= new Editor();
    editor->init();
    connect( editor, SIGNAL(runBuffer(QString*)), this, SLOT( slotEditorCmd(QString*)) );
    editor->show();

  slotStatusMsg(i18n("Ready."));
}

void Koctave3App::slotFileOpen()
{
  slotStatusMsg(i18n("Opening file..."));
  KURL url=KFileDialog::getOpenURL(QString::null,
        i18n("*.m *.oct *.txt|Matlab, Octave files, ascii text"), this, i18n("Open File..."));
    if(!url.isEmpty())
    {
      editor = new Editor();
      editor->init();
      editor->loadURL(url);
      connect( editor, SIGNAL(runBuffer(QString*)), this, SLOT( slotEditorCmd(QString*)) );
      editor->show();
      setCaption(url.fileName(), false);
      fileOpenRecent->addURL( url );
    }
  slotStatusMsg(i18n("Ready."));
}

void Koctave3App::slotFileOpenRecent(const KURL& url)
{
  slotStatusMsg(i18n("Opening file..."));
  editor=new Editor();
  editor->init();
  editor->loadURL(url);
  connect( editor, SIGNAL(runBuffer(QString*)), this, SLOT( slotEditorCmd(QString*)) );	
  slotStatusMsg(i18n("Ready."));
}

void Koctave3App::slotFilePrint()
{
  slotStatusMsg(i18n("Printing..."));
  QPrinter printer;
  if (printer.setup(this))
  {
    view->print(&printer);
  }
  slotStatusMsg(i18n("Ready."));
}

void Koctave3App::slotFileQuit()
{  
  slotStatusMsg(i18n("Exiting..."));
  saveOptions();
// if( editor != NULL )editor->close();		//if editor points anywhere..this could be a problem if more than 1 editor is open..since they have no pointers ?
// crashes, why ??
  this->close();
}

void Koctave3App::slotEditCut()
{
  slotStatusMsg(i18n("Cutting selection..."));
  QString *clipboard=new QString("");		//get clipboard somehow
   octave->insert(clipboard);
  slotStatusMsg(i18n("Ready."));
}

void Koctave3App::slotEditCopy()
{
  slotStatusMsg(i18n("Copying selection to clipboard..."));
  slotStatusMsg(i18n("Ready."));
}

void Koctave3App::slotEditPaste()
{
  slotStatusMsg(i18n("Inserting clipboard contents..."));

  slotStatusMsg(i18n("Ready."));
}

void Koctave3App::slotViewToolBar()
{
  slotStatusMsg(i18n("Toggling toolbar..."));
  ///////////////////////////////////////////////////////////////////
  // turn Toolbar on or off
  if(!viewToolBar->isChecked())
  {
    toolBar("mainToolBar")->hide();
  }
  else
  {
    toolBar("mainToolBar")->show();
  }		

  slotStatusMsg(i18n("Ready."));
}

void Koctave3App::slotViewStatusBar()
{
  slotStatusMsg(i18n("Toggle the statusbar..."));
  ///////////////////////////////////////////////////////////////////
  //turn Statusbar on or off
  if(!viewStatusBar->isChecked())
  {
    statusBar()->hide();
  }
  else
  {
    statusBar()->show();
  }

  slotStatusMsg(i18n("Ready."));
}


void Koctave3App::slotStatusMsg(const QString &text)
{
  // change status message permanently
  statusBar()->clear();
  statusBar()->changeItem(text, ID_STATUS_MSG);
}

void Koctave3App::slotOctaveExit()
{
  editor->close();
  slotFileQuit();
}

void Koctave3App::slotEditorCmd(QString *msg)
{
#ifdef DEBUG_S
    qDebug("main app");
#endif
    octave->sendCmdSlot(msg);
}

/** call for help browser */
void Koctave3App::slotHelpTopics()
{
  KConfig *cfg;
  cfg=kapp->config();
  cfg->setGroup("Paths");
  HelpWindow *help = new HelpWindow(cfg->readEntry("docs"), ".", 0, "help viewer");
  help->setCaption("Octave Documentation");
  help->show();
}

//open file from browser
void Koctave3App::slotOpen(QString file)
{
#ifdef DEBUG_S
    qDebug("openSLOT()");
#endif
    KURL tmp(file);		
    editor = new Editor();	//NOT GOOD!
    editor->loadURL(tmp);
    fileOpenRecent->addURL( tmp );
    editor->init();    
    connect( editor, SIGNAL(runBuffer(QString*)), this, SLOT( slotEditorCmd(QString*)) );	
}

/** No descriptions */
void Koctave3App::slotSettings()
{
  prefs *p=new prefs(this);
  connect( p, SIGNAL( configChanged() ), this, SLOT( updateConfig() ) );
  p->show();  
}

// Used changed something, update..
void Koctave3App::updateConfig()
{
    octave->updateConfig();
}


syntax highlighted by Code2HTML, v. 0.9.1