XML Mill  1.0.0
A GUI based XML editor with a memory.
gcmessagespace.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 "gcmessagespace.h"
00030 #include "ui_gcmessagedialog.h"
00031 #include "utils/gcglobalspace.h"
00032 
00033 #include <QSettings>
00034 #include <QDialog>
00035 #include <QMessageBox>
00036 
00038 class GCMessageDialog : public QDialog
00039 {
00040 Q_OBJECT
00041 public:
00042 
00051   explicit GCMessageDialog( bool* remember,
00052                             const QString& heading,
00053                             const QString& text,
00054                             GCMessageSpace::ButtonCombo buttons,
00055                             GCMessageSpace::Buttons defaultButton,
00056                             GCMessageSpace::Icon icon = GCMessageSpace::NoIcon )
00057   : ui( new Ui::GCMessageDialog ),
00058     m_remember( remember )
00059   {
00060     ui->setupUi( this );
00061     ui->textLabel->setText( text );
00062 
00063     switch( buttons )
00064     {
00065       case GCMessageSpace::YesNo:
00066         ui->acceptButton->setText( "Yes" );
00067         ui->rejectButton->setText( "No" );
00068         break;
00069       case GCMessageSpace::OKCancel:
00070         ui->acceptButton->setText( "OK" );
00071         ui->rejectButton->setText( "Cancel" );
00072         break;
00073       case GCMessageSpace::OKOnly:
00074         ui->acceptButton->setText( "OK" );
00075         ui->rejectButton->setVisible( false );
00076     }
00077 
00078     switch( defaultButton )
00079     {
00080       case GCMessageSpace::Yes:
00081         /* Deliberate fall-through. */
00082       case GCMessageSpace::OK:
00083         ui->acceptButton->setDefault( true );
00084         break;
00085       case GCMessageSpace::No:
00086         /* Deliberate fall-through. */
00087       case GCMessageSpace::Cancel:
00088         ui->rejectButton->setDefault( true );
00089     }
00090 
00091     switch( icon )
00092     {
00093       case GCMessageSpace::Information:
00094         ui->iconLabel->setPixmap( style()->standardIcon( QStyle::SP_MessageBoxInformation ).pixmap( 32, 32 ) );
00095         break;
00096       case GCMessageSpace::Warning:
00097         ui->iconLabel->setPixmap( style()->standardIcon( QStyle::SP_MessageBoxWarning ).pixmap( 32, 32 ) );
00098         break;
00099       case GCMessageSpace::Critical:
00100         ui->iconLabel->setPixmap( style()->standardIcon( QStyle::SP_MessageBoxCritical ).pixmap( 32, 32 ) );
00101         break;
00102       case GCMessageSpace::Question:
00103         ui->iconLabel->setPixmap( style()->standardIcon( QStyle::SP_MessageBoxQuestion ).pixmap( 32, 32 ) );
00104         break;
00105       case GCMessageSpace::NoIcon:
00106       default:
00107         ui->iconLabel->setPixmap( QPixmap() );
00108     }
00109 
00110     connect( ui->checkBox, SIGNAL( toggled( bool ) ), this, SLOT( setRememberUserChoice( bool ) ) );
00111     connect( ui->acceptButton, SIGNAL( clicked() ), this, SLOT( accept() ) );
00112     connect( ui->rejectButton, SIGNAL( clicked() ), this, SLOT( reject() ) );
00113 
00114     setWindowTitle( heading );
00115   }
00116 
00118   ~GCMessageDialog()
00119   {
00120     /* The variable that "m_remember" points to is owned externally. */
00121     delete ui;
00122   }
00123 
00124 private slots:
00126   void setRememberUserChoice( bool remember )
00127   {
00128     *m_remember = remember;
00129   }
00130 
00131 private:
00132   Ui::GCMessageDialog* ui;
00133   bool* m_remember;
00134 };
00135 
00136 /* Standard trick for classes defined in .cpp files (resolves "Undefined Reference
00137   to vtable for xxx issue). The file that seems "missing" at the moment is generated
00138   by MOC when qMake is run. Must include after class definition. */
00139 #include "gcmessagespace.moc"
00140 
00141 /*--------------------------------------------------------------------------------------*/
00142 
00143 namespace GCMessageSpace
00144 {
00145   /* Hides our "member" variables. */
00146   namespace
00147   {
00148     QSettings settings( GCGlobalSpace::getOrganisationName(), GCGlobalSpace::getApplicationName() );
00149     bool settingsInitialised( false );
00150   }
00151 
00152   /*------------------------------------------------------------------------------------*/
00153 
00154   /* Uses QSettings to save the user preference to the registry (Windows) or
00155     relevant XML files (Mac) or ini (Unix). */
00156   bool userAccepted( const QString& uniqueMessageKey,
00157                      const QString& heading,
00158                      const QString& text,
00159                      ButtonCombo buttons,
00160                      Buttons defaultButton,
00161                      Icon icon,
00162                      bool saveCancel )
00163   {
00164     if( !settingsInitialised )
00165     {
00166       settings.setValue( "dialogPreferences", "" );
00167       settingsInitialised = true;
00168     }
00169 
00170     /* Check if the user previously requested that his/her choice must be saved. */
00171     QString key = QString( "dialogPreferences/%1" ).arg( uniqueMessageKey );
00172     QString valueKey = QString( key + "/preference" );
00173 
00174     bool remembered = settings.value( key, false ).toBool();
00175 
00176     if( !remembered )
00177     {
00178       GCMessageDialog dialog( &remembered, heading, text, buttons, defaultButton, icon );
00179       QDialog::DialogCode accept = static_cast< QDialog::DialogCode >( dialog.exec() );
00180 
00181       if( accept == QDialog::Accepted )
00182       {
00183         if( remembered )
00184         {
00185           settings.setValue( key, true );
00186           settings.setValue( valueKey, true );
00187         }
00188 
00189         return true;
00190       }
00191       else
00192       {
00193         /* For some message prompts, it isn't desirable to save "Cancel" values and
00194           it is therefore necessary to ensure that none of these values are remembered
00195           by accident. */
00196         if( remembered )
00197         {
00198           if( saveCancel )
00199           {
00200             settings.setValue( key, true );
00201             settings.setValue( valueKey, false );
00202           }
00203           else
00204           {
00205             settings.setValue( key, false );
00206           }
00207         }
00208 
00209         return false;
00210       }
00211     }
00212     else
00213     {
00214       /* If we do have a remembered setting, act accordingly. */
00215       return settings.value( valueKey ).toBool();
00216     }
00217   }
00218 
00219   /*------------------------------------------------------------------------------------*/
00220 
00221   void forgetAllPreferences()
00222   {
00223     settings.beginGroup( "dialogPreferences" );
00224     settings.remove( "" );
00225     settings.endGroup();
00226   }
00227 
00228   /*------------------------------------------------------------------------------------*/
00229 
00230   void showErrorMessageBox( QWidget* parent, const QString& message )
00231   {
00232     QMessageBox::critical( parent, "Error!", message );
00233   }
00234 
00235   /*------------------------------------------------------------------------------------*/
00236 }