/* * textedit.cpp * * Copyright 2008 gpg4usb-team * * 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., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ #include "QDebug" #include "QUrl" #include "textedit.h" class QFileDialog; class QMessageBox; TextEdit::TextEdit() { countPage = 0; tabWidget = new QTabWidget(this); tabWidget->setMovable(true); tabWidget->setTabsClosable(true); tabWidget->setDocumentMode(true); QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(tabWidget); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); setLayout(layout); connect(tabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(removeTab(int))); newTab(); setAcceptDrops(false); } void TextEdit::newTab() { QString header = "new " + QString::number(++countPage); EditorPage *page = new EditorPage(); tabWidget->addTab(page, header); tabWidget->setCurrentIndex(tabWidget->count() - 1); page->getTextPage()->setFocus(); connect(page->getTextPage(), SIGNAL(modificationChanged(bool)), this, SLOT(showModified())); // setCursorPosition(); } void TextEdit::open() { QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Open file"), QDir::currentPath()); foreach (QString fileName,fileNames){ if (!fileName.isEmpty()) { QFile file(fileName); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { EditorPage *page = new EditorPage(fileName); QTextStream in(&file); QApplication::setOverrideCursor(Qt::WaitCursor); page->getTextPage()->setPlainText(in.readAll()); page->setFilePath(fileName); QTextDocument *document = page->getTextPage()->document(); document->setModified(false); tabWidget->addTab(page, strippedName(fileName)); tabWidget->setCurrentIndex(tabWidget->count() - 1); QApplication::restoreOverrideCursor(); page->getTextPage()->setFocus(); connect(page->getTextPage(), SIGNAL(modificationChanged(bool)), this, SLOT(showModified())); // setCursorPosition(); //enableAction(true) } else { QMessageBox::warning(this, tr("Application"), tr("Cannot read file %1:\n%2.") .arg(fileName) .arg(file.errorString())); } } } } void TextEdit::save() { QString fileName = curPage()->getFilePath(); qDebug() <getTextPage()->toPlainText(); QTextDocument *document = page->getTextPage()->document(); document->setModified(false); int curIndex = tabWidget->currentIndex(); tabWidget->setTabText(curIndex, strippedName(fileName)); page->setFilePath(fileName); // statusBar()->showMessage(tr("File saved"), 2000); return true; } else { QMessageBox::warning(this, tr("File"), tr("Cannot write file %1:\n%2.") .arg(fileName) .arg(file.errorString())); return false; } } bool TextEdit::saveAs() { QString fileName = QFileDialog::getSaveFileName(this, tr("Save file"), QDir::currentPath()); return saveFile(fileName); } bool TextEdit::closeFile() { if (tabWidget->count() != 0) { if (maybeSaveCurrentTab()) { int tabIndex = tabWidget->currentIndex(); tabWidget->setCurrentIndex(tabIndex); curPage()->close(); tabWidget->removeTab(tabIndex); if (tabWidget->count() == 0) { // enableAction(false); } return true; } return false; } return false; } void TextEdit::closeTab() { removeTab(tabWidget->currentIndex()); if (tabWidget->count() != 0) { curPage()->getTextPage()->setFocus(); } } void TextEdit::removeTab(int index) { if (tabWidget->count() != 0) { if (maybeSaveCurrentTab()) { tabWidget->setCurrentIndex(index); curPage()->close(); tabWidget->removeTab(index); } } if (tabWidget->count() == 0) { // enableAction(false); } } void TextEdit::cut() { curTextPage()->cut(); } void TextEdit::copy() { curTextPage()->copy(); } void TextEdit::paste() { curTextPage()->paste(); } void TextEdit::undo() { curTextPage()->undo(); } void TextEdit::redo() { curTextPage()->redo(); } void TextEdit::selectAll() { curTextPage()->selectAll(); } /*void TextEditor::closeEvent(QCloseEvent *event) { int curIndex = tabWidget->count(); bool answ = true; while (curIndex >= 1 && answ == true) { answ = closeFile(); curIndex--; } if (answ == true) { writeSettings(); event->accept(); } else { event->ignore(); } } */ /** * Check if current may need to be saved. * Call this function before closing the currently active tab- * * If it returns false, the close event should be aborted. */ bool TextEdit::maybeSaveCurrentTab() { EditorPage *page = curPage(); QTextDocument *document = page->getTextPage()->document(); if (document->isModified()) { QString filePath = page->getFilePath(); QMessageBox::StandardButton result; result = QMessageBox::warning(this, tr("Unsaved document"), tr("The document has been modified:")+"\n"+filePath+"\n\n"+tr("Do you want to save your changes?"), QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); if (result == QMessageBox::Save) { if (filePath == "") { return saveAs(); } else { return saveFile(filePath); } } else if (result == QMessageBox::Discard) { return true; } else { return false; } } return true; } /*! Checks if there are unsaved documents in any tab, which may need to be saved. Call this function before closing the programme or all tabs. If it returns false, the close event should be aborted. */ bool TextEdit::maybeSaveAnyTab() { QHash unsavedDocs; // this list could be used to implement gedit like "unsaved changed"-dialog for(int i=0; i < tabWidget->count(); i++) { EditorPage *ep = qobject_cast (tabWidget->widget(i)); if(ep->getTextPage()->document()->isModified()) { QString docname = tabWidget->tabText(i); docname.remove(0,2); unsavedDocs.insert(i, docname); } } /* * only 1 unsaved document -> set modified tab as current * and show normal unsaved doc dialog */ if(unsavedDocs.size() == 1) { int modifiedTab = unsavedDocs.keys().at(0); tabWidget->setCurrentIndex(modifiedTab); return maybeSaveCurrentTab(); /* * more than one unsaved documents */ } else if(unsavedDocs.size() > 0) { QString docList; QHashIterator i (unsavedDocs); while (i.hasNext()) { i.next(); qDebug() << "unsaved: " << i.key() << ": " << i.value(); docList.append(i.value()).append("\n"); } QMessageBox::StandardButton result; result = QMessageBox::warning(this, tr("Unsaved documents"), tr("There are unsaved changes in the following documents:\n") + docList, QMessageBox::Discard | QMessageBox::Cancel); if (result == QMessageBox::Discard) { return true; } else { return false; } /* * no unsaved documents */ } else { return true; } // code should never reach this statement return false; } QPlainTextEdit* TextEdit::curTextPage() { EditorPage *curTextPage = qobject_cast(tabWidget->currentWidget()); return curTextPage->getTextPage(); } EditorPage* TextEdit::curPage() { EditorPage *curPage = qobject_cast(tabWidget->currentWidget()); return curPage; } void TextEdit::dragEnterEvent(QDragEnterEvent *event) { if (event->mimeData()->hasFormat("text/plain")) qDebug() << "enter textedit drag action"; event->acceptProposedAction(); } void TextEdit::dropEvent(QDropEvent* event) { curTextPage()->setPlainText(event->mimeData()->text()); qDebug() << "enter textedit drop action"; qDebug() << event->mimeData()->text(); foreach (QUrl tmp, event->mimeData()->urls()) { qDebug() << "hallo" << tmp; } //event->acceptProposedAction(); } void TextEdit::quote() { QTextCursor cursor(curTextPage()->document()); // beginEditBlock and endEditBlock() let operation look like single undo/redo operation cursor.beginEditBlock(); cursor.setPosition(0); cursor.insertText("> "); while (!cursor.isNull() && !cursor.atEnd()) { cursor.movePosition(QTextCursor::EndOfLine); cursor.movePosition(QTextCursor::NextCharacter); if(!cursor.atEnd()) cursor.insertText("> "); } cursor.endEditBlock(); } void TextEdit::loadFile(const QString &fileName) { QFile file(fileName); if (!file.open(QFile::ReadOnly | QFile::Text)) { QMessageBox::warning(this, tr("Application"), tr("Cannot read file %1:\n%2.") .arg(fileName) .arg(file.errorString())); return; } QTextStream in(&file); QApplication::setOverrideCursor(Qt::WaitCursor); curTextPage()->setPlainText(in.readAll()); QApplication::restoreOverrideCursor(); curPage()->setFilePath(fileName); tabWidget->setTabText(tabWidget->currentIndex(), strippedName(fileName)); // statusBar()->showMessage(tr("File loaded"), 2000); } QString TextEdit::strippedName(const QString &fullFileName) { return QFileInfo(fullFileName).fileName(); } void TextEdit::print() { #ifndef QT_NO_PRINTER QTextDocument *document = curTextPage()->document(); QPrinter printer; QPrintDialog *dlg = new QPrintDialog(&printer, this); if (dlg->exec() != QDialog::Accepted) return; document->print(&printer); //statusBar()->showMessage(tr("Ready"), 2000); #endif } /** put a * in front of every modified document tab */ void TextEdit::showModified() { int index=tabWidget->currentIndex(); QString title= tabWidget->tabText(index); if(curTextPage()->document()->isModified()) tabWidget->setTabText(index, title.prepend("* ")); else tabWidget->setTabText(index, title.remove(0,2)); } void TextEdit::switchTabUp() { if (tabWidget->count() > 1) { if (tabWidget->count() == tabWidget->currentIndex()+1){ tabWidget->setCurrentIndex(0); } else { tabWidget->setCurrentIndex(tabWidget->currentIndex()+1); } } } void TextEdit::switchTabDown() { if (tabWidget->count() > 1) { if (tabWidget->currentIndex()==1) { tabWidget->setCurrentIndex(tabWidget->count()-1); } else { tabWidget->setCurrentIndex(tabWidget->currentIndex()-1); } } }