kspread

AbstractRegionCommand.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE project
00002    Copyright 2005,2007 Stefan Nikolaus <stefan.nikolaus@kdemail.net>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017    Boston, MA 02110-1301, USA.
00018 */
00019 
00020 // Local
00021 #include "AbstractRegionCommand.h"
00022 
00023 #include <QApplication>
00024 
00025 #include <klocale.h>
00026 #include <kpassivepopup.h>
00027 
00028 #include <KoCanvasBase.h>
00029 
00030 #include "Cell.h"
00031 #include "part/Doc.h" // FIXME detach from part
00032 #include "Map.h"
00033 #include "Sheet.h"
00034 
00035 using namespace KSpread;
00036 
00037 //BEGIN NOTE Stefan: some words on operations
00038 //
00039 // 1. SubTotal
00040 // a) Makes no sense to extend to non-contiguous selections (NCS) as
00041 //    it refers to a change in one column.
00042 // b) No special undo command available yet.
00043 //
00044 // 2. AutoSum
00045 // a) should insert cell at the end of the selection, if the last
00046 //    is not empty
00047 // b) opens an editor, if the user's intention is fuzzy -> hard to
00048 //    convert to NCS
00049 //END
00050 
00051 /***************************************************************************
00052   class AbstractRegionCommand
00053 ****************************************************************************/
00054 
00055 AbstractRegionCommand::AbstractRegionCommand(QUndoCommand* parent)
00056   : Region(),
00057     QUndoCommand(parent),
00058     m_sheet(0),
00059     m_reverse(false),
00060     m_firstrun(true),
00061     m_register(true),
00062     m_success(true),
00063     m_checkLock(false)
00064 {
00065 }
00066 
00067 AbstractRegionCommand::~AbstractRegionCommand()
00068 {
00069 }
00070 
00071 bool AbstractRegionCommand::execute(KoCanvasBase* canvas)
00072 {
00073     if ( !m_firstrun )
00074         return false;
00075     if ( !isApproved() )
00076         return false;
00077     // registering in undo history?
00078     if ( m_register )
00079         canvas ? canvas->addCommand(this) : m_sheet->doc()->addCommand(this);
00080     else
00081         redo();
00082     return m_success;
00083 }
00084 
00085 void AbstractRegionCommand::redo()
00086 {
00087     if ( !m_sheet )
00088     {
00089         kWarning() << "AbstractRegionCommand::redo(): No explicit m_sheet is set. "
00090                    << "Manipulating all sheets of the region." << endl;
00091     }
00092 
00093     bool successfully = true;
00094     successfully = preProcessing();
00095     if ( !successfully )
00096     {
00097         m_success = false;
00098         return;   // do nothing if pre-processing fails
00099     }
00100 
00101     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
00102     m_sheet->setRegionPaintDirty( *this );
00103 
00104     successfully = mainProcessing();
00105     if ( !successfully )
00106     {
00107         m_success = false;
00108         kWarning() << "AbstractRegionCommand::redo(): processing was not successful!";
00109     }
00110 
00111     successfully = true;
00112     successfully = postProcessing();
00113     if ( !successfully )
00114     {
00115         m_success = false;
00116         kWarning() << "AbstractRegionCommand::redo(): postprocessing was not successful!";
00117     }
00118 
00119     QApplication::restoreOverrideCursor();
00120 
00121     m_firstrun = false;
00122 }
00123 
00124 void AbstractRegionCommand::undo()
00125 {
00126   m_reverse = !m_reverse;
00127   redo();
00128   m_reverse = !m_reverse;
00129 }
00130 
00131 bool AbstractRegionCommand::isApproved() const
00132 {
00133     Region::ConstIterator endOfList( constEnd() );
00134     for ( Region::ConstIterator it = constBegin(); it != endOfList; ++it )
00135     {
00136         const QRect range = (*it)->rect();
00137 
00138         for ( int col = range.left(); col <= range.right(); ++col )
00139         {
00140             for ( int row = range.top(); row <= range.bottom(); ++row )
00141             {
00142                 Cell cell( m_sheet, col, row );
00143                 if ( m_sheet->isProtected() && !cell.style().notProtected() )
00144                 {
00145                     KPassivePopup::message( i18n( "Processing is not possible, "
00146                                                   "because some cells are protected." ),
00147                                             QApplication::activeWindow() );
00148                     return false;
00149                 }
00150 
00151                 // check for matrix locks
00152                 if ( m_checkLock && cell.isLocked() )
00153                 {
00154                     KPassivePopup::message( i18n( "Processing is not possible, because some "
00155                                                   "cells are locked as elements of a matrix." ),
00156                                             QApplication::activeWindow() );
00157                     return false;
00158                 }
00159             }
00160         }
00161     }
00162     return true;
00163 }
00164 
00165 bool AbstractRegionCommand::mainProcessing()
00166 {
00167   bool successfully = true;
00168   Region::Iterator endOfList(cells().end());
00169   for (Region::Iterator it = cells().begin(); it != endOfList; ++it)
00170   {
00171     successfully = successfully && process(*it);
00172   }
00173   return successfully;
00174 }