![]() |
XML Mill
1.0.0
A GUI based XML editor with a memory.
|
00001 /* Copyright (c) 2012 - 2013 by William Hallatt. 00002 * 00003 * This file forms part of "XML Mill". 00004 * 00005 * The official website for this project is <http://www.goblincoding.com> and, 00006 * although not compulsory, it would be appreciated if all works of whatever 00007 * nature using this source code (in whole or in part) include a reference to 00008 * this site. 00009 * 00010 * Should you wish to contact me for whatever reason, please do so via: 00011 * 00012 * <http://www.goblincoding.com/contact> 00013 * 00014 * This program is free software: you can redistribute it and/or modify it under 00015 * the terms of the GNU General Public License as published by the Free Software 00016 * Foundation, either version 3 of the License, or (at your option) any later 00017 * version. 00018 * 00019 * This program is distributed in the hope that it will be useful, but WITHOUT 00020 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00021 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 00022 * 00023 * You should have received a copy of the GNU General Public License along with 00024 * this program (GNUGPL.txt). If not, see 00025 * 00026 * <http://www.gnu.org/licenses/> 00027 */ 00028 00029 #include "gcrestorefilesform.h" 00030 #include "ui_gcrestorefilesform.h" 00031 #include "xml/xmlsyntaxhighlighter.h" 00032 #include "db/gcdatabaseinterface.h" 00033 #include "utils/gcglobalspace.h" 00034 #include "utils/gcmessagespace.h" 00035 00036 #include <QFile> 00037 #include <QDomDocument> 00038 #include <QTextStream> 00039 #include <QFileDialog> 00040 00041 /*--------------------------------------------------------------------------------------*/ 00042 00043 GCRestoreFilesForm::GCRestoreFilesForm( const QStringList& tempFiles, QWidget* parent ) 00044 : QDialog ( parent ), 00045 ui ( new Ui::GCRestoreFilesForm ), 00046 m_tempFiles( tempFiles ), 00047 m_fileName ( "" ) 00048 { 00049 ui->setupUi( this ); 00050 ui->plainTextEdit->setFont( QFont( GCGlobalSpace::FONT, GCGlobalSpace::FONTSIZE ) ); 00051 setAttribute( Qt::WA_DeleteOnClose ); 00052 00053 connect( ui->saveButton, SIGNAL( clicked() ), this, SLOT( saveFile() ) ); 00054 connect( ui->nextButton, SIGNAL( clicked() ), this, SLOT( next() ) ); 00055 connect( ui->cancelButton, SIGNAL( clicked() ), this, SLOT( close() ) ); 00056 connect( ui->discardButton, SIGNAL( clicked() ), this, SLOT( deleteTempFile() ) ); 00057 00058 /* Everything happens automagically and the text edit takes ownership. */ 00059 XmlSyntaxHighlighter* highLighter = new XmlSyntaxHighlighter( ui->plainTextEdit->document() ); 00060 Q_UNUSED( highLighter ); 00061 00062 next(); 00063 } 00064 00065 /*--------------------------------------------------------------------------------------*/ 00066 00067 GCRestoreFilesForm::~GCRestoreFilesForm() 00068 { 00069 delete ui; 00070 } 00071 00072 /*--------------------------------------------------------------------------------------*/ 00073 00074 void GCRestoreFilesForm::saveFile() 00075 { 00076 QString fileName = QFileDialog::getSaveFileName( this, "Save As", GCGlobalSpace::lastUserSelectedDirectory(), "XML Files (*.*)" ); 00077 00078 /* If the user clicked "OK". */ 00079 if( !fileName.isEmpty() ) 00080 { 00081 QFile file( fileName ); 00082 00083 if( !file.open( QIODevice::ReadWrite | QIODevice::Truncate | QIODevice::Text ) ) 00084 { 00085 QString errMsg = QString( "Failed to save file \"%1\": [%2]." ) 00086 .arg( fileName ) 00087 .arg( file.errorString() ); 00088 GCMessageSpace::showErrorMessageBox( this, errMsg ); 00089 } 00090 else 00091 { 00092 QTextStream outStream( &file ); 00093 outStream << ui->plainTextEdit->toPlainText(); 00094 file.close(); 00095 00096 deleteTempFile(); 00097 00098 /* Save the last visited directory. */ 00099 QFileInfo fileInfo( fileName ); 00100 QString finalDirectory = fileInfo.dir().path(); 00101 GCGlobalSpace::setLastUserSelectedDirectory( finalDirectory ); 00102 } 00103 } 00104 } 00105 00106 /*--------------------------------------------------------------------------------------*/ 00107 00108 void GCRestoreFilesForm::deleteTempFile() const 00109 { 00110 QDir dir; 00111 dir.remove( m_fileName ); 00112 ui->plainTextEdit->clear(); 00113 ui->lineEdit->clear(); 00114 } 00115 00116 /*--------------------------------------------------------------------------------------*/ 00117 00118 void GCRestoreFilesForm::next() 00119 { 00120 if( !m_tempFiles.isEmpty() ) 00121 { 00122 m_fileName = m_tempFiles.takeFirst(); 00123 ui->nextButton->setEnabled( true ); 00124 loadFile( m_fileName ); 00125 } 00126 else 00127 { 00128 ui->plainTextEdit->setPlainText( "No documents left to recover." ); 00129 ui->saveButton->setVisible( false ); 00130 ui->discardButton->setVisible( false ); 00131 ui->nextButton->setVisible( false ); 00132 ui->cancelButton->setText( "Close" ); 00133 ui->lineEdit->clear(); 00134 } 00135 } 00136 00137 /*--------------------------------------------------------------------------------------*/ 00138 00139 void GCRestoreFilesForm::loadFile( const QString& fileName ) 00140 { 00141 QFile file( fileName ); 00142 00143 if( file.open( QIODevice::ReadOnly | QIODevice::Text ) ) 00144 { 00145 QString displayName = fileName; 00146 displayName = displayName.remove( QString( "_%1_temp" ).arg( GCDataBaseInterface::instance()->activeSessionName() ).remove( ".db" ) ); 00147 ui->lineEdit->setText( displayName ); 00148 00149 QString xmlErr( "" ); 00150 int line ( -1 ); 00151 int col ( -1 ); 00152 00153 QTextStream inStream( &file ); 00154 QString fileContent = inStream.readAll(); 00155 ui->plainTextEdit->setPlainText( fileContent ); 00156 00157 QDomDocument doc; 00158 00159 if( !doc.setContent( fileContent, &xmlErr, &line, &col ) ) 00160 { 00161 QString errorMsg = QString( "XML is broken - Error [%1], line [%2], column [%3]." ) 00162 .arg( xmlErr ) 00163 .arg( line ) 00164 .arg( col ); 00165 00166 GCMessageSpace::showErrorMessageBox( this, errorMsg ); 00167 00168 /* Unfortunately the line number returned by the DOM doc doesn't match up with what's 00169 visible in the QTextEdit. It seems as if it's mostly off by two lines. For now it's a 00170 fix, but will have to figure out how to make sure that we highlight the correct lines. 00171 Ultimately this finds the broken XML and highlights it in red...what a mission... */ 00172 QTextBlock textBlock = ui->plainTextEdit->document()->findBlockByLineNumber( line - 2 ); 00173 QTextCursor cursor( textBlock ); 00174 cursor.movePosition( QTextCursor::NextWord ); 00175 cursor.movePosition( QTextCursor::EndOfBlock, QTextCursor::KeepAnchor ); 00176 00177 QTextEdit::ExtraSelection highlight; 00178 highlight.cursor = cursor; 00179 highlight.format.setBackground( QColor( 220, 150, 220 ) ); 00180 highlight.format.setProperty( QTextFormat::FullWidthSelection, true ); 00181 00182 QList< QTextEdit::ExtraSelection > extras; 00183 extras << highlight; 00184 ui->plainTextEdit->setExtraSelections( extras ); 00185 ui->plainTextEdit->ensureCursorVisible(); 00186 } 00187 } 00188 else 00189 { 00190 GCMessageSpace::showErrorMessageBox( this, "Failed to open file. Cannot recover." ); 00191 } 00192 } 00193 00194 /*--------------------------------------------------------------------------------------*/