XML Mill  1.0.0
A GUI based XML editor with a memory.
gcrestorefilesform.cpp
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 /*--------------------------------------------------------------------------------------*/