/* Klat - A LaTeX editor for KDE Copyright (C) 2002-2004 Jori Liesenborgs (jori@lumumba.luc.ac.be) 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. 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "klatedittab.h" #include "klatedittab.moc" #include "klattooltab.h" #include "klatoutputtab.h" #include #include #include #include #include #include #include #include #include #include "klateditwidget.h" KlatEditTab::KlatEditTab(QWidget *parent) : QTabWidget(parent,"Tab for kate edit widgets") { tooltab = 0; outputtab = 0; counter = 0; connect(this,SIGNAL(currentChanged(QWidget *)),this,SLOT(slotPageChanged(QWidget *))); setAcceptDrops(true); } KlatEditTab::~KlatEditTab() { } void KlatEditTab::slotFileNew() { KlatEditWidget *w; char dummy[256]; w = new KlatEditWidget(this); connect(w,SIGNAL(cursorPositionChanged()),this,SLOT(slotNewCursorPos())); sprintf(dummy,"Untitled %d",counter++); addTab(w,dummy); setCurrentPage(count()-1); } void KlatEditTab::slotFileOpen() { KURL::List urls; KURL::List::const_iterator it; KFileDialog dlg(QString("."),QString("*.tex *.bib"),this,"Open file",true); dlg.setOperationMode(KFileDialog::Opening); dlg.setMode(KFile::Files); if (dlg.exec() == QDialog::Rejected) return; urls = dlg.selectedURLs(); for (it = urls.begin() ; it != urls.end() ; ++it) slotOpenURL(*it); } void KlatEditTab::slotOpenURL(const KURL &url) { QString fname; KlatEditWidget *w; if (!url.isLocalFile()) { KMessageBox::messageBox(this,KMessageBox::Information, "The file you specified isn't a local file","Can't open file"); return; } w = new KlatEditWidget(this); if (!w->openURL(url)) { QString errstr = "Unable to open "; errstr += url.prettyURL(); KMessageBox::messageBox(this,KMessageBox::Error, errstr,"Error!"); delete w; return; } connect(w,SIGNAL(cursorPositionChanged()),this,SLOT(slotNewCursorPos())); if (getFilenameAndPath(url,&fname)) addTab(w,fname); else addTab(w,url.prettyURL()); setCurrentPage(count()-1); emit signalFileOpened(url); } void KlatEditTab::slotInsertString(const QString &str,int advance) { KlatEditWidget *w; unsigned int row,col; w = (KlatEditWidget *)currentPage(); if (w == 0) return; row = w->cursorLine(); col = w->cursorColumnReal(); w->insertText(row,col,str); w->setCursorPositionReal(row,col+advance); } void KlatEditTab::slotFileSave() { KlatEditWidget *w; KURL url; QString strurl; w = (KlatEditWidget *)currentPage(); if (!w) return; url = w->url(); strurl = url.url(); if (strurl.length() == 0) // was a new document saveAsProcedure(w); else { if (!w->save()) KMessageBox::messageBox(this,KMessageBox::Information,"Couldn't save document","Warning!"); emit signalFileSaved(url); } } void KlatEditTab::slotFileSaveAs() { KlatEditWidget *w; w = (KlatEditWidget *)currentPage(); if (w == 0) return; saveAsProcedure(w); } void KlatEditTab::saveAsProcedure(KlatEditWidget *w) { KFileDialog dlg(QString("."),QString("*.tex *.bib"),this,"Save file",true); KURL url; QString fname; dlg.setOperationMode(KFileDialog::Saving); if (dlg.exec() == QDialog::Rejected) return; url = dlg.selectedURL(); if (w->saveAs(url)) { if (getFilenameAndPath(url,&fname)) setTabLabel(w,fname); else setTabLabel(w,url.prettyURL()); emit signalFileSaved(url); } else KMessageBox::messageBox(this,KMessageBox::Information,"Couldn't save document","Warning!"); } bool KlatEditTab::getFilenameAndPath(const KURL &url,QString *fname,QString *path) { QString fullpath = url.path(); int i,length,fnamepos; bool done; if ((length = (int)fullpath.length()) == 0) return false; fnamepos = 0; for (i = length-1,done = false ; i >= 0 && !done ; i--) { if (fullpath[i] == '/') { done = true; fnamepos = i+1; } } if (!done) return false; if (fnamepos >= length) return false; if (fname) *fname = fullpath.right(length-fnamepos); if (path) *path = fullpath.left(fnamepos-1); return true; } void KlatEditTab::slotProcessExited(KProcess *process) { if (process->normalExit() && process->exitStatus() != 0) KMessageBox::messageBox(this,KMessageBox::Information,"A process exited with an error code. ","Error!"); outputtab->finishedProcess(process->pid()); delete process; } void KlatEditTab::executeCommand(const QString &cmdline,bool savefirst) { KShellProcess *process; KlatEditWidget *w; KURL url; QString fname,path,commandline,basename; if (cmdline.find('%') >= 0 || savefirst) // check if we got a document { w = (KlatEditWidget *)currentPage(); if (!w) { KMessageBox::messageBox(this,KMessageBox::Information,"You are not editing a document","No document"); return; } url = w->url(); if (url.url().length() == 0) { KMessageBox::messageBox(this,KMessageBox::Information,"You must save the file first","No filename"); return; } if (savefirst) { if (!w->save()) { KMessageBox::messageBox(this,KMessageBox::Information,"Unable to save document before executing the command","Error!"); return; } } if (!getFilenameAndPath(url,&fname,&path)) { KMessageBox::messageBox(this,KMessageBox::Information,"Can't determine the filename or the path of the file","Error!"); return; } basename = getBaseName(fname); commandline = cmdline; commandline.replace(QRegExp("%"),basename); } else { commandline = cmdline; path = "./"; } process = new KShellProcess(); process->setWorkingDirectory(path); (*process) << commandline; connect(process,SIGNAL(receivedStdout(KProcess*,char*,int)),outputtab,SLOT(slotAddStdout(KProcess *,char*,int))); connect(process,SIGNAL(receivedStderr(KProcess*,char*,int)),outputtab,SLOT(slotAddStderr(KProcess *,char*,int))); connect(process,SIGNAL(processExited(KProcess*)),this,SLOT(slotProcessExited(KProcess *))); if (process->start(KProcess::NotifyOnExit,KProcess::AllOutput)) outputtab->newProcess(process->pid(),commandline); else delete process; } QString KlatEditTab::getBaseName(const QString &fname) { int i,len,pos; bool found; len = (int)fname.length(); if (len == 0) return fname; pos = 0; for (i = len-1,found = false ; !found && i >= 0 ; i--) { if (fname[i] == '.') { found = true; pos = i; } } if (!found) return fname; return fname.left(pos); } void KlatEditTab::slotEditUndo() { KlatEditWidget *w = (KlatEditWidget *)currentPage(); if (w) w->undo(); } void KlatEditTab::slotEditRedo() { KlatEditWidget *w = (KlatEditWidget *)currentPage(); if (w) w->redo(); } void KlatEditTab::slotEditCopy() { KlatEditWidget *w = (KlatEditWidget *)currentPage(); if (w) w->copy(); } void KlatEditTab::slotEditCut() { KlatEditWidget *w = (KlatEditWidget *)currentPage(); if (w) w->cut(); } void KlatEditTab::slotEditPaste() { KlatEditWidget *w = (KlatEditWidget *)currentPage(); if (w) w->paste(); } void KlatEditTab::slotFileClose() { KlatEditWidget *w = (KlatEditWidget *)currentPage(); if (w == 0) return; if (w->isModified()) { int status = KMessageBox::warningYesNo(this,"Document contains unsaved data. Close anyway?","File not saved"); if (status != KMessageBox::Yes) return; } removePage(w); delete w; slotNewCursorPos(); } void KlatEditTab::slotNewCursorPos() { KlatEditWidget *w = (KlatEditWidget *)currentPage(); int line,col; if (!w) { line = -1; col = -1; } else { line = w->cursorLine(); col = w->cursorColumn(); } emit signalCursorPositionChanged(line,col); } void KlatEditTab::slotPageChanged(QWidget *w) { slotNewCursorPos(); } bool KlatEditTab::areAllDocumentsSaved() { int i,num; num = count(); for (i = 0 ; i < num ; i++) { KlatEditWidget *w; w = (KlatEditWidget *)page(i); if (w->isModified()) return false; } return true; } void KlatEditTab::slotConfigKateEditor() { int i,num; KlatEditWidget::configDialog(); // update all widgets num = count(); for (i = 0 ; i < num ; i++) { KlatEditWidget *w; w = (KlatEditWidget *)page(i); w->readConfig(); } } void KlatEditTab::slotEditFind() { KlatEditWidget *w = (KlatEditWidget *)currentPage(); if (w) w->find(); } void KlatEditTab::slotEditFindNext() { KlatEditWidget *w = (KlatEditWidget *)currentPage(); if (w) w->findAgain(false); } void KlatEditTab::slotEditFindPrev() { KlatEditWidget *w = (KlatEditWidget *)currentPage(); if (w) w->findPrev(); } void KlatEditTab::slotEditReplace() { KlatEditWidget *w = (KlatEditWidget *)currentPage(); if (w) w->replace(); } void KlatEditTab::slotEditGotoLine() { KlatEditWidget *w = (KlatEditWidget *)currentPage(); if (w) w->gotoLine(); } void KlatEditTab::slotEditSpelling() { KlatEditWidget *w = (KlatEditWidget *)currentPage(); if (w) w->spelling(); } void KlatEditTab::dropEvent(QDropEvent *e) { QStringList files; QStringList::const_iterator it; if (!QUriDrag::decodeLocalFiles(e,files)) return; for (it = files.begin() ; it != files.end() ; ++it) { QString urlstr = "file:"; urlstr += (*it); KURL url(urlstr); if (url.isValid()) { if (url.isLocalFile()) slotOpenURL(url); } } } void KlatEditTab::dragEnterEvent(QDragEnterEvent *e) { e->accept(QUriDrag::canDecode(e)); } void KlatEditTab::setFocus() { KlatEditWidget *w = (KlatEditWidget *)currentPage(); if (!w) return; w->setFocus(); } void KlatEditTab::slotNextDocument() { int pos,num; if ((num = count()) <= 1) return; pos = currentPageIndex(); pos++; if (pos >= num) pos = 0; setCurrentPage(pos); } void KlatEditTab::slotPrevDocument() { int pos,num; if ((num = count()) <= 1) return; pos = currentPageIndex(); pos--; if (pos < 0) pos = num-1; setCurrentPage(pos); }