Mercurial > octave-nkf
view gui/src/editor/FileEditorTab.cpp @ 14676:35512b788af2 gui
Editor can now handle multiple files in tabs.
* FileEditorInterface (new class): Interface class fpr the file editor.
* FileEditorTab (new class): File editor unit for editing a single file.
* MainWindow: Adjusted includes and method calls.
* FileEditor: Replaced code that allowed editing a file with code that manages tabs and delegates button clicks.
* src.pro: Added new files.
author | Jacob Dawid <jacob.dawid@googlemail.com> |
---|---|
date | Wed, 23 May 2012 20:25:07 +0200 |
parents | |
children | 628eeaf879f7 |
line wrap: on
line source
/* OctaveGUI - A graphical user interface for Octave * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com) * * 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 3 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, see <http://www.gnu.org/licenses/>. */ #include "FileEditorTab.h" #include "FileEditor.h" #include <QMessageBox> #include <QVBoxLayout> FileEditorTab::FileEditorTab(FileEditor *fileEditor) : QWidget ((QWidget*)fileEditor) { QSettings *settings = ResourceManager::instance ()->settings (); m_fileEditor = fileEditor; m_fileName = ""; m_editArea = new QsciScintilla (this); m_editArea->setLexer (fileEditor->lexer ()); // markers m_editArea->setMarginType (1, QsciScintilla::SymbolMargin); m_editArea->setMarginSensitivity (1, true); m_editArea->markerDefine (QsciScintilla::RightTriangle, MARKER_BOOKMARK); connect (m_editArea, SIGNAL (marginClicked (int, int, Qt::KeyboardModifiers)), this, SLOT (handleMarginClicked (int, int, Qt::KeyboardModifiers))); // line numbers m_editArea->setMarginsForegroundColor(QColor(96,96,96)); m_editArea->setMarginsBackgroundColor(QColor(232,232,220)); if (settings->value ("editor/showLineNumbers",true).toBool ()) { QFont marginFont( settings->value ("editor/fontName","Courier").toString () , settings->value ("editor/fontSize",10).toInt () ); m_editArea->setMarginsFont( marginFont ); QFontMetrics metrics(marginFont); m_editArea->setMarginType (2, QsciScintilla::TextMargin); m_editArea->setMarginWidth(2, metrics.width("99999")); m_editArea->setMarginLineNumbers(2, true); } // code folding m_editArea->setMarginType (3, QsciScintilla::SymbolMargin); m_editArea->setFolding (QsciScintilla::BoxedTreeFoldStyle , 3); // other features if (settings->value ("editor/highlightCurrentLine",true).toBool ()) { m_editArea->setCaretLineVisible(true); m_editArea->setCaretLineBackgroundColor(QColor(245,245,245)); } m_editArea->setBraceMatching (QsciScintilla::StrictBraceMatch); m_editArea->setAutoIndent (true); m_editArea->setIndentationWidth (2); m_editArea->setIndentationsUseTabs (false); if (settings->value ("editor/codeCompletion",true).toBool ()) { m_editArea->autoCompleteFromAll (); m_editArea->setAutoCompletionSource(QsciScintilla::AcsAll); m_editArea->setAutoCompletionThreshold (1); } m_editArea->setUtf8 (true); QVBoxLayout *layout = new QVBoxLayout (); layout->addWidget (m_editArea); setLayout (layout); // connect modified signal connect (m_editArea, SIGNAL (modificationChanged (bool)), this, SLOT (newTitle (bool))); connect (m_editArea, SIGNAL (copyAvailable (bool)), this, SLOT (handleCopyAvailable (bool))); m_fileName = ""; newTitle (false); } void FileEditorTab::closeEvent(QCloseEvent *event) { if (m_fileEditor->mainWindow ()->closing ()) { // close whole application: save file or not if modified checkFileModified ("Closing Octave", 0); // no cancel possible event->accept (); } else { // ignore close event if file is not saved and user cancels closing this window if (checkFileModified ("Close File",QMessageBox::Cancel) == QMessageBox::Cancel) { event->ignore (); } else { event->accept(); } } } void FileEditorTab::handleMarginClicked(int margin, int line, Qt::KeyboardModifiers state) { Q_UNUSED (state); if (margin == 1) // marker margin { unsigned int mask = m_editArea->markersAtLine (line); if (mask && (1 << MARKER_BOOKMARK)) m_editArea->markerDelete(line,MARKER_BOOKMARK); else m_editArea->markerAdd(line,MARKER_BOOKMARK); } } void FileEditorTab::commentSelectedText () { doCommentSelectedText (true); } void FileEditorTab::uncommentSelectedText () { doCommentSelectedText (false); } void FileEditorTab::doCommentSelectedText (bool comment) { if ( m_editArea->hasSelectedText() ) { int lineFrom, lineTo, colFrom, colTo, i; m_editArea->getSelection (&lineFrom,&colFrom,&lineTo,&colTo); if ( colTo == 0 ) // the beginning of last line is not selected lineTo--; // stop at line above m_editArea->beginUndoAction (); for ( i=lineFrom; i<=lineTo; i++ ) { if ( comment ) m_editArea->insertAt("%",i,0); else { QString line(m_editArea->text(i)); if ( line.startsWith("%") ) { m_editArea->setSelection(i,0,i,1); m_editArea->removeSelectedText(); } } } m_editArea->endUndoAction (); } } void FileEditorTab::newTitle(bool modified) { QString title(m_fileName); if ( !m_longTitle ) { QFileInfo file(m_fileName); title = file.fileName(); } if ( modified ) { emit fileNameChanged (title.prepend("* ")); } else emit fileNameChanged (title); } void FileEditorTab::handleCopyAvailable(bool enableCopy) { /* m_copyAction->setEnabled(enableCopy); m_cutAction->setEnabled(enableCopy); */ } int FileEditorTab::checkFileModified (QString msg, int cancelButton) { int decision = QMessageBox::Yes; if (m_editArea->isModified ()) { // file is modified but not saved, aks user what to do decision = QMessageBox::warning (this, msg, tr ("The file %1\n" "has been modified. Do you want to save the changes?"). arg (m_fileName), QMessageBox::Save, QMessageBox::Discard, cancelButton ); if (decision == QMessageBox::Save) { saveFile (); if (m_editArea->isModified ()) { // If the user attempted to save the file, but it's still // modified, then probably something went wrong, so return cancel // for cancel this operation or try to save files as if cancel not // possible if ( cancelButton ) return (QMessageBox::Cancel); else saveFileAs (); } } } return (decision); } void FileEditorTab::removeBookmark () { m_editArea->markerDeleteAll(MARKER_BOOKMARK); } void FileEditorTab::toggleBookmark () { int line,cur; m_editArea->getCursorPosition(&line,&cur); if ( m_editArea->markersAtLine (line) && (1 << MARKER_BOOKMARK) ) m_editArea->markerDelete(line,MARKER_BOOKMARK); else m_editArea->markerAdd(line,MARKER_BOOKMARK); } void FileEditorTab::nextBookmark () { int line,cur,nextline; m_editArea->getCursorPosition(&line,&cur); if ( m_editArea->markersAtLine(line) && (1 << MARKER_BOOKMARK) ) line++; // we have a bookmark here, so start search from next line nextline = m_editArea->markerFindNext(line,(1 << MARKER_BOOKMARK)); m_editArea->setCursorPosition(nextline,0); } void FileEditorTab::previousBookmark () { int line,cur,prevline; m_editArea->getCursorPosition(&line,&cur); if ( m_editArea->markersAtLine(line) && (1 << MARKER_BOOKMARK) ) line--; // we have a bookmark here, so start search from prev line prevline = m_editArea->markerFindPrevious(line,(1 << MARKER_BOOKMARK)); m_editArea->setCursorPosition(prevline,0); } void FileEditorTab::cut () { m_editArea->cut (); } void FileEditorTab::copy () { m_editArea->copy (); } void FileEditorTab::paste () { m_editArea->paste (); } void FileEditorTab::undo () { m_editArea->undo (); } void FileEditorTab::redo () { m_editArea->redo (); } void FileEditorTab::setModified (bool modified) { m_modified = modified; } void FileEditorTab::openFile () { QString openFileName; QFileDialog fileDialog(this); fileDialog.setNameFilter(SAVE_FILE_FILTER); fileDialog.setAcceptMode(QFileDialog::AcceptOpen); fileDialog.setViewMode(QFileDialog::Detail); if ( fileDialog.exec() ) { openFileName = fileDialog.selectedFiles().at(0); if (openFileName.isEmpty ()) return; loadFile(openFileName); } } void FileEditorTab::loadFile (QString fileName) { QFile file (fileName); if (!file.open (QFile::ReadOnly)) { QMessageBox::warning (this, tr ("Octave Editor"), tr ("Could not open file %1 for read:\n%2.").arg (fileName). arg (file.errorString ())); return; } QTextStream in (&file); QApplication::setOverrideCursor (Qt::WaitCursor); m_editArea->setText (in.readAll ()); QApplication::restoreOverrideCursor (); m_fileName = fileName; newTitle (false); // window title (no modification) //m_statusBar->showMessage (tr ("File loaded."), 2000); m_editArea->setModified (false); // loaded file is not modified yet } void FileEditorTab::newFile () { m_fileName = UNNAMED_FILE; newTitle (false); // window title (no modification) m_editArea->setText (""); m_editArea->setModified (false); // new file is not modified yet } void FileEditorTab::saveFile () { saveFile (m_fileName); } void FileEditorTab::saveFile (QString saveFileName) { // it is a new file with the name "<unnamed>" -> call saveFielAs if (saveFileName == UNNAMED_FILE || saveFileName.isEmpty ()) { saveFileAs(); return; } // open the file for writing QFile file (saveFileName); if (!file.open (QFile::WriteOnly)) { QMessageBox::warning (this, tr ("Octave Editor"), tr ("Could not open file %1 for write:\n%2."). arg (saveFileName).arg (file.errorString ())); return; } // save the contents into the file QTextStream out (&file); QApplication::setOverrideCursor (Qt::WaitCursor); out << m_editArea->text (); QApplication::restoreOverrideCursor (); m_fileName = saveFileName; // save file name for later use newTitle (false); // set the window title to actual file name (not modified) //m_statusBar->showMessage (tr ("File %1 saved").arg(m_fileName), 2000); m_editArea->setModified (false); // files is save -> not modified } void FileEditorTab::saveFileAs () { QString saveFileName(m_fileName); QFileDialog fileDialog(this); if (saveFileName == UNNAMED_FILE || saveFileName.isEmpty ()) { saveFileName = QDir::homePath (); fileDialog.setDirectory (saveFileName); } else { fileDialog.selectFile (saveFileName); } fileDialog.setNameFilter (SAVE_FILE_FILTER); fileDialog.setDefaultSuffix ("m"); fileDialog.setAcceptMode (QFileDialog::AcceptSave); fileDialog.setViewMode (QFileDialog::Detail); if (fileDialog.exec ()) { saveFileName = fileDialog.selectedFiles ().at (0); if (saveFileName.isEmpty ()) return; saveFile (saveFileName); } } void FileEditorTab::runFile () { if (m_editArea->isModified ()) saveFile(m_fileName); m_fileEditor->terminal ()->sendText (QString ("run \'%1\'\n").arg (m_fileName)); m_fileEditor->terminal ()->setFocus (); }