summaryrefslogtreecommitdiffstats
path: root/kspread/dialogs/kspread_dlg_subtotal.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kspread/dialogs/kspread_dlg_subtotal.cpp')
-rw-r--r--kspread/dialogs/kspread_dlg_subtotal.cpp321
1 files changed, 321 insertions, 0 deletions
diff --git a/kspread/dialogs/kspread_dlg_subtotal.cpp b/kspread/dialogs/kspread_dlg_subtotal.cpp
new file mode 100644
index 00000000..054cc1f7
--- /dev/null
+++ b/kspread/dialogs/kspread_dlg_subtotal.cpp
@@ -0,0 +1,321 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002-2003 Norbert Andres <[email protected]>
+ (C) 2002 Philipp Mueller <[email protected]>
+ (C) 2002 Laurent Montel <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include <tqcheckbox.h>
+#include <tqcombobox.h>
+#include <tqlistview.h>
+#include <tqmemarray.h>
+
+#include <kdebug.h>
+#include <tdelocale.h>
+#include <tdemessagebox.h>
+
+#include "kspreadsubtotal.h"
+#include "kspread_sheet.h"
+#include "kspread_view.h"
+#include "kspread_doc.h"
+#include "kspread_util.h"
+
+#include "kspread_dlg_subtotal.h"
+
+using namespace KSpread;
+
+SubtotalDialog::SubtotalDialog( View * parent, TQRect const & selection, const char * name )
+ : KDialogBase(parent, name, true, i18n( "Subtotals" ), Ok | Cancel | User1, Ok, true, KGuiItem(i18n( "Remove All" )) ),
+ m_pView( parent ),
+ m_pSheet( m_pView->activeSheet() ),
+ m_selection( selection ),
+ m_dialog( new Subtotal( this ) )
+{
+ setButtonBoxOrientation( Qt::Vertical );
+ setMainWidget( m_dialog );
+
+ fillColumnBoxes();
+ fillFunctionBox();
+}
+
+SubtotalDialog::~SubtotalDialog()
+{
+}
+
+void SubtotalDialog::slotOk()
+{
+ int numOfCols = m_selection.width();
+ TQMemArray<int> columns( numOfCols );
+
+ int n = 0;
+ bool empty = true;
+ int left = m_selection.left();
+ for ( TQListViewItem * item = m_dialog->m_columnList->firstChild(); item; item = item->nextSibling() )
+ {
+ if ( ((TQCheckListItem * ) item)->isOn() )
+ {
+ columns[n] = left + n;
+ empty = false;
+ }
+ else
+ columns[n] = -1;
+ ++n;
+ }
+
+ if ( empty )
+ {
+ KMessageBox::sorry( this, i18n("You need to select at least one column for adding subtotals.") );
+ return;
+ }
+
+ if ( m_dialog->m_replaceSubtotals->isChecked() )
+ removeSubtotalLines();
+
+ int mainCol = left + m_dialog->m_columnBox->currentItem();
+ int bottom = m_selection.bottom();
+ int top = m_selection.top();
+ left = m_selection.left();
+ TQString oldText = m_pSheet->cellAt( mainCol, top )->strOutText();
+ TQString newText;
+ TQString result( " " + i18n("Result") );
+ int lastChangedRow = top;
+
+ m_pView->doc()->emitBeginOperation( false );
+ bool ignoreEmptyCells = m_dialog->m_IgnoreBox->isChecked();
+ bool addRow;
+ if ( !m_dialog->m_summaryOnly->isChecked() )
+ {
+ int y = top + 1;
+ kdDebug() << "Starting in row " << y << endl;
+ while ( y <= bottom )
+ {
+ addRow = true;
+ newText = m_pSheet->cellAt( mainCol, y )->strOutText();
+
+ if ( ignoreEmptyCells && (newText.length() == 0) )
+ {
+ ++y;
+ kdDebug() << "Still the same -> " << y << endl;
+ continue;
+ }
+
+ if (newText != oldText)
+ {
+ int saveY = y;
+ for (int x = 0; x < numOfCols; ++x)
+ {
+ kdDebug() << "Column: " << x << ", " << columns[x] << endl;
+ if (columns[x] != -1)
+ {
+ if (!addSubtotal( mainCol, columns[x], y - 1, lastChangedRow, addRow, oldText + result))
+ reject();
+
+ if ( addRow )
+ {
+ ++saveY;
+ ++bottom;
+ }
+
+ addRow = false;
+ }
+ }
+ y = saveY;
+ lastChangedRow = y;
+ }
+ oldText = newText;
+ ++y;
+ }
+
+ addRow = true;
+ for ( int x = 0; x < numOfCols; ++x )
+ {
+ if ( columns[x] != -1 )
+ {
+ if ( !addSubtotal( mainCol, columns[x], y - 1, lastChangedRow, addRow, oldText + result ) )
+ reject();
+ addRow = false;
+ }
+ }
+ ++y;
+ }
+
+ if ( m_dialog->m_summaryBelow->isChecked() )
+ {
+ addRow = true;
+ int bottom = m_selection.bottom();
+ for (int x = 0; x < numOfCols; ++x)
+ {
+ if (columns[x] != -1)
+ {
+ addSubtotal( mainCol, columns[x], bottom, top, addRow, i18n("Grand Total") );
+ addRow = false;
+ }
+ }
+ }
+
+ m_pView->slotUpdateView( m_pView->activeSheet() );
+ accept();
+}
+
+void SubtotalDialog::slotCancel()
+{
+ reject();
+}
+
+void SubtotalDialog::slotUser1()
+{
+ m_pView->doc()->emitBeginOperation( false );
+ removeSubtotalLines();
+ m_pView->slotUpdateView( m_pView->activeSheet() );
+ accept();
+}
+
+void SubtotalDialog::removeSubtotalLines()
+{
+ kdDebug() << "Removing subtotal lines" << endl;
+
+ int r = m_selection.right();
+ int l = m_selection.left();
+ int t = m_selection.top();
+
+ Cell * cell;
+ TQString text;
+
+ for ( int y = m_selection.bottom(); y >= t; --y )
+ {
+ kdDebug() << "Checking row: " << y << endl;
+ bool containsSubtotal = false;
+ for (int x = l; x <= r; ++x )
+ {
+ cell = m_pSheet->cellAt( x, y );
+ if ( cell->isDefault() || !cell->isFormula() )
+ continue;
+
+ text = cell->text();
+ if ( text.find( "SUBTOTAL" ) != -1 )
+ {
+ containsSubtotal = true;
+ break;
+ }
+ }
+
+ if ( containsSubtotal )
+ {
+ kdDebug() << "Line " << y << " contains a subtotal " << endl;
+ TQRect rect( l, y, m_selection.width(), 1 );
+
+ m_pSheet->unshiftColumn( rect );
+ m_selection.setHeight( m_selection.height() - 1 );
+ }
+ }
+ kdDebug() << "Done removing subtotals" << endl;
+}
+
+void SubtotalDialog::fillColumnBoxes()
+{
+ int r = m_selection.right();
+ int row = m_selection.top();
+
+ Cell * cell;
+ TQCheckListItem * item;
+
+ TQString text;
+ TQString col( i18n( "Column '%1' ") );
+
+ for ( int i = m_selection.left(); i <= r; ++i )
+ {
+ cell = m_pSheet->cellAt( i, row );
+ text = cell->strOutText();
+
+ if ( text.length() > 0 )
+ {
+ text = col.arg( Cell::columnName( i ) );
+ }
+
+ m_dialog->m_columnBox->insertItem( text );
+
+ item = new TQCheckListItem( m_dialog->m_columnList,
+ text,
+ TQCheckListItem::CheckBox );
+ item->setOn(false);
+ m_dialog->m_columnList->insertItem( item );
+ }
+}
+
+void SubtotalDialog::fillFunctionBox()
+{
+ TQStringList lst;
+ lst << i18n( "Average" );
+ lst << i18n( "Count" );
+ lst << i18n( "CountA" );
+ lst << i18n( "Max" );
+ lst << i18n( "Min" );
+ lst << i18n( "Product" );
+ lst << i18n( "StDev" );
+ lst << i18n( "StDevP" );
+ lst << i18n( "Sum" );
+ lst << i18n( "Var" );
+ lst << i18n( "VarP" );
+ m_dialog->m_functionBox->insertStringList(lst);
+}
+
+bool SubtotalDialog::addSubtotal( int mainCol, int column, int row, int topRow,
+ bool addRow, TQString const & text )
+{
+ kdDebug() << "Adding subtotal: " << mainCol << ", " << column << ", Rows: " << row << ", " << topRow
+ << ": addRow: " << addRow << ", Text: " << text << endl;
+ if ( addRow )
+ {
+ TQRect rect(m_selection.left(), row + 1, m_selection.width(), 1);
+ if ( !m_pSheet->shiftColumn( rect ) )
+ return false;
+
+ m_selection.setHeight( m_selection.height() + 1 );
+
+ Cell * cell = m_pSheet->nonDefaultCell( mainCol, row + 1 );
+ cell->setCellText( text );
+ cell->format()->setTextFontBold( true );
+ cell->format()->setTextFontItalic( true );
+ cell->format()->setTextFontUnderline( true );
+ }
+
+ TQString colName = Cell::columnName( column );
+
+ TQString formula("=SUBTOTAL(");
+ formula += TQString::number( m_dialog->m_functionBox->currentItem() + 1 );
+ formula += "; ";
+ formula += colName;
+ formula += TQString::number( topRow );
+ // if ( topRow != row )
+ {
+ formula += ":";
+ formula += colName;
+ formula += TQString::number( row );
+ }
+ formula += ")";
+
+ Cell * cell = m_pSheet->nonDefaultCell( column, row + 1 );
+ cell->setCellText( formula );
+ cell->format()->setTextFontBold( true );
+ cell->format()->setTextFontItalic( true );
+ cell->format()->setTextFontUnderline( true );
+
+ return true;
+}
+
+#include "kspread_dlg_subtotal.moc"
+